aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cjson/fpconv.c211
-rw-r--r--src/cjson/fpconv.h22
-rw-r--r--src/cjson/lua_cjson.c1609
-rw-r--r--src/cjson/lua_cjson.h10
-rw-r--r--src/cjson/strbuf.c251
-rw-r--r--src/cjson/strbuf.h159
-rwxr-xr-xsrc/clint.py4
-rw-r--r--src/mpack/LICENSE-MIT22
-rw-r--r--src/mpack/conv.c378
-rw-r--r--src/mpack/conv.h55
-rw-r--r--src/mpack/lmpack.c1218
-rw-r--r--src/mpack/lmpack.h3
-rw-r--r--src/mpack/mpack_core.c578
-rw-r--r--src/mpack/mpack_core.h87
-rw-r--r--src/mpack/object.c198
-rw-r--r--src/mpack/object.h86
-rw-r--r--src/mpack/rpc.c334
-rw-r--r--src/mpack/rpc.h83
-rw-r--r--src/nvim/CMakeLists.txt28
-rw-r--r--src/nvim/README.md104
-rw-r--r--src/nvim/api/buffer.c357
-rw-r--r--src/nvim/api/deprecated.c107
-rw-r--r--src/nvim/api/private/dispatch.c33
-rw-r--r--src/nvim/api/private/handle.c40
-rw-r--r--src/nvim/api/private/handle.h24
-rw-r--r--src/nvim/api/private/helpers.c637
-rw-r--r--src/nvim/api/private/helpers.h8
-rw-r--r--src/nvim/api/tabpage.c11
-rw-r--r--src/nvim/api/ui.c108
-rw-r--r--src/nvim/api/ui_events.in.h3
-rw-r--r--src/nvim/api/vim.c727
-rw-r--r--src/nvim/api/vim.h2
-rw-r--r--src/nvim/api/window.c23
-rw-r--r--src/nvim/arabic.c879
-rw-r--r--src/nvim/ascii.h8
-rw-r--r--src/nvim/aucmd.c36
-rw-r--r--src/nvim/autocmd.c120
-rw-r--r--src/nvim/buffer.c851
-rw-r--r--src/nvim/buffer.h7
-rw-r--r--src/nvim/buffer_defs.h23
-rw-r--r--src/nvim/buffer_updates.c76
-rw-r--r--src/nvim/change.c237
-rw-r--r--src/nvim/channel.c241
-rw-r--r--src/nvim/channel.h8
-rw-r--r--src/nvim/charset.c519
-rw-r--r--src/nvim/charset.h11
-rw-r--r--src/nvim/context.c4
-rw-r--r--src/nvim/cursor.c92
-rw-r--r--src/nvim/cursor_shape.c92
-rw-r--r--src/nvim/debugger.c837
-rw-r--r--src/nvim/debugger.h11
-rw-r--r--src/nvim/decoration.c107
-rw-r--r--src/nvim/decoration.h21
-rw-r--r--src/nvim/diff.c188
-rw-r--r--src/nvim/digraph.c32
-rw-r--r--src/nvim/edit.c1586
-rw-r--r--src/nvim/eval.c2947
-rw-r--r--src/nvim/eval.h3
-rw-r--r--src/nvim/eval.lua234
-rw-r--r--src/nvim/eval/decode.c984
-rw-r--r--src/nvim/eval/encode.c807
-rw-r--r--src/nvim/eval/executor.c181
-rw-r--r--src/nvim/eval/funcs.c2108
-rw-r--r--src/nvim/eval/funcs.h5
-rw-r--r--src/nvim/eval/gc.c2
-rw-r--r--src/nvim/eval/typval.c1112
-rw-r--r--src/nvim/eval/typval.h73
-rw-r--r--src/nvim/eval/typval_encode.c.h12
-rw-r--r--src/nvim/eval/userfunc.c623
-rw-r--r--src/nvim/eval/userfunc.h26
-rw-r--r--src/nvim/event/libuv_process.c7
-rw-r--r--src/nvim/event/loop.c1
-rw-r--r--src/nvim/event/multiqueue.c7
-rw-r--r--src/nvim/event/process.c98
-rw-r--r--src/nvim/event/process.h1
-rw-r--r--src/nvim/event/rstream.c28
-rw-r--r--src/nvim/event/socket.c38
-rw-r--r--src/nvim/event/stream.c13
-rw-r--r--src/nvim/event/time.c4
-rw-r--r--src/nvim/event/wstream.c12
-rw-r--r--src/nvim/ex_cmds.c1680
-rw-r--r--src/nvim/ex_cmds.lua2
-rw-r--r--src/nvim/ex_cmds2.c1267
-rw-r--r--src/nvim/ex_cmds_defs.h2
-rw-r--r--src/nvim/ex_docmd.c3303
-rw-r--r--src/nvim/ex_docmd.h7
-rw-r--r--src/nvim/ex_eval.c473
-rw-r--r--src/nvim/ex_getln.c1581
-rw-r--r--src/nvim/ex_session.c107
-rw-r--r--src/nvim/extmark.c162
-rw-r--r--src/nvim/extmark_defs.h14
-rw-r--r--src/nvim/file_search.c735
-rw-r--r--src/nvim/fileio.c1735
-rw-r--r--src/nvim/fold.c1174
-rw-r--r--src/nvim/fold.h2
-rw-r--r--src/nvim/garray.c23
-rw-r--r--src/nvim/generators/gen_api_dispatch.lua8
-rw-r--r--src/nvim/generators/gen_eval.lua7
-rw-r--r--src/nvim/generators/gen_options.lua13
-rw-r--r--src/nvim/getchar.c790
-rw-r--r--src/nvim/globals.h104
-rw-r--r--src/nvim/grid_defs.h2
-rw-r--r--src/nvim/hardcopy.c756
-rw-r--r--src/nvim/hashtab.c16
-rw-r--r--src/nvim/highlight.c192
-rw-r--r--src/nvim/highlight_defs.h6
-rw-r--r--src/nvim/indent.c67
-rw-r--r--src/nvim/keymap.c211
-rw-r--r--src/nvim/keymap.h10
-rw-r--r--src/nvim/log.c25
-rw-r--r--src/nvim/log.h2
-rw-r--r--src/nvim/lua/converter.c769
-rw-r--r--src/nvim/lua/executor.c355
-rw-r--r--src/nvim/lua/treesitter.c200
-rw-r--r--src/nvim/lua/vim.lua108
-rw-r--r--src/nvim/lua/xdiff.c332
-rw-r--r--src/nvim/lua/xdiff.h12
-rw-r--r--src/nvim/macros.h6
-rw-r--r--src/nvim/main.c935
-rw-r--r--src/nvim/main.h1
-rw-r--r--src/nvim/map.c73
-rw-r--r--src/nvim/map.h22
-rw-r--r--src/nvim/mark.c536
-rw-r--r--src/nvim/marktree.c49
-rw-r--r--src/nvim/marktree.h4
-rw-r--r--src/nvim/math.c42
-rw-r--r--src/nvim/mbyte.c853
-rw-r--r--src/nvim/memfile.c116
-rw-r--r--src/nvim/memfile_defs.h2
-rw-r--r--src/nvim/memline.c1595
-rw-r--r--src/nvim/memory.c142
-rw-r--r--src/nvim/menu.c478
-rw-r--r--src/nvim/message.c702
-rw-r--r--src/nvim/misc1.c441
-rw-r--r--src/nvim/mouse.c215
-rw-r--r--src/nvim/move.c585
-rw-r--r--src/nvim/msgpack_rpc/channel.c168
-rw-r--r--src/nvim/msgpack_rpc/channel_defs.h2
-rw-r--r--src/nvim/msgpack_rpc/helpers.c414
-rw-r--r--src/nvim/msgpack_rpc/server.c18
-rw-r--r--src/nvim/normal.c2523
-rw-r--r--src/nvim/ops.c1471
-rw-r--r--src/nvim/ops.h7
-rw-r--r--src/nvim/option.c1805
-rw-r--r--src/nvim/option_defs.h26
-rw-r--r--src/nvim/options.lua1134
-rw-r--r--src/nvim/os/dl.c36
-rw-r--r--src/nvim/os/env.c103
-rw-r--r--src/nvim/os/fileio.c38
-rw-r--r--src/nvim/os/fs.c135
-rw-r--r--src/nvim/os/input.c53
-rw-r--r--src/nvim/os/os_win_console.c2
-rw-r--r--src/nvim/os/process.c6
-rw-r--r--src/nvim/os/pty_conpty_win.c110
-rw-r--r--src/nvim/os/pty_process_unix.c14
-rw-r--r--src/nvim/os/pty_process_win.c89
-rw-r--r--src/nvim/os/shell.c97
-rw-r--r--src/nvim/os/signal.c89
-rw-r--r--src/nvim/os/stdpaths.c9
-rw-r--r--src/nvim/os/time.c12
-rw-r--r--src/nvim/os/tty.c9
-rw-r--r--src/nvim/os/users.c13
-rw-r--r--src/nvim/os_unix.c27
-rw-r--r--src/nvim/path.c404
-rw-r--r--src/nvim/plines.c510
-rw-r--r--src/nvim/plines.h9
-rw-r--r--src/nvim/po/sr.po52
-rw-r--r--src/nvim/po/tr.po759
-rw-r--r--src/nvim/popupmnu.c44
-rw-r--r--src/nvim/profile.c15
-rw-r--r--src/nvim/quickfix.c1066
-rw-r--r--src/nvim/rbuffer.c4
-rw-r--r--src/nvim/regexp.c15
-rw-r--r--src/nvim/regexp_nfa.c8
-rw-r--r--src/nvim/runtime.c376
-rw-r--r--src/nvim/runtime.h20
-rw-r--r--src/nvim/screen.c1975
-rw-r--r--src/nvim/search.c2417
-rw-r--r--src/nvim/search.h2
-rw-r--r--src/nvim/sha256.c11
-rw-r--r--src/nvim/shada.c2790
-rw-r--r--src/nvim/sign.c949
-rw-r--r--src/nvim/spell.c1921
-rw-r--r--src/nvim/spellfile.c1768
-rw-r--r--src/nvim/state.c24
-rw-r--r--src/nvim/strings.c15
-rw-r--r--src/nvim/syntax.c2545
-rw-r--r--src/nvim/tag.c126
-rw-r--r--src/nvim/terminal.c39
-rw-r--r--src/nvim/testdir/check.vim11
-rw-r--r--src/nvim/testdir/samples/memfile_test.c4
-rw-r--r--src/nvim/testdir/sautest/autoload/foo.vim4
-rw-r--r--src/nvim/testdir/setup.vim11
-rw-r--r--src/nvim/testdir/test42.inbin2373 -> 2387 bytes
-rw-r--r--src/nvim/testdir/test_alot.vim1
-rw-r--r--src/nvim/testdir/test_arglist.vim4
-rw-r--r--src/nvim/testdir/test_assert.vim2
-rw-r--r--src/nvim/testdir/test_autocmd.vim3
-rw-r--r--src/nvim/testdir/test_autoload.vim2
-rw-r--r--src/nvim/testdir/test_blob.vim349
-rw-r--r--src/nvim/testdir/test_breakindent.vim148
-rw-r--r--src/nvim/testdir/test_bufline.vim8
-rw-r--r--src/nvim/testdir/test_bufwintabinfo.vim2
-rw-r--r--src/nvim/testdir/test_cd.vim20
-rw-r--r--src/nvim/testdir/test_cindent.vim10
-rw-r--r--src/nvim/testdir/test_cmdline.vim19
-rw-r--r--src/nvim/testdir/test_command_count.vim2
-rw-r--r--src/nvim/testdir/test_const.vim33
-rw-r--r--src/nvim/testdir/test_cursorline.vim271
-rw-r--r--src/nvim/testdir/test_debugger.vim11
-rw-r--r--src/nvim/testdir/test_diffmode.vim73
-rw-r--r--src/nvim/testdir/test_display.vim18
-rw-r--r--src/nvim/testdir/test_eval_stuff.vim251
-rw-r--r--src/nvim/testdir/test_ex_z.vim36
-rw-r--r--src/nvim/testdir/test_excmd.vim36
-rw-r--r--src/nvim/testdir/test_expr.vim11
-rw-r--r--src/nvim/testdir/test_filetype.vim117
-rw-r--r--src/nvim/testdir/test_filter_map.vim6
-rw-r--r--src/nvim/testdir/test_float_func.vim27
-rw-r--r--src/nvim/testdir/test_fnamemodify.vim4
-rw-r--r--src/nvim/testdir/test_functions.vim114
-rw-r--r--src/nvim/testdir/test_gf.vim2
-rw-r--r--src/nvim/testdir/test_hide.vim2
-rw-r--r--src/nvim/testdir/test_highlight.vim2
-rw-r--r--src/nvim/testdir/test_ins_complete.vim129
-rw-r--r--src/nvim/testdir/test_ins_complete_no_halt.vim51
-rw-r--r--src/nvim/testdir/test_join.vim2
-rw-r--r--src/nvim/testdir/test_lambda.vim2
-rw-r--r--src/nvim/testdir/test_listchars.vim186
-rw-r--r--src/nvim/testdir/test_listdict.vim4
-rw-r--r--src/nvim/testdir/test_match.vim7
-rw-r--r--src/nvim/testdir/test_method.vim154
-rw-r--r--src/nvim/testdir/test_mksession.vim29
-rw-r--r--src/nvim/testdir/test_modeline.vim10
-rw-r--r--src/nvim/testdir/test_normal.vim2
-rw-r--r--src/nvim/testdir/test_number.vim44
-rw-r--r--src/nvim/testdir/test_options.vim2
-rw-r--r--src/nvim/testdir/test_popup.vim6
-rw-r--r--src/nvim/testdir/test_quickfix.vim130
-rw-r--r--src/nvim/testdir/test_registers.vim80
-rw-r--r--src/nvim/testdir/test_rename.vim1
-rw-r--r--src/nvim/testdir/test_spellfile.vim46
-rw-r--r--src/nvim/testdir/test_startup.vim12
-rw-r--r--src/nvim/testdir/test_swap.vim17
-rw-r--r--src/nvim/testdir/test_syntax.vim6
-rw-r--r--src/nvim/testdir/test_system.vim4
-rw-r--r--src/nvim/testdir/test_tagjump.vim25
-rw-r--r--src/nvim/testdir/test_textformat.vim7
-rw-r--r--src/nvim/testdir/test_textobjects.vim277
-rw-r--r--src/nvim/testdir/test_undo.vim1
-rw-r--r--src/nvim/testdir/test_user_func.vim18
-rw-r--r--src/nvim/testdir/test_usercommands.vim42
-rw-r--r--src/nvim/testdir/test_utf8.vim35
-rw-r--r--src/nvim/testdir/test_vimscript.vim8
-rw-r--r--src/nvim/testdir/test_visual.vim30
-rw-r--r--src/nvim/testdir/test_window_cmd.vim2
-rw-r--r--src/nvim/testdir/test_writefile.vim10
-rw-r--r--src/nvim/testdir/view_util.vim3
-rw-r--r--src/nvim/tui/input.c61
-rw-r--r--src/nvim/tui/terminfo.c15
-rw-r--r--src/nvim/tui/tui.c347
-rw-r--r--src/nvim/ui.c13
-rw-r--r--src/nvim/ui_bridge.c2
-rw-r--r--src/nvim/ui_compositor.c4
-rw-r--r--src/nvim/undo.c394
-rw-r--r--src/nvim/version.c8
-rw-r--r--src/nvim/vim.h14
-rw-r--r--src/nvim/viml/parser/expressions.c3279
-rw-r--r--src/nvim/window.c2155
-rw-r--r--src/uncrustify.cfg3295
-rw-r--r--src/xdiff/COPYING (renamed from src/nvim/xdiff/COPYING)0
-rw-r--r--src/xdiff/README.txt (renamed from src/nvim/xdiff/README.txt)2
-rw-r--r--src/xdiff/xdiff.h (renamed from src/nvim/xdiff/xdiff.h)39
-rw-r--r--src/xdiff/xdiffi.c (renamed from src/nvim/xdiff/xdiffi.c)176
-rw-r--r--src/xdiff/xdiffi.h (renamed from src/nvim/xdiff/xdiffi.h)2
-rw-r--r--src/xdiff/xemit.c (renamed from src/nvim/xdiff/xemit.c)34
-rw-r--r--src/xdiff/xemit.h (renamed from src/nvim/xdiff/xemit.h)2
-rw-r--r--src/xdiff/xhistogram.c (renamed from src/nvim/xdiff/xhistogram.c)16
-rw-r--r--src/xdiff/xinclude.h (renamed from src/nvim/xdiff/xinclude.h)8
-rw-r--r--src/xdiff/xmacros.h (renamed from src/nvim/xdiff/xmacros.h)2
-rw-r--r--src/xdiff/xpatience.c (renamed from src/nvim/xdiff/xpatience.c)53
-rw-r--r--src/xdiff/xprepare.c (renamed from src/nvim/xdiff/xprepare.c)0
-rw-r--r--src/xdiff/xprepare.h (renamed from src/nvim/xdiff/xprepare.h)2
-rw-r--r--src/xdiff/xtypes.h (renamed from src/nvim/xdiff/xtypes.h)2
-rw-r--r--src/xdiff/xutils.c (renamed from src/nvim/xdiff/xutils.c)35
-rw-r--r--src/xdiff/xutils.h (renamed from src/nvim/xdiff/xutils.h)2
286 files changed, 50582 insertions, 34531 deletions
diff --git a/src/cjson/fpconv.c b/src/cjson/fpconv.c
new file mode 100644
index 0000000000..b2f7a214c2
--- /dev/null
+++ b/src/cjson/fpconv.c
@@ -0,0 +1,211 @@
+/* fpconv - Floating point conversion routines
+ *
+ * Copyright (c) 2011-2012 Mark Pulford <mark@kyne.com.au>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/* JSON uses a '.' decimal separator. strtod() / sprintf() under C libraries
+ * with locale support will break when the decimal separator is a comma.
+ *
+ * fpconv_* will around these issues with a translation buffer if required.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+
+#include "fpconv.h"
+
+/* Workaround for MSVC */
+#ifdef _MSC_VER
+#define inline __inline
+#define snprintf sprintf_s
+#endif
+
+/* Lua CJSON assumes the locale is the same for all threads within a
+ * process and doesn't change after initialisation.
+ *
+ * This avoids the need for per thread storage or expensive checks
+ * for call. */
+static char locale_decimal_point = '.';
+
+/* In theory multibyte decimal_points are possible, but
+ * Lua CJSON only supports UTF-8 and known locales only have
+ * single byte decimal points ([.,]).
+ *
+ * localconv() may not be thread safe (=>crash), and nl_langinfo() is
+ * not supported on some platforms. Use sprintf() instead - if the
+ * locale does change, at least Lua CJSON won't crash. */
+static void fpconv_update_locale(void)
+{
+ char buf[8];
+
+ snprintf(buf, sizeof(buf), "%g", 0.5);
+
+ /* Failing this test might imply the platform has a buggy dtoa
+ * implementation or wide characters */
+ if (buf[0] != '0' || buf[2] != '5' || buf[3] != 0) {
+ fprintf(stderr, "Error: wide characters found or printf() bug.");
+ abort();
+ }
+
+ locale_decimal_point = buf[1];
+}
+
+/* Check for a valid number character: [-+0-9a-yA-Y.]
+ * Eg: -0.6e+5, infinity, 0xF0.F0pF0
+ *
+ * Used to find the probable end of a number. It doesn't matter if
+ * invalid characters are counted - strtod() will find the valid
+ * number if it exists. The risk is that slightly more memory might
+ * be allocated before a parse error occurs. */
+static inline int valid_number_character(char ch)
+{
+ char lower_ch;
+
+ if ('0' <= ch && ch <= '9')
+ return 1;
+ if (ch == '-' || ch == '+' || ch == '.')
+ return 1;
+
+ /* Hex digits, exponent (e), base (p), "infinity",.. */
+ lower_ch = ch | 0x20;
+ if ('a' <= lower_ch && lower_ch <= 'y')
+ return 1;
+
+ return 0;
+}
+
+/* Calculate the size of the buffer required for a strtod locale
+ * conversion. */
+static int strtod_buffer_size(const char *s)
+{
+ const char *p = s;
+
+ while (valid_number_character(*p))
+ p++;
+
+ return p - s;
+}
+
+/* Similar to strtod(), but must be passed the current locale's decimal point
+ * character. Guaranteed to be called at the start of any valid number in a string */
+double fpconv_strtod(const char *nptr, char **endptr)
+{
+ char localbuf[FPCONV_G_FMT_BUFSIZE];
+ char *buf, *endbuf, *dp;
+ int buflen;
+ double value;
+
+ /* System strtod() is fine when decimal point is '.' */
+ if (locale_decimal_point == '.')
+ return strtod(nptr, endptr);
+
+ buflen = strtod_buffer_size(nptr);
+ if (!buflen) {
+ /* No valid characters found, standard strtod() return */
+ *endptr = (char *)nptr;
+ return 0;
+ }
+
+ /* Duplicate number into buffer */
+ if (buflen >= FPCONV_G_FMT_BUFSIZE) {
+ /* Handle unusually large numbers */
+ buf = malloc(buflen + 1);
+ if (!buf) {
+ fprintf(stderr, "Out of memory");
+ abort();
+ }
+ } else {
+ /* This is the common case.. */
+ buf = localbuf;
+ }
+ memcpy(buf, nptr, buflen);
+ buf[buflen] = 0;
+
+ /* Update decimal point character if found */
+ dp = strchr(buf, '.');
+ if (dp)
+ *dp = locale_decimal_point;
+
+ value = strtod(buf, &endbuf);
+ *endptr = (char *)&nptr[endbuf - buf];
+ if (buflen >= FPCONV_G_FMT_BUFSIZE)
+ free(buf);
+
+ return value;
+}
+
+/* "fmt" must point to a buffer of at least 6 characters */
+static void set_number_format(char *fmt, int precision)
+{
+ int d1, d2, i;
+
+ assert(1 <= precision && precision <= 16);
+
+ /* Create printf format (%.14g) from precision */
+ d1 = precision / 10;
+ d2 = precision % 10;
+ fmt[0] = '%';
+ fmt[1] = '.';
+ i = 2;
+ if (d1) {
+ fmt[i++] = '0' + d1;
+ }
+ fmt[i++] = '0' + d2;
+ fmt[i++] = 'g';
+ fmt[i] = 0;
+}
+
+/* Assumes there is always at least 32 characters available in the target buffer */
+int fpconv_g_fmt(char *str, double num, int precision)
+{
+ char buf[FPCONV_G_FMT_BUFSIZE];
+ char fmt[6];
+ int len;
+ char *b;
+
+ set_number_format(fmt, precision);
+
+ /* Pass through when decimal point character is dot. */
+ if (locale_decimal_point == '.')
+ return snprintf(str, FPCONV_G_FMT_BUFSIZE, fmt, num);
+
+ /* snprintf() to a buffer then translate for other decimal point characters */
+ len = snprintf(buf, FPCONV_G_FMT_BUFSIZE, fmt, num);
+
+ /* Copy into target location. Translate decimal point if required */
+ b = buf;
+ do {
+ *str++ = (*b == locale_decimal_point ? '.' : *b);
+ } while(*b++);
+
+ return len;
+}
+
+void fpconv_init()
+{
+ fpconv_update_locale();
+}
+
+/* vi:ai et sw=4 ts=4:
+ */
diff --git a/src/cjson/fpconv.h b/src/cjson/fpconv.h
new file mode 100644
index 0000000000..6ac97808b6
--- /dev/null
+++ b/src/cjson/fpconv.h
@@ -0,0 +1,22 @@
+/* Lua CJSON floating point conversion routines */
+
+/* Buffer required to store the largest string representation of a double.
+ *
+ * Longest double printed with %.14g is 21 characters long:
+ * -1.7976931348623e+308 */
+# define FPCONV_G_FMT_BUFSIZE 32
+
+#ifdef USE_INTERNAL_FPCONV
+static inline void fpconv_init()
+{
+ /* Do nothing - not required */
+}
+#else
+extern void fpconv_init(void);
+#endif
+
+extern int fpconv_g_fmt(char*, double, int);
+extern double fpconv_strtod(const char*, char**);
+
+/* vi:ai et sw=4 ts=4:
+ */
diff --git a/src/cjson/lua_cjson.c b/src/cjson/lua_cjson.c
new file mode 100644
index 0000000000..92d07963bd
--- /dev/null
+++ b/src/cjson/lua_cjson.c
@@ -0,0 +1,1609 @@
+/* Lua CJSON - JSON support for Lua
+ *
+ * Copyright (c) 2010-2012 Mark Pulford <mark@kyne.com.au>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/* Caveats:
+ * - JSON "null" values are represented as lightuserdata since Lua
+ * tables cannot contain "nil". Compare with cjson.null.
+ * - Invalid UTF-8 characters are not detected and will be passed
+ * untouched. If required, UTF-8 error checking should be done
+ * outside this library.
+ * - Javascript comments are not part of the JSON spec, and are not
+ * currently supported.
+ *
+ * Note: Decoding is slower than encoding. Lua spends significant
+ * time (30%) managing tables when parsing JSON since it is
+ * difficult to know object/array sizes ahead of time.
+ */
+
+#include <assert.h>
+#include <stdint.h>
+#include <string.h>
+#include <math.h>
+#include <limits.h>
+#include <lua.h>
+#include <lauxlib.h>
+
+#include "nvim/lua/executor.h"
+
+#include "lua_cjson.h"
+#include "strbuf.h"
+#include "fpconv.h"
+
+#ifndef CJSON_MODNAME
+#define CJSON_MODNAME "cjson"
+#endif
+
+#ifndef CJSON_VERSION
+#define CJSON_VERSION "2.1.0.9"
+#endif
+
+#ifdef _MSC_VER
+#define snprintf sprintf_s
+
+#ifndef isnan
+#include <float.h>
+#define isnan(x) _isnan(x)
+#endif
+
+#endif
+
+/* Workaround for Solaris platforms missing isinf() */
+#if !defined(isinf) && (defined(USE_INTERNAL_ISINF) || defined(MISSING_ISINF))
+#define isinf(x) (!isnan(x) && isnan((x) - (x)))
+#endif
+
+#define DEFAULT_SPARSE_CONVERT 0
+#define DEFAULT_SPARSE_RATIO 2
+#define DEFAULT_SPARSE_SAFE 10
+#define DEFAULT_ENCODE_MAX_DEPTH 1000
+#define DEFAULT_DECODE_MAX_DEPTH 1000
+#define DEFAULT_ENCODE_INVALID_NUMBERS 0
+#define DEFAULT_DECODE_INVALID_NUMBERS 1
+#define DEFAULT_ENCODE_KEEP_BUFFER 1
+#define DEFAULT_ENCODE_NUMBER_PRECISION 14
+#define DEFAULT_ENCODE_EMPTY_TABLE_AS_OBJECT 0
+#define DEFAULT_DECODE_ARRAY_WITH_ARRAY_MT 0
+#define DEFAULT_ENCODE_ESCAPE_FORWARD_SLASH 1
+
+#ifdef DISABLE_INVALID_NUMBERS
+#undef DEFAULT_DECODE_INVALID_NUMBERS
+#define DEFAULT_DECODE_INVALID_NUMBERS 0
+#endif
+
+#ifdef _MSC_VER
+/* Microsoft C compiler lacks strncasecmp and strcasecmp. */
+#define strncasecmp _strnicmp
+#define strcasecmp _stricmp
+#endif
+
+#if LONG_MAX > ((1UL << 31) - 1)
+#define json_lightudata_mask(ludata) \
+ ((void *) ((uintptr_t) (ludata) & ((1UL << 47) - 1)))
+
+#else
+#define json_lightudata_mask(ludata) (ludata)
+#endif
+
+#if LUA_VERSION_NUM > 501
+#define lua_objlen(L,i) lua_rawlen(L, (i))
+#endif
+
+static const char * const *json_empty_array;
+static const char * const *json_array;
+
+typedef enum {
+ T_OBJ_BEGIN,
+ T_OBJ_END,
+ T_ARR_BEGIN,
+ T_ARR_END,
+ T_STRING,
+ T_NUMBER,
+ T_BOOLEAN,
+ T_NULL,
+ T_COLON,
+ T_COMMA,
+ T_END,
+ T_WHITESPACE,
+ T_ERROR,
+ T_UNKNOWN
+} json_token_type_t;
+
+static const char *json_token_type_name[] = {
+ "T_OBJ_BEGIN",
+ "T_OBJ_END",
+ "T_ARR_BEGIN",
+ "T_ARR_END",
+ "T_STRING",
+ "T_NUMBER",
+ "T_BOOLEAN",
+ "T_NULL",
+ "T_COLON",
+ "T_COMMA",
+ "T_END",
+ "T_WHITESPACE",
+ "T_ERROR",
+ "T_UNKNOWN",
+ NULL
+};
+
+typedef struct {
+ json_token_type_t ch2token[256];
+ char escape2char[256]; /* Decoding */
+
+ /* encode_buf is only allocated and used when
+ * encode_keep_buffer is set */
+ strbuf_t encode_buf;
+
+ int encode_sparse_convert;
+ int encode_sparse_ratio;
+ int encode_sparse_safe;
+ int encode_max_depth;
+ int encode_invalid_numbers; /* 2 => Encode as "null" */
+ int encode_number_precision;
+ int encode_keep_buffer;
+ int encode_empty_table_as_object;
+ int encode_escape_forward_slash;
+
+ int decode_invalid_numbers;
+ int decode_max_depth;
+ int decode_array_with_array_mt;
+} json_config_t;
+
+typedef struct {
+ const char *data;
+ const char *ptr;
+ strbuf_t *tmp; /* Temporary storage for strings */
+ json_config_t *cfg;
+ int current_depth;
+} json_parse_t;
+
+typedef struct {
+ json_token_type_t type;
+ int index;
+ union {
+ const char *string;
+ double number;
+ int boolean;
+ } value;
+ int string_len;
+} json_token_t;
+
+static const char *char2escape[256] = {
+ "\\u0000", "\\u0001", "\\u0002", "\\u0003",
+ "\\u0004", "\\u0005", "\\u0006", "\\u0007",
+ "\\b", "\\t", "\\n", "\\u000b",
+ "\\f", "\\r", "\\u000e", "\\u000f",
+ "\\u0010", "\\u0011", "\\u0012", "\\u0013",
+ "\\u0014", "\\u0015", "\\u0016", "\\u0017",
+ "\\u0018", "\\u0019", "\\u001a", "\\u001b",
+ "\\u001c", "\\u001d", "\\u001e", "\\u001f",
+ NULL, NULL, "\\\"", NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "\\/",
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "\\\\", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "\\u007f",
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+};
+
+/* ===== CONFIGURATION ===== */
+
+static json_config_t *json_fetch_config(lua_State *l)
+{
+ json_config_t *cfg;
+
+ cfg = lua_touserdata(l, lua_upvalueindex(1));
+ if (!cfg)
+ luaL_error(l, "BUG: Unable to fetch CJSON configuration");
+
+ return cfg;
+}
+
+/* Ensure the correct number of arguments have been provided.
+ * Pad with nil to allow other functions to simply check arg[i]
+ * to find whether an argument was provided */
+static json_config_t *json_arg_init(lua_State *l, int args)
+{
+ luaL_argcheck(l, lua_gettop(l) <= args, args + 1,
+ "found too many arguments");
+
+ while (lua_gettop(l) < args)
+ lua_pushnil(l);
+
+ return json_fetch_config(l);
+}
+
+/* Process integer options for configuration functions */
+static int json_integer_option(lua_State *l, int optindex, int *setting,
+ int min, int max)
+{
+ char errmsg[64];
+ int value;
+
+ if (!lua_isnil(l, optindex)) {
+ value = luaL_checkinteger(l, optindex);
+ snprintf(errmsg, sizeof(errmsg), "expected integer between %d and %d", min, max);
+ luaL_argcheck(l, min <= value && value <= max, 1, errmsg);
+ *setting = value;
+ }
+
+ lua_pushinteger(l, *setting);
+
+ return 1;
+}
+
+/* Process enumerated arguments for a configuration function */
+static int json_enum_option(lua_State *l, int optindex, int *setting,
+ const char **options, int bool_true)
+{
+ static const char *bool_options[] = { "off", "on", NULL };
+
+ if (!options) {
+ options = bool_options;
+ bool_true = 1;
+ }
+
+ if (!lua_isnil(l, optindex)) {
+ if (bool_true && lua_isboolean(l, optindex))
+ *setting = lua_toboolean(l, optindex) * bool_true;
+ else
+ *setting = luaL_checkoption(l, optindex, NULL, options);
+ }
+
+ if (bool_true && (*setting == 0 || *setting == bool_true))
+ lua_pushboolean(l, *setting);
+ else
+ lua_pushstring(l, options[*setting]);
+
+ return 1;
+}
+
+/* Configures handling of extremely sparse arrays:
+ * convert: Convert extremely sparse arrays into objects? Otherwise error.
+ * ratio: 0: always allow sparse; 1: never allow sparse; >1: use ratio
+ * safe: Always use an array when the max index <= safe */
+static int json_cfg_encode_sparse_array(lua_State *l)
+{
+ json_config_t *cfg = json_arg_init(l, 3);
+
+ json_enum_option(l, 1, &cfg->encode_sparse_convert, NULL, 1);
+ json_integer_option(l, 2, &cfg->encode_sparse_ratio, 0, INT_MAX);
+ json_integer_option(l, 3, &cfg->encode_sparse_safe, 0, INT_MAX);
+
+ return 3;
+}
+
+/* Configures the maximum number of nested arrays/objects allowed when
+ * encoding */
+static int json_cfg_encode_max_depth(lua_State *l)
+{
+ json_config_t *cfg = json_arg_init(l, 1);
+
+ return json_integer_option(l, 1, &cfg->encode_max_depth, 1, INT_MAX);
+}
+
+/* Configures the maximum number of nested arrays/objects allowed when
+ * encoding */
+static int json_cfg_decode_max_depth(lua_State *l)
+{
+ json_config_t *cfg = json_arg_init(l, 1);
+
+ return json_integer_option(l, 1, &cfg->decode_max_depth, 1, INT_MAX);
+}
+
+/* Configures number precision when converting doubles to text */
+static int json_cfg_encode_number_precision(lua_State *l)
+{
+ json_config_t *cfg = json_arg_init(l, 1);
+
+ return json_integer_option(l, 1, &cfg->encode_number_precision, 1, 16);
+}
+
+/* Configures how to treat empty table when encode lua table */
+static int json_cfg_encode_empty_table_as_object(lua_State *l)
+{
+ json_config_t *cfg = json_arg_init(l, 1);
+
+ return json_enum_option(l, 1, &cfg->encode_empty_table_as_object, NULL, 1);
+}
+
+/* Configures how to decode arrays */
+static int json_cfg_decode_array_with_array_mt(lua_State *l)
+{
+ json_config_t *cfg = json_arg_init(l, 1);
+
+ json_enum_option(l, 1, &cfg->decode_array_with_array_mt, NULL, 1);
+
+ return 1;
+}
+
+/* Configures JSON encoding buffer persistence */
+static int json_cfg_encode_keep_buffer(lua_State *l)
+{
+ json_config_t *cfg = json_arg_init(l, 1);
+ int old_value;
+
+ old_value = cfg->encode_keep_buffer;
+
+ json_enum_option(l, 1, &cfg->encode_keep_buffer, NULL, 1);
+
+ /* Init / free the buffer if the setting has changed */
+ if (old_value ^ cfg->encode_keep_buffer) {
+ if (cfg->encode_keep_buffer)
+ strbuf_init(&cfg->encode_buf, 0);
+ else
+ strbuf_free(&cfg->encode_buf);
+ }
+
+ return 1;
+}
+
+#if defined(DISABLE_INVALID_NUMBERS) && !defined(USE_INTERNAL_FPCONV)
+void json_verify_invalid_number_setting(lua_State *l, int *setting)
+{
+ if (*setting == 1) {
+ *setting = 0;
+ luaL_error(l, "Infinity, NaN, and/or hexadecimal numbers are not supported.");
+ }
+}
+#else
+#define json_verify_invalid_number_setting(l, s) do { } while(0)
+#endif
+
+static int json_cfg_encode_invalid_numbers(lua_State *l)
+{
+ static const char *options[] = { "off", "on", "null", NULL };
+ json_config_t *cfg = json_arg_init(l, 1);
+
+ json_enum_option(l, 1, &cfg->encode_invalid_numbers, options, 1);
+
+ json_verify_invalid_number_setting(l, &cfg->encode_invalid_numbers);
+
+ return 1;
+}
+
+static int json_cfg_decode_invalid_numbers(lua_State *l)
+{
+ json_config_t *cfg = json_arg_init(l, 1);
+
+ json_enum_option(l, 1, &cfg->decode_invalid_numbers, NULL, 1);
+
+ json_verify_invalid_number_setting(l, &cfg->encode_invalid_numbers);
+
+ return 1;
+}
+
+static int json_cfg_encode_escape_forward_slash(lua_State *l)
+{
+ int ret;
+ json_config_t *cfg = json_arg_init(l, 1);
+
+ ret = json_enum_option(l, 1, &cfg->encode_escape_forward_slash, NULL, 1);
+ if (cfg->encode_escape_forward_slash) {
+ char2escape['/'] = "\\/";
+ } else {
+ char2escape['/'] = NULL;
+ }
+ return ret;
+}
+
+static int json_destroy_config(lua_State *l)
+{
+ json_config_t *cfg;
+
+ cfg = lua_touserdata(l, 1);
+ if (cfg)
+ strbuf_free(&cfg->encode_buf);
+ cfg = NULL;
+
+ return 0;
+}
+
+static void json_create_config(lua_State *l)
+{
+ json_config_t *cfg;
+ int i;
+
+ cfg = lua_newuserdata(l, sizeof(*cfg));
+
+ /* Create GC method to clean up strbuf */
+ lua_newtable(l);
+ lua_pushcfunction(l, json_destroy_config);
+ lua_setfield(l, -2, "__gc");
+ lua_setmetatable(l, -2);
+
+ cfg->encode_sparse_convert = DEFAULT_SPARSE_CONVERT;
+ cfg->encode_sparse_ratio = DEFAULT_SPARSE_RATIO;
+ cfg->encode_sparse_safe = DEFAULT_SPARSE_SAFE;
+ cfg->encode_max_depth = DEFAULT_ENCODE_MAX_DEPTH;
+ cfg->decode_max_depth = DEFAULT_DECODE_MAX_DEPTH;
+ cfg->encode_invalid_numbers = DEFAULT_ENCODE_INVALID_NUMBERS;
+ cfg->decode_invalid_numbers = DEFAULT_DECODE_INVALID_NUMBERS;
+ cfg->encode_keep_buffer = DEFAULT_ENCODE_KEEP_BUFFER;
+ cfg->encode_number_precision = DEFAULT_ENCODE_NUMBER_PRECISION;
+ cfg->encode_empty_table_as_object = DEFAULT_ENCODE_EMPTY_TABLE_AS_OBJECT;
+ cfg->decode_array_with_array_mt = DEFAULT_DECODE_ARRAY_WITH_ARRAY_MT;
+ cfg->encode_escape_forward_slash = DEFAULT_ENCODE_ESCAPE_FORWARD_SLASH;
+
+#if DEFAULT_ENCODE_KEEP_BUFFER > 0
+ strbuf_init(&cfg->encode_buf, 0);
+#endif
+
+ /* Decoding init */
+
+ /* Tag all characters as an error */
+ for (i = 0; i < 256; i++)
+ cfg->ch2token[i] = T_ERROR;
+
+ /* Set tokens that require no further processing */
+ cfg->ch2token['{'] = T_OBJ_BEGIN;
+ cfg->ch2token['}'] = T_OBJ_END;
+ cfg->ch2token['['] = T_ARR_BEGIN;
+ cfg->ch2token[']'] = T_ARR_END;
+ cfg->ch2token[','] = T_COMMA;
+ cfg->ch2token[':'] = T_COLON;
+ cfg->ch2token['\0'] = T_END;
+ cfg->ch2token[' '] = T_WHITESPACE;
+ cfg->ch2token['\t'] = T_WHITESPACE;
+ cfg->ch2token['\n'] = T_WHITESPACE;
+ cfg->ch2token['\r'] = T_WHITESPACE;
+
+ /* Update characters that require further processing */
+ cfg->ch2token['f'] = T_UNKNOWN; /* false? */
+ cfg->ch2token['i'] = T_UNKNOWN; /* inf, ininity? */
+ cfg->ch2token['I'] = T_UNKNOWN;
+ cfg->ch2token['n'] = T_UNKNOWN; /* null, nan? */
+ cfg->ch2token['N'] = T_UNKNOWN;
+ cfg->ch2token['t'] = T_UNKNOWN; /* true? */
+ cfg->ch2token['"'] = T_UNKNOWN; /* string? */
+ cfg->ch2token['+'] = T_UNKNOWN; /* number? */
+ cfg->ch2token['-'] = T_UNKNOWN;
+ for (i = 0; i < 10; i++)
+ cfg->ch2token['0' + i] = T_UNKNOWN;
+
+ /* Lookup table for parsing escape characters */
+ for (i = 0; i < 256; i++)
+ cfg->escape2char[i] = 0; /* String error */
+ cfg->escape2char['"'] = '"';
+ cfg->escape2char['\\'] = '\\';
+ cfg->escape2char['/'] = '/';
+ cfg->escape2char['b'] = '\b';
+ cfg->escape2char['t'] = '\t';
+ cfg->escape2char['n'] = '\n';
+ cfg->escape2char['f'] = '\f';
+ cfg->escape2char['r'] = '\r';
+ cfg->escape2char['u'] = 'u'; /* Unicode parsing required */
+}
+
+/* ===== ENCODING ===== */
+
+static void json_encode_exception(lua_State *l, json_config_t *cfg, strbuf_t *json, int lindex,
+ const char *reason)
+{
+ if (!cfg->encode_keep_buffer)
+ strbuf_free(json);
+ luaL_error(l, "Cannot serialise %s: %s",
+ lua_typename(l, lua_type(l, lindex)), reason);
+}
+
+/* json_append_string args:
+ * - lua_State
+ * - JSON strbuf
+ * - String (Lua stack index)
+ *
+ * Returns nothing. Doesn't remove string from Lua stack */
+static void json_append_string(lua_State *l, strbuf_t *json, int lindex)
+{
+ const char *escstr;
+ unsigned i;
+ const char *str;
+ size_t len;
+
+ str = lua_tolstring(l, lindex, &len);
+
+ /* Worst case is len * 6 (all unicode escapes).
+ * This buffer is reused constantly for small strings
+ * If there are any excess pages, they won't be hit anyway.
+ * This gains ~5% speedup. */
+ strbuf_ensure_empty_length(json, len * 6 + 2);
+
+ strbuf_append_char_unsafe(json, '\"');
+ for (i = 0; i < len; i++) {
+ escstr = char2escape[(unsigned char)str[i]];
+ if (escstr)
+ strbuf_append_string(json, escstr);
+ else
+ strbuf_append_char_unsafe(json, str[i]);
+ }
+ strbuf_append_char_unsafe(json, '\"');
+}
+
+/* Find the size of the array on the top of the Lua stack
+ * -1 object (not a pure array)
+ * >=0 elements in array
+ */
+static int lua_array_length(lua_State *l, json_config_t *cfg, strbuf_t *json)
+{
+ double k;
+ int max;
+ int items;
+
+ max = 0;
+ items = 0;
+
+ lua_pushnil(l);
+ /* table, startkey */
+ while (lua_next(l, -2) != 0) {
+ /* table, key, value */
+ if (lua_type(l, -2) == LUA_TNUMBER &&
+ (k = lua_tonumber(l, -2))) {
+ /* Integer >= 1 ? */
+ if (floor(k) == k && k >= 1) {
+ if (k > max)
+ max = k;
+ items++;
+ lua_pop(l, 1);
+ continue;
+ }
+ }
+
+ /* Must not be an array (non integer key) */
+ lua_pop(l, 2);
+ return -1;
+ }
+
+ /* Encode excessively sparse arrays as objects (if enabled) */
+ if (cfg->encode_sparse_ratio > 0 &&
+ max > items * cfg->encode_sparse_ratio &&
+ max > cfg->encode_sparse_safe) {
+ if (!cfg->encode_sparse_convert)
+ json_encode_exception(l, cfg, json, -1, "excessively sparse array");
+
+ return -1;
+ }
+
+ return max;
+}
+
+static void json_check_encode_depth(lua_State *l, json_config_t *cfg,
+ int current_depth, strbuf_t *json)
+{
+ /* Ensure there are enough slots free to traverse a table (key,
+ * value) and push a string for a potential error message.
+ *
+ * Unlike "decode", the key and value are still on the stack when
+ * lua_checkstack() is called. Hence an extra slot for luaL_error()
+ * below is required just in case the next check to lua_checkstack()
+ * fails.
+ *
+ * While this won't cause a crash due to the EXTRA_STACK reserve
+ * slots, it would still be an improper use of the API. */
+ if (current_depth <= cfg->encode_max_depth && lua_checkstack(l, 3))
+ return;
+
+ if (!cfg->encode_keep_buffer)
+ strbuf_free(json);
+
+ luaL_error(l, "Cannot serialise, excessive nesting (%d)",
+ current_depth);
+}
+
+static void json_append_data(lua_State *l, json_config_t *cfg,
+ int current_depth, strbuf_t *json);
+
+/* json_append_array args:
+ * - lua_State
+ * - JSON strbuf
+ * - Size of passwd Lua array (top of stack) */
+static void json_append_array(lua_State *l, json_config_t *cfg, int current_depth,
+ strbuf_t *json, int array_length)
+{
+ int comma, i;
+
+ strbuf_append_char(json, '[');
+
+ comma = 0;
+ for (i = 1; i <= array_length; i++) {
+ if (comma)
+ strbuf_append_char(json, ',');
+ else
+ comma = 1;
+
+ lua_rawgeti(l, -1, i);
+ json_append_data(l, cfg, current_depth, json);
+ lua_pop(l, 1);
+ }
+
+ strbuf_append_char(json, ']');
+}
+
+static void json_append_number(lua_State *l, json_config_t *cfg,
+ strbuf_t *json, int lindex)
+{
+ double num = lua_tonumber(l, lindex);
+ int len;
+
+ if (cfg->encode_invalid_numbers == 0) {
+ /* Prevent encoding invalid numbers */
+ if (isinf(num) || isnan(num))
+ json_encode_exception(l, cfg, json, lindex,
+ "must not be NaN or Infinity");
+ } else if (cfg->encode_invalid_numbers == 1) {
+ /* Encode NaN/Infinity separately to ensure Javascript compatible
+ * values are used. */
+ if (isnan(num)) {
+ strbuf_append_mem(json, "NaN", 3);
+ return;
+ }
+ if (isinf(num)) {
+ if (num < 0)
+ strbuf_append_mem(json, "-Infinity", 9);
+ else
+ strbuf_append_mem(json, "Infinity", 8);
+ return;
+ }
+ } else {
+ /* Encode invalid numbers as "null" */
+ if (isinf(num) || isnan(num)) {
+ strbuf_append_mem(json, "null", 4);
+ return;
+ }
+ }
+
+ strbuf_ensure_empty_length(json, FPCONV_G_FMT_BUFSIZE);
+ len = fpconv_g_fmt(strbuf_empty_ptr(json), num, cfg->encode_number_precision);
+ strbuf_extend_length(json, len);
+}
+
+static void json_append_object(lua_State *l, json_config_t *cfg,
+ int current_depth, strbuf_t *json)
+{
+ int comma, keytype;
+
+ /* Object */
+ strbuf_append_char(json, '{');
+
+ lua_pushnil(l);
+ /* table, startkey */
+ comma = 0;
+ while (lua_next(l, -2) != 0) {
+ if (comma)
+ strbuf_append_char(json, ',');
+ else
+ comma = 1;
+
+ /* table, key, value */
+ keytype = lua_type(l, -2);
+ if (keytype == LUA_TNUMBER) {
+ strbuf_append_char(json, '"');
+ json_append_number(l, cfg, json, -2);
+ strbuf_append_mem(json, "\":", 2);
+ } else if (keytype == LUA_TSTRING) {
+ json_append_string(l, json, -2);
+ strbuf_append_char(json, ':');
+ } else {
+ json_encode_exception(l, cfg, json, -2,
+ "table key must be a number or string");
+ /* never returns */
+ }
+
+ /* table, key, value */
+ json_append_data(l, cfg, current_depth, json);
+ lua_pop(l, 1);
+ /* table, key */
+ }
+
+ strbuf_append_char(json, '}');
+}
+
+/* Serialise Lua data into JSON string. */
+static void json_append_data(lua_State *l, json_config_t *cfg,
+ int current_depth, strbuf_t *json)
+{
+ int len;
+ int as_array = 0;
+ int as_empty_dict = 0;
+ int has_metatable;
+
+ switch (lua_type(l, -1)) {
+ case LUA_TSTRING:
+ json_append_string(l, json, -1);
+ break;
+ case LUA_TNUMBER:
+ json_append_number(l, cfg, json, -1);
+ break;
+ case LUA_TBOOLEAN:
+ if (lua_toboolean(l, -1))
+ strbuf_append_mem(json, "true", 4);
+ else
+ strbuf_append_mem(json, "false", 5);
+ break;
+ case LUA_TTABLE:
+ current_depth++;
+ json_check_encode_depth(l, cfg, current_depth, json);
+
+ has_metatable = lua_getmetatable(l, -1);
+
+ if (has_metatable) {
+
+ nlua_pushref(l, nlua_empty_dict_ref);
+ if (lua_rawequal(l, -2, -1)) {
+ as_empty_dict = true;
+ } else {
+ lua_pop(l, 1);
+ lua_pushlightuserdata(l, json_lightudata_mask(&json_array));
+ lua_rawget(l, LUA_REGISTRYINDEX);
+ as_array = lua_rawequal(l, -1, -2);
+ }
+ lua_pop(l, 2);
+ }
+
+ if (as_array) {
+ len = lua_objlen(l, -1);
+ json_append_array(l, cfg, current_depth, json, len);
+ } else {
+ len = lua_array_length(l, cfg, json);
+
+ if (len > 0 || (len == 0 && !cfg->encode_empty_table_as_object && !as_empty_dict)) {
+ json_append_array(l, cfg, current_depth, json, len);
+ } else {
+ if (has_metatable) {
+ lua_getmetatable(l, -1);
+ lua_pushlightuserdata(l, json_lightudata_mask(
+ &json_empty_array));
+ lua_rawget(l, LUA_REGISTRYINDEX);
+ as_array = lua_rawequal(l, -1, -2);
+ lua_pop(l, 2); /* pop pointer + metatable */
+ if (as_array) {
+ json_append_array(l, cfg, current_depth, json, 0);
+ break;
+ }
+ }
+ json_append_object(l, cfg, current_depth, json);
+ }
+ }
+ break;
+ case LUA_TNIL:
+ strbuf_append_mem(json, "null", 4);
+ break;
+ case LUA_TLIGHTUSERDATA:
+ if (lua_touserdata(l, -1) == &json_array) {
+ json_append_array(l, cfg, current_depth, json, 0);
+ }
+ break;
+ case LUA_TUSERDATA:
+ nlua_pushref(l, nlua_nil_ref);
+ bool is_nil = lua_rawequal(l, -2, -1);
+ lua_pop(l, 1);
+ if (is_nil) {
+ strbuf_append_mem(json, "null", 4);
+ break;
+ } else {
+ FALLTHROUGH;
+ }
+ default:
+ /* Remaining types (LUA_TFUNCTION, LUA_TUSERDATA, LUA_TTHREAD,
+ * and LUA_TLIGHTUSERDATA) cannot be serialised */
+ json_encode_exception(l, cfg, json, -1, "type not supported");
+ /* never returns */
+ }
+}
+
+static int json_encode(lua_State *l)
+{
+ json_config_t *cfg = json_fetch_config(l);
+ strbuf_t local_encode_buf;
+ strbuf_t *encode_buf;
+ char *json;
+ int len;
+
+ luaL_argcheck(l, lua_gettop(l) == 1, 1, "expected 1 argument");
+
+ if (!cfg->encode_keep_buffer) {
+ /* Use private buffer */
+ encode_buf = &local_encode_buf;
+ strbuf_init(encode_buf, 0);
+ } else {
+ /* Reuse existing buffer */
+ encode_buf = &cfg->encode_buf;
+ strbuf_reset(encode_buf);
+ }
+
+ json_append_data(l, cfg, 0, encode_buf);
+ json = strbuf_string(encode_buf, &len);
+
+ lua_pushlstring(l, json, len);
+
+ if (!cfg->encode_keep_buffer)
+ strbuf_free(encode_buf);
+
+ return 1;
+}
+
+/* ===== DECODING ===== */
+
+static void json_process_value(lua_State *l, json_parse_t *json,
+ json_token_t *token);
+
+static int hexdigit2int(char hex)
+{
+ if ('0' <= hex && hex <= '9')
+ return hex - '0';
+
+ /* Force lowercase */
+ hex |= 0x20;
+ if ('a' <= hex && hex <= 'f')
+ return 10 + hex - 'a';
+
+ return -1;
+}
+
+static int decode_hex4(const char *hex)
+{
+ int digit[4];
+ int i;
+
+ /* Convert ASCII hex digit to numeric digit
+ * Note: this returns an error for invalid hex digits, including
+ * NULL */
+ for (i = 0; i < 4; i++) {
+ digit[i] = hexdigit2int(hex[i]);
+ if (digit[i] < 0) {
+ return -1;
+ }
+ }
+
+ return (digit[0] << 12) +
+ (digit[1] << 8) +
+ (digit[2] << 4) +
+ digit[3];
+}
+
+/* Converts a Unicode codepoint to UTF-8.
+ * Returns UTF-8 string length, and up to 4 bytes in *utf8 */
+static int codepoint_to_utf8(char *utf8, int codepoint)
+{
+ /* 0xxxxxxx */
+ if (codepoint <= 0x7F) {
+ utf8[0] = codepoint;
+ return 1;
+ }
+
+ /* 110xxxxx 10xxxxxx */
+ if (codepoint <= 0x7FF) {
+ utf8[0] = (codepoint >> 6) | 0xC0;
+ utf8[1] = (codepoint & 0x3F) | 0x80;
+ return 2;
+ }
+
+ /* 1110xxxx 10xxxxxx 10xxxxxx */
+ if (codepoint <= 0xFFFF) {
+ utf8[0] = (codepoint >> 12) | 0xE0;
+ utf8[1] = ((codepoint >> 6) & 0x3F) | 0x80;
+ utf8[2] = (codepoint & 0x3F) | 0x80;
+ return 3;
+ }
+
+ /* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
+ if (codepoint <= 0x1FFFFF) {
+ utf8[0] = (codepoint >> 18) | 0xF0;
+ utf8[1] = ((codepoint >> 12) & 0x3F) | 0x80;
+ utf8[2] = ((codepoint >> 6) & 0x3F) | 0x80;
+ utf8[3] = (codepoint & 0x3F) | 0x80;
+ return 4;
+ }
+
+ return 0;
+}
+
+
+/* Called when index pointing to beginning of UTF-16 code escape: \uXXXX
+ * \u is guaranteed to exist, but the remaining hex characters may be
+ * missing.
+ * Translate to UTF-8 and append to temporary token string.
+ * Must advance index to the next character to be processed.
+ * Returns: 0 success
+ * -1 error
+ */
+static int json_append_unicode_escape(json_parse_t *json)
+{
+ char utf8[4]; /* Surrogate pairs require 4 UTF-8 bytes */
+ int codepoint;
+ int surrogate_low;
+ int len;
+ int escape_len = 6;
+
+ /* Fetch UTF-16 code unit */
+ codepoint = decode_hex4(json->ptr + 2);
+ if (codepoint < 0)
+ return -1;
+
+ /* UTF-16 surrogate pairs take the following 2 byte form:
+ * 11011 x yyyyyyyyyy
+ * When x = 0: y is the high 10 bits of the codepoint
+ * x = 1: y is the low 10 bits of the codepoint
+ *
+ * Check for a surrogate pair (high or low) */
+ if ((codepoint & 0xF800) == 0xD800) {
+ /* Error if the 1st surrogate is not high */
+ if (codepoint & 0x400)
+ return -1;
+
+ /* Ensure the next code is a unicode escape */
+ if (*(json->ptr + escape_len) != '\\' ||
+ *(json->ptr + escape_len + 1) != 'u') {
+ return -1;
+ }
+
+ /* Fetch the next codepoint */
+ surrogate_low = decode_hex4(json->ptr + 2 + escape_len);
+ if (surrogate_low < 0)
+ return -1;
+
+ /* Error if the 2nd code is not a low surrogate */
+ if ((surrogate_low & 0xFC00) != 0xDC00)
+ return -1;
+
+ /* Calculate Unicode codepoint */
+ codepoint = (codepoint & 0x3FF) << 10;
+ surrogate_low &= 0x3FF;
+ codepoint = (codepoint | surrogate_low) + 0x10000;
+ escape_len = 12;
+ }
+
+ /* Convert codepoint to UTF-8 */
+ len = codepoint_to_utf8(utf8, codepoint);
+ if (!len)
+ return -1;
+
+ /* Append bytes and advance parse index */
+ strbuf_append_mem_unsafe(json->tmp, utf8, len);
+ json->ptr += escape_len;
+
+ return 0;
+}
+
+static void json_set_token_error(json_token_t *token, json_parse_t *json,
+ const char *errtype)
+{
+ token->type = T_ERROR;
+ token->index = json->ptr - json->data;
+ token->value.string = errtype;
+}
+
+static void json_next_string_token(json_parse_t *json, json_token_t *token)
+{
+ char *escape2char = json->cfg->escape2char;
+ char ch;
+
+ /* Caller must ensure a string is next */
+ assert(*json->ptr == '"');
+
+ /* Skip " */
+ json->ptr++;
+
+ /* json->tmp is the temporary strbuf used to accumulate the
+ * decoded string value.
+ * json->tmp is sized to handle JSON containing only a string value.
+ */
+ strbuf_reset(json->tmp);
+
+ while ((ch = *json->ptr) != '"') {
+ if (!ch) {
+ /* Premature end of the string */
+ json_set_token_error(token, json, "unexpected end of string");
+ return;
+ }
+
+ /* Handle escapes */
+ if (ch == '\\') {
+ /* Fetch escape character */
+ ch = *(json->ptr + 1);
+
+ /* Translate escape code and append to tmp string */
+ ch = escape2char[(unsigned char)ch];
+ if (ch == 'u') {
+ if (json_append_unicode_escape(json) == 0)
+ continue;
+
+ json_set_token_error(token, json,
+ "invalid unicode escape code");
+ return;
+ }
+ if (!ch) {
+ json_set_token_error(token, json, "invalid escape code");
+ return;
+ }
+
+ /* Skip '\' */
+ json->ptr++;
+ }
+ /* Append normal character or translated single character
+ * Unicode escapes are handled above */
+ strbuf_append_char_unsafe(json->tmp, ch);
+ json->ptr++;
+ }
+ json->ptr++; /* Eat final quote (") */
+
+ strbuf_ensure_null(json->tmp);
+
+ token->type = T_STRING;
+ token->value.string = strbuf_string(json->tmp, &token->string_len);
+}
+
+/* JSON numbers should take the following form:
+ * -?(0|[1-9]|[1-9][0-9]+)(.[0-9]+)?([eE][-+]?[0-9]+)?
+ *
+ * json_next_number_token() uses strtod() which allows other forms:
+ * - numbers starting with '+'
+ * - NaN, -NaN, infinity, -infinity
+ * - hexadecimal numbers
+ * - numbers with leading zeros
+ *
+ * json_is_invalid_number() detects "numbers" which may pass strtod()'s
+ * error checking, but should not be allowed with strict JSON.
+ *
+ * json_is_invalid_number() may pass numbers which cause strtod()
+ * to generate an error.
+ */
+static int json_is_invalid_number(json_parse_t *json)
+{
+ const char *p = json->ptr;
+
+ /* Reject numbers starting with + */
+ if (*p == '+')
+ return 1;
+
+ /* Skip minus sign if it exists */
+ if (*p == '-')
+ p++;
+
+ /* Reject numbers starting with 0x, or leading zeros */
+ if (*p == '0') {
+ int ch2 = *(p + 1);
+
+ if ((ch2 | 0x20) == 'x' || /* Hex */
+ ('0' <= ch2 && ch2 <= '9')) /* Leading zero */
+ return 1;
+
+ return 0;
+ } else if (*p <= '9') {
+ return 0; /* Ordinary number */
+ }
+
+ /* Reject inf/nan */
+ if (!strncasecmp(p, "inf", 3))
+ return 1;
+ if (!strncasecmp(p, "nan", 3))
+ return 1;
+
+ /* Pass all other numbers which may still be invalid, but
+ * strtod() will catch them. */
+ return 0;
+}
+
+static void json_next_number_token(json_parse_t *json, json_token_t *token)
+{
+ char *endptr;
+
+ token->type = T_NUMBER;
+ token->value.number = fpconv_strtod(json->ptr, &endptr);
+ if (json->ptr == endptr)
+ json_set_token_error(token, json, "invalid number");
+ else
+ json->ptr = endptr; /* Skip the processed number */
+
+ return;
+}
+
+/* Fills in the token struct.
+ * T_STRING will return a pointer to the json_parse_t temporary string
+ * T_ERROR will leave the json->ptr pointer at the error.
+ */
+static void json_next_token(json_parse_t *json, json_token_t *token)
+{
+ const json_token_type_t *ch2token = json->cfg->ch2token;
+ int ch;
+
+ /* Eat whitespace. */
+ while (1) {
+ ch = (unsigned char)*(json->ptr);
+ token->type = ch2token[ch];
+ if (token->type != T_WHITESPACE)
+ break;
+ json->ptr++;
+ }
+
+ /* Store location of new token. Required when throwing errors
+ * for unexpected tokens (syntax errors). */
+ token->index = json->ptr - json->data;
+
+ /* Don't advance the pointer for an error or the end */
+ if (token->type == T_ERROR) {
+ json_set_token_error(token, json, "invalid token");
+ return;
+ }
+
+ if (token->type == T_END) {
+ return;
+ }
+
+ /* Found a known single character token, advance index and return */
+ if (token->type != T_UNKNOWN) {
+ json->ptr++;
+ return;
+ }
+
+ /* Process characters which triggered T_UNKNOWN
+ *
+ * Must use strncmp() to match the front of the JSON string.
+ * JSON identifier must be lowercase.
+ * When strict_numbers if disabled, either case is allowed for
+ * Infinity/NaN (since we are no longer following the spec..) */
+ if (ch == '"') {
+ json_next_string_token(json, token);
+ return;
+ } else if (ch == '-' || ('0' <= ch && ch <= '9')) {
+ if (!json->cfg->decode_invalid_numbers && json_is_invalid_number(json)) {
+ json_set_token_error(token, json, "invalid number");
+ return;
+ }
+ json_next_number_token(json, token);
+ return;
+ } else if (!strncmp(json->ptr, "true", 4)) {
+ token->type = T_BOOLEAN;
+ token->value.boolean = 1;
+ json->ptr += 4;
+ return;
+ } else if (!strncmp(json->ptr, "false", 5)) {
+ token->type = T_BOOLEAN;
+ token->value.boolean = 0;
+ json->ptr += 5;
+ return;
+ } else if (!strncmp(json->ptr, "null", 4)) {
+ token->type = T_NULL;
+ json->ptr += 4;
+ return;
+ } else if (json->cfg->decode_invalid_numbers &&
+ json_is_invalid_number(json)) {
+ /* When decode_invalid_numbers is enabled, only attempt to process
+ * numbers we know are invalid JSON (Inf, NaN, hex)
+ * This is required to generate an appropriate token error,
+ * otherwise all bad tokens will register as "invalid number"
+ */
+ json_next_number_token(json, token);
+ return;
+ }
+
+ /* Token starts with t/f/n but isn't recognised above. */
+ json_set_token_error(token, json, "invalid token");
+}
+
+/* This function does not return.
+ * DO NOT CALL WITH DYNAMIC MEMORY ALLOCATED.
+ * The only supported exception is the temporary parser string
+ * json->tmp struct.
+ * json and token should exist on the stack somewhere.
+ * luaL_error() will long_jmp and release the stack */
+static void json_throw_parse_error(lua_State *l, json_parse_t *json,
+ const char *exp, json_token_t *token)
+{
+ const char *found;
+
+ strbuf_free(json->tmp);
+
+ if (token->type == T_ERROR)
+ found = token->value.string;
+ else
+ found = json_token_type_name[token->type];
+
+ /* Note: token->index is 0 based, display starting from 1 */
+ luaL_error(l, "Expected %s but found %s at character %d",
+ exp, found, token->index + 1);
+}
+
+static inline void json_decode_ascend(json_parse_t *json)
+{
+ json->current_depth--;
+}
+
+static void json_decode_descend(lua_State *l, json_parse_t *json, int slots)
+{
+ json->current_depth++;
+
+ if (json->current_depth <= json->cfg->decode_max_depth &&
+ lua_checkstack(l, slots)) {
+ return;
+ }
+
+ strbuf_free(json->tmp);
+ luaL_error(l, "Found too many nested data structures (%d) at character %d",
+ json->current_depth, json->ptr - json->data);
+}
+
+static void json_parse_object_context(lua_State *l, json_parse_t *json)
+{
+ json_token_t token;
+
+ /* 3 slots required:
+ * .., table, key, value */
+ json_decode_descend(l, json, 3);
+
+ lua_newtable(l);
+
+ json_next_token(json, &token);
+
+ /* Handle empty objects */
+ if (token.type == T_OBJ_END) {
+ nlua_pushref(l, nlua_empty_dict_ref); \
+ lua_setmetatable(l, -2); \
+ json_decode_ascend(json);
+ return;
+ }
+
+ while (1) {
+ if (token.type != T_STRING)
+ json_throw_parse_error(l, json, "object key string", &token);
+
+ /* Push key */
+ lua_pushlstring(l, token.value.string, token.string_len);
+
+ json_next_token(json, &token);
+ if (token.type != T_COLON)
+ json_throw_parse_error(l, json, "colon", &token);
+
+ /* Fetch value */
+ json_next_token(json, &token);
+ json_process_value(l, json, &token);
+
+ /* Set key = value */
+ lua_rawset(l, -3);
+
+ json_next_token(json, &token);
+
+ if (token.type == T_OBJ_END) {
+ json_decode_ascend(json);
+ return;
+ }
+
+ if (token.type != T_COMMA)
+ json_throw_parse_error(l, json, "comma or object end", &token);
+
+ json_next_token(json, &token);
+ }
+}
+
+/* Handle the array context */
+static void json_parse_array_context(lua_State *l, json_parse_t *json)
+{
+ json_token_t token;
+ int i;
+
+ /* 2 slots required:
+ * .., table, value */
+ json_decode_descend(l, json, 2);
+
+ lua_newtable(l);
+
+ /* set array_mt on the table at the top of the stack */
+ if (json->cfg->decode_array_with_array_mt) {
+ lua_pushlightuserdata(l, json_lightudata_mask(&json_array));
+ lua_rawget(l, LUA_REGISTRYINDEX);
+ lua_setmetatable(l, -2);
+ }
+
+ json_next_token(json, &token);
+
+ /* Handle empty arrays */
+ if (token.type == T_ARR_END) {
+ json_decode_ascend(json);
+ return;
+ }
+
+ for (i = 1; ; i++) {
+ json_process_value(l, json, &token);
+ lua_rawseti(l, -2, i); /* arr[i] = value */
+
+ json_next_token(json, &token);
+
+ if (token.type == T_ARR_END) {
+ json_decode_ascend(json);
+ return;
+ }
+
+ if (token.type != T_COMMA)
+ json_throw_parse_error(l, json, "comma or array end", &token);
+
+ json_next_token(json, &token);
+ }
+}
+
+/* Handle the "value" context */
+static void json_process_value(lua_State *l, json_parse_t *json,
+ json_token_t *token)
+{
+ switch (token->type) {
+ case T_STRING:
+ lua_pushlstring(l, token->value.string, token->string_len);
+ break;;
+ case T_NUMBER:
+ lua_pushnumber(l, token->value.number);
+ break;;
+ case T_BOOLEAN:
+ lua_pushboolean(l, token->value.boolean);
+ break;;
+ case T_OBJ_BEGIN:
+ json_parse_object_context(l, json);
+ break;;
+ case T_ARR_BEGIN:
+ json_parse_array_context(l, json);
+ break;;
+ case T_NULL:
+ nlua_pushref(l, nlua_nil_ref);
+ break;;
+ default:
+ json_throw_parse_error(l, json, "value", token);
+ }
+}
+
+static int json_decode(lua_State *l)
+{
+ json_parse_t json;
+ json_token_t token;
+ size_t json_len;
+
+ luaL_argcheck(l, lua_gettop(l) == 1, 1, "expected 1 argument");
+
+ json.cfg = json_fetch_config(l);
+ json.data = luaL_checklstring(l, 1, &json_len);
+ json.current_depth = 0;
+ json.ptr = json.data;
+
+ /* Detect Unicode other than UTF-8 (see RFC 4627, Sec 3)
+ *
+ * CJSON can support any simple data type, hence only the first
+ * character is guaranteed to be ASCII (at worst: '"'). This is
+ * still enough to detect whether the wrong encoding is in use. */
+ if (json_len >= 2 && (!json.data[0] || !json.data[1]))
+ luaL_error(l, "JSON parser does not support UTF-16 or UTF-32");
+
+ /* Ensure the temporary buffer can hold the entire string.
+ * This means we no longer need to do length checks since the decoded
+ * string must be smaller than the entire json string */
+ json.tmp = strbuf_new(json_len);
+
+ json_next_token(&json, &token);
+ json_process_value(l, &json, &token);
+
+ /* Ensure there is no more input left */
+ json_next_token(&json, &token);
+
+ if (token.type != T_END)
+ json_throw_parse_error(l, &json, "the end", &token);
+
+ strbuf_free(json.tmp);
+
+ return 1;
+}
+
+/* ===== INITIALISATION ===== */
+
+#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 502
+/* Compatibility for Lua 5.1 and older LuaJIT.
+ *
+ * compat_luaL_setfuncs() is used to create a module table where the functions
+ * have json_config_t as their first upvalue. Code borrowed from Lua 5.2
+ * source's luaL_setfuncs().
+ */
+static void compat_luaL_setfuncs(lua_State *l, const luaL_Reg *reg, int nup)
+{
+ int i;
+
+ luaL_checkstack(l, nup, "too many upvalues");
+ for (; reg->name != NULL; reg++) { /* fill the table with given functions */
+ for (i = 0; i < nup; i++) /* copy upvalues to the top */
+ lua_pushvalue(l, -nup);
+ lua_pushcclosure(l, reg->func, nup); /* closure with those upvalues */
+ lua_setfield(l, -(nup + 2), reg->name);
+ }
+ lua_pop(l, nup); /* remove upvalues */
+}
+#else
+#define compat_luaL_setfuncs(L, reg, nup) luaL_setfuncs(L, reg, nup)
+#endif
+
+/* Call target function in protected mode with all supplied args.
+ * Assumes target function only returns a single non-nil value.
+ * Convert and return thrown errors as: nil, "error message" */
+static int json_protect_conversion(lua_State *l)
+{
+ int err;
+
+ /* Deliberately throw an error for invalid arguments */
+ luaL_argcheck(l, lua_gettop(l) == 1, 1, "expected 1 argument");
+
+ /* pcall() the function stored as upvalue(1) */
+ lua_pushvalue(l, lua_upvalueindex(1));
+ lua_insert(l, 1);
+ err = lua_pcall(l, 1, 1, 0);
+ if (!err)
+ return 1;
+
+ if (err == LUA_ERRRUN) {
+ lua_pushnil(l);
+ lua_insert(l, -2);
+ return 2;
+ }
+
+ /* Since we are not using a custom error handler, the only remaining
+ * errors are memory related */
+ return luaL_error(l, "Memory allocation error in CJSON protected call");
+}
+
+/* Return cjson module table */
+int lua_cjson_new(lua_State *l)
+{
+ luaL_Reg reg[] = {
+ { "encode", json_encode },
+ { "decode", json_decode },
+ { "encode_empty_table_as_object", json_cfg_encode_empty_table_as_object },
+ { "decode_array_with_array_mt", json_cfg_decode_array_with_array_mt },
+ { "encode_sparse_array", json_cfg_encode_sparse_array },
+ { "encode_max_depth", json_cfg_encode_max_depth },
+ { "decode_max_depth", json_cfg_decode_max_depth },
+ { "encode_number_precision", json_cfg_encode_number_precision },
+ { "encode_keep_buffer", json_cfg_encode_keep_buffer },
+ { "encode_invalid_numbers", json_cfg_encode_invalid_numbers },
+ { "decode_invalid_numbers", json_cfg_decode_invalid_numbers },
+ { "encode_escape_forward_slash", json_cfg_encode_escape_forward_slash },
+ { "new", lua_cjson_new },
+ { NULL, NULL }
+ };
+
+ /* Initialise number conversions */
+ fpconv_init();
+
+ /* Test if array metatables are in registry */
+ lua_pushlightuserdata(l, json_lightudata_mask(&json_empty_array));
+ lua_rawget(l, LUA_REGISTRYINDEX);
+ if (lua_isnil(l, -1)) {
+ /* Create array metatables.
+ *
+ * If multiple calls to lua_cjson_new() are made,
+ * this prevents overriding the tables at the given
+ * registry's index with a new one.
+ */
+ lua_pop(l, 1);
+
+ /* empty_array_mt */
+ lua_pushlightuserdata(l, json_lightudata_mask(&json_empty_array));
+ lua_newtable(l);
+ lua_rawset(l, LUA_REGISTRYINDEX);
+
+ /* array_mt */
+ lua_pushlightuserdata(l, json_lightudata_mask(&json_array));
+ lua_newtable(l);
+ lua_rawset(l, LUA_REGISTRYINDEX);
+ }
+
+ /* cjson module table */
+ lua_newtable(l);
+
+ /* Register functions with config data as upvalue */
+ json_create_config(l);
+ compat_luaL_setfuncs(l, reg, 1);
+
+ /* Set cjson.null */
+ nlua_pushref(l, nlua_nil_ref);
+ lua_setfield(l, -2, "null");
+
+ /* Set cjson.empty_array_mt */
+ lua_pushlightuserdata(l, json_lightudata_mask(&json_empty_array));
+ lua_rawget(l, LUA_REGISTRYINDEX);
+ lua_setfield(l, -2, "empty_array_mt");
+
+ /* Set cjson.array_mt */
+ lua_pushlightuserdata(l, json_lightudata_mask(&json_array));
+ lua_rawget(l, LUA_REGISTRYINDEX);
+ lua_setfield(l, -2, "array_mt");
+
+ /* Set cjson.empty_array */
+ lua_pushlightuserdata(l, json_lightudata_mask(&json_array));
+ lua_setfield(l, -2, "empty_array");
+
+ /* Set module name / version fields */
+ lua_pushliteral(l, CJSON_MODNAME);
+ lua_setfield(l, -2, "_NAME");
+ lua_pushliteral(l, CJSON_VERSION);
+ lua_setfield(l, -2, "_VERSION");
+
+ return 1;
+}
+
+/* Return cjson.safe module table */
+static int lua_cjson_safe_new(lua_State *l)
+{
+ const char *func[] = { "decode", "encode", NULL };
+ int i;
+
+ lua_cjson_new(l);
+
+ /* Fix new() method */
+ lua_pushcfunction(l, lua_cjson_safe_new);
+ lua_setfield(l, -2, "new");
+
+ for (i = 0; func[i]; i++) {
+ lua_getfield(l, -1, func[i]);
+ lua_pushcclosure(l, json_protect_conversion, 1);
+ lua_setfield(l, -2, func[i]);
+ }
+
+ return 1;
+}
+
+int luaopen_cjson(lua_State *l)
+{
+ lua_cjson_new(l);
+
+#ifdef ENABLE_CJSON_GLOBAL
+ /* Register a global "cjson" table. */
+ lua_pushvalue(l, -1);
+ lua_setglobal(l, CJSON_MODNAME);
+#endif
+
+ /* Return cjson table */
+ return 1;
+}
+
+int luaopen_cjson_safe(lua_State *l)
+{
+ lua_cjson_safe_new(l);
+
+ /* Return cjson.safe table */
+ return 1;
+}
+
+/* vi:ai et sw=4 ts=4:
+ */
diff --git a/src/cjson/lua_cjson.h b/src/cjson/lua_cjson.h
new file mode 100644
index 0000000000..3f70b679be
--- /dev/null
+++ b/src/cjson/lua_cjson.h
@@ -0,0 +1,10 @@
+#ifndef CJSON_LUACJSON_H
+#define CJSON_LUACJSON_H
+
+#include "lua.h"
+
+int lua_cjson_new(lua_State *l);
+int luaopen_cjson(lua_State *l);
+int luaopen_cjson_safe(lua_State *l);
+
+#endif // CJSON_LUACJSON_H
diff --git a/src/cjson/strbuf.c b/src/cjson/strbuf.c
new file mode 100644
index 0000000000..f0f7f4b9a3
--- /dev/null
+++ b/src/cjson/strbuf.c
@@ -0,0 +1,251 @@
+/* strbuf - String buffer routines
+ *
+ * Copyright (c) 2010-2012 Mark Pulford <mark@kyne.com.au>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include "strbuf.h"
+
+static void die(const char *fmt, ...)
+{
+ va_list arg;
+
+ va_start(arg, fmt);
+ vfprintf(stderr, fmt, arg);
+ va_end(arg);
+ fprintf(stderr, "\n");
+
+ exit(-1);
+}
+
+void strbuf_init(strbuf_t *s, int len)
+{
+ int size;
+
+ if (len <= 0)
+ size = STRBUF_DEFAULT_SIZE;
+ else
+ size = len + 1; /* \0 terminator */
+
+ s->buf = NULL;
+ s->size = size;
+ s->length = 0;
+ s->increment = STRBUF_DEFAULT_INCREMENT;
+ s->dynamic = 0;
+ s->reallocs = 0;
+ s->debug = 0;
+
+ s->buf = malloc(size);
+ if (!s->buf)
+ die("Out of memory");
+
+ strbuf_ensure_null(s);
+}
+
+strbuf_t *strbuf_new(int len)
+{
+ strbuf_t *s;
+
+ s = malloc(sizeof(strbuf_t));
+ if (!s)
+ die("Out of memory");
+
+ strbuf_init(s, len);
+
+ /* Dynamic strbuf allocation / deallocation */
+ s->dynamic = 1;
+
+ return s;
+}
+
+void strbuf_set_increment(strbuf_t *s, int increment)
+{
+ /* Increment > 0: Linear buffer growth rate
+ * Increment < -1: Exponential buffer growth rate */
+ if (increment == 0 || increment == -1)
+ die("BUG: Invalid string increment");
+
+ s->increment = increment;
+}
+
+static inline void debug_stats(strbuf_t *s)
+{
+ if (s->debug) {
+ fprintf(stderr, "strbuf(%lx) reallocs: %d, length: %d, size: %d\n",
+ (long)s, s->reallocs, s->length, s->size);
+ }
+}
+
+/* If strbuf_t has not been dynamically allocated, strbuf_free() can
+ * be called any number of times strbuf_init() */
+void strbuf_free(strbuf_t *s)
+{
+ debug_stats(s);
+
+ if (s->buf) {
+ free(s->buf);
+ s->buf = NULL;
+ }
+ if (s->dynamic)
+ free(s);
+}
+
+char *strbuf_free_to_string(strbuf_t *s, int *len)
+{
+ char *buf;
+
+ debug_stats(s);
+
+ strbuf_ensure_null(s);
+
+ buf = s->buf;
+ if (len)
+ *len = s->length;
+
+ if (s->dynamic)
+ free(s);
+
+ return buf;
+}
+
+static int calculate_new_size(strbuf_t *s, int len)
+{
+ int reqsize, newsize;
+
+ if (len <= 0)
+ die("BUG: Invalid strbuf length requested");
+
+ /* Ensure there is room for optional NULL termination */
+ reqsize = len + 1;
+
+ /* If the user has requested to shrink the buffer, do it exactly */
+ if (s->size > reqsize)
+ return reqsize;
+
+ newsize = s->size;
+ if (s->increment < 0) {
+ /* Exponential sizing */
+ while (newsize < reqsize)
+ newsize *= -s->increment;
+ } else {
+ /* Linear sizing */
+ newsize = ((newsize + s->increment - 1) / s->increment) * s->increment;
+ }
+
+ return newsize;
+}
+
+
+/* Ensure strbuf can handle a string length bytes long (ignoring NULL
+ * optional termination). */
+void strbuf_resize(strbuf_t *s, int len)
+{
+ int newsize;
+
+ newsize = calculate_new_size(s, len);
+
+ if (s->debug > 1) {
+ fprintf(stderr, "strbuf(%lx) resize: %d => %d\n",
+ (long)s, s->size, newsize);
+ }
+
+ s->size = newsize;
+ s->buf = realloc(s->buf, s->size);
+ if (!s->buf)
+ die("Out of memory");
+ s->reallocs++;
+}
+
+void strbuf_append_string(strbuf_t *s, const char *str)
+{
+ int space, i;
+
+ space = strbuf_empty_length(s);
+
+ for (i = 0; str[i]; i++) {
+ if (space < 1) {
+ strbuf_resize(s, s->length + 1);
+ space = strbuf_empty_length(s);
+ }
+
+ s->buf[s->length] = str[i];
+ s->length++;
+ space--;
+ }
+}
+
+/* strbuf_append_fmt() should only be used when an upper bound
+ * is known for the output string. */
+void strbuf_append_fmt(strbuf_t *s, int len, const char *fmt, ...)
+{
+ va_list arg;
+ int fmt_len;
+
+ strbuf_ensure_empty_length(s, len);
+
+ va_start(arg, fmt);
+ fmt_len = vsnprintf(s->buf + s->length, len, fmt, arg);
+ va_end(arg);
+
+ if (fmt_len < 0)
+ die("BUG: Unable to convert number"); /* This should never happen.. */
+
+ s->length += fmt_len;
+}
+
+/* strbuf_append_fmt_retry() can be used when the there is no known
+ * upper bound for the output string. */
+void strbuf_append_fmt_retry(strbuf_t *s, const char *fmt, ...)
+{
+ va_list arg;
+ int fmt_len, try;
+ int empty_len;
+
+ /* If the first attempt to append fails, resize the buffer appropriately
+ * and try again */
+ for (try = 0; ; try++) {
+ va_start(arg, fmt);
+ /* Append the new formatted string */
+ /* fmt_len is the length of the string required, excluding the
+ * trailing NULL */
+ empty_len = strbuf_empty_length(s);
+ /* Add 1 since there is also space to store the terminating NULL. */
+ fmt_len = vsnprintf(s->buf + s->length, empty_len + 1, fmt, arg);
+ va_end(arg);
+
+ if (fmt_len <= empty_len)
+ break; /* SUCCESS */
+ if (try > 0)
+ die("BUG: length of formatted string changed");
+
+ strbuf_resize(s, s->length + fmt_len);
+ }
+
+ s->length += fmt_len;
+}
+
+/* vi:ai et sw=4 ts=4:
+ */
diff --git a/src/cjson/strbuf.h b/src/cjson/strbuf.h
new file mode 100644
index 0000000000..5df0b7bea3
--- /dev/null
+++ b/src/cjson/strbuf.h
@@ -0,0 +1,159 @@
+/* strbuf - String buffer routines
+ *
+ * Copyright (c) 2010-2012 Mark Pulford <mark@kyne.com.au>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <stdlib.h>
+#include <stdarg.h>
+
+/* Workaround for MSVC */
+#ifdef _MSC_VER
+#define inline __inline
+#endif
+
+/* Size: Total bytes allocated to *buf
+ * Length: String length, excluding optional NULL terminator.
+ * Increment: Allocation increments when resizing the string buffer.
+ * Dynamic: True if created via strbuf_new()
+ */
+
+typedef struct {
+ char *buf;
+ int size;
+ int length;
+ int increment;
+ int dynamic;
+ int reallocs;
+ int debug;
+} strbuf_t;
+
+#ifndef STRBUF_DEFAULT_SIZE
+#define STRBUF_DEFAULT_SIZE 1023
+#endif
+#ifndef STRBUF_DEFAULT_INCREMENT
+#define STRBUF_DEFAULT_INCREMENT -2
+#endif
+
+/* Initialise */
+extern strbuf_t *strbuf_new(int len);
+extern void strbuf_init(strbuf_t *s, int len);
+extern void strbuf_set_increment(strbuf_t *s, int increment);
+
+/* Release */
+extern void strbuf_free(strbuf_t *s);
+extern char *strbuf_free_to_string(strbuf_t *s, int *len);
+
+/* Management */
+extern void strbuf_resize(strbuf_t *s, int len);
+static int strbuf_empty_length(strbuf_t *s);
+static int strbuf_length(strbuf_t *s);
+static char *strbuf_string(strbuf_t *s, int *len);
+static void strbuf_ensure_empty_length(strbuf_t *s, int len);
+static char *strbuf_empty_ptr(strbuf_t *s);
+static void strbuf_extend_length(strbuf_t *s, int len);
+
+/* Update */
+extern void strbuf_append_fmt(strbuf_t *s, int len, const char *fmt, ...);
+extern void strbuf_append_fmt_retry(strbuf_t *s, const char *format, ...);
+static void strbuf_append_mem(strbuf_t *s, const char *c, int len);
+extern void strbuf_append_string(strbuf_t *s, const char *str);
+static void strbuf_append_char(strbuf_t *s, const char c);
+static void strbuf_ensure_null(strbuf_t *s);
+
+/* Reset string for before use */
+static inline void strbuf_reset(strbuf_t *s)
+{
+ s->length = 0;
+}
+
+static inline int strbuf_allocated(strbuf_t *s)
+{
+ return s->buf != NULL;
+}
+
+/* Return bytes remaining in the string buffer
+ * Ensure there is space for a NULL terminator. */
+static inline int strbuf_empty_length(strbuf_t *s)
+{
+ return s->size - s->length - 1;
+}
+
+static inline void strbuf_ensure_empty_length(strbuf_t *s, int len)
+{
+ if (len > strbuf_empty_length(s))
+ strbuf_resize(s, s->length + len);
+}
+
+static inline char *strbuf_empty_ptr(strbuf_t *s)
+{
+ return s->buf + s->length;
+}
+
+static inline void strbuf_extend_length(strbuf_t *s, int len)
+{
+ s->length += len;
+}
+
+static inline int strbuf_length(strbuf_t *s)
+{
+ return s->length;
+}
+
+static inline void strbuf_append_char(strbuf_t *s, const char c)
+{
+ strbuf_ensure_empty_length(s, 1);
+ s->buf[s->length++] = c;
+}
+
+static inline void strbuf_append_char_unsafe(strbuf_t *s, const char c)
+{
+ s->buf[s->length++] = c;
+}
+
+static inline void strbuf_append_mem(strbuf_t *s, const char *c, int len)
+{
+ strbuf_ensure_empty_length(s, len);
+ memcpy(s->buf + s->length, c, len);
+ s->length += len;
+}
+
+static inline void strbuf_append_mem_unsafe(strbuf_t *s, const char *c, int len)
+{
+ memcpy(s->buf + s->length, c, len);
+ s->length += len;
+}
+
+static inline void strbuf_ensure_null(strbuf_t *s)
+{
+ s->buf[s->length] = 0;
+}
+
+static inline char *strbuf_string(strbuf_t *s, int *len)
+{
+ if (len)
+ *len = s->length;
+
+ return s->buf;
+}
+
+/* vi:ai et sw=4 ts=4:
+ */
diff --git a/src/clint.py b/src/clint.py
index 9b4128a0c9..e7d76366b0 100755
--- a/src/clint.py
+++ b/src/clint.py
@@ -68,7 +68,7 @@ Syntax: clint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...]
<file> [file] ...
The style guidelines this tries to follow are those in
- http://neovim.io/development-wiki/style-guide/style-guide.xml
+ http://neovim.io/develop/style-guide.xml
Note: This is Google's cpplint.py modified for use with the Neovim project,
which follows the Google C++ coding convention except with the following
@@ -264,7 +264,7 @@ _error_suppressions_2 = set()
# The allowed line length of files.
# This is set by --linelength flag.
-_line_length = 80
+_line_length = 100
# The allowed extensions for file names
# This is set by --extensions flag.
diff --git a/src/mpack/LICENSE-MIT b/src/mpack/LICENSE-MIT
new file mode 100644
index 0000000000..030ba872c5
--- /dev/null
+++ b/src/mpack/LICENSE-MIT
@@ -0,0 +1,22 @@
+Copyright (c) 2016 Thiago de Arruda
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
diff --git a/src/mpack/conv.c b/src/mpack/conv.c
new file mode 100644
index 0000000000..31297a8784
--- /dev/null
+++ b/src/mpack/conv.c
@@ -0,0 +1,378 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
+#include "conv.h"
+
+static int mpack_fits_single(double v);
+static mpack_value_t mpack_pack_ieee754(double v, unsigned m, unsigned e);
+static int mpack_is_be(void) FPURE;
+static double mpack_fmod_pow2_32(double a);
+
+
+#define POW2(n) \
+ ((double)(1 << (n / 2)) * (double)(1 << (n / 2)) * (double)(1 << (n % 2)))
+
+#define MPACK_SWAP_VALUE(val) \
+ do { \
+ mpack_uint32_t lo = val.lo; \
+ val.lo = val.hi; \
+ val.hi = lo; \
+ } while (0)
+
+MPACK_API mpack_token_t mpack_pack_nil(void)
+{
+ mpack_token_t rv;
+ rv.type = MPACK_TOKEN_NIL;
+ return rv;
+}
+
+MPACK_API mpack_token_t mpack_pack_boolean(unsigned v)
+{
+ mpack_token_t rv;
+ rv.type = MPACK_TOKEN_BOOLEAN;
+ rv.data.value.lo = v ? 1 : 0;
+ rv.data.value.hi = 0;
+ return rv;
+}
+
+MPACK_API mpack_token_t mpack_pack_uint(mpack_uintmax_t v)
+{
+ mpack_token_t rv;
+ rv.data.value.lo = v & 0xffffffff;
+ rv.data.value.hi = (mpack_uint32_t)((v >> 31) >> 1);
+ rv.type = MPACK_TOKEN_UINT;
+ return rv;
+}
+
+MPACK_API mpack_token_t mpack_pack_sint(mpack_sintmax_t v)
+{
+ if (v < 0) {
+ mpack_token_t rv;
+ mpack_uintmax_t tc = -((mpack_uintmax_t)(v + 1)) + 1;
+ tc = ~tc + 1;
+ rv = mpack_pack_uint(tc);
+ rv.type = MPACK_TOKEN_SINT;
+ return rv;
+ }
+
+ return mpack_pack_uint((mpack_uintmax_t)v);
+}
+
+MPACK_API mpack_token_t mpack_pack_float_compat(double v)
+{
+ /* ieee754 single-precision limits to determine if "v" can be fully
+ * represented in 4 bytes */
+ mpack_token_t rv;
+
+ if (mpack_fits_single(v)) {
+ rv.length = 4;
+ rv.data.value = mpack_pack_ieee754(v, 23, 8);
+ } else {
+ rv.length = 8;
+ rv.data.value = mpack_pack_ieee754(v, 52, 11);
+ }
+
+ rv.type = MPACK_TOKEN_FLOAT;
+ return rv;
+}
+
+MPACK_API mpack_token_t mpack_pack_float_fast(double v)
+{
+ /* ieee754 single-precision limits to determine if "v" can be fully
+ * represented in 4 bytes */
+ mpack_token_t rv;
+
+ if (mpack_fits_single(v)) {
+ union {
+ float f;
+ mpack_uint32_t m;
+ } conv;
+ conv.f = (float)v;
+ rv.length = 4;
+ rv.data.value.lo = conv.m;
+ rv.data.value.hi = 0;
+ } else {
+ union {
+ double d;
+ mpack_value_t m;
+ } conv;
+ conv.d = v;
+ rv.length = 8;
+ rv.data.value = conv.m;
+ if (mpack_is_be()) {
+ MPACK_SWAP_VALUE(rv.data.value);
+ }
+ }
+
+ rv.type = MPACK_TOKEN_FLOAT;
+ return rv;
+}
+
+MPACK_API mpack_token_t mpack_pack_number(double v)
+{
+ mpack_token_t tok;
+ double vabs;
+ vabs = v < 0 ? -v : v;
+ assert(v <= 9007199254740991. && v >= -9007199254740991.);
+ tok.data.value.hi = (mpack_uint32_t)(vabs / POW2(32));
+ tok.data.value.lo = (mpack_uint32_t)mpack_fmod_pow2_32(vabs);
+
+ if (v < 0) {
+ /* Compute the two's complement */
+ tok.type = MPACK_TOKEN_SINT;
+ tok.data.value.hi = ~tok.data.value.hi;
+ tok.data.value.lo = ~tok.data.value.lo + 1;
+ if (!tok.data.value.lo) tok.data.value.hi++;
+ if (tok.data.value.lo == 0 && tok.data.value.hi == 0) tok.length = 1;
+ else if (tok.data.value.lo < 0x80000000) tok.length = 8;
+ else if (tok.data.value.lo < 0xffff7fff) tok.length = 4;
+ else if (tok.data.value.lo < 0xffffff7f) tok.length = 2;
+ else tok.length = 1;
+ } else {
+ tok.type = MPACK_TOKEN_UINT;
+ if (tok.data.value.hi) tok.length = 8;
+ else if (tok.data.value.lo > 0xffff) tok.length = 4;
+ else if (tok.data.value.lo > 0xff) tok.length = 2;
+ else tok.length = 1;
+ }
+
+ if (mpack_unpack_number(tok) != v) {
+ return mpack_pack_float(v);
+ }
+
+ return tok;
+}
+
+MPACK_API mpack_token_t mpack_pack_chunk(const char *p, mpack_uint32_t l)
+{
+ mpack_token_t rv;
+ rv.type = MPACK_TOKEN_CHUNK;
+ rv.data.chunk_ptr = p;
+ rv.length = l;
+ return rv;
+}
+
+MPACK_API mpack_token_t mpack_pack_str(mpack_uint32_t l)
+{
+ mpack_token_t rv;
+ rv.type = MPACK_TOKEN_STR;
+ rv.length = l;
+ return rv;
+}
+
+MPACK_API mpack_token_t mpack_pack_bin(mpack_uint32_t l)
+{
+ mpack_token_t rv;
+ rv.type = MPACK_TOKEN_BIN;
+ rv.length = l;
+ return rv;
+}
+
+MPACK_API mpack_token_t mpack_pack_ext(int t, mpack_uint32_t l)
+{
+ mpack_token_t rv;
+ rv.type = MPACK_TOKEN_EXT;
+ rv.length = l;
+ rv.data.ext_type = t;
+ return rv;
+}
+
+MPACK_API mpack_token_t mpack_pack_array(mpack_uint32_t l)
+{
+ mpack_token_t rv;
+ rv.type = MPACK_TOKEN_ARRAY;
+ rv.length = l;
+ return rv;
+}
+
+MPACK_API mpack_token_t mpack_pack_map(mpack_uint32_t l)
+{
+ mpack_token_t rv;
+ rv.type = MPACK_TOKEN_MAP;
+ rv.length = l;
+ return rv;
+}
+
+MPACK_API bool mpack_unpack_boolean(mpack_token_t t)
+{
+ return t.data.value.lo || t.data.value.hi;
+}
+
+MPACK_API mpack_uintmax_t mpack_unpack_uint(mpack_token_t t)
+{
+ return (((mpack_uintmax_t)t.data.value.hi << 31) << 1) | t.data.value.lo;
+}
+
+/* unpack signed integer without relying on two's complement as internal
+ * representation */
+MPACK_API mpack_sintmax_t mpack_unpack_sint(mpack_token_t t)
+{
+ mpack_uint32_t hi = t.data.value.hi;
+ mpack_uint32_t lo = t.data.value.lo;
+ mpack_uintmax_t rv = lo;
+ assert(t.length <= sizeof(mpack_sintmax_t));
+
+ if (t.length == 8) {
+ rv |= (((mpack_uintmax_t)hi) << 31) << 1;
+ }
+ /* reverse the two's complement so that lo/hi contain the absolute value.
+ * note that we have to mask ~rv so that it reflects the two's complement
+ * of the appropriate byte length */
+ rv = (~rv & (((mpack_uintmax_t)1 << ((t.length * 8) - 1)) - 1)) + 1;
+ /* negate and return the absolute value, making sure mpack_sintmax_t can
+ * represent the positive cast. */
+ return -((mpack_sintmax_t)(rv - 1)) - 1;
+}
+
+MPACK_API double mpack_unpack_float_compat(mpack_token_t t)
+{
+ mpack_uint32_t sign;
+ mpack_sint32_t exponent, bias;
+ unsigned mantbits;
+ unsigned expbits;
+ double mant;
+
+ if (t.data.value.lo == 0 && t.data.value.hi == 0)
+ /* nothing to do */
+ return 0;
+
+ if (t.length == 4) mantbits = 23, expbits = 8;
+ else mantbits = 52, expbits = 11;
+ bias = (1 << (expbits - 1)) - 1;
+
+ /* restore sign/exponent/mantissa */
+ if (mantbits == 52) {
+ sign = t.data.value.hi >> 31;
+ exponent = (t.data.value.hi >> 20) & ((1 << 11) - 1);
+ mant = (t.data.value.hi & ((1 << 20) - 1)) * POW2(32);
+ mant += t.data.value.lo;
+ } else {
+ sign = t.data.value.lo >> 31;
+ exponent = (t.data.value.lo >> 23) & ((1 << 8) - 1);
+ mant = t.data.value.lo & ((1 << 23) - 1);
+ }
+
+ mant /= POW2(mantbits);
+ if (exponent) mant += 1.0; /* restore leading 1 */
+ else exponent = 1; /* subnormal */
+ exponent -= bias;
+
+ /* restore original value */
+ while (exponent > 0) mant *= 2.0, exponent--;
+ while (exponent < 0) mant /= 2.0, exponent++;
+ return mant * (sign ? -1 : 1);
+}
+
+MPACK_API double mpack_unpack_float_fast(mpack_token_t t)
+{
+ if (t.length == 4) {
+ union {
+ float f;
+ mpack_uint32_t m;
+ } conv;
+ conv.m = t.data.value.lo;
+ return conv.f;
+ } else {
+ union {
+ double d;
+ mpack_value_t m;
+ } conv;
+ conv.m = t.data.value;
+
+ if (mpack_is_be()) {
+ MPACK_SWAP_VALUE(conv.m);
+ }
+
+ return conv.d;
+ }
+}
+
+MPACK_API double mpack_unpack_number(mpack_token_t t)
+{
+ double rv;
+ mpack_uint32_t hi, lo;
+ if (t.type == MPACK_TOKEN_FLOAT) return mpack_unpack_float(t);
+ assert(t.type == MPACK_TOKEN_UINT || t.type == MPACK_TOKEN_SINT);
+ hi = t.data.value.hi;
+ lo = t.data.value.lo;
+ if (t.type == MPACK_TOKEN_SINT) {
+ /* same idea as mpack_unpack_sint, except here we shouldn't rely on
+ * mpack_uintmax_t having 64-bits, operating on the 32-bit words separately.
+ */
+ if (!hi) {
+ assert(t.length <= 4);
+ hi = 0;
+ lo = (~lo & (((mpack_uint32_t)1 << ((t.length * 8) - 1)) - 1));
+ } else {
+ hi = ~hi;
+ lo = ~lo;
+ }
+ lo++;
+ if (!lo) hi++;
+ }
+ rv = (double)lo + POW2(32) * hi;
+ return t.type == MPACK_TOKEN_SINT ? -rv : rv;
+}
+
+static int mpack_fits_single(double v)
+{
+ return (float)v == v;
+}
+
+static mpack_value_t mpack_pack_ieee754(double v, unsigned mantbits,
+ unsigned expbits)
+{
+ mpack_value_t rv = {0, 0};
+ mpack_sint32_t exponent, bias = (1 << (expbits - 1)) - 1;
+ mpack_uint32_t sign;
+ double mant;
+
+ if (v == 0) {
+ rv.lo = 0;
+ rv.hi = 0;
+ goto end;
+ }
+
+ if (v < 0) sign = 1, mant = -v;
+ else sign = 0, mant = v;
+
+ exponent = 0;
+ while (mant >= 2.0) mant /= 2.0, exponent++;
+ while (mant < 1.0 && exponent > -(bias - 1)) mant *= 2.0, exponent--;
+
+ if (mant < 1.0) exponent = -bias; /* subnormal value */
+ else mant = mant - 1.0; /* remove leading 1 */
+ exponent += bias;
+ mant *= POW2(mantbits);
+
+ if (mantbits == 52) {
+ rv.hi = (mpack_uint32_t)(mant / POW2(32));
+ rv.lo = (mpack_uint32_t)(mant - rv.hi * POW2(32));
+ rv.hi |= ((mpack_uint32_t)exponent << 20) | (sign << 31);
+ } else if (mantbits == 23) {
+ rv.hi = 0;
+ rv.lo = (mpack_uint32_t)mant;
+ rv.lo |= ((mpack_uint32_t)exponent << 23) | (sign << 31);
+ }
+
+end:
+ return rv;
+}
+
+static int mpack_is_be(void)
+{
+ union {
+ mpack_uint32_t i;
+ char c[sizeof(mpack_uint32_t)];
+ } test;
+
+ test.i = 1;
+ return test.c[0] == 0;
+}
+
+/* this simplified version of `fmod` that returns the remainder of double
+ * division by 0xffffffff, which is enough for our purposes */
+static double mpack_fmod_pow2_32(double a)
+{
+ return a - ((double)(mpack_uint32_t)(a / POW2(32)) * POW2(32));
+}
diff --git a/src/mpack/conv.h b/src/mpack/conv.h
new file mode 100644
index 0000000000..71f14a067e
--- /dev/null
+++ b/src/mpack/conv.h
@@ -0,0 +1,55 @@
+#ifndef MPACK_CONV_H
+#define MPACK_CONV_H
+
+#include "mpack_core.h"
+
+#if ULLONG_MAX == 0xffffffffffffffff
+typedef long long mpack_sintmax_t;
+typedef unsigned long long mpack_uintmax_t;
+#elif UINT64_MAX == 0xffffffffffffffff
+typedef int64_t mpack_sintmax_t;
+typedef uint64_t mpack_uintmax_t;
+#else
+typedef mpack_sint32_t mpack_sintmax_t;
+typedef mpack_uint32_t mpack_uintmax_t;
+#endif
+
+#ifndef bool
+# define bool unsigned
+#endif
+
+MPACK_API mpack_token_t mpack_pack_nil(void) FUNUSED FPURE;
+MPACK_API mpack_token_t mpack_pack_boolean(unsigned v) FUNUSED FPURE;
+MPACK_API mpack_token_t mpack_pack_uint(mpack_uintmax_t v) FUNUSED FPURE;
+MPACK_API mpack_token_t mpack_pack_sint(mpack_sintmax_t v) FUNUSED FPURE;
+MPACK_API mpack_token_t mpack_pack_float_compat(double v) FUNUSED FPURE;
+MPACK_API mpack_token_t mpack_pack_float_fast(double v) FUNUSED FPURE;
+MPACK_API mpack_token_t mpack_pack_number(double v) FUNUSED FPURE;
+MPACK_API mpack_token_t mpack_pack_chunk(const char *p, mpack_uint32_t l)
+ FUNUSED FPURE FNONULL;
+MPACK_API mpack_token_t mpack_pack_str(mpack_uint32_t l) FUNUSED FPURE;
+MPACK_API mpack_token_t mpack_pack_bin(mpack_uint32_t l) FUNUSED FPURE;
+MPACK_API mpack_token_t mpack_pack_ext(int type, mpack_uint32_t l)
+ FUNUSED FPURE;
+MPACK_API mpack_token_t mpack_pack_array(mpack_uint32_t l) FUNUSED FPURE;
+MPACK_API mpack_token_t mpack_pack_map(mpack_uint32_t l) FUNUSED FPURE;
+MPACK_API bool mpack_unpack_boolean(mpack_token_t t) FUNUSED FPURE;
+MPACK_API mpack_uintmax_t mpack_unpack_uint(mpack_token_t t) FUNUSED FPURE;
+MPACK_API mpack_sintmax_t mpack_unpack_sint(mpack_token_t t) FUNUSED FPURE;
+MPACK_API double mpack_unpack_float_fast(mpack_token_t t) FUNUSED FPURE;
+MPACK_API double mpack_unpack_float_compat(mpack_token_t t) FUNUSED FPURE;
+MPACK_API double mpack_unpack_number(mpack_token_t t) FUNUSED FPURE;
+
+/* The mpack_{pack,unpack}_float_fast functions should work in 99% of the
+ * platforms. When compiling for a platform where floats don't use ieee754 as
+ * the internal format, pass
+ * -Dmpack_{pack,unpack}_float=mpack_{pack,unpack}_float_compat to the
+ * compiler.*/
+#ifndef mpack_pack_float
+# define mpack_pack_float mpack_pack_float_fast
+#endif
+#ifndef mpack_unpack_float
+# define mpack_unpack_float mpack_unpack_float_fast
+#endif
+
+#endif /* MPACK_CONV_H */
diff --git a/src/mpack/lmpack.c b/src/mpack/lmpack.c
new file mode 100644
index 0000000000..4b0e132a3a
--- /dev/null
+++ b/src/mpack/lmpack.c
@@ -0,0 +1,1218 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
+/*
+ * This module exports three classes, and each instance of those classes has its
+ * own private registry for temporary reference storage(keeping state between
+ * calls). A private registry makes managing memory much easier since all we
+ * have to do is call luaL_unref passing the registry reference when the
+ * instance is collected by the __gc metamethod.
+ *
+ * This private registry is manipulated with `lmpack_ref` / `lmpack_unref` /
+ * `lmpack_geti`, which are analogous to `luaL_ref` / `luaL_unref` /
+ * `lua_rawgeti` but operate on the private registry passed as argument.
+ *
+ * In order to simplify debug registry leaks during normal operation(with the
+ * leak_test.lua script), these `lmpack_*` registry functions will target the
+ * normal lua registry when MPACK_DEBUG_REGISTRY_LEAK is defined during
+ * compilation.
+ */
+#define LUA_LIB
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <lauxlib.h>
+#include <lua.h>
+#include <luaconf.h>
+
+#include "nvim/macros.h"
+
+#include "lmpack.h"
+
+#include "rpc.h"
+
+#define UNPACKER_META_NAME "mpack.Unpacker"
+#define PACKER_META_NAME "mpack.Packer"
+#define SESSION_META_NAME "mpack.Session"
+#define NIL_NAME "mpack.NIL"
+#define EMPTY_DICT_NAME "mpack.empty_dict"
+
+/*
+ * TODO(tarruda): When targeting lua 5.3 and being compiled with `long long`
+ * support(not -ansi), we should make use of lua 64 bit integers for
+ * representing msgpack integers, since `double` can't represent the full range.
+ */
+
+#ifndef luaL_reg
+/* Taken from Lua5.1's lauxlib.h */
+#define luaL_reg luaL_Reg
+#endif
+
+#if LUA_VERSION_NUM > 501
+#ifndef luaL_register
+#define luaL_register(L,n,f) luaL_setfuncs(L,f,0)
+#endif
+#endif
+
+typedef struct {
+ lua_State *L;
+ mpack_parser_t *parser;
+ int reg, ext, unpacking, mtdict;
+ char *string_buffer;
+} Unpacker;
+
+typedef struct {
+ lua_State *L;
+ mpack_parser_t *parser;
+ int reg, ext, root, packing, mtdict;
+ int is_bin, is_bin_fn;
+} Packer;
+
+typedef struct {
+ lua_State *L;
+ int reg;
+ mpack_rpc_session_t *session;
+ struct {
+ int type;
+ mpack_rpc_message_t msg;
+ int method_or_error;
+ int args_or_result;
+ } unpacked;
+ int unpacker;
+} Session;
+
+static int lmpack_ref(lua_State *L, int reg)
+{
+#ifdef MPACK_DEBUG_REGISTRY_LEAK
+ return luaL_ref(L, LUA_REGISTRYINDEX);
+#else
+ int rv;
+ lua_rawgeti(L, LUA_REGISTRYINDEX, reg);
+ lua_pushvalue(L, -2);
+ rv = luaL_ref(L, -2);
+ lua_pop(L, 2);
+ return rv;
+#endif
+}
+
+static void lmpack_unref(lua_State *L, int reg, int ref)
+{
+#ifdef MPACK_DEBUG_REGISTRY_LEAK
+ luaL_unref(L, LUA_REGISTRYINDEX, ref);
+#else
+ lua_rawgeti(L, LUA_REGISTRYINDEX, reg);
+ luaL_unref(L, -1, ref);
+ lua_pop(L, 1);
+#endif
+}
+
+static void lmpack_geti(lua_State *L, int reg, int ref)
+{
+#ifdef MPACK_DEBUG_REGISTRY_LEAK
+ lua_rawgeti(L, LUA_REGISTRYINDEX, ref);
+#else
+ lua_rawgeti(L, LUA_REGISTRYINDEX, reg);
+ lua_rawgeti(L, -1, ref);
+ lua_replace(L, -2);
+#endif
+}
+
+/* make a shallow copy of the table on stack and remove it after the copy is
+ * done */
+static void lmpack_shallow_copy(lua_State *L)
+{
+ lua_newtable(L);
+ lua_pushnil(L);
+ while (lua_next(L, -3)) {
+ lua_pushvalue(L, -2);
+ lua_insert(L, -2);
+ lua_settable(L, -4);
+ }
+ lua_remove(L, -2);
+}
+
+static mpack_parser_t *lmpack_grow_parser(mpack_parser_t *parser)
+{
+ mpack_parser_t *old = parser;
+ mpack_uint32_t new_capacity = old->capacity * 2;
+ parser = malloc(MPACK_PARSER_STRUCT_SIZE(new_capacity));
+ if (!parser) goto end;
+ mpack_parser_init(parser, new_capacity);
+ mpack_parser_copy(parser, old);
+ free(old);
+end:
+ return parser;
+}
+
+static mpack_rpc_session_t *lmpack_grow_session(mpack_rpc_session_t *session)
+{
+ mpack_rpc_session_t *old = session;
+ mpack_uint32_t new_capacity = old->capacity * 2;
+ session = malloc(MPACK_RPC_SESSION_STRUCT_SIZE(new_capacity));
+ if (!session) goto end;
+ mpack_rpc_session_init(session, new_capacity);
+ mpack_rpc_session_copy(session, old);
+ free(old);
+end:
+ return session;
+}
+
+static Unpacker *lmpack_check_unpacker(lua_State *L, int index)
+{
+ return luaL_checkudata(L, index, UNPACKER_META_NAME);
+}
+
+static Packer *lmpack_check_packer(lua_State *L, int index)
+{
+ return luaL_checkudata(L, index, PACKER_META_NAME);
+}
+
+static Session *lmpack_check_session(lua_State *L, int index)
+{
+ return luaL_checkudata(L, index, SESSION_META_NAME);
+}
+
+static int lmpack_isnil(lua_State *L, int index)
+{
+ int rv;
+ if (!lua_isuserdata(L, index)) return 0;
+ lua_getfield(L, LUA_REGISTRYINDEX, NIL_NAME);
+ rv = lua_rawequal(L, -1, -2);
+ lua_pop(L, 1);
+ return rv;
+}
+
+static int lmpack_isunpacker(lua_State *L, int index)
+{
+ int rv;
+ if (!lua_isuserdata(L, index) || !lua_getmetatable(L, index)) return 0;
+ luaL_getmetatable(L, UNPACKER_META_NAME);
+ rv = lua_rawequal(L, -1, -2);
+ lua_pop(L, 2);
+ return rv;
+}
+
+static void lmpack_pushnil(lua_State *L)
+{
+ lua_getfield(L, LUA_REGISTRYINDEX, NIL_NAME);
+}
+
+/* adapted from
+ * https://github.com/antirez/lua-cmsgpack/blob/master/lua_cmsgpack.c */
+static mpack_uint32_t lmpack_objlen(lua_State *L, int *is_array)
+{
+ size_t len, max;
+ int isarr, type;
+ lua_Number n;
+#ifndef NDEBUG
+ int top = lua_gettop(L);
+ assert(top);
+#endif
+
+ if ((type = lua_type(L, -1)) != LUA_TTABLE) {
+#if LUA_VERSION_NUM >= 502
+ len = lua_rawlen(L, -1);
+#elif LUA_VERSION_NUM == 501
+ len = lua_objlen(L, -1);
+#else
+ #error You have either broken or too old Lua installation. This library requires Lua>=5.1
+#endif
+ goto end;
+ }
+
+ /* count the number of keys and determine if it is an array */
+ len = 0;
+ max = 0;
+ isarr = 1;
+ lua_pushnil(L);
+
+ while (lua_next(L, -2)) {
+ lua_pop(L, 1); /* pop value */
+ isarr = isarr
+ && lua_isnumber(L, -1) /* lua number */
+ && (n = lua_tonumber(L, -1)) > 0 /* greater than 0 */
+ && (size_t)n == n; /* and integer */
+ max = isarr && (size_t)n > max ? (size_t)n : max;
+ len++;
+ }
+
+ // when len==0, the caller should guess the type!
+ if (len > 0) {
+ *is_array = isarr && max == len;
+ }
+
+end:
+ if ((size_t)-1 > (mpack_uint32_t)-1 && len > (mpack_uint32_t)-1)
+ /* msgpack spec doesn't allow lengths > 32 bits */
+ len = (mpack_uint32_t)-1;
+ assert(top == lua_gettop(L));
+ return (mpack_uint32_t)len;
+}
+
+static int lmpack_unpacker_new(lua_State *L)
+{
+ Unpacker *rv;
+
+ if (lua_gettop(L) > 1)
+ return luaL_error(L, "expecting at most 1 table argument");
+
+ rv = lua_newuserdata(L, sizeof(*rv));
+ rv->parser = malloc(sizeof(*rv->parser));
+ if (!rv->parser) return luaL_error(L, "Failed to allocate memory");
+ mpack_parser_init(rv->parser, 0);
+ rv->parser->data.p = rv;
+ rv->string_buffer = NULL;
+ rv->L = L;
+ rv->unpacking = 0;
+ luaL_getmetatable(L, UNPACKER_META_NAME);
+ lua_setmetatable(L, -2);
+
+#ifndef MPACK_DEBUG_REGISTRY_LEAK
+ lua_newtable(L);
+ rv->reg = luaL_ref(L, LUA_REGISTRYINDEX);
+#endif
+ rv->ext = LUA_NOREF;
+
+ lua_getfield(L, LUA_REGISTRYINDEX, EMPTY_DICT_NAME);
+ rv->mtdict = lmpack_ref(L, rv->reg);
+
+ if (lua_istable(L, 1)) {
+ /* parse options */
+ lua_getfield(L, 1, "ext");
+ if (!lua_isnil(L, -1)) {
+ if (!lua_istable(L, -1))
+ return luaL_error(L, "\"ext\" option must be a table");
+ lmpack_shallow_copy(L);
+ }
+ rv->ext = lmpack_ref(L, rv->reg);
+ }
+
+ return 1;
+}
+
+static int lmpack_unpacker_delete(lua_State *L)
+{
+ Unpacker *unpacker = lmpack_check_unpacker(L, 1);
+ if (unpacker->ext != LUA_NOREF)
+ lmpack_unref(L, unpacker->reg, unpacker->ext);
+#ifndef MPACK_DEBUG_REGISTRY_LEAK
+ luaL_unref(L, LUA_REGISTRYINDEX, unpacker->reg);
+#endif
+ free(unpacker->parser);
+ return 0;
+}
+
+static void lmpack_parse_enter(mpack_parser_t *parser, mpack_node_t *node)
+{
+ Unpacker *unpacker = parser->data.p;
+ lua_State *L = unpacker->L;
+
+ switch (node->tok.type) {
+ case MPACK_TOKEN_NIL:
+ lmpack_pushnil(L); break;
+ case MPACK_TOKEN_BOOLEAN:
+ lua_pushboolean(L, (int)mpack_unpack_boolean(node->tok)); break;
+ case MPACK_TOKEN_UINT:
+ case MPACK_TOKEN_SINT:
+ case MPACK_TOKEN_FLOAT:
+ lua_pushnumber(L, mpack_unpack_number(node->tok)); break;
+ case MPACK_TOKEN_CHUNK:
+ assert(unpacker->string_buffer);
+ memcpy(unpacker->string_buffer + MPACK_PARENT_NODE(node)->pos,
+ node->tok.data.chunk_ptr, node->tok.length);
+ break;
+ case MPACK_TOKEN_BIN:
+ case MPACK_TOKEN_STR:
+ case MPACK_TOKEN_EXT:
+ unpacker->string_buffer = malloc(node->tok.length);
+ if (!unpacker->string_buffer) luaL_error(L, "Failed to allocate memory");
+ break;
+ case MPACK_TOKEN_ARRAY:
+ case MPACK_TOKEN_MAP:
+ lua_newtable(L);
+ node->data[0].i = lmpack_ref(L, unpacker->reg);
+ break;
+ }
+}
+
+static void lmpack_parse_exit(mpack_parser_t *parser, mpack_node_t *node)
+{
+ Unpacker *unpacker = parser->data.p;
+ lua_State *L = unpacker->L;
+ mpack_node_t *parent = MPACK_PARENT_NODE(node);
+
+ switch (node->tok.type) {
+ case MPACK_TOKEN_BIN:
+ case MPACK_TOKEN_STR:
+ case MPACK_TOKEN_EXT:
+ lua_pushlstring(L, unpacker->string_buffer, node->tok.length);
+ free(unpacker->string_buffer);
+ unpacker->string_buffer = NULL;
+ if (node->tok.type == MPACK_TOKEN_EXT && unpacker->ext != LUA_NOREF) {
+ /* check if there's a handler for this type */
+ lmpack_geti(L, unpacker->reg, unpacker->ext);
+ lua_rawgeti(L, -1, node->tok.data.ext_type);
+ if (lua_isfunction(L, -1)) {
+ /* stack:
+ *
+ * -1: ext unpacker function
+ * -2: ext unpackers table
+ * -3: ext string
+ *
+ * We want to call the ext unpacker function with the type and string
+ * as arguments, so push those now
+ */
+ lua_pushinteger(L, node->tok.data.ext_type);
+ lua_pushvalue(L, -4);
+ lua_call(L, 2, 1);
+ /* stack:
+ *
+ * -1: returned object
+ * -2: ext unpackers table
+ * -3: ext string
+ */
+ lua_replace(L, -3);
+ } else {
+ /* the last lua_rawgeti should have pushed nil on the stack,
+ * remove it */
+ lua_pop(L, 1);
+ }
+ /* pop the ext unpackers table */
+ lua_pop(L, 1);
+ }
+ break;
+ case MPACK_TOKEN_ARRAY:
+ case MPACK_TOKEN_MAP:
+ lmpack_geti(L, unpacker->reg, (int)node->data[0].i);
+ lmpack_unref(L, unpacker->reg, (int)node->data[0].i);
+ if (node->key_visited == 0 && node->tok.type == MPACK_TOKEN_MAP) {
+ lmpack_geti(L, unpacker->reg, unpacker->mtdict); // [table, mtdict]
+ lua_setmetatable(L, -2); // [table]
+ }
+
+ break;
+ default:
+ break;
+ }
+
+ if (parent && parent->tok.type < MPACK_TOKEN_BIN) {
+ /* At this point the parsed object is on the stack. Add it to the parent
+ * container. First put the container on the stack. */
+ lmpack_geti(L, unpacker->reg, (int)parent->data[0].i);
+
+ if (parent->tok.type == MPACK_TOKEN_ARRAY) {
+ /* Array, save the value on key equal to `parent->pos` */
+ lua_pushnumber(L, (lua_Number)parent->pos);
+ lua_pushvalue(L, -3);
+ lua_settable(L, -3);
+ } else {
+ assert(parent->tok.type == MPACK_TOKEN_MAP);
+ if (parent->key_visited) {
+ /* save the key on the registry */
+ lua_pushvalue(L, -2);
+ parent->data[1].i = lmpack_ref(L, unpacker->reg);
+ } else {
+ /* set the key/value pair */
+ lmpack_geti(L, unpacker->reg, (int)parent->data[1].i);
+ lmpack_unref(L, unpacker->reg, (int)parent->data[1].i);
+ lua_pushvalue(L, -3);
+ lua_settable(L, -3);
+ }
+ }
+ lua_pop(L, 2); /* pop the container/object */
+ }
+}
+
+static int lmpack_unpacker_unpack_str(lua_State *L, Unpacker *unpacker,
+ const char **str, size_t *len)
+{
+ int rv;
+
+ if (unpacker->unpacking) {
+ return luaL_error(L, "Unpacker instance already working. Use another "
+ "Unpacker or the module's \"unpack\" function if you "
+ "need to unpack from the ext handler");
+ }
+
+ do {
+ unpacker->unpacking = 1;
+ rv = mpack_parse(unpacker->parser, str, len, lmpack_parse_enter,
+ lmpack_parse_exit);
+ unpacker->unpacking = 0;
+
+ if (rv == MPACK_NOMEM) {
+ unpacker->parser = lmpack_grow_parser(unpacker->parser);
+ if (!unpacker->parser) {
+ unpacker->unpacking = 0;
+ return luaL_error(L, "failed to grow Unpacker capacity");
+ }
+ }
+ } while (rv == MPACK_NOMEM);
+
+ if (rv == MPACK_ERROR)
+ return luaL_error(L, "invalid msgpack string");
+
+ return rv;
+}
+
+static int lmpack_unpacker_unpack(lua_State *L)
+{
+ int result, argc;
+ lua_Number startpos;
+ size_t len, offset;
+ const char *str, *str_init;
+ Unpacker *unpacker;
+
+ if ((argc = lua_gettop(L)) > 3 || argc < 2)
+ return luaL_error(L, "expecting between 2 and 3 arguments");
+
+ unpacker = lmpack_check_unpacker(L, 1);
+ unpacker->L = L;
+
+ str_init = str = luaL_checklstring(L, 2, &len);
+ startpos = lua_gettop(L) == 3 ? luaL_checknumber(L, 3) : 1;
+
+ luaL_argcheck(L, startpos > 0, 3,
+ "start position must be greater than zero");
+ luaL_argcheck(L, (size_t)startpos == startpos, 3,
+ "start position must be an integer");
+ luaL_argcheck(L, (size_t)startpos <= len, 3,
+ "start position must be less than or equal to the input string length");
+
+ offset = (size_t)startpos - 1 ;
+ str += offset;
+ len -= offset;
+ result = lmpack_unpacker_unpack_str(L, unpacker, &str, &len);
+
+ if (result == MPACK_EOF)
+ /* if we hit EOF, return nil as the object */
+ lua_pushnil(L);
+
+ /* also return the new position in the input string */
+ lua_pushinteger(L, str - str_init + 1);
+ assert(lua_gettop(L) == argc + 2);
+ return 2;
+}
+
+static int lmpack_packer_new(lua_State *L)
+{
+ Packer *rv;
+
+ if (lua_gettop(L) > 1)
+ return luaL_error(L, "expecting at most 1 table argument");
+
+ rv = lua_newuserdata(L, sizeof(*rv));
+ rv->parser = malloc(sizeof(*rv->parser));
+ if (!rv->parser) return luaL_error(L, "failed to allocate parser memory");
+ mpack_parser_init(rv->parser, 0);
+ rv->parser->data.p = rv;
+ rv->L = L;
+ rv->packing = 0;
+ rv->is_bin = 0;
+ rv->is_bin_fn = LUA_NOREF;
+ luaL_getmetatable(L, PACKER_META_NAME);
+ lua_setmetatable(L, -2);
+
+#ifndef MPACK_DEBUG_REGISTRY_LEAK
+ lua_newtable(L);
+ rv->reg = luaL_ref(L, LUA_REGISTRYINDEX);
+#endif
+ rv->ext = LUA_NOREF;
+
+ lua_getfield(L, LUA_REGISTRYINDEX, EMPTY_DICT_NAME);
+ rv->mtdict = lmpack_ref(L, rv->reg);
+
+ if (lua_istable(L, 1)) {
+ /* parse options */
+ lua_getfield(L, 1, "ext");
+ if (!lua_isnil(L, -1)) {
+ if (!lua_istable(L, -1))
+ return luaL_error(L, "\"ext\" option must be a table");
+ lmpack_shallow_copy(L);
+ }
+ rv->ext = lmpack_ref(L, rv->reg);
+ lua_getfield(L, 1, "is_bin");
+ if (!lua_isnil(L, -1)) {
+ if (!lua_isboolean(L, -1) && !lua_isfunction(L, -1))
+ return luaL_error(L,
+ "\"is_bin\" option must be a boolean or function");
+ rv->is_bin = lua_toboolean(L, -1);
+ if (lua_isfunction(L, -1)) rv->is_bin_fn = lmpack_ref(L, rv->reg);
+ else lua_pop(L, 1);
+ } else {
+ lua_pop(L, 1);
+ }
+
+ }
+
+ return 1;
+}
+
+static int lmpack_packer_delete(lua_State *L)
+{
+ Packer *packer = lmpack_check_packer(L, 1);
+ if (packer->ext != LUA_NOREF)
+ lmpack_unref(L, packer->reg, packer->ext);
+#ifndef MPACK_DEBUG_REGISTRY_LEAK
+ luaL_unref(L, LUA_REGISTRYINDEX, packer->reg);
+#endif
+ free(packer->parser);
+ return 0;
+}
+
+static void lmpack_unparse_enter(mpack_parser_t *parser, mpack_node_t *node)
+{
+ int type;
+ Packer *packer = parser->data.p;
+ lua_State *L = packer->L;
+ mpack_node_t *parent = MPACK_PARENT_NODE(node);
+
+ if (parent) {
+ /* get the parent */
+ lmpack_geti(L, packer->reg, (int)parent->data[0].i);
+
+ if (parent->tok.type > MPACK_TOKEN_MAP) {
+ /* strings are a special case, they are packed as single child chunk
+ * node */
+ const char *str = lua_tolstring(L, -1, NULL);
+ node->tok = mpack_pack_chunk(str, parent->tok.length);
+ lua_pop(L, 1);
+ return;
+ }
+
+ if (parent->tok.type == MPACK_TOKEN_ARRAY) {
+ /* push the next index */
+ lua_pushnumber(L, (lua_Number)(parent->pos + 1));
+ /* push the element */
+ lua_gettable(L, -2);
+ } else if (parent->tok.type == MPACK_TOKEN_MAP) {
+ int result;
+ /* push the previous key */
+ lmpack_geti(L, packer->reg, (int)parent->data[1].i);
+ /* push the pair */
+ result = lua_next(L, -2);
+ assert(result); /* should not be here if the map was fully processed */
+ if (parent->key_visited) {
+ /* release the current key */
+ lmpack_unref(L, packer->reg, (int)parent->data[1].i);
+ /* push key to the top */
+ lua_pushvalue(L, -2);
+ /* set the key for the next iteration, leaving value on top */
+ parent->data[1].i = lmpack_ref(L, packer->reg);
+ /* replace key by the value */
+ lua_replace(L, -2);
+ } else {
+ /* pop value */
+ lua_pop(L, 1);
+ }
+ }
+ /* remove parent, leaving only the object which will be serialized */
+ lua_remove(L, -2);
+ } else {
+ /* root object */
+ lmpack_geti(L, packer->reg, packer->root);
+ }
+
+ type = lua_type(L, -1);
+
+ switch (type) {
+ case LUA_TBOOLEAN:
+ node->tok = mpack_pack_boolean((unsigned)lua_toboolean(L, -1));
+ break;
+ case LUA_TNUMBER:
+ node->tok = mpack_pack_number(lua_tonumber(L, -1));
+ break;
+ case LUA_TSTRING: {
+ int is_bin = packer->is_bin;
+ if (is_bin && packer->is_bin_fn != LUA_NOREF) {
+ lmpack_geti(L, packer->reg, packer->is_bin_fn);
+ lua_pushvalue(L, -2);
+ lua_call(L, 1, 1);
+ is_bin = lua_toboolean(L, -1);
+ lua_pop(L, 1);
+ }
+ if (is_bin) node->tok = mpack_pack_bin(lmpack_objlen(L, NULL));
+ else node->tok = mpack_pack_str(lmpack_objlen(L, NULL));
+ break;
+ }
+ case LUA_TTABLE: {
+ mpack_uint32_t len;
+ mpack_node_t *n;
+
+ int has_meta = lua_getmetatable(L, -1);
+ if (packer->ext != LUA_NOREF && has_meta) {
+ /* check if there's a handler for this metatable */
+ lmpack_geti(L, packer->reg, packer->ext);
+ lua_pushvalue(L, -2);
+ lua_gettable(L, -2);
+ if (lua_isfunction(L, -1)) {
+ lua_Number ext = -1;
+ /* stack:
+ *
+ * -1: ext packer function
+ * -2: ext packers table
+ * -3: metatable
+ * -4: original object
+ *
+ * We want to call the ext packer function with the original object as
+ * argument, so push it on the top
+ */
+ lua_pushvalue(L, -4);
+ /* handler should return type code and string */
+ lua_call(L, 1, 2);
+ if (!lua_isnumber(L, -2) || (ext = lua_tonumber(L, -2)) < 0
+ || ext > 127 || (int)ext != ext)
+ luaL_error(L,
+ "the first result from ext packer must be an integer "
+ "between 0 and 127");
+ if (!lua_isstring(L, -1))
+ luaL_error(L,
+ "the second result from ext packer must be a string");
+ node->tok = mpack_pack_ext((int)ext, lmpack_objlen(L, NULL));
+ /* stack:
+ *
+ * -1: ext string
+ * -2: ext type
+ * -3: ext packers table
+ * -4: metatable
+ * -5: original table
+ *
+ * We want to leave only the returned ext string, so
+ * replace -5 with the string and pop 3
+ */
+ lua_replace(L, -5);
+ lua_pop(L, 3);
+ break; /* done */
+ } else {
+ /* stack:
+ *
+ * -1: ext packers table
+ * -2: metatable
+ * -3: original table
+ *
+ * We want to leave only the original table and metatable since they
+ * will be handled below, so pop 1
+ */
+ lua_pop(L, 1);
+ }
+ }
+
+ int is_array = 1;
+ if (has_meta) {
+ // stack: [table, metatable]
+ if (packer->mtdict != LUA_NOREF) {
+ lmpack_geti(L, packer->reg, packer->mtdict); // [table, metatable, mtdict]
+ is_array = !lua_rawequal(L, -1, -2);
+ lua_pop(L, 1); // [table, metatable];
+ }
+ lua_pop(L, 1); // [table]
+ }
+
+ /* check for cycles */
+ n = node;
+ while ((n = MPACK_PARENT_NODE(n))) {
+ lmpack_geti(L, packer->reg, (int)n->data[0].i);
+ if (lua_rawequal(L, -1, -2)) {
+ /* break out of cycles with NIL */
+ node->tok = mpack_pack_nil();
+ lua_pop(L, 2);
+ lmpack_pushnil(L);
+ goto end;
+ }
+ lua_pop(L, 1);
+ }
+
+ len = lmpack_objlen(L, &is_array);
+ if (is_array) {
+ node->tok = mpack_pack_array(len);
+ } else {
+ node->tok = mpack_pack_map(len);
+ /* save nil as the previous key to start iteration */
+ node->data[1].i = LUA_REFNIL;
+ }
+ break;
+ }
+ case LUA_TUSERDATA:
+ if (lmpack_isnil(L, -1)) {
+ node->tok = mpack_pack_nil();
+ break;
+ }
+ FALLTHROUGH;
+ default:
+ {
+ /* #define FMT */
+ char errmsg[50];
+ snprintf(errmsg, 50, "can't serialize object of type %d", type);
+ luaL_error(L, errmsg);
+ }
+ }
+
+end:
+ node->data[0].i = lmpack_ref(L, packer->reg);
+}
+
+static void lmpack_unparse_exit(mpack_parser_t *parser, mpack_node_t *node)
+{
+ Packer *packer = parser->data.p;
+ lua_State *L = packer->L;
+ if (node->tok.type != MPACK_TOKEN_CHUNK) {
+ /* release the object */
+ lmpack_unref(L, packer->reg, (int)node->data[0].i);
+ if (node->tok.type == MPACK_TOKEN_MAP)
+ lmpack_unref(L, packer->reg, (int)node->data[1].i);
+ }
+}
+
+static int lmpack_packer_pack(lua_State *L)
+{
+ char *b;
+ size_t bl;
+ int result, argc;
+ Packer *packer;
+ luaL_Buffer buffer;
+
+ if ((argc = lua_gettop(L)) != 2)
+ return luaL_error(L, "expecting exactly 2 arguments");
+
+ packer = lmpack_check_packer(L, 1);
+ packer->L = L;
+ packer->root = lmpack_ref(L, packer->reg);
+ luaL_buffinit(L, &buffer);
+ b = luaL_prepbuffer(&buffer);
+ bl = LUAL_BUFFERSIZE;
+
+ if (packer->packing) {
+ return luaL_error(L, "Packer instance already working. Use another Packer "
+ "or the module's \"pack\" function if you need to "
+ "pack from the ext handler");
+ }
+
+ do {
+ size_t bl_init = bl;
+ packer->packing = 1;
+ result = mpack_unparse(packer->parser, &b, &bl, lmpack_unparse_enter,
+ lmpack_unparse_exit);
+ packer->packing = 0;
+
+ if (result == MPACK_NOMEM) {
+ packer->parser = lmpack_grow_parser(packer->parser);
+ if (!packer->parser) {
+ packer->packing = 0;
+ return luaL_error(L, "Failed to grow Packer capacity");
+ }
+ }
+
+ luaL_addsize(&buffer, bl_init - bl);
+
+ if (!bl) {
+ /* buffer empty, resize */
+ b = luaL_prepbuffer(&buffer);
+ bl = LUAL_BUFFERSIZE;
+ }
+ } while (result == MPACK_EOF || result == MPACK_NOMEM);
+
+ lmpack_unref(L, packer->reg, packer->root);
+ luaL_pushresult(&buffer);
+ assert(lua_gettop(L) == argc);
+ return 1;
+}
+
+static int lmpack_session_new(lua_State *L)
+{
+ Session *rv = lua_newuserdata(L, sizeof(*rv));
+ rv->session = malloc(sizeof(*rv->session));
+ if (!rv->session) return luaL_error(L, "Failed to allocate memory");
+ mpack_rpc_session_init(rv->session, 0);
+ rv->L = L;
+ luaL_getmetatable(L, SESSION_META_NAME);
+ lua_setmetatable(L, -2);
+#ifndef MPACK_DEBUG_REGISTRY_LEAK
+ lua_newtable(L);
+ rv->reg = luaL_ref(L, LUA_REGISTRYINDEX);
+#endif
+ rv->unpacker = LUA_REFNIL;
+ rv->unpacked.args_or_result = LUA_NOREF;
+ rv->unpacked.method_or_error = LUA_NOREF;
+ rv->unpacked.type = MPACK_EOF;
+
+ if (lua_istable(L, 1)) {
+ /* parse options */
+ lua_getfield(L, 1, "unpack");
+ if (!lmpack_isunpacker(L, -1)) {
+ return luaL_error(L,
+ "\"unpack\" option must be a " UNPACKER_META_NAME " instance");
+ }
+ rv->unpacker = lmpack_ref(L, rv->reg);
+ }
+
+ return 1;
+}
+
+static int lmpack_session_delete(lua_State *L)
+{
+ Session *session = lmpack_check_session(L, 1);
+ lmpack_unref(L, session->reg, session->unpacker);
+#ifndef MPACK_DEBUG_REGISTRY_LEAK
+ luaL_unref(L, LUA_REGISTRYINDEX, session->reg);
+#endif
+ free(session->session);
+ return 0;
+}
+
+static int lmpack_session_receive(lua_State *L)
+{
+ int argc, done, rcount = 3;
+ lua_Number startpos;
+ size_t len;
+ const char *str, *str_init;
+ Session *session;
+ Unpacker *unpacker = NULL;
+
+ if ((argc = lua_gettop(L)) > 3 || argc < 2)
+ return luaL_error(L, "expecting between 2 and 3 arguments");
+
+ session = lmpack_check_session(L, 1);
+ str_init = str = luaL_checklstring(L, 2, &len);
+ startpos = lua_gettop(L) == 3 ? luaL_checknumber(L, 3) : 1;
+
+ luaL_argcheck(L, startpos > 0, 3,
+ "start position must be greater than zero");
+ luaL_argcheck(L, (size_t)startpos == startpos, 3,
+ "start position must be an integer");
+ luaL_argcheck(L, (size_t)startpos <= len, 3,
+ "start position must be less than or equal to the input string length");
+
+ str += (size_t)startpos - 1;
+
+ if (session->unpacker != LUA_REFNIL) {
+ lmpack_geti(L, session->reg, session->unpacker);
+ unpacker = lmpack_check_unpacker(L, -1);
+ unpacker->L = L;
+ rcount += 2;
+ lua_pop(L, 1);
+ }
+
+ for (;;) {
+ int result;
+
+ if (session->unpacked.type == MPACK_EOF) {
+ session->unpacked.type =
+ mpack_rpc_receive(session->session, &str, &len, &session->unpacked.msg);
+
+ if (!unpacker || session->unpacked.type == MPACK_EOF)
+ break;
+ }
+
+ result = lmpack_unpacker_unpack_str(L, unpacker, &str, &len);
+
+ if (result == MPACK_EOF) break;
+
+ if (session->unpacked.method_or_error == LUA_NOREF) {
+ session->unpacked.method_or_error = lmpack_ref(L, session->reg);
+ } else {
+ session->unpacked.args_or_result = lmpack_ref(L, session->reg);
+ break;
+ }
+ }
+
+ done = session->unpacked.type != MPACK_EOF
+ && (session->unpacked.args_or_result != LUA_NOREF || !unpacker);
+
+ if (!done) {
+ lua_pushnil(L);
+ lua_pushnil(L);
+ if (unpacker) {
+ lua_pushnil(L);
+ lua_pushnil(L);
+ }
+ goto end;
+ }
+
+ switch (session->unpacked.type) {
+ case MPACK_RPC_REQUEST:
+ lua_pushstring(L, "request");
+ lua_pushnumber(L, session->unpacked.msg.id);
+ break;
+ case MPACK_RPC_RESPONSE:
+ lua_pushstring(L, "response");
+ lmpack_geti(L, session->reg, (int)session->unpacked.msg.data.i);
+ break;
+ case MPACK_RPC_NOTIFICATION:
+ lua_pushstring(L, "notification");
+ lua_pushnil(L);
+ break;
+ default:
+ /* In most cases the only sane thing to do when receiving invalid
+ * msgpack-rpc is to close the connection, so handle all errors with
+ * this generic message. Later may add more detailed information. */
+ return luaL_error(L, "invalid msgpack-rpc string");
+ }
+
+ session->unpacked.type = MPACK_EOF;
+
+ if (unpacker) {
+ lmpack_geti(L, session->reg, session->unpacked.method_or_error);
+ lmpack_geti(L, session->reg, session->unpacked.args_or_result);
+ lmpack_unref(L, session->reg, session->unpacked.method_or_error);
+ lmpack_unref(L, session->reg, session->unpacked.args_or_result);
+ session->unpacked.method_or_error = LUA_NOREF;
+ session->unpacked.args_or_result = LUA_NOREF;
+ }
+
+end:
+ lua_pushinteger(L, str - str_init + 1);
+ return rcount;
+}
+
+static int lmpack_session_request(lua_State *L)
+{
+ int result;
+ char buf[16], *b = buf;
+ size_t bl = sizeof(buf);
+ Session *session;
+ mpack_data_t data;
+
+ if (lua_gettop(L) > 2 || lua_gettop(L) < 1)
+ return luaL_error(L, "expecting 1 or 2 arguments");
+
+ session = lmpack_check_session(L, 1);
+ data.i = lua_isnoneornil(L, 2) ? LUA_NOREF : lmpack_ref(L, session->reg);
+ do {
+ result = mpack_rpc_request(session->session, &b, &bl, data);
+ if (result == MPACK_NOMEM) {
+ session->session = lmpack_grow_session(session->session);
+ if (!session->session)
+ return luaL_error(L, "Failed to grow Session capacity");
+ }
+ } while (result == MPACK_NOMEM);
+
+ assert(result == MPACK_OK);
+ lua_pushlstring(L, buf, sizeof(buf) - bl);
+ return 1;
+}
+
+static int lmpack_session_reply(lua_State *L)
+{
+ int result;
+ char buf[16], *b = buf;
+ size_t bl = sizeof(buf);
+ Session *session;
+ lua_Number id;
+
+ if (lua_gettop(L) != 2)
+ return luaL_error(L, "expecting exactly 2 arguments");
+
+ session = lmpack_check_session(L, 1);
+ id = lua_tonumber(L, 2);
+ luaL_argcheck(L, ((size_t)id == id && id >= 0 && id <= 0xffffffff), 2,
+ "invalid request id");
+ result = mpack_rpc_reply(session->session, &b, &bl, (mpack_uint32_t)id);
+ assert(result == MPACK_OK);
+ lua_pushlstring(L, buf, sizeof(buf) - bl);
+ return 1;
+}
+
+static int lmpack_session_notify(lua_State *L)
+{
+ int result;
+ char buf[16], *b = buf;
+ size_t bl = sizeof(buf);
+ Session *session;
+
+ if (lua_gettop(L) != 1)
+ return luaL_error(L, "expecting exactly 1 argument");
+
+ session = lmpack_check_session(L, 1);
+ result = mpack_rpc_notify(session->session, &b, &bl);
+ assert(result == MPACK_OK);
+ lua_pushlstring(L, buf, sizeof(buf) - bl);
+ return 1;
+}
+
+static int lmpack_nil_tostring(lua_State* L)
+{
+ lua_pushfstring(L, NIL_NAME, lua_topointer(L, 1));
+ return 1;
+}
+
+static int lmpack_unpack(lua_State *L)
+{
+ int result;
+ size_t len;
+ const char *str;
+ Unpacker unpacker;
+ mpack_parser_t parser;
+
+ if (lua_gettop(L) != 1)
+ return luaL_error(L, "expecting exactly 1 argument");
+
+ str = luaL_checklstring(L, 1, &len);
+
+ /* initialize unpacker */
+ lua_newtable(L);
+ unpacker.reg = luaL_ref(L, LUA_REGISTRYINDEX);
+ unpacker.ext = LUA_NOREF;
+ unpacker.parser = &parser;
+ mpack_parser_init(unpacker.parser, 0);
+ unpacker.parser->data.p = &unpacker;
+ unpacker.string_buffer = NULL;
+ unpacker.L = L;
+
+ lua_getfield(L, LUA_REGISTRYINDEX, EMPTY_DICT_NAME);
+ unpacker.mtdict = lmpack_ref(L, unpacker.reg);
+
+ result = mpack_parse(&parser, &str, &len, lmpack_parse_enter,
+ lmpack_parse_exit);
+
+ luaL_unref(L, LUA_REGISTRYINDEX, unpacker.reg);
+
+ if (result == MPACK_NOMEM)
+ return luaL_error(L, "object was too deep to unpack");
+ else if (result == MPACK_EOF)
+ return luaL_error(L, "incomplete msgpack string");
+ else if (result == MPACK_ERROR)
+ return luaL_error(L, "invalid msgpack string");
+ else if (result == MPACK_OK && len)
+ return luaL_error(L, "trailing data in msgpack string");
+
+ assert(result == MPACK_OK);
+ return 1;
+}
+
+static int lmpack_pack(lua_State *L)
+{
+ char *b;
+ size_t bl;
+ int result;
+ Packer packer;
+ mpack_parser_t parser;
+ luaL_Buffer buffer;
+
+ if (lua_gettop(L) != 1)
+ return luaL_error(L, "expecting exactly 1 argument");
+
+ /* initialize packer */
+ lua_newtable(L);
+ packer.reg = luaL_ref(L, LUA_REGISTRYINDEX);
+ packer.ext = LUA_NOREF;
+ packer.parser = &parser;
+ mpack_parser_init(packer.parser, 0);
+ packer.parser->data.p = &packer;
+ packer.is_bin = 0;
+ packer.L = L;
+ packer.root = lmpack_ref(L, packer.reg);
+
+ lua_getfield(L, LUA_REGISTRYINDEX, EMPTY_DICT_NAME);
+ packer.mtdict = lmpack_ref(L, packer.reg);
+
+
+ luaL_buffinit(L, &buffer);
+ b = luaL_prepbuffer(&buffer);
+ bl = LUAL_BUFFERSIZE;
+
+ do {
+ size_t bl_init = bl;
+ result = mpack_unparse(packer.parser, &b, &bl, lmpack_unparse_enter,
+ lmpack_unparse_exit);
+
+ if (result == MPACK_NOMEM) {
+ lmpack_unref(L, packer.reg, packer.root);
+ luaL_unref(L, LUA_REGISTRYINDEX, packer.reg);
+ return luaL_error(L, "object was too deep to pack");
+ }
+
+ luaL_addsize(&buffer, bl_init - bl);
+
+ if (!bl) {
+ /* buffer empty, resize */
+ b = luaL_prepbuffer(&buffer);
+ bl = LUAL_BUFFERSIZE;
+ }
+ } while (result == MPACK_EOF);
+
+ lmpack_unref(L, packer.reg, packer.root);
+ luaL_unref(L, LUA_REGISTRYINDEX, packer.reg);
+ luaL_pushresult(&buffer);
+ return 1;
+}
+
+static const luaL_reg unpacker_methods[] = {
+ {"__call", lmpack_unpacker_unpack},
+ {"__gc", lmpack_unpacker_delete},
+ {NULL, NULL}
+};
+
+static const luaL_reg packer_methods[] = {
+ {"__call", lmpack_packer_pack},
+ {"__gc", lmpack_packer_delete},
+ {NULL, NULL}
+};
+
+static const luaL_reg session_methods[] = {
+ {"receive", lmpack_session_receive},
+ {"request", lmpack_session_request},
+ {"reply", lmpack_session_reply},
+ {"notify", lmpack_session_notify},
+ {"__gc", lmpack_session_delete},
+ {NULL, NULL}
+};
+
+static const luaL_reg mpack_functions[] = {
+ {"Unpacker", lmpack_unpacker_new},
+ {"Packer", lmpack_packer_new},
+ {"Session", lmpack_session_new},
+ {"unpack", lmpack_unpack},
+ {"pack", lmpack_pack},
+ {NULL, NULL}
+};
+
+int luaopen_mpack(lua_State *L)
+{
+ /* Unpacker */
+ luaL_newmetatable(L, UNPACKER_META_NAME);
+ lua_pushvalue(L, -1);
+ lua_setfield(L, -2, "__index");
+ luaL_register(L, NULL, unpacker_methods);
+ lua_pop(L, 1);
+ /* Packer */
+ luaL_newmetatable(L, PACKER_META_NAME);
+ lua_pushvalue(L, -1);
+ lua_setfield(L, -2, "__index");
+ luaL_register(L, NULL, packer_methods);
+ lua_pop(L, 1);
+ /* Session */
+ luaL_newmetatable(L, SESSION_META_NAME);
+ lua_pushvalue(L, -1);
+ lua_setfield(L, -2, "__index");
+ luaL_register(L, NULL, session_methods);
+ lua_pop(L, 1);
+ /* NIL */
+ /* Check if NIL is already stored in the registry */
+ lua_getfield(L, LUA_REGISTRYINDEX, NIL_NAME);
+ /* If it isn't, create it */
+ if (lua_isnil(L, -1)) {
+ /* Use a constant userdata to represent NIL */
+ (void)lua_newuserdata(L, sizeof(void *));
+ /* Create a metatable for NIL userdata */
+ lua_createtable(L, 0, 1);
+ lua_pushstring(L, "__tostring");
+ lua_pushcfunction(L, lmpack_nil_tostring);
+ lua_settable(L, -3);
+ /* Assign the metatable to the userdata object */
+ lua_setmetatable(L, -2);
+ /* Save NIL on the registry so we can access it easily from other functions */
+ lua_setfield(L, LUA_REGISTRYINDEX, NIL_NAME);
+ }
+
+ lua_pop(L, 1);
+
+ /* module */
+ lua_newtable(L);
+ luaL_register(L, NULL, mpack_functions);
+ /* save NIL on the module */
+ lua_getfield(L, LUA_REGISTRYINDEX, NIL_NAME);
+ lua_setfield(L, -2, "NIL");
+ return 1;
+}
diff --git a/src/mpack/lmpack.h b/src/mpack/lmpack.h
new file mode 100644
index 0000000000..e35f40fab6
--- /dev/null
+++ b/src/mpack/lmpack.h
@@ -0,0 +1,3 @@
+#include <lua.h>
+
+int luaopen_mpack(lua_State *L);
diff --git a/src/mpack/mpack_core.c b/src/mpack/mpack_core.c
new file mode 100644
index 0000000000..f8ca63b7a3
--- /dev/null
+++ b/src/mpack/mpack_core.c
@@ -0,0 +1,578 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
+#include <string.h>
+
+#include "mpack_core.h"
+
+#define UNUSED(p) (void)p;
+#define ADVANCE(buf, buflen) ((*buflen)--, (unsigned char)*((*buf)++))
+#define TLEN(val, range_start) ((mpack_uint32_t)(1 << (val - range_start)))
+#ifndef MIN
+# define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
+#endif
+
+static int mpack_rtoken(const char **buf, size_t *buflen,
+ mpack_token_t *tok);
+static int mpack_rpending(const char **b, size_t *nl, mpack_tokbuf_t *tb);
+static int mpack_rvalue(mpack_token_type_t t, mpack_uint32_t l,
+ const char **b, size_t *bl, mpack_token_t *tok);
+static int mpack_rblob(mpack_token_type_t t, mpack_uint32_t l,
+ const char **b, size_t *bl, mpack_token_t *tok);
+static int mpack_wtoken(const mpack_token_t *tok, char **b, size_t *bl);
+static int mpack_wpending(char **b, size_t *bl, mpack_tokbuf_t *tb);
+static int mpack_wpint(char **b, size_t *bl, mpack_value_t v);
+static int mpack_wnint(char **b, size_t *bl, mpack_value_t v);
+static int mpack_wfloat(char **b, size_t *bl, const mpack_token_t *v);
+static int mpack_wstr(char **buf, size_t *buflen, mpack_uint32_t len);
+static int mpack_wbin(char **buf, size_t *buflen, mpack_uint32_t len);
+static int mpack_wext(char **buf, size_t *buflen, int type,
+ mpack_uint32_t len);
+static int mpack_warray(char **buf, size_t *buflen, mpack_uint32_t len);
+static int mpack_wmap(char **buf, size_t *buflen, mpack_uint32_t len);
+static int mpack_w1(char **b, size_t *bl, mpack_uint32_t v);
+static int mpack_w2(char **b, size_t *bl, mpack_uint32_t v);
+static int mpack_w4(char **b, size_t *bl, mpack_uint32_t v);
+static mpack_value_t mpack_byte(unsigned char b);
+static int mpack_value(mpack_token_type_t t, mpack_uint32_t l,
+ mpack_value_t v, mpack_token_t *tok);
+static int mpack_blob(mpack_token_type_t t, mpack_uint32_t l, int et,
+ mpack_token_t *tok);
+
+MPACK_API void mpack_tokbuf_init(mpack_tokbuf_t *tokbuf)
+{
+ tokbuf->ppos = 0;
+ tokbuf->plen = 0;
+ tokbuf->passthrough = 0;
+}
+
+MPACK_API int mpack_read(mpack_tokbuf_t *tokbuf, const char **buf,
+ size_t *buflen, mpack_token_t *tok)
+{
+ int status;
+ size_t initial_ppos, ptrlen, advanced;
+ const char *ptr, *ptr_save;
+ assert(*buf && *buflen);
+
+ if (tokbuf->passthrough) {
+ /* pass data from str/bin/ext directly as a MPACK_TOKEN_CHUNK, adjusting
+ * *buf and *buflen */
+ tok->type = MPACK_TOKEN_CHUNK;
+ tok->data.chunk_ptr = *buf;
+ tok->length = MIN((mpack_uint32_t)*buflen, tokbuf->passthrough);
+ tokbuf->passthrough -= tok->length;
+ *buf += tok->length;
+ *buflen -= tok->length;
+ goto done;
+ }
+
+ initial_ppos = tokbuf->ppos;
+
+ if (tokbuf->plen) {
+ if (!mpack_rpending(buf, buflen, tokbuf)) {
+ return MPACK_EOF;
+ }
+ ptr = tokbuf->pending;
+ ptrlen = tokbuf->ppos;
+ } else {
+ ptr = *buf;
+ ptrlen = *buflen;
+ }
+
+ ptr_save = ptr;
+
+ if ((status = mpack_rtoken(&ptr, &ptrlen, tok))) {
+ if (status != MPACK_EOF) return MPACK_ERROR;
+ /* need more data */
+ assert(!tokbuf->plen);
+ /* read the remainder of *buf to tokbuf->pending so it can be parsed
+ * later with more data. only required when tokbuf->plen == 0 or else
+ * it would have been done already. */
+ tokbuf->plen = tok->length + 1;
+ assert(tokbuf->plen <= sizeof(tokbuf->pending));
+ tokbuf->ppos = 0;
+ status = mpack_rpending(buf, buflen, tokbuf);
+ assert(!status);
+ return MPACK_EOF;
+ }
+
+ advanced = (size_t)(ptr - ptr_save) - initial_ppos;
+ tokbuf->plen = tokbuf->ppos = 0;
+ *buflen -= advanced;
+ *buf += advanced;
+
+ if (tok->type > MPACK_TOKEN_MAP) {
+ tokbuf->passthrough = tok->length;
+ }
+
+done:
+ return MPACK_OK;
+}
+
+MPACK_API int mpack_write(mpack_tokbuf_t *tokbuf, char **buf, size_t *buflen,
+ const mpack_token_t *t)
+{
+ int status;
+ char *ptr;
+ size_t ptrlen;
+ mpack_token_t tok = tokbuf->plen ? tokbuf->pending_tok : *t;
+ assert(*buf && *buflen);
+
+ if (tok.type == MPACK_TOKEN_CHUNK) {
+ size_t written, pending, count;
+ if (!tokbuf->plen) tokbuf->ppos = 0;
+ written = tokbuf->ppos;
+ pending = tok.length - written;
+ count = MIN(pending, *buflen);
+ memcpy(*buf, tok.data.chunk_ptr + written, count);
+ *buf += count;
+ *buflen -= count;
+ tokbuf->ppos += count;
+ tokbuf->plen = count == pending ? 0 : tok.length;
+ if (count == pending) {
+ return MPACK_OK;
+ } else {
+ tokbuf->pending_tok = tok;
+ return MPACK_EOF;
+ }
+ }
+
+ if (tokbuf->plen) return mpack_wpending(buf, buflen, tokbuf);
+
+ if (*buflen < MPACK_MAX_TOKEN_LEN) {
+ ptr = tokbuf->pending;
+ ptrlen = sizeof(tokbuf->pending);
+ } else {
+ ptr = *buf;
+ ptrlen = *buflen;
+ }
+
+ if ((status = mpack_wtoken(&tok, &ptr, &ptrlen))) return status;
+
+ if (*buflen < MPACK_MAX_TOKEN_LEN) {
+ size_t toklen = sizeof(tokbuf->pending) - ptrlen;
+ size_t write_cnt = MIN(toklen, *buflen);
+ memcpy(*buf, tokbuf->pending, write_cnt);
+ *buf += write_cnt;
+ *buflen -= write_cnt;
+ if (write_cnt < toklen) {
+ assert(!*buflen);
+ tokbuf->plen = toklen;
+ tokbuf->ppos = write_cnt;
+ tokbuf->pending_tok = tok;
+ return MPACK_EOF;
+ }
+ } else {
+ *buflen -= (size_t)(ptr - *buf);
+ *buf = ptr;
+ }
+
+ return MPACK_OK;
+}
+
+static int mpack_rtoken(const char **buf, size_t *buflen,
+ mpack_token_t *tok)
+{
+ unsigned char t = ADVANCE(buf, buflen);
+ if (t < 0x80) {
+ /* positive fixint */
+ return mpack_value(MPACK_TOKEN_UINT, 1, mpack_byte(t), tok);
+ } else if (t < 0x90) {
+ /* fixmap */
+ return mpack_blob(MPACK_TOKEN_MAP, t & 0xf, 0, tok);
+ } else if (t < 0xa0) {
+ /* fixarray */
+ return mpack_blob(MPACK_TOKEN_ARRAY, t & 0xf, 0, tok);
+ } else if (t < 0xc0) {
+ /* fixstr */
+ return mpack_blob(MPACK_TOKEN_STR, t & 0x1f, 0, tok);
+ } else if (t < 0xe0) {
+ switch (t) {
+ case 0xc0: /* nil */
+ return mpack_value(MPACK_TOKEN_NIL, 0, mpack_byte(0), tok);
+ case 0xc2: /* false */
+ return mpack_value(MPACK_TOKEN_BOOLEAN, 1, mpack_byte(0), tok);
+ case 0xc3: /* true */
+ return mpack_value(MPACK_TOKEN_BOOLEAN, 1, mpack_byte(1), tok);
+ case 0xc4: /* bin 8 */
+ case 0xc5: /* bin 16 */
+ case 0xc6: /* bin 32 */
+ return mpack_rblob(MPACK_TOKEN_BIN, TLEN(t, 0xc4), buf, buflen, tok);
+ case 0xc7: /* ext 8 */
+ case 0xc8: /* ext 16 */
+ case 0xc9: /* ext 32 */
+ return mpack_rblob(MPACK_TOKEN_EXT, TLEN(t, 0xc7), buf, buflen, tok);
+ case 0xca: /* float 32 */
+ case 0xcb: /* float 64 */
+ return mpack_rvalue(MPACK_TOKEN_FLOAT, TLEN(t, 0xc8), buf, buflen, tok);
+ case 0xcc: /* uint 8 */
+ case 0xcd: /* uint 16 */
+ case 0xce: /* uint 32 */
+ case 0xcf: /* uint 64 */
+ return mpack_rvalue(MPACK_TOKEN_UINT, TLEN(t, 0xcc), buf, buflen, tok);
+ case 0xd0: /* int 8 */
+ case 0xd1: /* int 16 */
+ case 0xd2: /* int 32 */
+ case 0xd3: /* int 64 */
+ return mpack_rvalue(MPACK_TOKEN_SINT, TLEN(t, 0xd0), buf, buflen, tok);
+ case 0xd4: /* fixext 1 */
+ case 0xd5: /* fixext 2 */
+ case 0xd6: /* fixext 4 */
+ case 0xd7: /* fixext 8 */
+ case 0xd8: /* fixext 16 */
+ if (*buflen == 0) {
+ /* require only one extra byte for the type code */
+ tok->length = 1;
+ return MPACK_EOF;
+ }
+ tok->length = TLEN(t, 0xd4);
+ tok->type = MPACK_TOKEN_EXT;
+ tok->data.ext_type = ADVANCE(buf, buflen);
+ return MPACK_OK;
+ case 0xd9: /* str 8 */
+ case 0xda: /* str 16 */
+ case 0xdb: /* str 32 */
+ return mpack_rblob(MPACK_TOKEN_STR, TLEN(t, 0xd9), buf, buflen, tok);
+ case 0xdc: /* array 16 */
+ case 0xdd: /* array 32 */
+ return mpack_rblob(MPACK_TOKEN_ARRAY, TLEN(t, 0xdb), buf, buflen, tok);
+ case 0xde: /* map 16 */
+ case 0xdf: /* map 32 */
+ return mpack_rblob(MPACK_TOKEN_MAP, TLEN(t, 0xdd), buf, buflen, tok);
+ default:
+ return MPACK_ERROR;
+ }
+ } else {
+ /* negative fixint */
+ return mpack_value(MPACK_TOKEN_SINT, 1, mpack_byte(t), tok);
+ }
+}
+
+static int mpack_rpending(const char **buf, size_t *buflen,
+ mpack_tokbuf_t *state)
+{
+ size_t count;
+ assert(state->ppos < state->plen);
+ count = MIN(state->plen - state->ppos, *buflen);
+ memcpy(state->pending + state->ppos, *buf, count);
+ state->ppos += count;
+ if (state->ppos < state->plen) {
+ /* consume buffer since no token will be parsed yet. */
+ *buf += *buflen;
+ *buflen = 0;
+ return 0;
+ }
+ return 1;
+}
+
+static int mpack_rvalue(mpack_token_type_t type, mpack_uint32_t remaining,
+ const char **buf, size_t *buflen, mpack_token_t *tok)
+{
+ if (*buflen < remaining) {
+ tok->length = remaining;
+ return MPACK_EOF;
+ }
+
+ mpack_value(type, remaining, mpack_byte(0), tok);
+
+ while (remaining) {
+ mpack_uint32_t byte = ADVANCE(buf, buflen), byte_idx, byte_shift;
+ byte_idx = (mpack_uint32_t)--remaining;
+ byte_shift = (byte_idx % 4) * 8;
+ tok->data.value.lo |= byte << byte_shift;
+ if (remaining == 4) {
+ /* unpacked the first half of a 8-byte value, shift what was parsed to the
+ * "hi" field and reset "lo" for the trailing 4 bytes. */
+ tok->data.value.hi = tok->data.value.lo;
+ tok->data.value.lo = 0;
+ }
+ }
+
+ if (type == MPACK_TOKEN_SINT) {
+ mpack_uint32_t hi = tok->data.value.hi;
+ mpack_uint32_t lo = tok->data.value.lo;
+ mpack_uint32_t msb = (tok->length == 8 && hi >> 31) ||
+ (tok->length == 4 && lo >> 31) ||
+ (tok->length == 2 && lo >> 15) ||
+ (tok->length == 1 && lo >> 7);
+ if (!msb) {
+ tok->type = MPACK_TOKEN_UINT;
+ }
+ }
+
+ return MPACK_OK;
+}
+
+static int mpack_rblob(mpack_token_type_t type, mpack_uint32_t tlen,
+ const char **buf, size_t *buflen, mpack_token_t *tok)
+{
+ mpack_token_t l;
+ mpack_uint32_t required = tlen + (type == MPACK_TOKEN_EXT ? 1 : 0);
+
+ if (*buflen < required) {
+ tok->length = required;
+ return MPACK_EOF;
+ }
+
+ l.data.value.lo = 0;
+ mpack_rvalue(MPACK_TOKEN_UINT, tlen, buf, buflen, &l);
+ tok->type = type;
+ tok->length = l.data.value.lo;
+
+ if (type == MPACK_TOKEN_EXT) {
+ tok->data.ext_type = ADVANCE(buf, buflen);
+ }
+
+ return MPACK_OK;
+}
+
+static int mpack_wtoken(const mpack_token_t *tok, char **buf,
+ size_t *buflen)
+{
+ switch (tok->type) {
+ case MPACK_TOKEN_NIL:
+ return mpack_w1(buf, buflen, 0xc0);
+ case MPACK_TOKEN_BOOLEAN:
+ return mpack_w1(buf, buflen, tok->data.value.lo ? 0xc3 : 0xc2);
+ case MPACK_TOKEN_UINT:
+ return mpack_wpint(buf, buflen, tok->data.value);
+ case MPACK_TOKEN_SINT:
+ return mpack_wnint(buf, buflen, tok->data.value);
+ case MPACK_TOKEN_FLOAT:
+ return mpack_wfloat(buf, buflen, tok);
+ case MPACK_TOKEN_BIN:
+ return mpack_wbin(buf, buflen, tok->length);
+ case MPACK_TOKEN_STR:
+ return mpack_wstr(buf, buflen, tok->length);
+ case MPACK_TOKEN_EXT:
+ return mpack_wext(buf, buflen, tok->data.ext_type, tok->length);
+ case MPACK_TOKEN_ARRAY:
+ return mpack_warray(buf, buflen, tok->length);
+ case MPACK_TOKEN_MAP:
+ return mpack_wmap(buf, buflen, tok->length);
+ default:
+ return MPACK_ERROR;
+ }
+}
+
+static int mpack_wpending(char **buf, size_t *buflen, mpack_tokbuf_t *state)
+{
+ size_t count;
+ assert(state->ppos < state->plen);
+ count = MIN(state->plen - state->ppos, *buflen);
+ memcpy(*buf, state->pending + state->ppos, count);
+ state->ppos += count;
+ *buf += count;
+ *buflen -= count;
+ if (state->ppos == state->plen) {
+ state->plen = 0;
+ return MPACK_OK;
+ }
+ return MPACK_EOF;
+}
+
+static int mpack_wpint(char **buf, size_t *buflen, mpack_value_t val)
+{
+ mpack_uint32_t hi = val.hi;
+ mpack_uint32_t lo = val.lo;
+
+ if (hi) {
+ /* uint 64 */
+ return mpack_w1(buf, buflen, 0xcf) ||
+ mpack_w4(buf, buflen, hi) ||
+ mpack_w4(buf, buflen, lo);
+ } else if (lo > 0xffff) {
+ /* uint 32 */
+ return mpack_w1(buf, buflen, 0xce) ||
+ mpack_w4(buf, buflen, lo);
+ } else if (lo > 0xff) {
+ /* uint 16 */
+ return mpack_w1(buf, buflen, 0xcd) ||
+ mpack_w2(buf, buflen, lo);
+ } else if (lo > 0x7f) {
+ /* uint 8 */
+ return mpack_w1(buf, buflen, 0xcc) ||
+ mpack_w1(buf, buflen, lo);
+ } else {
+ return mpack_w1(buf, buflen, lo);
+ }
+}
+
+static int mpack_wnint(char **buf, size_t *buflen, mpack_value_t val)
+{
+ mpack_uint32_t hi = val.hi;
+ mpack_uint32_t lo = val.lo;
+
+ if (lo < 0x80000000) {
+ /* int 64 */
+ return mpack_w1(buf, buflen, 0xd3) ||
+ mpack_w4(buf, buflen, hi) ||
+ mpack_w4(buf, buflen, lo);
+ } else if (lo < 0xffff7fff) {
+ /* int 32 */
+ return mpack_w1(buf, buflen, 0xd2) ||
+ mpack_w4(buf, buflen, lo);
+ } else if (lo < 0xffffff7f) {
+ /* int 16 */
+ return mpack_w1(buf, buflen, 0xd1) ||
+ mpack_w2(buf, buflen, lo);
+ } else if (lo < 0xffffffe0) {
+ /* int 8 */
+ return mpack_w1(buf, buflen, 0xd0) ||
+ mpack_w1(buf, buflen, lo);
+ } else {
+ /* negative fixint */
+ return mpack_w1(buf, buflen, (mpack_uint32_t)(0x100 + lo));
+ }
+}
+
+static int mpack_wfloat(char **buf, size_t *buflen,
+ const mpack_token_t *tok)
+{
+ if (tok->length == 4) {
+ return mpack_w1(buf, buflen, 0xca) ||
+ mpack_w4(buf, buflen, tok->data.value.lo);
+ } else if (tok->length == 8) {
+ return mpack_w1(buf, buflen, 0xcb) ||
+ mpack_w4(buf, buflen, tok->data.value.hi) ||
+ mpack_w4(buf, buflen, tok->data.value.lo);
+ } else {
+ return MPACK_ERROR;
+ }
+}
+
+static int mpack_wstr(char **buf, size_t *buflen, mpack_uint32_t len)
+{
+ if (len < 0x20) {
+ return mpack_w1(buf, buflen, 0xa0 | len);
+ } else if (len < 0x100) {
+ return mpack_w1(buf, buflen, 0xd9) ||
+ mpack_w1(buf, buflen, len);
+ } else if (len < 0x10000) {
+ return mpack_w1(buf, buflen, 0xda) ||
+ mpack_w2(buf, buflen, len);
+ } else {
+ return mpack_w1(buf, buflen, 0xdb) ||
+ mpack_w4(buf, buflen, len);
+ }
+}
+
+static int mpack_wbin(char **buf, size_t *buflen, mpack_uint32_t len)
+{
+ if (len < 0x100) {
+ return mpack_w1(buf, buflen, 0xc4) ||
+ mpack_w1(buf, buflen, len);
+ } else if (len < 0x10000) {
+ return mpack_w1(buf, buflen, 0xc5) ||
+ mpack_w2(buf, buflen, len);
+ } else {
+ return mpack_w1(buf, buflen, 0xc6) ||
+ mpack_w4(buf, buflen, len);
+ }
+}
+
+static int mpack_wext(char **buf, size_t *buflen, int type,
+ mpack_uint32_t len)
+{
+ mpack_uint32_t t;
+ assert(type >= 0 && type < 0x80);
+ t = (mpack_uint32_t)type;
+ switch (len) {
+ case 1: mpack_w1(buf, buflen, 0xd4); return mpack_w1(buf, buflen, t);
+ case 2: mpack_w1(buf, buflen, 0xd5); return mpack_w1(buf, buflen, t);
+ case 4: mpack_w1(buf, buflen, 0xd6); return mpack_w1(buf, buflen, t);
+ case 8: mpack_w1(buf, buflen, 0xd7); return mpack_w1(buf, buflen, t);
+ case 16: mpack_w1(buf, buflen, 0xd8); return mpack_w1(buf, buflen, t);
+ default:
+ if (len < 0x100) {
+ return mpack_w1(buf, buflen, 0xc7) ||
+ mpack_w1(buf, buflen, len) ||
+ mpack_w1(buf, buflen, t);
+ } else if (len < 0x10000) {
+ return mpack_w1(buf, buflen, 0xc8) ||
+ mpack_w2(buf, buflen, len) ||
+ mpack_w1(buf, buflen, t);
+ } else {
+ return mpack_w1(buf, buflen, 0xc9) ||
+ mpack_w4(buf, buflen, len) ||
+ mpack_w1(buf, buflen, t);
+ }
+ }
+}
+
+static int mpack_warray(char **buf, size_t *buflen, mpack_uint32_t len)
+{
+ if (len < 0x10) {
+ return mpack_w1(buf, buflen, 0x90 | len);
+ } else if (len < 0x10000) {
+ return mpack_w1(buf, buflen, 0xdc) ||
+ mpack_w2(buf, buflen, len);
+ } else {
+ return mpack_w1(buf, buflen, 0xdd) ||
+ mpack_w4(buf, buflen, len);
+ }
+}
+
+static int mpack_wmap(char **buf, size_t *buflen, mpack_uint32_t len)
+{
+ if (len < 0x10) {
+ return mpack_w1(buf, buflen, 0x80 | len);
+ } else if (len < 0x10000) {
+ return mpack_w1(buf, buflen, 0xde) ||
+ mpack_w2(buf, buflen, len);
+ } else {
+ return mpack_w1(buf, buflen, 0xdf) ||
+ mpack_w4(buf, buflen, len);
+ }
+}
+
+static int mpack_w1(char **b, size_t *bl, mpack_uint32_t v)
+{
+ (*bl)--;
+ *(*b)++ = (char)(v & 0xff);
+ return MPACK_OK;
+}
+
+static int mpack_w2(char **b, size_t *bl, mpack_uint32_t v)
+{
+ *bl -= 2;
+ *(*b)++ = (char)((v >> 8) & 0xff);
+ *(*b)++ = (char)(v & 0xff);
+ return MPACK_OK;
+}
+
+static int mpack_w4(char **b, size_t *bl, mpack_uint32_t v)
+{
+ *bl -= 4;
+ *(*b)++ = (char)((v >> 24) & 0xff);
+ *(*b)++ = (char)((v >> 16) & 0xff);
+ *(*b)++ = (char)((v >> 8) & 0xff);
+ *(*b)++ = (char)(v & 0xff);
+ return MPACK_OK;
+}
+
+static int mpack_value(mpack_token_type_t type, mpack_uint32_t length,
+ mpack_value_t value, mpack_token_t *tok)
+{
+ tok->type = type;
+ tok->length = length;
+ tok->data.value = value;
+ return MPACK_OK;
+}
+
+static int mpack_blob(mpack_token_type_t type, mpack_uint32_t length,
+ int ext_type, mpack_token_t *tok)
+{
+ tok->type = type;
+ tok->length = length;
+ tok->data.ext_type = ext_type;
+ return MPACK_OK;
+}
+
+static mpack_value_t mpack_byte(unsigned char byte)
+{
+ mpack_value_t rv;
+ rv.lo = byte;
+ rv.hi = 0;
+ return rv;
+}
diff --git a/src/mpack/mpack_core.h b/src/mpack/mpack_core.h
new file mode 100644
index 0000000000..9edd13c41e
--- /dev/null
+++ b/src/mpack/mpack_core.h
@@ -0,0 +1,87 @@
+#ifndef MPACK_CORE_H
+#define MPACK_CORE_H
+
+#ifndef MPACK_API
+# define MPACK_API extern
+#endif
+
+#include <assert.h>
+#include <limits.h>
+#include <stddef.h>
+
+#ifdef __GNUC__
+# define FPURE __attribute__((const))
+# define FNONULL __attribute__((nonnull))
+# define FNONULL_ARG(x) __attribute__((nonnull x))
+# define FUNUSED __attribute__((unused))
+#else
+# define FPURE
+# define FNONULL
+# define FNONULL_ARG(x)
+# define FUNUSED
+#endif
+
+#if UINT_MAX == 0xffffffff
+typedef int mpack_sint32_t;
+typedef unsigned int mpack_uint32_t;
+#elif ULONG_MAX == 0xffffffff
+typedef long mpack_sint32_t;
+typedef unsigned long mpack_uint32_t;
+#else
+# error "can't find unsigned 32-bit integer type"
+#endif
+
+typedef struct mpack_value_s {
+ mpack_uint32_t lo, hi;
+} mpack_value_t;
+
+
+enum {
+ MPACK_OK = 0,
+ MPACK_EOF = 1,
+ MPACK_ERROR = 2
+};
+
+#define MPACK_MAX_TOKEN_LEN 9 /* 64-bit ints/floats plus type code */
+
+typedef enum {
+ MPACK_TOKEN_NIL = 1,
+ MPACK_TOKEN_BOOLEAN = 2,
+ MPACK_TOKEN_UINT = 3,
+ MPACK_TOKEN_SINT = 4,
+ MPACK_TOKEN_FLOAT = 5,
+ MPACK_TOKEN_CHUNK = 6,
+ MPACK_TOKEN_ARRAY = 7,
+ MPACK_TOKEN_MAP = 8,
+ MPACK_TOKEN_BIN = 9,
+ MPACK_TOKEN_STR = 10,
+ MPACK_TOKEN_EXT = 11
+} mpack_token_type_t;
+
+typedef struct mpack_token_s {
+ mpack_token_type_t type; /* Type of token */
+ mpack_uint32_t length; /* Byte length for str/bin/ext/chunk/float/int/uint.
+ Item count for array/map. */
+ union {
+ mpack_value_t value; /* 32-bit parts of primitives (bool,int,float) */
+ const char *chunk_ptr; /* Chunk of data from str/bin/ext */
+ int ext_type; /* Type field for ext tokens */
+ } data;
+} mpack_token_t;
+
+typedef struct mpack_tokbuf_s {
+ char pending[MPACK_MAX_TOKEN_LEN];
+ mpack_token_t pending_tok;
+ size_t ppos, plen;
+ mpack_uint32_t passthrough;
+} mpack_tokbuf_t;
+
+#define MPACK_TOKBUF_INITIAL_VALUE { { 0 }, { 0, 0, { { 0, 0 } } }, 0, 0, 0 }
+
+MPACK_API void mpack_tokbuf_init(mpack_tokbuf_t *tb) FUNUSED FNONULL;
+MPACK_API int mpack_read(mpack_tokbuf_t *tb, const char **b, size_t *bl,
+ mpack_token_t *tok) FUNUSED FNONULL;
+MPACK_API int mpack_write(mpack_tokbuf_t *tb, char **b, size_t *bl,
+ const mpack_token_t *tok) FUNUSED FNONULL;
+
+#endif /* MPACK_CORE_H */
diff --git a/src/mpack/object.c b/src/mpack/object.c
new file mode 100644
index 0000000000..e2d893bc88
--- /dev/null
+++ b/src/mpack/object.c
@@ -0,0 +1,198 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
+#include <string.h>
+
+#include "object.h"
+
+static int mpack_parser_full(mpack_parser_t *w);
+static mpack_node_t *mpack_parser_push(mpack_parser_t *w);
+static mpack_node_t *mpack_parser_pop(mpack_parser_t *w);
+
+MPACK_API void mpack_parser_init(mpack_parser_t *parser,
+ mpack_uint32_t capacity)
+{
+ mpack_tokbuf_init(&parser->tokbuf);
+ parser->data.p = NULL;
+ parser->capacity = capacity ? capacity : MPACK_MAX_OBJECT_DEPTH;
+ parser->size = 0;
+ parser->exiting = 0;
+ memset(parser->items, 0, sizeof(mpack_node_t) * (parser->capacity + 1));
+ parser->items[0].pos = (size_t)-1;
+ parser->status = 0;
+}
+
+#define MPACK_EXCEPTION_CHECK(parser) \
+ do { \
+ if (parser->status == MPACK_EXCEPTION) { \
+ return MPACK_EXCEPTION; \
+ } \
+ } while (0)
+
+#define MPACK_WALK(action) \
+ do { \
+ mpack_node_t *n; \
+ \
+ if (parser->exiting) goto exit; \
+ if (mpack_parser_full(parser)) return MPACK_NOMEM; \
+ n = mpack_parser_push(parser); \
+ action; \
+ MPACK_EXCEPTION_CHECK(parser); \
+ parser->exiting = 1; \
+ return MPACK_EOF; \
+ \
+exit: \
+ parser->exiting = 0; \
+ while ((n = mpack_parser_pop(parser))) { \
+ exit_cb(parser, n); \
+ MPACK_EXCEPTION_CHECK(parser); \
+ if (!parser->size) return MPACK_OK; \
+ } \
+ \
+ return MPACK_EOF; \
+ } while (0)
+
+MPACK_API int mpack_parse_tok(mpack_parser_t *parser, mpack_token_t tok,
+ mpack_walk_cb enter_cb, mpack_walk_cb exit_cb)
+{
+ MPACK_EXCEPTION_CHECK(parser);
+ MPACK_WALK({n->tok = tok; enter_cb(parser, n);});
+}
+
+MPACK_API int mpack_unparse_tok(mpack_parser_t *parser, mpack_token_t *tok,
+ mpack_walk_cb enter_cb, mpack_walk_cb exit_cb)
+{
+ MPACK_EXCEPTION_CHECK(parser);
+ MPACK_WALK({enter_cb(parser, n); *tok = n->tok;});
+}
+
+MPACK_API int mpack_parse(mpack_parser_t *parser, const char **buf,
+ size_t *buflen, mpack_walk_cb enter_cb, mpack_walk_cb exit_cb)
+{
+ int status = MPACK_EOF;
+ MPACK_EXCEPTION_CHECK(parser);
+
+ while (*buflen && status) {
+ mpack_token_t tok;
+ mpack_tokbuf_t *tb = &parser->tokbuf;
+ const char *buf_save = *buf;
+ size_t buflen_save = *buflen;
+
+ if ((status = mpack_read(tb, buf, buflen, &tok)) == MPACK_EOF) continue;
+ else if (status == MPACK_ERROR) goto rollback;
+
+ do {
+ status = mpack_parse_tok(parser, tok, enter_cb, exit_cb);
+ MPACK_EXCEPTION_CHECK(parser);
+ } while (parser->exiting);
+
+ if (status != MPACK_NOMEM) continue;
+
+rollback:
+ /* restore buf/buflen so the next call will try to read the same token */
+ *buf = buf_save;
+ *buflen = buflen_save;
+ break;
+ }
+
+ return status;
+}
+
+MPACK_API int mpack_unparse(mpack_parser_t *parser, char **buf, size_t *buflen,
+ mpack_walk_cb enter_cb, mpack_walk_cb exit_cb)
+{
+ int status = MPACK_EOF;
+ MPACK_EXCEPTION_CHECK(parser);
+
+ while (*buflen && status) {
+ int write_status;
+ mpack_token_t tok;
+ mpack_tokbuf_t *tb = &parser->tokbuf;
+
+ if (!tb->plen)
+ parser->status = mpack_unparse_tok(parser, &tok, enter_cb, exit_cb);
+
+ MPACK_EXCEPTION_CHECK(parser);
+
+ status = parser->status;
+
+ if (status == MPACK_NOMEM)
+ break;
+
+ if (parser->exiting) {
+ write_status = mpack_write(tb, buf, buflen, &tok);
+ status = write_status ? write_status : status;
+ }
+ }
+
+ return status;
+}
+
+MPACK_API void mpack_parser_copy(mpack_parser_t *dst, mpack_parser_t *src)
+{
+ mpack_uint32_t i;
+ mpack_uint32_t dst_capacity = dst->capacity;
+ assert(src->capacity <= dst_capacity);
+ /* copy all fields except the stack */
+ memcpy(dst, src, sizeof(mpack_one_parser_t) - sizeof(mpack_node_t));
+ /* reset capacity */
+ dst->capacity = dst_capacity;
+ /* copy the stack */
+ for (i = 0; i <= src->capacity; i++) {
+ dst->items[i] = src->items[i];
+ }
+}
+
+static int mpack_parser_full(mpack_parser_t *parser)
+{
+ return parser->size == parser->capacity;
+}
+
+static mpack_node_t *mpack_parser_push(mpack_parser_t *parser)
+{
+ mpack_node_t *top;
+ assert(parser->size < parser->capacity);
+ top = parser->items + parser->size + 1;
+ top->data[0].p = NULL;
+ top->data[1].p = NULL;
+ top->pos = 0;
+ top->key_visited = 0;
+ /* increase size and invoke callback, passing parent node if any */
+ parser->size++;
+ return top;
+}
+
+static mpack_node_t *mpack_parser_pop(mpack_parser_t *parser)
+{
+ mpack_node_t *top, *parent;
+ assert(parser->size);
+ top = parser->items + parser->size;
+
+ if (top->tok.type > MPACK_TOKEN_CHUNK && top->pos < top->tok.length) {
+ /* continue processing children */
+ return NULL;
+ }
+
+ parent = MPACK_PARENT_NODE(top);
+ if (parent) {
+ /* we use parent->tok.length to keep track of how many children remain.
+ * update it to reflect the processed node. */
+ if (top->tok.type == MPACK_TOKEN_CHUNK) {
+ parent->pos += top->tok.length;
+ } else if (parent->tok.type == MPACK_TOKEN_MAP) {
+ /* maps allow up to 2^32 - 1 pairs, so to allow this many items in a
+ * 32-bit length variable we use an additional flag to determine if the
+ * key of a certain position was visited */
+ if (parent->key_visited) {
+ parent->pos++;
+ }
+ parent->key_visited = !parent->key_visited;
+ } else {
+ parent->pos++;
+ }
+ }
+
+ parser->size--;
+ return top;
+}
+
diff --git a/src/mpack/object.h b/src/mpack/object.h
new file mode 100644
index 0000000000..5327e56e18
--- /dev/null
+++ b/src/mpack/object.h
@@ -0,0 +1,86 @@
+#ifndef MPACK_OBJECT_H
+#define MPACK_OBJECT_H
+
+#include "mpack_core.h"
+#include "conv.h"
+
+#ifndef MPACK_MAX_OBJECT_DEPTH
+# define MPACK_MAX_OBJECT_DEPTH 32
+#endif
+
+#define MPACK_PARENT_NODE(n) (((n) - 1)->pos == (size_t)-1 ? NULL : (n) - 1)
+
+#define MPACK_THROW(parser) \
+ do { \
+ parser->status = MPACK_EXCEPTION; \
+ return; \
+ } while (0)
+
+enum {
+ MPACK_EXCEPTION = -1,
+ MPACK_NOMEM = MPACK_ERROR + 1
+};
+
+/* Storing integer in pointers in undefined behavior according to the C
+ * standard. Define a union type to accomodate arbitrary user data associated
+ * with nodes(and with requests in rpc.h). */
+typedef union {
+ void *p;
+ mpack_uintmax_t u;
+ mpack_sintmax_t i;
+ double d;
+} mpack_data_t;
+
+typedef struct mpack_node_s {
+ mpack_token_t tok;
+ size_t pos;
+ /* flag to determine if the key was visited when traversing a map */
+ int key_visited;
+ /* allow 2 instances mpack_data_t per node. the reason is that when
+ * serializing, the user may need to keep track of traversal state besides the
+ * parent node reference */
+ mpack_data_t data[2];
+} mpack_node_t;
+
+#define MPACK_PARSER_STRUCT(c) \
+ struct { \
+ mpack_data_t data; \
+ mpack_uint32_t size, capacity; \
+ int status; \
+ int exiting; \
+ mpack_tokbuf_t tokbuf; \
+ mpack_node_t items[c + 1]; \
+ }
+
+/* Some compilers warn against anonymous structs:
+ * https://github.com/libmpack/libmpack/issues/6 */
+typedef MPACK_PARSER_STRUCT(0) mpack_one_parser_t;
+
+#define MPACK_PARSER_STRUCT_SIZE(c) \
+ (sizeof(mpack_node_t) * c + \
+ sizeof(mpack_one_parser_t))
+
+typedef MPACK_PARSER_STRUCT(MPACK_MAX_OBJECT_DEPTH) mpack_parser_t;
+typedef void(*mpack_walk_cb)(mpack_parser_t *w, mpack_node_t *n);
+
+MPACK_API void mpack_parser_init(mpack_parser_t *p, mpack_uint32_t c)
+ FUNUSED FNONULL;
+
+MPACK_API int mpack_parse_tok(mpack_parser_t *walker, mpack_token_t tok,
+ mpack_walk_cb enter_cb, mpack_walk_cb exit_cb)
+ FUNUSED FNONULL_ARG((1,3,4));
+MPACK_API int mpack_unparse_tok(mpack_parser_t *walker, mpack_token_t *tok,
+ mpack_walk_cb enter_cb, mpack_walk_cb exit_cb)
+ FUNUSED FNONULL_ARG((1,2,3,4));
+
+MPACK_API int mpack_parse(mpack_parser_t *parser, const char **b, size_t *bl,
+ mpack_walk_cb enter_cb, mpack_walk_cb exit_cb)
+ FUNUSED FNONULL_ARG((1,2,3,4,5));
+MPACK_API int mpack_unparse(mpack_parser_t *parser, char **b, size_t *bl,
+ mpack_walk_cb enter_cb, mpack_walk_cb exit_cb)
+ FUNUSED FNONULL_ARG((1,2,3,4,5));
+
+MPACK_API void mpack_parser_copy(mpack_parser_t *d, mpack_parser_t *s)
+ FUNUSED FNONULL;
+
+#endif /* MPACK_OBJECT_H */
diff --git a/src/mpack/rpc.c b/src/mpack/rpc.c
new file mode 100644
index 0000000000..2d251284ba
--- /dev/null
+++ b/src/mpack/rpc.c
@@ -0,0 +1,334 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
+#include <string.h>
+
+#include "rpc.h"
+
+enum {
+ MPACK_RPC_RECEIVE_ARRAY = 1,
+ MPACK_RPC_RECEIVE_TYPE,
+ MPACK_RPC_RECEIVE_ID
+};
+
+static mpack_rpc_header_t mpack_rpc_request_hdr(void);
+static mpack_rpc_header_t mpack_rpc_reply_hdr(void);
+static mpack_rpc_header_t mpack_rpc_notify_hdr(void);
+static int mpack_rpc_put(mpack_rpc_session_t *s, mpack_rpc_message_t m);
+static int mpack_rpc_pop(mpack_rpc_session_t *s, mpack_rpc_message_t *m);
+static void mpack_rpc_reset_hdr(mpack_rpc_header_t *hdr);
+
+MPACK_API void mpack_rpc_session_init(mpack_rpc_session_t *session,
+ mpack_uint32_t capacity)
+{
+ session->capacity = capacity ? capacity : MPACK_RPC_MAX_REQUESTS;
+ session->request_id = 0;
+ mpack_tokbuf_init(&session->reader);
+ mpack_tokbuf_init(&session->writer);
+ mpack_rpc_reset_hdr(&session->receive);
+ mpack_rpc_reset_hdr(&session->send);
+ memset(session->slots, 0,
+ sizeof(struct mpack_rpc_slot_s) * session->capacity);
+}
+
+MPACK_API int mpack_rpc_receive_tok(mpack_rpc_session_t *session,
+ mpack_token_t tok, mpack_rpc_message_t *msg)
+{
+ int type;
+
+ if (session->receive.index == 0) {
+ if (tok.type != MPACK_TOKEN_ARRAY)
+ /* not an array */
+ return MPACK_RPC_EARRAY;
+
+ if (tok.length < 3 || tok.length > 4)
+ /* invalid array length */
+ return MPACK_RPC_EARRAYL;
+
+ session->receive.toks[0] = tok;
+ session->receive.index++;
+ return MPACK_EOF; /* get the type */
+ }
+
+ if (session->receive.index == 1) {
+
+ if (tok.type != MPACK_TOKEN_UINT || tok.length > 1 || tok.data.value.lo > 2)
+ /* invalid type */
+ return MPACK_RPC_ETYPE;
+
+ if (tok.data.value.lo < 2 && session->receive.toks[0].length != 4)
+ /* request or response with array length != 4 */
+ return MPACK_RPC_EARRAYL;
+
+ if (tok.data.value.lo == 2 && session->receive.toks[0].length != 3)
+ /* notification with array length != 3 */
+ return MPACK_RPC_EARRAYL;
+
+ session->receive.toks[1] = tok;
+ session->receive.index++;
+
+ if (tok.data.value.lo < 2) return MPACK_EOF;
+
+ type = MPACK_RPC_NOTIFICATION;
+ goto end;
+ }
+
+ assert(session->receive.index == 2);
+
+ if (tok.type != MPACK_TOKEN_UINT || tok.length > 4)
+ /* invalid request/response id */
+ return MPACK_RPC_EMSGID;
+
+ msg->id = tok.data.value.lo;
+ msg->data.p = NULL;
+ type = (int)session->receive.toks[1].data.value.lo + MPACK_RPC_REQUEST;
+
+ if (type == MPACK_RPC_RESPONSE && !mpack_rpc_pop(session, msg))
+ /* response with invalid id */
+ return MPACK_RPC_ERESPID;
+
+end:
+ mpack_rpc_reset_hdr(&session->receive);
+ return type;
+}
+
+MPACK_API int mpack_rpc_request_tok(mpack_rpc_session_t *session,
+ mpack_token_t *tok, mpack_data_t data)
+{
+ if (session->send.index == 0) {
+ int status;
+ mpack_rpc_message_t msg;
+ do {
+ msg.id = session->request_id;
+ msg.data = data;
+ session->send = mpack_rpc_request_hdr();
+ session->send.toks[2].type = MPACK_TOKEN_UINT;
+ session->send.toks[2].data.value.lo = msg.id;
+ session->send.toks[2].data.value.hi = 0;
+ *tok = session->send.toks[0];
+ status = mpack_rpc_put(session, msg);
+ if (status == -1) return MPACK_NOMEM;
+ session->request_id = (session->request_id + 1) % 0xffffffff;
+ } while (!status);
+ session->send.index++;
+ return MPACK_EOF;
+ }
+
+ if (session->send.index == 1) {
+ *tok = session->send.toks[1];
+ session->send.index++;
+ return MPACK_EOF;
+ }
+
+ assert(session->send.index == 2);
+ *tok = session->send.toks[2];
+ mpack_rpc_reset_hdr(&session->send);
+ return MPACK_OK;
+}
+
+MPACK_API int mpack_rpc_reply_tok(mpack_rpc_session_t *session,
+ mpack_token_t *tok, mpack_uint32_t id)
+{
+ if (session->send.index == 0) {
+ session->send = mpack_rpc_reply_hdr();
+ session->send.toks[2].type = MPACK_TOKEN_UINT;
+ session->send.toks[2].data.value.lo = id;
+ session->send.toks[2].data.value.hi = 0;
+ *tok = session->send.toks[0];
+ session->send.index++;
+ return MPACK_EOF;
+ }
+
+ if (session->send.index == 1) {
+ *tok = session->send.toks[1];
+ session->send.index++;
+ return MPACK_EOF;
+ }
+
+ assert(session->send.index == 2);
+ *tok = session->send.toks[2];
+ mpack_rpc_reset_hdr(&session->send);
+ return MPACK_OK;
+}
+
+MPACK_API int mpack_rpc_notify_tok(mpack_rpc_session_t *session,
+ mpack_token_t *tok)
+{
+ if (session->send.index == 0) {
+ session->send = mpack_rpc_notify_hdr();
+ *tok = session->send.toks[0];
+ session->send.index++;
+ return MPACK_EOF;
+ }
+
+ assert(session->send.index == 1);
+ *tok = session->send.toks[1];
+ mpack_rpc_reset_hdr(&session->send);
+ return MPACK_OK;
+}
+
+MPACK_API int mpack_rpc_receive(mpack_rpc_session_t *session, const char **buf,
+ size_t *buflen, mpack_rpc_message_t *msg)
+{
+ int status;
+
+ do {
+ mpack_token_t tok;
+ status = mpack_read(&session->reader, buf, buflen, &tok);
+ if (status) break;
+ status = mpack_rpc_receive_tok(session, tok, msg);
+ if (status >= MPACK_RPC_REQUEST) break;
+ } while (*buflen);
+
+ return status;
+}
+
+MPACK_API int mpack_rpc_request(mpack_rpc_session_t *session, char **buf,
+ size_t *buflen, mpack_data_t data)
+{
+ int status = MPACK_EOF;
+
+ while (status && *buflen) {
+ int write_status;
+ mpack_token_t tok;
+ if (!session->writer.plen) {
+ status = mpack_rpc_request_tok(session, &tok, data);
+ }
+ if (status == MPACK_NOMEM) break;
+ write_status = mpack_write(&session->writer, buf, buflen, &tok);
+ status = write_status ? write_status : status;
+ }
+
+ return status;
+}
+
+MPACK_API int mpack_rpc_reply(mpack_rpc_session_t *session, char **buf,
+ size_t *buflen, mpack_uint32_t id)
+{
+ int status = MPACK_EOF;
+
+ while (status && *buflen) {
+ int write_status;
+ mpack_token_t tok;
+ if (!session->writer.plen) {
+ status = mpack_rpc_reply_tok(session, &tok, id);
+ }
+ write_status = mpack_write(&session->writer, buf, buflen, &tok);
+ status = write_status ? write_status : status;
+ }
+
+ return status;
+}
+
+MPACK_API int mpack_rpc_notify(mpack_rpc_session_t *session, char **buf,
+ size_t *buflen)
+{
+ int status = MPACK_EOF;
+
+ while (status && *buflen) {
+ int write_status;
+ mpack_token_t tok;
+ if (!session->writer.plen) {
+ status = mpack_rpc_notify_tok(session, &tok);
+ }
+ write_status = mpack_write(&session->writer, buf, buflen, &tok);
+ status = write_status ? write_status : status;
+ }
+
+ return status;
+}
+
+MPACK_API void mpack_rpc_session_copy(mpack_rpc_session_t *dst,
+ mpack_rpc_session_t *src)
+{
+ mpack_uint32_t i;
+ mpack_uint32_t dst_capacity = dst->capacity;
+ assert(src->capacity <= dst_capacity);
+ /* copy all fields except slots */
+ memcpy(dst, src, sizeof(mpack_rpc_one_session_t) -
+ sizeof(struct mpack_rpc_slot_s));
+ /* reset capacity */
+ dst->capacity = dst_capacity;
+ /* reinsert requests */
+ memset(dst->slots, 0, sizeof(struct mpack_rpc_slot_s) * dst->capacity);
+ for (i = 0; i < src->capacity; i++) {
+ if (src->slots[i].used) mpack_rpc_put(dst, src->slots[i].msg);
+ }
+}
+
+static mpack_rpc_header_t mpack_rpc_request_hdr(void)
+{
+ mpack_rpc_header_t hdr;
+ hdr.index = 0;
+ hdr.toks[0].type = MPACK_TOKEN_ARRAY;
+ hdr.toks[0].length = 4;
+ hdr.toks[1].type = MPACK_TOKEN_UINT;
+ hdr.toks[1].data.value.lo = 0;
+ hdr.toks[1].data.value.hi = 0;
+ return hdr;
+}
+
+static mpack_rpc_header_t mpack_rpc_reply_hdr(void)
+{
+ mpack_rpc_header_t hdr = mpack_rpc_request_hdr();
+ hdr.toks[1].data.value.lo = 1;
+ hdr.toks[1].data.value.hi = 0;
+ return hdr;
+}
+
+static mpack_rpc_header_t mpack_rpc_notify_hdr(void)
+{
+ mpack_rpc_header_t hdr = mpack_rpc_request_hdr();
+ hdr.toks[0].length = 3;
+ hdr.toks[1].data.value.lo = 2;
+ hdr.toks[1].data.value.hi = 0;
+ return hdr;
+}
+
+static int mpack_rpc_put(mpack_rpc_session_t *session, mpack_rpc_message_t msg)
+{
+ struct mpack_rpc_slot_s *slot = NULL;
+ mpack_uint32_t i;
+ mpack_uint32_t hash = msg.id % session->capacity;
+
+ for (i = 0; i < session->capacity; i++) {
+ if (!session->slots[hash].used || session->slots[hash].msg.id == msg.id) {
+ slot = session->slots + hash;
+ break;
+ }
+ hash = hash > 0 ? hash - 1 : session->capacity - 1;
+ }
+
+ if (!slot) return -1; /* no space */
+ if (slot->msg.id == msg.id && slot->used) return 0; /* duplicate key */
+ slot->msg = msg;
+ slot->used = 1;
+ return 1;
+}
+
+static int mpack_rpc_pop(mpack_rpc_session_t *session, mpack_rpc_message_t *msg)
+{
+ struct mpack_rpc_slot_s *slot = NULL;
+ mpack_uint32_t i;
+ mpack_uint32_t hash = msg->id % session->capacity;
+
+ for (i = 0; i < session->capacity; i++) {
+ if (session->slots[hash].used && session->slots[hash].msg.id == msg->id) {
+ slot = session->slots + hash;
+ break;
+ }
+ hash = hash > 0 ? hash - 1 : session->capacity - 1;
+ }
+
+ if (!slot) return 0;
+
+ *msg = slot->msg;
+ slot->used = 0;
+
+ return 1;
+}
+
+static void mpack_rpc_reset_hdr(mpack_rpc_header_t *hdr)
+{
+ hdr->index = 0;
+}
diff --git a/src/mpack/rpc.h b/src/mpack/rpc.h
new file mode 100644
index 0000000000..c1e8d656b5
--- /dev/null
+++ b/src/mpack/rpc.h
@@ -0,0 +1,83 @@
+#ifndef MPACK_RPC_H
+#define MPACK_RPC_H
+
+#include "mpack_core.h"
+#include "object.h"
+
+#ifndef MPACK_RPC_MAX_REQUESTS
+# define MPACK_RPC_MAX_REQUESTS 32
+#endif
+
+enum {
+ MPACK_RPC_REQUEST = MPACK_NOMEM + 1,
+ MPACK_RPC_RESPONSE,
+ MPACK_RPC_NOTIFICATION,
+ MPACK_RPC_ERROR
+};
+
+enum {
+ MPACK_RPC_EARRAY = MPACK_RPC_ERROR,
+ MPACK_RPC_EARRAYL,
+ MPACK_RPC_ETYPE,
+ MPACK_RPC_EMSGID,
+ MPACK_RPC_ERESPID
+};
+
+typedef struct mpack_rpc_header_s {
+ mpack_token_t toks[3];
+ int index;
+} mpack_rpc_header_t;
+
+typedef struct mpack_rpc_message_s {
+ mpack_uint32_t id;
+ mpack_data_t data;
+} mpack_rpc_message_t;
+
+struct mpack_rpc_slot_s {
+ int used;
+ mpack_rpc_message_t msg;
+};
+
+#define MPACK_RPC_SESSION_STRUCT(c) \
+ struct { \
+ mpack_tokbuf_t reader, writer; \
+ mpack_rpc_header_t receive, send; \
+ mpack_uint32_t request_id, capacity; \
+ struct mpack_rpc_slot_s slots[c]; \
+ }
+
+/* Some compilers warn against anonymous structs:
+ * https://github.com/libmpack/libmpack/issues/6 */
+typedef MPACK_RPC_SESSION_STRUCT(1) mpack_rpc_one_session_t;
+
+#define MPACK_RPC_SESSION_STRUCT_SIZE(c) \
+ (sizeof(struct mpack_rpc_slot_s) * (c - 1) + \
+ sizeof(mpack_rpc_one_session_t))
+
+typedef MPACK_RPC_SESSION_STRUCT(MPACK_RPC_MAX_REQUESTS) mpack_rpc_session_t;
+
+MPACK_API void mpack_rpc_session_init(mpack_rpc_session_t *s, mpack_uint32_t c)
+ FUNUSED FNONULL;
+
+MPACK_API int mpack_rpc_receive_tok(mpack_rpc_session_t *s, mpack_token_t t,
+ mpack_rpc_message_t *msg) FUNUSED FNONULL;
+MPACK_API int mpack_rpc_request_tok(mpack_rpc_session_t *s, mpack_token_t *t,
+ mpack_data_t d) FUNUSED FNONULL_ARG((1,2));
+MPACK_API int mpack_rpc_reply_tok(mpack_rpc_session_t *s, mpack_token_t *t,
+ mpack_uint32_t i) FUNUSED FNONULL;
+MPACK_API int mpack_rpc_notify_tok(mpack_rpc_session_t *s, mpack_token_t *t)
+ FUNUSED FNONULL;
+
+MPACK_API int mpack_rpc_receive(mpack_rpc_session_t *s, const char **b,
+ size_t *bl, mpack_rpc_message_t *m) FUNUSED FNONULL;
+MPACK_API int mpack_rpc_request(mpack_rpc_session_t *s, char **b, size_t *bl,
+ mpack_data_t d) FUNUSED FNONULL_ARG((1,2,3));
+MPACK_API int mpack_rpc_reply(mpack_rpc_session_t *s, char **b, size_t *bl,
+ mpack_uint32_t i) FNONULL FUNUSED;
+MPACK_API int mpack_rpc_notify(mpack_rpc_session_t *s, char **b, size_t *bl)
+ FNONULL FUNUSED;
+
+MPACK_API void mpack_rpc_session_copy(mpack_rpc_session_t *d,
+ mpack_rpc_session_t *s) FUNUSED FNONULL;
+
+#endif /* MPACK_RPC_H */
diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt
index e4d7115654..e35e7ce2d4 100644
--- a/src/nvim/CMakeLists.txt
+++ b/src/nvim/CMakeLists.txt
@@ -29,7 +29,7 @@ set(API_UI_EVENTS_GENERATOR ${GENERATOR_DIR}/gen_api_ui_events.lua)
set(GENERATOR_C_GRAMMAR ${GENERATOR_DIR}/c_grammar.lua)
set(API_METADATA ${PROJECT_BINARY_DIR}/api_metadata.mpack)
set(FUNCS_DATA ${PROJECT_BINARY_DIR}/funcs_data.mpack)
-set(MSGPACK_LUA_C_BINDINGS ${GENERATED_DIR}/msgpack_lua_c_bindings.generated.c)
+set(LUA_API_C_BINDINGS ${GENERATED_DIR}/lua_api_c_bindings.generated.c)
set(HEADER_GENERATOR ${GENERATOR_DIR}/gen_declarations.lua)
set(GENERATED_INCLUDES_DIR ${PROJECT_BINARY_DIR}/include)
set(GENERATED_API_DISPATCH ${GENERATED_DIR}/api/private/dispatch_wrappers.generated.h)
@@ -56,6 +56,8 @@ set(VIM_MODULE_FILE ${GENERATED_DIR}/lua/vim_module.generated.h)
set(LUA_VIM_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/src/nvim/lua/vim.lua)
set(LUA_SHARED_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/runtime/lua/vim/shared.lua)
set(LUA_INSPECT_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/runtime/lua/vim/inspect.lua)
+set(LUA_F_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/runtime/lua/vim/F.lua)
+set(LUA_META_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/runtime/lua/vim/_meta.lua)
set(CHAR_BLOB_GENERATOR ${GENERATOR_DIR}/gen_char_blob.lua)
set(LINT_SUPPRESS_FILE ${PROJECT_BINARY_DIR}/errors.json)
set(LINT_SUPPRESS_URL_BASE "https://raw.githubusercontent.com/neovim/doc/gh-pages/reports/clint")
@@ -85,8 +87,8 @@ file(MAKE_DIRECTORY ${LINT_SUPPRESSES_ROOT}/src)
file(GLOB NVIM_SOURCES *.c)
file(GLOB NVIM_HEADERS *.h)
-file(GLOB XDIFF_SOURCES xdiff/*.c)
-file(GLOB XDIFF_HEADERS xdiff/*.h)
+file(GLOB EXTERNAL_SOURCES ../xdiff/*.c ../mpack/*.c ../cjson/*.c)
+file(GLOB EXTERNAL_HEADERS ../xdiff/*.h ../mpack/*.h ../cjson/*.h)
foreach(subdir
os
@@ -169,8 +171,8 @@ foreach(sfile ${CONV_SOURCES})
message(FATAL_ERROR "${sfile} doesn't exist (it was added to CONV_SOURCES)")
endif()
endforeach()
-# xdiff: inlined external project, we don't maintain it. #9306
-list(APPEND CONV_SOURCES ${XDIFF_SOURCES})
+# xdiff, mpack, lua-cjson: inlined external project, we don't maintain it. #9306
+list(APPEND CONV_SOURCES ${EXTERNAL_SOURCES})
if(NOT MSVC)
set_source_files_properties(
@@ -305,11 +307,11 @@ add_custom_command(OUTPUT ${GENERATED_UNICODE_TABLES}
add_custom_command(
OUTPUT ${GENERATED_API_DISPATCH} ${GENERATED_FUNCS_METADATA}
- ${API_METADATA} ${MSGPACK_LUA_C_BINDINGS}
+ ${API_METADATA} ${LUA_API_C_BINDINGS}
COMMAND ${LUA_PRG} ${API_DISPATCH_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}
${GENERATED_API_DISPATCH}
${GENERATED_FUNCS_METADATA} ${API_METADATA}
- ${MSGPACK_LUA_C_BINDINGS}
+ ${LUA_API_C_BINDINGS}
${API_HEADERS}
DEPENDS
${API_HEADERS}
@@ -325,15 +327,19 @@ add_custom_command(
${LUA_VIM_MODULE_SOURCE} vim_module
${LUA_SHARED_MODULE_SOURCE} shared_module
${LUA_INSPECT_MODULE_SOURCE} inspect_module
+ ${LUA_F_MODULE_SOURCE} lua_F_module
+ ${LUA_META_MODULE_SOURCE} lua_meta_module
DEPENDS
${CHAR_BLOB_GENERATOR}
${LUA_VIM_MODULE_SOURCE}
${LUA_SHARED_MODULE_SOURCE}
${LUA_INSPECT_MODULE_SOURCE}
+ ${LUA_F_MODULE_SOURCE}
+ ${LUA_META_MODULE_SOURCE}
)
list(APPEND NVIM_GENERATED_SOURCES
- "${MSGPACK_LUA_C_BINDINGS}"
+ "${LUA_API_C_BINDINGS}"
)
add_custom_command(
@@ -465,7 +471,7 @@ endif()
add_executable(nvim ${NVIM_GENERATED_FOR_SOURCES} ${NVIM_GENERATED_FOR_HEADERS}
${NVIM_GENERATED_SOURCES} ${NVIM_SOURCES} ${NVIM_HEADERS}
- ${XDIFF_SOURCES} ${XDIFF_HEADERS})
+ ${EXTERNAL_SOURCES} ${EXTERNAL_HEADERS})
target_link_libraries(nvim ${NVIM_EXEC_LINK_LIBRARIES})
install_helper(TARGETS nvim)
@@ -596,7 +602,7 @@ add_library(
EXCLUDE_FROM_ALL
${NVIM_SOURCES} ${NVIM_GENERATED_SOURCES}
${NVIM_HEADERS} ${NVIM_GENERATED_FOR_SOURCES} ${NVIM_GENERATED_FOR_HEADERS}
- ${XDIFF_SOURCES} ${XDIFF_HEADERS}
+ ${EXTERNAL_SOURCES} ${EXTERNAL_HEADERS}
)
set_property(TARGET libnvim APPEND PROPERTY
INCLUDE_DIRECTORIES ${LUA_PREFERRED_INCLUDE_DIRS})
@@ -626,7 +632,7 @@ else()
EXCLUDE_FROM_ALL
${NVIM_SOURCES} ${NVIM_GENERATED_SOURCES}
${NVIM_HEADERS} ${NVIM_GENERATED_FOR_SOURCES} ${NVIM_GENERATED_FOR_HEADERS}
- ${XDIFF_SOURCES} ${XDIFF_HEADERS}
+ ${EXTERNAL_SOURCES} ${EXTERNAL_HEADERS}
${UNIT_TEST_FIXTURES}
)
target_link_libraries(nvim-test ${NVIM_TEST_LINK_LIBRARIES})
diff --git a/src/nvim/README.md b/src/nvim/README.md
index affc5c79cc..4efb42b896 100644
--- a/src/nvim/README.md
+++ b/src/nvim/README.md
@@ -75,8 +75,108 @@ Logs will be written to `${HOME}/logs/*san.PID` then.
For more information: https://github.com/google/sanitizers/wiki/SanitizerCommonFlags
-TUI debugging
--------------
+Debug: Performance
+------------------
+
+### Profiling (easy)
+
+For debugging performance bottlenecks in any code, there is a simple (and very
+effective) approach:
+
+1. Run the slow code in a loop.
+2. Break execution ~5 times and save the stacktrace.
+3. The cause of the bottleneck will (almost always) appear in most of the stacktraces.
+
+### Profiling (fancy)
+
+For more advanced profiling, consider `perf` + `flamegraph`.
+
+### USDT profiling (powerful)
+
+Or you can use USDT probes via `NVIM_PROBE` ([#12036](https://github.com/neovim/neovim/pull/12036)).
+
+> USDT is basically a way to define stable probe points in userland binaries.
+> The benefit of bcc is the ability to define logic to go along with the probe
+> points.
+
+Tools:
+- bpftrace provides an awk-like language to the kernel bytecode, BPF.
+- BCC provides a subset of C. Provides more complex logic than bpftrace, but takes a bit more effort.
+
+Example using bpftrace to track slow vim functions, and print out any files
+that were opened during the trace. At the end, it prints a histogram of
+function timing:
+
+ #!/usr/bin/env bpftrace
+
+ BEGIN {
+ @depth = -1;
+ }
+
+ tracepoint:sched:sched_process_fork /@pidmap[args->parent_pid]/ {
+ @pidmap[args->child_pid] = 1;
+ }
+
+ tracepoint:sched:sched_process_exit /@pidmap[args->pid]/ {
+ delete(@pidmap[args->pid]);
+ }
+
+ usdt:build/bin/nvim:neovim:eval__call_func__entry {
+ @pidmap[pid] = 1;
+ @depth++;
+ @funcentry[@depth] = nsecs;
+ }
+
+ usdt:build/bin/nvim:neovim:eval__call_func__return {
+ $func = str(arg0);
+ $msecs = (nsecs - @funcentry[@depth]) / 1000000;
+
+ @time_histo = hist($msecs);
+
+ if ($msecs >= 1000) {
+ printf("%u ms for %s\n", $msecs, $func);
+ print(@files);
+ }
+
+ clear(@files);
+ delete(@funcentry[@depth]);
+ @depth--;
+ }
+
+ tracepoint:syscalls:sys_enter_open,
+ tracepoint:syscalls:sys_enter_openat {
+ if (@pidmap[pid] == 1 && @depth >= 0) {
+ @files[str(args->filename)] = count();
+ }
+ }
+
+ END {
+ clear(@depth);
+ }
+
+ $ sudo bpftrace funcslower.bt
+ 1527 ms for Slower
+ @files[/usr/lib/libstdc++.so.6]: 2
+ @files[/etc/fish/config.fish]: 2
+ <snip>
+
+ ^C
+ @time_histo:
+ [0] 71430 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@|
+ [1] 346 | |
+ [2, 4) 208 | |
+ [4, 8) 91 | |
+ [8, 16) 22 | |
+ [16, 32) 85 | |
+ [32, 64) 7 | |
+ [64, 128) 0 | |
+ [128, 256) 0 | |
+ [256, 512) 6 | |
+ [512, 1K) 1 | |
+ [1K, 2K) 5 | |
+
+Debug: TUI
+----------
### TUI troubleshoot
diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c
index b371c08d2a..0ef2776263 100644
--- a/src/nvim/api/buffer.c
+++ b/src/nvim/api/buffer.c
@@ -3,40 +3,39 @@
// Some of this code was adapted from 'if_py_both.h' from the original
// vim source
+#include <lauxlib.h>
+#include <limits.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
-#include <limits.h>
-
-#include <lauxlib.h>
#include "nvim/api/buffer.h"
-#include "nvim/api/private/helpers.h"
#include "nvim/api/private/defs.h"
-#include "nvim/lua/executor.h"
-#include "nvim/vim.h"
+#include "nvim/api/private/helpers.h"
#include "nvim/buffer.h"
+#include "nvim/buffer_updates.h"
#include "nvim/change.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
+#include "nvim/decoration.h"
+#include "nvim/ex_cmds.h"
+#include "nvim/ex_docmd.h"
+#include "nvim/extmark.h"
+#include "nvim/fileio.h"
#include "nvim/getchar.h"
+#include "nvim/lua/executor.h"
+#include "nvim/map.h"
+#include "nvim/map_defs.h"
+#include "nvim/mark.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/misc1.h"
-#include "nvim/ex_cmds.h"
-#include "nvim/map_defs.h"
-#include "nvim/map.h"
-#include "nvim/mark.h"
-#include "nvim/ops.h"
-#include "nvim/extmark.h"
-#include "nvim/decoration.h"
-#include "nvim/fileio.h"
#include "nvim/move.h"
+#include "nvim/ops.h"
#include "nvim/syntax.h"
-#include "nvim/window.h"
#include "nvim/undo.h"
-#include "nvim/ex_docmd.h"
-#include "nvim/buffer_updates.h"
+#include "nvim/vim.h"
+#include "nvim/window.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "api/buffer.c.generated.h"
@@ -149,11 +148,8 @@ Integer nvim_buf_line_count(Buffer buffer, Error *err)
/// @param[out] err Error details, if any
/// @return False if attach failed (invalid parameter, or buffer isn't loaded);
/// otherwise True. TODO: LUA_API_NO_EVAL
-Boolean nvim_buf_attach(uint64_t channel_id,
- Buffer buffer,
- Boolean send_buffer,
- DictionaryOf(LuaRef) opts,
- Error *err)
+Boolean nvim_buf_attach(uint64_t channel_id, Buffer buffer, Boolean send_buffer,
+ DictionaryOf(LuaRef) opts, Error *err)
FUNC_API_SINCE(4)
{
buf_T *buf = find_buffer_by_handle(buffer, err);
@@ -237,9 +233,7 @@ error:
/// @param[out] err Error details, if any
/// @return False if detach failed (because the buffer isn't loaded);
/// otherwise True.
-Boolean nvim_buf_detach(uint64_t channel_id,
- Buffer buffer,
- Error *err)
+Boolean nvim_buf_detach(uint64_t channel_id, Buffer buffer, Error *err)
FUNC_API_SINCE(4) FUNC_API_REMOTE_ONLY
{
buf_T *buf = find_buffer_by_handle(buffer, err);
@@ -252,8 +246,7 @@ Boolean nvim_buf_detach(uint64_t channel_id,
return true;
}
-void nvim__buf_redraw_range(Buffer buffer, Integer first, Integer last,
- Error *err)
+void nvim__buf_redraw_range(Buffer buffer, Integer first, Integer last, Error *err)
FUNC_API_LUA_ONLY
{
buf_T *buf = find_buffer_by_handle(buffer, err);
@@ -315,7 +308,7 @@ ArrayOf(String) nvim_buf_get_lines(uint64_t channel_id,
}
rv.size = (size_t)(end - start);
- rv.items = xcalloc(sizeof(Object), rv.size);
+ rv.items = xcalloc(rv.size, sizeof(Object));
if (!buf_collect_lines(buf, rv.size, start,
(channel_id != VIML_INTERNAL_CALL), &rv, err)) {
@@ -376,13 +369,8 @@ static bool check_string_array(Array arr, bool disallow_nl, Error *err)
/// @param strict_indexing Whether out-of-bounds should be an error.
/// @param replacement Array of lines to use as replacement
/// @param[out] err Error details, if any
-void nvim_buf_set_lines(uint64_t channel_id,
- Buffer buffer,
- Integer start,
- Integer end,
- Boolean strict_indexing,
- ArrayOf(String) replacement,
- Error *err)
+void nvim_buf_set_lines(uint64_t channel_id, Buffer buffer, Integer start, Integer end,
+ Boolean strict_indexing, ArrayOf(String) replacement, Error *err)
FUNC_API_SINCE(1)
FUNC_API_CHECK_TEXTLOCK
{
@@ -554,10 +542,8 @@ end:
/// @param end_column Last column
/// @param replacement Array of lines to use as replacement
/// @param[out] err Error details, if any
-void nvim_buf_set_text(uint64_t channel_id, Buffer buffer,
- Integer start_row, Integer start_col,
- Integer end_row, Integer end_col,
- ArrayOf(String) replacement, Error *err)
+void nvim_buf_set_text(uint64_t channel_id, Buffer buffer, Integer start_row, Integer start_col,
+ Integer end_row, Integer end_col, ArrayOf(String) replacement, Error *err)
FUNC_API_SINCE(7)
{
FIXED_TEMP_ARRAY(scratch, 1);
@@ -617,17 +603,17 @@ void nvim_buf_set_text(uint64_t channel_id, Buffer buffer,
// calculate byte size of old region before it gets modified/deleted
if (start_row == end_row) {
- old_byte = (bcount_t)end_col - start_col;
+ old_byte = (bcount_t)end_col - start_col;
} else {
- const char *bufline;
- old_byte += (bcount_t)strlen(str_at_start) - start_col;
- for (int64_t i = 1; i < end_row - start_row; i++) {
- int64_t lnum = start_row + i;
+ const char *bufline;
+ old_byte += (bcount_t)strlen(str_at_start) - start_col;
+ for (int64_t i = 1; i < end_row - start_row; i++) {
+ int64_t lnum = start_row + i;
- bufline = (char *)ml_get_buf(buf, lnum, false);
- old_byte += (bcount_t)(strlen(bufline))+1;
- }
- old_byte += (bcount_t)end_col+1;
+ bufline = (char *)ml_get_buf(buf, lnum, false);
+ old_byte += (bcount_t)(strlen(bufline))+1;
+ }
+ old_byte += (bcount_t)end_col+1;
}
String first_item = replacement.items[0].data.string;
@@ -824,7 +810,7 @@ Object nvim_buf_get_var(Buffer buffer, String name, Error *err)
buf_T *buf = find_buffer_by_handle(buffer, err);
if (!buf) {
- return (Object) OBJECT_INIT;
+ return (Object)OBJECT_INIT;
}
return dict_get_value(buf->b_vars, name, err);
@@ -872,8 +858,8 @@ ArrayOf(Dictionary) nvim_buf_get_keymap(Buffer buffer, String mode, Error *err)
/// @see |nvim_set_keymap()|
///
/// @param buffer Buffer handle, or 0 for current buffer
-void nvim_buf_set_keymap(Buffer buffer, String mode, String lhs, String rhs,
- Dictionary opts, Error *err)
+void nvim_buf_set_keymap(Buffer buffer, String mode, String lhs, String rhs, Dictionary opts,
+ Error *err)
FUNC_API_SINCE(6)
{
modify_keymap(buffer, false, mode, lhs, rhs, opts, err);
@@ -980,7 +966,7 @@ Object nvim_buf_get_option(Buffer buffer, String name, Error *err)
buf_T *buf = find_buffer_by_handle(buffer, err);
if (!buf) {
- return (Object) OBJECT_INIT;
+ return (Object)OBJECT_INIT;
}
return get_option_from(buf, SREQ_BUF, name, err);
@@ -994,8 +980,7 @@ Object nvim_buf_get_option(Buffer buffer, String name, Error *err)
/// @param name Option name
/// @param value Option value
/// @param[out] err Error details, if any
-void nvim_buf_set_option(uint64_t channel_id, Buffer buffer,
- String name, Object value, Error *err)
+void nvim_buf_set_option(uint64_t channel_id, Buffer buffer, String name, Object value, Error *err)
FUNC_API_SINCE(1)
{
buf_T *buf = find_buffer_by_handle(buffer, err);
@@ -1044,7 +1029,7 @@ void nvim_buf_set_name(Buffer buffer, String name, Error *err)
// Using aucmd_*: autocommands will be executed by rename_buffer
aco_save_T aco;
aucmd_prepbuf(&aco, buf);
- int ren_ret = rename_buffer((char_u *) name.data);
+ int ren_ret = rename_buffer((char_u *)name.data);
aucmd_restbuf(&aco);
if (try_end(err)) {
@@ -1105,12 +1090,11 @@ void nvim_buf_delete(Buffer buffer, Dictionary opts, Error *err)
return;
}
- int result = do_buffer(
- unload ? DOBUF_UNLOAD : DOBUF_WIPE,
- DOBUF_FIRST,
- FORWARD,
- buf->handle,
- force);
+ int result = do_buffer(unload ? DOBUF_UNLOAD : DOBUF_WIPE,
+ DOBUF_FIRST,
+ FORWARD,
+ buf->handle,
+ force);
if (result == FAIL) {
api_set_error(err, kErrorTypeException, "Failed to unload buffer.");
@@ -1213,8 +1197,7 @@ static Array extmark_to_array(ExtmarkInfo extmark, bool id, bool add_dict)
ADD(chunk, STRING_OBJ(cstr_to_string(vtc->text)));
if (vtc->hl_id > 0) {
ADD(chunk,
- STRING_OBJ(cstr_to_string(
- (const char *)syn_id2name(vtc->hl_id))));
+ STRING_OBJ(cstr_to_string((const char *)syn_id2name(vtc->hl_id))));
}
ADD(chunks, ARRAY_OBJ(chunk));
}
@@ -1232,7 +1215,7 @@ static Array extmark_to_array(ExtmarkInfo extmark, bool id, bool add_dict)
return rv;
}
-/// Returns position for a given extmark id
+/// Gets the position (0-indexed) of an extmark.
///
/// @param buffer Buffer handle, or 0 for current buffer
/// @param ns_id Namespace id from |nvim_create_namespace()|
@@ -1240,7 +1223,8 @@ static Array extmark_to_array(ExtmarkInfo extmark, bool id, bool add_dict)
/// @param opts Optional parameters. Keys:
/// - details: Whether to include the details dict
/// @param[out] err Error details, if any
-/// @return (row, col) tuple or empty list () if extmark id was absent
+/// @return 0-indexed (row, col) tuple or empty list () if extmark id was
+/// absent
ArrayOf(Integer) nvim_buf_get_extmark_by_id(Buffer buffer, Integer ns_id,
Integer id, Dictionary opts,
Error *err)
@@ -1320,18 +1304,17 @@ ArrayOf(Integer) nvim_buf_get_extmark_by_id(Buffer buffer, Integer ns_id,
///
/// @param buffer Buffer handle, or 0 for current buffer
/// @param ns_id Namespace id from |nvim_create_namespace()|
-/// @param start Start of range, given as (row, col) or valid extmark id
-/// (whose position defines the bound)
-/// @param end End of range, given as (row, col) or valid extmark id
-/// (whose position defines the bound)
+/// @param start Start of range: a 0-indexed (row, col) or valid extmark id
+/// (whose position defines the bound). |api-indexing|
+/// @param end End of range (inclusive): a 0-indexed (row, col) or valid
+/// extmark id (whose position defines the bound). |api-indexing|
/// @param opts Optional parameters. Keys:
/// - limit: Maximum number of marks to return
/// - details Whether to include the details dict
/// @param[out] err Error details, if any
/// @return List of [extmark_id, row, col] tuples in "traversal order".
-Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id,
- Object start, Object end,
- Dictionary opts, Error *err)
+Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, Object start, Object end, Dictionary opts,
+ Error *err)
FUNC_API_SINCE(7)
{
Array rv = ARRAY_DICT_INIT;
@@ -1424,17 +1407,27 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id,
///
/// @param buffer Buffer handle, or 0 for current buffer
/// @param ns_id Namespace id from |nvim_create_namespace()|
-/// @param line Line where to place the mark, 0-based
-/// @param col Column where to place the mark, 0-based
+/// @param line Line where to place the mark, 0-based. |api-indexing|
+/// @param col Column where to place the mark, 0-based. |api-indexing|
/// @param opts Optional parameters.
/// - id : id of the extmark to edit.
/// - end_line : ending line of the mark, 0-based inclusive.
/// - end_col : ending col of the mark, 0-based exclusive.
/// - hl_group : name of the highlight group used to highlight
/// this mark.
+/// - hl_eol : when true, for a multiline highlight covering the
+/// EOL of a line, continue the highlight for the rest
+/// of the screen line (just like for diff and
+/// cursorline highlight).
/// - virt_text : virtual text to link to this mark.
-/// - virt_text_pos : positioning of virtual text. Possible
-/// values:
+/// A list of [text, highlight] tuples, each representing a
+/// text chunk with specified highlight. `highlight` element
+/// can either be a a single highlight group, or an array of
+/// multiple highlight groups that will be stacked
+/// (highest priority last). A highlight group can be supplied
+/// either as a string or as an integer, the latter which
+/// can be obtained using |nvim_get_hl_id_by_name|.
+/// - virt_text_pos : position of virtual text. Possible values:
/// - "eol": right after eol character (default)
/// - "overlay": display over the specified column, without
/// shifting the underlying text.
@@ -1453,10 +1446,28 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id,
/// default
/// - "combine": combine with background text color
/// - "blend": blend with background text color.
-/// - hl_eol : when true, for a multiline highlight covering the
-/// EOL of a line, continue the highlight for the rest
-/// of the screen line (just like for diff and
-/// cursorline highlight).
+///
+/// - virt_lines : virtual lines to add next to this mark
+/// This should be an array over lines, where each line in
+/// turn is an array over [text, highlight] tuples. In
+/// general, buffer and window options do not affect the
+/// display of the text. In particular 'wrap'
+/// and 'linebreak' options do not take effect, so
+/// the number of extra screen lines will always match
+/// the size of the array. However the 'tabstop' buffer
+/// option is still used for hard tabs. By default lines are
+/// placed below the buffer line containing the mark.
+///
+/// Note: currently virtual lines are limited to one block
+/// per buffer. Thus setting a new mark disables any previous
+/// `virt_lines` decoration. However plugins should not rely
+/// on this behaviour, as this limitation is planned to be
+/// removed.
+///
+/// - virt_lines_above: place virtual lines above instead.
+/// - virt_lines_leftcol: Place extmarks in the leftmost
+/// column of the window, bypassing
+/// sign and number columns.
///
/// - ephemeral : for use with |nvim_set_decoration_provider|
/// callbacks. The mark will only be used for the current
@@ -1473,14 +1484,12 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id,
/// example treesitter highlighting uses a value of 100.
/// @param[out] err Error details, if any
/// @return Id of the created/updated extmark
-Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id,
- Integer line, Integer col,
+Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer col,
Dictionary opts, Error *err)
FUNC_API_SINCE(7)
{
buf_T *buf = find_buffer_by_handle(buffer, err);
if (!buf) {
- api_set_error(err, kErrorTypeValidation, "Invalid buffer id");
return 0;
}
@@ -1500,6 +1509,10 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id,
bool end_right_gravity = false;
bool end_gravity_set = false;
+ VirtLines virt_lines = KV_INITIAL_VALUE;
+ bool virt_lines_above = false;
+ bool virt_lines_leftcol = false;
+
for (size_t i = 0; i < opts.size; i++) {
String k = opts.items[i].key;
Object *v = &opts.items[i].value;
@@ -1540,19 +1553,18 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id,
} else if (strequal("hl_group", k.data)) {
String hl_group;
switch (v->type) {
- case kObjectTypeString:
- hl_group = v->data.string;
- decor.hl_id = syn_check_group(
- (char_u *)(hl_group.data),
- (int)hl_group.size);
- break;
- case kObjectTypeInteger:
- decor.hl_id = (int)v->data.integer;
- break;
- default:
- api_set_error(err, kErrorTypeValidation,
- "hl_group is not valid.");
- goto error;
+ case kObjectTypeString:
+ hl_group = v->data.string;
+ decor.hl_id = syn_check_group((char_u *)(hl_group.data),
+ (int)hl_group.size);
+ break;
+ case kObjectTypeInteger:
+ decor.hl_id = (int)v->data.integer;
+ break;
+ default:
+ api_set_error(err, kErrorTypeValidation,
+ "hl_group is not valid.");
+ goto error;
}
} else if (strequal("virt_text", k.data)) {
if (v->type != kObjectTypeArray) {
@@ -1560,7 +1572,8 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id,
"virt_text is not an Array");
goto error;
}
- decor.virt_text = parse_virt_text(v->data.array, err);
+ decor.virt_text = parse_virt_text(v->data.array, err,
+ &decor.virt_text_width);
if (ERROR_SET(err)) {
goto error;
}
@@ -1597,6 +1610,36 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id,
if (ERROR_SET(err)) {
goto error;
}
+ } else if (strequal("virt_lines", k.data)) {
+ if (v->type != kObjectTypeArray) {
+ api_set_error(err, kErrorTypeValidation,
+ "virt_lines is not an Array");
+ goto error;
+ }
+ Array a = v->data.array;
+ for (size_t j = 0; j < a.size; j++) {
+ if (a.items[j].type != kObjectTypeArray) {
+ api_set_error(err, kErrorTypeValidation,
+ "virt_text_line item is not an Array");
+ goto error;
+ }
+ int dummig;
+ VirtText jtem = parse_virt_text(a.items[j].data.array, err, &dummig);
+ kv_push(virt_lines, jtem);
+ if (ERROR_SET(err)) {
+ goto error;
+ }
+ }
+ } else if (strequal("virt_lines_above", k.data)) {
+ virt_lines_above = api_object_to_bool(*v, "virt_lines_above", false, err);
+ if (ERROR_SET(err)) {
+ goto error;
+ }
+ } else if (strequal("virt_lines_leftcol", k.data)) {
+ virt_lines_leftcol = api_object_to_bool(*v, "virt_lines_leftcol", false, err);
+ if (ERROR_SET(err)) {
+ goto error;
+ }
} else if (strequal("hl_eol", k.data)) {
decor.hl_eol = api_object_to_bool(*v, "hl_eol", false, err);
if (ERROR_SET(err)) {
@@ -1685,8 +1728,7 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id,
if (col2 >= 0) {
if (line2 >= 0 && line2 < buf->b_ml.ml_line_count) {
- len = ephemeral ? MAXCOL : STRLEN(
- ml_get_buf(buf, (linenr_T)line2 + 1, false));
+ len = ephemeral ? MAXCOL : STRLEN(ml_get_buf(buf, (linenr_T)line2 + 1, false));
} else if (line2 == buf->b_ml.ml_line_count) {
// We are trying to add an extmark past final newline
len = 0;
@@ -1706,7 +1748,7 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id,
decor.col = 0;
for (size_t i = 0; i < kv_size(decor.virt_text); i++) {
decor.col
- += (int)mb_string2cells((char_u *)kv_A(decor.virt_text, i).text);
+ += (int)mb_string2cells((char_u *)kv_A(decor.virt_text, i).text);
}
}
@@ -1735,9 +1777,23 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id,
goto error;
}
- id = extmark_set(buf, (uint64_t)ns_id, id, (int)line, (colnr_T)col,
- line2, col2, d, right_gravity,
- end_right_gravity, kExtmarkNoUndo);
+ if (kv_size(virt_lines) && buf->b_virt_line_mark) {
+ mtpos_t pos = marktree_lookup(buf->b_marktree, buf->b_virt_line_mark, NULL);
+ clear_virt_lines(buf, pos.row); // handles pos.row == -1
+ }
+
+ uint64_t mark = extmark_set(buf, (uint64_t)ns_id, &id, (int)line, (colnr_T)col,
+ line2, col2, d, right_gravity,
+ end_right_gravity, kExtmarkNoUndo);
+
+ if (kv_size(virt_lines)) {
+ buf->b_virt_lines = virt_lines;
+ buf->b_virt_line_mark = mark;
+ buf->b_virt_line_pos = -1;
+ buf->b_virt_line_above = virt_lines_above;
+ buf->b_virt_line_leftcol = virt_lines_leftcol;
+ redraw_buf_line_later(buf, MIN(buf->b_ml.ml_line_count, line+1+(virt_lines_above?0:1)));
+ }
}
return (Integer)id;
@@ -1754,10 +1810,7 @@ error:
/// @param id Extmark id
/// @param[out] err Error details, if any
/// @return true if the extmark was found, else false
-Boolean nvim_buf_del_extmark(Buffer buffer,
- Integer ns_id,
- Integer id,
- Error *err)
+Boolean nvim_buf_del_extmark(Buffer buffer, Integer ns_id, Integer id, Error *err)
FUNC_API_SINCE(7)
{
buf_T *buf = find_buffer_by_handle(buffer, err);
@@ -1803,13 +1856,8 @@ Boolean nvim_buf_del_extmark(Buffer buffer,
/// or -1 to highlight to end of line
/// @param[out] err Error details, if any
/// @return The ns_id that was used
-Integer nvim_buf_add_highlight(Buffer buffer,
- Integer ns_id,
- String hl_group,
- Integer line,
- Integer col_start,
- Integer col_end,
- Error *err)
+Integer nvim_buf_add_highlight(Buffer buffer, Integer ns_id, String hl_group, Integer line,
+ Integer col_start, Integer col_end, Error *err)
FUNC_API_SINCE(1)
{
buf_T *buf = find_buffer_by_handle(buffer, err);
@@ -1849,7 +1897,7 @@ Integer nvim_buf_add_highlight(Buffer buffer,
end_line++;
}
- extmark_set(buf, ns, 0,
+ extmark_set(buf, ns, NULL,
(int)line, (colnr_T)col_start,
end_line, (colnr_T)col_end,
decor_hl(hl_id), true, false, kExtmarkNoUndo);
@@ -1868,10 +1916,7 @@ Integer nvim_buf_add_highlight(Buffer buffer,
/// @param line_end End of range of lines to clear (exclusive) or -1 to clear
/// to end of buffer.
/// @param[out] err Error details, if any
-void nvim_buf_clear_namespace(Buffer buffer,
- Integer ns_id,
- Integer line_start,
- Integer line_end,
+void nvim_buf_clear_namespace(Buffer buffer, Integer ns_id, Integer line_start, Integer line_end,
Error *err)
FUNC_API_SINCE(5)
{
@@ -1892,80 +1937,6 @@ void nvim_buf_clear_namespace(Buffer buffer,
(int)line_end-1, MAXCOL);
}
-/// Set the virtual text (annotation) for a buffer line.
-///
-/// By default (and currently the only option) the text will be placed after
-/// the buffer text. Virtual text will never cause reflow, rather virtual
-/// text will be truncated at the end of the screen line. The virtual text will
-/// begin one cell (|lcs-eol| or space) after the ordinary text.
-///
-/// Namespaces are used to support batch deletion/updating of virtual text.
-/// To create a namespace, use |nvim_create_namespace()|. Virtual text is
-/// cleared using |nvim_buf_clear_namespace()|. The same `ns_id` can be used for
-/// both virtual text and highlights added by |nvim_buf_add_highlight()|, both
-/// can then be cleared with a single call to |nvim_buf_clear_namespace()|. If
-/// the virtual text never will be cleared by an API call, pass `ns_id = -1`.
-///
-/// As a shorthand, `ns_id = 0` can be used to create a new namespace for the
-/// virtual text, the allocated id is then returned.
-///
-/// @param buffer Buffer handle, or 0 for current buffer
-/// @param ns_id Namespace to use or 0 to create a namespace,
-/// or -1 for a ungrouped annotation
-/// @param line Line to annotate with virtual text (zero-indexed)
-/// @param chunks A list of [text, hl_group] arrays, each representing a
-/// text chunk with specified highlight. `hl_group` element
-/// can be omitted for no highlight.
-/// @param opts Optional parameters. Currently not used.
-/// @param[out] err Error details, if any
-/// @return The ns_id that was used
-Integer nvim_buf_set_virtual_text(Buffer buffer,
- Integer src_id,
- Integer line,
- Array chunks,
- Dictionary opts,
- Error *err)
- FUNC_API_SINCE(5)
-{
- buf_T *buf = find_buffer_by_handle(buffer, err);
- if (!buf) {
- return 0;
- }
-
- if (line < 0 || line >= MAXLNUM) {
- api_set_error(err, kErrorTypeValidation, "Line number outside range");
- return 0;
- }
-
- if (opts.size > 0) {
- api_set_error(err, kErrorTypeValidation, "opts dict isn't empty");
- return 0;
- }
-
- uint64_t ns_id = src2ns(&src_id);
-
- VirtText virt_text = parse_virt_text(chunks, err);
- if (ERROR_SET(err)) {
- return 0;
- }
-
-
- VirtText *existing = decor_find_virttext(buf, (int)line, ns_id);
-
- if (existing) {
- clear_virttext(existing);
- *existing = virt_text;
- return src_id;
- }
-
- Decoration *decor = xcalloc(1, sizeof(*decor));
- decor->virt_text = virt_text;
-
- extmark_set(buf, ns_id, 0, (int)line, 0, -1, -1, decor, true,
- false, kExtmarkNoUndo);
- return src_id;
-}
-
/// call a function with buffer as temporary current buffer
///
/// This temporarily switches current buffer to "buffer".
diff --git a/src/nvim/api/deprecated.c b/src/nvim/api/deprecated.c
index 3989386bb9..332fc0ba96 100644
--- a/src/nvim/api/deprecated.c
+++ b/src/nvim/api/deprecated.c
@@ -1,16 +1,17 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+#include <limits.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
-#include <limits.h>
-#include "nvim/api/deprecated.h"
#include "nvim/api/buffer.h"
-#include "nvim/api/vim.h"
-#include "nvim/api/private/helpers.h"
+#include "nvim/api/deprecated.h"
#include "nvim/api/private/defs.h"
+#include "nvim/api/private/helpers.h"
+#include "nvim/api/vim.h"
+#include "nvim/extmark.h"
#include "nvim/lua/executor.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -68,10 +69,7 @@ Integer nvim_buf_get_number(Buffer buffer, Error *err)
/// @param line_end End of range of lines to clear (exclusive) or -1 to clear
/// to end of file.
/// @param[out] err Error details, if any
-void nvim_buf_clear_highlight(Buffer buffer,
- Integer ns_id,
- Integer line_start,
- Integer line_end,
+void nvim_buf_clear_highlight(Buffer buffer, Integer ns_id, Integer line_start, Integer line_end,
Error *err)
FUNC_API_SINCE(1)
FUNC_API_DEPRECATED_SINCE(7)
@@ -80,6 +78,83 @@ void nvim_buf_clear_highlight(Buffer buffer,
}
+/// Set the virtual text (annotation) for a buffer line.
+///
+/// @deprecated use nvim_buf_set_extmark to use full virtual text
+/// functionality.
+///
+/// The text will be placed after the buffer text. Virtual text will never
+/// cause reflow, rather virtual text will be truncated at the end of the screen
+/// line. The virtual text will begin one cell (|lcs-eol| or space) after the
+/// ordinary text.
+///
+/// Namespaces are used to support batch deletion/updating of virtual text.
+/// To create a namespace, use |nvim_create_namespace()|. Virtual text is
+/// cleared using |nvim_buf_clear_namespace()|. The same `ns_id` can be used for
+/// both virtual text and highlights added by |nvim_buf_add_highlight()|, both
+/// can then be cleared with a single call to |nvim_buf_clear_namespace()|. If
+/// the virtual text never will be cleared by an API call, pass `ns_id = -1`.
+///
+/// As a shorthand, `ns_id = 0` can be used to create a new namespace for the
+/// virtual text, the allocated id is then returned.
+///
+/// @param buffer Buffer handle, or 0 for current buffer
+/// @param ns_id Namespace to use or 0 to create a namespace,
+/// or -1 for a ungrouped annotation
+/// @param line Line to annotate with virtual text (zero-indexed)
+/// @param chunks A list of [text, hl_group] arrays, each representing a
+/// text chunk with specified highlight. `hl_group` element
+/// can be omitted for no highlight.
+/// @param opts Optional parameters. Currently not used.
+/// @param[out] err Error details, if any
+/// @return The ns_id that was used
+Integer nvim_buf_set_virtual_text(Buffer buffer, Integer src_id, Integer line, Array chunks,
+ Dictionary opts, Error *err)
+ FUNC_API_SINCE(5)
+ FUNC_API_DEPRECATED_SINCE(8)
+{
+ buf_T *buf = find_buffer_by_handle(buffer, err);
+ if (!buf) {
+ return 0;
+ }
+
+ if (line < 0 || line >= MAXLNUM) {
+ api_set_error(err, kErrorTypeValidation, "Line number outside range");
+ return 0;
+ }
+
+ if (opts.size > 0) {
+ api_set_error(err, kErrorTypeValidation, "opts dict isn't empty");
+ return 0;
+ }
+
+ uint64_t ns_id = src2ns(&src_id);
+ int width;
+
+ VirtText virt_text = parse_virt_text(chunks, err, &width);
+ if (ERROR_SET(err)) {
+ return 0;
+ }
+
+
+ Decoration *existing = decor_find_virttext(buf, (int)line, ns_id);
+
+ if (existing) {
+ clear_virttext(&existing->virt_text);
+ existing->virt_text = virt_text;
+ existing->virt_text_width = width;
+ return src_id;
+ }
+
+ Decoration *decor = xcalloc(1, sizeof(*decor));
+ decor->virt_text = virt_text;
+ decor->virt_text_width = width;
+
+ extmark_set(buf, ns_id, NULL, (int)line, 0, -1, -1, decor, true,
+ false, kExtmarkNoUndo);
+ return src_id;
+}
+
/// Inserts a sequence of lines to a buffer at a certain index
///
/// @deprecated use nvim_buf_set_lines(buffer, lnum, lnum, true, lines)
@@ -89,10 +164,7 @@ void nvim_buf_clear_highlight(Buffer buffer,
/// the end of the buffer.
/// @param lines Array of lines
/// @param[out] err Error details, if any
-void buffer_insert(Buffer buffer,
- Integer lnum,
- ArrayOf(String) lines,
- Error *err)
+void buffer_insert(Buffer buffer, Integer lnum, ArrayOf(String) lines, Error *err)
{
// "lnum" will be the index of the line after inserting,
// no matter if it is negative or not
@@ -186,7 +258,7 @@ ArrayOf(String) buffer_get_line_slice(Buffer buffer,
{
start = convert_index(start) + !include_start;
end = convert_index(end) + include_end;
- return nvim_buf_get_lines(0, buffer, start , end, false, err);
+ return nvim_buf_get_lines(0, buffer, start, end, false, err);
}
/// Replaces a line range on the buffer
@@ -204,13 +276,8 @@ ArrayOf(String) buffer_get_line_slice(Buffer buffer,
/// @param replacement Array of lines to use as replacement (0-length
// array will delete the line range)
/// @param[out] err Error details, if any
-void buffer_set_line_slice(Buffer buffer,
- Integer start,
- Integer end,
- Boolean include_start,
- Boolean include_end,
- ArrayOf(String) replacement,
- Error *err)
+void buffer_set_line_slice(Buffer buffer, Integer start, Integer end, Boolean include_start,
+ Boolean include_end, ArrayOf(String) replacement, Error *err)
{
start = convert_index(start) + !include_start;
end = convert_index(end) + include_end;
diff --git a/src/nvim/api/private/dispatch.c b/src/nvim/api/private/dispatch.c
index eae4581f42..5e93ccce17 100644
--- a/src/nvim/api/private/dispatch.c
+++ b/src/nvim/api/private/dispatch.c
@@ -1,43 +1,40 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
-#include <inttypes.h>
-#include <stdbool.h>
#include <assert.h>
+#include <inttypes.h>
#include <msgpack.h>
+#include <stdbool.h>
-#include "nvim/map.h"
-#include "nvim/log.h"
-#include "nvim/vim.h"
-#include "nvim/msgpack_rpc/helpers.h"
+#include "nvim/api/buffer.h"
+#include "nvim/api/deprecated.h"
+#include "nvim/api/private/defs.h"
#include "nvim/api/private/dispatch.h"
#include "nvim/api/private/helpers.h"
-#include "nvim/api/private/defs.h"
-
-#include "nvim/api/buffer.h"
#include "nvim/api/tabpage.h"
#include "nvim/api/ui.h"
#include "nvim/api/vim.h"
#include "nvim/api/window.h"
-#include "nvim/api/deprecated.h"
+#include "nvim/log.h"
+#include "nvim/map.h"
+#include "nvim/msgpack_rpc/helpers.h"
+#include "nvim/vim.h"
-static Map(String, MsgpackRpcRequestHandler) *methods = NULL;
+static Map(String, MsgpackRpcRequestHandler) methods = MAP_INIT;
-static void msgpack_rpc_add_method_handler(String method,
- MsgpackRpcRequestHandler handler)
+static void msgpack_rpc_add_method_handler(String method, MsgpackRpcRequestHandler handler)
{
- map_put(String, MsgpackRpcRequestHandler)(methods, method, handler);
+ map_put(String, MsgpackRpcRequestHandler)(&methods, method, handler);
}
/// @param name API method name
/// @param name_len name size (includes terminating NUL)
-MsgpackRpcRequestHandler msgpack_rpc_get_handler_for(const char *name,
- size_t name_len,
+MsgpackRpcRequestHandler msgpack_rpc_get_handler_for(const char *name, size_t name_len,
Error *error)
{
String m = { .data = (char *)name, .size = name_len };
MsgpackRpcRequestHandler rv =
- map_get(String, MsgpackRpcRequestHandler)(methods, m);
+ map_get(String, MsgpackRpcRequestHandler)(&methods, m);
if (!rv.fn) {
api_set_error(error, kErrorTypeException, "Invalid method: %.*s",
@@ -48,5 +45,5 @@ MsgpackRpcRequestHandler msgpack_rpc_get_handler_for(const char *name,
}
#ifdef INCLUDE_GENERATED_DECLARATIONS
-#include "api/private/dispatch_wrappers.generated.h"
+# include "api/private/dispatch_wrappers.generated.h"
#endif
diff --git a/src/nvim/api/private/handle.c b/src/nvim/api/private/handle.c
deleted file mode 100644
index eb96192af2..0000000000
--- a/src/nvim/api/private/handle.c
+++ /dev/null
@@ -1,40 +0,0 @@
-// This is an open source non-commercial project. Dear PVS-Studio, please check
-// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
-
-#include <assert.h>
-#include <stdint.h>
-
-#include "nvim/vim.h"
-#include "nvim/map.h"
-#include "nvim/api/private/handle.h"
-
-#define HANDLE_INIT(name) name##_handles = pmap_new(handle_T)()
-
-#define HANDLE_IMPL(type, name) \
- static PMap(handle_T) *name##_handles = NULL; /* NOLINT */ \
- \
- type *handle_get_##name(handle_T handle) \
- { \
- return pmap_get(handle_T)(name##_handles, handle); \
- } \
- \
- void handle_register_##name(type *name) \
- { \
- pmap_put(handle_T)(name##_handles, name->handle, name); \
- } \
- \
- void handle_unregister_##name(type *name) \
- { \
- pmap_del(handle_T)(name##_handles, name->handle); \
- }
-
-HANDLE_IMPL(buf_T, buffer)
-HANDLE_IMPL(win_T, window)
-HANDLE_IMPL(tabpage_T, tabpage)
-
-void handle_init(void)
-{
- HANDLE_INIT(buffer);
- HANDLE_INIT(window);
- HANDLE_INIT(tabpage);
-}
diff --git a/src/nvim/api/private/handle.h b/src/nvim/api/private/handle.h
deleted file mode 100644
index 26e9dc3314..0000000000
--- a/src/nvim/api/private/handle.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#ifndef NVIM_API_PRIVATE_HANDLE_H
-#define NVIM_API_PRIVATE_HANDLE_H
-
-#include "nvim/vim.h"
-#include "nvim/buffer_defs.h"
-#include "nvim/api/private/defs.h"
-
-#define HANDLE_DECLS(type, name) \
- type *handle_get_##name(handle_T handle); \
- void handle_register_##name(type *name); \
- void handle_unregister_##name(type *name);
-
-// handle_get_buffer handle_register_buffer, handle_unregister_buffer
-HANDLE_DECLS(buf_T, buffer)
-// handle_get_window handle_register_window, handle_unregister_window
-HANDLE_DECLS(win_T, window)
-// handle_get_tabpage handle_register_tabpage, handle_unregister_tabpage
-HANDLE_DECLS(tabpage_T, tabpage)
-
-void handle_init(void);
-
-
-#endif // NVIM_API_PRIVATE_HANDLE_H
-
diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c
index c7d261ba18..193f1dd572 100644
--- a/src/nvim/api/private/helpers.c
+++ b/src/nvim/api/private/helpers.c
@@ -7,43 +7,42 @@
#include <stdlib.h>
#include <string.h>
-#include "nvim/api/private/helpers.h"
#include "nvim/api/private/defs.h"
-#include "nvim/api/private/handle.h"
+#include "nvim/api/private/helpers.h"
#include "nvim/api/vim.h"
-#include "nvim/msgpack_rpc/helpers.h"
-#include "nvim/lua/executor.h"
#include "nvim/ascii.h"
#include "nvim/assert.h"
-#include "nvim/charset.h"
-#include "nvim/syntax.h"
-#include "nvim/vim.h"
#include "nvim/buffer.h"
-#include "nvim/window.h"
-#include "nvim/memline.h"
-#include "nvim/memory.h"
+#include "nvim/charset.h"
+#include "nvim/decoration.h"
#include "nvim/eval.h"
#include "nvim/eval/typval.h"
-#include "nvim/map_defs.h"
-#include "nvim/map.h"
#include "nvim/extmark.h"
-#include "nvim/decoration.h"
+#include "nvim/fileio.h"
+#include "nvim/getchar.h"
+#include "nvim/lib/kvec.h"
+#include "nvim/lua/executor.h"
+#include "nvim/map.h"
+#include "nvim/map_defs.h"
+#include "nvim/memline.h"
+#include "nvim/memory.h"
+#include "nvim/msgpack_rpc/helpers.h"
#include "nvim/option.h"
#include "nvim/option_defs.h"
-#include "nvim/version.h"
-#include "nvim/lib/kvec.h"
-#include "nvim/getchar.h"
-#include "nvim/fileio.h"
+#include "nvim/syntax.h"
#include "nvim/ui.h"
+#include "nvim/version.h"
+#include "nvim/vim.h"
+#include "nvim/window.h"
/// Helper structure for vim_to_object
typedef struct {
- kvec_t(Object) stack; ///< Object stack.
+ kvec_withinit_t(Object, 2) stack; ///< Object stack.
} EncodedData;
#ifdef INCLUDE_GENERATED_DECLARATIONS
-# include "api/private/helpers.c.generated.h"
# include "api/private/funcs_metadata.generated.h"
+# include "api/private/helpers.c.generated.h"
# include "api/private/ui_events_metadata.generated.h"
#endif
@@ -211,8 +210,7 @@ dictitem_T *dict_check_writable(dict_T *dict, String key, bool del, Error *err)
/// @param retval If true the old value will be converted and returned.
/// @param[out] err Details of an error that may have occurred
/// @return The old value if `retval` is true and the key was present, else NIL
-Object dict_set_var(dict_T *dict, String key, Object value, bool del,
- bool retval, Error *err)
+Object dict_set_var(dict_T *dict, String key, Object value, bool del, bool retval, Error *err)
{
Object rv = OBJECT_INIT;
dictitem_T *di = dict_check_writable(dict, key, del, err);
@@ -327,8 +325,7 @@ Object get_option_from(void *from, int type, String name, Error *err)
/// @param type One of `SREQ_GLOBAL`, `SREQ_WIN` or `SREQ_BUF`
/// @param name The option name
/// @param[out] err Details of an error that may have occurred
-void set_option_to(uint64_t channel_id, void *to, int type,
- String name, Object value, Error *err)
+void set_option_to(uint64_t channel_id, void *to, int type, String name, Object value, Error *err)
{
if (name.size == 0) {
api_set_error(err, kErrorTypeValidation, "Empty option name");
@@ -419,57 +416,63 @@ void set_option_to(uint64_t channel_id, void *to, int type,
#define TYPVAL_ENCODE_ALLOW_SPECIALS false
#define TYPVAL_ENCODE_CONV_NIL(tv) \
- kv_push(edata->stack, NIL)
+ kvi_push(edata->stack, NIL)
#define TYPVAL_ENCODE_CONV_BOOL(tv, num) \
- kv_push(edata->stack, BOOLEAN_OBJ((Boolean)(num)))
+ kvi_push(edata->stack, BOOLEAN_OBJ((Boolean)(num)))
#define TYPVAL_ENCODE_CONV_NUMBER(tv, num) \
- kv_push(edata->stack, INTEGER_OBJ((Integer)(num)))
+ kvi_push(edata->stack, INTEGER_OBJ((Integer)(num)))
#define TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER TYPVAL_ENCODE_CONV_NUMBER
#define TYPVAL_ENCODE_CONV_FLOAT(tv, flt) \
- kv_push(edata->stack, FLOAT_OBJ((Float)(flt)))
+ kvi_push(edata->stack, FLOAT_OBJ((Float)(flt)))
#define TYPVAL_ENCODE_CONV_STRING(tv, str, len) \
- do { \
- const size_t len_ = (size_t)(len); \
- const char *const str_ = (const char *)(str); \
- assert(len_ == 0 || str_ != NULL); \
- kv_push(edata->stack, STRING_OBJ(((String) { \
- .data = xmemdupz((len_?str_:""), len_), \
- .size = len_ \
- }))); \
- } while (0)
+ do { \
+ const size_t len_ = (size_t)(len); \
+ const char *const str_ = (const char *)(str); \
+ assert(len_ == 0 || str_ != NULL); \
+ kvi_push(edata->stack, STRING_OBJ(cbuf_to_string((len_?str_:""), len_))); \
+ } while (0)
#define TYPVAL_ENCODE_CONV_STR_STRING TYPVAL_ENCODE_CONV_STRING
#define TYPVAL_ENCODE_CONV_EXT_STRING(tv, str, len, type) \
- TYPVAL_ENCODE_CONV_NIL(tv)
+ TYPVAL_ENCODE_CONV_NIL(tv)
+
+#define TYPVAL_ENCODE_CONV_BLOB(tv, blob, len) \
+ do { \
+ const size_t len_ = (size_t)(len); \
+ const blob_T *const blob_ = (blob); \
+ kvi_push(edata->stack, STRING_OBJ(((String) { \
+ .data = len_ != 0 ? xmemdup(blob_->bv_ga.ga_data, len_) : NULL, \
+ .size = len_ \
+ }))); \
+ } while (0)
#define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun) \
- do { \
- TYPVAL_ENCODE_CONV_NIL(tv); \
- goto typval_encode_stop_converting_one_item; \
- } while (0)
+ do { \
+ TYPVAL_ENCODE_CONV_NIL(tv); \
+ goto typval_encode_stop_converting_one_item; \
+ } while (0)
#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, len)
#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, len)
#define TYPVAL_ENCODE_CONV_FUNC_END(tv)
#define TYPVAL_ENCODE_CONV_EMPTY_LIST(tv) \
- kv_push(edata->stack, ARRAY_OBJ(((Array) { .capacity = 0, .size = 0 })))
+ kvi_push(edata->stack, ARRAY_OBJ(((Array) { .capacity = 0, .size = 0 })))
#define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, dict) \
- kv_push(edata->stack, \
- DICTIONARY_OBJ(((Dictionary) { .capacity = 0, .size = 0 })))
+ kvi_push(edata->stack, \
+ DICTIONARY_OBJ(((Dictionary) { .capacity = 0, .size = 0 })))
-static inline void typval_encode_list_start(EncodedData *const edata,
- const size_t len)
+static inline void typval_encode_list_start(EncodedData *const edata, const size_t len)
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL
{
- kv_push(edata->stack, ARRAY_OBJ(((Array) {
+ kvi_push(edata->stack, ARRAY_OBJ(((Array) {
.capacity = len,
.size = 0,
.items = xmalloc(len * sizeof(*((Object)OBJECT_INIT).data.array.items)),
@@ -477,7 +480,7 @@ static inline void typval_encode_list_start(EncodedData *const edata,
}
#define TYPVAL_ENCODE_CONV_LIST_START(tv, len) \
- typval_encode_list_start(edata, (size_t)(len))
+ typval_encode_list_start(edata, (size_t)(len))
#define TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START(tv, mpsv)
@@ -492,7 +495,7 @@ static inline void typval_encode_between_list_items(EncodedData *const edata)
}
#define TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(tv) \
- typval_encode_between_list_items(edata)
+ typval_encode_between_list_items(edata)
static inline void typval_encode_list_end(EncodedData *const edata)
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL
@@ -505,22 +508,21 @@ static inline void typval_encode_list_end(EncodedData *const edata)
}
#define TYPVAL_ENCODE_CONV_LIST_END(tv) \
- typval_encode_list_end(edata)
+ typval_encode_list_end(edata)
-static inline void typval_encode_dict_start(EncodedData *const edata,
- const size_t len)
+static inline void typval_encode_dict_start(EncodedData *const edata, const size_t len)
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL
{
- kv_push(edata->stack, DICTIONARY_OBJ(((Dictionary) {
+ kvi_push(edata->stack, DICTIONARY_OBJ(((Dictionary) {
.capacity = len,
.size = 0,
.items = xmalloc(len * sizeof(
- *((Object)OBJECT_INIT).data.dictionary.items)),
+ *((Object)OBJECT_INIT).data.dictionary.items)),
})));
}
#define TYPVAL_ENCODE_CONV_DICT_START(tv, dict, len) \
- typval_encode_dict_start(edata, (size_t)(len))
+ typval_encode_dict_start(edata, (size_t)(len))
#define TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START(tv, dict, mpsv)
@@ -535,16 +537,16 @@ static inline void typval_encode_after_key(EncodedData *const edata)
assert(dict->data.dictionary.size < dict->data.dictionary.capacity);
if (key.type == kObjectTypeString) {
dict->data.dictionary.items[dict->data.dictionary.size].key
- = key.data.string;
+ = key.data.string;
} else {
api_free_object(key);
dict->data.dictionary.items[dict->data.dictionary.size].key
- = STATIC_CSTR_TO_STRING("__INVALID_KEY__");
+ = STATIC_CSTR_TO_STRING("__INVALID_KEY__");
}
}
#define TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(tv, dict) \
- typval_encode_after_key(edata)
+ typval_encode_after_key(edata)
static inline void typval_encode_between_dict_items(EncodedData *const edata)
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL
@@ -557,7 +559,7 @@ static inline void typval_encode_between_dict_items(EncodedData *const edata)
}
#define TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(tv, dict) \
- typval_encode_between_dict_items(edata)
+ typval_encode_between_dict_items(edata)
static inline void typval_encode_dict_end(EncodedData *const edata)
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL
@@ -570,10 +572,10 @@ static inline void typval_encode_dict_end(EncodedData *const edata)
}
#define TYPVAL_ENCODE_CONV_DICT_END(tv, dict) \
- typval_encode_dict_end(edata)
+ typval_encode_dict_end(edata)
#define TYPVAL_ENCODE_CONV_RECURSE(val, conv_type) \
- TYPVAL_ENCODE_CONV_NIL(val)
+ TYPVAL_ENCODE_CONV_NIL(val)
#define TYPVAL_ENCODE_SCOPE static
#define TYPVAL_ENCODE_NAME object
@@ -588,6 +590,7 @@ static inline void typval_encode_dict_end(EncodedData *const edata)
#undef TYPVAL_ENCODE_CONV_STRING
#undef TYPVAL_ENCODE_CONV_STR_STRING
#undef TYPVAL_ENCODE_CONV_EXT_STRING
+#undef TYPVAL_ENCODE_CONV_BLOB
#undef TYPVAL_ENCODE_CONV_NUMBER
#undef TYPVAL_ENCODE_CONV_FLOAT
#undef TYPVAL_ENCODE_CONV_FUNC_START
@@ -619,14 +622,15 @@ static inline void typval_encode_dict_end(EncodedData *const edata)
/// @return The converted value
Object vim_to_object(typval_T *obj)
{
- EncodedData edata = { .stack = KV_INITIAL_VALUE };
+ EncodedData edata;
+ kvi_init(edata.stack);
const int evo_ret = encode_vim_to_object(&edata, obj,
"vim_to_object argument");
(void)evo_ret;
assert(evo_ret == OK);
Object ret = kv_A(edata.stack, 0);
assert(kv_size(edata.stack) == 1);
- kv_destroy(edata.stack);
+ kvi_destroy(edata.stack);
return ret;
}
@@ -700,15 +704,15 @@ String cchar_to_string(char c)
/// empty String is returned
String cstr_to_string(const char *str)
{
- if (str == NULL) {
- return (String)STRING_INIT;
- }
+ if (str == NULL) {
+ return (String)STRING_INIT;
+ }
- size_t len = strlen(str);
- return (String){
- .data = xmemdupz(str, len),
- .size = len,
- };
+ size_t len = strlen(str);
+ return (String){
+ .data = xmemdupz(str, len),
+ .size = len,
+ };
}
/// Copies buffer to an allocated String.
@@ -809,8 +813,8 @@ Array string_to_array(const String input, bool crlf)
/// @param buffer Buffer handle for a specific buffer, or 0 for the current
/// buffer, or -1 to signify global behavior ("all buffers")
/// @param is_unmap When true, removes the mapping that matches {lhs}.
-void modify_keymap(Buffer buffer, bool is_unmap, String mode, String lhs,
- String rhs, Dictionary opts, Error *err)
+void modify_keymap(Buffer buffer, bool is_unmap, String mode, String lhs, String rhs,
+ Dictionary opts, Error *err)
{
char *err_msg = NULL; // the error message to report, if any
char *err_arg = NULL; // argument for the error message format string
@@ -908,21 +912,21 @@ void modify_keymap(Buffer buffer, bool is_unmap, String mode, String lhs,
}
switch (buf_do_map(maptype_val, &parsed_args, mode_val, 0, target_buf)) {
- case 0:
- break;
- case 1:
- api_set_error(err, kErrorTypeException, (char *)e_invarg, 0);
- goto fail_and_free;
- case 2:
- api_set_error(err, kErrorTypeException, (char *)e_nomap, 0);
- goto fail_and_free;
- case 5:
- api_set_error(err, kErrorTypeException,
- "E227: mapping already exists for %s", parsed_args.lhs);
- goto fail_and_free;
- default:
- assert(false && "Unrecognized return code!");
- goto fail_and_free;
+ case 0:
+ break;
+ case 1:
+ api_set_error(err, kErrorTypeException, (char *)e_invarg, 0);
+ goto fail_and_free;
+ case 2:
+ api_set_error(err, kErrorTypeException, (char *)e_nomap, 0);
+ goto fail_and_free;
+ case 5:
+ api_set_error(err, kErrorTypeException,
+ "E227: mapping already exists for %s", parsed_args.lhs);
+ goto fail_and_free;
+ default:
+ assert(false && "Unrecognized return code!");
+ goto fail_and_free;
} // switch
xfree(lhs_buf);
@@ -978,44 +982,44 @@ Integer parse_keymap_opts(Dictionary opts, MapArguments *out, Error *err)
bool was_valid_opt = false;
switch (optname[0]) {
- // note: strncmp up to and including the null terminator, so that
- // "nowaitFoobar" won't match against "nowait"
-
- // don't recognize 'buffer' as a key; user shouldn't provide <buffer>
- // when calling nvim_set_keymap or nvim_buf_set_keymap, since it can be
- // inferred from which function they called
- case 'n':
- if (STRNCMP(optname, "noremap", 8) == 0) {
- was_valid_opt = true;
- out->noremap = key_and_val->value.data.boolean;
- } else if (STRNCMP(optname, "nowait", 7) == 0) {
- was_valid_opt = true;
- out->nowait = key_and_val->value.data.boolean;
- }
- break;
- case 's':
- if (STRNCMP(optname, "silent", 7) == 0) {
- was_valid_opt = true;
- out->silent = key_and_val->value.data.boolean;
- } else if (STRNCMP(optname, "script", 7) == 0) {
- was_valid_opt = true;
- out->script = key_and_val->value.data.boolean;
- }
- break;
- case 'e':
- if (STRNCMP(optname, "expr", 5) == 0) {
- was_valid_opt = true;
- out->expr = key_and_val->value.data.boolean;
- }
- break;
- case 'u':
- if (STRNCMP(optname, "unique", 7) == 0) {
- was_valid_opt = true;
- out->unique = key_and_val->value.data.boolean;
- }
- break;
- default:
- break;
+ // note: strncmp up to and including the null terminator, so that
+ // "nowaitFoobar" won't match against "nowait"
+
+ // don't recognize 'buffer' as a key; user shouldn't provide <buffer>
+ // when calling nvim_set_keymap or nvim_buf_set_keymap, since it can be
+ // inferred from which function they called
+ case 'n':
+ if (STRNCMP(optname, "noremap", 8) == 0) {
+ was_valid_opt = true;
+ out->noremap = key_and_val->value.data.boolean;
+ } else if (STRNCMP(optname, "nowait", 7) == 0) {
+ was_valid_opt = true;
+ out->nowait = key_and_val->value.data.boolean;
+ }
+ break;
+ case 's':
+ if (STRNCMP(optname, "silent", 7) == 0) {
+ was_valid_opt = true;
+ out->silent = key_and_val->value.data.boolean;
+ } else if (STRNCMP(optname, "script", 7) == 0) {
+ was_valid_opt = true;
+ out->script = key_and_val->value.data.boolean;
+ }
+ break;
+ case 'e':
+ if (STRNCMP(optname, "expr", 5) == 0) {
+ was_valid_opt = true;
+ out->expr = key_and_val->value.data.boolean;
+ }
+ break;
+ case 'u':
+ if (STRNCMP(optname, "unique", 7) == 0) {
+ was_valid_opt = true;
+ out->unique = key_and_val->value.data.boolean;
+ }
+ break;
+ default:
+ break;
} // switch
if (!was_valid_opt) {
err_msg = "Invalid key: %s";
@@ -1042,8 +1046,7 @@ fail_with_message:
/// @param[out] l Lines are copied here
/// @param err[out] Error, if any
/// @return true unless `err` was set
-bool buf_collect_lines(buf_T *buf, size_t n, int64_t start, bool replace_nl,
- Array *l, Error *err)
+bool buf_collect_lines(buf_T *buf, size_t n, int64_t start, bool replace_nl, Array *l, Error *err)
{
for (size_t i = 0; i < n; i++) {
int64_t lnum = start + (int64_t)i;
@@ -1081,96 +1084,96 @@ bool object_to_vim(Object obj, typval_T *tv, Error *err)
tv->v_lock = VAR_UNLOCKED;
switch (obj.type) {
- case kObjectTypeNil:
- tv->v_type = VAR_SPECIAL;
- tv->vval.v_special = kSpecialVarNull;
- break;
-
- case kObjectTypeBoolean:
- tv->v_type = VAR_BOOL;
- tv->vval.v_bool = obj.data.boolean? kBoolVarTrue: kBoolVarFalse;
- break;
-
- case kObjectTypeBuffer:
- case kObjectTypeWindow:
- case kObjectTypeTabpage:
- case kObjectTypeInteger:
- STATIC_ASSERT(sizeof(obj.data.integer) <= sizeof(varnumber_T),
- "Integer size must be <= VimL number size");
- tv->v_type = VAR_NUMBER;
- tv->vval.v_number = (varnumber_T)obj.data.integer;
- break;
-
- case kObjectTypeFloat:
- tv->v_type = VAR_FLOAT;
- tv->vval.v_float = obj.data.floating;
- break;
-
- case kObjectTypeString:
- tv->v_type = VAR_STRING;
- if (obj.data.string.data == NULL) {
- tv->vval.v_string = NULL;
- } else {
- tv->vval.v_string = xmemdupz(obj.data.string.data,
- obj.data.string.size);
- }
- break;
-
- case kObjectTypeArray: {
- list_T *const list = tv_list_alloc((ptrdiff_t)obj.data.array.size);
+ case kObjectTypeNil:
+ tv->v_type = VAR_SPECIAL;
+ tv->vval.v_special = kSpecialVarNull;
+ break;
+
+ case kObjectTypeBoolean:
+ tv->v_type = VAR_BOOL;
+ tv->vval.v_bool = obj.data.boolean? kBoolVarTrue: kBoolVarFalse;
+ break;
+
+ case kObjectTypeBuffer:
+ case kObjectTypeWindow:
+ case kObjectTypeTabpage:
+ case kObjectTypeInteger:
+ STATIC_ASSERT(sizeof(obj.data.integer) <= sizeof(varnumber_T),
+ "Integer size must be <= VimL number size");
+ tv->v_type = VAR_NUMBER;
+ tv->vval.v_number = (varnumber_T)obj.data.integer;
+ break;
+
+ case kObjectTypeFloat:
+ tv->v_type = VAR_FLOAT;
+ tv->vval.v_float = obj.data.floating;
+ break;
+
+ case kObjectTypeString:
+ tv->v_type = VAR_STRING;
+ if (obj.data.string.data == NULL) {
+ tv->vval.v_string = NULL;
+ } else {
+ tv->vval.v_string = xmemdupz(obj.data.string.data,
+ obj.data.string.size);
+ }
+ break;
- for (uint32_t i = 0; i < obj.data.array.size; i++) {
- Object item = obj.data.array.items[i];
- typval_T li_tv;
+ case kObjectTypeArray: {
+ list_T *const list = tv_list_alloc((ptrdiff_t)obj.data.array.size);
- if (!object_to_vim(item, &li_tv, err)) {
- tv_list_free(list);
- return false;
- }
+ for (uint32_t i = 0; i < obj.data.array.size; i++) {
+ Object item = obj.data.array.items[i];
+ typval_T li_tv;
- tv_list_append_owned_tv(list, li_tv);
+ if (!object_to_vim(item, &li_tv, err)) {
+ tv_list_free(list);
+ return false;
}
- tv_list_ref(list);
- tv->v_type = VAR_LIST;
- tv->vval.v_list = list;
- break;
+ tv_list_append_owned_tv(list, li_tv);
}
+ tv_list_ref(list);
- case kObjectTypeDictionary: {
- dict_T *const dict = tv_dict_alloc();
+ tv->v_type = VAR_LIST;
+ tv->vval.v_list = list;
+ break;
+ }
- for (uint32_t i = 0; i < obj.data.dictionary.size; i++) {
- KeyValuePair item = obj.data.dictionary.items[i];
- String key = item.key;
+ case kObjectTypeDictionary: {
+ dict_T *const dict = tv_dict_alloc();
- if (key.size == 0) {
- api_set_error(err, kErrorTypeValidation,
- "Empty dictionary keys aren't allowed");
- // cleanup
- tv_dict_free(dict);
- return false;
- }
+ for (uint32_t i = 0; i < obj.data.dictionary.size; i++) {
+ KeyValuePair item = obj.data.dictionary.items[i];
+ String key = item.key;
- dictitem_T *const di = tv_dict_item_alloc(key.data);
+ if (key.size == 0) {
+ api_set_error(err, kErrorTypeValidation,
+ "Empty dictionary keys aren't allowed");
+ // cleanup
+ tv_dict_free(dict);
+ return false;
+ }
- if (!object_to_vim(item.value, &di->di_tv, err)) {
- // cleanup
- tv_dict_item_free(di);
- tv_dict_free(dict);
- return false;
- }
+ dictitem_T *const di = tv_dict_item_alloc(key.data);
- tv_dict_add(dict, di);
+ if (!object_to_vim(item.value, &di->di_tv, err)) {
+ // cleanup
+ tv_dict_item_free(di);
+ tv_dict_free(dict);
+ return false;
}
- dict->dv_refcount++;
- tv->v_type = VAR_DICT;
- tv->vval.v_dict = dict;
- break;
+ tv_dict_add(dict, di);
}
- default:
- abort();
+ dict->dv_refcount++;
+
+ tv->v_type = VAR_DICT;
+ tv->vval.v_dict = dict;
+ break;
+ }
+ default:
+ abort();
}
return true;
@@ -1188,33 +1191,33 @@ void api_free_string(String value)
void api_free_object(Object value)
{
switch (value.type) {
- case kObjectTypeNil:
- case kObjectTypeBoolean:
- case kObjectTypeInteger:
- case kObjectTypeFloat:
- case kObjectTypeBuffer:
- case kObjectTypeWindow:
- case kObjectTypeTabpage:
- break;
-
- case kObjectTypeString:
- api_free_string(value.data.string);
- break;
-
- case kObjectTypeArray:
- api_free_array(value.data.array);
- break;
-
- case kObjectTypeDictionary:
- api_free_dictionary(value.data.dictionary);
- break;
-
- case kObjectTypeLuaRef:
- api_free_luaref(value.data.luaref);
- break;
-
- default:
- abort();
+ case kObjectTypeNil:
+ case kObjectTypeBoolean:
+ case kObjectTypeInteger:
+ case kObjectTypeFloat:
+ case kObjectTypeBuffer:
+ case kObjectTypeWindow:
+ case kObjectTypeTabpage:
+ break;
+
+ case kObjectTypeString:
+ api_free_string(value.data.string);
+ break;
+
+ case kObjectTypeArray:
+ api_free_array(value.data.array);
+ break;
+
+ case kObjectTypeDictionary:
+ api_free_dictionary(value.data.dictionary);
+ break;
+
+ case kObjectTypeLuaRef:
+ api_free_luaref(value.data.luaref);
+ break;
+
+ default:
+ abort();
}
}
@@ -1377,36 +1380,30 @@ Dictionary copy_dictionary(Dictionary dict)
Object copy_object(Object obj)
{
switch (obj.type) {
- case kObjectTypeBuffer:
- case kObjectTypeTabpage:
- case kObjectTypeWindow:
- case kObjectTypeNil:
- case kObjectTypeBoolean:
- case kObjectTypeInteger:
- case kObjectTypeFloat:
- return obj;
-
- case kObjectTypeString:
- return STRING_OBJ(copy_string(obj.data.string));
-
- case kObjectTypeArray:
- return ARRAY_OBJ(copy_array(obj.data.array));
-
- case kObjectTypeDictionary: {
- return DICTIONARY_OBJ(copy_dictionary(obj.data.dictionary));
- }
- default:
- abort();
+ case kObjectTypeBuffer:
+ case kObjectTypeTabpage:
+ case kObjectTypeWindow:
+ case kObjectTypeNil:
+ case kObjectTypeBoolean:
+ case kObjectTypeInteger:
+ case kObjectTypeFloat:
+ return obj;
+
+ case kObjectTypeString:
+ return STRING_OBJ(copy_string(obj.data.string));
+
+ case kObjectTypeArray:
+ return ARRAY_OBJ(copy_array(obj.data.array));
+
+ case kObjectTypeDictionary:
+ return DICTIONARY_OBJ(copy_dictionary(obj.data.dictionary));
+ default:
+ abort();
}
}
-static void set_option_value_for(char *key,
- int numval,
- char *stringval,
- int opt_flags,
- int opt_type,
- void *from,
- Error *err)
+static void set_option_value_for(char *key, int numval, char *stringval, int opt_flags,
+ int opt_type, void *from, Error *err)
{
win_T *save_curwin = NULL;
tabpage_T *save_curtab = NULL;
@@ -1415,29 +1412,30 @@ static void set_option_value_for(char *key,
try_start();
switch (opt_type)
{
- case SREQ_WIN:
- if (switch_win(&save_curwin, &save_curtab, (win_T *)from,
- win_find_tabpage((win_T *)from), false) == FAIL)
- {
- if (try_end(err)) {
- return;
- }
- api_set_error(err,
- kErrorTypeException,
- "Problem while switching windows");
+ case SREQ_WIN:
+ if (switch_win_noblock(&save_curwin, &save_curtab, (win_T *)from,
+ win_find_tabpage((win_T *)from), true)
+ == FAIL) {
+ restore_win_noblock(save_curwin, save_curtab, true);
+ if (try_end(err)) {
return;
}
- set_option_value_err(key, numval, stringval, opt_flags, err);
- restore_win(save_curwin, save_curtab, true);
- break;
- case SREQ_BUF:
- aucmd_prepbuf(&aco, (buf_T *)from);
- set_option_value_err(key, numval, stringval, opt_flags, err);
- aucmd_restbuf(&aco);
- break;
- case SREQ_GLOBAL:
- set_option_value_err(key, numval, stringval, opt_flags, err);
- break;
+ api_set_error(err,
+ kErrorTypeException,
+ "Problem while switching windows");
+ return;
+ }
+ set_option_value_err(key, numval, stringval, opt_flags, err);
+ restore_win_noblock(save_curwin, save_curtab, true);
+ break;
+ case SREQ_BUF:
+ aucmd_prepbuf(&aco, (buf_T *)from);
+ set_option_value_err(key, numval, stringval, opt_flags, err);
+ aucmd_restbuf(&aco);
+ break;
+ case SREQ_GLOBAL:
+ set_option_value_err(key, numval, stringval, opt_flags, err);
+ break;
}
if (ERROR_SET(err)) {
@@ -1448,11 +1446,7 @@ static void set_option_value_for(char *key,
}
-static void set_option_value_err(char *key,
- int numval,
- char *stringval,
- int opt_flags,
- Error *err)
+static void set_option_value_err(char *key, int numval, char *stringval, int opt_flags, Error *err)
{
char *errmsg;
@@ -1511,8 +1505,7 @@ ArrayOf(Dictionary) keymap_array(String mode, buf_T *buf)
// Check for correct mode
if (int_mode & current_maphash->m_mode) {
mapblock_fill_dict(dict, current_maphash, buffer_value, false);
- ADD(mappings, vim_to_object(
- (typval_T[]) { { .v_type = VAR_DICT, .vval.v_dict = dict } }));
+ ADD(mappings, vim_to_object((typval_T[]) { { .v_type = VAR_DICT, .vval.v_dict = dict } }));
tv_dict_clear(dict);
}
@@ -1548,13 +1541,13 @@ bool extmark_get_index_from_obj(buf_T *buf, Integer ns_id, Object obj, int
if (obj.type == kObjectTypeInteger) {
Integer id = obj.data.integer;
if (id == 0) {
- *row = 0;
- *col = 0;
- return true;
+ *row = 0;
+ *col = 0;
+ return true;
} else if (id == -1) {
- *row = MAXLNUM;
- *col = MAXCOL;
- return true;
+ *row = MAXLNUM;
+ *col = MAXCOL;
+ return true;
} else if (id < 0) {
api_set_error(err, kErrorTypeValidation, "Mark id must be positive");
return false;
@@ -1570,7 +1563,7 @@ bool extmark_get_index_from_obj(buf_T *buf, Integer ns_id, Object obj, int
return false;
}
- // Check if it is a position
+ // Check if it is a position
} else if (obj.type == kObjectTypeArray) {
Array pos = obj.data.array;
if (pos.size != 2
@@ -1592,9 +1585,10 @@ bool extmark_get_index_from_obj(buf_T *buf, Integer ns_id, Object obj, int
}
}
-VirtText parse_virt_text(Array chunks, Error *err)
+VirtText parse_virt_text(Array chunks, Error *err, int *width)
{
VirtText virt_text = KV_INITIAL_VALUE;
+ int w = 0;
for (size_t i = 0; i < chunks.size; i++) {
if (chunks.items[i].type != kObjectTypeArray) {
api_set_error(err, kErrorTypeValidation, "Chunk is not an array");
@@ -1602,26 +1596,44 @@ VirtText parse_virt_text(Array chunks, Error *err)
}
Array chunk = chunks.items[i].data.array;
if (chunk.size == 0 || chunk.size > 2
- || chunk.items[0].type != kObjectTypeString
- || (chunk.size == 2 && chunk.items[1].type != kObjectTypeString)) {
+ || chunk.items[0].type != kObjectTypeString) {
api_set_error(err, kErrorTypeValidation,
"Chunk is not an array with one or two strings");
goto free_exit;
}
String str = chunk.items[0].data.string;
- char *text = transstr(str.size > 0 ? str.data : ""); // allocates
int hl_id = 0;
if (chunk.size == 2) {
- String hl = chunk.items[1].data.string;
- if (hl.size > 0) {
- hl_id = syn_check_group((char_u *)hl.data, (int)hl.size);
+ Object hl = chunk.items[1];
+ if (hl.type == kObjectTypeArray) {
+ Array arr = hl.data.array;
+ for (size_t j = 0; j < arr.size; j++) {
+ hl_id = object_to_hl_id(arr.items[j], "virt_text highlight", err);
+ if (ERROR_SET(err)) {
+ goto free_exit;
+ }
+ if (j < arr.size-1) {
+ kv_push(virt_text, ((VirtTextChunk){ .text = NULL,
+ .hl_id = hl_id }));
+ }
+ }
+ } else {
+ hl_id = object_to_hl_id(hl, "virt_text highlight", err);
+ if (ERROR_SET(err)) {
+ goto free_exit;
+ }
}
}
+
+ char *text = transstr(str.size > 0 ? str.data : "", false); // allocates
+ w += (int)mb_string2cells((char_u *)text);
+
kv_push(virt_text, ((VirtTextChunk){ .text = text, .hl_id = hl_id }));
}
+ *width = w;
return virt_text;
free_exit:
@@ -1635,8 +1647,7 @@ free_exit:
/// @param what The name of the object, used for error message
/// @param nil_value What to return if the type is nil.
/// @param err Set if there was an error in converting to a bool
-bool api_object_to_bool(Object obj, const char *what,
- bool nil_value, Error *err)
+bool api_object_to_bool(Object obj, const char *what, bool nil_value, Error *err)
{
if (obj.type == kObjectTypeBoolean) {
return obj.data.boolean;
@@ -1656,7 +1667,7 @@ int object_to_hl_id(Object obj, const char *what, Error *err)
String str = obj.data.string;
return str.size ? syn_check_group((char_u *)str.data, (int)str.size) : 0;
} else if (obj.type == kObjectTypeInteger) {
- return (int)obj.data.integer;
+ return MAX((int)obj.data.integer, 0);
} else {
api_set_error(err, kErrorTypeValidation,
"%s is not a valid highlight", what);
@@ -1687,6 +1698,7 @@ HlMessage parse_hl_msg(Array chunks, Error *err)
if (chunk.size == 2) {
String hl = chunk.items[1].data.string;
if (hl.size > 0) {
+ // TODO(bfredl): use object_to_hl_id and allow integer
int hl_id = syn_check_group((char_u *)hl.data, (int)hl.size);
attr = hl_id > 0 ? syn_id2attr(hl_id) : 0;
}
@@ -1705,7 +1717,7 @@ const char *describe_ns(NS ns_id)
{
String name;
handle_T id;
- map_foreach(namespace_ids, name, id, {
+ map_foreach(&namespace_ids, name, id, {
if ((NS)id == ns_id && name.size) {
return name.data;
}
@@ -1738,7 +1750,7 @@ static bool parse_float_relative(String relative, FloatRelative *out)
char *str = relative.data;
if (striequal(str, "editor")) {
*out = kFloatRelativeEditor;
- } else if (striequal(str, "win")) {
+ } else if (striequal(str, "win")) {
*out = kFloatRelativeWindow;
} else if (striequal(str, "cursor")) {
*out = kFloatRelativeCursor;
@@ -1772,7 +1784,7 @@ static void parse_border_style(Object style, FloatConfig *fconfig, Error *err)
{ "shadow", { "", "", " ", " ", " ", " ", " ", "" }, true },
{ "rounded", { "╭", "─", "╮", "│", "╯", "─", "╰", "│" }, false },
{ "solid", { " ", " ", " ", " ", " ", " ", " ", " " }, false },
- { NULL, { { NUL } } , false },
+ { NULL, { { NUL } }, false },
};
schar_T *chars = fconfig->border_chars;
@@ -1790,7 +1802,7 @@ static void parse_border_style(Object style, FloatConfig *fconfig, Error *err)
}
for (size_t i = 0; i < size; i++) {
Object iytem = arr.items[i];
- String string = NULL_STRING;
+ String string;
int hl_id = 0;
if (iytem.type == kObjectTypeArray) {
Array iarr = iytem.data.array;
@@ -1809,7 +1821,6 @@ static void parse_border_style(Object style, FloatConfig *fconfig, Error *err)
return;
}
}
-
} else if (iytem.type == kObjectTypeString) {
string = iytem.data.string;
} else {
@@ -1868,8 +1879,8 @@ static void parse_border_style(Object style, FloatConfig *fconfig, Error *err)
}
}
-bool parse_float_config(Dictionary config, FloatConfig *fconfig, bool reconf,
- bool new_win, Error *err)
+bool parse_float_config(Dictionary config, FloatConfig *fconfig, bool reconf, bool new_win,
+ Error *err)
{
// TODO(bfredl): use a get/has_key interface instead and get rid of extra
// flags
@@ -1970,13 +1981,13 @@ bool parse_float_config(Dictionary config, FloatConfig *fconfig, bool reconf,
has_bufpos = true;
} else if (!strcmp(key, "external")) {
has_external = fconfig->external
- = api_object_to_bool(val, "'external' key", false, err);
+ = api_object_to_bool(val, "'external' key", false, err);
if (ERROR_SET(err)) {
return false;
}
} else if (!strcmp(key, "focusable")) {
fconfig->focusable
- = api_object_to_bool(val, "'focusable' key", true, err);
+ = api_object_to_bool(val, "'focusable' key", true, err);
if (ERROR_SET(err)) {
return false;
}
@@ -2003,13 +2014,13 @@ bool parse_float_config(Dictionary config, FloatConfig *fconfig, bool reconf,
fconfig->style = kWinStyleUnused;
} else if (striequal(val.data.string.data, "minimal")) {
fconfig->style = kWinStyleMinimal;
- } else {
+ } else {
api_set_error(err, kErrorTypeValidation,
"Invalid value of 'style' key");
}
} else if (strequal(key, "noautocmd") && new_win) {
fconfig->noautocmd
- = api_object_to_bool(val, "'noautocmd' key", false, err);
+ = api_object_to_bool(val, "'noautocmd' key", false, err);
if (ERROR_SET(err)) {
return false;
}
diff --git a/src/nvim/api/private/helpers.h b/src/nvim/api/private/helpers.h
index 055abb797f..ecce6afa26 100644
--- a/src/nvim/api/private/helpers.h
+++ b/src/nvim/api/private/helpers.h
@@ -101,6 +101,14 @@
#define api_free_window(value)
#define api_free_tabpage(value)
+EXTERN PMap(handle_T) buffer_handles INIT(= MAP_INIT);
+EXTERN PMap(handle_T) window_handles INIT(= MAP_INIT);
+EXTERN PMap(handle_T) tabpage_handles INIT(= MAP_INIT);
+
+#define handle_get_buffer(h) pmap_get(handle_T)(&buffer_handles, (h))
+#define handle_get_window(h) pmap_get(handle_T)(&window_handles, (h))
+#define handle_get_tabpage(h) pmap_get(handle_T)(&tabpage_handles, (h))
+
/// Structure used for saving state for :try
///
/// Used when caller is supposed to be operating when other VimL code is being
diff --git a/src/nvim/api/tabpage.c b/src/nvim/api/tabpage.c
index 5f727dbc38..14b6be8eeb 100644
--- a/src/nvim/api/tabpage.c
+++ b/src/nvim/api/tabpage.c
@@ -5,10 +5,10 @@
#include <stdint.h>
#include <stdlib.h>
-#include "nvim/api/tabpage.h"
-#include "nvim/api/vim.h"
#include "nvim/api/private/defs.h"
#include "nvim/api/private/helpers.h"
+#include "nvim/api/tabpage.h"
+#include "nvim/api/vim.h"
#include "nvim/memory.h"
#include "nvim/window.h"
@@ -53,7 +53,7 @@ Object nvim_tabpage_get_var(Tabpage tabpage, String name, Error *err)
tabpage_T *tab = find_tab_by_handle(tabpage, err);
if (!tab) {
- return (Object) OBJECT_INIT;
+ return (Object)OBJECT_INIT;
}
return dict_get_value(tab->tp_vars, name, err);
@@ -65,10 +65,7 @@ Object nvim_tabpage_get_var(Tabpage tabpage, String name, Error *err)
/// @param name Variable name
/// @param value Variable value
/// @param[out] err Error details, if any
-void nvim_tabpage_set_var(Tabpage tabpage,
- String name,
- Object value,
- Error *err)
+void nvim_tabpage_set_var(Tabpage tabpage, String name, Object value, Error *err)
FUNC_API_SINCE(1)
{
tabpage_T *tab = find_tab_by_handle(tabpage, err);
diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c
index 51f1af4eb5..9b200dcba2 100644
--- a/src/nvim/api/ui.c
+++ b/src/nvim/api/ui.c
@@ -2,22 +2,22 @@
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
#include <assert.h>
+#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
-#include <stdbool.h>
-#include "nvim/vim.h"
-#include "nvim/ui.h"
-#include "nvim/memory.h"
-#include "nvim/map.h"
-#include "nvim/msgpack_rpc/channel.h"
-#include "nvim/api/ui.h"
#include "nvim/api/private/defs.h"
#include "nvim/api/private/helpers.h"
-#include "nvim/popupmnu.h"
+#include "nvim/api/ui.h"
#include "nvim/cursor_shape.h"
#include "nvim/highlight.h"
+#include "nvim/map.h"
+#include "nvim/memory.h"
+#include "nvim/msgpack_rpc/channel.h"
+#include "nvim/popupmnu.h"
#include "nvim/screen.h"
+#include "nvim/ui.h"
+#include "nvim/vim.h"
#include "nvim/window.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -37,24 +37,18 @@ typedef struct {
bool wildmenu_active;
} UIData;
-static PMap(uint64_t) *connected_uis = NULL;
-
-void remote_ui_init(void)
- FUNC_API_NOEXPORT
-{
- connected_uis = pmap_new(uint64_t)();
-}
+static PMap(uint64_t) connected_uis = MAP_INIT;
void remote_ui_disconnect(uint64_t channel_id)
FUNC_API_NOEXPORT
{
- UI *ui = pmap_get(uint64_t)(connected_uis, channel_id);
+ UI *ui = pmap_get(uint64_t)(&connected_uis, channel_id);
if (!ui) {
return;
}
UIData *data = ui->data;
api_free_array(data->buffer); // Destroy pending screen updates.
- pmap_del(uint64_t)(connected_uis, channel_id);
+ pmap_del(uint64_t)(&connected_uis, channel_id);
xfree(ui->data);
ui->data = NULL; // Flag UI as "stopped".
ui_detach_impl(ui, channel_id);
@@ -73,7 +67,7 @@ void remote_ui_wait_for_attach(void)
}
LOOP_PROCESS_EVENTS_UNTIL(&main_loop, channel->events, -1,
- pmap_has(uint64_t)(connected_uis, CHAN_STDIO));
+ pmap_has(uint64_t)(&connected_uis, CHAN_STDIO));
}
/// Activates UI events on the channel.
@@ -91,11 +85,11 @@ void remote_ui_wait_for_attach(void)
/// @param height Requested screen rows
/// @param options |ui-option| map
/// @param[out] err Error details, if any
-void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height,
- Dictionary options, Error *err)
+void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height, Dictionary options,
+ Error *err)
FUNC_API_SINCE(1) FUNC_API_REMOTE_ONLY
{
- if (pmap_has(uint64_t)(connected_uis, channel_id)) {
+ if (pmap_has(uint64_t)(&connected_uis, channel_id)) {
api_set_error(err, kErrorTypeException,
"UI already attached to channel: %" PRId64, channel_id);
return;
@@ -158,7 +152,7 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height,
}
if (ui->ui_ext[kUIMessages]) {
- // This uses attribute indicies, so ext_linegrid is needed.
+ // This uses attribute indices, so ext_linegrid is needed.
ui->ui_ext[kUILinegrid] = true;
// Cmdline uses the messages area, so it should be externalized too.
ui->ui_ext[kUICmdline] = true;
@@ -172,13 +166,12 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height,
data->wildmenu_active = false;
ui->data = data;
- pmap_put(uint64_t)(connected_uis, channel_id, ui);
+ pmap_put(uint64_t)(&connected_uis, channel_id, ui);
ui_attach_impl(ui, channel_id);
}
/// @deprecated
-void ui_attach(uint64_t channel_id, Integer width, Integer height,
- Boolean enable_rgb, Error *err)
+void ui_attach(uint64_t channel_id, Integer width, Integer height, Boolean enable_rgb, Error *err)
{
Dictionary opts = ARRAY_DICT_INIT;
PUT(opts, "rgb", BOOLEAN_OBJ(enable_rgb));
@@ -195,7 +188,7 @@ void ui_attach(uint64_t channel_id, Integer width, Integer height,
void nvim_ui_detach(uint64_t channel_id, Error *err)
FUNC_API_SINCE(1) FUNC_API_REMOTE_ONLY
{
- if (!pmap_has(uint64_t)(connected_uis, channel_id)) {
+ if (!pmap_has(uint64_t)(&connected_uis, channel_id)) {
api_set_error(err, kErrorTypeException,
"UI not attached to channel: %" PRId64, channel_id);
return;
@@ -204,11 +197,10 @@ void nvim_ui_detach(uint64_t channel_id, Error *err)
}
-void nvim_ui_try_resize(uint64_t channel_id, Integer width,
- Integer height, Error *err)
+void nvim_ui_try_resize(uint64_t channel_id, Integer width, Integer height, Error *err)
FUNC_API_SINCE(1) FUNC_API_REMOTE_ONLY
{
- if (!pmap_has(uint64_t)(connected_uis, channel_id)) {
+ if (!pmap_has(uint64_t)(&connected_uis, channel_id)) {
api_set_error(err, kErrorTypeException,
"UI not attached to channel: %" PRId64, channel_id);
return;
@@ -220,28 +212,26 @@ void nvim_ui_try_resize(uint64_t channel_id, Integer width,
return;
}
- UI *ui = pmap_get(uint64_t)(connected_uis, channel_id);
+ UI *ui = pmap_get(uint64_t)(&connected_uis, channel_id);
ui->width = (int)width;
ui->height = (int)height;
ui_refresh();
}
-void nvim_ui_set_option(uint64_t channel_id, String name,
- Object value, Error *error)
+void nvim_ui_set_option(uint64_t channel_id, String name, Object value, Error *error)
FUNC_API_SINCE(1) FUNC_API_REMOTE_ONLY
{
- if (!pmap_has(uint64_t)(connected_uis, channel_id)) {
+ if (!pmap_has(uint64_t)(&connected_uis, channel_id)) {
api_set_error(error, kErrorTypeException,
"UI not attached to channel: %" PRId64, channel_id);
return;
}
- UI *ui = pmap_get(uint64_t)(connected_uis, channel_id);
+ UI *ui = pmap_get(uint64_t)(&connected_uis, channel_id);
ui_set_option(ui, false, name, value, error);
}
-static void ui_set_option(UI *ui, bool init, String name, Object value,
- Error *error)
+static void ui_set_option(UI *ui, bool init, String name, Object value, Error *error)
{
if (strequal(name.data, "override")) {
if (value.type != kObjectTypeBoolean) {
@@ -306,11 +296,11 @@ static void ui_set_option(UI *ui, bool init, String name, Object value,
/// @param width The new requested width.
/// @param height The new requested height.
/// @param[out] err Error details, if any
-void nvim_ui_try_resize_grid(uint64_t channel_id, Integer grid, Integer width,
- Integer height, Error *err)
+void nvim_ui_try_resize_grid(uint64_t channel_id, Integer grid, Integer width, Integer height,
+ Error *err)
FUNC_API_SINCE(6) FUNC_API_REMOTE_ONLY
{
- if (!pmap_has(uint64_t)(connected_uis, channel_id)) {
+ if (!pmap_has(uint64_t)(&connected_uis, channel_id)) {
api_set_error(err, kErrorTypeException,
"UI not attached to channel: %" PRId64, channel_id);
return;
@@ -328,7 +318,7 @@ void nvim_ui_try_resize_grid(uint64_t channel_id, Integer grid, Integer width,
void nvim_ui_pum_set_height(uint64_t channel_id, Integer height, Error *err)
FUNC_API_SINCE(6) FUNC_API_REMOTE_ONLY
{
- if (!pmap_has(uint64_t)(connected_uis, channel_id)) {
+ if (!pmap_has(uint64_t)(&connected_uis, channel_id)) {
api_set_error(err, kErrorTypeException,
"UI not attached to channel: %" PRId64, channel_id);
return;
@@ -339,7 +329,7 @@ void nvim_ui_pum_set_height(uint64_t channel_id, Integer height, Error *err)
return;
}
- UI *ui = pmap_get(uint64_t)(connected_uis, channel_id);
+ UI *ui = pmap_get(uint64_t)(&connected_uis, channel_id);
if (!ui->ui_ext[kUIPopupmenu]) {
api_set_error(err, kErrorTypeValidation,
"It must support the ext_popupmenu option");
@@ -365,17 +355,17 @@ void nvim_ui_pum_set_height(uint64_t channel_id, Integer height, Error *err)
/// @param row Popupmenu row.
/// @param col Popupmenu height.
/// @param[out] err Error details, if any.
-void nvim_ui_pum_set_bounds(uint64_t channel_id, Float width, Float height,
- Float row, Float col, Error *err)
+void nvim_ui_pum_set_bounds(uint64_t channel_id, Float width, Float height, Float row, Float col,
+ Error *err)
FUNC_API_SINCE(7) FUNC_API_REMOTE_ONLY
{
- if (!pmap_has(uint64_t)(connected_uis, channel_id)) {
+ if (!pmap_has(uint64_t)(&connected_uis, channel_id)) {
api_set_error(err, kErrorTypeException,
"UI not attached to channel: %" PRId64, channel_id);
return;
}
- UI *ui = pmap_get(uint64_t)(connected_uis, channel_id);
+ UI *ui = pmap_get(uint64_t)(&connected_uis, channel_id);
if (!ui->ui_ext[kUIPopupmenu]) {
api_set_error(err, kErrorTypeValidation,
"UI must support the ext_popupmenu option");
@@ -430,8 +420,7 @@ static void remote_ui_grid_clear(UI *ui, Integer grid)
push_call(ui, name, args);
}
-static void remote_ui_grid_resize(UI *ui, Integer grid,
- Integer width, Integer height)
+static void remote_ui_grid_resize(UI *ui, Integer grid, Integer width, Integer height)
{
Array args = ARRAY_DICT_INIT;
if (ui->ui_ext[kUILinegrid]) {
@@ -443,9 +432,8 @@ static void remote_ui_grid_resize(UI *ui, Integer grid,
push_call(ui, name, args);
}
-static void remote_ui_grid_scroll(UI *ui, Integer grid, Integer top,
- Integer bot, Integer left, Integer right,
- Integer rows, Integer cols)
+static void remote_ui_grid_scroll(UI *ui, Integer grid, Integer top, Integer bot, Integer left,
+ Integer right, Integer rows, Integer cols)
{
if (ui->ui_ext[kUILinegrid]) {
Array args = ARRAY_DICT_INIT;
@@ -480,8 +468,7 @@ static void remote_ui_grid_scroll(UI *ui, Integer grid, Integer top,
}
}
-static void remote_ui_default_colors_set(UI *ui, Integer rgb_fg,
- Integer rgb_bg, Integer rgb_sp,
+static void remote_ui_default_colors_set(UI *ui, Integer rgb_fg, Integer rgb_bg, Integer rgb_sp,
Integer cterm_fg, Integer cterm_bg)
{
if (!ui->ui_ext[kUITermColors]) {
@@ -511,8 +498,8 @@ static void remote_ui_default_colors_set(UI *ui, Integer rgb_fg,
}
}
-static void remote_ui_hl_attr_define(UI *ui, Integer id, HlAttrs rgb_attrs,
- HlAttrs cterm_attrs, Array info)
+static void remote_ui_hl_attr_define(UI *ui, Integer id, HlAttrs rgb_attrs, HlAttrs cterm_attrs,
+ Array info)
{
if (!ui->ui_ext[kUILinegrid]) {
return;
@@ -549,8 +536,7 @@ static void remote_ui_highlight_set(UI *ui, int id)
}
/// "true" cursor used only for input focus
-static void remote_ui_grid_cursor_goto(UI *ui, Integer grid, Integer row,
- Integer col)
+static void remote_ui_grid_cursor_goto(UI *ui, Integer grid, Integer row, Integer col)
{
if (ui->ui_ext[kUILinegrid]) {
Array args = ARRAY_DICT_INIT;
@@ -590,11 +576,9 @@ static void remote_ui_put(UI *ui, const char *cell)
push_call(ui, "put", args);
}
-static void remote_ui_raw_line(UI *ui, Integer grid, Integer row,
- Integer startcol, Integer endcol,
- Integer clearcol, Integer clearattr,
- LineFlags flags, const schar_T *chunk,
- const sattr_T *attrs)
+static void remote_ui_raw_line(UI *ui, Integer grid, Integer row, Integer startcol, Integer endcol,
+ Integer clearcol, Integer clearattr, LineFlags flags,
+ const schar_T *chunk, const sattr_T *attrs)
{
UIData *data = ui->data;
if (ui->ui_ext[kUILinegrid]) {
@@ -735,7 +719,7 @@ static void remote_ui_event(UI *ui, char *name, Array args, bool *args_consumed)
if (ui->ui_ext[kUIWildmenu]) {
if (strequal(name, "popupmenu_show")) {
data->wildmenu_active = (args.items[4].data.integer == -1)
- || !ui->ui_ext[kUIPopupmenu];
+ || !ui->ui_ext[kUIPopupmenu];
if (data->wildmenu_active) {
Array new_args = ARRAY_DICT_INIT;
Array items = args.items[0].data.array;
diff --git a/src/nvim/api/ui_events.in.h b/src/nvim/api/ui_events.in.h
index 35d39a34d7..03fe5c5058 100644
--- a/src/nvim/api/ui_events.in.h
+++ b/src/nvim/api/ui_events.in.h
@@ -119,7 +119,8 @@ void msg_set_pos(Integer grid, Integer row, Boolean scrolled, String sep_char)
FUNC_API_SINCE(6) FUNC_API_BRIDGE_IMPL FUNC_API_COMPOSITOR_IMPL;
void win_viewport(Integer grid, Window win, Integer topline,
- Integer botline, Integer curline, Integer curcol)
+ Integer botline, Integer curline, Integer curcol,
+ Integer line_count)
FUNC_API_SINCE(7) FUNC_API_REMOTE_ONLY;
void popupmenu_show(Array items, Integer selected,
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index 349cc0e7da..3be45d0cf7 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -3,54 +3,54 @@
#include <assert.h>
#include <inttypes.h>
+#include <limits.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
-#include <limits.h>
-#include "nvim/api/vim.h"
-#include "nvim/ascii.h"
-#include "nvim/api/private/helpers.h"
+#include "nvim/api/buffer.h"
+#include "nvim/api/deprecated.h"
#include "nvim/api/private/defs.h"
#include "nvim/api/private/dispatch.h"
-#include "nvim/api/buffer.h"
+#include "nvim/api/private/helpers.h"
+#include "nvim/api/vim.h"
#include "nvim/api/window.h"
-#include "nvim/api/deprecated.h"
-#include "nvim/msgpack_rpc/channel.h"
-#include "nvim/msgpack_rpc/helpers.h"
-#include "nvim/lua/executor.h"
-#include "nvim/vim.h"
+#include "nvim/ascii.h"
#include "nvim/buffer.h"
#include "nvim/context.h"
-#include "nvim/file_search.h"
-#include "nvim/highlight.h"
-#include "nvim/window.h"
-#include "nvim/types.h"
-#include "nvim/ex_cmds2.h"
-#include "nvim/ex_docmd.h"
-#include "nvim/screen.h"
-#include "nvim/memline.h"
-#include "nvim/mark.h"
-#include "nvim/memory.h"
-#include "nvim/message.h"
-#include "nvim/popupmnu.h"
+#include "nvim/decoration.h"
#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_docmd.h"
+#include "nvim/file_search.h"
#include "nvim/fileio.h"
+#include "nvim/getchar.h"
+#include "nvim/highlight.h"
+#include "nvim/lua/executor.h"
+#include "nvim/mark.h"
+#include "nvim/memline.h"
+#include "nvim/memory.h"
+#include "nvim/message.h"
#include "nvim/move.h"
+#include "nvim/msgpack_rpc/channel.h"
+#include "nvim/msgpack_rpc/helpers.h"
#include "nvim/ops.h"
#include "nvim/option.h"
-#include "nvim/state.h"
-#include "nvim/decoration.h"
-#include "nvim/syntax.h"
-#include "nvim/getchar.h"
#include "nvim/os/input.h"
#include "nvim/os/process.h"
+#include "nvim/popupmnu.h"
+#include "nvim/screen.h"
+#include "nvim/state.h"
+#include "nvim/syntax.h"
+#include "nvim/types.h"
+#include "nvim/ui.h"
+#include "nvim/vim.h"
#include "nvim/viml/parser/expressions.h"
#include "nvim/viml/parser/parser.h"
-#include "nvim/ui.h"
+#include "nvim/window.h"
#define LINE_BUFFER_SIZE 4096
@@ -58,22 +58,16 @@
# include "api/vim.c.generated.h"
#endif
-void api_vim_init(void)
- FUNC_API_NOEXPORT
-{
- namespace_ids = map_new(String, handle_T)();
-}
-
void api_vim_free_all_mem(void)
FUNC_API_NOEXPORT
{
String name;
handle_T id;
- map_foreach(namespace_ids, name, id, {
+ map_foreach(&namespace_ids, name, id, {
(void)id;
xfree(name.data);
})
- map_free(String, handle_T)(namespace_ids);
+ map_destroy(String, handle_T)(&namespace_ids);
}
/// Executes Vimscript (multiline block of Ex-commands), like anonymous
@@ -217,7 +211,7 @@ Dictionary nvim__get_hl_defs(Integer ns_id, Error *err)
///
/// @param ns_id number of namespace for this highlight
/// @param name highlight group name, like ErrorMsg
-/// @param val highlight definiton map, like |nvim_get_hl_by_name|.
+/// @param val highlight definition map, like |nvim_get_hl_by_name|.
/// in addition the following keys are also recognized:
/// `default`: don't override existing definition,
/// like `hi default`
@@ -281,9 +275,9 @@ static void on_redraw_event(void **argv)
///
/// On execution error: does not fail, but updates v:errmsg.
///
-/// If you need to input sequences like <C-o> use |nvim_replace_termcodes| to
-/// replace the termcodes and then pass the resulting string to nvim_feedkeys.
-/// You'll also want to enable escape_csi.
+/// To input sequences like <C-o> use |nvim_replace_termcodes()| (typically
+/// with escape_csi=true) to replace |keycodes|, then pass the result to
+/// nvim_feedkeys().
///
/// Example:
/// <pre>
@@ -307,12 +301,18 @@ void nvim_feedkeys(String keys, String mode, Boolean escape_csi)
for (size_t i = 0; i < mode.size; ++i) {
switch (mode.data[i]) {
- case 'n': remap = false; break;
- case 'm': remap = true; break;
- case 't': typed = true; break;
- case 'i': insert = true; break;
- case 'x': execute = true; break;
- case '!': dangerous = true; break;
+ case 'n':
+ remap = false; break;
+ case 'm':
+ remap = true; break;
+ case 't':
+ typed = true; break;
+ case 'i':
+ insert = true; break;
+ case 'x':
+ execute = true; break;
+ case '!':
+ dangerous = true; break;
}
}
@@ -322,11 +322,11 @@ void nvim_feedkeys(String keys, String mode, Boolean escape_csi)
char *keys_esc;
if (escape_csi) {
- // Need to escape K_SPECIAL and CSI before putting the string in the
- // typeahead buffer.
- keys_esc = (char *)vim_strsave_escape_csi((char_u *)keys.data);
+ // Need to escape K_SPECIAL and CSI before putting the string in the
+ // typeahead buffer.
+ keys_esc = (char *)vim_strsave_escape_csi((char_u *)keys.data);
} else {
- keys_esc = keys.data;
+ keys_esc = keys.data;
}
ins_typebuf((char_u *)keys_esc, (remap ? REMAP_YES : REMAP_NONE),
insert ? 0 : typebuf.tb_len, !typed, false);
@@ -335,7 +335,7 @@ void nvim_feedkeys(String keys, String mode, Boolean escape_csi)
}
if (escape_csi) {
- xfree(keys_esc);
+ xfree(keys_esc);
}
if (execute) {
@@ -384,7 +384,7 @@ Integer nvim_input(String keys)
/// by calling it multiple times in a loop: the intermediate mouse
/// positions will be ignored. It should be used to implement real-time
/// mouse input in a GUI. The deprecated pseudokey form
-/// ("<LeftMouse><col,row>") of |nvim_input()| has the same limitiation.
+/// ("<LeftMouse><col,row>") of |nvim_input()| has the same limitation.
///
/// @param button Mouse button: one of "left", "right", "middle", "wheel".
/// @param action For ordinary buttons, one of "press", "drag", "release".
@@ -397,8 +397,8 @@ Integer nvim_input(String keys)
/// @param row Mouse row-position (zero-based, like redraw events)
/// @param col Mouse column-position (zero-based, like redraw events)
/// @param[out] err Error details, if any
-void nvim_input_mouse(String button, String action, String modifier,
- Integer grid, Integer row, Integer col, Error *err)
+void nvim_input_mouse(String button, String action, String modifier, Integer grid, Integer row,
+ Integer col, Error *err)
FUNC_API_SINCE(6) FUNC_API_FAST
{
if (button.data == NULL || action.data == NULL) {
@@ -475,8 +475,7 @@ error:
/// @param special Replace |keycodes|, e.g. <CR> becomes a "\n" char.
/// @see replace_termcodes
/// @see cpoptions
-String nvim_replace_termcodes(String str, Boolean from_part, Boolean do_lt,
- Boolean special)
+String nvim_replace_termcodes(String str, Boolean from_part, Boolean do_lt, Boolean special)
FUNC_API_SINCE(1)
{
if (str.size == 0) {
@@ -505,32 +504,32 @@ Object nvim_eval(String expr, Error *err)
Object rv = OBJECT_INIT;
TRY_WRAP({
- // Initialize `force_abort` and `suppress_errthrow` at the top level.
- if (!recursive) {
- force_abort = false;
- suppress_errthrow = false;
- current_exception = NULL;
- // `did_emsg` is set by emsg(), which cancels execution.
- did_emsg = false;
- }
- recursive++;
- try_start();
+ // Initialize `force_abort` and `suppress_errthrow` at the top level.
+ if (!recursive) {
+ force_abort = false;
+ suppress_errthrow = false;
+ current_exception = NULL;
+ // `did_emsg` is set by emsg(), which cancels execution.
+ did_emsg = false;
+ }
+ recursive++;
+ try_start();
- typval_T rettv;
- int ok = eval0((char_u *)expr.data, &rettv, NULL, true);
+ typval_T rettv;
+ int ok = eval0((char_u *)expr.data, &rettv, NULL, true);
- if (!try_end(err)) {
- if (ok == FAIL) {
- // Should never happen, try_end() should get the error. #8371
- api_set_error(err, kErrorTypeException,
- "Failed to evaluate expression: '%.*s'", 256, expr.data);
- } else {
- rv = vim_to_object(&rettv);
+ if (!try_end(err)) {
+ if (ok == FAIL) {
+ // Should never happen, try_end() should get the error. #8371
+ api_set_error(err, kErrorTypeException,
+ "Failed to evaluate expression: '%.*s'", 256, expr.data);
+ } else {
+ rv = vim_to_object(&rettv);
+ }
}
- }
- tv_clear(&rettv);
- recursive--;
+ tv_clear(&rettv);
+ recursive--;
});
return rv;
@@ -558,7 +557,7 @@ Object nvim_exec_lua(String code, Array args, Error *err)
/// Notify the user with a message
///
/// Relays the call to vim.notify . By default forwards your message in the
-/// echo area but can be overriden to trigger desktop notifications.
+/// echo area but can be overridden to trigger desktop notifications.
///
/// @param msg Message to display to the user
/// @param log_level The log level
@@ -603,28 +602,31 @@ static Object _call_function(String fn, Array args, dict_T *self, Error *err)
}
TRY_WRAP({
- // Initialize `force_abort` and `suppress_errthrow` at the top level.
- if (!recursive) {
- force_abort = false;
- suppress_errthrow = false;
- current_exception = NULL;
- // `did_emsg` is set by emsg(), which cancels execution.
- did_emsg = false;
- }
- recursive++;
- try_start();
- typval_T rettv;
- int dummy;
- // call_func() retval is deceptive, ignore it. Instead we set `msg_list`
- // (see above) to capture abort-causing non-exception errors.
- (void)call_func((char_u *)fn.data, (int)fn.size, &rettv, (int)args.size,
- vim_args, NULL, curwin->w_cursor.lnum, curwin->w_cursor.lnum,
- &dummy, true, NULL, self);
- if (!try_end(err)) {
- rv = vim_to_object(&rettv);
- }
- tv_clear(&rettv);
- recursive--;
+ // Initialize `force_abort` and `suppress_errthrow` at the top level.
+ if (!recursive) {
+ force_abort = false;
+ suppress_errthrow = false;
+ current_exception = NULL;
+ // `did_emsg` is set by emsg(), which cancels execution.
+ did_emsg = false;
+ }
+ recursive++;
+ try_start();
+ typval_T rettv;
+ funcexe_T funcexe = FUNCEXE_INIT;
+ funcexe.firstline = curwin->w_cursor.lnum;
+ funcexe.lastline = curwin->w_cursor.lnum;
+ funcexe.evaluate = true;
+ funcexe.selfdict = self;
+ // call_func() retval is deceptive, ignore it. Instead we set `msg_list`
+ // (see above) to capture abort-causing non-exception errors.
+ (void)call_func((char_u *)fn.data, (int)fn.size, &rettv, (int)args.size,
+ vim_args, &funcexe);
+ if (!try_end(err)) {
+ rv = vim_to_object(&rettv);
+ }
+ tv_clear(&rettv);
+ recursive--;
});
free_vim_args:
@@ -666,31 +668,28 @@ Object nvim_call_dict_function(Object dict, String fn, Array args, Error *err)
typval_T rettv;
bool mustfree = false;
switch (dict.type) {
- case kObjectTypeString: {
- try_start();
- if (eval0((char_u *)dict.data.string.data, &rettv, NULL, true) == FAIL) {
- api_set_error(err, kErrorTypeException,
- "Failed to evaluate dict expression");
- }
- if (try_end(err)) {
- return rv;
- }
- // Evaluation of the string arg created a new dict or increased the
- // refcount of a dict. Not necessary for a RPC dict.
- mustfree = true;
- break;
- }
- case kObjectTypeDictionary: {
- if (!object_to_vim(dict, &rettv, err)) {
- goto end;
- }
- break;
+ case kObjectTypeString:
+ try_start();
+ if (eval0((char_u *)dict.data.string.data, &rettv, NULL, true) == FAIL) {
+ api_set_error(err, kErrorTypeException,
+ "Failed to evaluate dict expression");
}
- default: {
- api_set_error(err, kErrorTypeValidation,
- "dict argument type must be String or Dictionary");
+ if (try_end(err)) {
return rv;
}
+ // Evaluation of the string arg created a new dict or increased the
+ // refcount of a dict. Not necessary for a RPC dict.
+ mustfree = true;
+ break;
+ case kObjectTypeDictionary:
+ if (!object_to_vim(dict, &rettv, err)) {
+ goto end;
+ }
+ break;
+ default:
+ api_set_error(err, kErrorTypeValidation,
+ "dict argument type must be String or Dictionary");
+ return rv;
}
dict_T *self_dict = rettv.vval.v_dict;
if (rettv.v_type != VAR_DICT || !self_dict) {
@@ -753,47 +752,10 @@ Integer nvim_strwidth(String text, Error *err)
/// Gets the paths contained in 'runtimepath'.
///
/// @return List of paths
-ArrayOf(String) nvim_list_runtime_paths(void)
+ArrayOf(String) nvim_list_runtime_paths(Error *err)
FUNC_API_SINCE(1)
{
- // TODO(bfredl): this should just work:
- // return nvim_get_runtime_file(NULL_STRING, true);
-
- Array rv = ARRAY_DICT_INIT;
-
- char_u *rtp = p_rtp;
-
- if (*rtp == NUL) {
- // No paths
- return rv;
- }
-
- // Count the number of paths in rtp
- while (*rtp != NUL) {
- if (*rtp == ',') {
- rv.size++;
- }
- rtp++;
- }
- rv.size++;
-
- // Allocate memory for the copies
- rv.items = xmalloc(sizeof(*rv.items) * rv.size);
- // Reset the position
- rtp = p_rtp;
- // Start copying
- for (size_t i = 0; i < rv.size; i++) {
- rv.items[i].type = kObjectTypeString;
- rv.items[i].data.string.data = xmalloc(MAXPATHL);
- // Copy the path from 'runtimepath' to rv.items[i]
- size_t length = copy_option_part(&rtp,
- (char_u *)rv.items[i].data.string.data,
- MAXPATHL,
- ",");
- rv.items[i].data.string.size = length;
- }
-
- return rv;
+ return nvim_get_runtime_file(NULL_STRING, true, err);
}
/// Find files in runtime directories
@@ -805,10 +767,6 @@ ArrayOf(String) nvim_list_runtime_paths(void)
///
/// It is not an error to not find any files. An empty array is returned then.
///
-/// To find a directory, `name` must end with a forward slash, like
-/// "rplugin/python/". Without the slash it would instead look for an ordinary
-/// file called "rplugin/python".
-///
/// @param name pattern of files to search for
/// @param all whether to return all matches or only the first
/// @return list of absolute paths to the found files
@@ -818,11 +776,7 @@ ArrayOf(String) nvim_get_runtime_file(String name, Boolean all, Error *err)
{
Array rv = ARRAY_DICT_INIT;
- int flags = DIP_START | (all ? DIP_ALL : 0);
-
- if (name.size == 0 || name.data[name.size-1] == '/') {
- flags |= DIP_DIR;
- }
+ int flags = DIP_DIRFILE | (all ? DIP_ALL : 0);
do_in_runtimepath((char_u *)(name.size ? name.data : ""),
flags, find_runtime_cb, &rv);
@@ -1260,7 +1214,7 @@ fail:
///
/// By default (and currently the only option) the terminal will not be
/// connected to an external process. Instead, input send on the channel
-/// will be echoed directly by the terminal. This is useful to disply
+/// will be echoed directly by the terminal. This is useful to display
/// ANSI terminal sequences returned as part of a rpc message, or similar.
///
/// Note: to directly initiate the terminal using the right size, display the
@@ -1290,7 +1244,7 @@ Integer nvim_open_term(Buffer buffer, Dictionary opts, Error *err)
TerminalOptions topts;
Channel *chan = channel_alloc(kChannelStreamInternal);
topts.data = chan;
- // NB: overriden in terminal_check_size if a window is already
+ // NB: overridden in terminal_check_size if a window is already
// displaying the buffer
topts.width = (uint16_t)MAX(curwin->w_width_inner - win_col_off(curwin), 0);
topts.height = (uint16_t)curwin->w_height_inner;
@@ -1468,8 +1422,7 @@ void nvim_chan_send(Integer chan, String data, Error *err)
/// @param[out] err Error details, if any
///
/// @return Window handle, or 0 on error
-Window nvim_open_win(Buffer buffer, Boolean enter, Dictionary config,
- Error *err)
+Window nvim_open_win(Buffer buffer, Boolean enter, Dictionary config, Error *err)
FUNC_API_SINCE(6)
FUNC_API_CHECK_TEXTLOCK
{
@@ -1554,10 +1507,10 @@ void nvim_set_current_tabpage(Tabpage tabpage, Error *err)
}
}
-/// Creates a new namespace, or gets an existing one.
+/// Creates a new *namespace*, or gets an existing one.
///
/// Namespaces are used for buffer highlights and virtual text, see
-/// |nvim_buf_add_highlight()| and |nvim_buf_set_virtual_text()|.
+/// |nvim_buf_add_highlight()| and |nvim_buf_set_extmark()|.
///
/// Namespaces can be named or anonymous. If `name` matches an existing
/// namespace, the associated id is returned. If `name` is an empty string
@@ -1568,14 +1521,14 @@ void nvim_set_current_tabpage(Tabpage tabpage, Error *err)
Integer nvim_create_namespace(String name)
FUNC_API_SINCE(5)
{
- handle_T id = map_get(String, handle_T)(namespace_ids, name);
+ handle_T id = map_get(String, handle_T)(&namespace_ids, name);
if (id > 0) {
return id;
}
id = next_namespace_id++;
if (name.size > 0) {
String name_alloc = copy_string(name);
- map_put(String, handle_T)(namespace_ids, name_alloc, id);
+ map_put(String, handle_T)(&namespace_ids, name_alloc, id);
}
return (Integer)id;
}
@@ -1590,7 +1543,7 @@ Dictionary nvim_get_namespaces(void)
String name;
handle_T id;
- map_foreach(namespace_ids, name, id, {
+ map_foreach(&namespace_ids, name, id, {
PUT(retval, name.data, INTEGER_OBJ(id));
})
@@ -1627,7 +1580,7 @@ Boolean nvim_paste(String data, Boolean crlf, Integer phase, Error *err)
bool cancel = false;
if (phase < -1 || phase > 3) {
- api_set_error(err, kErrorTypeValidation, "Invalid phase: %"PRId64, phase);
+ api_set_error(err, kErrorTypeValidation, "Invalid phase: %" PRId64, phase);
return false;
}
Array args = ARRAY_DICT_INIT;
@@ -1691,12 +1644,11 @@ theend:
/// @param after If true insert after cursor (like |p|), or before (like |P|).
/// @param follow If true place cursor at end of inserted text.
/// @param[out] err Error details, if any
-void nvim_put(ArrayOf(String) lines, String type, Boolean after,
- Boolean follow, Error *err)
+void nvim_put(ArrayOf(String) lines, String type, Boolean after, Boolean follow, Error *err)
FUNC_API_SINCE(6)
FUNC_API_CHECK_TEXTLOCK
{
- yankreg_T *reg = xcalloc(sizeof(yankreg_T), 1);
+ yankreg_T *reg = xcalloc(1, sizeof(yankreg_T));
if (!prepare_yankreg_from_object(reg, type, lines.size)) {
api_set_error(err, kErrorTypeValidation, "Invalid type: '%s'", type.data);
goto cleanup;
@@ -1933,8 +1885,7 @@ ArrayOf(Dictionary) nvim_get_keymap(String mode)
/// as keys excluding |<buffer>| but including |noremap|.
/// Values are Booleans. Unknown key is an error.
/// @param[out] err Error details, if any.
-void nvim_set_keymap(String mode, String lhs, String rhs,
- Dictionary opts, Error *err)
+void nvim_set_keymap(String mode, String lhs, String rhs, Dictionary opts, Error *err)
FUNC_API_SINCE(6)
{
modify_keymap(-1, false, mode, lhs, rhs, opts, err);
@@ -2031,10 +1982,8 @@ Array nvim_get_api_info(uint64_t channel_id)
/// .png or .svg format is preferred.
///
/// @param[out] err Error details, if any
-void nvim_set_client_info(uint64_t channel_id, String name,
- Dictionary version, String type,
- Dictionary methods, Dictionary attributes,
- Error *err)
+void nvim_set_client_info(uint64_t channel_id, String name, Dictionary version, String type,
+ Dictionary methods, Dictionary attributes, Error *err)
FUNC_API_SINCE(4) FUNC_API_REMOTE_ONLY
{
Dictionary info = ARRAY_DICT_INIT;
@@ -2060,27 +2009,28 @@ void nvim_set_client_info(uint64_t channel_id, String name,
rpc_set_client_info(channel_id, info);
}
-/// Get information about a channel.
+/// Gets information about a channel.
///
/// @returns Dictionary describing a channel, with these keys:
-/// - "stream" the stream underlying the channel
+/// - "id" Channel id.
+/// - "argv" (optional) Job arguments list.
+/// - "stream" Stream underlying the channel.
/// - "stdio" stdin and stdout of this Nvim instance
/// - "stderr" stderr of this Nvim instance
/// - "socket" TCP/IP socket or named pipe
-/// - "job" job with communication over its stdio
-/// - "mode" how data received on the channel is interpreted
-/// - "bytes" send and receive raw bytes
-/// - "terminal" a |terminal| instance interprets ASCII sequences
-/// - "rpc" |RPC| communication on the channel is active
-/// - "pty" Name of pseudoterminal, if one is used (optional).
-/// On a POSIX system, this will be a device path like
-/// /dev/pts/1. Even if the name is unknown, the key will
-/// still be present to indicate a pty is used. This is
-/// currently the case when using winpty on windows.
-/// - "buffer" buffer with connected |terminal| instance (optional)
-/// - "client" information about the client on the other end of the
-/// RPC channel, if it has added it using
-/// |nvim_set_client_info()|. (optional)
+/// - "job" Job with communication over its stdio.
+/// - "mode" How data received on the channel is interpreted.
+/// - "bytes" Send and receive raw bytes.
+/// - "terminal" |terminal| instance interprets ASCII sequences.
+/// - "rpc" |RPC| communication on the channel is active.
+/// - "pty" (optional) Name of pseudoterminal. On a POSIX system this
+/// is a device path like "/dev/pts/1". If the name is unknown,
+/// the key will still be present if a pty is used (e.g. for
+/// winpty on Windows).
+/// - "buffer" (optional) Buffer with connected |terminal| instance.
+/// - "client" (optional) Info about the peer (client on the other end of
+/// the RPC channel), if provided by it via
+/// |nvim_set_client_info()|.
///
Dictionary nvim_get_chan_info(Integer chan, Error *err)
FUNC_API_SINCE(4)
@@ -2161,9 +2111,9 @@ Array nvim_call_atomic(uint64_t channel_id, Array calls, Error *err)
Array args = call.items[1].data.array;
MsgpackRpcRequestHandler handler =
- msgpack_rpc_get_handler_for(name.data,
- name.size,
- &nested_error);
+ msgpack_rpc_get_handler_for(name.data,
+ name.size,
+ &nested_error);
if (ERROR_SET(&nested_error)) {
break;
@@ -2237,7 +2187,7 @@ typedef kvec_withinit_t(ExprASTConvStackItem, 16) ExprASTConvStack;
/// - "arg": String, error message argument.
/// - "len": Amount of bytes successfully parsed. With flags equal to ""
/// that should be equal to the length of expr string.
-/// (“Sucessfully parsed” here means “participated in AST
+/// (“Successfully parsed” here means “participated in AST
/// creation”, not “till the first error”.)
/// - "ast": AST, either nil or a dictionary with these keys:
/// - "type": node type, one of the value names from ExprASTNodeType
@@ -2279,29 +2229,29 @@ typedef kvec_withinit_t(ExprASTConvStackItem, 16) ExprASTConvStack;
/// - "svalue": String, value for "SingleQuotedString" and
/// "DoubleQuotedString" nodes.
/// @param[out] err Error details, if any
-Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight,
- Error *err)
+Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight, Error *err)
FUNC_API_SINCE(4) FUNC_API_FAST
{
int pflags = 0;
for (size_t i = 0 ; i < flags.size ; i++) {
switch (flags.data[i]) {
- case 'm': { pflags |= kExprFlagsMulti; break; }
- case 'E': { pflags |= kExprFlagsDisallowEOC; break; }
- case 'l': { pflags |= kExprFlagsParseLet; break; }
- case NUL: {
- api_set_error(err, kErrorTypeValidation, "Invalid flag: '\\0' (%u)",
- (unsigned)flags.data[i]);
- return (Dictionary)ARRAY_DICT_INIT;
- }
- default: {
- api_set_error(err, kErrorTypeValidation, "Invalid flag: '%c' (%u)",
- flags.data[i], (unsigned)flags.data[i]);
- return (Dictionary)ARRAY_DICT_INIT;
- }
+ case 'm':
+ pflags |= kExprFlagsMulti; break;
+ case 'E':
+ pflags |= kExprFlagsDisallowEOC; break;
+ case 'l':
+ pflags |= kExprFlagsParseLet; break;
+ case NUL:
+ api_set_error(err, kErrorTypeValidation, "Invalid flag: '\\0' (%u)",
+ (unsigned)flags.data[i]);
+ return (Dictionary)ARRAY_DICT_INIT;
+ default:
+ api_set_error(err, kErrorTypeValidation, "Invalid flag: '%c' (%u)",
+ flags.data[i], (unsigned)flags.data[i]);
+ return (Dictionary)ARRAY_DICT_INIT;
}
}
- ParserLine plines[] = {
+ ParserLine parser_lines[] = {
{
.data = expr.data,
.size = expr.size,
@@ -2309,20 +2259,19 @@ Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight,
},
{ NULL, 0, false },
};
- ParserLine *plines_p = plines;
+ ParserLine *plines_p = parser_lines;
ParserHighlight colors;
kvi_init(colors);
ParserHighlight *const colors_p = (highlight ? &colors : NULL);
ParserState pstate;
- viml_parser_init(
- &pstate, parser_simple_get_line, &plines_p, colors_p);
+ viml_parser_init(&pstate, parser_simple_get_line, &plines_p, colors_p);
ExprAST east = viml_pexpr_parse(&pstate, pflags);
const size_t ret_size = (
- 2 // "ast", "len"
- + (size_t)(east.err.msg != NULL) // "error"
- + (size_t)highlight // "highlight"
- + 0);
+ 2 // "ast", "len"
+ + (size_t)(east.err.msg != NULL) // "error"
+ + (size_t)highlight // "highlight"
+ + 0);
Dictionary ret = {
.items = xmalloc(ret_size * sizeof(ret.items[0])),
.size = 0,
@@ -2335,7 +2284,7 @@ Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight,
ret.items[ret.size++] = (KeyValuePair) {
.key = STATIC_CSTR_TO_STRING("len"),
.value = INTEGER_OBJ((Integer)(pstate.pos.line == 1
- ? plines[0].size
+ ? parser_lines[0].size
: pstate.pos.col)),
};
if (east.err.msg != NULL) {
@@ -2409,23 +2358,23 @@ Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight,
} else {
if (cur_item.ret_node_p->type == kObjectTypeNil) {
const size_t ret_node_items_size = (size_t)(
- 3 // "type", "start" and "len"
- + (node->children != NULL) // "children"
- + (node->type == kExprNodeOption
- || node->type == kExprNodePlainIdentifier) // "scope"
- + (node->type == kExprNodeOption
- || node->type == kExprNodePlainIdentifier
- || node->type == kExprNodePlainKey
- || node->type == kExprNodeEnvironment) // "ident"
- + (node->type == kExprNodeRegister) // "name"
- + (3 // "cmp_type", "ccs_strategy", "invert"
- * (node->type == kExprNodeComparison))
- + (node->type == kExprNodeInteger) // "ivalue"
- + (node->type == kExprNodeFloat) // "fvalue"
- + (node->type == kExprNodeDoubleQuotedString
- || node->type == kExprNodeSingleQuotedString) // "svalue"
- + (node->type == kExprNodeAssignment) // "augmentation"
- + 0);
+ 3 // "type", "start" and "len"
+ + (node->children != NULL) // "children"
+ + (node->type == kExprNodeOption
+ || node->type == kExprNodePlainIdentifier) // "scope"
+ + (node->type == kExprNodeOption
+ || node->type == kExprNodePlainIdentifier
+ || node->type == kExprNodePlainKey
+ || node->type == kExprNodeEnvironment) // "ident"
+ + (node->type == kExprNodeRegister) // "name"
+ + (3 // "cmp_type", "ccs_strategy", "invert"
+ * (node->type == kExprNodeComparison))
+ + (node->type == kExprNodeInteger) // "ivalue"
+ + (node->type == kExprNodeFloat) // "fvalue"
+ + (node->type == kExprNodeDoubleQuotedString
+ || node->type == kExprNodeSingleQuotedString) // "svalue"
+ + (node->type == kExprNodeAssignment) // "augmentation"
+ + 0);
Dictionary ret_node = {
.items = xmalloc(ret_node_items_size * sizeof(ret_node.items[0])),
.capacity = ret_node_items_size,
@@ -2479,151 +2428,138 @@ Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight,
.value = INTEGER_OBJ((Integer)node->len),
};
switch (node->type) {
- case kExprNodeDoubleQuotedString:
- case kExprNodeSingleQuotedString: {
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("svalue"),
- .value = STRING_OBJ(((String) {
- .data = node->data.str.value,
- .size = node->data.str.size,
- })),
- };
- break;
- }
- case kExprNodeOption: {
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("scope"),
- .value = INTEGER_OBJ(node->data.opt.scope),
- };
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("ident"),
- .value = STRING_OBJ(((String) {
- .data = xmemdupz(node->data.opt.ident,
- node->data.opt.ident_len),
- .size = node->data.opt.ident_len,
- })),
- };
- break;
- }
- case kExprNodePlainIdentifier: {
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("scope"),
- .value = INTEGER_OBJ(node->data.var.scope),
- };
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("ident"),
- .value = STRING_OBJ(((String) {
- .data = xmemdupz(node->data.var.ident,
- node->data.var.ident_len),
- .size = node->data.var.ident_len,
- })),
- };
- break;
- }
- case kExprNodePlainKey: {
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("ident"),
- .value = STRING_OBJ(((String) {
- .data = xmemdupz(node->data.var.ident,
- node->data.var.ident_len),
- .size = node->data.var.ident_len,
- })),
- };
- break;
- }
- case kExprNodeEnvironment: {
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("ident"),
- .value = STRING_OBJ(((String) {
- .data = xmemdupz(node->data.env.ident,
- node->data.env.ident_len),
- .size = node->data.env.ident_len,
- })),
- };
- break;
- }
- case kExprNodeRegister: {
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("name"),
- .value = INTEGER_OBJ(node->data.reg.name),
- };
- break;
- }
- case kExprNodeComparison: {
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("cmp_type"),
- .value = STRING_OBJ(cstr_to_string(
- eltkn_cmp_type_tab[node->data.cmp.type])),
- };
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("ccs_strategy"),
- .value = STRING_OBJ(cstr_to_string(
- ccs_tab[node->data.cmp.ccs])),
- };
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("invert"),
- .value = BOOLEAN_OBJ(node->data.cmp.inv),
- };
- break;
- }
- case kExprNodeFloat: {
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("fvalue"),
- .value = FLOAT_OBJ(node->data.flt.value),
- };
- break;
- }
- case kExprNodeInteger: {
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("ivalue"),
- .value = INTEGER_OBJ((Integer)(
- node->data.num.value > API_INTEGER_MAX
+ case kExprNodeDoubleQuotedString:
+ case kExprNodeSingleQuotedString:
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("svalue"),
+ .value = STRING_OBJ(((String) {
+ .data = node->data.str.value,
+ .size = node->data.str.size,
+ })),
+ };
+ break;
+ case kExprNodeOption:
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("scope"),
+ .value = INTEGER_OBJ(node->data.opt.scope),
+ };
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("ident"),
+ .value = STRING_OBJ(((String) {
+ .data = xmemdupz(node->data.opt.ident,
+ node->data.opt.ident_len),
+ .size = node->data.opt.ident_len,
+ })),
+ };
+ break;
+ case kExprNodePlainIdentifier:
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("scope"),
+ .value = INTEGER_OBJ(node->data.var.scope),
+ };
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("ident"),
+ .value = STRING_OBJ(((String) {
+ .data = xmemdupz(node->data.var.ident,
+ node->data.var.ident_len),
+ .size = node->data.var.ident_len,
+ })),
+ };
+ break;
+ case kExprNodePlainKey:
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("ident"),
+ .value = STRING_OBJ(((String) {
+ .data = xmemdupz(node->data.var.ident,
+ node->data.var.ident_len),
+ .size = node->data.var.ident_len,
+ })),
+ };
+ break;
+ case kExprNodeEnvironment:
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("ident"),
+ .value = STRING_OBJ(((String) {
+ .data = xmemdupz(node->data.env.ident,
+ node->data.env.ident_len),
+ .size = node->data.env.ident_len,
+ })),
+ };
+ break;
+ case kExprNodeRegister:
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("name"),
+ .value = INTEGER_OBJ(node->data.reg.name),
+ };
+ break;
+ case kExprNodeComparison:
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("cmp_type"),
+ .value = STRING_OBJ(cstr_to_string(eltkn_cmp_type_tab[node->data.cmp.type])),
+ };
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("ccs_strategy"),
+ .value = STRING_OBJ(cstr_to_string(ccs_tab[node->data.cmp.ccs])),
+ };
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("invert"),
+ .value = BOOLEAN_OBJ(node->data.cmp.inv),
+ };
+ break;
+ case kExprNodeFloat:
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("fvalue"),
+ .value = FLOAT_OBJ(node->data.flt.value),
+ };
+ break;
+ case kExprNodeInteger:
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("ivalue"),
+ .value = INTEGER_OBJ((Integer)(
+ node->data.num.value > API_INTEGER_MAX
? API_INTEGER_MAX
: (Integer)node->data.num.value)),
- };
- break;
- }
- case kExprNodeAssignment: {
- const ExprAssignmentType asgn_type = node->data.ass.type;
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("augmentation"),
- .value = STRING_OBJ(
- asgn_type == kExprAsgnPlain
+ };
+ break;
+ case kExprNodeAssignment: {
+ const ExprAssignmentType asgn_type = node->data.ass.type;
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("augmentation"),
+ .value = STRING_OBJ(asgn_type == kExprAsgnPlain
? (String)STRING_INIT
: cstr_to_string(expr_asgn_type_tab[asgn_type])),
- };
- break;
- }
- case kExprNodeMissing:
- case kExprNodeOpMissing:
- case kExprNodeTernary:
- case kExprNodeTernaryValue:
- case kExprNodeSubscript:
- case kExprNodeListLiteral:
- case kExprNodeUnaryPlus:
- case kExprNodeBinaryPlus:
- case kExprNodeNested:
- case kExprNodeCall:
- case kExprNodeComplexIdentifier:
- case kExprNodeUnknownFigure:
- case kExprNodeLambda:
- case kExprNodeDictLiteral:
- case kExprNodeCurlyBracesIdentifier:
- case kExprNodeComma:
- case kExprNodeColon:
- case kExprNodeArrow:
- case kExprNodeConcat:
- case kExprNodeConcatOrSubscript:
- case kExprNodeOr:
- case kExprNodeAnd:
- case kExprNodeUnaryMinus:
- case kExprNodeBinaryMinus:
- case kExprNodeNot:
- case kExprNodeMultiplication:
- case kExprNodeDivision:
- case kExprNodeMod: {
- break;
- }
+ };
+ break;
+ }
+ case kExprNodeMissing:
+ case kExprNodeOpMissing:
+ case kExprNodeTernary:
+ case kExprNodeTernaryValue:
+ case kExprNodeSubscript:
+ case kExprNodeListLiteral:
+ case kExprNodeUnaryPlus:
+ case kExprNodeBinaryPlus:
+ case kExprNodeNested:
+ case kExprNodeCall:
+ case kExprNodeComplexIdentifier:
+ case kExprNodeUnknownFigure:
+ case kExprNodeLambda:
+ case kExprNodeDictLiteral:
+ case kExprNodeCurlyBracesIdentifier:
+ case kExprNodeComma:
+ case kExprNodeColon:
+ case kExprNodeArrow:
+ case kExprNodeConcat:
+ case kExprNodeConcatOrSubscript:
+ case kExprNodeOr:
+ case kExprNodeAnd:
+ case kExprNodeUnaryMinus:
+ case kExprNodeBinaryMinus:
+ case kExprNodeNot:
+ case kExprNodeMultiplication:
+ case kExprNodeDivision:
+ case kExprNodeMod:
+ break;
}
assert(cur_item.ret_node_p->data.dictionary.size
== cur_item.ret_node_p->data.dictionary.capacity);
@@ -2853,8 +2789,8 @@ Object nvim_get_proc(Integer pid, Error *err)
/// `insert`.
/// @param opts Optional parameters. Reserved for future use.
/// @param[out] err Error details, if any
-void nvim_select_popupmenu_item(Integer item, Boolean insert, Boolean finish,
- Dictionary opts, Error *err)
+void nvim_select_popupmenu_item(Integer item, Boolean insert, Boolean finish, Dictionary opts,
+ Error *err)
FUNC_API_SINCE(6)
{
if (opts.size > 0) {
@@ -2925,7 +2861,7 @@ void nvim__screenshot(String path)
/// Note: this function should not be called often. Rather, the callbacks
/// themselves can be used to throttle unneeded callbacks. the `on_start`
/// callback can return `false` to disable the provider until the next redraw.
-/// Similarily, return `false` in `on_win` will skip the `on_lines` calls
+/// Similarly, return `false` in `on_win` will skip the `on_lines` calls
/// for that window (but any extmarks set in `on_win` will still be used).
/// A plugin managing multiple sources of decoration should ideally only set
/// one provider, and merge the sources internally. You can use multiple `ns_id`
@@ -2951,8 +2887,7 @@ void nvim__screenshot(String path)
/// ["win", winid, bufnr, row]
/// - on_end: called at the end of a redraw cycle
/// ["end", tick]
-void nvim_set_decoration_provider(Integer ns_id, DictionaryOf(LuaRef) opts,
- Error *err)
+void nvim_set_decoration_provider(Integer ns_id, DictionaryOf(LuaRef) opts, Error *err)
FUNC_API_SINCE(7) FUNC_API_LUA_ONLY
{
DecorProvider *p = get_decor_provider((NS)ns_id, true);
diff --git a/src/nvim/api/vim.h b/src/nvim/api/vim.h
index d6873da6d2..4fd353ce5c 100644
--- a/src/nvim/api/vim.h
+++ b/src/nvim/api/vim.h
@@ -6,7 +6,7 @@
#include "nvim/api/private/defs.h"
#include "nvim/map.h"
-EXTERN Map(String, handle_T) *namespace_ids INIT(= NULL);
+EXTERN Map(String, handle_T) namespace_ids INIT(= MAP_INIT);
EXTERN handle_T next_namespace_id INIT(= 1);
#ifdef INCLUDE_GENERATED_DECLARATIONS
diff --git a/src/nvim/api/window.c b/src/nvim/api/window.c
index 094328b5b0..99ba297111 100644
--- a/src/nvim/api/window.c
+++ b/src/nvim/api/window.c
@@ -1,25 +1,25 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+#include <limits.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
-#include <limits.h>
#include "nvim/api/private/defs.h"
#include "nvim/api/private/helpers.h"
-#include "nvim/lua/executor.h"
-#include "nvim/ex_docmd.h"
-#include "nvim/vim.h"
#include "nvim/api/window.h"
#include "nvim/ascii.h"
#include "nvim/buffer.h"
#include "nvim/cursor.h"
+#include "nvim/ex_docmd.h"
#include "nvim/globals.h"
+#include "nvim/lua/executor.h"
#include "nvim/move.h"
#include "nvim/option.h"
#include "nvim/screen.h"
#include "nvim/syntax.h"
+#include "nvim/vim.h"
#include "nvim/window.h"
/// Gets the current buffer in a window
@@ -222,7 +222,7 @@ Object nvim_win_get_var(Window window, String name, Error *err)
win_T *win = find_window_by_handle(window, err);
if (!win) {
- return (Object) OBJECT_INIT;
+ return (Object)OBJECT_INIT;
}
return dict_get_value(win->w_vars, name, err);
@@ -275,7 +275,7 @@ Object nvim_win_get_option(Window window, String name, Error *err)
win_T *win = find_window_by_handle(window, err);
if (!win) {
- return (Object) OBJECT_INIT;
+ return (Object)OBJECT_INIT;
}
return get_option_from(win, SREQ_WIN, name, err);
@@ -289,8 +289,7 @@ Object nvim_win_get_option(Window window, String name, Error *err)
/// @param name Option name
/// @param value Option value
/// @param[out] err Error details, if any
-void nvim_win_set_option(uint64_t channel_id, Window window,
- String name, Object value, Error *err)
+void nvim_win_set_option(uint64_t channel_id, Window window, String name, Object value, Error *err)
FUNC_API_SINCE(1)
{
win_T *win = find_window_by_handle(window, err);
@@ -394,7 +393,7 @@ void nvim_win_set_config(Window window, Dictionary config, Error *err)
return;
}
bool new_float = !win->w_floating;
- // reuse old values, if not overriden
+ // reuse old values, if not overridden
FloatConfig fconfig = new_float ? FLOAT_CONFIG_INIT : win->w_float_config;
if (!parse_float_config(config, &fconfig, !new_float, false, err)) {
@@ -452,8 +451,7 @@ Dictionary nvim_win_get_config(Window window, Error *err)
PUT(rv, "bufpos", ARRAY_OBJ(pos));
}
}
- PUT(rv, "anchor", STRING_OBJ(cstr_to_string(
- float_anchor_str[config->anchor])));
+ PUT(rv, "anchor", STRING_OBJ(cstr_to_string(float_anchor_str[config->anchor])));
PUT(rv, "row", FLOAT_OBJ(config->row));
PUT(rv, "col", FLOAT_OBJ(config->col));
PUT(rv, "zindex", INTEGER_OBJ(config->zindex));
@@ -463,8 +461,7 @@ Dictionary nvim_win_get_config(Window window, Error *err)
for (size_t i = 0; i < 8; i++) {
Array tuple = ARRAY_DICT_INIT;
- String s = cstrn_to_string(
- (const char *)config->border_chars[i], sizeof(schar_T));
+ String s = cstrn_to_string((const char *)config->border_chars[i], sizeof(schar_T));
int hi_id = config->border_hl_ids[i];
char_u *hi_name = syn_id2name(hi_id);
diff --git a/src/nvim/arabic.c b/src/nvim/arabic.c
index 9fba38a49f..5dcc3d3d0d 100644
--- a/src/nvim/arabic.c
+++ b/src/nvim/arabic.c
@@ -15,9 +15,9 @@
#include <stdbool.h>
-#include "nvim/vim.h"
-#include "nvim/ascii.h"
#include "nvim/arabic.h"
+#include "nvim/ascii.h"
+#include "nvim/vim.h"
// Arabic ISO-10646-1 character set definition
@@ -253,44 +253,44 @@
static bool A_is_a(int cur_c)
{
switch (cur_c) {
- case a_HAMZA:
- case a_ALEF_MADDA:
- case a_ALEF_HAMZA_ABOVE:
- case a_WAW_HAMZA:
- case a_ALEF_HAMZA_BELOW:
- case a_YEH_HAMZA:
- case a_ALEF:
- case a_BEH:
- case a_TEH_MARBUTA:
- case a_TEH:
- case a_THEH:
- case a_JEEM:
- case a_HAH:
- case a_KHAH:
- case a_DAL:
- case a_THAL:
- case a_REH:
- case a_ZAIN:
- case a_SEEN:
- case a_SHEEN:
- case a_SAD:
- case a_DAD:
- case a_TAH:
- case a_ZAH:
- case a_AIN:
- case a_GHAIN:
- case a_TATWEEL:
- case a_FEH:
- case a_QAF:
- case a_KAF:
- case a_LAM:
- case a_MEEM:
- case a_NOON:
- case a_HEH:
- case a_WAW:
- case a_ALEF_MAKSURA:
- case a_YEH:
- return true;
+ case a_HAMZA:
+ case a_ALEF_MADDA:
+ case a_ALEF_HAMZA_ABOVE:
+ case a_WAW_HAMZA:
+ case a_ALEF_HAMZA_BELOW:
+ case a_YEH_HAMZA:
+ case a_ALEF:
+ case a_BEH:
+ case a_TEH_MARBUTA:
+ case a_TEH:
+ case a_THEH:
+ case a_JEEM:
+ case a_HAH:
+ case a_KHAH:
+ case a_DAL:
+ case a_THAL:
+ case a_REH:
+ case a_ZAIN:
+ case a_SEEN:
+ case a_SHEEN:
+ case a_SAD:
+ case a_DAD:
+ case a_TAH:
+ case a_ZAH:
+ case a_AIN:
+ case a_GHAIN:
+ case a_TATWEEL:
+ case a_FEH:
+ case a_QAF:
+ case a_KAF:
+ case a_LAM:
+ case a_MEEM:
+ case a_NOON:
+ case a_HEH:
+ case a_WAW:
+ case a_ALEF_MAKSURA:
+ case a_YEH:
+ return true;
}
return false;
@@ -300,43 +300,43 @@ static bool A_is_a(int cur_c)
static bool A_is_s(int cur_c)
{
switch (cur_c) {
- case a_s_HAMZA:
- case a_s_ALEF_MADDA:
- case a_s_ALEF_HAMZA_ABOVE:
- case a_s_WAW_HAMZA:
- case a_s_ALEF_HAMZA_BELOW:
- case a_s_YEH_HAMZA:
- case a_s_ALEF:
- case a_s_BEH:
- case a_s_TEH_MARBUTA:
- case a_s_TEH:
- case a_s_THEH:
- case a_s_JEEM:
- case a_s_HAH:
- case a_s_KHAH:
- case a_s_DAL:
- case a_s_THAL:
- case a_s_REH:
- case a_s_ZAIN:
- case a_s_SEEN:
- case a_s_SHEEN:
- case a_s_SAD:
- case a_s_DAD:
- case a_s_TAH:
- case a_s_ZAH:
- case a_s_AIN:
- case a_s_GHAIN:
- case a_s_FEH:
- case a_s_QAF:
- case a_s_KAF:
- case a_s_LAM:
- case a_s_MEEM:
- case a_s_NOON:
- case a_s_HEH:
- case a_s_WAW:
- case a_s_ALEF_MAKSURA:
- case a_s_YEH:
- return true;
+ case a_s_HAMZA:
+ case a_s_ALEF_MADDA:
+ case a_s_ALEF_HAMZA_ABOVE:
+ case a_s_WAW_HAMZA:
+ case a_s_ALEF_HAMZA_BELOW:
+ case a_s_YEH_HAMZA:
+ case a_s_ALEF:
+ case a_s_BEH:
+ case a_s_TEH_MARBUTA:
+ case a_s_TEH:
+ case a_s_THEH:
+ case a_s_JEEM:
+ case a_s_HAH:
+ case a_s_KHAH:
+ case a_s_DAL:
+ case a_s_THAL:
+ case a_s_REH:
+ case a_s_ZAIN:
+ case a_s_SEEN:
+ case a_s_SHEEN:
+ case a_s_SAD:
+ case a_s_DAD:
+ case a_s_TAH:
+ case a_s_ZAH:
+ case a_s_AIN:
+ case a_s_GHAIN:
+ case a_s_FEH:
+ case a_s_QAF:
+ case a_s_KAF:
+ case a_s_LAM:
+ case a_s_MEEM:
+ case a_s_NOON:
+ case a_s_HEH:
+ case a_s_WAW:
+ case a_s_ALEF_MAKSURA:
+ case a_s_YEH:
+ return true;
}
return false;
@@ -346,46 +346,46 @@ static bool A_is_s(int cur_c)
static bool A_is_f(int cur_c)
{
switch (cur_c) {
- case a_f_ALEF_MADDA:
- case a_f_ALEF_HAMZA_ABOVE:
- case a_f_WAW_HAMZA:
- case a_f_ALEF_HAMZA_BELOW:
- case a_f_YEH_HAMZA:
- case a_f_ALEF:
- case a_f_BEH:
- case a_f_TEH_MARBUTA:
- case a_f_TEH:
- case a_f_THEH:
- case a_f_JEEM:
- case a_f_HAH:
- case a_f_KHAH:
- case a_f_DAL:
- case a_f_THAL:
- case a_f_REH:
- case a_f_ZAIN:
- case a_f_SEEN:
- case a_f_SHEEN:
- case a_f_SAD:
- case a_f_DAD:
- case a_f_TAH:
- case a_f_ZAH:
- case a_f_AIN:
- case a_f_GHAIN:
- case a_f_FEH:
- case a_f_QAF:
- case a_f_KAF:
- case a_f_LAM:
- case a_f_MEEM:
- case a_f_NOON:
- case a_f_HEH:
- case a_f_WAW:
- case a_f_ALEF_MAKSURA:
- case a_f_YEH:
- case a_f_LAM_ALEF_MADDA_ABOVE:
- case a_f_LAM_ALEF_HAMZA_ABOVE:
- case a_f_LAM_ALEF_HAMZA_BELOW:
- case a_f_LAM_ALEF:
- return true;
+ case a_f_ALEF_MADDA:
+ case a_f_ALEF_HAMZA_ABOVE:
+ case a_f_WAW_HAMZA:
+ case a_f_ALEF_HAMZA_BELOW:
+ case a_f_YEH_HAMZA:
+ case a_f_ALEF:
+ case a_f_BEH:
+ case a_f_TEH_MARBUTA:
+ case a_f_TEH:
+ case a_f_THEH:
+ case a_f_JEEM:
+ case a_f_HAH:
+ case a_f_KHAH:
+ case a_f_DAL:
+ case a_f_THAL:
+ case a_f_REH:
+ case a_f_ZAIN:
+ case a_f_SEEN:
+ case a_f_SHEEN:
+ case a_f_SAD:
+ case a_f_DAD:
+ case a_f_TAH:
+ case a_f_ZAH:
+ case a_f_AIN:
+ case a_f_GHAIN:
+ case a_f_FEH:
+ case a_f_QAF:
+ case a_f_KAF:
+ case a_f_LAM:
+ case a_f_MEEM:
+ case a_f_NOON:
+ case a_f_HEH:
+ case a_f_WAW:
+ case a_f_ALEF_MAKSURA:
+ case a_f_YEH:
+ case a_f_LAM_ALEF_MADDA_ABOVE:
+ case a_f_LAM_ALEF_HAMZA_ABOVE:
+ case a_f_LAM_ALEF_HAMZA_BELOW:
+ case a_f_LAM_ALEF:
+ return true;
}
return false;
}
@@ -394,43 +394,80 @@ static bool A_is_f(int cur_c)
static int chg_c_a2s(int cur_c)
{
switch (cur_c) {
- case a_HAMZA: return a_s_HAMZA;
- case a_ALEF_MADDA: return a_s_ALEF_MADDA;
- case a_ALEF_HAMZA_ABOVE: return a_s_ALEF_HAMZA_ABOVE;
- case a_WAW_HAMZA: return a_s_WAW_HAMZA;
- case a_ALEF_HAMZA_BELOW: return a_s_ALEF_HAMZA_BELOW;
- case a_YEH_HAMZA: return a_s_YEH_HAMZA;
- case a_ALEF: return a_s_ALEF;
- case a_TEH_MARBUTA: return a_s_TEH_MARBUTA;
- case a_DAL: return a_s_DAL;
- case a_THAL: return a_s_THAL;
- case a_REH: return a_s_REH;
- case a_ZAIN: return a_s_ZAIN;
- case a_TATWEEL: return cur_c; // exceptions
- case a_WAW: return a_s_WAW;
- case a_ALEF_MAKSURA: return a_s_ALEF_MAKSURA;
- case a_BEH: return a_s_BEH;
- case a_TEH: return a_s_TEH;
- case a_THEH: return a_s_THEH;
- case a_JEEM: return a_s_JEEM;
- case a_HAH: return a_s_HAH;
- case a_KHAH: return a_s_KHAH;
- case a_SEEN: return a_s_SEEN;
- case a_SHEEN: return a_s_SHEEN;
- case a_SAD: return a_s_SAD;
- case a_DAD: return a_s_DAD;
- case a_TAH: return a_s_TAH;
- case a_ZAH: return a_s_ZAH;
- case a_AIN: return a_s_AIN;
- case a_GHAIN: return a_s_GHAIN;
- case a_FEH: return a_s_FEH;
- case a_QAF: return a_s_QAF;
- case a_KAF: return a_s_KAF;
- case a_LAM: return a_s_LAM;
- case a_MEEM: return a_s_MEEM;
- case a_NOON: return a_s_NOON;
- case a_HEH: return a_s_HEH;
- case a_YEH: return a_s_YEH;
+ case a_HAMZA:
+ return a_s_HAMZA;
+ case a_ALEF_MADDA:
+ return a_s_ALEF_MADDA;
+ case a_ALEF_HAMZA_ABOVE:
+ return a_s_ALEF_HAMZA_ABOVE;
+ case a_WAW_HAMZA:
+ return a_s_WAW_HAMZA;
+ case a_ALEF_HAMZA_BELOW:
+ return a_s_ALEF_HAMZA_BELOW;
+ case a_YEH_HAMZA:
+ return a_s_YEH_HAMZA;
+ case a_ALEF:
+ return a_s_ALEF;
+ case a_TEH_MARBUTA:
+ return a_s_TEH_MARBUTA;
+ case a_DAL:
+ return a_s_DAL;
+ case a_THAL:
+ return a_s_THAL;
+ case a_REH:
+ return a_s_REH;
+ case a_ZAIN:
+ return a_s_ZAIN;
+ case a_TATWEEL:
+ return cur_c; // exceptions
+ case a_WAW:
+ return a_s_WAW;
+ case a_ALEF_MAKSURA:
+ return a_s_ALEF_MAKSURA;
+ case a_BEH:
+ return a_s_BEH;
+ case a_TEH:
+ return a_s_TEH;
+ case a_THEH:
+ return a_s_THEH;
+ case a_JEEM:
+ return a_s_JEEM;
+ case a_HAH:
+ return a_s_HAH;
+ case a_KHAH:
+ return a_s_KHAH;
+ case a_SEEN:
+ return a_s_SEEN;
+ case a_SHEEN:
+ return a_s_SHEEN;
+ case a_SAD:
+ return a_s_SAD;
+ case a_DAD:
+ return a_s_DAD;
+ case a_TAH:
+ return a_s_TAH;
+ case a_ZAH:
+ return a_s_ZAH;
+ case a_AIN:
+ return a_s_AIN;
+ case a_GHAIN:
+ return a_s_GHAIN;
+ case a_FEH:
+ return a_s_FEH;
+ case a_QAF:
+ return a_s_QAF;
+ case a_KAF:
+ return a_s_KAF;
+ case a_LAM:
+ return a_s_LAM;
+ case a_MEEM:
+ return a_s_MEEM;
+ case a_NOON:
+ return a_s_NOON;
+ case a_HEH:
+ return a_s_HEH;
+ case a_YEH:
+ return a_s_YEH;
}
return 0;
}
@@ -439,43 +476,80 @@ static int chg_c_a2s(int cur_c)
static int chg_c_a2i(int cur_c)
{
switch (cur_c) {
- case a_YEH_HAMZA: return a_i_YEH_HAMZA;
- case a_HAMZA: return a_s_HAMZA; // exceptions
- case a_ALEF_MADDA: return a_s_ALEF_MADDA; // exceptions
- case a_ALEF_HAMZA_ABOVE: return a_s_ALEF_HAMZA_ABOVE; // exceptions
- case a_WAW_HAMZA: return a_s_WAW_HAMZA; // exceptions
- case a_ALEF_HAMZA_BELOW: return a_s_ALEF_HAMZA_BELOW; // exceptions
- case a_ALEF: return a_s_ALEF; // exceptions
- case a_TEH_MARBUTA: return a_s_TEH_MARBUTA; // exceptions
- case a_DAL: return a_s_DAL; // exceptions
- case a_THAL: return a_s_THAL; // exceptions
- case a_REH: return a_s_REH; // exceptions
- case a_ZAIN: return a_s_ZAIN; // exceptions
- case a_TATWEEL: return cur_c; // exceptions
- case a_WAW: return a_s_WAW; // exceptions
- case a_ALEF_MAKSURA: return a_s_ALEF_MAKSURA; // exceptions
- case a_BEH: return a_i_BEH;
- case a_TEH: return a_i_TEH;
- case a_THEH: return a_i_THEH;
- case a_JEEM: return a_i_JEEM;
- case a_HAH: return a_i_HAH;
- case a_KHAH: return a_i_KHAH;
- case a_SEEN: return a_i_SEEN;
- case a_SHEEN: return a_i_SHEEN;
- case a_SAD: return a_i_SAD;
- case a_DAD: return a_i_DAD;
- case a_TAH: return a_i_TAH;
- case a_ZAH: return a_i_ZAH;
- case a_AIN: return a_i_AIN;
- case a_GHAIN: return a_i_GHAIN;
- case a_FEH: return a_i_FEH;
- case a_QAF: return a_i_QAF;
- case a_KAF: return a_i_KAF;
- case a_LAM: return a_i_LAM;
- case a_MEEM: return a_i_MEEM;
- case a_NOON: return a_i_NOON;
- case a_HEH: return a_i_HEH;
- case a_YEH: return a_i_YEH;
+ case a_YEH_HAMZA:
+ return a_i_YEH_HAMZA;
+ case a_HAMZA:
+ return a_s_HAMZA; // exceptions
+ case a_ALEF_MADDA:
+ return a_s_ALEF_MADDA; // exceptions
+ case a_ALEF_HAMZA_ABOVE:
+ return a_s_ALEF_HAMZA_ABOVE; // exceptions
+ case a_WAW_HAMZA:
+ return a_s_WAW_HAMZA; // exceptions
+ case a_ALEF_HAMZA_BELOW:
+ return a_s_ALEF_HAMZA_BELOW; // exceptions
+ case a_ALEF:
+ return a_s_ALEF; // exceptions
+ case a_TEH_MARBUTA:
+ return a_s_TEH_MARBUTA; // exceptions
+ case a_DAL:
+ return a_s_DAL; // exceptions
+ case a_THAL:
+ return a_s_THAL; // exceptions
+ case a_REH:
+ return a_s_REH; // exceptions
+ case a_ZAIN:
+ return a_s_ZAIN; // exceptions
+ case a_TATWEEL:
+ return cur_c; // exceptions
+ case a_WAW:
+ return a_s_WAW; // exceptions
+ case a_ALEF_MAKSURA:
+ return a_s_ALEF_MAKSURA; // exceptions
+ case a_BEH:
+ return a_i_BEH;
+ case a_TEH:
+ return a_i_TEH;
+ case a_THEH:
+ return a_i_THEH;
+ case a_JEEM:
+ return a_i_JEEM;
+ case a_HAH:
+ return a_i_HAH;
+ case a_KHAH:
+ return a_i_KHAH;
+ case a_SEEN:
+ return a_i_SEEN;
+ case a_SHEEN:
+ return a_i_SHEEN;
+ case a_SAD:
+ return a_i_SAD;
+ case a_DAD:
+ return a_i_DAD;
+ case a_TAH:
+ return a_i_TAH;
+ case a_ZAH:
+ return a_i_ZAH;
+ case a_AIN:
+ return a_i_AIN;
+ case a_GHAIN:
+ return a_i_GHAIN;
+ case a_FEH:
+ return a_i_FEH;
+ case a_QAF:
+ return a_i_QAF;
+ case a_KAF:
+ return a_i_KAF;
+ case a_LAM:
+ return a_i_LAM;
+ case a_MEEM:
+ return a_i_MEEM;
+ case a_NOON:
+ return a_i_NOON;
+ case a_HEH:
+ return a_i_HEH;
+ case a_YEH:
+ return a_i_YEH;
}
return 0;
}
@@ -484,43 +558,80 @@ static int chg_c_a2i(int cur_c)
static int chg_c_a2m(int cur_c)
{
switch (cur_c) {
- case a_HAMZA: return a_s_HAMZA; // exception
- case a_ALEF_MADDA: return a_f_ALEF_MADDA; // exception
- case a_ALEF_HAMZA_ABOVE: return a_f_ALEF_HAMZA_ABOVE; // exception
- case a_WAW_HAMZA: return a_f_WAW_HAMZA; // exception
- case a_ALEF_HAMZA_BELOW: return a_f_ALEF_HAMZA_BELOW; // exception
- case a_YEH_HAMZA: return a_m_YEH_HAMZA;
- case a_ALEF: return a_f_ALEF; // exception
- case a_BEH: return a_m_BEH;
- case a_TEH_MARBUTA: return a_f_TEH_MARBUTA; // exception
- case a_TEH: return a_m_TEH;
- case a_THEH: return a_m_THEH;
- case a_JEEM: return a_m_JEEM;
- case a_HAH: return a_m_HAH;
- case a_KHAH: return a_m_KHAH;
- case a_DAL: return a_f_DAL; // exception
- case a_THAL: return a_f_THAL; // exception
- case a_REH: return a_f_REH; // exception
- case a_ZAIN: return a_f_ZAIN; // exception
- case a_SEEN: return a_m_SEEN;
- case a_SHEEN: return a_m_SHEEN;
- case a_SAD: return a_m_SAD;
- case a_DAD: return a_m_DAD;
- case a_TAH: return a_m_TAH;
- case a_ZAH: return a_m_ZAH;
- case a_AIN: return a_m_AIN;
- case a_GHAIN: return a_m_GHAIN;
- case a_TATWEEL: return cur_c; // exception
- case a_FEH: return a_m_FEH;
- case a_QAF: return a_m_QAF;
- case a_KAF: return a_m_KAF;
- case a_LAM: return a_m_LAM;
- case a_MEEM: return a_m_MEEM;
- case a_NOON: return a_m_NOON;
- case a_HEH: return a_m_HEH;
- case a_WAW: return a_f_WAW; // exception
- case a_ALEF_MAKSURA: return a_f_ALEF_MAKSURA; // exception
- case a_YEH: return a_m_YEH;
+ case a_HAMZA:
+ return a_s_HAMZA; // exception
+ case a_ALEF_MADDA:
+ return a_f_ALEF_MADDA; // exception
+ case a_ALEF_HAMZA_ABOVE:
+ return a_f_ALEF_HAMZA_ABOVE; // exception
+ case a_WAW_HAMZA:
+ return a_f_WAW_HAMZA; // exception
+ case a_ALEF_HAMZA_BELOW:
+ return a_f_ALEF_HAMZA_BELOW; // exception
+ case a_YEH_HAMZA:
+ return a_m_YEH_HAMZA;
+ case a_ALEF:
+ return a_f_ALEF; // exception
+ case a_BEH:
+ return a_m_BEH;
+ case a_TEH_MARBUTA:
+ return a_f_TEH_MARBUTA; // exception
+ case a_TEH:
+ return a_m_TEH;
+ case a_THEH:
+ return a_m_THEH;
+ case a_JEEM:
+ return a_m_JEEM;
+ case a_HAH:
+ return a_m_HAH;
+ case a_KHAH:
+ return a_m_KHAH;
+ case a_DAL:
+ return a_f_DAL; // exception
+ case a_THAL:
+ return a_f_THAL; // exception
+ case a_REH:
+ return a_f_REH; // exception
+ case a_ZAIN:
+ return a_f_ZAIN; // exception
+ case a_SEEN:
+ return a_m_SEEN;
+ case a_SHEEN:
+ return a_m_SHEEN;
+ case a_SAD:
+ return a_m_SAD;
+ case a_DAD:
+ return a_m_DAD;
+ case a_TAH:
+ return a_m_TAH;
+ case a_ZAH:
+ return a_m_ZAH;
+ case a_AIN:
+ return a_m_AIN;
+ case a_GHAIN:
+ return a_m_GHAIN;
+ case a_TATWEEL:
+ return cur_c; // exception
+ case a_FEH:
+ return a_m_FEH;
+ case a_QAF:
+ return a_m_QAF;
+ case a_KAF:
+ return a_m_KAF;
+ case a_LAM:
+ return a_m_LAM;
+ case a_MEEM:
+ return a_m_MEEM;
+ case a_NOON:
+ return a_m_NOON;
+ case a_HEH:
+ return a_m_HEH;
+ case a_WAW:
+ return a_f_WAW; // exception
+ case a_ALEF_MAKSURA:
+ return a_f_ALEF_MAKSURA; // exception
+ case a_YEH:
+ return a_m_YEH;
}
return 0;
}
@@ -538,43 +649,80 @@ static int chg_c_a2f(int cur_c)
// a_f_LAM_ALEF_HAMZA_BELOW;
switch (cur_c) {
- case a_HAMZA: return a_s_HAMZA; // exception
- case a_ALEF_MADDA: return a_f_ALEF_MADDA;
- case a_ALEF_HAMZA_ABOVE: return a_f_ALEF_HAMZA_ABOVE;
- case a_WAW_HAMZA: return a_f_WAW_HAMZA;
- case a_ALEF_HAMZA_BELOW: return a_f_ALEF_HAMZA_BELOW;
- case a_YEH_HAMZA: return a_f_YEH_HAMZA;
- case a_ALEF: return a_f_ALEF;
- case a_BEH: return a_f_BEH;
- case a_TEH_MARBUTA: return a_f_TEH_MARBUTA;
- case a_TEH: return a_f_TEH;
- case a_THEH: return a_f_THEH;
- case a_JEEM: return a_f_JEEM;
- case a_HAH: return a_f_HAH;
- case a_KHAH: return a_f_KHAH;
- case a_DAL: return a_f_DAL;
- case a_THAL: return a_f_THAL;
- case a_REH: return a_f_REH;
- case a_ZAIN: return a_f_ZAIN;
- case a_SEEN: return a_f_SEEN;
- case a_SHEEN: return a_f_SHEEN;
- case a_SAD: return a_f_SAD;
- case a_DAD: return a_f_DAD;
- case a_TAH: return a_f_TAH;
- case a_ZAH: return a_f_ZAH;
- case a_AIN: return a_f_AIN;
- case a_GHAIN: return a_f_GHAIN;
- case a_TATWEEL: return cur_c; // exception
- case a_FEH: return a_f_FEH;
- case a_QAF: return a_f_QAF;
- case a_KAF: return a_f_KAF;
- case a_LAM: return a_f_LAM;
- case a_MEEM: return a_f_MEEM;
- case a_NOON: return a_f_NOON;
- case a_HEH: return a_f_HEH;
- case a_WAW: return a_f_WAW;
- case a_ALEF_MAKSURA: return a_f_ALEF_MAKSURA;
- case a_YEH: return a_f_YEH;
+ case a_HAMZA:
+ return a_s_HAMZA; // exception
+ case a_ALEF_MADDA:
+ return a_f_ALEF_MADDA;
+ case a_ALEF_HAMZA_ABOVE:
+ return a_f_ALEF_HAMZA_ABOVE;
+ case a_WAW_HAMZA:
+ return a_f_WAW_HAMZA;
+ case a_ALEF_HAMZA_BELOW:
+ return a_f_ALEF_HAMZA_BELOW;
+ case a_YEH_HAMZA:
+ return a_f_YEH_HAMZA;
+ case a_ALEF:
+ return a_f_ALEF;
+ case a_BEH:
+ return a_f_BEH;
+ case a_TEH_MARBUTA:
+ return a_f_TEH_MARBUTA;
+ case a_TEH:
+ return a_f_TEH;
+ case a_THEH:
+ return a_f_THEH;
+ case a_JEEM:
+ return a_f_JEEM;
+ case a_HAH:
+ return a_f_HAH;
+ case a_KHAH:
+ return a_f_KHAH;
+ case a_DAL:
+ return a_f_DAL;
+ case a_THAL:
+ return a_f_THAL;
+ case a_REH:
+ return a_f_REH;
+ case a_ZAIN:
+ return a_f_ZAIN;
+ case a_SEEN:
+ return a_f_SEEN;
+ case a_SHEEN:
+ return a_f_SHEEN;
+ case a_SAD:
+ return a_f_SAD;
+ case a_DAD:
+ return a_f_DAD;
+ case a_TAH:
+ return a_f_TAH;
+ case a_ZAH:
+ return a_f_ZAH;
+ case a_AIN:
+ return a_f_AIN;
+ case a_GHAIN:
+ return a_f_GHAIN;
+ case a_TATWEEL:
+ return cur_c; // exception
+ case a_FEH:
+ return a_f_FEH;
+ case a_QAF:
+ return a_f_QAF;
+ case a_KAF:
+ return a_f_KAF;
+ case a_LAM:
+ return a_f_LAM;
+ case a_MEEM:
+ return a_f_MEEM;
+ case a_NOON:
+ return a_f_NOON;
+ case a_HEH:
+ return a_f_HEH;
+ case a_WAW:
+ return a_f_WAW;
+ case a_ALEF_MAKSURA:
+ return a_f_ALEF_MAKSURA;
+ case a_YEH:
+ return a_f_YEH;
}
return 0;
}
@@ -586,29 +734,52 @@ static int chg_c_a2f(int cur_c)
static int chg_c_i2m(int cur_c)
{
switch (cur_c) {
- case a_i_YEH_HAMZA: return a_m_YEH_HAMZA;
- case a_i_BEH: return a_m_BEH;
- case a_i_TEH: return a_m_TEH;
- case a_i_THEH: return a_m_THEH;
- case a_i_JEEM: return a_m_JEEM;
- case a_i_HAH: return a_m_HAH;
- case a_i_KHAH: return a_m_KHAH;
- case a_i_SEEN: return a_m_SEEN;
- case a_i_SHEEN: return a_m_SHEEN;
- case a_i_SAD: return a_m_SAD;
- case a_i_DAD: return a_m_DAD;
- case a_i_TAH: return a_m_TAH;
- case a_i_ZAH: return a_m_ZAH;
- case a_i_AIN: return a_m_AIN;
- case a_i_GHAIN: return a_m_GHAIN;
- case a_i_FEH: return a_m_FEH;
- case a_i_QAF: return a_m_QAF;
- case a_i_KAF: return a_m_KAF;
- case a_i_LAM: return a_m_LAM;
- case a_i_MEEM: return a_m_MEEM;
- case a_i_NOON: return a_m_NOON;
- case a_i_HEH: return a_m_HEH;
- case a_i_YEH: return a_m_YEH;
+ case a_i_YEH_HAMZA:
+ return a_m_YEH_HAMZA;
+ case a_i_BEH:
+ return a_m_BEH;
+ case a_i_TEH:
+ return a_m_TEH;
+ case a_i_THEH:
+ return a_m_THEH;
+ case a_i_JEEM:
+ return a_m_JEEM;
+ case a_i_HAH:
+ return a_m_HAH;
+ case a_i_KHAH:
+ return a_m_KHAH;
+ case a_i_SEEN:
+ return a_m_SEEN;
+ case a_i_SHEEN:
+ return a_m_SHEEN;
+ case a_i_SAD:
+ return a_m_SAD;
+ case a_i_DAD:
+ return a_m_DAD;
+ case a_i_TAH:
+ return a_m_TAH;
+ case a_i_ZAH:
+ return a_m_ZAH;
+ case a_i_AIN:
+ return a_m_AIN;
+ case a_i_GHAIN:
+ return a_m_GHAIN;
+ case a_i_FEH:
+ return a_m_FEH;
+ case a_i_QAF:
+ return a_m_QAF;
+ case a_i_KAF:
+ return a_m_KAF;
+ case a_i_LAM:
+ return a_m_LAM;
+ case a_i_MEEM:
+ return a_m_MEEM;
+ case a_i_NOON:
+ return a_m_NOON;
+ case a_i_HEH:
+ return a_m_HEH;
+ case a_i_YEH:
+ return a_m_YEH;
}
return 0;
}
@@ -618,43 +789,66 @@ static int chg_c_i2m(int cur_c)
static int chg_c_f2m(int cur_c)
{
switch (cur_c) {
- // NOTE: these encodings are multi-positional, no ?
- // case a_f_ALEF_MADDA:
- // case a_f_ALEF_HAMZA_ABOVE:
- // case a_f_ALEF_HAMZA_BELOW:
- case a_f_YEH_HAMZA: return a_m_YEH_HAMZA;
- case a_f_WAW_HAMZA: // exceptions
- case a_f_ALEF:
- case a_f_TEH_MARBUTA:
- case a_f_DAL:
- case a_f_THAL:
- case a_f_REH:
- case a_f_ZAIN:
- case a_f_WAW:
- case a_f_ALEF_MAKSURA:
- return cur_c;
- case a_f_BEH: return a_m_BEH;
- case a_f_TEH: return a_m_TEH;
- case a_f_THEH: return a_m_THEH;
- case a_f_JEEM: return a_m_JEEM;
- case a_f_HAH: return a_m_HAH;
- case a_f_KHAH: return a_m_KHAH;
- case a_f_SEEN: return a_m_SEEN;
- case a_f_SHEEN: return a_m_SHEEN;
- case a_f_SAD: return a_m_SAD;
- case a_f_DAD: return a_m_DAD;
- case a_f_TAH: return a_m_TAH;
- case a_f_ZAH: return a_m_ZAH;
- case a_f_AIN: return a_m_AIN;
- case a_f_GHAIN: return a_m_GHAIN;
- case a_f_FEH: return a_m_FEH;
- case a_f_QAF: return a_m_QAF;
- case a_f_KAF: return a_m_KAF;
- case a_f_LAM: return a_m_LAM;
- case a_f_MEEM: return a_m_MEEM;
- case a_f_NOON: return a_m_NOON;
- case a_f_HEH: return a_m_HEH;
- case a_f_YEH: return a_m_YEH;
+ // NOTE: these encodings are multi-positional, no ?
+ // case a_f_ALEF_MADDA:
+ // case a_f_ALEF_HAMZA_ABOVE:
+ // case a_f_ALEF_HAMZA_BELOW:
+ case a_f_YEH_HAMZA:
+ return a_m_YEH_HAMZA;
+ case a_f_WAW_HAMZA: // exceptions
+ case a_f_ALEF:
+ case a_f_TEH_MARBUTA:
+ case a_f_DAL:
+ case a_f_THAL:
+ case a_f_REH:
+ case a_f_ZAIN:
+ case a_f_WAW:
+ case a_f_ALEF_MAKSURA:
+ return cur_c;
+ case a_f_BEH:
+ return a_m_BEH;
+ case a_f_TEH:
+ return a_m_TEH;
+ case a_f_THEH:
+ return a_m_THEH;
+ case a_f_JEEM:
+ return a_m_JEEM;
+ case a_f_HAH:
+ return a_m_HAH;
+ case a_f_KHAH:
+ return a_m_KHAH;
+ case a_f_SEEN:
+ return a_m_SEEN;
+ case a_f_SHEEN:
+ return a_m_SHEEN;
+ case a_f_SAD:
+ return a_m_SAD;
+ case a_f_DAD:
+ return a_m_DAD;
+ case a_f_TAH:
+ return a_m_TAH;
+ case a_f_ZAH:
+ return a_m_ZAH;
+ case a_f_AIN:
+ return a_m_AIN;
+ case a_f_GHAIN:
+ return a_m_GHAIN;
+ case a_f_FEH:
+ return a_m_FEH;
+ case a_f_QAF:
+ return a_m_QAF;
+ case a_f_KAF:
+ return a_m_KAF;
+ case a_f_LAM:
+ return a_m_LAM;
+ case a_f_MEEM:
+ return a_m_MEEM;
+ case a_f_NOON:
+ return a_m_NOON;
+ case a_f_HEH:
+ return a_m_HEH;
+ case a_f_YEH:
+ return a_m_YEH;
// NOTE: these encodings are multi-positional, no ?
// case a_f_LAM_ALEF_MADDA_ABOVE:
// case a_f_LAM_ALEF_HAMZA_ABOVE:
@@ -668,10 +862,14 @@ static int chg_c_f2m(int cur_c)
static int chg_c_laa2i(int hid_c)
{
switch (hid_c) {
- case a_ALEF_MADDA: return a_s_LAM_ALEF_MADDA_ABOVE;
- case a_ALEF_HAMZA_ABOVE: return a_s_LAM_ALEF_HAMZA_ABOVE;
- case a_ALEF_HAMZA_BELOW: return a_s_LAM_ALEF_HAMZA_BELOW;
- case a_ALEF: return a_s_LAM_ALEF;
+ case a_ALEF_MADDA:
+ return a_s_LAM_ALEF_MADDA_ABOVE;
+ case a_ALEF_HAMZA_ABOVE:
+ return a_s_LAM_ALEF_HAMZA_ABOVE;
+ case a_ALEF_HAMZA_BELOW:
+ return a_s_LAM_ALEF_HAMZA_BELOW;
+ case a_ALEF:
+ return a_s_LAM_ALEF;
}
return 0;
}
@@ -680,10 +878,14 @@ static int chg_c_laa2i(int hid_c)
static int chg_c_laa2f(int hid_c)
{
switch (hid_c) {
- case a_ALEF_MADDA: return a_f_LAM_ALEF_MADDA_ABOVE;
- case a_ALEF_HAMZA_ABOVE: return a_f_LAM_ALEF_HAMZA_ABOVE;
- case a_ALEF_HAMZA_BELOW: return a_f_LAM_ALEF_HAMZA_BELOW;
- case a_ALEF: return a_f_LAM_ALEF;
+ case a_ALEF_MADDA:
+ return a_f_LAM_ALEF_MADDA_ABOVE;
+ case a_ALEF_HAMZA_ABOVE:
+ return a_f_LAM_ALEF_HAMZA_ABOVE;
+ case a_ALEF_HAMZA_BELOW:
+ return a_f_LAM_ALEF_HAMZA_BELOW;
+ case a_ALEF:
+ return a_f_LAM_ALEF;
}
return 0;
}
@@ -708,8 +910,7 @@ static int half_shape(int c)
// in: "prev_c1" is the first composing char for the previous char
// (not shaped)
// in: "next_c" is the next character (not shaped).
-int arabic_shape(int c, int *ccp, int *c1p, int prev_c, int prev_c1,
- int next_c)
+int arabic_shape(int c, int *ccp, int *c1p, int prev_c, int prev_c1, int next_c)
{
// Deal only with Arabic character, pass back all others
if (!A_is_ok(c)) {
@@ -786,14 +987,14 @@ bool arabic_maycombine(int two)
{
if (p_arshape && !p_tbidi) {
return two == a_ALEF_MADDA
- || two == a_ALEF_HAMZA_ABOVE
- || two == a_ALEF_HAMZA_BELOW
- || two == a_ALEF;
+ || two == a_ALEF_HAMZA_ABOVE
+ || two == a_ALEF_HAMZA_BELOW
+ || two == a_ALEF;
}
return false;
}
-// A_firstc_laa returns first character of LAA combination if it ex.ists
+// A_firstc_laa returns first character of LAA combination if it exists
// in: "c" base character
// in: "c1" first composing character
static int A_firstc_laa(int c, int c1)
diff --git a/src/nvim/ascii.h b/src/nvim/ascii.h
index f41068ea70..7b5e82cd3f 100644
--- a/src/nvim/ascii.h
+++ b/src/nvim/ascii.h
@@ -169,6 +169,14 @@ static inline bool ascii_isbdigit(int c)
return (c == '0' || c == '1');
}
+/// Checks if `c` is an octal digit, that is, 0-7.
+///
+/// @see {ascii_isdigit}
+static inline bool ascii_isodigit(int c)
+{
+ return (c >= '0' && c <= '7');
+}
+
/// Checks if `c` is a white-space character, that is,
/// one of \f, \n, \r, \t, \v.
///
diff --git a/src/nvim/aucmd.c b/src/nvim/aucmd.c
index 32c77fa288..af519dcba9 100644
--- a/src/nvim/aucmd.c
+++ b/src/nvim/aucmd.c
@@ -1,15 +1,16 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
-#include "nvim/os/os.h"
-#include "nvim/fileio.h"
-#include "nvim/vim.h"
-#include "nvim/main.h"
-#include "nvim/ui.h"
#include "nvim/aucmd.h"
+#include "nvim/buffer.h"
#include "nvim/eval.h"
+#include "nvim/ex_docmd.h"
#include "nvim/ex_getln.h"
-#include "nvim/buffer.h"
+#include "nvim/fileio.h"
+#include "nvim/main.h"
+#include "nvim/os/os.h"
+#include "nvim/ui.h"
+#include "nvim/vim.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "aucmd.c.generated.h"
@@ -35,6 +36,29 @@ void do_autocmd_uienter(uint64_t chanid, bool attached)
recursive = false;
}
+void init_default_autocmds(void)
+{
+ // open terminals when opening files that start with term://
+#define PROTO "term://"
+ do_cmdline_cmd("augroup nvim_terminal");
+ do_cmdline_cmd("autocmd BufReadCmd " PROTO "* ++nested "
+ "if !exists('b:term_title')|call termopen("
+ // Capture the command string
+ "matchstr(expand(\"<amatch>\"), "
+ "'\\c\\m" PROTO "\\%(.\\{-}//\\%(\\d\\+:\\)\\?\\)\\?\\zs.*'), "
+ // capture the working directory
+ "{'cwd': expand(get(matchlist(expand(\"<amatch>\"), "
+ "'\\c\\m" PROTO "\\(.\\{-}\\)//'), 1, ''))})"
+ "|endif");
+ do_cmdline_cmd("augroup END");
+#undef PROTO
+
+ // limit syntax synchronization in the command window
+ do_cmdline_cmd("augroup nvim_cmdwin");
+ do_cmdline_cmd("autocmd! CmdwinEnter [:>] syntax sync minlines=1 maxlines=1");
+ do_cmdline_cmd("augroup END");
+}
+
static void focusgained_event(void **argv)
{
bool *gainedp = argv[0];
diff --git a/src/nvim/autocmd.c b/src/nvim/autocmd.c
index 145f6f5601..e7b2ad9000 100644
--- a/src/nvim/autocmd.c
+++ b/src/nvim/autocmd.c
@@ -3,10 +3,9 @@
// autocmd.c: Autocommand related functions
-#include "nvim/autocmd.h"
-
-#include "nvim/api/private/handle.h"
+#include "nvim/api/private/helpers.h"
#include "nvim/ascii.h"
+#include "nvim/autocmd.h"
#include "nvim/buffer.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
@@ -25,8 +24,8 @@
#include "nvim/vim.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
-#include "auevents_name_map.generated.h"
-#include "autocmd.c.generated.h"
+# include "auevents_name_map.generated.h"
+# include "autocmd.c.generated.h"
#endif
//
@@ -326,8 +325,7 @@ static void au_del_group(char_u *name)
event = (event_T)((int)event + 1)) {
for (ap = first_autopat[(int)event]; ap != NULL; ap = ap->next) {
if (ap->group == i && ap->pat != NULL) {
- give_warning(
- (char_u *)_("W19: Deleting augroup that is still in use"), true);
+ give_warning((char_u *)_("W19: Deleting augroup that is still in use"), true);
in_use = true;
event = NUM_EVENTS;
break;
@@ -761,13 +759,8 @@ static int au_get_grouparg(char_u **argp)
// If *cmd == NUL: show entries.
// If forceit == true: delete entries.
// If group is not AUGROUP_ALL: only use this group.
-static int do_autocmd_event(event_T event,
- char_u *pat,
- bool once,
- int nested,
- char_u *cmd,
- int forceit,
- int group)
+static int do_autocmd_event(event_T event, char_u *pat, bool once, int nested, char_u *cmd,
+ int forceit, int group)
{
AutoPat *ap;
AutoPat **prev_ap;
@@ -847,11 +840,10 @@ static int do_autocmd_event(event_T event,
if (is_buflocal) {
// normalize pat into standard "<buffer>#N" form
- snprintf(
- (char *)buflocal_pat,
- BUFLOCAL_PAT_LEN,
- "<buffer=%d>",
- buflocal_nr);
+ snprintf((char *)buflocal_pat,
+ BUFLOCAL_PAT_LEN,
+ "<buffer=%d>",
+ buflocal_nr);
pat = buflocal_pat; // can modify pat and patlen
patlen = (int)STRLEN(buflocal_pat); // but not endpat
@@ -889,7 +881,6 @@ static int do_autocmd_event(event_T event,
} else if (*cmd == NUL) {
// Show autocmd's for this autopat, or buflocals <buffer=X>
show_autocmd(ap, event);
-
} else if (ap->next == NULL) {
// Add autocmd to this autopat, if it's the last one.
break;
@@ -965,11 +956,11 @@ static int do_autocmd_event(event_T event,
return OK;
}
-// Implementation of ":doautocmd [group] event [fname]".
-// Return OK for success, FAIL for failure;
-int do_doautocmd(char_u *arg,
- bool do_msg, // give message for no matching autocmds?
- bool *did_something)
+/// Implementation of ":doautocmd [group] event [fname]".
+/// Return OK for success, FAIL for failure;
+///
+/// @param do_msg give message for no matching autocmds?
+int do_doautocmd(char_u *arg, bool do_msg, bool *did_something)
{
char_u *fname;
int nothing_done = true;
@@ -1150,7 +1141,7 @@ void aucmd_prepbuf(aco_save_T *aco, buf_T *buf)
block_autocmds(); // We don't want BufEnter/WinEnter autocommands.
if (need_append) {
win_append(lastwin, aucmd_win);
- handle_register_window(aucmd_win);
+ pmap_put(handle_T)(&window_handles, aucmd_win->handle, aucmd_win);
win_config_float(aucmd_win, aucmd_win->w_float_config);
}
// Prevent chdir() call in win_enter_ext(), through do_autochdir()
@@ -1188,10 +1179,10 @@ void aucmd_restbuf(aco_save_T *aco)
}
}
}
- win_found:
+win_found:
win_remove(curwin, NULL);
- handle_unregister_window(curwin);
+ pmap_del(handle_T)(&window_handles, curwin->handle);
if (curwin->w_grid_alloc.chars != NULL) {
ui_comp_remove_grid(&curwin->w_grid_alloc);
ui_call_win_hide(curwin->w_grid_alloc.handle);
@@ -1268,11 +1259,7 @@ void aucmd_restbuf(aco_save_T *aco)
/// @param buf Buffer for <abuf>
///
/// @return true if some commands were executed.
-bool apply_autocmds(event_T event,
- char_u *fname,
- char_u *fname_io,
- bool force,
- buf_T *buf)
+bool apply_autocmds(event_T event, char_u *fname, char_u *fname_io, bool force, buf_T *buf)
{
return apply_autocmds_group(event, fname, fname_io, force, AUGROUP_ALL, buf,
NULL);
@@ -1289,11 +1276,7 @@ bool apply_autocmds(event_T event,
/// @param exarg Ex command arguments
///
/// @return true if some commands were executed.
-bool apply_autocmds_exarg(event_T event,
- char_u *fname,
- char_u *fname_io,
- bool force,
- buf_T *buf,
+bool apply_autocmds_exarg(event_T event, char_u *fname, char_u *fname_io, bool force, buf_T *buf,
exarg_T *eap)
{
return apply_autocmds_group(event, fname, fname_io, force, AUGROUP_ALL, buf,
@@ -1313,11 +1296,7 @@ bool apply_autocmds_exarg(event_T event,
/// @param[in,out] retval caller's retval
///
/// @return true if some autocommands were executed
-bool apply_autocmds_retval(event_T event,
- char_u *fname,
- char_u *fname_io,
- bool force,
- buf_T *buf,
+bool apply_autocmds_retval(event_T event, char_u *fname, char_u *fname_io, bool force, buf_T *buf,
int *retval)
{
if (should_abort(*retval)) {
@@ -1344,8 +1323,7 @@ bool has_event(event_T event) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
/// the current mode.
bool has_cursorhold(void) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
- return has_event(
- (get_real_state() == NORMAL_BUSY ? EVENT_CURSORHOLD : EVENT_CURSORHOLDI));
+ return has_event((get_real_state() == NORMAL_BUSY ? EVENT_CURSORHOLD : EVENT_CURSORHOLDI));
// return first_autopat[] != NULL;
}
@@ -1376,13 +1354,8 @@ bool trigger_cursorhold(void) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
/// @param eap Ex command arguments
///
/// @return true if some commands were executed.
-static bool apply_autocmds_group(event_T event,
- char_u *fname,
- char_u *fname_io,
- bool force,
- int group,
- buf_T *buf,
- exarg_T *eap)
+static bool apply_autocmds_group(event_T event, char_u *fname, char_u *fname_io, bool force,
+ int group, buf_T *buf, exarg_T *eap)
{
char_u *sfname = NULL; // short file name
char_u *tail;
@@ -1724,7 +1697,7 @@ BYPASS_AU:
void block_autocmds(void)
{
// Remember the value of v:termresponse.
- if (is_autocmd_blocked()) {
+ if (!is_autocmd_blocked()) {
old_termresponse = get_vim_var_str(VV_TERMRESPONSE);
}
autocmd_blocked++;
@@ -1737,7 +1710,7 @@ void unblock_autocmds(void)
// When v:termresponse was set while autocommands were blocked, trigger
// the autocommands now. Esp. useful when executing a shell command
// during startup (nvim -d).
- if (is_autocmd_blocked()
+ if (!is_autocmd_blocked()
&& get_vim_var_str(VV_TERMRESPONSE) != old_termresponse) {
apply_autocmds(EVENT_TERMRESPONSE, NULL, NULL, false, curbuf);
}
@@ -1769,19 +1742,18 @@ void auto_next_pat(AutoPatCmd *apc, int stop_at_last)
&& (apc->group == AUGROUP_ALL || apc->group == ap->group)) {
// execution-condition
if (ap->buflocal_nr == 0
- ? match_file_pat(
- NULL,
- &ap->reg_prog,
- apc->fname,
- apc->sfname,
- apc->tail,
- ap->allow_dirs)
+ ? match_file_pat(NULL,
+ &ap->reg_prog,
+ apc->fname,
+ apc->sfname,
+ apc->tail,
+ ap->allow_dirs)
: ap->buflocal_nr == apc->arg_bufnr) {
const char *const name = event_nr2name(apc->event);
s = _("%s Autocommands for \"%s\"");
const size_t sourcing_name_len
- = (STRLEN(s) + strlen(name) + (size_t)ap->patlen + 1);
+ = (STRLEN(s) + strlen(name) + (size_t)ap->patlen + 1);
sourcing_name = xmalloc(sourcing_name_len);
snprintf((char *)sourcing_name, sourcing_name_len, s, name,
@@ -1885,9 +1857,7 @@ char_u *getnextac(int c, void *cookie, int indent, bool do_concat)
/// @param event event that occurred.
/// @param sfname filename the event occurred in.
/// @param buf buffer the file is open in
-bool has_autocmd(event_T event,
- char_u *sfname,
- buf_T *buf) FUNC_ATTR_WARN_UNUSED_RESULT
+bool has_autocmd(event_T event, char_u *sfname, buf_T *buf) FUNC_ATTR_WARN_UNUSED_RESULT
{
AutoPat *ap;
char_u *fname;
@@ -1910,13 +1880,12 @@ bool has_autocmd(event_T event,
for (ap = first_autopat[(int)event]; ap != NULL; ap = ap->next) {
if (ap->pat != NULL && ap->cmds != NULL
&& (ap->buflocal_nr == 0
- ? match_file_pat(
- NULL,
- &ap->reg_prog,
- fname,
- sfname,
- tail,
- ap->allow_dirs)
+ ? match_file_pat(NULL,
+ &ap->reg_prog,
+ fname,
+ sfname,
+ tail,
+ ap->allow_dirs)
: buf != NULL && ap->buflocal_nr == buf->b_fnum)) {
retval = true;
break;
@@ -1948,11 +1917,8 @@ char_u *get_augroup_name(expand_T *xp, int idx)
return (char_u *)AUGROUP_NAME(idx);
}
-char_u *set_context_in_autocmd(
- expand_T *xp,
- char_u *arg,
- int doautocmd // true for :doauto*, false for :autocmd
-)
+/// @param doautocmd true for :doauto*, false for :autocmd
+char_u *set_context_in_autocmd(expand_T *xp, char_u *arg, int doautocmd)
{
char_u *p;
int group;
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index f1f32076bf..3c86f55260 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -19,33 +19,34 @@
// The current implementation remembers all file names ever used.
//
+#include <assert.h>
+#include <inttypes.h>
#include <stdbool.h>
#include <string.h>
-#include <inttypes.h>
-#include <assert.h>
-#include "nvim/api/private/handle.h"
#include "nvim/api/private/helpers.h"
#include "nvim/api/vim.h"
#include "nvim/ascii.h"
#include "nvim/assert.h"
-#include "nvim/channel.h"
-#include "nvim/vim.h"
#include "nvim/buffer.h"
+#include "nvim/buffer_updates.h"
#include "nvim/change.h"
+#include "nvim/channel.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
#include "nvim/diff.h"
#include "nvim/digraph.h"
#include "nvim/eval.h"
-#include "nvim/ex_cmds2.h"
#include "nvim/ex_cmds.h"
+#include "nvim/ex_cmds2.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_eval.h"
#include "nvim/ex_getln.h"
-#include "nvim/fileio.h"
+#include "nvim/extmark.h"
#include "nvim/file_search.h"
+#include "nvim/fileio.h"
#include "nvim/fold.h"
+#include "nvim/garray.h"
#include "nvim/getchar.h"
#include "nvim/hashtab.h"
#include "nvim/highlight.h"
@@ -53,20 +54,22 @@
#include "nvim/indent_c.h"
#include "nvim/main.h"
#include "nvim/mark.h"
-#include "nvim/extmark.h"
#include "nvim/mbyte.h"
-#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/garray.h"
#include "nvim/move.h"
#include "nvim/option.h"
+#include "nvim/os/input.h"
+#include "nvim/os/os.h"
+#include "nvim/os/time.h"
#include "nvim/os_unix.h"
#include "nvim/path.h"
+#include "nvim/plines.h"
#include "nvim/quickfix.h"
#include "nvim/regexp.h"
#include "nvim/screen.h"
+#include "nvim/shada.h"
#include "nvim/sign.h"
#include "nvim/spell.h"
#include "nvim/strings.h"
@@ -74,12 +77,8 @@
#include "nvim/ui.h"
#include "nvim/undo.h"
#include "nvim/version.h"
+#include "nvim/vim.h"
#include "nvim/window.h"
-#include "nvim/shada.h"
-#include "nvim/os/os.h"
-#include "nvim/os/time.h"
-#include "nvim/os/input.h"
-#include "nvim/buffer_updates.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "buffer.c.generated.h"
@@ -100,15 +99,15 @@ typedef enum {
kBffInitChangedtick = 2,
} BufFreeFlags;
-// Read data from buffer for retrying.
-static int
-read_buffer(
- int read_stdin, // read file from stdin, otherwise fifo
- exarg_T *eap, // for forced 'ff' and 'fenc' or NULL
- int flags) // extra flags for readfile()
+/// Read data from buffer for retrying.
+///
+/// @param read_stdin read file from stdin, otherwise fifo
+/// @param eap for forced 'ff' and 'fenc' or NULL
+/// @param flags extra flags for readfile()
+static int read_buffer(int read_stdin, exarg_T *eap, int flags)
{
- int retval = OK;
- linenr_T line_count;
+ int retval = OK;
+ linenr_T line_count;
//
// Read from the buffer which the text is already filled in and append at
@@ -116,11 +115,10 @@ read_buffer(
// 'fileencoding' was guessed wrong.
//
line_count = curbuf->b_ml.ml_line_count;
- retval = readfile(
- read_stdin ? NULL : curbuf->b_ffname,
- read_stdin ? NULL : curbuf->b_fname,
- (linenr_T)line_count, (linenr_T)0, (linenr_T)MAXLNUM, eap,
- flags | READ_BUFFER);
+ retval = readfile(read_stdin ? NULL : curbuf->b_ffname,
+ read_stdin ? NULL : curbuf->b_fname,
+ (linenr_T)line_count, (linenr_T)0, (linenr_T)MAXLNUM, eap,
+ flags | READ_BUFFER);
if (retval == OK) {
// Delete the binary lines.
while (--line_count >= 0) {
@@ -139,7 +137,7 @@ read_buffer(
if (read_stdin) {
// Set or reset 'modified' before executing autocommands, so that
// it can be changed there.
- if (!readonlymode && !BUFEMPTY()) {
+ if (!readonlymode && !buf_is_empty(curbuf)) {
changed();
} else if (retval != FAIL) {
unchanged(curbuf, false, true);
@@ -151,17 +149,18 @@ read_buffer(
return retval;
}
-// Open current buffer, that is: open the memfile and read the file into
-// memory.
-// Return FAIL for failure, OK otherwise.
-int open_buffer(
- int read_stdin, // read file from stdin
- exarg_T *eap, // for forced 'ff' and 'fenc' or NULL
- int flags // extra flags for readfile()
-)
+/// Open current buffer, that is: open the memfile and read the file into
+/// memory.
+///
+/// @param read_stdin read file from stdin
+/// @param eap for forced 'ff' and 'fenc' or NULL
+/// @param flags extra flags for readfile()
+///
+/// @return FAIL for failure, OK otherwise.
+int open_buffer(int read_stdin, exarg_T *eap, int flags)
{
int retval = OK;
- bufref_T old_curbuf;
+ bufref_T old_curbuf;
long old_tw = curbuf->b_p_tw;
int read_fifo = false;
@@ -171,8 +170,9 @@ int open_buffer(
* user may have reset the flag by hand.
*/
if (readonlymode && curbuf->b_ffname != NULL
- && (curbuf->b_flags & BF_NEVERLOADED))
+ && (curbuf->b_flags & BF_NEVERLOADED)) {
curbuf->b_p_ro = true;
+ }
if (ml_open(curbuf) == FAIL) {
/*
@@ -229,8 +229,7 @@ int open_buffer(
|| (S_ISCHR(perm)
&& is_dev_fd_file(curbuf->b_ffname))
# endif
- )
- ) {
+ )) {
read_fifo = true;
}
if (read_fifo) {
@@ -269,8 +268,8 @@ int open_buffer(
*/
curbuf->b_p_bin = true;
retval = readfile(NULL, NULL, (linenr_T)0,
- (linenr_T)0, (linenr_T)MAXLNUM, NULL,
- flags | (READ_NEW + READ_STDIN));
+ (linenr_T)0, (linenr_T)MAXLNUM, NULL,
+ flags | (READ_NEW + READ_STDIN));
curbuf->b_p_bin = save_bin;
if (retval == OK) {
retval = read_buffer(true, eap, flags);
@@ -433,8 +432,9 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last)
del_buf = true;
unload_buf = true;
wipe_buf = true;
- } else if (buf->b_p_bh[0] == 'u') // 'bufhidden' == "unload"
+ } else if (buf->b_p_bh[0] == 'u') { // 'bufhidden' == "unload"
unload_buf = true;
+ }
}
if (buf->terminal && (unload_buf || del_buf || wipe_buf)) {
@@ -533,7 +533,7 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last)
}
if (buf->terminal) {
- terminal_close(buf->terminal, NULL);
+ terminal_close(buf->terminal, -1);
}
// Always remove the buffer when there is no file name.
@@ -541,12 +541,10 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last)
del_buf = true;
}
- /*
- * Free all things allocated for this buffer.
- * Also calls the "BufDelete" autocommands when del_buf is TRUE.
- */
- /* Remember if we are closing the current buffer. Restore the number of
- * windows, so that autocommands in buf_freeall() don't get confused. */
+ // Free all things allocated for this buffer.
+ // Also calls the "BufDelete" autocommands when del_buf is true.
+ // Remember if we are closing the current buffer. Restore the number of
+ // windows, so that autocommands in buf_freeall() don't get confused.
bool is_curbuf = (buf == curbuf);
// When closing the current buffer stop Visual mode before freeing
@@ -760,7 +758,7 @@ void buf_freeall(buf_T *buf, int flags)
*/
static void free_buffer(buf_T *buf)
{
- handle_unregister_buffer(buf);
+ pmap_del(handle_T)(&buffer_handles, buf->b_fnum);
buf_free_count++;
// b:changedtick uses an item in buf_T.
free_buffer_stuff(buf, kBffClearWinInfo);
@@ -810,8 +808,8 @@ static void free_buffer_stuff(buf_T *buf, int free_flags)
// Avoid losing b:changedtick when deleting buffer: clearing variables
// implies using clear_tv() on b:changedtick and that sets changedtick to
// zero.
- hashitem_T *const changedtick_hi = hash_find(
- &buf->b_vars->dv_hashtab, (const char_u *)"changedtick");
+ hashitem_T *const changedtick_hi = hash_find(&buf->b_vars->dv_hashtab,
+ (const char_u *)"changedtick");
assert(changedtick_hi != NULL);
hash_remove(&buf->b_vars->dv_hashtab, changedtick_hi);
}
@@ -823,6 +821,7 @@ static void free_buffer_stuff(buf_T *buf, int free_flags)
uc_clear(&buf->b_ucmds); // clear local user commands
buf_delete_signs(buf, (char_u *)"*"); // delete any signs
extmark_free_all(buf); // delete any extmarks
+ clear_virt_lines(buf, -1);
map_clear_int(buf, MAP_ALL_MODES, true, false); // clear local mappings
map_clear_int(buf, MAP_ALL_MODES, true, true); // clear local abbrevs
XFREE_CLEAR(buf->b_start_fenc);
@@ -835,7 +834,7 @@ static void free_buffer_stuff(buf_T *buf, int free_flags)
*/
static void clear_wininfo(buf_T *buf)
{
- wininfo_T *wip;
+ wininfo_T *wip;
while (buf->b_wininfo != NULL) {
wip = buf->b_wininfo;
@@ -901,7 +900,10 @@ void handle_swap_exists(bufref_T *old_curbuf)
if (old_curbuf == NULL
|| !bufref_valid(old_curbuf)
|| old_curbuf->br_buf == curbuf) {
+ // Block autocommands here because curwin->w_buffer is NULL.
+ block_autocmds();
buf = buflist_new(NULL, NULL, 1L, BLN_CURBUF | BLN_LISTED);
+ unblock_autocmds();
} else {
buf = old_curbuf->br_buf;
}
@@ -943,34 +945,28 @@ void handle_swap_exists(bufref_T *old_curbuf)
swap_exists_action = SEA_NONE; // -V519
}
-/*
- * do_bufdel() - delete or unload buffer(s)
- *
- * addr_count == 0: ":bdel" - delete current buffer
- * addr_count == 1: ":N bdel" or ":bdel N [N ..]" - first delete
- * buffer "end_bnr", then any other arguments.
- * addr_count == 2: ":N,N bdel" - delete buffers in range
- *
- * command can be DOBUF_UNLOAD (":bunload"), DOBUF_WIPE (":bwipeout") or
- * DOBUF_DEL (":bdel")
- *
- * Returns error message or NULL
- */
-char_u *
-do_bufdel(
- int command,
- char_u *arg, // pointer to extra arguments
- int addr_count,
- int start_bnr, // first buffer number in a range
- int end_bnr, // buffer nr or last buffer nr in a range
- int forceit
-)
+/// do_bufdel() - delete or unload buffer(s)
+///
+/// addr_count == 0: ":bdel" - delete current buffer
+/// addr_count == 1: ":N bdel" or ":bdel N [N ..]" - first delete
+/// buffer "end_bnr", then any other arguments.
+/// addr_count == 2: ":N,N bdel" - delete buffers in range
+///
+/// command can be DOBUF_UNLOAD (":bunload"), DOBUF_WIPE (":bwipeout") or
+/// DOBUF_DEL (":bdel")
+///
+/// @param arg pointer to extra arguments
+/// @param start_bnr first buffer number in a range
+/// @param end_bnr buffer nr or last buffer nr in a range
+///
+/// @return error message or NULL
+char_u *do_bufdel(int command, char_u *arg, int addr_count, int start_bnr, int end_bnr, int forceit)
{
int do_current = 0; // delete current buffer?
int deleted = 0; // number of buffers deleted
- char_u *errormsg = NULL; // return value
+ char_u *errormsg = NULL; // return value
int bnr; // buffer number
- char_u *p;
+ char_u *p;
if (addr_count == 0) {
(void)do_buffer(command, DOBUF_CURRENT, FORWARD, 0, forceit);
@@ -1074,7 +1070,7 @@ do_bufdel(
static int empty_curbuf(int close_others, int forceit, int action)
{
int retval;
- buf_T *buf = curbuf;
+ buf_T *buf = curbuf;
if (action == DOBUF_UNLOAD) {
EMSG(_("E90: Cannot unload last buffer"));
@@ -1091,7 +1087,7 @@ static int empty_curbuf(int close_others, int forceit, int action)
setpcmark();
retval = do_ecmd(0, NULL, NULL, NULL, ECMD_ONE,
- forceit ? ECMD_FORCEIT : 0, curwin);
+ forceit ? ECMD_FORCEIT : 0, curwin);
// do_ecmd() may create a new buffer, then we have to delete
// the old one. But do_ecmd() may have done that already, check
@@ -1106,40 +1102,39 @@ static int empty_curbuf(int close_others, int forceit, int action)
return retval;
}
-/*
- * Implementation of the commands for the buffer list.
- *
- * action == DOBUF_GOTO go to specified buffer
- * action == DOBUF_SPLIT split window and go to specified buffer
- * action == DOBUF_UNLOAD unload specified buffer(s)
- * action == DOBUF_DEL delete specified buffer(s) from buffer list
- * action == DOBUF_WIPE delete specified buffer(s) really
- *
- * start == DOBUF_CURRENT go to "count" buffer from current buffer
- * start == DOBUF_FIRST go to "count" buffer from first buffer
- * start == DOBUF_LAST go to "count" buffer from last buffer
- * start == DOBUF_MOD go to "count" modified buffer from current buffer
- *
- * Return FAIL or OK.
- */
-int
-do_buffer(
- int action,
- int start,
- int dir, // FORWARD or BACKWARD
- int count, // buffer number or number of buffers
- int forceit // true for :...!
-)
+
+/// Implementation of the commands for the buffer list.
+///
+/// action == DOBUF_GOTO go to specified buffer
+/// action == DOBUF_SPLIT split window and go to specified buffer
+/// action == DOBUF_UNLOAD unload specified buffer(s)
+/// action == DOBUF_DEL delete specified buffer(s) from buffer list
+/// action == DOBUF_WIPE delete specified buffer(s) really
+///
+/// start == DOBUF_CURRENT go to "count" buffer from current buffer
+/// start == DOBUF_FIRST go to "count" buffer from first buffer
+/// start == DOBUF_LAST go to "count" buffer from last buffer
+/// start == DOBUF_MOD go to "count" modified buffer from current buffer
+///
+/// @param dir FORWARD or BACKWARD
+/// @param count buffer number or number of buffers
+/// @param forceit true for :...!
+///
+/// @return FAIL or OK.
+int do_buffer(int action, int start, int dir, int count, int forceit)
{
- buf_T *buf;
- buf_T *bp;
+ buf_T *buf;
+ buf_T *bp;
int unload = (action == DOBUF_UNLOAD || action == DOBUF_DEL
|| action == DOBUF_WIPE);
switch (start) {
- case DOBUF_FIRST: buf = firstbuf; break;
- case DOBUF_LAST: buf = lastbuf; break;
- default: buf = curbuf; break;
+ case DOBUF_FIRST:
+ buf = firstbuf; break;
+ case DOBUF_LAST:
+ buf = lastbuf; break;
+ default:
+ buf = curbuf; break;
}
if (start == DOBUF_MOD) { // find next modified buffer
while (count-- > 0) {
@@ -1219,8 +1214,8 @@ do_buffer(
return FAIL;
}
- if (!forceit && (buf->terminal || bufIsChanged(buf))) {
- if ((p_confirm || cmdmod.confirm) && p_write && !buf->terminal) {
+ if (!forceit && bufIsChanged(buf)) {
+ if ((p_confirm || cmdmod.confirm) && p_write) {
dialog_changed(buf, false);
if (!bufref_valid(&bufref)) {
// Autocommand deleted buffer, oops! It's not changed now.
@@ -1232,22 +1227,22 @@ do_buffer(
return FAIL;
}
} else {
- if (buf->terminal) {
- if (p_confirm || cmdmod.confirm) {
- if (!dialog_close_terminal(buf)) {
- return FAIL;
- }
- } else {
- EMSG2(_("E89: %s will be killed (add ! to override)"),
- (char *)buf->b_fname);
- return FAIL;
- }
- } else {
- EMSGN(_("E89: No write since last change for buffer %" PRId64
- " (add ! to override)"),
- buf->b_fnum);
+ EMSGN(_("E89: No write since last change for buffer %" PRId64
+ " (add ! to override)"),
+ buf->b_fnum);
+ return FAIL;
+ }
+ }
+
+ if (!forceit && buf->terminal && terminal_running(buf->terminal)) {
+ if (p_confirm || cmdmod.confirm) {
+ if (!dialog_close_terminal(buf)) {
return FAIL;
}
+ } else {
+ EMSG2(_("E89: %s will be killed (add ! to override)"),
+ (char *)buf->b_fname);
+ return FAIL;
}
}
@@ -1460,15 +1455,15 @@ do_buffer(
/*
* Set current buffer to "buf". Executes autocommands and closes current
* buffer. "action" tells how to close the current buffer:
- * DOBUF_GOTO free or hide it
- * DOBUF_SPLIT nothing
- * DOBUF_UNLOAD unload it
- * DOBUF_DEL delete it
- * DOBUF_WIPE wipe it out
+ * DOBUF_GOTO free or hide it
+ * DOBUF_SPLIT nothing
+ * DOBUF_UNLOAD unload it
+ * DOBUF_DEL delete it
+ * DOBUF_WIPE wipe it out
*/
void set_curbuf(buf_T *buf, int action)
{
- buf_T *prevbuf;
+ buf_T *prevbuf;
int unload = (action == DOBUF_UNLOAD || action == DOBUF_DEL
|| action == DOBUF_WIPE);
long old_tw = curbuf->b_p_tw;
@@ -1489,7 +1484,7 @@ void set_curbuf(buf_T *buf, int action)
set_bufref(&prevbufref, prevbuf);
set_bufref(&newbufref, buf);
- // Autocommands may delete the curren buffer and/or the buffer we wan to go
+ // Autocommands may delete the curren buffer and/or the buffer we want to go
// to. In those cases don't close the buffer.
if (!apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, false, curbuf)
|| (bufref_valid(&prevbufref) && bufref_valid(&newbufref)
@@ -1501,7 +1496,7 @@ void set_curbuf(buf_T *buf, int action)
close_windows(prevbuf, false);
}
if (bufref_valid(&prevbufref) && !aborting()) {
- win_T *previouswin = curwin;
+ win_T *previouswin = curwin;
if (prevbuf == curbuf) {
u_sync(false);
}
@@ -1523,8 +1518,7 @@ void set_curbuf(buf_T *buf, int action)
* If curwin->w_buffer is null, enter_buffer() will make it valid again */
if ((buf_valid(buf) && buf != curbuf
&& !aborting()
- ) || curwin->w_buffer == NULL
- ) {
+ ) || curwin->w_buffer == NULL) {
enter_buffer(buf);
if (old_tw != curbuf->b_p_tw) {
check_colorcolumn(curwin);
@@ -1670,7 +1664,7 @@ static int top_file_num = 1; ///< highest file number
/// Initialize b:changedtick and changedtick_val attribute
///
-/// @param[out] buf Buffer to intialize for.
+/// @param[out] buf Buffer to initialize for.
static inline void buf_init_changedtick(buf_T *const buf)
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL
{
@@ -1706,12 +1700,11 @@ static inline void buf_init_changedtick(buf_T *const buf)
/// @param bufnr
///
/// @return pointer to the buffer
-buf_T *buflist_new(char_u *ffname_arg, char_u *sfname_arg, linenr_T lnum,
- int flags)
+buf_T *buflist_new(char_u *ffname_arg, char_u *sfname_arg, linenr_T lnum, int flags)
{
char_u *ffname = ffname_arg;
char_u *sfname = sfname_arg;
- buf_T *buf;
+ buf_T *buf;
fname_expand(curbuf, &ffname, &sfname); // will allocate ffname
@@ -1751,7 +1744,7 @@ buf_T *buflist_new(char_u *ffname_arg, char_u *sfname_arg, linenr_T lnum,
/*
* If the current buffer has no name and no contents, use the current
- * buffer. Otherwise: Need to allocate a new buffer structure.
+ * buffer. Otherwise: Need to allocate a new buffer structure.
*
* This is the ONLY place where a new buffer structure is allocated!
* (A spell file buffer is allocated in spell.c, but that's not a normal
@@ -1783,7 +1776,7 @@ buf_T *buflist_new(char_u *ffname_arg, char_u *sfname_arg, linenr_T lnum,
buf = xcalloc(1, sizeof(buf_T));
// init b: variables
buf->b_vars = tv_dict_alloc();
- buf->b_signcols_max = -1;
+ buf->b_signcols_valid = false;
init_var_dict(buf->b_vars, &buf->b_bufvar, VAR_SCOPE);
buf_init_changedtick(buf);
}
@@ -1841,7 +1834,7 @@ buf_T *buflist_new(char_u *ffname_arg, char_u *sfname_arg, linenr_T lnum,
lastbuf = buf;
buf->b_fnum = top_file_num++;
- handle_register_buffer(buf);
+ pmap_put(handle_T)(&buffer_handles, buf->b_fnum, buf);
if (top_file_num < 0) { // wrap around (may cause duplicates)
EMSG(_("W14: Warning: List of file names overflow"));
if (emsg_silent == 0) {
@@ -1918,7 +1911,7 @@ bool curbuf_reusable(void)
return (curbuf != NULL
&& curbuf->b_ffname == NULL
&& curbuf->b_nwindows <= 1
- && (curbuf->b_ml.ml_mfp == NULL || BUFEMPTY())
+ && (curbuf->b_ml.ml_mfp == NULL || buf_is_empty(curbuf))
&& !bt_quickfix(curbuf)
&& !curbufIsChanged());
}
@@ -2006,9 +1999,9 @@ void free_buf_options(buf_T *buf, int free_p_ff)
/// Return FAIL for failure, OK for success.
int buflist_getfile(int n, linenr_T lnum, int options, int forceit)
{
- buf_T *buf;
- win_T *wp = NULL;
- pos_T *fpos;
+ buf_T *buf;
+ win_T *wp = NULL;
+ pos_T *fpos;
colnr_T col;
buf = buflist_findnr(n);
@@ -2039,8 +2032,9 @@ int buflist_getfile(int n, linenr_T lnum, int options, int forceit)
fpos = buflist_findfpos(buf);
lnum = fpos->lnum;
col = fpos->col;
- } else
+ } else {
col = 0;
+ }
if (options & GETF_SWITCH) {
// If 'switchbuf' contains "useopen": jump to first window containing
@@ -2058,7 +2052,7 @@ int buflist_getfile(int n, linenr_T lnum, int options, int forceit)
// If 'switchbuf' contains "split", "vsplit" or "newtab" and the
// current buffer isn't empty: open new tab or window
if (wp == NULL && (swb_flags & (SWB_VSPLIT | SWB_SPLIT | SWB_NEWTAB))
- && !BUFEMPTY()) {
+ && !buf_is_empty(curbuf)) {
if (swb_flags & SWB_NEWTAB) {
tabpage_new();
} else if (win_split(0, (swb_flags & SWB_VSPLIT) ? WSP_VERT : 0)
@@ -2090,7 +2084,7 @@ int buflist_getfile(int n, linenr_T lnum, int options, int forceit)
// Go to the last known line number for the current buffer.
void buflist_getfpos(void)
{
- pos_T *fpos;
+ pos_T *fpos;
fpos = buflist_findfpos(curbuf);
@@ -2113,8 +2107,8 @@ void buflist_getfpos(void)
*/
buf_T *buflist_findname_exp(char_u *fname)
{
- char_u *ffname;
- buf_T *buf = NULL;
+ char_u *ffname;
+ buf_T *buf = NULL;
// First make the name into a full path name
ffname = (char_u *)FullName_save((char *)fname,
@@ -2124,7 +2118,7 @@ buf_T *buflist_findname_exp(char_u *fname)
#else
false
#endif
- );
+ );
if (ffname != NULL) {
buf = buflist_findname(ffname);
xfree(ffname);
@@ -2150,8 +2144,7 @@ buf_T *buflist_findname(char_u *ffname)
* getting it twice for the same file.
* Returns NULL if not found.
*/
-static buf_T *buflist_findname_file_id(char_u *ffname, FileID *file_id,
- bool file_id_valid)
+static buf_T *buflist_findname_file_id(char_u *ffname, FileID *file_id, bool file_id_valid)
{
// Start at the last buffer, expect to find a match sooner.
FOR_ALL_BUFFERS_BACKWARDS(buf) {
@@ -2166,21 +2159,21 @@ static buf_T *buflist_findname_file_id(char_u *ffname, FileID *file_id,
/// Find file in buffer list by a regexp pattern.
/// Return fnum of the found buffer.
/// Return < 0 for error.
-int buflist_findpat(
- const char_u *pattern,
- const char_u *pattern_end, // pointer to first char after pattern
- bool unlisted, // find unlisted buffers
- bool diffmode, // find diff-mode buffers only
- bool curtab_only // find buffers in current tab only
-)
+///
+/// @param pattern_end pointer to first char after pattern
+/// @param unlisted find unlisted buffers
+/// @param diffmode find diff-mode buffers only
+/// @param curtab_only find buffers in current tab only
+int buflist_findpat(const char_u *pattern, const char_u *pattern_end, bool unlisted, bool diffmode,
+ bool curtab_only)
FUNC_ATTR_NONNULL_ARG(1)
{
int match = -1;
int find_listed;
- char_u *pat;
- char_u *patend;
+ char_u *pat;
+ char_u *patend;
int attempt;
- char_u *p;
+ char_u *p;
int toggledollar;
if (pattern_end == pattern + 1 && (*pattern == '%' || *pattern == '#')) {
@@ -2284,13 +2277,12 @@ int buflist_findpat(
}
typedef struct {
- buf_T *buf;
- char_u *match;
+ buf_T *buf;
+ char_u *match;
} bufmatch_T;
/// Compare functions for qsort() below, that compares b_last_used.
-static int
-buf_time_compare(const void *s1, const void *s2)
+static int buf_time_compare(const void *s1, const void *s2)
{
buf_T *buf1 = *(buf_T **)s1;
buf_T *buf2 = *(buf_T **)s2;
@@ -2310,10 +2302,10 @@ int ExpandBufnames(char_u *pat, int *num_file, char_u ***file, int options)
{
int count = 0;
int round;
- char_u *p;
+ char_u *p;
int attempt;
- char_u *patc;
- bufmatch_T *matches = NULL;
+ char_u *patc;
+ bufmatch_T *matches = NULL;
*num_file = 0; // return values in case of FAIL
*file = NULL;
@@ -2327,8 +2319,9 @@ int ExpandBufnames(char_u *pat, int *num_file, char_u ***file, int options)
patc = xmalloc(STRLEN(pat) + 11);
STRCPY(patc, "\\(^\\|[\\/]\\)");
STRCPY(patc + 11, pat + 1);
- } else
+ } else {
patc = pat;
+ }
/*
* attempt == 0: try match with '\<', match at start of word
@@ -2449,8 +2442,8 @@ static char_u *buflist_match(regmatch_T *rmp, buf_T *buf, bool ignore_case)
/// @return "name" when there is a match, NULL when not.
static char_u *fname_match(regmatch_T *rmp, char_u *name, bool ignore_case)
{
- char_u *match = NULL;
- char_u *p;
+ char_u *match = NULL;
+ char_u *p;
if (name != NULL) {
// Ignore case when 'fileignorecase' or the argument is set.
@@ -2480,27 +2473,23 @@ buf_T *buflist_findnr(int nr)
return handle_get_buffer((handle_T)nr);
}
-/*
- * Get name of file 'n' in the buffer list.
- * When the file has no name an empty string is returned.
- * home_replace() is used to shorten the file name (used for marks).
- * Returns a pointer to allocated memory, of NULL when failed.
- */
-char_u *
-buflist_nr2name(
- int n,
- int fullname,
- int helptail // for help buffers return tail only
-)
+/// Get name of file 'n' in the buffer list.
+/// When the file has no name an empty string is returned.
+/// home_replace() is used to shorten the file name (used for marks).
+///
+/// @param helptail for help buffers return tail only
+///
+/// @return a pointer to allocated memory, of NULL when failed.
+char_u *buflist_nr2name(int n, int fullname, int helptail)
{
- buf_T *buf;
+ buf_T *buf;
buf = buflist_findnr(n);
if (buf == NULL) {
return NULL;
}
return home_replace_save(helptail ? buf : NULL,
- fullname ? buf->b_ffname : buf->b_fname);
+ fullname ? buf->b_ffname : buf->b_fname);
}
/// Set the line and column numbers for the given buffer and window
@@ -2512,12 +2501,11 @@ buflist_nr2name(
/// options are touched.
/// @param[in] col Column number to be set.
/// @param[in] copy_options If true save the local window option values.
-void buflist_setfpos(buf_T *const buf, win_T *const win,
- linenr_T lnum, colnr_T col,
+void buflist_setfpos(buf_T *const buf, win_T *const win, linenr_T lnum, colnr_T col,
bool copy_options)
FUNC_ATTR_NONNULL_ARG(1)
{
- wininfo_T *wip;
+ wininfo_T *wip;
for (wip = buf->b_wininfo; wip != NULL; wip = wip->wi_next) {
if (wip->wi_win == win) {
@@ -2594,11 +2582,10 @@ static bool wininfo_other_tab_diff(wininfo_T *wip)
// When "skip_diff_buffer" is true avoid windows with 'diff' set that is in
// another tab page.
// Returns NULL when there isn't any info.
-static wininfo_T *find_wininfo(buf_T *buf, bool need_options,
- bool skip_diff_buffer)
+static wininfo_T *find_wininfo(buf_T *buf, bool need_options, bool skip_diff_buffer)
FUNC_ATTR_NONNULL_ALL
{
- wininfo_T *wip;
+ wininfo_T *wip;
for (wip = buf->b_wininfo; wip != NULL; wip = wip->wi_next) {
if (wip->wi_win == curwin
@@ -2655,8 +2642,9 @@ void get_winopts(buf_T *buf)
curwin->w_fold_manual = wip->wi_fold_manual;
curwin->w_foldinvalid = true;
cloneFoldGrowArray(&wip->wi_folds, &curwin->w_folds);
- } else
+ } else {
copy_winopt(&curwin->w_allbuf_opt, &curwin->w_onebuf_opt);
+ }
if (curwin->w_float_config.style == kWinStyleMinimal) {
didset_window_options(curwin);
@@ -2694,7 +2682,7 @@ linenr_T buflist_findlnum(buf_T *buf)
// List all known file names (for :files and :buffers command).
void buflist_list(exarg_T *eap)
{
- buf_T *buf = firstbuf;
+ buf_T *buf = firstbuf;
int len;
int i;
@@ -2720,7 +2708,7 @@ void buflist_list(exarg_T *eap)
buf != NULL && !got_int;
buf = buflist_data != NULL
? (++p < buflist_data + buflist.ga_len ? *p : NULL)
- : buf->b_next) {
+ : buf->b_next) {
const bool is_terminal = buf->terminal;
const bool job_running = buf->terminal && terminal_running(buf->terminal);
@@ -2762,18 +2750,17 @@ void buflist_list(exarg_T *eap)
}
msg_putchar('\n');
- len = vim_snprintf(
- (char *)IObuff, IOSIZE - 20, "%3d%c%c%c%c%c \"%s\"",
- buf->b_fnum,
- buf->b_p_bl ? ' ' : 'u',
- buf == curbuf ? '%' : (curwin->w_alt_fnum == buf->b_fnum ? '#' : ' '),
- buf->b_ml.ml_mfp == NULL ? ' ' : (buf->b_nwindows == 0 ? 'h' : 'a'),
- ro_char,
- changed_char,
- NameBuff);
+ len = vim_snprintf((char *)IObuff, IOSIZE - 20, "%3d%c%c%c%c%c \"%s\"",
+ buf->b_fnum,
+ buf->b_p_bl ? ' ' : 'u',
+ buf == curbuf ? '%' : (curwin->w_alt_fnum == buf->b_fnum ? '#' : ' '),
+ buf->b_ml.ml_mfp == NULL ? ' ' : (buf->b_nwindows == 0 ? 'h' : 'a'),
+ ro_char,
+ changed_char,
+ NameBuff);
if (len > IOSIZE - 20) {
- len = IOSIZE - 20;
+ len = IOSIZE - 20;
}
// put "line 999" in column 40 or after the file name
@@ -2787,7 +2774,7 @@ void buflist_list(exarg_T *eap)
vim_snprintf((char *)IObuff + len, (size_t)(IOSIZE - len),
_("line %" PRId64),
buf == curbuf ? (int64_t)curwin->w_cursor.lnum
- : (int64_t)buflist_findlnum(buf));
+ : (int64_t)buflist_findlnum(buf));
}
msg_outtrans(IObuff);
@@ -2807,7 +2794,7 @@ void buflist_list(exarg_T *eap)
*/
int buflist_name_nr(int fnum, char_u **fname, linenr_T *lnum)
{
- buf_T *buf;
+ buf_T *buf;
buf = buflist_findnr(fnum);
if (buf == NULL || buf->b_fname == NULL) {
@@ -2820,21 +2807,18 @@ int buflist_name_nr(int fnum, char_u **fname, linenr_T *lnum)
return OK;
}
-// Set the file name for "buf" to "ffname_arg", short file name to
-// "sfname_arg".
-// The file name with the full path is also remembered, for when :cd is used.
-// Returns FAIL for failure (file name already in use by other buffer)
-// OK otherwise.
-int setfname(
- buf_T *buf,
- char_u *ffname_arg,
- char_u *sfname_arg,
- bool message // give message when buffer already exists
-)
+/// Set the file name for "buf" to "ffname_arg", short file name to
+/// "sfname_arg".
+/// The file name with the full path is also remembered, for when :cd is used.
+///
+/// @param message give message when buffer already exists
+///
+/// @return FAIL for failure (file name already in use by other buffer) OK otherwise.
+int setfname(buf_T *buf, char_u *ffname_arg, char_u *sfname_arg, bool message)
{
char_u *ffname = ffname_arg;
char_u *sfname = sfname_arg;
- buf_T *obuf = NULL;
+ buf_T *obuf = NULL;
FileID file_id;
bool file_id_valid = false;
@@ -2901,7 +2885,7 @@ int setfname(
*/
void buf_set_name(int fnum, char_u *name)
{
- buf_T *buf;
+ buf_T *buf;
buf = buflist_findnr(fnum);
if (buf != NULL) {
@@ -2948,7 +2932,7 @@ void buf_name_changed(buf_T *buf)
*/
buf_T *setaltfname(char_u *ffname, char_u *sfname, linenr_T lnum)
{
- buf_T *buf;
+ buf_T *buf;
// Create a buffer. 'buflisted' is not set if it's a new buffer
buf = buflist_new(ffname, sfname, lnum, 0);
@@ -2958,15 +2942,13 @@ buf_T *setaltfname(char_u *ffname, char_u *sfname, linenr_T lnum)
return buf;
}
-/*
- * Get alternate file name for current window.
- * Return NULL if there isn't any, and give error message if requested.
- */
-char_u * getaltfname(
- bool errmsg // give error message
-)
+/// Get alternate file name for current window.
+/// Return NULL if there isn't any, and give error message if requested.
+///
+/// @param errmsg give error message
+char_u *getaltfname(bool errmsg)
{
- char_u *fname;
+ char_u *fname;
linenr_T dummy;
if (buflist_name_nr(0, &fname, &dummy) == FAIL) {
@@ -2986,7 +2968,7 @@ char_u * getaltfname(
*/
int buflist_add(char_u *fname, int flags)
{
- buf_T *buf;
+ buf_T *buf;
buf = buflist_new(fname, NULL, (linenr_T)0, flags);
if (buf != NULL) {
@@ -3039,8 +3021,7 @@ bool otherfile(char_u *ffname)
/// @param ffname full path name to check
/// @param file_id_p information about the file at "ffname".
/// @param file_id_valid whether a valid "file_id_p" was passed in.
-static bool otherfile_buf(buf_T *buf, char_u *ffname, FileID *file_id_p,
- bool file_id_valid)
+static bool otherfile_buf(buf_T *buf, char_u *ffname, FileID *file_id_p, bool file_id_valid)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
// no name is different
@@ -3104,20 +3085,15 @@ static bool buf_same_file_id(buf_T *buf, FileID *file_id)
return buf->file_id_valid && os_fileid_equal(&(buf->file_id), file_id);
}
-/*
- * Print info about the current buffer.
- */
-void
-fileinfo(
- int fullname, // when non-zero print full path
- int shorthelp,
- int dont_truncate
-)
+/// Print info about the current buffer.
+///
+/// @param fullname when non-zero print full path
+void fileinfo(int fullname, int shorthelp, int dont_truncate)
{
- char_u *name;
+ char_u *name;
int n;
- char_u *p;
- char_u *buffer;
+ char_u *p;
+ char_u *buffer;
size_t len;
buffer = xmalloc(IOSIZE);
@@ -3125,8 +3101,9 @@ fileinfo(
if (fullname > 1) { // 2 CTRL-G: include buffer number
vim_snprintf((char *)buffer, IOSIZE, "buf %d: ", curbuf->b_fnum);
p = buffer + STRLEN(buffer);
- } else
+ } else {
p = buffer;
+ }
*p++ = '"';
if (buf_spname(curbuf) != NULL) {
@@ -3141,12 +3118,13 @@ fileinfo(
(size_t)(IOSIZE - (p - buffer)), true);
}
+ bool dontwrite = bt_dontwrite(curbuf);
vim_snprintf_add((char *)buffer, IOSIZE, "\"%s%s%s%s%s%s",
curbufIsChanged()
? (shortmess(SHM_MOD) ? " [+]" : _(" [Modified]")) : " ",
- (curbuf->b_flags & BF_NOTEDITED) && !bt_dontwrite(curbuf)
+ (curbuf->b_flags & BF_NOTEDITED) && !dontwrite
? _("[Not edited]") : "",
- (curbuf->b_flags & BF_NEW) && !bt_dontwrite(curbuf)
+ (curbuf->b_flags & BF_NEW) && !dontwrite
? new_file_message() : "",
(curbuf->b_flags & BF_READERR)
? _("[Read errors]") : "",
@@ -3177,14 +3155,14 @@ fileinfo(
}
} else {
vim_snprintf_add((char *)buffer, IOSIZE,
- _("line %" PRId64 " of %" PRId64 " --%d%%-- col "),
- (int64_t)curwin->w_cursor.lnum,
- (int64_t)curbuf->b_ml.ml_line_count,
- n);
+ _("line %" PRId64 " of %" PRId64 " --%d%%-- col "),
+ (int64_t)curwin->w_cursor.lnum,
+ (int64_t)curbuf->b_ml.ml_line_count,
+ n);
validate_virtcol();
len = STRLEN(buffer);
col_print(buffer + len, IOSIZE - len,
- (int)curwin->w_cursor.col + 1, (int)curwin->w_virtcol + 1);
+ (int)curwin->w_cursor.col + 1, (int)curwin->w_virtcol + 1);
}
(void)append_arg_number(curwin, buffer, IOSIZE, !shortmess(SHM_FILE));
@@ -3286,21 +3264,28 @@ void maketitle(void)
buf_p += MIN(size, SPACE_FOR_FNAME);
} else {
buf_p += transstr_buf((const char *)path_tail(curbuf->b_fname),
- buf_p, SPACE_FOR_FNAME + 1);
+ buf_p, SPACE_FOR_FNAME + 1, true);
}
switch (bufIsChanged(curbuf)
| (curbuf->b_p_ro << 1)
| (!MODIFIABLE(curbuf) << 2)) {
- case 0: break;
- case 1: buf_p = strappend(buf_p, " +"); break;
- case 2: buf_p = strappend(buf_p, " ="); break;
- case 3: buf_p = strappend(buf_p, " =+"); break;
- case 4:
- case 6: buf_p = strappend(buf_p, " -"); break;
- case 5:
- case 7: buf_p = strappend(buf_p, " -+"); break;
- default: abort();
+ case 0:
+ break;
+ case 1:
+ buf_p = strappend(buf_p, " +"); break;
+ case 2:
+ buf_p = strappend(buf_p, " ="); break;
+ case 3:
+ buf_p = strappend(buf_p, " =+"); break;
+ case 4:
+ case 6:
+ buf_p = strappend(buf_p, " -"); break;
+ case 5:
+ case 7:
+ buf_p = strappend(buf_p, " -+"); break;
+ default:
+ abort();
}
if (curbuf->b_fname != NULL) {
@@ -3328,7 +3313,7 @@ void maketitle(void)
// room for the server name. When there is no room (very long
// file name) use (...).
if ((size_t)(buf_p - buf) < SPACE_FOR_DIR) {
- char *const tbuf = transstr(buf_p);
+ char *const tbuf = transstr(buf_p, true);
const size_t free_space = SPACE_FOR_DIR - (size_t)(buf_p - buf) + 1;
const size_t dir_len = xstrlcpy(buf_p, tbuf, free_space);
buf_p += MIN(dir_len, free_space - 1);
@@ -3444,14 +3429,14 @@ void resettitle(void)
ui_flush();
}
-# if defined(EXITFREE)
+#if defined(EXITFREE)
void free_titles(void)
{
xfree(lasttitle);
xfree(lasticon);
}
-# endif
+#endif
/// Enumeration specifying the valid numeric bases that can
/// be used when printing numbers in the status line.
@@ -3486,17 +3471,8 @@ typedef enum {
/// @param tabtab Tab clicks definition (can be NULL).
///
/// @return The final width of the statusline
-int build_stl_str_hl(
- win_T *wp,
- char_u *out,
- size_t outlen,
- char_u *fmt,
- int use_sandbox,
- char_u fillchar,
- int maxwidth,
- stl_hlrec_t **hltab,
- StlClickRecord **tabtab
-)
+int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use_sandbox,
+ char_u fillchar, int maxwidth, stl_hlrec_t **hltab, StlClickRecord **tabtab)
{
static size_t stl_items_len = 20; // Initial value, grows as needed.
static stl_item_t *stl_items = NULL;
@@ -3508,7 +3484,7 @@ int build_stl_str_hl(
#define TMPLEN 70
char_u buf_tmp[TMPLEN];
char_u win_tmp[TMPLEN];
- char_u *usefmt = fmt;
+ char_u *usefmt = fmt;
const int save_must_redraw = must_redraw;
const int save_redr_type = curwin->w_redr_type;
@@ -3587,19 +3563,19 @@ int build_stl_str_hl(
// Proceed character by character through the statusline format string
- // fmt_p is the current positon in the input buffer
+ // fmt_p is the current position in the input buffer
for (char_u *fmt_p = usefmt; *fmt_p; ) {
if (curitem == (int)stl_items_len) {
- size_t new_len = stl_items_len * 3 / 2;
+ size_t new_len = stl_items_len * 3 / 2;
- stl_items = xrealloc(stl_items, sizeof(stl_item_t) * new_len);
- stl_groupitems = xrealloc(stl_groupitems, sizeof(int) * new_len);
- stl_hltab = xrealloc(stl_hltab, sizeof(stl_hlrec_t) * new_len);
- stl_tabtab = xrealloc(stl_tabtab, sizeof(StlClickRecord) * new_len);
- stl_separator_locations =
- xrealloc(stl_separator_locations, sizeof(int) * new_len);
+ stl_items = xrealloc(stl_items, sizeof(stl_item_t) * new_len);
+ stl_groupitems = xrealloc(stl_groupitems, sizeof(int) * new_len);
+ stl_hltab = xrealloc(stl_hltab, sizeof(stl_hlrec_t) * new_len);
+ stl_tabtab = xrealloc(stl_tabtab, sizeof(StlClickRecord) * new_len);
+ stl_separator_locations =
+ xrealloc(stl_separator_locations, sizeof(int) * new_len);
- stl_items_len = new_len;
+ stl_items_len = new_len;
}
if (*fmt_p != NUL && *fmt_p != '%') {
@@ -3609,8 +3585,9 @@ int build_stl_str_hl(
// Copy the formatting verbatim until we reach the end of the string
// or find a formatting item (denoted by `%`)
// or run out of room in our output buffer.
- while (*fmt_p != NUL && *fmt_p != '%' && out_p < out_end_p)
+ while (*fmt_p != NUL && *fmt_p != '%' && out_p < out_end_p) {
*out_p++ = *fmt_p++;
+ }
// If we have processed the entire format string or run out of
// room in our output buffer, exit the loop.
@@ -3753,17 +3730,18 @@ int build_stl_str_hl(
stl_items[idx].start = t;
}
}
- // If the group is shorter than the minimum width, add padding characters.
+ // If the group is shorter than the minimum width, add padding characters.
} else if (
- abs(stl_items[stl_groupitems[groupdepth]].minwid) > group_len) {
+ abs(stl_items[stl_groupitems[groupdepth]].minwid) > group_len) {
long min_group_width = stl_items[stl_groupitems[groupdepth]].minwid;
// If the group is left-aligned, add characters to the right.
if (min_group_width < 0) {
min_group_width = 0 - min_group_width;
- while (group_len++ < min_group_width && out_p < out_end_p)
+ while (group_len++ < min_group_width && out_p < out_end_p) {
*out_p++ = fillchar;
- // If the group is right-aligned, shift everything to the right and
- // prepend with filler characters.
+ }
+ // If the group is right-aligned, shift everything to the right and
+ // prepend with filler characters.
} else {
// { Move the group to the right
memmove(t + min_group_width - group_len, t, (size_t)(out_p - t));
@@ -3868,7 +3846,7 @@ int build_stl_str_hl(
if (*fmt_p == STL_CLICK_FUNC) {
fmt_p++;
- char *t = (char *) fmt_p;
+ char *t = (char *)fmt_p;
while (*fmt_p != STL_CLICK_FUNC && *fmt_p) {
fmt_p++;
}
@@ -3911,9 +3889,9 @@ int build_stl_str_hl(
// Denotes end of expanded %{} block
if (*fmt_p == '}' && evaldepth > 0) {
- fmt_p++;
- evaldepth--;
- continue;
+ fmt_p++;
+ evaldepth--;
+ continue;
}
// An invalid item was specified.
@@ -3936,7 +3914,6 @@ int build_stl_str_hl(
case STL_FILEPATH:
case STL_FULLPATH:
case STL_FILENAME:
- {
// Set fillable to false so that ' ' in the filename will not
// get replaced with the fillchar
fillable = false;
@@ -3944,7 +3921,7 @@ int build_stl_str_hl(
STRLCPY(NameBuff, buf_spname(wp->w_buffer), MAXPATHL);
} else {
char_u *t = (opt == STL_FULLPATH) ? wp->w_buffer->b_ffname
- : wp->w_buffer->b_fname;
+ : wp->w_buffer->b_fname;
home_replace(wp->w_buffer, t, NameBuff, MAXPATHL, true);
}
trans_characters(NameBuff, MAXPATHL);
@@ -3954,7 +3931,6 @@ int build_stl_str_hl(
str = path_tail(NameBuff);
}
break;
- }
case STL_VIM_EXPR: // '{'
{
char_u *block_start = fmt_p - 1;
@@ -4037,17 +4013,17 @@ int build_stl_str_hl(
size_t str_length = strlen((const char *)str);
size_t fmt_length = strlen((const char *)fmt_p);
size_t new_fmt_len = parsed_usefmt
- + str_length + fmt_length + 3;
+ + str_length + fmt_length + 3;
char_u *new_fmt = (char_u *)xmalloc(new_fmt_len * sizeof(char_u));
char_u *new_fmt_p = new_fmt;
new_fmt_p = (char_u *)memcpy(new_fmt_p, usefmt, parsed_usefmt)
- + parsed_usefmt;
- new_fmt_p = (char_u *)memcpy(new_fmt_p , str, str_length)
- + str_length;
+ + parsed_usefmt;
+ new_fmt_p = (char_u *)memcpy(new_fmt_p, str, str_length)
+ + str_length;
new_fmt_p = (char_u *)memcpy(new_fmt_p, "%}", 2) + 2;
- new_fmt_p = (char_u *)memcpy(new_fmt_p , fmt_p, fmt_length)
- + fmt_length;
+ new_fmt_p = (char_u *)memcpy(new_fmt_p, fmt_p, fmt_length)
+ + fmt_length;
*new_fmt_p = 0;
new_fmt_p = NULL;
@@ -4078,8 +4054,7 @@ int build_stl_str_hl(
break;
case STL_VIRTCOL:
- case STL_VIRTCOL_ALT:
- {
+ case STL_VIRTCOL_ALT: {
// In list mode virtcol needs to be recomputed
colnr_T virtcol = wp->w_virtcol;
if (wp->w_p_list && wp->w_p_lcs_chars.tab1 == NUL) {
@@ -4091,8 +4066,9 @@ int build_stl_str_hl(
// Don't display %V if it's the same as %c.
if (opt == STL_VIRTCOL_ALT
&& (virtcol == (colnr_T)(!(State & INSERT) && empty_line
- ? 0 : (int)wp->w_cursor.col + 1)))
+ ? 0 : (int)wp->w_cursor.col + 1))) {
break;
+ }
num = (long)virtcol;
break;
}
@@ -4143,8 +4119,7 @@ int build_stl_str_hl(
case STL_OFFSET_X:
base = kNumBaseHexadecimal;
FALLTHROUGH;
- case STL_OFFSET:
- {
+ case STL_OFFSET: {
long l = ml_find_line_or_offset(wp->w_buffer, wp->w_cursor.lnum, NULL,
false);
num = (wp->w_buffer->b_ml.ml_flags & ML_EMPTY) || l < 0 ?
@@ -4175,9 +4150,10 @@ int build_stl_str_hl(
case STL_HELPFLAG:
case STL_HELPFLAG_ALT:
itemisflag = true;
- if (wp->w_buffer->b_help)
+ if (wp->w_buffer->b_help) {
str = (char_u *)((opt == STL_HELPFLAG_ALT) ? ",HLP"
- : _("[Help]"));
+ : _("[Help]"));
+ }
break;
case STL_FILETYPE:
@@ -4193,7 +4169,6 @@ int build_stl_str_hl(
break;
case STL_FILETYPE_ALT:
- {
itemisflag = true;
// Copy the filetype if it is not null and the formatted string will fit
// in the temporary buffer
@@ -4209,20 +4184,21 @@ int build_stl_str_hl(
str = buf_tmp;
}
break;
- }
case STL_PREVIEWFLAG:
case STL_PREVIEWFLAG_ALT:
itemisflag = true;
- if (wp->w_p_pvw)
+ if (wp->w_p_pvw) {
str = (char_u *)((opt == STL_PREVIEWFLAG_ALT) ? ",PRV"
- : _("[Preview]"));
+ : _("[Preview]"));
+ }
break;
case STL_QUICKFIX:
- if (bt_quickfix(wp->w_buffer))
+ if (bt_quickfix(wp->w_buffer)) {
str = (char_u *)(wp->w_llist_ref
? _(msg_loclist)
: _(msg_qflist));
+ }
break;
case STL_MODIFIED:
@@ -4231,17 +4207,22 @@ int build_stl_str_hl(
switch ((opt == STL_MODIFIED_ALT)
+ bufIsChanged(wp->w_buffer) * 2
+ (!MODIFIABLE(wp->w_buffer)) * 4) {
- case 2: str = (char_u *)"[+]"; break;
- case 3: str = (char_u *)",+"; break;
- case 4: str = (char_u *)"[-]"; break;
- case 5: str = (char_u *)",-"; break;
- case 6: str = (char_u *)"[+-]"; break;
- case 7: str = (char_u *)",+-"; break;
+ case 2:
+ str = (char_u *)"[+]"; break;
+ case 3:
+ str = (char_u *)",+"; break;
+ case 4:
+ str = (char_u *)"[-]"; break;
+ case 5:
+ str = (char_u *)",-"; break;
+ case 6:
+ str = (char_u *)"[+-]"; break;
+ case 7:
+ str = (char_u *)",+-"; break;
}
break;
- case STL_HIGHLIGHT:
- {
+ case STL_HIGHLIGHT: {
// { The name of the highlight is surrounded by `#`
char_u *t = fmt_p;
while (*fmt_p != '#' && *fmt_p != NUL) {
@@ -4253,7 +4234,7 @@ int build_stl_str_hl(
if (*fmt_p == '#') {
stl_items[curitem].type = Highlight;
stl_items[curitem].start = out_p;
- stl_items[curitem].minwid = -syn_namen2id(t, (int)(fmt_p - t));
+ stl_items[curitem].minwid = -syn_name2id_len(t, (size_t)(fmt_p - t));
curitem++;
fmt_p++;
}
@@ -4275,8 +4256,9 @@ int build_stl_str_hl(
if (itemisflag) {
if ((t[0] && t[1])
&& ((!prevchar_isitem && *t == ',')
- || (prevchar_isflag && *t == ' ')))
+ || (prevchar_isflag && *t == ' '))) {
t++;
+ }
prevchar_isflag = true;
}
// }
@@ -4329,8 +4311,9 @@ int build_stl_str_hl(
// Change a space by fillchar, unless fillchar is '-' and a
// digit follows.
if (fillable && out_p[-1] == ' '
- && (!ascii_isdigit(*t) || fillchar != '-'))
+ && (!ascii_isdigit(*t) || fillchar != '-')) {
out_p[-1] = fillchar;
+ }
}
// }
@@ -4339,7 +4322,7 @@ int build_stl_str_hl(
*out_p++ = fillchar;
}
- // Otherwise if the item is a number, copy that to the output buffer.
+ // Otherwise if the item is a number, copy that to the output buffer.
} else if (num >= 0) {
if (out_p + 20 > out_end_p) {
break; // not sufficient space
@@ -4368,7 +4351,7 @@ int build_stl_str_hl(
// Note: We have to cast the base because the compiler uses
// unsigned ints for the enum values.
long num_chars = 1;
- for (long n = num; n >= (int) base; n /= (int) base) {
+ for (long n = num; n >= (int)base; n /= (int)base) {
num_chars++;
}
@@ -4408,17 +4391,17 @@ int build_stl_str_hl(
// }
vim_snprintf((char *)out_p, remaining_buf_len, (char *)nstr,
- 0, num, n);
+ 0, num, n);
} else {
vim_snprintf((char *)out_p, remaining_buf_len, (char *)nstr,
- minwid, num);
+ minwid, num);
}
// Advance the output buffer position to the end of the
// number we just printed
out_p += STRLEN(out_p);
- // Otherwise, there was nothing to print so mark the item as empty
+ // Otherwise, there was nothing to print so mark the item as empty
} else {
stl_items[curitem].type = Empty;
}
@@ -4458,7 +4441,7 @@ int build_stl_str_hl(
if (itemcnt == 0) {
trunc_p = out;
- // Otherwise, look for the truncation item
+ // Otherwise, look for the truncation item
} else {
// Default to truncating at the first item
trunc_p = stl_items[0].start;
@@ -4505,7 +4488,7 @@ int build_stl_str_hl(
*trunc_p++ = '>';
*trunc_p = 0;
- // Truncate at the truncation point we found
+ // Truncate at the truncation point we found
} else {
// { Determine how many bytes to remove
long trunc_len = 0;
@@ -4546,8 +4529,8 @@ int build_stl_str_hl(
// to be moved backwards.
if (stl_items[i].start >= trunc_end_p) {
stl_items[i].start -= item_offset;
- // Anything inside the truncated area is set to start
- // at the `<` truncation character.
+ // Anything inside the truncated area is set to start
+ // at the `<` truncation character.
} else {
stl_items[i].start = trunc_p;
}
@@ -4556,9 +4539,9 @@ int build_stl_str_hl(
}
width = maxwidth;
- // If there is room left in our statusline, and room left in our buffer,
- // add characters at the separate marker (if there is one) to
- // fill up the available space.
+ // If there is room left in our statusline, and room left in our buffer,
+ // add characters at the separate marker (if there is one) to
+ // fill up the available space.
} else if (width < maxwidth
&& STRLEN(out) + (size_t)(maxwidth - width) + 1 < outlen) {
// Find how many separators there are, which we will use when
@@ -4577,7 +4560,7 @@ int build_stl_str_hl(
if (num_separators) {
int standard_spaces = (maxwidth - width) / num_separators;
int final_spaces = (maxwidth - width) -
- standard_spaces * (num_separators - 1);
+ standard_spaces * (num_separators - 1);
for (int i = 0; i < num_separators; i++) {
int dislocation = (i == (num_separators - 1))
@@ -4676,7 +4659,7 @@ void get_rel_pos(win_T *wp, char_u *buf, int buflen)
long below; // number of lines below window
above = wp->w_topline - 1;
- above += diff_check_fill(wp, wp->w_topline) - wp->w_topfill;
+ above += win_get_fill(wp, wp->w_topline) - wp->w_topfill;
if (wp->w_topline == 1 && wp->w_topfill >= 1) {
// All buffer lines are displayed and there is an indication
// of filler lines, that can be considered seeing all lines.
@@ -4735,7 +4718,7 @@ static bool append_arg_number(win_T *wp, char_u *buf, int buflen, bool add_file)
// When resolving a link both "*sfname" and "*ffname" will point to the same
// allocated memory.
// The "*ffname" and "*sfname" pointer values on call will not be freed.
-// Note that the resulting "*ffname" pointer should be considered not allocaed.
+// Note that the resulting "*ffname" pointer should be considered not allocated.
void fname_expand(buf_T *buf, char_u **ffname, char_u **sfname)
{
if (*ffname == NULL) { // no file name given, nothing to do
@@ -4764,7 +4747,7 @@ void fname_expand(buf_T *buf, char_u **ffname, char_u **sfname)
*/
char_u *alist_name(aentry_T *aep)
{
- buf_T *bp;
+ buf_T *bp;
// Use the name from the associated buffer if it exists.
bp = buflist_findnr(aep->ae_fnum);
@@ -4774,35 +4757,31 @@ char_u *alist_name(aentry_T *aep)
return bp->b_fname;
}
-/*
- * do_arg_all(): Open up to 'count' windows, one for each argument.
- */
-void
-do_arg_all(
- int count,
- int forceit, // hide buffers in current windows
- int keep_tabs // keep current tabs, for ":tab drop file"
-)
+/// do_arg_all(): Open up to 'count' windows, one for each argument.
+///
+/// @param forceit hide buffers in current windows
+/// @param keep_tabs keep current tabs, for ":tab drop file"
+void do_arg_all(int count, int forceit, int keep_tabs)
{
- char_u *opened; // Array of weight for which args are open:
- // 0: not opened
- // 1: opened in other tab
- // 2: opened in curtab
- // 3: opened in curtab and curwin
+ char_u *opened; // Array of weight for which args are open:
+ // 0: not opened
+ // 1: opened in other tab
+ // 2: opened in curtab
+ // 3: opened in curtab and curwin
int opened_len; // length of opened[]
int use_firstwin = false; // use first window for arglist
bool tab_drop_empty_window = false;
int split_ret = OK;
bool p_ea_save;
- alist_T *alist; // argument list to be used
- buf_T *buf;
- tabpage_T *tpnext;
+ alist_T *alist; // argument list to be used
+ buf_T *buf;
+ tabpage_T *tpnext;
int had_tab = cmdmod.tab;
- win_T *old_curwin, *last_curwin;
- tabpage_T *old_curtab, *last_curtab;
- win_T *new_curwin = NULL;
- tabpage_T *new_curtab = NULL;
+ win_T *old_curwin, *last_curwin;
+ tabpage_T *old_curtab, *last_curtab;
+ win_T *new_curwin = NULL;
+ tabpage_T *new_curtab = NULL;
assert(firstwin != NULL); // satisfy coverity
@@ -4948,7 +4927,7 @@ do_arg_all(
win_enter(lastwin, false);
// ":tab drop file" should re-use an empty window to avoid "--remote-tab"
// leaving an empty tab page when executed locally.
- if (keep_tabs && BUFEMPTY() && curbuf->b_nwindows == 1
+ if (keep_tabs && buf_is_empty(curbuf) && curbuf->b_nwindows == 1
&& curbuf->b_ffname == NULL && !curbuf->b_changed) {
use_firstwin = true;
tab_drop_empty_window = true;
@@ -5044,10 +5023,10 @@ do_arg_all(
xfree(opened);
}
-// Return TRUE if "buf" is a prompt buffer.
-int bt_prompt(buf_T *buf)
+/// @return true if "buf" is a prompt buffer.
+bool bt_prompt(buf_T *buf)
{
- return buf != NULL && buf->b_p_bt[0] == 'p';
+ return buf != NULL && buf->b_p_bt[0] == 'p';
}
/*
@@ -5055,8 +5034,8 @@ int bt_prompt(buf_T *buf)
*/
void ex_buffer_all(exarg_T *eap)
{
- buf_T *buf;
- win_T *wp, *wpnext;
+ buf_T *buf;
+ win_T *wp, *wpnext;
int split_ret = OK;
bool p_ea_save;
int open_wins = 0;
@@ -5064,7 +5043,7 @@ void ex_buffer_all(exarg_T *eap)
long count; // Maximum number of windows to open.
int all; // When true also load inactive buffers.
int had_tab = cmdmod.tab;
- tabpage_T *tpnext;
+ tabpage_T *tpnext;
if (eap->addr_count == 0) { // make as many windows as possible
count = 9999;
@@ -5098,8 +5077,8 @@ void ex_buffer_all(exarg_T *eap)
: wp->w_width != Columns)
|| (had_tab > 0 && wp != firstwin))
&& !ONE_WINDOW
- && !(wp->w_closing || wp->w_buffer->b_locked > 0)
- ) {
+ && !(wp->w_closing ||
+ wp->w_buffer->b_locked > 0)) {
win_close(wp, false);
wpnext = firstwin; // just in case an autocommand does
// something strange with windows
@@ -5190,8 +5169,9 @@ void ex_buffer_all(exarg_T *eap)
* discarded by a new aborting error, interrupt, or uncaught
* exception. */
leave_cleanup(&cs);
- } else
+ } else {
handle_swap_exists(NULL);
+ }
}
os_breakcheck();
@@ -5240,8 +5220,8 @@ void ex_buffer_all(exarg_T *eap)
* do_modelines() - process mode lines for the current file
*
* "flags" can be:
- * OPT_WINONLY only set options local to window
- * OPT_NOWIN don't set options local to window
+ * OPT_WINONLY only set options local to window
+ * OPT_NOWIN don't set options local to window
*
* Returns immediately if the "ml" option isn't set.
*/
@@ -5262,15 +5242,16 @@ void do_modelines(int flags)
}
entered++;
- for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count && lnum <= nmlines;
- lnum++) {
+ for (lnum = 1; curbuf->b_p_ml && lnum <= curbuf->b_ml.ml_line_count
+ && lnum <= nmlines; lnum++) {
if (chk_modeline(lnum, flags) == FAIL) {
nmlines = 0;
}
}
- for (lnum = curbuf->b_ml.ml_line_count; lnum > 0 && lnum > nmlines
- && lnum > curbuf->b_ml.ml_line_count - nmlines; lnum--) {
+ for (lnum = curbuf->b_ml.ml_line_count; curbuf->b_p_ml && lnum > 0
+ && lnum > nmlines && lnum > curbuf->b_ml.ml_line_count - nmlines;
+ lnum--) {
if (chk_modeline(lnum, flags) == FAIL) {
nmlines = 0;
}
@@ -5278,32 +5259,29 @@ void do_modelines(int flags)
entered--;
}
-/*
- * chk_modeline() - check a single line for a mode string
- * Return FAIL if an error encountered.
- */
-static int
-chk_modeline(
- linenr_T lnum,
- int flags // Same as for do_modelines().
-)
+/// chk_modeline() - check a single line for a mode string
+/// Return FAIL if an error encountered.
+///
+/// @param flags Same as for do_modelines().
+static int chk_modeline(linenr_T lnum, int flags)
{
- char_u *s;
- char_u *e;
- char_u *linecopy; // local copy of any modeline found
+ char_u *s;
+ char_u *e;
+ char_u *linecopy; // local copy of any modeline found
int prev;
intmax_t vers;
int end;
int retval = OK;
- char_u *save_sourcing_name;
+ char_u *save_sourcing_name;
linenr_T save_sourcing_lnum;
prev = -1;
for (s = ml_get(lnum); *s != NUL; s++) {
if (prev == -1 || ascii_isspace(prev)) {
if ((prev != -1 && STRNCMP(s, "ex:", (size_t)3) == 0)
- || STRNCMP(s, "vi:", (size_t)3) == 0)
+ || STRNCMP(s, "vi:", (size_t)3) == 0) {
break;
+ }
// Accept both "vim" and "Vim".
if ((s[0] == 'v' || s[0] == 'V') && s[1] == 'i' && s[2] == 'm') {
if (s[3] == '<' || s[3] == '=' || s[3] == '>') {
@@ -5477,8 +5455,10 @@ bool buf_hide(const buf_T *const buf)
switch (buf->b_p_bh[0]) {
case 'u': // "unload"
case 'w': // "wipe"
- case 'd': return false; // "delete"
- case 'h': return true; // "hide"
+ case 'd':
+ return false; // "delete"
+ case 'h':
+ return true; // "hide"
}
return p_hid || cmdmod.hide;
}
@@ -5544,36 +5524,38 @@ bool find_win_for_buf(buf_T *buf, win_T **wp, tabpage_T **tp)
int buf_signcols(buf_T *buf)
{
- if (buf->b_signcols_max == -1) {
- sign_entry_T *sign; // a sign in the sign list
- buf->b_signcols_max = 0;
- int linesum = 0;
- linenr_T curline = 0;
-
- FOR_ALL_SIGNS_IN_BUF(buf, sign) {
- if (sign->se_lnum > curline) {
- if (linesum > buf->b_signcols_max) {
- buf->b_signcols_max = linesum;
- }
- curline = sign->se_lnum;
- linesum = 0;
- }
- if (sign->se_has_text_or_icon) {
- linesum++;
- }
- }
- if (linesum > buf->b_signcols_max) {
- buf->b_signcols_max = linesum;
+ if (!buf->b_signcols_valid) {
+ sign_entry_T *sign; // a sign in the sign list
+ int signcols = 0;
+ int linesum = 0;
+ linenr_T curline = 0;
+
+ FOR_ALL_SIGNS_IN_BUF(buf, sign) {
+ if (sign->se_lnum > curline) {
+ if (linesum > signcols) {
+ signcols = linesum;
}
+ curline = sign->se_lnum;
+ linesum = 0;
+ }
+ if (sign->se_has_text_or_icon) {
+ linesum++;
+ }
+ }
+ if (linesum > signcols) {
+ signcols = linesum;
+ }
- // Check if we need to redraw
- if (buf->b_signcols_max != buf->b_signcols) {
- buf->b_signcols = buf->b_signcols_max;
- redraw_buf_later(buf, NOT_VALID);
- }
+ // Check if we need to redraw
+ if (signcols != buf->b_signcols) {
+ buf->b_signcols = signcols;
+ redraw_buf_later(buf, NOT_VALID);
}
- return buf->b_signcols;
+ buf->b_signcols_valid = true;
+ }
+
+ return buf->b_signcols;
}
// Get "buf->b_fname", use "[No Name]" if it is NULL.
@@ -5653,16 +5635,12 @@ bool buf_contents_changed(buf_T *buf)
return differ;
}
-/*
- * Wipe out a buffer and decrement the last buffer number if it was used for
- * this buffer. Call this to wipe out a temp buffer that does not contain any
- * marks.
- */
-void
-wipe_buffer(
- buf_T *buf,
- bool aucmd // When true trigger autocommands.
-)
+/// Wipe out a buffer and decrement the last buffer number if it was used for
+/// this buffer. Call this to wipe out a temp buffer that does not contain any
+/// marks.
+///
+/// @param aucmd When true trigger autocommands.
+void wipe_buffer(buf_T *buf, bool aucmd)
{
if (!aucmd) {
// Don't trigger BufDelete autocommands here.
@@ -5691,3 +5669,4 @@ void buf_open_scratch(handle_T bufnr, char *bufname)
set_option_value("swf", 0L, NULL, OPT_LOCAL);
RESET_BINDING(curwin);
}
+
diff --git a/src/nvim/buffer.h b/src/nvim/buffer.h
index ac7ead5f92..02a2ac36f7 100644
--- a/src/nvim/buffer.h
+++ b/src/nvim/buffer.h
@@ -9,6 +9,7 @@
#include "nvim/func_attr.h"
#include "nvim/eval.h"
#include "nvim/macros.h"
+#include "nvim/memline.h"
// Values for buflist_getfile()
enum getf_values {
@@ -128,4 +129,10 @@ static inline void buf_inc_changedtick(buf_T *const buf)
buf_set_changedtick(buf, buf_get_changedtick(buf) + 1);
}
+static inline bool buf_is_empty(buf_T *buf)
+{
+ return buf->b_ml.ml_line_count == 1
+ && *ml_get_buf(buf, (linenr_T)1, false) == '\0';
+}
+
#endif // NVIM_BUFFER_H
diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h
index e3e538bd12..0264a60117 100644
--- a/src/nvim/buffer_defs.h
+++ b/src/nvim/buffer_defs.h
@@ -226,8 +226,12 @@ typedef struct {
# define w_p_cuc w_onebuf_opt.wo_cuc // 'cursorcolumn'
int wo_cul;
# define w_p_cul w_onebuf_opt.wo_cul // 'cursorline'
+ char_u *wo_culopt;
+# define w_p_culopt w_onebuf_opt.wo_culopt // 'cursorlineopt'
char_u *wo_cc;
# define w_p_cc w_onebuf_opt.wo_cc // 'colorcolumn'
+ char_u *wo_sbr;
+# define w_p_sbr w_onebuf_opt.wo_sbr // 'showbreak'
char_u *wo_stl;
#define w_p_stl w_onebuf_opt.wo_stl // 'statusline'
int wo_scb;
@@ -525,6 +529,8 @@ struct file_buffer {
int b_flags; // various BF_ flags
int b_locked; // Buffer is being closed or referenced, don't
// let autocommands wipe it out.
+ int b_ro_locked; // Non-zero when the buffer can't be changed.
+ // Used for FileChangedRO
//
// b_ffname has the full path of the file (NULL for no name).
@@ -849,8 +855,8 @@ struct file_buffer {
// may use a different synblock_T.
sign_entry_T *b_signlist; // list of placed signs
- int b_signcols_max; // cached maximum number of sign columns
int b_signcols; // last calculated number of sign columns
+ bool b_signcols_valid; // calculated sign columns is valid
Terminal *terminal; // Terminal instance associated with the buffer
@@ -859,8 +865,14 @@ struct file_buffer {
int b_mapped_ctrl_c; // modes where CTRL-C is mapped
MarkTree b_marktree[1];
- Map(uint64_t, ExtmarkItem) *b_extmark_index;
- Map(uint64_t, ExtmarkNs) *b_extmark_ns; // extmark namespaces
+ Map(uint64_t, ExtmarkItem) b_extmark_index[1];
+ Map(uint64_t, ExtmarkNs) b_extmark_ns[1]; // extmark namespaces
+
+ VirtLines b_virt_lines;
+ uint64_t b_virt_line_mark;
+ int b_virt_line_pos;
+ bool b_virt_line_above;
+ bool b_virt_line_leftcol;
// array of channel_id:s which have asked to receive updates for this
// buffer.
@@ -1208,6 +1220,7 @@ struct window_S {
int tab3; ///< third tab character
int lead;
int trail;
+ int *multispace;
int conceal;
} w_p_lcs_chars;
@@ -1294,7 +1307,7 @@ struct window_S {
/*
* w_cline_height is the number of physical lines taken by the buffer line
- * that the cursor is on. We use this to avoid extra calls to plines().
+ * that the cursor is on. We use this to avoid extra calls to plines_win().
*/
int w_cline_height; // current size of cursor line
bool w_cline_folded; // cursor line is folded
@@ -1384,12 +1397,14 @@ struct window_S {
uint32_t w_p_fde_flags; // flags for 'foldexpr'
uint32_t w_p_fdt_flags; // flags for 'foldtext'
int *w_p_cc_cols; // array of columns to highlight or NULL
+ char_u w_p_culopt_flags; // flags for cursorline highlighting
long w_p_siso; // 'sidescrolloff' local value
long w_p_so; // 'scrolloff' local value
int w_briopt_min; // minimum width for breakindent
int w_briopt_shift; // additional shift for breakindent
bool w_briopt_sbr; // sbr in 'briopt'
+ int w_briopt_list; // additional indent for lists
// transform a pointer to a "onebuf" option into a "allbuf" option
#define GLOBAL_WO(p) ((char *)p + sizeof(winopt_T))
diff --git a/src/nvim/buffer_updates.c b/src/nvim/buffer_updates.c
index 5c573530d1..ee1b7ebc95 100644
--- a/src/nvim/buffer_updates.c
+++ b/src/nvim/buffer_updates.c
@@ -1,14 +1,14 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+#include "nvim/api/private/helpers.h"
+#include "nvim/assert.h"
+#include "nvim/buffer.h"
#include "nvim/buffer_updates.h"
#include "nvim/extmark.h"
+#include "nvim/lua/executor.h"
#include "nvim/memline.h"
-#include "nvim/api/private/helpers.h"
#include "nvim/msgpack_rpc/channel.h"
-#include "nvim/lua/executor.h"
-#include "nvim/assert.h"
-#include "nvim/buffer.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "buffer_updates.c.generated.h"
@@ -17,8 +17,7 @@
// Register a channel. Return True if the channel was added, or already added.
// Return False if the channel couldn't be added because the buffer is
// unloaded.
-bool buf_updates_register(buf_T *buf, uint64_t channel_id,
- BufUpdateCallbacks cb, bool send_buffer)
+bool buf_updates_register(buf_T *buf, uint64_t channel_id, BufUpdateCallbacks cb, bool send_buffer)
{
// must fail if the buffer isn't loaded
if (buf->b_ml.ml_mfp == NULL) {
@@ -50,7 +49,7 @@ bool buf_updates_register(buf_T *buf, uint64_t channel_id,
if (send_buffer) {
Array args = ARRAY_DICT_INIT;
args.size = 6;
- args.items = xcalloc(sizeof(Object), args.size);
+ args.items = xcalloc(args.size, sizeof(Object));
// the first argument is always the buffer handle
args.items[0] = BUFFER_OBJ(buf->handle);
@@ -68,7 +67,7 @@ bool buf_updates_register(buf_T *buf, uint64_t channel_id,
if (line_count >= 1) {
linedata.size = line_count;
- linedata.items = xcalloc(sizeof(Object), line_count);
+ linedata.items = xcalloc(line_count, sizeof(Object));
buf_collect_lines(buf, line_count, 1, true, &linedata, NULL);
}
@@ -86,16 +85,16 @@ bool buf_updates_register(buf_T *buf, uint64_t channel_id,
bool buf_updates_active(buf_T *buf)
{
- return kv_size(buf->update_channels) || kv_size(buf->update_callbacks);
+ return kv_size(buf->update_channels) || kv_size(buf->update_callbacks);
}
void buf_updates_send_end(buf_T *buf, uint64_t channelid)
{
- Array args = ARRAY_DICT_INIT;
- args.size = 1;
- args.items = xcalloc(sizeof(Object), args.size);
- args.items[0] = BUFFER_OBJ(buf->handle);
- rpc_send_event(channelid, "nvim_buf_detach_event", args);
+ Array args = ARRAY_DICT_INIT;
+ args.size = 1;
+ args.items = xcalloc(args.size, sizeof(Object));
+ args.items[0] = BUFFER_OBJ(buf->handle);
+ rpc_send_event(channelid, "nvim_buf_detach_event", args);
}
void buf_updates_unregister(buf_T *buf, uint64_t channelid)
@@ -187,11 +186,8 @@ void buf_updates_unload(buf_T *buf, bool can_reload)
}
-void buf_updates_send_changes(buf_T *buf,
- linenr_T firstline,
- int64_t num_added,
- int64_t num_removed,
- bool send_tick)
+void buf_updates_send_changes(buf_T *buf, linenr_T firstline, int64_t num_added,
+ int64_t num_removed, bool send_tick)
{
size_t deleted_codepoints, deleted_codeunits;
size_t deleted_bytes = ml_flush_deleted_bytes(buf, &deleted_codepoints,
@@ -211,7 +207,7 @@ void buf_updates_send_changes(buf_T *buf,
// send through the changes now channel contents now
Array args = ARRAY_DICT_INIT;
args.size = 6;
- args.items = xcalloc(sizeof(Object), args.size);
+ args.items = xcalloc(args.size, sizeof(Object));
// the first argument is always the buffer handle
args.items[0] = BUFFER_OBJ(buf->handle);
@@ -228,11 +224,11 @@ void buf_updates_send_changes(buf_T *buf,
// linedata of lines being swapped in
Array linedata = ARRAY_DICT_INIT;
if (num_added > 0) {
- STATIC_ASSERT(SIZE_MAX >= MAXLNUM, "size_t smaller than MAXLNUM");
- linedata.size = (size_t)num_added;
- linedata.items = xcalloc(sizeof(Object), (size_t)num_added);
- buf_collect_lines(buf, (size_t)num_added, firstline, true, &linedata,
- NULL);
+ STATIC_ASSERT(SIZE_MAX >= MAXLNUM, "size_t smaller than MAXLNUM");
+ linedata.size = (size_t)num_added;
+ linedata.items = xcalloc((size_t)num_added, sizeof(Object));
+ buf_collect_lines(buf, (size_t)num_added, firstline, true, &linedata,
+ NULL);
}
args.items[4] = ARRAY_OBJ(linedata);
args.items[5] = BOOLEAN_OBJ(false);
@@ -248,7 +244,7 @@ void buf_updates_send_changes(buf_T *buf,
// change notifications are so frequent that many dead channels will be
// cleared up quickly.
if (badchannelid != 0) {
- ELOG("Disabling buffer updates for dead channel %"PRIu64, badchannelid);
+ ELOG("Disabling buffer updates for dead channel %" PRIu64, badchannelid);
buf_updates_unregister(buf, badchannelid);
}
@@ -302,18 +298,16 @@ void buf_updates_send_changes(buf_T *buf,
kv_size(buf->update_callbacks) = j;
}
-void buf_updates_send_splice(
- buf_T *buf,
- int start_row, colnr_T start_col, bcount_t start_byte,
- int old_row, colnr_T old_col, bcount_t old_byte,
- int new_row, colnr_T new_col, bcount_t new_byte)
+void buf_updates_send_splice(buf_T *buf, int start_row, colnr_T start_col, bcount_t start_byte,
+ int old_row, colnr_T old_col, bcount_t old_byte, int new_row,
+ colnr_T new_col, bcount_t new_byte)
{
if (!buf_updates_active(buf)
|| (old_byte == 0 && new_byte == 0)) {
return;
}
- // notify each of the active callbakcs
+ // notify each of the active callbacks
size_t j = 0;
for (size_t i = 0; i < kv_size(buf->update_callbacks); i++) {
BufUpdateCallbacks cb = kv_A(buf->update_callbacks, i);
@@ -392,18 +386,18 @@ void buf_updates_changedtick(buf_T *buf)
void buf_updates_changedtick_single(buf_T *buf, uint64_t channel_id)
{
- Array args = ARRAY_DICT_INIT;
- args.size = 2;
- args.items = xcalloc(sizeof(Object), args.size);
+ Array args = ARRAY_DICT_INIT;
+ args.size = 2;
+ args.items = xcalloc(args.size, sizeof(Object));
- // the first argument is always the buffer handle
- args.items[0] = BUFFER_OBJ(buf->handle);
+ // the first argument is always the buffer handle
+ args.items[0] = BUFFER_OBJ(buf->handle);
- // next argument is b:changedtick
- args.items[1] = INTEGER_OBJ(buf_get_changedtick(buf));
+ // next argument is b:changedtick
+ args.items[1] = INTEGER_OBJ(buf_get_changedtick(buf));
- // don't try and clean up dead channels here
- rpc_send_event(channel_id, "nvim_buf_changedtick_event", args);
+ // don't try and clean up dead channels here
+ rpc_send_event(channel_id, "nvim_buf_changedtick_event", args);
}
void buffer_update_callbacks_free(BufUpdateCallbacks cb)
diff --git a/src/nvim/change.c b/src/nvim/change.c
index c0183d4317..4ac5edeaa9 100644
--- a/src/nvim/change.c
+++ b/src/nvim/change.c
@@ -12,16 +12,17 @@
#include "nvim/diff.h"
#include "nvim/edit.h"
#include "nvim/eval.h"
+#include "nvim/extmark.h"
#include "nvim/fileio.h"
#include "nvim/fold.h"
#include "nvim/indent.h"
#include "nvim/indent_c.h"
#include "nvim/mark.h"
-#include "nvim/extmark.h"
#include "nvim/memline.h"
#include "nvim/misc1.h"
#include "nvim/move.h"
#include "nvim/option.h"
+#include "nvim/plines.h"
#include "nvim/screen.h"
#include "nvim/search.h"
#include "nvim/state.h"
@@ -40,25 +41,25 @@
/// "col" is the column for the message; non-zero when in insert mode and
/// 'showmode' is on.
/// Careful: may trigger autocommands that reload the buffer.
-void change_warning(int col)
+void change_warning(buf_T *buf, int col)
{
static char *w_readonly = N_("W10: Warning: Changing a readonly file");
- if (curbuf->b_did_warn == false
+ if (buf->b_did_warn == false
&& curbufIsChanged() == 0
&& !autocmd_busy
- && curbuf->b_p_ro) {
- curbuf_lock++;
- apply_autocmds(EVENT_FILECHANGEDRO, NULL, NULL, false, curbuf);
- curbuf_lock--;
- if (!curbuf->b_p_ro) {
- return;
+ && buf->b_p_ro) {
+ buf->b_ro_locked++;
+ apply_autocmds(EVENT_FILECHANGEDRO, NULL, NULL, false, buf);
+ buf->b_ro_locked--;
+ if (!buf->b_p_ro) {
+ return;
}
// Do what msg() does, but with a column offset if the warning should
// be after the mode message.
msg_start();
if (msg_row == Rows - 1) {
- msg_col = col;
+ msg_col = col;
}
msg_source(HL_ATTR(HLF_W));
msg_ext_set_kind("wmsg");
@@ -70,10 +71,10 @@ void change_warning(int col)
ui_flush();
os_delay(1002L, true); // give the user time to think about it
}
- curbuf->b_did_warn = true;
+ buf->b_did_warn = true;
redraw_cmdline = false; // don't redraw and erase the message
if (msg_row < Rows - 1) {
- showmode();
+ showmode();
}
}
}
@@ -91,14 +92,13 @@ void changed(void)
// Give a warning about changing a read-only file. This may also
// check-out the file, thus change "curbuf"!
- change_warning(0);
+ change_warning(curbuf, 0);
// Create a swap file if that is wanted.
// Don't do this for "nofile" and "nowrite" buffer types.
if (curbuf->b_may_swap
- && !bt_dontwrite(curbuf)
- ) {
- int save_need_wait_return = need_wait_return;
+ && !bt_dontwrite(curbuf)) {
+ bool save_need_wait_return = need_wait_return;
need_wait_return = false;
ml_open_file(curbuf);
@@ -139,11 +139,10 @@ void changed_internal(void)
/// Common code for when a change was made.
/// See changed_lines() for the arguments.
/// Careful: may trigger autocommands that reload the buffer.
-static void changed_common(linenr_T lnum, colnr_T col, linenr_T lnume,
- long xtra)
+static void changed_common(linenr_T lnum, colnr_T col, linenr_T lnume, long xtra)
{
int i;
- pos_T *p;
+ pos_T *p;
int add;
// mark the buffer as modified
@@ -161,18 +160,18 @@ static void changed_common(linenr_T lnum, colnr_T col, linenr_T lnume,
// don't have an entry yet.
if (curbuf->b_new_change || curbuf->b_changelistlen == 0) {
if (curbuf->b_changelistlen == 0) {
- add = true;
+ add = true;
} else {
// Don't create a new entry when the line number is the same
// as the last one and the column is not too far away. Avoids
// creating many entries for typing "xxxxx".
p = &curbuf->b_changelist[curbuf->b_changelistlen - 1].mark;
if (p->lnum != lnum) {
- add = true;
+ add = true;
} else {
int cols = comp_textwidth(false);
if (cols == 0) {
- cols = 79;
+ cols = 79;
}
add = (p->col + cols < col || col + cols < p->col);
}
@@ -218,7 +217,7 @@ static void changed_common(linenr_T lnum, colnr_T col, linenr_T lnume,
if (wp->w_buffer == curbuf) {
// Mark this window to be redrawn later.
if (wp->w_redr_type < VALID) {
- wp->w_redr_type = VALID;
+ wp->w_redr_type = VALID;
}
// Check if a change in the buffer has invalidated the cached
@@ -234,11 +233,11 @@ static void changed_common(linenr_T lnum, colnr_T col, linenr_T lnume,
// inserting lines just above a closed fold. */
bool folded = hasFoldingWin(wp, lnum, &lnum, NULL, false, NULL);
if (wp->w_cursor.lnum == lnum) {
- wp->w_cline_folded = folded;
+ wp->w_cline_folded = folded;
}
folded = hasFoldingWin(wp, lnume, NULL, &lnume, false, NULL);
if (wp->w_cursor.lnum == lnume) {
- wp->w_cline_folded = folded;
+ wp->w_cline_folded = folded;
}
// If the changed line is in a range of previously folded lines,
@@ -246,14 +245,14 @@ static void changed_common(linenr_T lnum, colnr_T col, linenr_T lnume,
if (wp->w_cursor.lnum <= lnum) {
i = find_wl_entry(wp, lnum);
if (i >= 0 && wp->w_cursor.lnum > wp->w_lines[i].wl_lnum) {
- changed_line_abv_curs_win(wp);
+ changed_line_abv_curs_win(wp);
}
}
if (wp->w_cursor.lnum > lnum) {
- changed_line_abv_curs_win(wp);
+ changed_line_abv_curs_win(wp);
} else if (wp->w_cursor.lnum == lnum && wp->w_cursor.col >= col) {
- changed_cline_bef_curs_win(wp);
+ changed_cline_bef_curs_win(wp);
}
if (wp->w_botline >= lnum) {
// Assume that botline doesn't change (inserted lines make
@@ -290,13 +289,21 @@ static void changed_common(linenr_T lnum, colnr_T col, linenr_T lnume,
set_topline(wp, wp->w_topline);
}
- // Relative numbering may require updating more. Cursor line
- // highlighting probably needs to be updated if it's below the
- // change.
- if (wp->w_p_rnu
- || (wp->w_p_cul && lnum <= wp->w_last_cursorline)) {
+ // Relative numbering may require updating more.
+ if (wp->w_p_rnu) {
redraw_later(wp, SOME_VALID);
}
+
+ // Cursor line highlighting probably need to be updated with
+ // "VALID" if it's below the change.
+ // If the cursor line is inside the change we need to redraw more.
+ if (wp->w_p_cul) {
+ if (xtra == 0) {
+ redraw_later(wp, VALID);
+ } else if (lnum <= wp->w_last_cursorline) {
+ redraw_later(wp, SOME_VALID);
+ }
+ }
}
}
@@ -318,9 +325,9 @@ static void changedOneline(buf_T *buf, linenr_T lnum)
if (buf->b_mod_set) {
// find the maximum area that must be redisplayed
if (lnum < buf->b_mod_top) {
- buf->b_mod_top = lnum;
+ buf->b_mod_top = lnum;
} else if (lnum >= buf->b_mod_bot) {
- buf->b_mod_bot = lnum + 1;
+ buf->b_mod_bot = lnum + 1;
}
} else {
// set the area that must be redisplayed to one line
@@ -352,7 +359,7 @@ void changed_bytes(linenr_T lnum, colnr_T col)
redraw_later(wp, VALID);
wlnum = diff_lnum_win(lnum, wp);
if (wlnum > 0) {
- changedOneline(wp->w_buffer, wlnum);
+ changedOneline(wp->w_buffer, wlnum);
}
}
}
@@ -454,17 +461,15 @@ void changed_lines_buf(buf_T *buf, linenr_T lnum, linenr_T lnume, long xtra)
/// When only inserting lines, "lnum" and "lnume" are equal.
/// Takes care of calling changed() and updating b_mod_*.
/// Careful: may trigger autocommands that reload the buffer.
-void
-changed_lines(
- linenr_T lnum, // first line with change
- colnr_T col, // column in first line with change
- linenr_T lnume, // line below last changed line
- long xtra, // number of extra lines (negative when deleting)
- bool do_buf_event // some callers like undo/redo call changed_lines()
- // and then increment changedtick *again*. This flag
- // allows these callers to send the nvim_buf_lines_event
- // events after they're done modifying changedtick.
-)
+///
+/// @param lnum first line with change
+/// @param col column in first line with change
+/// @param lnume line below last changed line
+/// @param xtra number of extra lines (negative when deleting)
+/// @param do_buf_event some callers like undo/redo call changed_lines() and
+/// then increment changedtick *again*. This flag allows these callers to send
+/// the nvim_buf_lines_event events after they're done modifying changedtick.
+void changed_lines(linenr_T lnum, colnr_T col, linenr_T lnume, long xtra, bool do_buf_event)
{
changed_lines_buf(curbuf, lnum, lnume, xtra);
@@ -585,9 +590,9 @@ void ins_char_bytes(char_u *buf, size_t charlen)
// cells. May result in adding spaces to fill a gap.
colnr_T vcol;
getvcol(curwin, &curwin->w_cursor, NULL, &vcol, NULL);
- colnr_T new_vcol = vcol + chartabsize(buf, vcol);
+ colnr_T new_vcol = vcol + win_chartabsize(curwin, buf, vcol);
while (oldp[col + oldlen] != NUL && vcol < new_vcol) {
- vcol += chartabsize(oldp + col + oldlen, vcol);
+ vcol += win_chartabsize(curwin, oldp + col + oldlen, vcol);
// Don't need to remove a TAB that takes us to the right
// position.
if (vcol > new_vcol && oldp[col + oldlen] == TAB) {
@@ -600,7 +605,7 @@ void ins_char_bytes(char_u *buf, size_t charlen)
}
}
curwin->w_p_list = old_list;
- } else if (oldp[col] != NUL) {
+ } else if (oldp[col] != NUL) {
// normal replace
oldlen = (size_t)(*mb_ptr2len)(oldp + col);
}
@@ -648,8 +653,7 @@ void ins_char_bytes(char_u *buf, size_t charlen)
// show the match for right parens and braces.
if (p_sm && (State & INSERT)
&& msg_silent == 0
- && !ins_compl_active()
- ) {
+ && !ins_compl_active()) {
showmatch(utf_ptr2char(buf));
}
@@ -665,7 +669,7 @@ void ins_char_bytes(char_u *buf, size_t charlen)
/// Caller must have prepared for undo.
void ins_str(char_u *s)
{
- char_u *oldp, *newp;
+ char_u *oldp, *newp;
int newlen = (int)STRLEN(s);
int oldlen;
colnr_T col;
@@ -712,7 +716,7 @@ int del_chars(long count, int fixpos)
{
int bytes = 0;
long i;
- char_u *p;
+ char_u *p;
int l;
p = get_cursor_pos_ptr();
@@ -779,11 +783,10 @@ int del_bytes(colnr_T count, bool fixpos_arg, bool use_delcombine)
int movelen = oldlen - col - count + 1; // includes trailing NUL
if (movelen <= 1) {
// If we just took off the last character of a non-blank line, and
- // fixpos is TRUE, we don't want to end up positioned at the NUL,
+ // fixpos is true, we don't want to end up positioned at the NUL,
// unless "restart_edit" is set or 'virtualedit' contains "onemore".
if (col > 0 && fixpos && restart_edit == 0
- && (ve_flags & VE_ONEMORE) == 0
- ) {
+ && (ve_flags & VE_ONEMORE) == 0) {
curwin->w_cursor.col--;
curwin->w_cursor.coladd = 0;
curwin->w_cursor.col -= utf_head_off(oldp, oldp + curwin->w_cursor.col);
@@ -947,12 +950,10 @@ int copy_indent(int size, char_u *src)
/// "second_line_indent": indent for after ^^D in Insert mode or if flag
/// OPENLINE_COM_LIST
///
+/// @param dir FORWARD or BACKWARD
+///
/// @return true on success, false on failure
-int open_line(
- int dir, // FORWARD or BACKWARD
- int flags,
- int second_line_indent
-)
+int open_line(int dir, int flags, int second_line_indent)
{
char_u *next_line = NULL; // copy of the next line
char_u *p_extra = NULL; // what goes to next line
@@ -994,9 +995,9 @@ int open_line(
// the line, replacing what was there before and pushing the right
// stuff onto the replace stack. -- webb.
if (curwin->w_cursor.lnum < orig_line_count) {
- next_line = vim_strsave(ml_get(curwin->w_cursor.lnum + 1));
+ next_line = vim_strsave(ml_get(curwin->w_cursor.lnum + 1));
} else {
- next_line = vim_strsave((char_u *)"");
+ next_line = vim_strsave((char_u *)"");
}
// In VREPLACE mode, a NL replaces the rest of the line, and starts
@@ -1014,8 +1015,7 @@ int open_line(
}
if ((State & INSERT)
- && !(State & VREPLACE_FLAG)
- ) {
+ && !(State & VREPLACE_FLAG)) {
p_extra = saved_line + curwin->w_cursor.col;
if (do_si) { // need first char after new line break
p = skipwhite(p_extra);
@@ -1034,14 +1034,13 @@ int open_line(
// the prior line, and it should be truncated. Do this even if 'ai' is not
// set because automatically inserting a comment leader also sets did_ai.
if (dir == FORWARD && did_ai) {
- trunc_line = true;
+ trunc_line = true;
}
// If 'autoindent' and/or 'smartindent' is set, try to figure out what
// indent to use for the new line.
if (curbuf->b_p_ai
- || do_si
- ) {
+ || do_si) {
// count white space on current line
newindent = get_indent_str_vtab(saved_line,
curbuf->b_p_ts,
@@ -1057,15 +1056,15 @@ int open_line(
// "if (condition) {"
if (!trunc_line && do_si && *saved_line != NUL
&& (p_extra == NULL || first_char != '{')) {
- char_u *ptr;
+ char_u *ptr;
char_u last_char;
old_cursor = curwin->w_cursor;
ptr = saved_line;
if (flags & OPENLINE_DO_COM) {
- lead_len = get_leader_len(ptr, NULL, false, true);
+ lead_len = get_leader_len(ptr, NULL, false, true);
} else {
- lead_len = 0;
+ lead_len = 0;
}
if (dir == FORWARD) {
// Skip preprocessor directives, unless they are
@@ -1110,17 +1109,17 @@ int open_line(
// Find last non-blank in line
p = ptr + STRLEN(ptr) - 1;
while (p > ptr && ascii_iswhite(*p)) {
- p--;
+ p--;
}
last_char = *p;
// find the character just before the '{' or ';'
if (last_char == '{' || last_char == ';') {
if (p > ptr) {
- p--;
+ p--;
}
while (p > ptr && ascii_iswhite(*p)) {
- p--;
+ p--;
}
}
// Try to catch lines that are split over multiple
@@ -1142,12 +1141,12 @@ int open_line(
if (last_char == '{') {
did_si = true; // do indent
no_si = true; // don't delete it when '{' typed
- // Look for "if" and the like, use 'cinwords'.
- // Don't do this if the previous line ended in ';' or
- // '}'.
+ // Look for "if" and the like, use 'cinwords'.
+ // Don't do this if the previous line ended in ';' or
+ // '}'.
} else if (last_char != ';' && last_char != '}'
&& cin_is_cinword(ptr)) {
- did_si = true;
+ did_si = true;
}
}
} else { // dir == BACKWARD
@@ -1196,15 +1195,15 @@ int open_line(
lead_len = 0;
}
if (lead_len > 0) {
- char_u *lead_repl = NULL; // replaces comment leader
+ char_u *lead_repl = NULL; // replaces comment leader
int lead_repl_len = 0; // length of *lead_repl
char_u lead_middle[COM_MAX_LEN]; // middle-comment string
char_u lead_end[COM_MAX_LEN]; // end-comment string
- char_u *comment_end = NULL; // where lead_end has been found
+ char_u *comment_end = NULL; // where lead_end has been found
int extra_space = false; // append extra space
int current_flag;
int require_blank = false; // requires blank after middle
- char_u *p2;
+ char_u *p2;
// If the comment leader has the start, middle or end flag, it may not
// be used or may be replaced with the middle leader.
@@ -1295,7 +1294,7 @@ int open_line(
// Doing "O" on the end of a comment inserts the middle leader.
// Find the string for the middle leader, searching backwards.
while (p > curbuf->b_p_com && *p != ',') {
- p--;
+ p--;
}
for (lead_repl = p; lead_repl > curbuf->b_p_com
&& lead_repl[-1] != ':'; lead_repl--) {
@@ -1309,13 +1308,13 @@ int open_line(
// Check whether we allow automatic ending of comments
for (p2 = p; *p2 && *p2 != ':'; p2++) {
if (*p2 == COM_AUTO_END) {
- end_comment_pending = -1; // means we want to set it
+ end_comment_pending = -1; // means we want to set it
}
}
if (end_comment_pending == -1) {
// Find last character in end-comment string
while (*p2 && *p2 != ',') {
- p2++;
+ p2++;
}
end_comment_pending = p2[-1];
}
@@ -1325,7 +1324,7 @@ int open_line(
// Comment leader for first line only: Don't repeat leader
// when using "O", blank out leader when using "o".
if (dir == BACKWARD) {
- lead_len = 0;
+ lead_len = 0;
} else {
lead_repl = (char_u *)"";
lead_repl_len = 0;
@@ -1336,11 +1335,11 @@ int open_line(
if (lead_len > 0) {
// allocate buffer (may concatenate p_extra later)
int bytes = lead_len
- + lead_repl_len
- + extra_space
- + extra_len
- + (second_line_indent > 0 ? second_line_indent : 0)
- + 1;
+ + lead_repl_len
+ + extra_space
+ + extra_len
+ + (second_line_indent > 0 ? second_line_indent : 0)
+ + 1;
assert(bytes >= 0);
leader = xmalloc((size_t)bytes);
allocated = leader; // remember to free it later
@@ -1354,11 +1353,11 @@ int open_line(
for (p = lead_flags; *p != NUL && *p != ':'; ) {
if (*p == COM_RIGHT || *p == COM_LEFT) {
- c = *p++;
+ c = *p++;
} else if (ascii_isdigit(*p) || *p == '-') {
- off = getdigits_int(&p, true, 0);
+ off = getdigits_int(&p, true, 0);
} else {
- p++;
+ p++;
}
}
if (c == COM_RIGHT) { // right adjusted leader
@@ -1374,7 +1373,7 @@ int open_line(
int repl_size = vim_strnsize(lead_repl,
lead_repl_len);
int old_size = 0;
- char_u *endp = p;
+ char_u *endp = p;
int l;
while (old_size < repl_size && p > leader) {
@@ -1383,14 +1382,14 @@ int open_line(
}
l = lead_repl_len - (int)(endp - p);
if (l != 0) {
- memmove(endp + l, endp,
- (size_t)((leader + lead_len) - endp));
+ memmove(endp + l, endp,
+ (size_t)((leader + lead_len) - endp));
}
lead_len += l;
}
memmove(p, lead_repl, (size_t)lead_repl_len);
if (p + lead_repl_len > leader + lead_len) {
- p[lead_repl_len] = NUL;
+ p[lead_repl_len] = NUL;
}
// blank-out any other chars from the old leader.
@@ -1408,7 +1407,7 @@ int open_line(
lead_len -= l;
*p = ' ';
} else if (!ascii_iswhite(*p)) {
- *p = ' ';
+ *p = ' ';
}
}
} else { // left adjusted leader
@@ -1425,12 +1424,12 @@ int open_line(
for (i = 0; i < lead_len && p[i] != NUL; i += l) {
l = (*mb_ptr2len)(p + i);
if (vim_strnsize(p, i + l) > repl_size) {
- break;
+ break;
}
}
if (i != lead_repl_len) {
- memmove(p + lead_repl_len, p + i,
- (size_t)(lead_len - i - (p - leader)));
+ memmove(p + lead_repl_len, p + i,
+ (size_t)(lead_len - i - (p - leader)));
lead_len += lead_repl_len - i;
}
}
@@ -1467,8 +1466,7 @@ int open_line(
// Recompute the indent, it may have changed.
if (curbuf->b_p_ai
- || do_si
- ) {
+ || do_si) {
newindent = get_indent_str_vtab(leader,
curbuf->b_p_ts,
curbuf->b_p_vts_array, false);
@@ -1488,7 +1486,7 @@ int open_line(
&& leader[lead_len - 1] == ' ') {
// Don't do it when there is a tab before the space
if (vim_strchr(skipwhite(leader), '\t') != NULL) {
- break;
+ break;
}
lead_len--;
off--;
@@ -1497,7 +1495,7 @@ int open_line(
// If the leader ends in white space, don't add an
// extra space
if (lead_len > 0 && ascii_iswhite(leader[lead_len - 1])) {
- extra_space = false;
+ extra_space = false;
}
leader[lead_len] = NUL;
}
@@ -1512,8 +1510,7 @@ int open_line(
// if a new indent will be set below, remove the indent that
// is in the comment leader
if (newindent
- || did_si
- ) {
+ || did_si) {
while (lead_len && ascii_iswhite(*leader)) {
lead_len--;
newcol--;
@@ -1550,7 +1547,7 @@ int open_line(
// When in REPLACE mode, put the deleted blanks on the replace stack,
// preceded by a NUL, so they can be put back when a BS is entered.
if (REPLACE_NORMAL(State)) {
- replace_push(NUL); // end of extra blanks
+ replace_push(NUL); // end of extra blanks
}
if (curbuf->b_p_ai || (flags & OPENLINE_DELSPACES)) {
while ((*p_extra == ' ' || *p_extra == '\t')
@@ -1568,7 +1565,7 @@ int open_line(
}
if (p_extra == NULL) {
- p_extra = (char_u *)""; // append empty line
+ p_extra = (char_u *)""; // append empty line
}
// concatenate leader and p_extra, if there is a leader
@@ -1632,8 +1629,7 @@ int open_line(
inhibit_delete_count++;
if (newindent
- || did_si
- ) {
+ || did_si) {
curwin->w_cursor.lnum++;
if (did_si) {
int sw = get_sw_value(curbuf);
@@ -1697,9 +1693,8 @@ int open_line(
// TODO(vigoux): maybe there is issues there with expandtabs ?
int cols_spliced = 0;
if (new_len < curwin->w_cursor.col) {
- extmark_splice_cols(
- curbuf, (int)curwin->w_cursor.lnum - 1,
- new_len, curwin->w_cursor.col - new_len, 0, kExtmarkUndo);
+ extmark_splice_cols(curbuf, (int)curwin->w_cursor.lnum - 1,
+ new_len, curwin->w_cursor.col - new_len, 0, kExtmarkUndo);
cols_spliced = curwin->w_cursor.col - new_len;
}
@@ -1732,7 +1727,7 @@ int open_line(
}
if (did_append) {
changed_lines(curwin->w_cursor.lnum, 0, curwin->w_cursor.lnum, 1L, true);
- // bail out and just get the final lenght of the line we just manipulated
+ // bail out and just get the final length of the line we just manipulated
bcount_t extra = (bcount_t)STRLEN(ml_get(curwin->w_cursor.lnum));
extmark_splice(curbuf, (int)curwin->w_cursor.lnum-1, 0,
0, 0, 0, 1, 0, 1+extra, kExtmarkUndo);
@@ -1806,7 +1801,7 @@ theend:
/// If "fixpos" is true fix the cursor position when done.
void truncate_line(int fixpos)
{
- char_u *newp;
+ char_u *newp;
linenr_T lnum = curwin->w_cursor.lnum;
colnr_T col = curwin->w_cursor.col;
@@ -1828,18 +1823,18 @@ void truncate_line(int fixpos)
/// Delete "nlines" lines at the cursor.
/// Saves the lines for undo first if "undo" is true.
-void del_lines(long nlines, int undo)
+void del_lines(long nlines, bool undo)
{
long n;
linenr_T first = curwin->w_cursor.lnum;
if (nlines <= 0) {
- return;
+ return;
}
// save the deleted lines for undo
if (undo && u_savedel(first, nlines) == FAIL) {
- return;
+ return;
}
for (n = 0; n < nlines; ) {
@@ -1852,7 +1847,7 @@ void del_lines(long nlines, int undo)
// If we delete the last line in the file, stop
if (first > curbuf->b_ml.ml_line_count) {
- break;
+ break;
}
}
diff --git a/src/nvim/channel.c b/src/nvim/channel.c
index 60af11e94b..30243a3102 100644
--- a/src/nvim/channel.c
+++ b/src/nvim/channel.c
@@ -12,11 +12,11 @@
#include "nvim/msgpack_rpc/server.h"
#include "nvim/os/shell.h"
#ifdef WIN32
-# include "nvim/os/pty_conpty_win.h"
# include "nvim/os/os_win_console.h"
+# include "nvim/os/pty_conpty_win.h"
#endif
-#include "nvim/path.h"
#include "nvim/ascii.h"
+#include "nvim/path.h"
static bool did_stdio = false;
@@ -32,13 +32,9 @@ static uint64_t next_chan_id = CHAN_STDERR+1;
/// Teardown the module
void channel_teardown(void)
{
- if (!channels) {
- return;
- }
-
Channel *channel;
- map_foreach_value(channels, channel, {
+ map_foreach_value(&channels, channel, {
channel_close(channel->id, kChannelPartAll, NULL);
});
}
@@ -70,7 +66,7 @@ bool channel_close(uint64_t id, ChannelPart part, const char **error)
if (part == kChannelPartRpc || part == kChannelPartAll) {
close_main = true;
if (chan->is_rpc) {
- rpc_close(chan);
+ rpc_close(chan);
} else if (part == kChannelPartRpc) {
*error = (const char *)e_invstream;
return false;
@@ -82,68 +78,68 @@ bool channel_close(uint64_t id, ChannelPart part, const char **error)
}
switch (chan->streamtype) {
- case kChannelStreamSocket:
- if (!close_main) {
- *error = (const char *)e_invstream;
- return false;
- }
- stream_may_close(&chan->stream.socket);
- break;
+ case kChannelStreamSocket:
+ if (!close_main) {
+ *error = (const char *)e_invstream;
+ return false;
+ }
+ stream_may_close(&chan->stream.socket);
+ break;
- case kChannelStreamProc:
- proc = (Process *)&chan->stream.proc;
- if (part == kChannelPartStdin || close_main) {
- stream_may_close(&proc->in);
- }
- if (part == kChannelPartStdout || close_main) {
- stream_may_close(&proc->out);
- }
- if (part == kChannelPartStderr || part == kChannelPartAll) {
- stream_may_close(&proc->err);
- }
- if (proc->type == kProcessTypePty && part == kChannelPartAll) {
- pty_process_close_master(&chan->stream.pty);
- }
+ case kChannelStreamProc:
+ proc = (Process *)&chan->stream.proc;
+ if (part == kChannelPartStdin || close_main) {
+ stream_may_close(&proc->in);
+ }
+ if (part == kChannelPartStdout || close_main) {
+ stream_may_close(&proc->out);
+ }
+ if (part == kChannelPartStderr || part == kChannelPartAll) {
+ stream_may_close(&proc->err);
+ }
+ if (proc->type == kProcessTypePty && part == kChannelPartAll) {
+ pty_process_close_master(&chan->stream.pty);
+ }
- break;
+ break;
- case kChannelStreamStdio:
- if (part == kChannelPartStdin || close_main) {
- stream_may_close(&chan->stream.stdio.in);
- }
- if (part == kChannelPartStdout || close_main) {
- stream_may_close(&chan->stream.stdio.out);
- }
- if (part == kChannelPartStderr) {
- *error = (const char *)e_invstream;
- return false;
- }
- break;
+ case kChannelStreamStdio:
+ if (part == kChannelPartStdin || close_main) {
+ stream_may_close(&chan->stream.stdio.in);
+ }
+ if (part == kChannelPartStdout || close_main) {
+ stream_may_close(&chan->stream.stdio.out);
+ }
+ if (part == kChannelPartStderr) {
+ *error = (const char *)e_invstream;
+ return false;
+ }
+ break;
- case kChannelStreamStderr:
- if (part != kChannelPartAll && part != kChannelPartStderr) {
- *error = (const char *)e_invstream;
- return false;
- }
- if (!chan->stream.err.closed) {
- chan->stream.err.closed = true;
- // Don't close on exit, in case late error messages
- if (!exiting) {
- fclose(stderr);
- }
- channel_decref(chan);
+ case kChannelStreamStderr:
+ if (part != kChannelPartAll && part != kChannelPartStderr) {
+ *error = (const char *)e_invstream;
+ return false;
+ }
+ if (!chan->stream.err.closed) {
+ chan->stream.err.closed = true;
+ // Don't close on exit, in case late error messages
+ if (!exiting) {
+ fclose(stderr);
}
- break;
+ channel_decref(chan);
+ }
+ break;
- case kChannelStreamInternal:
- if (!close_main) {
- *error = (const char *)e_invstream;
- return false;
- }
- break;
+ case kChannelStreamInternal:
+ if (!close_main) {
+ *error = (const char *)e_invstream;
+ return false;
+ }
+ break;
- default:
- abort();
+ default:
+ abort();
}
return true;
@@ -152,7 +148,6 @@ bool channel_close(uint64_t id, ChannelPart part, const char **error)
/// Initializes the module
void channel_init(void)
{
- channels = pmap_new(uint64_t)();
channel_alloc(kChannelStreamStderr);
rpc_init();
}
@@ -177,7 +172,7 @@ Channel *channel_alloc(ChannelStreamType type)
chan->exit_status = -1;
chan->streamtype = type;
assert(chan->id <= VARNUMBER_MAX);
- pmap_put(uint64_t)(channels, chan->id, chan);
+ pmap_put(uint64_t)(&channels, chan->id, chan);
return chan;
}
@@ -245,11 +240,15 @@ static void free_channel_event(void **argv)
rpc_free(chan);
}
+ if (chan->streamtype == kChannelStreamProc) {
+ process_free(&chan->stream.proc);
+ }
+
callback_reader_free(&chan->on_data);
callback_reader_free(&chan->on_stderr);
callback_free(&chan->on_exit);
- pmap_del(uint64_t)(channels, chan->id);
+ pmap_del(uint64_t)(&channels, chan->id);
multiqueue_free(chan->events);
xfree(chan);
}
@@ -259,7 +258,7 @@ static void channel_destroy_early(Channel *chan)
if ((chan->id != --next_chan_id)) {
abort();
}
- pmap_del(uint64_t)(channels, chan->id);
+ pmap_del(uint64_t)(&channels, chan->id);
chan->id = 0;
if ((--chan->refcount != 0)) {
@@ -289,6 +288,9 @@ static void close_cb(Stream *stream, void *data)
/// `on_stdout` is ignored
/// @param[in] detach True if the job should not be killed when nvim exits,
/// ignored if `pty` is true
+/// @param[in] stdin_mode Stdin mode. Either kChannelStdinPipe to open a
+/// channel for stdin or kChannelStdinNull to leave
+/// stdin disconnected.
/// @param[in] cwd Initial working directory for the job. Nvim's working
/// directory if `cwd` is NULL
/// @param[in] pty_width Width of the pty, ignored if `pty` is false
@@ -299,12 +301,10 @@ static void close_cb(Stream *stream, void *data)
/// < 0 if the job can't start
///
/// @returns [allocated] channel
-Channel *channel_job_start(char **argv, CallbackReader on_stdout,
- CallbackReader on_stderr, Callback on_exit,
- bool pty, bool rpc, bool overlapped, bool detach,
- const char *cwd,
- uint16_t pty_width, uint16_t pty_height,
- dict_T *env, varnumber_T *status_out)
+Channel *channel_job_start(char **argv, CallbackReader on_stdout, CallbackReader on_stderr,
+ Callback on_exit, bool pty, bool rpc, bool overlapped, bool detach,
+ ChannelStdinMode stdin_mode, const char *cwd, uint16_t pty_width,
+ uint16_t pty_height, dict_T *env, varnumber_T *status_out)
{
assert(cwd == NULL || os_isdir_executable(cwd));
@@ -345,7 +345,7 @@ Channel *channel_job_start(char **argv, CallbackReader on_stdout,
proc->overlapped = overlapped;
char *cmd = xstrdup(proc->argv[0]);
- bool has_out, has_err;
+ bool has_in, has_out, has_err;
if (proc->type == kProcessTypePty) {
has_out = true;
has_err = false;
@@ -353,7 +353,17 @@ Channel *channel_job_start(char **argv, CallbackReader on_stdout,
has_out = rpc || callback_reader_set(chan->on_data);
has_err = callback_reader_set(chan->on_stderr);
}
- int status = process_spawn(proc, true, has_out, has_err);
+
+ switch (stdin_mode) {
+ case kChannelStdinPipe:
+ has_in = true;
+ break;
+ case kChannelStdinNull:
+ has_in = false;
+ break;
+ }
+
+ int status = process_spawn(proc, has_in, has_out, has_err);
if (status) {
EMSG3(_(e_jobspawn), os_strerror(status), cmd);
xfree(cmd);
@@ -369,7 +379,9 @@ Channel *channel_job_start(char **argv, CallbackReader on_stdout,
tv_dict_free(proc->env);
}
- wstream_init(&proc->in, 0);
+ if (has_in) {
+ wstream_init(&proc->in, 0);
+ }
if (has_out) {
rstream_init(&proc->out, 0);
}
@@ -395,8 +407,7 @@ Channel *channel_job_start(char **argv, CallbackReader on_stdout,
}
-uint64_t channel_connect(bool tcp, const char *address,
- bool rpc, CallbackReader on_output,
+uint64_t channel_connect(bool tcp, const char *address, bool rpc, CallbackReader on_output,
int timeout, const char **error)
{
Channel *channel;
@@ -456,8 +467,7 @@ void channel_from_connection(SocketWatcher *watcher)
/// Creates an API channel from stdin/stdout. This is used when embedding
/// Neovim
-uint64_t channel_from_stdio(bool rpc, CallbackReader on_output,
- const char **error)
+uint64_t channel_from_stdio(bool rpc, CallbackReader on_output, const char **error)
FUNC_ATTR_NONNULL_ALL
{
if (!headless_mode && !embedded_mode) {
@@ -500,8 +510,8 @@ uint64_t channel_from_stdio(bool rpc, CallbackReader on_output,
}
/// @param data will be consumed
-size_t channel_send(uint64_t id, char *data, size_t len,
- bool data_owned, const char **error)
+size_t channel_send(uint64_t id, char *data, size_t len, bool data_owned, const char **error)
+ FUNC_ATTR_NONNULL_ALL
{
Channel *chan = find_channel(id);
size_t written = 0;
@@ -569,22 +579,20 @@ static inline list_T *buffer_to_tv_list(const char *const buf, const size_t len)
return l;
}
-void on_channel_data(Stream *stream, RBuffer *buf, size_t count,
- void *data, bool eof)
+void on_channel_data(Stream *stream, RBuffer *buf, size_t count, void *data, bool eof)
{
Channel *chan = data;
on_channel_output(stream, chan, buf, count, eof, &chan->on_data);
}
-void on_job_stderr(Stream *stream, RBuffer *buf, size_t count,
- void *data, bool eof)
+void on_job_stderr(Stream *stream, RBuffer *buf, size_t count, void *data, bool eof)
{
Channel *chan = data;
on_channel_output(stream, chan, buf, count, eof, &chan->on_stderr);
}
-static void on_channel_output(Stream *stream, Channel *chan, RBuffer *buf,
- size_t count, bool eof, CallbackReader *reader)
+static void on_channel_output(Stream *stream, Channel *chan, RBuffer *buf, size_t count, bool eof,
+ CallbackReader *reader)
{
// stub variable, to keep reading consistent with the order of events, only
// consider the count parameter.
@@ -683,9 +691,7 @@ static void channel_process_exit_cb(Process *proc, int status, void *data)
{
Channel *chan = data;
if (chan->term) {
- char msg[sizeof("\r\n[Process exited ]") + NUMBUFLEN];
- snprintf(msg, sizeof msg, "\r\n[Process exited %d]", proc->status);
- terminal_close(chan->term, msg);
+ terminal_close(chan->term, status);
}
// If process did not exit, we only closed the handle of a detached process.
@@ -839,32 +845,43 @@ Dictionary channel_info(uint64_t id)
const char *stream_desc, *mode_desc;
switch (chan->streamtype) {
- case kChannelStreamProc:
- stream_desc = "job";
- if (chan->stream.proc.type == kProcessTypePty) {
- const char *name = pty_process_tty_name(&chan->stream.pty);
- PUT(info, "pty", STRING_OBJ(cstr_to_string(name)));
+ case kChannelStreamProc: {
+ stream_desc = "job";
+ if (chan->stream.proc.type == kProcessTypePty) {
+ const char *name = pty_process_tty_name(&chan->stream.pty);
+ PUT(info, "pty", STRING_OBJ(cstr_to_string(name)));
+ }
+
+ char **p = chan->stream.proc.argv;
+ Array argv = ARRAY_DICT_INIT;
+ if (p != NULL) {
+ while (*p != NULL) {
+ ADD(argv, STRING_OBJ(cstr_to_string(*p)));
+ p++;
}
- break;
+ }
+ PUT(info, "argv", ARRAY_OBJ(argv));
+ break;
+ }
- case kChannelStreamStdio:
- stream_desc = "stdio";
- break;
+ case kChannelStreamStdio:
+ stream_desc = "stdio";
+ break;
- case kChannelStreamStderr:
- stream_desc = "stderr";
- break;
+ case kChannelStreamStderr:
+ stream_desc = "stderr";
+ break;
- case kChannelStreamInternal:
- PUT(info, "internal", BOOLEAN_OBJ(true));
- FALLTHROUGH;
+ case kChannelStreamInternal:
+ PUT(info, "internal", BOOLEAN_OBJ(true));
+ FALLTHROUGH;
- case kChannelStreamSocket:
- stream_desc = "socket";
- break;
+ case kChannelStreamSocket:
+ stream_desc = "socket";
+ break;
- default:
- abort();
+ default:
+ abort();
}
PUT(info, "stream", STRING_OBJ(cstr_to_string(stream_desc)));
@@ -886,7 +903,7 @@ Array channel_all_info(void)
{
Channel *channel;
Array ret = ARRAY_DICT_INIT;
- map_foreach_value(channels, channel, {
+ map_foreach_value(&channels, channel, {
ADD(ret, DICTIONARY_OBJ(channel_info(channel->id)));
});
return ret;
diff --git a/src/nvim/channel.h b/src/nvim/channel.h
index 9d26852ce5..9bc0df3615 100644
--- a/src/nvim/channel.h
+++ b/src/nvim/channel.h
@@ -28,6 +28,10 @@ typedef enum {
kChannelPartAll
} ChannelPart;
+typedef enum {
+ kChannelStdinPipe,
+ kChannelStdinNull,
+} ChannelStdinMode;
typedef struct {
Stream in;
@@ -85,7 +89,7 @@ struct Channel {
bool callback_scheduled;
};
-EXTERN PMap(uint64_t) *channels INIT(= NULL);
+EXTERN PMap(uint64_t) channels INIT(= MAP_INIT);
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "channel.h.generated.h"
@@ -94,7 +98,7 @@ EXTERN PMap(uint64_t) *channels INIT(= NULL);
/// @returns Channel with the id or NULL if not found
static inline Channel *find_channel(uint64_t id)
{
- return pmap_get(uint64_t)(channels, id);
+ return pmap_get(uint64_t)(&channels, id);
}
static inline Stream *channel_instream(Channel *chan)
diff --git a/src/nvim/charset.c b/src/nvim/charset.c
index e2d844a351..f899ebf57c 100644
--- a/src/nvim/charset.c
+++ b/src/nvim/charset.c
@@ -6,14 +6,15 @@
/// Code related to character sets.
#include <assert.h>
+#include <inttypes.h>
#include <string.h>
#include <wctype.h>
-#include <inttypes.h>
-#include "nvim/vim.h"
#include "nvim/ascii.h"
#include "nvim/charset.h"
+#include "nvim/cursor.h"
#include "nvim/func_attr.h"
+#include "nvim/garray.h"
#include "nvim/indent.h"
#include "nvim/main.h"
#include "nvim/mark.h"
@@ -21,14 +22,14 @@
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/misc1.h"
-#include "nvim/garray.h"
#include "nvim/move.h"
#include "nvim/option.h"
#include "nvim/os_unix.h"
+#include "nvim/path.h"
+#include "nvim/plines.h"
#include "nvim/state.h"
#include "nvim/strings.h"
-#include "nvim/path.h"
-#include "nvim/cursor.h"
+#include "nvim/vim.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "charset.c.generated.h"
@@ -40,11 +41,11 @@ static bool chartab_initialized = false;
// b_chartab[] is an array with 256 bits, each bit representing one of the
// characters 0-255.
#define SET_CHARTAB(buf, c) \
- (buf)->b_chartab[(unsigned)(c) >> 6] |= (1ull << ((c) & 0x3f))
+ (buf)->b_chartab[(unsigned)(c) >> 6] |= (1ull << ((c) & 0x3f))
#define RESET_CHARTAB(buf, c) \
- (buf)->b_chartab[(unsigned)(c) >> 6] &= ~(1ull << ((c) & 0x3f))
+ (buf)->b_chartab[(unsigned)(c) >> 6] &= ~(1ull << ((c) & 0x3f))
#define GET_CHARTAB_TAB(chartab, c) \
- ((chartab)[(unsigned)(c) >> 6] & (1ull << ((c) & 0x3f)))
+ ((chartab)[(unsigned)(c) >> 6] & (1ull << ((c) & 0x3f)))
// Table used below, see init_chartab() for an explanation
static char_u g_chartab[256];
@@ -211,7 +212,7 @@ int buf_init_chartab(buf_T *buf, int global)
if (i == 0) {
// (re)set ID flag
if (tilde) {
- g_chartab[c] &= (uint8_t)~CT_ID_CHAR;
+ g_chartab[c] &= (uint8_t) ~CT_ID_CHAR;
} else {
g_chartab[c] |= CT_ID_CHAR;
}
@@ -223,7 +224,7 @@ int buf_init_chartab(buf_T *buf, int global)
if (tilde) {
g_chartab[c] = (uint8_t)((g_chartab[c] & ~CT_CELL_MASK)
+ ((dy_flags & DY_UHEX) ? 4 : 2));
- g_chartab[c] &= (uint8_t)~CT_PRINT_CHAR;
+ g_chartab[c] &= (uint8_t) ~CT_PRINT_CHAR;
} else {
g_chartab[c] = (uint8_t)((g_chartab[c] & ~CT_CELL_MASK) + 1);
g_chartab[c] |= CT_PRINT_CHAR;
@@ -232,7 +233,7 @@ int buf_init_chartab(buf_T *buf, int global)
} else if (i == 2) {
// (re)set fname flag
if (tilde) {
- g_chartab[c] &= (uint8_t)~CT_FNAME_CHAR;
+ g_chartab[c] &= (uint8_t) ~CT_FNAME_CHAR;
} else {
g_chartab[c] |= CT_FNAME_CHAR;
}
@@ -309,7 +310,7 @@ void trans_characters(char_u *buf, int bufsize)
///
/// @return number of bytes needed to hold a translation of `s`, NUL byte not
/// included.
-size_t transstr_len(const char *const s)
+size_t transstr_len(const char *const s, bool untab)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE
{
const char *p = s;
@@ -330,6 +331,9 @@ size_t transstr_len(const char *const s)
}
}
p += l;
+ } else if (*p == TAB && !untab) {
+ len += 1;
+ p++;
} else {
const int b2c_l = byte2cells((uint8_t)(*p++));
// Illegal byte sequence may occupy up to 4 characters.
@@ -345,9 +349,10 @@ size_t transstr_len(const char *const s)
/// @param[out] buf Buffer to which result should be saved.
/// @param[in] len Buffer length. Resulting string may not occupy more then
/// len - 1 bytes (one for trailing NUL byte).
+/// @param[in] untab remove tab characters
///
/// @return length of the resulting string, without the NUL byte.
-size_t transstr_buf(const char *const s, char *const buf, const size_t len)
+size_t transstr_buf(const char *const s, char *const buf, const size_t len, bool untab)
FUNC_ATTR_NONNULL_ALL
{
const char *p = s;
@@ -378,6 +383,8 @@ size_t transstr_buf(const char *const s, char *const buf, const size_t len)
}
}
p += l;
+ } else if (*p == TAB && !untab) {
+ *buf_p++ = *p++;
} else {
const char *const tb = (const char *)transchar_byte((uint8_t)(*p++));
const size_t tb_len = strlen(tb);
@@ -400,14 +407,14 @@ size_t transstr_buf(const char *const s, char *const buf, const size_t len)
/// @param[in] s String to replace characters from.
///
/// @return [allocated] translated string
-char *transstr(const char *const s)
+char *transstr(const char *const s, bool untab)
FUNC_ATTR_NONNULL_RET
{
// Compute the length of the result, taking account of unprintable
// multi-byte characters.
- const size_t len = transstr_len((const char *)s) + 1;
+ const size_t len = transstr_len((const char *)s, untab) + 1;
char *const buf = xmalloc(len);
- transstr_buf(s, buf, len);
+ transstr_buf(s, buf, len, untab);
return buf;
}
@@ -416,7 +423,7 @@ char *transstr(const char *const s)
///
/// When "buf" is NULL, return an allocated string.
/// Otherwise, put the result in buf, limited by buflen, and return buf.
-char_u* str_foldcase(char_u *str, int orglen, char_u *buf, int buflen)
+char_u *str_foldcase(char_u *str, int orglen, char_u *buf, int buflen)
FUNC_ATTR_NONNULL_RET
{
garray_T ga;
@@ -733,80 +740,6 @@ int vim_strnsize(char_u *s, int len)
return size;
}
-/// Return the number of characters 'c' will take on the screen, taking
-/// into account the size of a tab.
-/// Use a define to make it fast, this is used very often!!!
-/// Also see getvcol() below.
-///
-/// @param p
-/// @param col
-///
-/// @return Number of characters.
-#define RET_WIN_BUF_CHARTABSIZE(wp, buf, p, col) \
- if (*(p) == TAB && (!(wp)->w_p_list || wp->w_p_lcs_chars.tab1)) { \
- return tabstop_padding(col, (buf)->b_p_ts, (buf)->b_p_vts_array); \
- } else { \
- return ptr2cells(p); \
- }
-
-int chartabsize(char_u *p, colnr_T col)
-{
- RET_WIN_BUF_CHARTABSIZE(curwin, curbuf, p, col)
-}
-
-static int win_chartabsize(win_T *wp, char_u *p, colnr_T col)
-{
- RET_WIN_BUF_CHARTABSIZE(wp, wp->w_buffer, p, col)
-}
-
-/// Return the number of characters the string 's' will take on the screen,
-/// taking into account the size of a tab.
-///
-/// @param s
-///
-/// @return Number of characters the string will take on the screen.
-int linetabsize(char_u *s)
-{
- return linetabsize_col(0, s);
-}
-
-/// Like linetabsize(), but starting at column "startcol".
-///
-/// @param startcol
-/// @param s
-///
-/// @return Number of characters the string will take on the screen.
-int linetabsize_col(int startcol, char_u *s)
-{
- colnr_T col = startcol;
- char_u *line = s; /* pointer to start of line, for breakindent */
-
- while (*s != NUL) {
- col += lbr_chartabsize_adv(line, &s, col);
- }
- return (int)col;
-}
-
-/// Like linetabsize(), but for a given window instead of the current one.
-///
-/// @param wp
-/// @param line
-/// @param len
-///
-/// @return Number of characters the string will take on the screen.
-unsigned int win_linetabsize(win_T *wp, char_u *line, colnr_T len)
-{
- colnr_T col = 0;
-
- for (char_u *s = line;
- *s != NUL && (len == MAXCOL || s < line + len);
- MB_PTR_ADV(s)) {
- col += win_lbr_chartabsize(wp, line, s, col, NULL);
- }
-
- return (unsigned int)col;
-}
-
/// Check that "c" is a normal identifier character:
/// Letters and characters from the 'isident' option.
///
@@ -936,229 +869,6 @@ bool vim_isprintc_strict(int c)
return c > 0 && (g_chartab[c] & CT_PRINT_CHAR);
}
-/// like chartabsize(), but also check for line breaks on the screen
-///
-/// @param line
-/// @param s
-/// @param col
-///
-/// @return The number of characters taken up on the screen.
-int lbr_chartabsize(char_u *line, unsigned char *s, colnr_T col)
-{
- if (!curwin->w_p_lbr && (*p_sbr == NUL) && !curwin->w_p_bri) {
- if (curwin->w_p_wrap) {
- return win_nolbr_chartabsize(curwin, s, col, NULL);
- }
- RET_WIN_BUF_CHARTABSIZE(curwin, curbuf, s, col)
- }
- return win_lbr_chartabsize(curwin, line == NULL ? s: line, s, col, NULL);
-}
-
-/// Call lbr_chartabsize() and advance the pointer.
-///
-/// @param line
-/// @param s
-/// @param col
-///
-/// @return The number of characters take up on the screen.
-int lbr_chartabsize_adv(char_u *line, char_u **s, colnr_T col)
-{
- int retval;
-
- retval = lbr_chartabsize(line, *s, col);
- MB_PTR_ADV(*s);
- return retval;
-}
-
-/// This function is used very often, keep it fast!!!!
-///
-/// If "headp" not NULL, set *headp to the size of what we for 'showbreak'
-/// string at start of line. Warning: *headp is only set if it's a non-zero
-/// value, init to 0 before calling.
-///
-/// @param wp
-/// @param line
-/// @param s
-/// @param col
-/// @param headp
-///
-/// @return The number of characters taken up on the screen.
-int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s, colnr_T col, int *headp)
-{
- colnr_T col2;
- colnr_T col_adj = 0; /* col + screen size of tab */
- colnr_T colmax;
- int added;
- int mb_added = 0;
- int numberextra;
- char_u *ps;
- int n;
-
- // No 'linebreak', 'showbreak' and 'breakindent': return quickly.
- if (!wp->w_p_lbr && !wp->w_p_bri && (*p_sbr == NUL)) {
- if (wp->w_p_wrap) {
- return win_nolbr_chartabsize(wp, s, col, headp);
- }
- RET_WIN_BUF_CHARTABSIZE(wp, wp->w_buffer, s, col)
- }
-
- // First get normal size, without 'linebreak'
- int size = win_chartabsize(wp, s, col);
- int c = *s;
- if (*s == TAB) {
- col_adj = size - 1;
- }
-
- // If 'linebreak' set check at a blank before a non-blank if the line
- // needs a break here
- if (wp->w_p_lbr
- && vim_isbreak(c)
- && !vim_isbreak((int)s[1])
- && wp->w_p_wrap
- && (wp->w_width_inner != 0)) {
- // Count all characters from first non-blank after a blank up to next
- // non-blank after a blank.
- numberextra = win_col_off(wp);
- col2 = col;
- colmax = (colnr_T)(wp->w_width_inner - numberextra - col_adj);
-
- if (col >= colmax) {
- colmax += col_adj;
- n = colmax + win_col_off2(wp);
-
- if (n > 0) {
- colmax += (((col - colmax) / n) + 1) * n - col_adj;
- }
- }
-
- for (;;) {
- ps = s;
- MB_PTR_ADV(s);
- c = *s;
-
- if (!(c != NUL
- && (vim_isbreak(c) || col2 == col || !vim_isbreak((int)(*ps))))) {
- break;
- }
-
- col2 += win_chartabsize(wp, s, col2);
-
- if (col2 >= colmax) { /* doesn't fit */
- size = colmax - col + col_adj;
- break;
- }
- }
- } else if ((size == 2)
- && (MB_BYTE2LEN(*s) > 1)
- && wp->w_p_wrap
- && in_win_border(wp, col)) {
- // Count the ">" in the last column.
- ++size;
- mb_added = 1;
- }
-
- // May have to add something for 'breakindent' and/or 'showbreak'
- // string at start of line.
- // Set *headp to the size of what we add.
- added = 0;
-
- if ((*p_sbr != NUL || wp->w_p_bri) && wp->w_p_wrap && (col != 0)) {
- colnr_T sbrlen = 0;
- int numberwidth = win_col_off(wp);
-
- numberextra = numberwidth;
- col += numberextra + mb_added;
-
- if (col >= (colnr_T)wp->w_width_inner) {
- col -= wp->w_width_inner;
- numberextra = wp->w_width_inner - (numberextra - win_col_off2(wp));
- if (col >= numberextra && numberextra > 0) {
- col %= numberextra;
- }
- if (*p_sbr != NUL) {
- sbrlen = (colnr_T)MB_CHARLEN(p_sbr);
- if (col >= sbrlen) {
- col -= sbrlen;
- }
- }
- if (col >= numberextra && numberextra > 0) {
- col %= numberextra;
- } else if (col > 0 && numberextra > 0) {
- col += numberwidth - win_col_off2(wp);
- }
-
- numberwidth -= win_col_off2(wp);
- }
-
- if (col == 0 || (col + size + sbrlen > (colnr_T)wp->w_width_inner)) {
- if (*p_sbr != NUL) {
- if (size + sbrlen + numberwidth > (colnr_T)wp->w_width_inner) {
- // Calculate effective window width.
- int width = (colnr_T)wp->w_width_inner - sbrlen - numberwidth;
- int prev_width = col ? ((colnr_T)wp->w_width_inner - (sbrlen + col))
- : 0;
-
- if (width <= 0) {
- width = 1;
- }
- added += ((size - prev_width) / width) * vim_strsize(p_sbr);
- if ((size - prev_width) % width) {
- // Wrapped, add another length of 'sbr'.
- added += vim_strsize(p_sbr);
- }
- } else {
- added += vim_strsize(p_sbr);
- }
- }
-
- if (wp->w_p_bri)
- added += get_breakindent_win(wp, line);
-
- size += added;
- if (col != 0) {
- added = 0;
- }
- }
- }
-
- if (headp != NULL) {
- *headp = added + mb_added;
- }
- return size;
-}
-
-/// Like win_lbr_chartabsize(), except that we know 'linebreak' is off and
-/// 'wrap' is on. This means we need to check for a double-byte character that
-/// doesn't fit at the end of the screen line.
-///
-/// @param wp
-/// @param s
-/// @param col
-/// @param headp
-///
-/// @return The number of characters take up on the screen.
-static int win_nolbr_chartabsize(win_T *wp, char_u *s, colnr_T col, int *headp)
-{
- int n;
-
- if ((*s == TAB) && (!wp->w_p_list || wp->w_p_lcs_chars.tab1)) {
- return tabstop_padding(col,
- wp->w_buffer->b_p_ts,
- wp->w_buffer->b_p_vts_array);
- }
- n = ptr2cells(s);
-
- // Add one cell for a double-width character in the last column of the
- // window, displayed with a ">".
- if ((n == 2) && (MB_BYTE2LEN(*s) > 1) && in_win_border(wp, col)) {
- if (headp != NULL) {
- *headp = 1;
- }
- return 3;
- }
- return n;
-}
-
/// Check that virtual column "vcol" is in the rightmost column of window "wp".
///
/// @param wp window
@@ -1202,12 +912,11 @@ bool in_win_border(win_T *wp, colnr_T vcol)
/// @param start
/// @param cursor
/// @param end
-void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor,
- colnr_T *end)
+void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *end)
{
colnr_T vcol;
char_u *ptr; // points to current char
- char_u *posptr; // points to char at pos->col
+ char_u *posptr; // points to char at pos->col
char_u *line; // start of the line
int incr;
int head;
@@ -1237,7 +946,7 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor,
// Also use this when 'list' is set but tabs take their normal size.
if ((!wp->w_p_list || (wp->w_p_lcs_chars.tab1 != NUL))
&& !wp->w_p_lbr
- && (*p_sbr == NUL)
+ && *get_showbreak_value(wp) == NUL
&& !wp->w_p_bri ) {
for (;;) {
head = 0;
@@ -1355,8 +1064,7 @@ colnr_T getvcol_nolist(pos_T *posp)
/// @param start
/// @param cursor
/// @param end
-void getvvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor,
- colnr_T *end)
+void getvvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *end)
{
colnr_T col;
colnr_T coladd;
@@ -1411,8 +1119,7 @@ void getvvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor,
/// @param pos2
/// @param left
/// @param right
-void getvcols(win_T *wp, pos_T *pos1, pos_T *pos2, colnr_T *left,
- colnr_T *right)
+void getvcols(win_T *wp, pos_T *pos1, pos_T *pos2, colnr_T *left, colnr_T *right)
{
colnr_T from1;
colnr_T from2;
@@ -1446,15 +1153,29 @@ void getvcols(win_T *wp, pos_T *pos1, pos_T *pos2, colnr_T *left,
/// skipwhite: skip over ' ' and '\t'.
///
-/// @param[in] q String to skip in.
+/// @param[in] p String to skip in.
///
/// @return Pointer to character after the skipped whitespace.
-char_u *skipwhite(const char_u *q)
+char_u *skipwhite(const char_u *const p)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
FUNC_ATTR_NONNULL_RET
{
- const char_u *p = q;
- while (ascii_iswhite(*p)) {
+ return skipwhite_len(p, STRLEN(p));
+}
+
+/// Like `skipwhite`, but skip up to `len` characters.
+/// @see skipwhite
+///
+/// @param[in] p String to skip in.
+/// @param[in] len Max length to skip.
+///
+/// @return Pointer to character after the skipped whitespace, or the `len`-th
+/// character in the string.
+char_u *skipwhite_len(const char_u *p, size_t len)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
+ FUNC_ATTR_NONNULL_RET
+{
+ for (; len > 0 && ascii_iswhite(*p); len--) {
p++;
}
return (char_u *)p;
@@ -1494,7 +1215,7 @@ char_u *skipdigits(const char_u *q)
/// @param q pointer to string
///
/// @return Pointer to the character after the skipped digits.
-const char* skipbin(const char *q)
+const char *skipbin(const char *q)
FUNC_ATTR_PURE
FUNC_ATTR_NONNULL_ALL
FUNC_ATTR_NONNULL_RET
@@ -1513,7 +1234,7 @@ const char* skipbin(const char *q)
///
/// @return Pointer to the character after the skipped digits and hex
/// characters.
-char_u* skiphex(char_u *q)
+char_u *skiphex(char_u *q)
{
char_u *p = q;
while (ascii_isxdigit(*p)) {
@@ -1528,7 +1249,7 @@ char_u* skiphex(char_u *q)
/// @param q
///
/// @return Pointer to the digit or (NUL after the string).
-char_u* skiptodigit(char_u *q)
+char_u *skiptodigit(char_u *q)
{
char_u *p = q;
while (*p != NUL && !ascii_isdigit(*p)) {
@@ -1543,7 +1264,7 @@ char_u* skiptodigit(char_u *q)
/// @param q pointer to string
///
/// @return Pointer to the binary character or (NUL after the string).
-const char* skiptobin(const char *q)
+const char *skiptobin(const char *q)
FUNC_ATTR_PURE
FUNC_ATTR_NONNULL_ALL
FUNC_ATTR_NONNULL_RET
@@ -1561,7 +1282,7 @@ const char* skiptobin(const char *q)
/// @param q
///
/// @return Pointer to the hex character or (NUL after the string).
-char_u* skiptohex(char_u *q)
+char_u *skiptohex(char_u *q)
{
char_u *p = q;
while (*p != NUL && !ascii_isxdigit(*p)) {
@@ -1590,7 +1311,7 @@ char_u *skiptowhite(const char_u *p)
/// @param p
///
/// @return Pointer to the next whitespace character.
-char_u* skiptowhite_esc(char_u *p) {
+char_u *skiptowhite_esc(char_u *p) {
while (*p != ' ' && *p != '\t' && *p != NUL) {
if (((*p == '\\') || (*p == Ctrl_V)) && (*(p + 1) != NUL)) {
++p;
@@ -1600,6 +1321,18 @@ char_u* skiptowhite_esc(char_u *p) {
return p;
}
+/// Skip over text until '\n' or NUL.
+///
+/// @param[in] p Text to skip over.
+///
+/// @return Pointer to the next '\n' or NUL character.
+char_u *skip_to_newline(const char_u *const p)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
+ FUNC_ATTR_NONNULL_RET
+{
+ return (char_u *)xstrchrnul((const char *)p, NL);
+}
+
/// Gets a number from a string and skips over it, signalling overflow.
///
/// @param[out] pp A pointer to a pointer to char_u.
@@ -1681,6 +1414,8 @@ bool vim_isblankline(char_u *lbuf)
/// If "prep" is not NULL, returns a flag to indicate the type of the number:
/// 0 decimal
/// '0' octal
+/// 'O' octal
+/// 'o' octal
/// 'B' bin
/// 'b' bin
/// 'X' hex
@@ -1692,68 +1427,81 @@ bool vim_isblankline(char_u *lbuf)
/// If "what" contains STR2NR_OCT recognize octal numbers.
/// If "what" contains STR2NR_HEX recognize hex numbers.
/// If "what" contains STR2NR_FORCE always assume bin/oct/hex.
+/// If "what" contains STR2NR_QUOTE ignore embedded single quotes
/// If maxlen > 0, check at a maximum maxlen chars.
+/// If strict is true, check the number strictly. return *len = 0 if fail.
///
/// @param start
/// @param prep Returns guessed type of number 0 = decimal, 'x' or 'X' is
-/// hexadecimal, '0' = octal, 'b' or 'B' is binary. When using
-/// STR2NR_FORCE is always zero.
+/// hexadecimal, '0', 'o' or 'O' is octal, 'b' or 'B' is binary.
+/// When using STR2NR_FORCE is always zero.
/// @param len Returns the detected length of number.
/// @param what Recognizes what number passed, @see ChStr2NrFlags.
/// @param nptr Returns the signed result.
/// @param unptr Returns the unsigned result.
/// @param maxlen Max length of string to check.
-void vim_str2nr(const char_u *const start, int *const prep, int *const len,
- const int what, varnumber_T *const nptr,
- uvarnumber_T *const unptr, const int maxlen)
+/// @param strict If true, fail if the number has unexpected trailing
+/// alpha-numeric chars: *len is set to 0 and nothing else is
+/// returned.
+void vim_str2nr(const char_u *const start, int *const prep, int *const len, const int what,
+ varnumber_T *const nptr, uvarnumber_T *const unptr, const int maxlen,
+ const bool strict)
FUNC_ATTR_NONNULL_ARG(1)
{
const char *ptr = (const char *)start;
#define STRING_ENDED(ptr) \
- (!(maxlen == 0 || (int)((ptr) - (const char *)start) < maxlen))
+ (!(maxlen == 0 || (int)((ptr) - (const char *)start) < maxlen))
int pre = 0; // default is decimal
const bool negative = (ptr[0] == '-');
uvarnumber_T un = 0;
+ if (len != NULL) {
+ *len = 0;
+ }
+
if (negative) {
ptr++;
}
if (what & STR2NR_FORCE) {
- // When forcing main consideration is skipping the prefix. Octal and decimal
- // numbers have no prefixes to skip. pre is not set.
- switch ((unsigned)what & (~(unsigned)STR2NR_FORCE)) {
- case STR2NR_HEX: {
- if (!STRING_ENDED(ptr + 2)
- && ptr[0] == '0'
- && (ptr[1] == 'x' || ptr[1] == 'X')
- && ascii_isxdigit(ptr[2])) {
- ptr += 2;
- }
- goto vim_str2nr_hex;
+ // When forcing main consideration is skipping the prefix. Decimal numbers
+ // have no prefixes to skip. pre is not set.
+ switch (what & ~(STR2NR_FORCE | STR2NR_QUOTE)) {
+ case STR2NR_HEX:
+ if (!STRING_ENDED(ptr + 2)
+ && ptr[0] == '0'
+ && (ptr[1] == 'x' || ptr[1] == 'X')
+ && ascii_isxdigit(ptr[2])) {
+ ptr += 2;
}
- case STR2NR_BIN: {
- if (!STRING_ENDED(ptr + 2)
- && ptr[0] == '0'
- && (ptr[1] == 'b' || ptr[1] == 'B')
- && ascii_isbdigit(ptr[2])) {
- ptr += 2;
- }
- goto vim_str2nr_bin;
- }
- case STR2NR_OCT: {
- goto vim_str2nr_oct;
- }
- case 0: {
- goto vim_str2nr_dec;
+ goto vim_str2nr_hex;
+ case STR2NR_BIN:
+ if (!STRING_ENDED(ptr + 2)
+ && ptr[0] == '0'
+ && (ptr[1] == 'b' || ptr[1] == 'B')
+ && ascii_isbdigit(ptr[2])) {
+ ptr += 2;
}
- default: {
- abort();
+ goto vim_str2nr_bin;
+ // Make STR2NR_OOCT work the same as STR2NR_OCT when forcing.
+ case STR2NR_OCT:
+ case STR2NR_OOCT:
+ case STR2NR_OCT | STR2NR_OOCT:
+ if (!STRING_ENDED(ptr + 2)
+ && ptr[0] == '0'
+ && (ptr[1] == 'o' || ptr[1] == 'O')
+ && ascii_isodigit(ptr[2])) {
+ ptr += 2;
}
+ goto vim_str2nr_oct;
+ case 0:
+ goto vim_str2nr_dec;
+ default:
+ abort();
}
- } else if ((what & (STR2NR_HEX|STR2NR_OCT|STR2NR_BIN))
- && !STRING_ENDED(ptr + 1)
- && ptr[0] == '0' && ptr[1] != '8' && ptr[1] != '9') {
+ } else if ((what & (STR2NR_HEX | STR2NR_OCT | STR2NR_OOCT | STR2NR_BIN))
+ && !STRING_ENDED(ptr + 1) && ptr[0] == '0' && ptr[1] != '8'
+ && ptr[1] != '9') {
pre = ptr[1];
// Detect hexadecimal: 0x or 0X followed by hex digit.
if ((what & STR2NR_HEX)
@@ -1771,10 +1519,18 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len,
ptr += 2;
goto vim_str2nr_bin;
}
- // Detect octal number: zero followed by octal digits without '8' or '9'.
+ // Detect octal: 0o or 0O followed by octal digits (without '8' or '9').
+ if ((what & STR2NR_OOCT)
+ && !STRING_ENDED(ptr + 2)
+ && (pre == 'O' || pre == 'o')
+ && ascii_isodigit(ptr[2])) {
+ ptr += 2;
+ goto vim_str2nr_oct;
+ }
+ // Detect old octal format: 0 followed by octal digits.
pre = 0;
if (!(what & STR2NR_OCT)
- || !('0' <= ptr[1] && ptr[1] <= '7')) {
+ || !ascii_isodigit(ptr[1])) {
goto vim_str2nr_dec;
}
for (int i = 2; !STRING_ENDED(ptr + i) && ascii_isdigit(ptr[i]); i++) {
@@ -1788,11 +1544,22 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len,
goto vim_str2nr_dec;
}
- // Do the string-to-numeric conversion "manually" to avoid sscanf quirks.
+ // Do the conversion manually to avoid sscanf() quirks.
abort(); // Should’ve used goto earlier.
#define PARSE_NUMBER(base, cond, conv) \
do { \
- while (!STRING_ENDED(ptr) && (cond)) { \
+ const char *const after_prefix = ptr; \
+ while (!STRING_ENDED(ptr)) { \
+ if ((what & STR2NR_QUOTE) && ptr > after_prefix && *ptr == '\'') { \
+ ptr++; \
+ if (!STRING_ENDED(ptr) && (cond)) { \
+ continue; \
+ } \
+ ptr--; \
+ } \
+ if (!(cond)) { \
+ break; \
+ } \
const uvarnumber_T digit = (uvarnumber_T)(conv); \
/* avoid ubsan error for overflow */ \
if (un < UVARNUMBER_MAX / base \
@@ -1809,7 +1576,7 @@ vim_str2nr_bin:
PARSE_NUMBER(2, (*ptr == '0' || *ptr == '1'), (*ptr - '0'));
goto vim_str2nr_proceed;
vim_str2nr_oct:
- PARSE_NUMBER(8, ('0' <= *ptr && *ptr <= '7'), (*ptr - '0'));
+ PARSE_NUMBER(8, (ascii_isodigit(*ptr)), (*ptr - '0'));
goto vim_str2nr_proceed;
vim_str2nr_dec:
PARSE_NUMBER(10, (ascii_isdigit(*ptr)), (*ptr - '0'));
@@ -1820,6 +1587,12 @@ vim_str2nr_hex:
#undef PARSE_NUMBER
vim_str2nr_proceed:
+ // Check for an alpha-numeric character immediately following, that is
+ // most likely a typo.
+ if (strict && ptr - (const char *)start != maxlen && ASCII_ISALNUM(*ptr)) {
+ return;
+ }
+
if (prep != NULL) {
*prep = pre;
}
diff --git a/src/nvim/charset.h b/src/nvim/charset.h
index e657ce19b6..2fef4d78a2 100644
--- a/src/nvim/charset.h
+++ b/src/nvim/charset.h
@@ -23,13 +23,20 @@ typedef enum {
STR2NR_BIN = (1 << 0), ///< Allow binary numbers.
STR2NR_OCT = (1 << 1), ///< Allow octal numbers.
STR2NR_HEX = (1 << 2), ///< Allow hexadecimal numbers.
+ STR2NR_OOCT = (1 << 3), ///< Octal with prefix "0o": 0o777
/// Force one of the above variants.
///
/// STR2NR_FORCE|STR2NR_DEC is actually not different from supplying zero
/// as flags, but still present for completeness.
- STR2NR_FORCE = (1 << 3),
+ ///
+ /// STR2NR_FORCE|STR2NR_OCT|STR2NR_OOCT is the same as STR2NR_FORCE|STR2NR_OCT
+ /// or STR2NR_FORCE|STR2NR_OOCT.
+ STR2NR_FORCE = (1 << 7),
/// Recognize all formats vim_str2nr() can recognize.
- STR2NR_ALL = STR2NR_BIN | STR2NR_OCT | STR2NR_HEX,
+ STR2NR_ALL = STR2NR_BIN | STR2NR_OCT | STR2NR_HEX | STR2NR_OOCT,
+ /// Disallow octals numbers without the 0o prefix.
+ STR2NR_NO_OCT = STR2NR_BIN | STR2NR_HEX | STR2NR_OOCT,
+ STR2NR_QUOTE = (1 << 4), ///< Ignore embedded single quotes.
} ChStr2NrFlags;
#ifdef INCLUDE_GENERATED_DECLARATIONS
diff --git a/src/nvim/context.c b/src/nvim/context.c
index 4162daa6ca..1db7938ef4 100644
--- a/src/nvim/context.c
+++ b/src/nvim/context.c
@@ -3,13 +3,13 @@
// Context: snapshot of the entire editor state as one big object/map
+#include "nvim/api/private/helpers.h"
+#include "nvim/api/vim.h"
#include "nvim/context.h"
#include "nvim/eval/encode.h"
#include "nvim/ex_docmd.h"
#include "nvim/option.h"
#include "nvim/shada.h"
-#include "nvim/api/vim.h"
-#include "nvim/api/private/helpers.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "context.c.generated.h"
diff --git a/src/nvim/cursor.c b/src/nvim/cursor.c
index 5d2210dc7d..e334fd166e 100644
--- a/src/nvim/cursor.c
+++ b/src/nvim/cursor.c
@@ -1,24 +1,25 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
-#include <stdbool.h>
#include <inttypes.h>
+#include <stdbool.h>
+#include "nvim/ascii.h"
#include "nvim/assert.h"
#include "nvim/change.h"
-#include "nvim/cursor.h"
#include "nvim/charset.h"
+#include "nvim/cursor.h"
+#include "nvim/extmark.h"
#include "nvim/fold.h"
+#include "nvim/mark.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/misc1.h"
#include "nvim/move.h"
+#include "nvim/plines.h"
#include "nvim/screen.h"
-#include "nvim/extmark.h"
#include "nvim/state.h"
#include "nvim/vim.h"
-#include "nvim/ascii.h"
-#include "nvim/mark.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "cursor.c.generated.h"
@@ -62,7 +63,7 @@ int coladvance_force(colnr_T wcol)
if (wcol == MAXCOL) {
curwin->w_valid &= ~VALID_VIRTCOL;
} else {
- /* Virtcol is valid */
+ // Virtcol is valid
curwin->w_valid |= VALID_VIRTCOL;
curwin->w_virtcol = wcol;
}
@@ -82,27 +83,25 @@ int coladvance(colnr_T wcol)
{
int rc = getvpos(&curwin->w_cursor, wcol);
- if (wcol == MAXCOL || rc == FAIL)
+ if (wcol == MAXCOL || rc == FAIL) {
curwin->w_valid &= ~VALID_VIRTCOL;
- else if (*get_cursor_pos_ptr() != TAB) {
- /* Virtcol is valid when not on a TAB */
+ } else if (*get_cursor_pos_ptr() != TAB) {
+ // Virtcol is valid when not on a TAB
curwin->w_valid |= VALID_VIRTCOL;
curwin->w_virtcol = wcol;
}
return rc;
}
-static int coladvance2(
- pos_T *pos,
- bool addspaces, // change the text to achieve our goal?
- bool finetune, // change char offset for the exact column
- colnr_T wcol_arg // column to move to (can be negative)
-)
+/// @param addspaces change the text to achieve our goal?
+/// @param finetune change char offset for the exact column
+/// @param wcol_arg column to move to (can be negative)
+static int coladvance2(pos_T *pos, bool addspaces, bool finetune, colnr_T wcol_arg)
{
colnr_T wcol = wcol_arg;
int idx;
- char_u *ptr;
- char_u *line;
+ char_u *ptr;
+ char_u *line;
colnr_T col = 0;
int csize = 0;
int one_more;
@@ -120,8 +119,9 @@ static int coladvance2(
if ((addspaces || finetune) && !VIsual_active) {
curwin->w_curswant = linetabsize(line) + one_more;
- if (curwin->w_curswant > 0)
+ if (curwin->w_curswant > 0) {
--curwin->w_curswant;
+ }
}
} else {
int width = curwin->w_width_inner - win_col_off(curwin);
@@ -129,10 +129,12 @@ static int coladvance2(
if (finetune
&& curwin->w_p_wrap
&& curwin->w_width_inner != 0
- && wcol >= (colnr_T)width) {
+ && wcol >= (colnr_T)width
+ && width > 0) {
csize = linetabsize(line);
- if (csize > 0)
+ if (csize > 0) {
csize--;
+ }
if (wcol / width > (colnr_T)csize / width
&& ((State & INSERT) == 0 || (int)wcol > csize + 1)) {
@@ -146,7 +148,7 @@ static int coladvance2(
ptr = line;
while (col <= wcol && *ptr != NUL) {
- /* Count a tab for what it's worth (if list mode not on) */
+ // Count a tab for what it's worth (if list mode not on)
csize = win_lbr_chartabsize(curwin, line, ptr, col, &head);
MB_PTR_ADV(ptr);
col += csize;
@@ -160,7 +162,7 @@ static int coladvance2(
*/
if (col > wcol || (!virtual_active() && one_more == 0)) {
idx -= 1;
- /* Don't count the chars from 'showbreak'. */
+ // Don't count the chars from 'showbreak'.
csize -= head;
col -= csize;
}
@@ -173,7 +175,7 @@ static int coladvance2(
* filled with spaces. */
if (line[idx] == NUL) {
- /* Append spaces */
+ // Append spaces
int correct = wcol - col;
size_t newline_size;
STRICT_ADD(idx, correct, &newline_size, size_t);
@@ -186,13 +188,14 @@ static int coladvance2(
idx += correct;
col = wcol;
} else {
- /* Break a tab */
+ // Break a tab
int linelen = (int)STRLEN(line);
- int correct = wcol - col - csize + 1; /* negative!! */
- char_u *newline;
+ int correct = wcol - col - csize + 1; // negative!!
+ char_u *newline;
- if (-correct > csize)
+ if (-correct > csize) {
return FAIL;
+ }
size_t n;
STRICT_ADD(linelen - 1, csize, &n, size_t);
@@ -214,16 +217,17 @@ static int coladvance2(
}
}
- if (idx < 0)
+ if (idx < 0) {
pos->col = 0;
- else
+ } else {
pos->col = idx;
+ }
pos->coladd = 0;
if (finetune) {
if (wcol == MAXCOL) {
- /* The width of the last character is used to set coladd. */
+ // The width of the last character is used to set coladd.
if (!one_more) {
colnr_T scol, ecol;
@@ -317,15 +321,15 @@ void check_pos(buf_T *buf, pos_T *pos)
colnr_T len;
if (pos->lnum > buf->b_ml.ml_line_count) {
- pos->lnum = buf->b_ml.ml_line_count;
+ pos->lnum = buf->b_ml.ml_line_count;
}
if (pos->col > 0) {
- line = ml_get_buf(buf, pos->lnum, false);
- len = (colnr_T)STRLEN(line);
- if (pos->col > len) {
- pos->col = len;
- }
+ line = ml_get_buf(buf, pos->lnum, false);
+ len = (colnr_T)STRLEN(line);
+ if (pos->col > len) {
+ pos->col = len;
+ }
}
}
@@ -338,11 +342,13 @@ void check_cursor_lnum(void)
/* If there is a closed fold at the end of the file, put the cursor in
* its first line. Otherwise in the last line. */
if (!hasFolding(curbuf->b_ml.ml_line_count,
- &curwin->w_cursor.lnum, NULL))
+ &curwin->w_cursor.lnum, NULL)) {
curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+ }
}
- if (curwin->w_cursor.lnum <= 0)
+ if (curwin->w_cursor.lnum <= 0) {
curwin->w_cursor.lnum = 1;
+ }
}
/*
@@ -428,8 +434,9 @@ void adjust_cursor_col(void)
{
if (curwin->w_cursor.col > 0
&& (!VIsual_active || *p_sel == 'o')
- && gchar_cursor() == NUL)
+ && gchar_cursor() == NUL) {
--curwin->w_cursor.col;
+ }
}
/*
@@ -471,14 +478,15 @@ bool leftcol_changed(void)
coladvance(s - 1);
} else if (s < curwin->w_leftcol) {
retval = true;
- if (coladvance(e + 1) == FAIL) { /* there isn't another character */
- curwin->w_leftcol = s; /* adjust w_leftcol instead */
+ if (coladvance(e + 1) == FAIL) { // there isn't another character
+ curwin->w_leftcol = s; // adjust w_leftcol instead
changed_cline_bef_curs();
}
}
- if (retval)
+ if (retval) {
curwin->w_set_curswant = true;
+ }
redraw_later(curwin, NOT_VALID);
return retval;
}
diff --git a/src/nvim/cursor_shape.c b/src/nvim/cursor_shape.c
index 0d21080aa5..128bc480da 100644
--- a/src/nvim/cursor_shape.c
+++ b/src/nvim/cursor_shape.c
@@ -3,15 +3,16 @@
#include <assert.h>
#include <stdint.h>
-#include "nvim/vim.h"
+
+#include "nvim/api/private/helpers.h"
#include "nvim/ascii.h"
+#include "nvim/charset.h"
#include "nvim/cursor_shape.h"
#include "nvim/ex_getln.h"
-#include "nvim/charset.h"
#include "nvim/strings.h"
#include "nvim/syntax.h"
-#include "nvim/api/private/helpers.h"
#include "nvim/ui.h"
+#include "nvim/vim.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "cursor_shape.c.generated.h"
@@ -56,10 +57,14 @@ Array mode_style_array(void)
if (cur->used_for & SHAPE_CURSOR) {
String shape_str;
switch (cur->shape) {
- case SHAPE_BLOCK: shape_str = cstr_to_string("block"); break;
- case SHAPE_VER: shape_str = cstr_to_string("vertical"); break;
- case SHAPE_HOR: shape_str = cstr_to_string("horizontal"); break;
- default: shape_str = cstr_to_string("unknown");
+ case SHAPE_BLOCK:
+ shape_str = cstr_to_string("block"); break;
+ case SHAPE_VER:
+ shape_str = cstr_to_string("vertical"); break;
+ case SHAPE_HOR:
+ shape_str = cstr_to_string("horizontal"); break;
+ default:
+ shape_str = cstr_to_string("unknown");
}
PUT(dic, "cursor_shape", STRING_OBJ(shape_str));
PUT(dic, "cell_percentage", INTEGER_OBJ(cur->percentage));
@@ -90,12 +95,12 @@ Array mode_style_array(void)
/// @returns error message for an illegal option, NULL otherwise.
char_u *parse_shape_opt(int what)
{
- char_u *modep;
- char_u *colonp;
- char_u *commap;
- char_u *slashp;
- char_u *p = NULL;
- char_u *endp;
+ char_u *modep;
+ char_u *colonp;
+ char_u *commap;
+ char_u *slashp;
+ char_u *p = NULL;
+ char_u *endp;
int idx = 0; // init for GCC
int all_idx;
int len;
@@ -142,14 +147,18 @@ char_u *parse_shape_opt(int what)
if (len == 1 && TOLOWER_ASC(modep[0]) == 'a') {
all_idx = SHAPE_IDX_COUNT - 1;
} else {
- for (idx = 0; idx < SHAPE_IDX_COUNT; ++idx)
- if (STRNICMP(modep, shape_table[idx].name, len) == 0)
+ for (idx = 0; idx < SHAPE_IDX_COUNT; ++idx) {
+ if (STRNICMP(modep, shape_table[idx].name, len) == 0) {
break;
+ }
+ }
if (idx == SHAPE_IDX_COUNT
- || (shape_table[idx].used_for & what) == 0)
+ || (shape_table[idx].used_for & what) == 0) {
return (char_u *)N_("E546: Illegal mode");
- if (len == 2 && modep[0] == 'v' && modep[1] == 'e')
+ }
+ if (len == 2 && modep[0] == 'v' && modep[1] == 'e') {
found_ve = true;
+ }
}
modep += len + 1;
}
@@ -158,7 +167,7 @@ char_u *parse_shape_opt(int what)
idx = all_idx--;
}
- /* Parse the part after the colon */
+ // Parse the part after the colon
for (p = colonp + 1; *p && *p != ','; ) {
{
/*
@@ -166,20 +175,22 @@ char_u *parse_shape_opt(int what)
*/
i = *p;
len = 0;
- if (STRNICMP(p, "ver", 3) == 0)
+ if (STRNICMP(p, "ver", 3) == 0) {
len = 3;
- else if (STRNICMP(p, "hor", 3) == 0)
+ } else if (STRNICMP(p, "hor", 3) == 0) {
len = 3;
- else if (STRNICMP(p, "blinkwait", 9) == 0)
+ } else if (STRNICMP(p, "blinkwait", 9) == 0) {
len = 9;
- else if (STRNICMP(p, "blinkon", 7) == 0)
+ } else if (STRNICMP(p, "blinkon", 7) == 0) {
len = 7;
- else if (STRNICMP(p, "blinkoff", 8) == 0)
+ } else if (STRNICMP(p, "blinkoff", 8) == 0) {
len = 8;
+ }
if (len != 0) {
p += len;
- if (!ascii_isdigit(*p))
+ if (!ascii_isdigit(*p)) {
return (char_u *)N_("E548: digit expected");
+ }
int n = getdigits_int(&p, false, 0);
if (len == 3) { // "ver" or "hor"
if (n == 0) {
@@ -194,44 +205,49 @@ char_u *parse_shape_opt(int what)
shape_table[idx].percentage = n;
}
} else if (round == 2) {
- if (len == 9)
+ if (len == 9) {
shape_table[idx].blinkwait = n;
- else if (len == 7)
+ } else if (len == 7) {
shape_table[idx].blinkon = n;
- else
+ } else {
shape_table[idx].blinkoff = n;
+ }
}
} else if (STRNICMP(p, "block", 5) == 0) {
- if (round == 2)
+ if (round == 2) {
shape_table[idx].shape = SHAPE_BLOCK;
+ }
p += 5;
- } else { /* must be a highlight group name then */
+ } else { // must be a highlight group name then
endp = vim_strchr(p, '-');
- if (commap == NULL) { /* last part */
- if (endp == NULL)
- endp = p + STRLEN(p); /* find end of part */
+ if (commap == NULL) { // last part
+ if (endp == NULL) {
+ endp = p + STRLEN(p); // find end of part
+ }
} else if (endp > commap || endp == NULL) {
endp = commap;
}
slashp = vim_strchr(p, '/');
if (slashp != NULL && slashp < endp) {
- /* "group/langmap_group" */
+ // "group/langmap_group"
i = syn_check_group(p, (int)(slashp - p));
p = slashp + 1;
}
if (round == 2) {
shape_table[idx].id = syn_check_group(p,
- (int)(endp - p));
+ (int)(endp - p));
shape_table[idx].id_lm = shape_table[idx].id;
- if (slashp != NULL && slashp < endp)
+ if (slashp != NULL && slashp < endp) {
shape_table[idx].id = i;
+ }
}
p = endp;
}
- } /* if (what != SHAPE_MOUSE) */
+ } // if (what != SHAPE_MOUSE)
- if (*p == '-')
+ if (*p == '-') {
++p;
+ }
}
}
modep = p;
@@ -241,7 +257,7 @@ char_u *parse_shape_opt(int what)
}
}
- /* If the 's' flag is not given, use the 'v' cursor for 's' */
+ // If the 's' flag is not given, use the 'v' cursor for 's'
if (!found_ve) {
{
shape_table[SHAPE_IDX_VE].shape = shape_table[SHAPE_IDX_V].shape;
diff --git a/src/nvim/debugger.c b/src/nvim/debugger.c
new file mode 100644
index 0000000000..0ddf163176
--- /dev/null
+++ b/src/nvim/debugger.c
@@ -0,0 +1,837 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
+/// @file debugger.c
+///
+/// Vim script debugger functions
+
+#include "nvim/ascii.h"
+#include "nvim/charset.h"
+#include "nvim/debugger.h"
+#include "nvim/eval.h"
+#include "nvim/ex_docmd.h"
+#include "nvim/ex_getln.h"
+#include "nvim/fileio.h"
+#include "nvim/getchar.h"
+#include "nvim/globals.h"
+#include "nvim/os/os.h"
+#include "nvim/pos.h"
+#include "nvim/regexp.h"
+#include "nvim/screen.h"
+#include "nvim/types.h"
+#include "nvim/vim.h"
+
+/// batch mode debugging: don't save and restore typeahead.
+static bool debug_greedy = false;
+
+static char *debug_oldval = NULL; // old and newval for debug expressions
+static char *debug_newval = NULL;
+
+/// The list of breakpoints: dbg_breakp.
+/// This is a grow-array of structs.
+struct debuggy {
+ int dbg_nr; ///< breakpoint number
+ int dbg_type; ///< DBG_FUNC or DBG_FILE or DBG_EXPR
+ char_u *dbg_name; ///< function, expression or file name
+ regprog_T *dbg_prog; ///< regexp program
+ linenr_T dbg_lnum; ///< line number in function or file
+ int dbg_forceit; ///< ! used
+ typval_T *dbg_val; ///< last result of watchexpression
+ int dbg_level; ///< stored nested level for expr
+};
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "debugger.c.generated.h"
+#endif
+
+/// Debug mode. Repeatedly get Ex commands, until told to continue normal
+/// execution.
+void do_debug(char_u *cmd)
+{
+ int save_msg_scroll = msg_scroll;
+ int save_State = State;
+ int save_did_emsg = did_emsg;
+ const bool save_cmd_silent = cmd_silent;
+ int save_msg_silent = msg_silent;
+ int save_emsg_silent = emsg_silent;
+ bool save_redir_off = redir_off;
+ tasave_T typeaheadbuf;
+ bool typeahead_saved = false;
+ int save_ignore_script = 0;
+ int save_ex_normal_busy;
+ int n;
+ char_u *cmdline = NULL;
+ char_u *p;
+ char *tail = NULL;
+ static int last_cmd = 0;
+#define CMD_CONT 1
+#define CMD_NEXT 2
+#define CMD_STEP 3
+#define CMD_FINISH 4
+#define CMD_QUIT 5
+#define CMD_INTERRUPT 6
+#define CMD_BACKTRACE 7
+#define CMD_FRAME 8
+#define CMD_UP 9
+#define CMD_DOWN 10
+
+
+ RedrawingDisabled++; // don't redisplay the window
+ no_wait_return++; // don't wait for return
+ did_emsg = false; // don't use error from debugged stuff
+ cmd_silent = false; // display commands
+ msg_silent = false; // display messages
+ emsg_silent = false; // display error messages
+ redir_off = true; // don't redirect debug commands
+
+ State = NORMAL;
+ debug_mode = true;
+
+ if (!debug_did_msg) {
+ MSG(_("Entering Debug mode. Type \"cont\" to continue."));
+ }
+ if (debug_oldval != NULL) {
+ smsg(_("Oldval = \"%s\""), debug_oldval);
+ xfree(debug_oldval);
+ debug_oldval = NULL;
+ }
+ if (debug_newval != NULL) {
+ smsg(_("Newval = \"%s\""), debug_newval);
+ xfree(debug_newval);
+ debug_newval = NULL;
+ }
+ if (sourcing_name != NULL) {
+ msg(sourcing_name);
+ }
+ if (sourcing_lnum != 0) {
+ smsg(_("line %" PRId64 ": %s"), (int64_t)sourcing_lnum, cmd);
+ } else {
+ smsg(_("cmd: %s"), cmd);
+ }
+ // Repeat getting a command and executing it.
+ for (;; ) {
+ msg_scroll = true;
+ need_wait_return = false;
+ // Save the current typeahead buffer and replace it with an empty one.
+ // This makes sure we get input from the user here and don't interfere
+ // with the commands being executed. Reset "ex_normal_busy" to avoid
+ // the side effects of using ":normal". Save the stuff buffer and make
+ // it empty. Set ignore_script to avoid reading from script input.
+ save_ex_normal_busy = ex_normal_busy;
+ ex_normal_busy = 0;
+ if (!debug_greedy) {
+ save_typeahead(&typeaheadbuf);
+ typeahead_saved = true;
+ save_ignore_script = ignore_script;
+ ignore_script = true;
+ }
+
+ xfree(cmdline);
+ cmdline = (char_u *)getcmdline_prompt('>', NULL, 0, EXPAND_NOTHING, NULL,
+ CALLBACK_NONE);
+
+ if (typeahead_saved) {
+ restore_typeahead(&typeaheadbuf);
+ ignore_script = save_ignore_script;
+ }
+ ex_normal_busy = save_ex_normal_busy;
+
+ cmdline_row = msg_row;
+ msg_starthere();
+ if (cmdline != NULL) {
+ // If this is a debug command, set "last_cmd".
+ // If not, reset "last_cmd".
+ // For a blank line use previous command.
+ p = skipwhite(cmdline);
+ if (*p != NUL) {
+ switch (*p) {
+ case 'c':
+ last_cmd = CMD_CONT;
+ tail = "ont";
+ break;
+ case 'n':
+ last_cmd = CMD_NEXT;
+ tail = "ext";
+ break;
+ case 's':
+ last_cmd = CMD_STEP;
+ tail = "tep";
+ break;
+ case 'f':
+ last_cmd = 0;
+ if (p[1] == 'r') {
+ last_cmd = CMD_FRAME;
+ tail = "rame";
+ } else {
+ last_cmd = CMD_FINISH;
+ tail = "inish";
+ }
+ break;
+ case 'q':
+ last_cmd = CMD_QUIT;
+ tail = "uit";
+ break;
+ case 'i':
+ last_cmd = CMD_INTERRUPT;
+ tail = "nterrupt";
+ break;
+ case 'b':
+ last_cmd = CMD_BACKTRACE;
+ if (p[1] == 't') {
+ tail = "t";
+ } else {
+ tail = "acktrace";
+ }
+ break;
+ case 'w':
+ last_cmd = CMD_BACKTRACE;
+ tail = "here";
+ break;
+ case 'u':
+ last_cmd = CMD_UP;
+ tail = "p";
+ break;
+ case 'd':
+ last_cmd = CMD_DOWN;
+ tail = "own";
+ break;
+ default:
+ last_cmd = 0;
+ }
+ if (last_cmd != 0) {
+ // Check that the tail matches.
+ p++;
+ while (*p != NUL && *p == *tail) {
+ p++;
+ tail++;
+ }
+ if (ASCII_ISALPHA(*p) && last_cmd != CMD_FRAME) {
+ last_cmd = 0;
+ }
+ }
+ }
+
+ if (last_cmd != 0) {
+ // Execute debug command: decided where to break next and return.
+ switch (last_cmd) {
+ case CMD_CONT:
+ debug_break_level = -1;
+ break;
+ case CMD_NEXT:
+ debug_break_level = ex_nesting_level;
+ break;
+ case CMD_STEP:
+ debug_break_level = 9999;
+ break;
+ case CMD_FINISH:
+ debug_break_level = ex_nesting_level - 1;
+ break;
+ case CMD_QUIT:
+ got_int = true;
+ debug_break_level = -1;
+ break;
+ case CMD_INTERRUPT:
+ got_int = true;
+ debug_break_level = 9999;
+ // Do not repeat ">interrupt" cmd, continue stepping.
+ last_cmd = CMD_STEP;
+ break;
+ case CMD_BACKTRACE:
+ do_showbacktrace(cmd);
+ continue;
+ case CMD_FRAME:
+ if (*p == NUL) {
+ do_showbacktrace(cmd);
+ } else {
+ p = skipwhite(p);
+ do_setdebugtracelevel(p);
+ }
+ continue;
+ case CMD_UP:
+ debug_backtrace_level++;
+ do_checkbacktracelevel();
+ continue;
+ case CMD_DOWN:
+ debug_backtrace_level--;
+ do_checkbacktracelevel();
+ continue;
+ }
+ // Going out reset backtrace_level
+ debug_backtrace_level = 0;
+ break;
+ }
+
+ // don't debug this command
+ n = debug_break_level;
+ debug_break_level = -1;
+ (void)do_cmdline(cmdline, getexline, NULL,
+ DOCMD_VERBOSE|DOCMD_EXCRESET);
+ debug_break_level = n;
+ }
+ lines_left = (int)(Rows - 1);
+ }
+ xfree(cmdline);
+
+ RedrawingDisabled--;
+ no_wait_return--;
+ redraw_all_later(NOT_VALID);
+ need_wait_return = false;
+ msg_scroll = save_msg_scroll;
+ lines_left = (int)(Rows - 1);
+ State = save_State;
+ debug_mode = false;
+ did_emsg = save_did_emsg;
+ cmd_silent = save_cmd_silent;
+ msg_silent = save_msg_silent;
+ emsg_silent = save_emsg_silent;
+ redir_off = save_redir_off;
+
+ // Only print the message again when typing a command before coming back here.
+ debug_did_msg = true;
+}
+
+static int get_maxbacktrace_level(void)
+{
+ int maxbacktrace = 0;
+
+ if (sourcing_name != NULL) {
+ char *p = (char *)sourcing_name;
+ char *q;
+ while ((q = strstr(p, "..")) != NULL) {
+ p = q + 2;
+ maxbacktrace++;
+ }
+ }
+ return maxbacktrace;
+}
+
+static void do_setdebugtracelevel(char_u *arg)
+{
+ int level = atoi((char *)arg);
+ if (*arg == '+' || level < 0) {
+ debug_backtrace_level += level;
+ } else {
+ debug_backtrace_level = level;
+ }
+
+ do_checkbacktracelevel();
+}
+
+static void do_checkbacktracelevel(void)
+{
+ if (debug_backtrace_level < 0) {
+ debug_backtrace_level = 0;
+ MSG(_("frame is zero"));
+ } else {
+ int max = get_maxbacktrace_level();
+ if (debug_backtrace_level > max) {
+ debug_backtrace_level = max;
+ smsg(_("frame at highest level: %d"), max);
+ }
+ }
+}
+
+static void do_showbacktrace(char_u *cmd)
+{
+ if (sourcing_name != NULL) {
+ int i = 0;
+ int max = get_maxbacktrace_level();
+ char *cur = (char *)sourcing_name;
+ while (!got_int) {
+ char *next = strstr(cur, "..");
+ if (next != NULL) {
+ *next = NUL;
+ }
+ if (i == max - debug_backtrace_level) {
+ smsg("->%d %s", max - i, cur);
+ } else {
+ smsg(" %d %s", max - i, cur);
+ }
+ i++;
+ if (next == NULL) {
+ break;
+ }
+ *next = '.';
+ cur = next + 2;
+ }
+ }
+ if (sourcing_lnum != 0) {
+ smsg(_("line %" PRId64 ": %s"), (int64_t)sourcing_lnum, cmd);
+ } else {
+ smsg(_("cmd: %s"), cmd);
+ }
+}
+
+/// ":debug".
+void ex_debug(exarg_T *eap)
+{
+ int debug_break_level_save = debug_break_level;
+
+ debug_break_level = 9999;
+ do_cmdline_cmd((char *)eap->arg);
+ debug_break_level = debug_break_level_save;
+}
+
+static char_u *debug_breakpoint_name = NULL;
+static linenr_T debug_breakpoint_lnum;
+
+/// When debugging or a breakpoint is set on a skipped command, no debug prompt
+/// is shown by do_one_cmd(). This situation is indicated by debug_skipped, and
+/// debug_skipped_name is then set to the source name in the breakpoint case. If
+/// a skipped command decides itself that a debug prompt should be displayed, it
+/// can do so by calling dbg_check_skipped().
+static int debug_skipped;
+static char_u *debug_skipped_name;
+
+/// Go to debug mode when a breakpoint was encountered or "ex_nesting_level" is
+/// at or below the break level. But only when the line is actually
+/// executed. Return true and set breakpoint_name for skipped commands that
+/// decide to execute something themselves.
+/// Called from do_one_cmd() before executing a command.
+void dbg_check_breakpoint(exarg_T *eap)
+{
+ char_u *p;
+
+ debug_skipped = false;
+ if (debug_breakpoint_name != NULL) {
+ if (!eap->skip) {
+ // replace K_SNR with "<SNR>"
+ if (debug_breakpoint_name[0] == K_SPECIAL
+ && debug_breakpoint_name[1] == KS_EXTRA
+ && debug_breakpoint_name[2] == (int)KE_SNR) {
+ p = (char_u *)"<SNR>";
+ } else {
+ p = (char_u *)"";
+ }
+ smsg(_("Breakpoint in \"%s%s\" line %" PRId64),
+ p,
+ debug_breakpoint_name + (*p == NUL ? 0 : 3),
+ (int64_t)debug_breakpoint_lnum);
+ debug_breakpoint_name = NULL;
+ do_debug(eap->cmd);
+ } else {
+ debug_skipped = true;
+ debug_skipped_name = debug_breakpoint_name;
+ debug_breakpoint_name = NULL;
+ }
+ } else if (ex_nesting_level <= debug_break_level) {
+ if (!eap->skip) {
+ do_debug(eap->cmd);
+ } else {
+ debug_skipped = true;
+ debug_skipped_name = NULL;
+ }
+ }
+}
+
+/// Go to debug mode if skipped by dbg_check_breakpoint() because eap->skip was
+/// set.
+///
+/// @return true when the debug mode is entered this time.
+bool dbg_check_skipped(exarg_T *eap)
+{
+ int prev_got_int;
+
+ if (debug_skipped) {
+ // Save the value of got_int and reset it. We don't want a previous
+ // interruption cause flushing the input buffer.
+ prev_got_int = got_int;
+ got_int = false;
+ debug_breakpoint_name = debug_skipped_name;
+ // eap->skip is true
+ eap->skip = false;
+ dbg_check_breakpoint(eap);
+ eap->skip = true;
+ got_int |= prev_got_int;
+ return true;
+ }
+ return false;
+}
+
+static garray_T dbg_breakp = { 0, 0, sizeof(struct debuggy), 4, NULL };
+#define BREAKP(idx) (((struct debuggy *)dbg_breakp.ga_data)[idx])
+#define DEBUGGY(gap, idx) (((struct debuggy *)gap->ga_data)[idx])
+static int last_breakp = 0; // nr of last defined breakpoint
+
+// Profiling uses file and func names similar to breakpoints.
+static garray_T prof_ga = { 0, 0, sizeof(struct debuggy), 4, NULL };
+#define DBG_FUNC 1
+#define DBG_FILE 2
+#define DBG_EXPR 3
+
+/// Evaluate the "bp->dbg_name" expression and return the result.
+/// Disables error messages.
+static typval_T *eval_expr_no_emsg(struct debuggy *const bp)
+ FUNC_ATTR_NONNULL_ALL
+{
+ // Disable error messages, a bad expression would make Vim unusable.
+ emsg_off++;
+ typval_T *const tv = eval_expr(bp->dbg_name);
+ emsg_off--;
+ return tv;
+}
+
+/// Parse the arguments of ":profile", ":breakadd" or ":breakdel" and put them
+/// in the entry just after the last one in dbg_breakp. Note that "dbg_name"
+/// is allocated.
+/// Returns FAIL for failure.
+///
+/// @param arg
+/// @param gap either &dbg_breakp or &prof_ga
+static int dbg_parsearg(char_u *arg, garray_T *gap)
+{
+ char_u *p = arg;
+ char_u *q;
+ struct debuggy *bp;
+ bool here = false;
+
+ ga_grow(gap, 1);
+
+ bp = &DEBUGGY(gap, gap->ga_len);
+
+ // Find "func" or "file".
+ if (STRNCMP(p, "func", 4) == 0) {
+ bp->dbg_type = DBG_FUNC;
+ } else if (STRNCMP(p, "file", 4) == 0) {
+ bp->dbg_type = DBG_FILE;
+ } else if (gap != &prof_ga && STRNCMP(p, "here", 4) == 0) {
+ if (curbuf->b_ffname == NULL) {
+ EMSG(_(e_noname));
+ return FAIL;
+ }
+ bp->dbg_type = DBG_FILE;
+ here = true;
+ } else if (gap != &prof_ga && STRNCMP(p, "expr", 4) == 0) {
+ bp->dbg_type = DBG_EXPR;
+ } else {
+ EMSG2(_(e_invarg2), p);
+ return FAIL;
+ }
+ p = skipwhite(p + 4);
+
+ // Find optional line number.
+ if (here) {
+ bp->dbg_lnum = curwin->w_cursor.lnum;
+ } else if (gap != &prof_ga && ascii_isdigit(*p)) {
+ bp->dbg_lnum = getdigits_long(&p, true, 0);
+ p = skipwhite(p);
+ } else {
+ bp->dbg_lnum = 0;
+ }
+
+ // Find the function or file name. Don't accept a function name with ().
+ if ((!here && *p == NUL)
+ || (here && *p != NUL)
+ || (bp->dbg_type == DBG_FUNC && strstr((char *)p, "()") != NULL)) {
+ EMSG2(_(e_invarg2), arg);
+ return FAIL;
+ }
+
+ if (bp->dbg_type == DBG_FUNC) {
+ bp->dbg_name = vim_strsave(p);
+ } else if (here) {
+ bp->dbg_name = vim_strsave(curbuf->b_ffname);
+ } else if (bp->dbg_type == DBG_EXPR) {
+ bp->dbg_name = vim_strsave(p);
+ bp->dbg_val = eval_expr_no_emsg(bp);
+ } else {
+ // Expand the file name in the same way as do_source(). This means
+ // doing it twice, so that $DIR/file gets expanded when $DIR is
+ // "~/dir".
+ q = expand_env_save(p);
+ if (q == NULL) {
+ return FAIL;
+ }
+ p = expand_env_save(q);
+ xfree(q);
+ if (p == NULL) {
+ return FAIL;
+ }
+ if (*p != '*') {
+ bp->dbg_name = (char_u *)fix_fname((char *)p);
+ xfree(p);
+ } else {
+ bp->dbg_name = p;
+ }
+ }
+
+ if (bp->dbg_name == NULL) {
+ return FAIL;
+ }
+ return OK;
+}
+
+/// ":breakadd". Also used for ":profile".
+void ex_breakadd(exarg_T *eap)
+{
+ struct debuggy *bp;
+ garray_T *gap;
+
+ gap = &dbg_breakp;
+ if (eap->cmdidx == CMD_profile) {
+ gap = &prof_ga;
+ }
+
+ if (dbg_parsearg(eap->arg, gap) == OK) {
+ bp = &DEBUGGY(gap, gap->ga_len);
+ bp->dbg_forceit = eap->forceit;
+
+ if (bp->dbg_type != DBG_EXPR) {
+ char_u *pat = file_pat_to_reg_pat(bp->dbg_name, NULL, NULL, false);
+ if (pat != NULL) {
+ bp->dbg_prog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
+ xfree(pat);
+ }
+ if (pat == NULL || bp->dbg_prog == NULL) {
+ xfree(bp->dbg_name);
+ } else {
+ if (bp->dbg_lnum == 0) { // default line number is 1
+ bp->dbg_lnum = 1;
+ }
+ if (eap->cmdidx != CMD_profile) {
+ DEBUGGY(gap, gap->ga_len).dbg_nr = ++last_breakp;
+ debug_tick++;
+ }
+ gap->ga_len++;
+ }
+ } else {
+ // DBG_EXPR
+ DEBUGGY(gap, gap->ga_len++).dbg_nr = ++last_breakp;
+ debug_tick++;
+ }
+ }
+}
+
+/// ":debuggreedy".
+void ex_debuggreedy(exarg_T *eap)
+{
+ if (eap->addr_count == 0 || eap->line2 != 0) {
+ debug_greedy = true;
+ } else {
+ debug_greedy = false;
+ }
+}
+
+/// ":breakdel" and ":profdel".
+void ex_breakdel(exarg_T *eap)
+{
+ struct debuggy *bp, *bpi;
+ int nr;
+ int todel = -1;
+ bool del_all = false;
+ linenr_T best_lnum = 0;
+ garray_T *gap;
+
+ gap = &dbg_breakp;
+ if (eap->cmdidx == CMD_profdel) {
+ gap = &prof_ga;
+ }
+
+ if (ascii_isdigit(*eap->arg)) {
+ // ":breakdel {nr}"
+ nr = atoi((char *)eap->arg);
+ for (int i = 0; i < gap->ga_len; i++) {
+ if (DEBUGGY(gap, i).dbg_nr == nr) {
+ todel = i;
+ break;
+ }
+ }
+ } else if (*eap->arg == '*') {
+ todel = 0;
+ del_all = true;
+ } else {
+ // ":breakdel {func|file|expr} [lnum] {name}"
+ if (dbg_parsearg(eap->arg, gap) == FAIL) {
+ return;
+ }
+ bp = &DEBUGGY(gap, gap->ga_len);
+ for (int i = 0; i < gap->ga_len; i++) {
+ bpi = &DEBUGGY(gap, i);
+ if (bp->dbg_type == bpi->dbg_type
+ && STRCMP(bp->dbg_name, bpi->dbg_name) == 0
+ && (bp->dbg_lnum == bpi->dbg_lnum
+ || (bp->dbg_lnum == 0
+ && (best_lnum == 0
+ || bpi->dbg_lnum < best_lnum)))) {
+ todel = i;
+ best_lnum = bpi->dbg_lnum;
+ }
+ }
+ xfree(bp->dbg_name);
+ }
+
+ if (todel < 0) {
+ EMSG2(_("E161: Breakpoint not found: %s"), eap->arg);
+ } else {
+ while (!GA_EMPTY(gap)) {
+ xfree(DEBUGGY(gap, todel).dbg_name);
+ if (DEBUGGY(gap, todel).dbg_type == DBG_EXPR
+ && DEBUGGY(gap, todel).dbg_val != NULL) {
+ tv_free(DEBUGGY(gap, todel).dbg_val);
+ }
+ vim_regfree(DEBUGGY(gap, todel).dbg_prog);
+ gap->ga_len--;
+ if (todel < gap->ga_len) {
+ memmove(&DEBUGGY(gap, todel), &DEBUGGY(gap, todel + 1),
+ (size_t)(gap->ga_len - todel) * sizeof(struct debuggy));
+ }
+ if (eap->cmdidx == CMD_breakdel) {
+ debug_tick++;
+ }
+ if (!del_all) {
+ break;
+ }
+ }
+
+ // If all breakpoints were removed clear the array.
+ if (GA_EMPTY(gap)) {
+ ga_clear(gap);
+ }
+ }
+}
+
+/// ":breaklist".
+void ex_breaklist(exarg_T *eap)
+{
+ struct debuggy *bp;
+
+ if (GA_EMPTY(&dbg_breakp)) {
+ MSG(_("No breakpoints defined"));
+ } else {
+ for (int i = 0; i < dbg_breakp.ga_len; i++) {
+ bp = &BREAKP(i);
+ if (bp->dbg_type == DBG_FILE) {
+ home_replace(NULL, bp->dbg_name, NameBuff, MAXPATHL, true);
+ }
+ if (bp->dbg_type != DBG_EXPR) {
+ smsg(_("%3d %s %s line %" PRId64),
+ bp->dbg_nr,
+ bp->dbg_type == DBG_FUNC ? "func" : "file",
+ bp->dbg_type == DBG_FUNC ? bp->dbg_name : NameBuff,
+ (int64_t)bp->dbg_lnum);
+ } else {
+ smsg(_("%3d expr %s"), bp->dbg_nr, bp->dbg_name);
+ }
+ }
+ }
+}
+
+/// Find a breakpoint for a function or sourced file.
+/// Returns line number at which to break; zero when no matching breakpoint.
+///
+/// @param file true for a file, false for a function
+/// @param fname file or function name
+/// @param after after this line number
+linenr_T dbg_find_breakpoint(bool file, char_u *fname, linenr_T after)
+{
+ return debuggy_find(file, fname, after, &dbg_breakp, NULL);
+}
+
+/// @param file true for a file, false for a function
+/// @param fname file or function name
+/// @param fp[out] forceit
+///
+/// @returns true if profiling is on for a function or sourced file.
+bool has_profiling(bool file, char_u *fname, bool *fp)
+{
+ return debuggy_find(file, fname, (linenr_T)0, &prof_ga, fp)
+ != (linenr_T)0;
+}
+
+/// Common code for dbg_find_breakpoint() and has_profiling().
+///
+/// @param file true for a file, false for a function
+/// @param fname file or function name
+/// @param after after this line number
+/// @param gap either &dbg_breakp or &prof_ga
+/// @param fp if not NULL: return forceit
+static linenr_T debuggy_find(bool file, char_u *fname, linenr_T after, garray_T *gap, bool *fp)
+{
+ struct debuggy *bp;
+ linenr_T lnum = 0;
+ char_u *name = fname;
+ int prev_got_int;
+
+ // Return quickly when there are no breakpoints.
+ if (GA_EMPTY(gap)) {
+ return (linenr_T)0;
+ }
+
+ // Replace K_SNR in function name with "<SNR>".
+ if (!file && fname[0] == K_SPECIAL) {
+ name = xmalloc(STRLEN(fname) + 3);
+ STRCPY(name, "<SNR>");
+ STRCPY(name + 5, fname + 3);
+ }
+
+ for (int i = 0; i < gap->ga_len; i++) {
+ // Skip entries that are not useful or are for a line that is beyond
+ // an already found breakpoint.
+ bp = &DEBUGGY(gap, i);
+ if ((bp->dbg_type == DBG_FILE) == file
+ && bp->dbg_type != DBG_EXPR
+ && (gap == &prof_ga
+ || (bp->dbg_lnum > after && (lnum == 0 || bp->dbg_lnum < lnum)))) {
+ // Save the value of got_int and reset it. We don't want a
+ // previous interruption cancel matching, only hitting CTRL-C
+ // while matching should abort it.
+ prev_got_int = got_int;
+ got_int = false;
+ if (vim_regexec_prog(&bp->dbg_prog, false, name, (colnr_T)0)) {
+ lnum = bp->dbg_lnum;
+ if (fp != NULL) {
+ *fp = bp->dbg_forceit;
+ }
+ }
+ got_int |= prev_got_int;
+ } else if (bp->dbg_type == DBG_EXPR) {
+ bool line = false;
+
+ typval_T *const tv = eval_expr_no_emsg(bp);
+ if (tv != NULL) {
+ if (bp->dbg_val == NULL) {
+ debug_oldval = typval_tostring(NULL);
+ bp->dbg_val = tv;
+ debug_newval = typval_tostring(bp->dbg_val);
+ line = true;
+ } else {
+ if (typval_compare(tv, bp->dbg_val, EXPR_IS, false) == OK
+ && tv->vval.v_number == false) {
+ line = true;
+ debug_oldval = typval_tostring(bp->dbg_val);
+ // Need to evaluate again, typval_compare() overwrites "tv".
+ typval_T *const v = eval_expr_no_emsg(bp);
+ debug_newval = typval_tostring(v);
+ tv_free(bp->dbg_val);
+ bp->dbg_val = v;
+ }
+ tv_free(tv);
+ }
+ } else if (bp->dbg_val != NULL) {
+ debug_oldval = typval_tostring(bp->dbg_val);
+ debug_newval = typval_tostring(NULL);
+ tv_free(bp->dbg_val);
+ bp->dbg_val = NULL;
+ line = true;
+ }
+
+ if (line) {
+ lnum = after > 0 ? after : 1;
+ break;
+ }
+ }
+ }
+ if (name != fname) {
+ xfree(name);
+ }
+
+ return lnum;
+}
+
+/// Called when a breakpoint was encountered.
+void dbg_breakpoint(char_u *name, linenr_T lnum)
+{
+ // We need to check if this line is actually executed in do_one_cmd()
+ debug_breakpoint_name = name;
+ debug_breakpoint_lnum = lnum;
+}
diff --git a/src/nvim/debugger.h b/src/nvim/debugger.h
new file mode 100644
index 0000000000..1f1139b3bc
--- /dev/null
+++ b/src/nvim/debugger.h
@@ -0,0 +1,11 @@
+#ifndef NVIM_DEBUGGER_H
+#define NVIM_DEBUGGER_H
+
+#include <stdbool.h>
+
+#include "nvim/ex_cmds_defs.h"
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "debugger.h.generated.h"
+#endif
+#endif // NVIM_DEBUGGER_H
diff --git a/src/nvim/decoration.c b/src/nvim/decoration.c
index f3000f4430..561be9968a 100644
--- a/src/nvim/decoration.c
+++ b/src/nvim/decoration.c
@@ -1,24 +1,19 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
-#include "nvim/vim.h"
-#include "nvim/lua/executor.h"
-#include "nvim/extmark.h"
#include "nvim/decoration.h"
+#include "nvim/extmark.h"
+#include "nvim/highlight.h"
+#include "nvim/lua/executor.h"
#include "nvim/screen.h"
#include "nvim/syntax.h"
-#include "nvim/highlight.h"
+#include "nvim/vim.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "decoration.c.generated.h"
#endif
-static PMap(uint64_t) *hl_decors;
-
-void decor_init(void)
-{
- hl_decors = pmap_new(uint64_t)();
-}
+static PMap(uint64_t) hl_decors;
/// Add highlighting to a buffer, bounded by two cursor positions,
/// with an offset.
@@ -30,14 +25,10 @@ void decor_init(void)
/// @param src_id src_id to use or 0 to use a new src_id group,
/// or -1 for ungrouped highlight.
/// @param hl_id Highlight group id
-/// @param pos_start Cursor position to start the hightlighting at
+/// @param pos_start Cursor position to start the highlighting at
/// @param pos_end Cursor position to end the highlighting at
/// @param offset Move the whole highlighting this many columns to the right
-void bufhl_add_hl_pos_offset(buf_T *buf,
- int src_id,
- int hl_id,
- lpos_T pos_start,
- lpos_T pos_end,
+void bufhl_add_hl_pos_offset(buf_T *buf, int src_id, int hl_id, lpos_T pos_start, lpos_T pos_end,
colnr_T offset)
{
colnr_T hl_start = 0;
@@ -46,7 +37,7 @@ void bufhl_add_hl_pos_offset(buf_T *buf,
decor->priority = DECOR_PRIORITY_BASE;
// TODO(bfredl): if decoration had blocky mode, we could avoid this loop
- for (linenr_T lnum = pos_start.lnum; lnum <= pos_end.lnum; lnum ++) {
+ for (linenr_T lnum = pos_start.lnum; lnum <= pos_end.lnum; lnum++) {
int end_off = 0;
if (pos_start.lnum < lnum && lnum < pos_end.lnum) {
// TODO(bfredl): This is quite ad-hoc, but the space between |num| and
@@ -68,7 +59,7 @@ void bufhl_add_hl_pos_offset(buf_T *buf,
hl_start = pos_start.col + offset;
hl_end = pos_end.col + offset;
}
- (void)extmark_set(buf, (uint64_t)src_id, 0,
+ (void)extmark_set(buf, (uint64_t)src_id, NULL,
(int)lnum-1, hl_start, (int)lnum-1+end_off, hl_end,
decor, true, false, kExtmarkNoUndo);
}
@@ -77,7 +68,7 @@ void bufhl_add_hl_pos_offset(buf_T *buf,
Decoration *decor_hl(int hl_id)
{
assert(hl_id > 0);
- Decoration **dp = (Decoration **)pmap_ref(uint64_t)(hl_decors,
+ Decoration **dp = (Decoration **)pmap_ref(uint64_t)(&hl_decors,
(uint64_t)hl_id, true);
if (*dp) {
return *dp;
@@ -119,7 +110,7 @@ void clear_virttext(VirtText *text)
*text = (VirtText)KV_INITIAL_VALUE;
}
-VirtText *decor_find_virttext(buf_T *buf, int row, uint64_t ns_id)
+Decoration *decor_find_virttext(buf_T *buf, int row, uint64_t ns_id)
{
MarkTreeIter itr[1] = { 0 };
marktree_itr_get(buf->b_marktree, row, 0, itr);
@@ -132,7 +123,7 @@ VirtText *decor_find_virttext(buf_T *buf, int row, uint64_t ns_id)
mark.id, false);
if (item && (ns_id == 0 || ns_id == item->ns_id)
&& item->decor && kv_size(item->decor->virt_text)) {
- return &item->decor->virt_text;
+ return item->decor;
}
marktree_itr_next(buf->b_marktree, itr);
}
@@ -150,7 +141,7 @@ bool decor_redraw_reset(buf_T *buf, DecorState *state)
}
}
kv_size(state->active) = 0;
- return buf->b_extmark_index;
+ return map_size(buf->b_extmark_index);
}
@@ -177,7 +168,7 @@ bool decor_redraw_start(buf_T *buf, int top_row, DecorState *state)
ExtmarkItem *item = map_ref(uint64_t, ExtmarkItem)(buf->b_extmark_index,
start_id, false);
if (!item || !item->decor) {
- // TODO(bfredl): dedicated flag for being a decoration?
+ // TODO(bfredl): dedicated flag for being a decoration?
goto next_mark;
}
Decoration *decor = item->decor;
@@ -218,21 +209,18 @@ bool decor_redraw_line(buf_T *buf, int row, DecorState *state)
}
state->row = row;
state->col_until = -1;
+ state->eol_col = -1;
return true; // TODO(bfredl): be more precise
}
-static void decor_add(DecorState *state, int start_row, int start_col,
- int end_row, int end_col, Decoration *decor, bool owned)
+static void decor_add(DecorState *state, int start_row, int start_col, int end_row, int end_col,
+ Decoration *decor, bool owned)
{
int attr_id = decor->hl_id > 0 ? syn_id2attr(decor->hl_id) : 0;
DecorRange range = { start_row, start_col, end_row, end_col,
*decor, attr_id,
- kv_size(decor->virt_text) && owned, -1 };
-
- if (decor->virt_text_pos == kVTEndOfLine) {
- range.win_col = -2; // handled separately
- }
+ kv_size(decor->virt_text) && owned, -1 };
kv_pushp(state->active);
size_t index;
@@ -246,8 +234,7 @@ static void decor_add(DecorState *state, int start_row, int start_col,
kv_A(state->active, index) = range;
}
-int decor_redraw_col(buf_T *buf, int col, int win_col, bool hidden,
- DecorState *state)
+int decor_redraw_col(buf_T *buf, int col, int win_col, bool hidden, DecorState *state)
{
if (col <= state->col_until) {
return state->current;
@@ -265,7 +252,7 @@ int decor_redraw_col(buf_T *buf, int col, int win_col, bool hidden,
}
if ((mark.id&MARKTREE_END_FLAG)) {
- // TODO(bfredl): check decoration flag
+ // TODO(bfredl): check decoration flag
goto next_mark;
}
mtpos_t endpos = marktree_lookup(buf->b_marktree,
@@ -274,7 +261,7 @@ int decor_redraw_col(buf_T *buf, int col, int win_col, bool hidden,
ExtmarkItem *item = map_ref(uint64_t, ExtmarkItem)(buf->b_extmark_index,
mark.id, false);
if (!item || !item->decor) {
- // TODO(bfredl): dedicated flag for being a decoration?
+ // TODO(bfredl): dedicated flag for being a decoration?
goto next_mark;
}
Decoration *decor = item->decor;
@@ -345,33 +332,25 @@ void decor_redraw_end(DecorState *state)
state->buf = NULL;
}
-VirtText decor_redraw_eol(buf_T *buf, DecorState *state, int *eol_attr,
- bool *aligned)
+bool decor_redraw_eol(buf_T *buf, DecorState *state, int *eol_attr, int eol_col)
{
decor_redraw_col(buf, MAXCOL, MAXCOL, false, state);
- VirtText text = VIRTTEXT_EMPTY;
+ state->eol_col = eol_col;
+ bool has_virttext = false;
for (size_t i = 0; i < kv_size(state->active); i++) {
DecorRange item = kv_A(state->active, i);
if (item.start_row == state->row && kv_size(item.decor.virt_text)) {
- if (!kv_size(text) && item.decor.virt_text_pos == kVTEndOfLine) {
- text = item.decor.virt_text;
- } else if (item.decor.virt_text_pos == kVTRightAlign
- || item.decor.virt_text_pos == kVTWinCol) {
- *aligned = true;
- }
+ has_virttext = true;
}
-
if (item.decor.hl_eol && item.start_row <= state->row) {
*eol_attr = hl_combine_attr(*eol_attr, item.attr_id);
}
}
-
- return text;
+ return has_virttext;
}
-void decor_add_ephemeral(int start_row, int start_col, int end_row, int end_col,
- Decoration *decor)
+void decor_add_ephemeral(int start_row, int start_col, int end_row, int end_col, Decoration *decor)
{
if (end_row == -1) {
end_row = start_row;
@@ -433,3 +412,35 @@ void decor_free_all_mem(void)
}
kv_destroy(decor_providers);
}
+
+
+int decor_virtual_lines(win_T *wp, linenr_T lnum)
+{
+ buf_T *buf = wp->w_buffer;
+ if (!buf->b_virt_line_mark) {
+ return 0;
+ }
+ if (buf->b_virt_line_pos < 0) {
+ mtpos_t pos = marktree_lookup(buf->b_marktree, buf->b_virt_line_mark, NULL);
+ if (pos.row < 0) {
+ buf->b_virt_line_mark = 0;
+ }
+ buf->b_virt_line_pos = pos.row + (buf->b_virt_line_above ? 0 : 1);
+ }
+
+ return (lnum-1 == buf->b_virt_line_pos) ? (int)kv_size(buf->b_virt_lines) : 0;
+}
+
+void clear_virt_lines(buf_T *buf, int row)
+{
+ if (row > -1) {
+ redraw_buf_line_later(buf, MIN(buf->b_ml.ml_line_count,
+ row+1+(buf->b_virt_line_above?0:1)));
+ }
+ for (size_t i = 0; i < kv_size(buf->b_virt_lines); i++) {
+ clear_virttext(&kv_A(buf->b_virt_lines, i));
+ }
+ kv_destroy(buf->b_virt_lines); // re-initializes
+ buf->b_virt_line_pos = -1;
+ buf->b_virt_line_mark = 0;
+}
diff --git a/src/nvim/decoration.h b/src/nvim/decoration.h
index 4cebc0b731..35f5af87ed 100644
--- a/src/nvim/decoration.h
+++ b/src/nvim/decoration.h
@@ -7,14 +7,6 @@
// actual Decoration data is in extmark_defs.h
-typedef struct {
- char *text;
- int hl_id;
-} VirtTextChunk;
-
-typedef kvec_t(VirtTextChunk) VirtText;
-#define VIRTTEXT_EMPTY ((VirtText)KV_INITIAL_VALUE)
-
typedef uint16_t DecorPriority;
#define DECOR_PRIORITY_BASE 0x1000
@@ -34,19 +26,20 @@ typedef enum {
struct Decoration
{
- int hl_id; // highlight group
VirtText virt_text;
+ int hl_id; // highlight group
VirtTextPos virt_text_pos;
- bool virt_text_hide;
HlMode hl_mode;
+ bool virt_text_hide;
bool hl_eol;
+ bool shared; // shared decoration, don't free
// TODO(bfredl): style, signs, etc
DecorPriority priority;
- bool shared; // shared decoration, don't free
int col; // fixed col value, like win_col
+ int virt_text_width; // width of virt_text
};
-#define DECORATION_INIT { 0, KV_INITIAL_VALUE, kVTEndOfLine, false, \
- kHlModeUnknown, false, DECOR_PRIORITY_BASE, false, 0 }
+#define DECORATION_INIT { KV_INITIAL_VALUE, 0, kVTEndOfLine, kHlModeUnknown, \
+ false, false, false, DECOR_PRIORITY_BASE, 0, 0 }
typedef struct {
int start_row;
@@ -67,6 +60,8 @@ typedef struct {
int row;
int col_until;
int current;
+
+ int eol_col;
VirtText *virt_text;
} DecorState;
diff --git a/src/nvim/diff.c b/src/nvim/diff.c
index 5f8b81822b..5c43b2498e 100644
--- a/src/nvim/diff.c
+++ b/src/nvim/diff.c
@@ -13,14 +13,12 @@
#include <inttypes.h>
#include <stdbool.h>
-#include "nvim/vim.h"
-#include "xdiff/xdiff.h"
#include "nvim/ascii.h"
-#include "nvim/diff.h"
#include "nvim/buffer.h"
#include "nvim/change.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
+#include "nvim/diff.h"
#include "nvim/eval.h"
#include "nvim/ex_cmds.h"
#include "nvim/ex_docmd.h"
@@ -29,19 +27,21 @@
#include "nvim/mark.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
+#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/memory.h"
#include "nvim/move.h"
#include "nvim/normal.h"
#include "nvim/option.h"
+#include "nvim/os/os.h"
+#include "nvim/os/shell.h"
#include "nvim/path.h"
#include "nvim/screen.h"
#include "nvim/strings.h"
#include "nvim/undo.h"
+#include "nvim/vim.h"
#include "nvim/window.h"
-#include "nvim/os/os.h"
-#include "nvim/os/shell.h"
+#include "xdiff/xdiff.h"
static int diff_busy = false; // using diff structs, don't change them
static bool diff_need_update = false; // ex_diffupdate needs to be called
@@ -72,22 +72,22 @@ static TriState diff_a_works = kNone;
// used for diff input
typedef struct {
- char_u *din_fname; // used for external diff
- mmfile_t din_mmfile; // used for internal diff
+ char_u *din_fname; // used for external diff
+ mmfile_t din_mmfile; // used for internal diff
} diffin_T;
// used for diff result
typedef struct {
- char_u *dout_fname; // used for external diff
- garray_T dout_ga; // used for internal diff
+ char_u *dout_fname; // used for external diff
+ garray_T dout_ga; // used for internal diff
} diffout_T;
// two diff inputs and one result
typedef struct {
- diffin_T dio_orig; // original file input
- diffin_T dio_new; // new file input
- diffout_T dio_diff; // diff result
- int dio_internal; // using internal diff
+ diffin_T dio_orig; // original file input
+ diffin_T dio_new; // new file input
+ diffout_T dio_diff; // diff result
+ int dio_internal; // using internal diff
} diffio_T;
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -119,7 +119,6 @@ void diff_buf_delete(buf_T *buf)
/// @param win
void diff_buf_adjust(win_T *win)
{
-
if (!win->w_p_diff) {
// When there is no window showing a diff for this buffer, remove
// it from the diffs.
@@ -242,8 +241,7 @@ void diff_invalidate(buf_T *buf)
/// @param line2
/// @param amount
/// @param amount_after
-void diff_mark_adjust(linenr_T line1, linenr_T line2, long amount,
- long amount_after)
+void diff_mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after)
{
// Handle all tab pages that use the current buffer in a diff.
FOR_ALL_TABS(tp) {
@@ -267,8 +265,8 @@ void diff_mark_adjust(linenr_T line1, linenr_T line2, long amount,
/// @param line2
/// @param amount
/// @amount_after
-static void diff_mark_adjust_tp(tabpage_T *tp, int idx, linenr_T line1,
- linenr_T line2, long amount, long amount_after)
+static void diff_mark_adjust_tp(tabpage_T *tp, int idx, linenr_T line1, linenr_T line2, long amount,
+ long amount_after)
{
if (diff_internal()) {
// Will update diffs before redrawing. Set _invalid to update the
@@ -299,7 +297,7 @@ static void diff_mark_adjust_tp(tabpage_T *tp, int idx, linenr_T line1,
diff_T *dp = tp->tp_first_diff;
linenr_T last;
- linenr_T lnum_deleted = line1; // lnum of remaining deletion
+ linenr_T lnum_deleted = line1; // lnum of remaining deletion
int n;
int off;
for (;;) {
@@ -323,8 +321,8 @@ static void diff_mark_adjust_tp(tabpage_T *tp, int idx, linenr_T line1,
dnext->df_lnum[i] = line1;
} else {
dnext->df_lnum[i] = line1
- + (dprev->df_lnum[i] + dprev->df_count[i])
- - (dprev->df_lnum[idx] + dprev->df_count[idx]);
+ + (dprev->df_lnum[i] + dprev->df_count[i])
+ - (dprev->df_lnum[idx] + dprev->df_count[idx]);
}
dnext->df_count[i] = deleted;
}
@@ -509,7 +507,7 @@ static void diff_mark_adjust_tp(tabpage_T *tp, int idx, linenr_T line1,
/// @param dp
///
/// @return The new diff block.
-static diff_T* diff_alloc_new(tabpage_T *tp, diff_T *dprev, diff_T *dp)
+static diff_T *diff_alloc_new(tabpage_T *tp, diff_T *dprev, diff_T *dp)
{
diff_T *dnew = xmalloc(sizeof(*dnew));
@@ -639,12 +637,18 @@ static int diff_check_sanity(tabpage_T *tp, diff_T *dp)
/// @param dofold Also recompute the folds
void diff_redraw(bool dofold)
{
+ win_T *wp_other = NULL;
+ bool used_max_fill = false;
+
need_diff_redraw = false;
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
if (!wp->w_p_diff) {
continue;
}
redraw_later(wp, SOME_VALID);
+ if (wp != curwin) {
+ wp_other = wp;
+ }
if (dofold && foldmethodIsDiff(wp)) {
foldUpdateAll(wp);
}
@@ -658,10 +662,18 @@ void diff_redraw(bool dofold)
wp->w_topfill = (n < 0 ? 0 : n);
} else if ((n > 0) && (n > wp->w_topfill)) {
wp->w_topfill = n;
+ if (wp == curwin) {
+ used_max_fill = true;
+ }
}
check_topfill(wp, false);
}
}
+ if (wp_other != NULL && used_max_fill && curwin->w_p_scb) {
+ // The current window was set to used the maximum number of filler
+ // lines, may need to reduce them.
+ diff_set_topline(wp_other, curwin);
+ }
}
static void clear_diffin(diffin_T *din)
@@ -690,10 +702,10 @@ static void clear_diffout(diffout_T *dout)
/// @return FAIL for failure.
static int diff_write_buffer(buf_T *buf, diffin_T *din)
{
- linenr_T lnum;
- char_u *s;
- long len = 0;
- char_u *ptr;
+ linenr_T lnum;
+ char_u *s;
+ long len = 0;
+ char_u *ptr;
// xdiff requires one big block of memory with all the text.
for (lnum = 1; lnum <= buf->b_ml.ml_line_count; lnum++) {
@@ -720,7 +732,7 @@ static int diff_write_buffer(buf_T *buf, diffin_T *din)
for (lnum = 1; lnum <= buf->b_ml.ml_line_count; lnum++) {
for (s = ml_get_buf(buf, lnum, false); *s != NUL; ) {
if (diff_flags & DIFF_ICASE) {
- char_u cbuf[MB_MAXBYTES + 1];
+ char_u cbuf[MB_MAXBYTES + 1];
// xdiff doesn't support ignoring case, fold-case the text.
int c = PTR2CHAR(s);
@@ -775,12 +787,10 @@ static int diff_write(buf_T *buf, diffin_T *din)
/// @param dio
/// @param idx_orig
/// @param eap can be NULL
-static void diff_try_update(diffio_T *dio,
- int idx_orig,
- exarg_T *eap)
+static void diff_try_update(diffio_T *dio, int idx_orig, exarg_T *eap)
{
buf_T *buf;
- int idx_new;
+ int idx_new;
if (dio->dio_internal) {
ga_init(&dio->dio_diff.dout_ga, sizeof(char *), 1000);
@@ -918,7 +928,7 @@ void ex_diffupdate(exarg_T *eap)
}
// Only use the internal method if it did not fail for one of the buffers.
- diffio_T diffio;
+ diffio_T diffio;
memset(&diffio, 0, sizeof(diffio));
diffio.dio_internal = diff_internal() && !diff_internal_failed();
@@ -1034,9 +1044,9 @@ static int check_external_diff(diffio_T *diffio)
///
static int diff_file_internal(diffio_T *diffio)
{
- xpparam_t param;
- xdemitconf_t emit_cfg;
- xdemitcb_t emit_cb;
+ xpparam_t param;
+ xdemitconf_t emit_cfg;
+ xdemitcb_t emit_cb;
memset(&param, 0, sizeof(param));
memset(&emit_cfg, 0, sizeof(emit_cfg));
@@ -1059,7 +1069,7 @@ static int diff_file_internal(diffio_T *diffio)
emit_cfg.ctxlen = 0; // don't need any diff_context here
emit_cb.priv = &diffio->dio_diff;
- emit_cb.outf = xdiff_out;
+ emit_cb.out_line = xdiff_out;
if (xdl_diff(&diffio->dio_orig.din_mmfile,
&diffio->dio_new.din_mmfile,
&param, &emit_cfg, &emit_cb) < 0) {
@@ -1076,9 +1086,9 @@ static int diff_file_internal(diffio_T *diffio)
/// @return OK or FAIL
static int diff_file(diffio_T *dio)
{
- char *tmp_orig = (char *)dio->dio_orig.din_fname;
- char *tmp_new = (char *)dio->dio_new.din_fname;
- char *tmp_diff = (char *)dio->dio_diff.dout_fname;
+ char *tmp_orig = (char *)dio->dio_orig.din_fname;
+ char *tmp_new = (char *)dio->dio_new.din_fname;
+ char *tmp_diff = (char *)dio->dio_diff.dout_fname;
if (*p_dex != NUL) {
// Use 'diffexpr' to generate the diff file.
eval_diff(tmp_orig, tmp_new, tmp_diff);
@@ -1109,9 +1119,9 @@ static int diff_file(diffio_T *dio)
(diff_flags & DIFF_IBLANK) ? "-B " : "",
(diff_flags & DIFF_ICASE) ? "-i " : "",
tmp_orig, tmp_new);
- append_redir(cmd, len, (char *) p_srr, tmp_diff);
+ append_redir(cmd, len, (char *)p_srr, tmp_diff);
block_autocmds(); // Avoid ShellCmdPost stuff
- (void)call_shell((char_u *) cmd,
+ (void)call_shell((char_u *)cmd,
kShellOptFilter | kShellOptSilent | kShellOptDoOut,
NULL);
unblock_autocmds();
@@ -1157,8 +1167,8 @@ void ex_diffpatch(exarg_T *eap)
#ifdef UNIX
// Get the absolute path of the patchfile, changing directory below.
fullname = FullName_save((char *)eap->arg, false);
- esc_name = vim_strsave_shellescape(
- (fullname != NULL ? (char_u *)fullname : eap->arg), true, true);
+ esc_name =
+ vim_strsave_shellescape((fullname != NULL ? (char_u *)fullname : eap->arg), true, true);
#else
esc_name = vim_strsave_shellescape(eap->arg, true, true);
#endif
@@ -1310,8 +1320,8 @@ void ex_diffsplit(exarg_T *eap)
if (bufref_valid(&old_curbuf)) {
// Move the cursor position to that of the old window.
- curwin->w_cursor.lnum = diff_get_corresponding_line(
- old_curbuf.br_buf, old_curwin->w_cursor.lnum);
+ curwin->w_cursor.lnum = diff_get_corresponding_line(old_curbuf.br_buf,
+ old_curwin->w_cursor.lnum);
}
}
// Now that lines are folded scroll to show the cursor at the same
@@ -1330,15 +1340,15 @@ void ex_diffthis(exarg_T *eap)
static void set_diff_option(win_T *wp, int value)
{
- win_T *old_curwin = curwin;
-
- curwin = wp;
- curbuf = curwin->w_buffer;
- curbuf_lock++;
- set_option_value("diff", (long)value, NULL, OPT_LOCAL);
- curbuf_lock--;
- curwin = old_curwin;
- curbuf = curwin->w_buffer;
+ win_T *old_curwin = curwin;
+
+ curwin = wp;
+ curbuf = curwin->w_buffer;
+ curbuf->b_ro_locked++;
+ set_option_value("diff", (long)value, NULL, OPT_LOCAL);
+ curbuf->b_ro_locked--;
+ curwin = old_curwin;
+ curbuf = curwin->w_buffer;
}
@@ -1710,8 +1720,7 @@ static void diff_read(int idx_orig, int idx_new, diffout_T *dout)
/// @param dp
/// @param idx_orig
/// @param idx_new
-static void diff_copy_entry(diff_T *dprev, diff_T *dp, int idx_orig,
- int idx_new)
+static void diff_copy_entry(diff_T *dprev, diff_T *dp, int idx_orig, int idx_new)
{
long off;
@@ -1755,7 +1764,7 @@ void diff_clear(tabpage_T *tp)
/// @return diff status.
int diff_check(win_T *wp, linenr_T lnum)
{
- int idx; // index in tp_diffbuf[] for this buffer
+ int idx; // index in tp_diffbuf[] for this buffer
diff_T *dp;
int maxcount;
int i;
@@ -1869,7 +1878,7 @@ int diff_check(win_T *wp, linenr_T lnum)
/// @param idx1 first entry in diff "dp"
/// @param idx2 second entry in diff "dp"
///
-/// @return true if two entires are equal.
+/// @return true if two entries are equal.
static bool diff_equal_entry(diff_T *dp, int idx1, int idx2)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ARG(1)
{
@@ -1898,8 +1907,7 @@ static bool diff_equal_entry(diff_T *dp, int idx1, int idx2)
// Compare the characters at "p1" and "p2". If they are equal (possibly
// ignoring case) return true and set "len" to the number of bytes.
-static bool diff_equal_char(const char_u *const p1, const char_u *const p2,
- int *const len)
+static bool diff_equal_char(const char_u *const p1, const char_u *const p2, int *const len)
{
const int l = utfc_ptr2len(p1);
@@ -1977,26 +1985,6 @@ static int diff_cmp(char_u *s1, char_u *s2)
return 0;
}
-/// Return the number of filler lines above "lnum".
-///
-/// @param wp
-/// @param lnum
-///
-/// @return Number of filler lines above lnum
-int diff_check_fill(win_T *wp, linenr_T lnum)
-{
- // be quick when there are no filler lines
- if (!(diff_flags & DIFF_FILLER)) {
- return 0;
- }
- int n = diff_check(wp, lnum);
-
- if (n <= 0) {
- return 0;
- }
- return n;
-}
-
/// Set the topline of "towin" to match the position in "fromwin", so that they
/// show the same diff'ed lines.
///
@@ -2022,6 +2010,7 @@ void diff_set_topline(win_T *fromwin, win_T *towin)
}
towin->w_topfill = 0;
+
// search for a change that includes "lnum" in the list of diffblocks.
for (dp = curtab->tp_first_diff; dp != NULL; dp = dp->df_next) {
if (lnum <= dp->df_lnum[fromidx] + dp->df_count[fromidx]) {
@@ -2247,6 +2236,13 @@ bool diffopt_closeoff(void)
return (diff_flags & DIFF_CLOSE_OFF) != 0;
}
+// Return true if 'diffopt' contains "filler".
+bool diffopt_filler(void)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ return (diff_flags & DIFF_FILLER) != 0;
+}
+
/// Find the difference within a changed line.
///
/// @param wp window whose current buffer to check
@@ -2523,7 +2519,7 @@ void ex_diffgetput(exarg_T *eap)
if ((curtab->tp_diffbuf[i] != curbuf)
&& (curtab->tp_diffbuf[i] != NULL)
&& ((eap->cmdidx != CMD_diffput)
- || MODIFIABLE(curtab->tp_diffbuf[i]))) {
+ || MODIFIABLE(curtab->tp_diffbuf[i]))) {
EMSG(_("E101: More than two buffers in diff mode, don't know "
"which one to use"));
return;
@@ -2603,7 +2599,7 @@ void ex_diffgetput(exarg_T *eap)
// FileChangedRO autocommand, which may do nasty things and mess
// everything up.
if (!curbuf->b_changed) {
- change_warning(0);
+ change_warning(curbuf, 0);
if (diff_buf_idx(curbuf) != idx_to) {
EMSG(_("E787: Buffer changed unexpectedly"));
goto theend;
@@ -2669,7 +2665,7 @@ void ex_diffgetput(exarg_T *eap)
}
}
- buf_empty = BUFEMPTY();
+ buf_empty = buf_is_empty(curbuf);
added = 0;
for (i = 0; i < count; ++i) {
@@ -2944,7 +2940,7 @@ static linenr_T diff_get_corresponding_line_int(buf_T *buf1, linenr_T lnum1)
return curwin->w_cursor.lnum;
}
baseline = (dp->df_lnum[idx1] + dp->df_count[idx1])
- - (dp->df_lnum[idx2] + dp->df_count[idx2]);
+ - (dp->df_lnum[idx2] + dp->df_count[idx2]);
}
// If we get here then the cursor is after the last diff
@@ -3021,15 +3017,12 @@ linenr_T diff_lnum_win(linenr_T lnum, win_T *wp)
/// Handle an ED style diff line.
/// Return FAIL if the line does not contain diff info.
///
-static int parse_diff_ed(char_u *line,
- linenr_T *lnum_orig,
- long *count_orig,
- linenr_T *lnum_new,
- long *count_new)
+static int parse_diff_ed(char_u *line, linenr_T *lnum_orig, long *count_orig, linenr_T *lnum_new,
+ long *count_new)
{
char_u *p;
- long f1, l1, f2, l2;
- int difftype;
+ long f1, l1, f2, l2;
+ int difftype;
// The line must be one of three formats:
// change: {first}[,{last}]c{first}[,{last}]
@@ -3079,14 +3072,11 @@ static int parse_diff_ed(char_u *line,
/// Parses unified diff with zero(!) context lines.
/// Return FAIL if there is no diff information in "line".
///
-static int parse_diff_unified(char_u *line,
- linenr_T *lnum_orig,
- long *count_orig,
- linenr_T *lnum_new,
- long *count_new)
+static int parse_diff_unified(char_u *line, linenr_T *lnum_orig, long *count_orig,
+ linenr_T *lnum_new, long *count_new)
{
char_u *p;
- long oldline, oldcount, newline, newcount;
+ long oldline, oldcount, newline, newcount;
// Parse unified diff hunk header:
// @@ -oldline,oldcount +newline,newcount @@
@@ -3139,7 +3129,7 @@ static int parse_diff_unified(char_u *line,
static int xdiff_out(void *priv, mmbuffer_t *mb, int nbuf)
{
diffout_T *dout = (diffout_T *)priv;
- char_u *p;
+ char_u *p;
// The header line always comes by itself, text lines in at least two
// parts. We drop the text part.
diff --git a/src/nvim/digraph.c b/src/nvim/digraph.c
index dd32cef1e3..b0fc4ee463 100644
--- a/src/nvim/digraph.c
+++ b/src/nvim/digraph.c
@@ -6,26 +6,26 @@
/// code for digraphs
#include <assert.h>
-#include <stdbool.h>
#include <inttypes.h>
+#include <stdbool.h>
-#include "nvim/vim.h"
#include "nvim/ascii.h"
-#include "nvim/digraph.h"
#include "nvim/charset.h"
+#include "nvim/digraph.h"
#include "nvim/ex_cmds2.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_getln.h"
+#include "nvim/garray.h"
#include "nvim/getchar.h"
-#include "nvim/misc1.h"
#include "nvim/mbyte.h"
-#include "nvim/message.h"
#include "nvim/memory.h"
-#include "nvim/garray.h"
+#include "nvim/message.h"
+#include "nvim/misc1.h"
#include "nvim/normal.h"
+#include "nvim/os/input.h"
#include "nvim/screen.h"
#include "nvim/strings.h"
-#include "nvim/os/input.h"
+#include "nvim/vim.h"
typedef int result_T;
@@ -40,7 +40,7 @@ typedef struct digraph {
# include "digraph.c.generated.h"
#endif
// digraphs added by the user
-static garray_T user_digraphs = {0, 0, (int)sizeof(digr_T), 10, NULL};
+static garray_T user_digraphs = { 0, 0, (int)sizeof(digr_T), 10, NULL };
/// Note: Characters marked with XX are not included literally, because some
/// compilers cannot handle them (Amiga SAS/C is the most picky one).
@@ -49,7 +49,7 @@ static digr_T digraphdefault[] =
// digraphs for Unicode from RFC1345
// (also work for ISO-8859-1 aka latin1)
{
- { 'N', 'U', 0x0a }, // LF for NUL
+ { 'N', 'U', 0x0a }, // LF for NUL
{ 'S', 'H', 0x01 },
{ 'S', 'X', 0x02 },
{ 'E', 'X', 0x03 },
@@ -1452,12 +1452,12 @@ static digr_T digraphdefault[] =
/// @return The digraph.
int do_digraph(int c)
{
- static int backspaced; // character before K_BS
+ static int backspaced; // character before K_BS
static int lastchar; // last typed character
if (c == -1) { // init values
backspaced = -1;
- } else if (p_dg) {
+ } else if (p_dg) {
if (backspaced >= 0) {
c = getdigraph(backspaced, c, false);
}
@@ -1502,10 +1502,10 @@ char_u *get_digraph_for_char(int val_arg)
/// Get a digraph. Used after typing CTRL-K on the command line or in normal
/// mode.
///
-/// @param cmdline TRUE when called from the cmdline
+/// @param cmdline true when called from the cmdline
///
/// @returns composed character, or NUL when ESC was used.
-int get_digraph(int cmdline)
+int get_digraph(bool cmdline)
{
int cc;
no_mapping++;
@@ -1557,7 +1557,7 @@ static int getexactdigraph(int char1, int char2, bool meta_char)
// Search user digraphs first.
digr_T *dp = (digr_T *)user_digraphs.ga_data;
for (int i = 0; i < user_digraphs.ga_len; ++i) {
- if (((int) dp->char1 == char1) && ((int) dp->char2 == char2)) {
+ if (((int)dp->char1 == char1) && ((int)dp->char2 == char2)) {
retval = dp->result;
break;
}
@@ -1569,7 +1569,7 @@ static int getexactdigraph(int char1, int char2, bool meta_char)
dp = digraphdefault;
for (int i = 0; dp->char1 != 0; ++i) {
- if (((int) dp->char1 == char1) && ((int) dp->char2 == char2)) {
+ if (((int)dp->char1 == char1) && ((int)dp->char2 == char2)) {
retval = dp->result;
break;
}
@@ -1821,7 +1821,7 @@ typedef struct {
/// @return NULL if OK, an error message for failure. This only needs to be
/// used when setting the option, not later when the value has already
/// been checked.
-char_u* keymap_init(void)
+char_u *keymap_init(void)
{
curbuf->b_kmap_state &= ~KEYMAP_INIT;
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index 1579f3ff98..45edbec4a6 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.c
@@ -6,59 +6,60 @@
*/
#include <assert.h>
-#include <string.h>
#include <inttypes.h>
#include <stdbool.h>
+#include <string.h>
-#include "nvim/vim.h"
#include "nvim/ascii.h"
-#include "nvim/edit.h"
#include "nvim/buffer.h"
#include "nvim/change.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
#include "nvim/digraph.h"
+#include "nvim/edit.h"
#include "nvim/eval.h"
#include "nvim/eval/typval.h"
+#include "nvim/event/loop.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/getchar.h"
#include "nvim/indent.h"
#include "nvim/indent_c.h"
+#include "nvim/keymap.h"
#include "nvim/main.h"
-#include "nvim/extmark.h"
+#include "nvim/mark.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/keymap.h"
+#include "nvim/mouse.h"
#include "nvim/move.h"
#include "nvim/normal.h"
#include "nvim/ops.h"
#include "nvim/option.h"
+#include "nvim/os/input.h"
+#include "nvim/os/time.h"
#include "nvim/path.h"
+#include "nvim/plines.h"
#include "nvim/popupmnu.h"
#include "nvim/quickfix.h"
#include "nvim/regexp.h"
#include "nvim/screen.h"
#include "nvim/search.h"
#include "nvim/spell.h"
-#include "nvim/strings.h"
#include "nvim/state.h"
+#include "nvim/strings.h"
#include "nvim/syntax.h"
#include "nvim/tag.h"
-#include "nvim/ui.h"
-#include "nvim/mouse.h"
#include "nvim/terminal.h"
+#include "nvim/ui.h"
#include "nvim/undo.h"
+#include "nvim/vim.h"
#include "nvim/window.h"
-#include "nvim/event/loop.h"
-#include "nvim/mark.h"
-#include "nvim/os/input.h"
-#include "nvim/os/time.h"
// Definitions used for CTRL-X submode.
// Note: If you change CTRL-X submode, you must also maintain ctrl_x_msgs[]
@@ -83,6 +84,7 @@
#define CTRL_X_SPELL 14
#define CTRL_X_LOCAL_MSG 15 ///< only used in "ctrl_x_msgs"
#define CTRL_X_EVAL 16 ///< for builtin function complete()
+#define CTRL_X_CMDLINE_CTRL_X 17 ///< CTRL-X typed in CTRL_X_CMDLINE
#define CTRL_X_MSG(i) ctrl_x_msgs[(i) & ~CTRL_X_WANT_IDENT]
#define CTRL_X_MODE_LINE_OR_EVAL(m) \
@@ -108,6 +110,7 @@ static char *ctrl_x_msgs[] =
N_(" Spelling suggestion (s^N^P)"),
N_(" Keyword Local completion (^N^P)"),
NULL, // CTRL_X_EVAL doesn't use msg.
+ N_(" Command-line completion (^V^N^P)"),
};
static char *ctrl_x_mode_names[] = {
@@ -127,7 +130,8 @@ static char *ctrl_x_mode_names[] = {
"omni",
"spell",
NULL, // CTRL_X_LOCAL_MSG only used in "ctrl_x_msgs"
- "eval"
+ "eval",
+ "cmdline",
};
static char e_hitend[] = N_("Hit end of paragraph");
@@ -139,13 +143,13 @@ static char e_compldel[] = N_("E840: Completion function deleted text");
*/
typedef struct compl_S compl_T;
struct compl_S {
- compl_T *cp_next;
- compl_T *cp_prev;
- char_u *cp_str; // matched text
- char_u *(cp_text[CPT_COUNT]); // text for the menu
- typval_T cp_user_data;
- char_u *cp_fname; // file containing the match, allocated when
- // cp_flags has CP_FREE_FNAME
+ compl_T *cp_next;
+ compl_T *cp_prev;
+ char_u *cp_str; // matched text
+ char_u *(cp_text[CPT_COUNT]); // text for the menu
+ typval_T cp_user_data;
+ char_u *cp_fname; // file containing the match, allocated when
+ // cp_flags has CP_FREE_FNAME
int cp_flags; // CP_ values
int cp_number; // sequence number
};
@@ -157,10 +161,10 @@ struct compl_S {
* "compl_shown_match" is different from compl_curr_match during
* ins_compl_get_exp().
*/
-static compl_T *compl_first_match = NULL;
-static compl_T *compl_curr_match = NULL;
-static compl_T *compl_shown_match = NULL;
-static compl_T *compl_old_match = NULL;
+static compl_T *compl_first_match = NULL;
+static compl_T *compl_curr_match = NULL;
+static compl_T *compl_shown_match = NULL;
+static compl_T *compl_old_match = NULL;
/* After using a cursor key <Enter> selects a match in the popup menu,
* otherwise it inserts a line break. */
@@ -168,10 +172,9 @@ static int compl_enter_selects = FALSE;
/* When "compl_leader" is not NULL only matches that start with this string
* are used. */
-static char_u *compl_leader = NULL;
+static char_u *compl_leader = NULL;
-static int compl_get_longest = FALSE; /* put longest common string
- in compl_leader */
+static bool compl_get_longest = false; // put longest common string in compl_leader
static int compl_no_insert = FALSE; /* FALSE: select & insert
TRUE: noinsert */
@@ -195,19 +198,19 @@ static bool compl_started = false;
static int ctrl_x_mode = CTRL_X_NORMAL;
static int compl_matches = 0;
-static char_u *compl_pattern = NULL;
+static char_u *compl_pattern = NULL;
static Direction compl_direction = FORWARD;
static Direction compl_shows_dir = FORWARD;
static int compl_pending = 0; // > 1 for postponed CTRL-N
static pos_T compl_startpos;
static colnr_T compl_col = 0; /* column where the text starts
* that is being completed */
-static char_u *compl_orig_text = NULL; /* text as it was before
- * completion started */
+static char_u *compl_orig_text = NULL; /* text as it was before
+ * completion started */
static int compl_cont_mode = 0;
static expand_T compl_xp;
-static int compl_opt_refresh_always = FALSE;
+static bool compl_opt_refresh_always = false;
static int pum_selected_item = -1;
@@ -256,8 +259,8 @@ static colnr_T Insstart_textlen; // length of line when insert started
static colnr_T Insstart_blank_vcol; // vcol for first inserted blank
static bool update_Insstart_orig = true; // set Insstart_orig to Insstart
-static char_u *last_insert = NULL; // the text of the previous insert,
- // K_SPECIAL and CSI are escaped
+static char_u *last_insert = NULL; // the text of the previous insert,
+ // K_SPECIAL and CSI are escaped
static int last_insert_skip; // nr of chars in front of previous insert
static int new_insert_skip; // nr of chars in front of current insert
static int did_restart_edit; // "restart_edit" when calling edit()
@@ -309,7 +312,7 @@ static void insert_enter(InsertState *s)
s->ptr = (char_u *)"i";
}
- set_vim_var_string(VV_INSERTMODE, (char *) s->ptr, 1);
+ set_vim_var_string(VV_INSERTMODE, (char *)s->ptr, 1);
set_vim_var_string(VV_CHAR, NULL, -1);
ins_apply_autocmds(EVENT_INSERTENTER);
@@ -467,7 +470,7 @@ static void insert_enter(InsertState *s)
}
if (!p_im && did_restart_edit == 0) {
- change_warning(s->i == 0 ? 0 : s->i + 1);
+ change_warning(curbuf, s->i == 0 ? 0 : s->i + 1);
}
ui_cursor_shape(); // may show different cursor shape
@@ -761,7 +764,8 @@ static int insert_execute(VimState *state, int key)
s->c = do_digraph(s->c);
- if ((s->c == Ctrl_V || s->c == Ctrl_Q) && ctrl_x_mode == CTRL_X_CMDLINE) {
+ if ((s->c == Ctrl_V || s->c == Ctrl_Q)
+ && (ctrl_x_mode == CTRL_X_CMDLINE || ctrl_x_mode == CTRL_X_CMDLINE_CTRL_X)) {
insert_do_complete(s);
return 1;
}
@@ -790,15 +794,22 @@ static int insert_execute(VimState *state, int key)
}
}
- if (curwin->w_p_rl)
+ if (curwin->w_p_rl) {
switch (s->c) {
- case K_LEFT: s->c = K_RIGHT; break;
- case K_S_LEFT: s->c = K_S_RIGHT; break;
- case K_C_LEFT: s->c = K_C_RIGHT; break;
- case K_RIGHT: s->c = K_LEFT; break;
- case K_S_RIGHT: s->c = K_S_LEFT; break;
- case K_C_RIGHT: s->c = K_C_LEFT; break;
+ case K_LEFT:
+ s->c = K_RIGHT; break;
+ case K_S_LEFT:
+ s->c = K_S_RIGHT; break;
+ case K_C_LEFT:
+ s->c = K_C_RIGHT; break;
+ case K_RIGHT:
+ s->c = K_LEFT; break;
+ case K_S_RIGHT:
+ s->c = K_S_LEFT; break;
+ case K_C_RIGHT:
+ s->c = K_C_LEFT; break;
}
+ }
// If 'keymodel' contains "startsel", may start selection. If it
// does, a CTRL-O and c will be stuffed, we need to get these
@@ -1287,8 +1298,9 @@ normalchar:
// If the new value is already inserted or an empty string
// then don't insert any character.
- if (s->c == NUL)
+ if (s->c == NUL) {
break;
+ }
}
// Try to perform smart-indenting.
ins_try_si(s->c);
@@ -1308,8 +1320,8 @@ normalchar:
// special character. Let CTRL-] expand abbreviations without
// inserting it.
if (vim_iswordc(s->c)
- // Add ABBR_OFF for characters above 0x100, this is
- // what check_abbr() expects.
+ // Add ABBR_OFF for characters above 0x100, this is
+ // what check_abbr() expects.
|| (!echeck_abbr((s->c >= 0x100) ? (s->c + ABBR_OFF) : s->c)
&& s->c != Ctrl_RSB)) {
insert_special(s->c, false, false);
@@ -1414,21 +1426,20 @@ bool edit(int cmdchar, bool startln, long count)
return s->c == Ctrl_O;
}
-/*
- * Redraw for Insert mode.
- * This is postponed until getting the next character to make '$' in the 'cpo'
- * option work correctly.
- * Only redraw when there are no characters available. This speeds up
- * inserting sequences of characters (e.g., for CTRL-R).
- */
-static void ins_redraw(
- bool ready // not busy with something
-)
+/// Redraw for Insert mode.
+/// This is postponed until getting the next character to make '$' in the 'cpo'
+/// option work correctly.
+/// Only redraw when there are no characters available. This speeds up
+/// inserting sequences of characters (e.g., for CTRL-R).
+///
+/// @param ready not busy with something
+static void ins_redraw(bool ready)
{
bool conceal_cursor_moved = false;
- if (char_avail())
+ if (char_avail()) {
return;
+ }
// Trigger CursorMoved if the cursor moved. Not when the popup menu is
// visible, the command might delete it.
@@ -1651,11 +1662,11 @@ static void init_prompt(int cmdchar_todo)
check_cursor();
}
-// Return TRUE if the cursor is in the editable position of the prompt line.
-int prompt_curpos_editable(void)
+/// @return true if the cursor is in the editable position of the prompt line.
+bool prompt_curpos_editable(void)
{
- return curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count
- && curwin->w_cursor.col >= (int)STRLEN(prompt_text());
+ return curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count
+ && curwin->w_cursor.col >= (int)STRLEN(prompt_text());
}
/*
@@ -1684,8 +1695,9 @@ void display_dollar(colnr_T col)
{
colnr_T save_col;
- if (!redrawing())
+ if (!redrawing()) {
return;
+ }
save_col = curwin->w_cursor.col;
curwin->w_cursor.col = col;
@@ -1713,34 +1725,28 @@ static void undisplay_dollar(void)
}
}
-/*
- * Insert an indent (for <Tab> or CTRL-T) or delete an indent (for CTRL-D).
- * Keep the cursor on the same character.
- * type == INDENT_INC increase indent (for CTRL-T or <Tab>)
- * type == INDENT_DEC decrease indent (for CTRL-D)
- * type == INDENT_SET set indent to "amount"
- * if round is TRUE, round the indent to 'shiftwidth' (only with _INC and _Dec).
- */
-void
-change_indent (
- int type,
- int amount,
- int round,
- int replaced, // replaced character, put on replace stack
- int call_changed_bytes // call changed_bytes()
-)
+/// Insert an indent (for <Tab> or CTRL-T) or delete an indent (for CTRL-D).
+/// Keep the cursor on the same character.
+/// type == INDENT_INC increase indent (for CTRL-T or <Tab>)
+/// type == INDENT_DEC decrease indent (for CTRL-D)
+/// type == INDENT_SET set indent to "amount"
+///
+/// @param round if TRUE, round the indent to 'shiftwidth' (only with _INC and _Dec).
+/// @param replaced replaced character, put on replace stack
+/// @param call_changed_bytes call changed_bytes()
+void change_indent(int type, int amount, int round, int replaced, int call_changed_bytes)
{
int vcol;
int last_vcol;
int insstart_less; // reduction for Insstart.col
int new_cursor_col;
int i;
- char_u *ptr;
+ char_u *ptr;
int save_p_list;
int start_col;
colnr_T vc;
colnr_T orig_col = 0; // init for GCC
- char_u *new_line, *orig_line = NULL; // init for GCC
+ char_u *new_line, *orig_line = NULL; // init for GCC
// VREPLACE mode needs to know what the line was like before changing
if (State & VREPLACE_FLAG) {
@@ -1772,8 +1778,9 @@ change_indent (
* If the cursor is in the indent, compute how many screen columns the
* cursor is to the left of the first non-blank.
*/
- if (new_cursor_col < 0)
+ if (new_cursor_col < 0) {
vcol = get_indent() - vcol;
+ }
if (new_cursor_col > 0) { // can't fix replace stack
start_col = -1;
@@ -1782,9 +1789,9 @@ change_indent (
/*
* Set the new indent. The cursor will be put on the first non-blank.
*/
- if (type == INDENT_SET)
+ if (type == INDENT_SET) {
(void)set_indent(amount, call_changed_bytes ? SIN_CHANGED : 0);
- else {
+ } else {
int save_State = State;
// Avoid being called recursively.
@@ -1810,12 +1817,13 @@ change_indent (
* When changing the indent while the cursor is touching it, reset
* Insstart_col to 0.
*/
- if (new_cursor_col == 0)
+ if (new_cursor_col == 0) {
insstart_less = MAXCOL;
+ }
new_cursor_col += curwin->w_cursor.col;
- } else if (!(State & INSERT))
+ } else if (!(State & INSERT)) {
new_cursor_col = curwin->w_cursor.col;
- else {
+ } else {
/*
* Compute the screen column where the cursor should be.
*/
@@ -1862,10 +1870,11 @@ change_indent (
curwin->w_p_list = save_p_list;
- if (new_cursor_col <= 0)
+ if (new_cursor_col <= 0) {
curwin->w_cursor.col = 0;
- else
+ } else {
curwin->w_cursor.col = (colnr_T)new_cursor_col;
+ }
curwin->w_set_curswant = TRUE;
changed_cline_bef_curs();
@@ -1874,15 +1883,17 @@ change_indent (
*/
if (State & INSERT) {
if (curwin->w_cursor.lnum == Insstart.lnum && Insstart.col != 0) {
- if ((int)Insstart.col <= insstart_less)
+ if ((int)Insstart.col <= insstart_less) {
Insstart.col = 0;
- else
+ } else {
Insstart.col -= insstart_less;
+ }
}
- if ((int)ai_col <= insstart_less)
+ if ((int)ai_col <= insstart_less) {
ai_col = 0;
- else
+ } else {
ai_col -= insstart_less;
+ }
}
/*
@@ -1974,10 +1985,11 @@ void backspace_until_column(int col)
{
while ((int)curwin->w_cursor.col > col) {
curwin->w_cursor.col--;
- if (State & REPLACE_FLAG)
+ if (State & REPLACE_FLAG) {
replace_do_bs(col);
- else if (!del_char_after_col(col))
+ } else if (!del_char_after_col(col)) {
break;
+ }
}
}
@@ -2019,20 +2031,22 @@ static bool del_char_after_col(int limit_col)
*/
static void ins_ctrl_x(void)
{
- /* CTRL-X after CTRL-X CTRL-V doesn't do anything, so that CTRL-X
- * CTRL-V works like CTRL-N */
- if (ctrl_x_mode != CTRL_X_CMDLINE) {
- /* if the next ^X<> won't ADD nothing, then reset
- * compl_cont_status */
- if (compl_cont_status & CONT_N_ADDS)
+ if (ctrl_x_mode != CTRL_X_CMDLINE && ctrl_x_mode != CTRL_X_CMDLINE_CTRL_X) {
+ // if the next ^X<> won't ADD nothing, then reset compl_cont_status
+ if (compl_cont_status & CONT_N_ADDS) {
compl_cont_status |= CONT_INTRPT;
- else
+ } else {
compl_cont_status = 0;
+ }
// We're not sure which CTRL-X mode it will be yet
ctrl_x_mode = CTRL_X_NOT_DEFINED_YET;
edit_submode = (char_u *)_(CTRL_X_MSG(ctrl_x_mode));
edit_submode_pre = NULL;
showmode();
+ } else {
+ // CTRL-X in CTRL-X CTRL-V mode behaves differently to make CTRL-X
+ // CTRL-V look like CTRL-N
+ ctrl_x_mode = CTRL_X_CMDLINE_CTRL_X;
}
}
@@ -2042,7 +2056,8 @@ bool ctrl_x_mode_not_default(void)
return ctrl_x_mode != CTRL_X_NORMAL;
}
-// Whether CTRL-X was typed without a following character.
+// Whether CTRL-X was typed without a following character,
+// not including when in CTRL-X CTRL-V mode.
bool ctrl_x_mode_not_defined_yet(void)
{
return ctrl_x_mode == CTRL_X_NOT_DEFINED_YET;
@@ -2094,12 +2109,14 @@ bool vim_is_ctrl_x_key(int c)
case 0: // Not in any CTRL-X mode
return c == Ctrl_N || c == Ctrl_P || c == Ctrl_X;
case CTRL_X_NOT_DEFINED_YET:
+ case CTRL_X_CMDLINE_CTRL_X:
return c == Ctrl_X || c == Ctrl_Y || c == Ctrl_E
|| c == Ctrl_L || c == Ctrl_F || c == Ctrl_RSB
|| c == Ctrl_I || c == Ctrl_D || c == Ctrl_P
|| c == Ctrl_N || c == Ctrl_T || c == Ctrl_V
|| c == Ctrl_Q || c == Ctrl_U || c == Ctrl_O
- || c == Ctrl_S || c == Ctrl_K || c == 's';
+ || c == Ctrl_S || c == Ctrl_K || c == 's'
+ || c == Ctrl_Z;
case CTRL_X_SCROLL:
return c == Ctrl_Y || c == Ctrl_E;
case CTRL_X_WHOLE_LINE:
@@ -2153,6 +2170,7 @@ static bool ins_compl_accept_char(int c)
return vim_isfilec(c) && !vim_ispathsep(c);
case CTRL_X_CMDLINE:
+ case CTRL_X_CMDLINE_CTRL_X:
case CTRL_X_OMNI:
// Command line and Omni completion can work with just about any
// printable character, but do stop at white space.
@@ -2171,8 +2189,8 @@ static bool ins_compl_accept_char(int c)
/// the rest of the word to be in -- webb
///
/// @param[in] cont_s_ipos next ^X<> will set initial_pos
-int ins_compl_add_infercase(char_u *str_arg, int len, bool icase, char_u *fname,
- Direction dir, bool cont_s_ipos)
+int ins_compl_add_infercase(char_u *str_arg, int len, bool icase, char_u *fname, Direction dir,
+ bool cont_s_ipos)
FUNC_ATTR_NONNULL_ARG(1)
{
char_u *str = str_arg;
@@ -2315,15 +2333,12 @@ int ins_compl_add_infercase(char_u *str_arg, int len, bool icase, char_u *fname,
/// @return NOTDONE if the given string is already in the list of completions,
/// otherwise it is added to the list and OK is returned. FAIL will be
/// returned in case of error.
-static int ins_compl_add(char_u *const str, int len,
- char_u *const fname,
- char_u *const *const cptext,
- const bool cptext_allocated,
- typval_T *user_data,
- const Direction cdir, int flags_arg, const bool adup)
+static int ins_compl_add(char_u *const str, int len, char_u *const fname,
+ char_u *const *const cptext, const bool cptext_allocated,
+ typval_T *user_data, const Direction cdir, int flags_arg, const bool adup)
FUNC_ATTR_NONNULL_ARG(1)
{
- compl_T *match;
+ compl_T *match;
const Direction dir = (cdir == kDirectionNotSet ? compl_direction : cdir);
int flags = flags_arg;
@@ -2419,9 +2434,9 @@ static int ins_compl_add(char_u *const str, int len,
/*
* Link the new match structure in the list of matches.
*/
- if (compl_first_match == NULL)
+ if (compl_first_match == NULL) {
match->cp_next = match->cp_prev = NULL;
- else if (dir == FORWARD) {
+ } else if (dir == FORWARD) {
match->cp_next = compl_curr_match->cp_next;
match->cp_prev = compl_curr_match;
} else { // BACKWARD
@@ -2453,7 +2468,7 @@ static int ins_compl_add(char_u *const str, int len,
///
/// @param match completion match
/// @param str character string to check
-/// @param len lenth of "str"
+/// @param len length of "str"
static bool ins_compl_equal(compl_T *match, char_u *str, size_t len)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
@@ -2471,7 +2486,7 @@ static bool ins_compl_equal(compl_T *match, char_u *str, size_t len)
*/
static void ins_compl_longest_match(compl_T *match)
{
- char_u *p, *s;
+ char_u *p, *s;
int c1, c2;
int had_match;
@@ -2485,8 +2500,9 @@ static void ins_compl_longest_match(compl_T *match)
/* When the match isn't there (to avoid matching itself) remove it
* again after redrawing. */
- if (!had_match)
+ if (!had_match) {
ins_compl_delete();
+ }
compl_used_match = false;
} else {
// Reduce the text if this match differs from compl_leader.
@@ -2515,8 +2531,9 @@ static void ins_compl_longest_match(compl_T *match)
/* When the match isn't there (to avoid matching itself) remove it
* again after redrawing. */
- if (!had_match)
+ if (!had_match) {
ins_compl_delete();
+ }
}
compl_used_match = false;
@@ -2600,8 +2617,9 @@ void set_completion(colnr_T startcol, list_T *list)
ins_compl_free();
compl_direction = FORWARD;
- if (startcol > curwin->w_cursor.col)
+ if (startcol > curwin->w_cursor.col) {
startcol = curwin->w_cursor.col;
+ }
compl_col = startcol;
compl_length = (int)curwin->w_cursor.col - (int)startcol;
// compl_pattern doesn't need to be set
@@ -2724,8 +2742,8 @@ static void trigger_complete_changed_event(int cur)
/// Also adjusts "compl_shown_match" to an entry that is actually displayed.
void ins_compl_show_pum(void)
{
- compl_T *compl;
- compl_T *shown_compl = NULL;
+ compl_T *compl;
+ compl_T *shown_compl = NULL;
bool did_find_shown_match = false;
bool shown_match_ok = false;
int i;
@@ -2734,8 +2752,9 @@ void ins_compl_show_pum(void)
int lead_len = 0;
bool array_changed = false;
- if (!pum_wanted() || !pum_enough_matches())
+ if (!pum_wanted() || !pum_enough_matches()) {
return;
+ }
// Dirty hard-coded hack: remove any matchparen highlighting.
do_cmdline_cmd("if exists('g:loaded_matchparen')|3match none|endif");
@@ -2766,8 +2785,9 @@ void ins_compl_show_pum(void)
}
compl = compl->cp_next;
} while (compl != NULL && compl != compl_first_match);
- if (compl_match_arraysize == 0)
+ if (compl_match_arraysize == 0) {
return;
+ }
assert(compl_match_arraysize >= 0);
compl_match_array = xcalloc(compl_match_arraysize, sizeof(pumitem_T));
@@ -2798,18 +2818,20 @@ void ins_compl_show_pum(void)
cur = i;
}
- if (compl->cp_text[CPT_ABBR] != NULL)
+ if (compl->cp_text[CPT_ABBR] != NULL) {
compl_match_array[i].pum_text =
compl->cp_text[CPT_ABBR];
- else
+ } else {
compl_match_array[i].pum_text = compl->cp_str;
+ }
compl_match_array[i].pum_kind = compl->cp_text[CPT_KIND];
compl_match_array[i].pum_info = compl->cp_text[CPT_INFO];
- if (compl->cp_text[CPT_MENU] != NULL)
+ if (compl->cp_text[CPT_MENU] != NULL) {
compl_match_array[i++].pum_extra =
compl->cp_text[CPT_MENU];
- else
+ } else {
compl_match_array[i++].pum_extra = compl->cp_fname;
+ }
}
if (compl == compl_shown_match) {
@@ -2866,23 +2888,18 @@ void ins_compl_show_pum(void)
#define DICT_FIRST (1) // use just first element in "dict"
#define DICT_EXACT (2) // "dict" is the exact name of a file
-/*
- * Add any identifiers that match the given pattern in the list of dictionary
- * files "dict_start" to the list of completions.
- */
-static void
-ins_compl_dictionaries (
- char_u *dict_start,
- char_u *pat,
- int flags, // DICT_FIRST and/or DICT_EXACT
- int thesaurus // Thesaurus completion
-)
-{
- char_u *dict = dict_start;
- char_u *ptr;
- char_u *buf;
+/// Add any identifiers that match the given pattern in the list of dictionary
+/// files "dict_start" to the list of completions.
+///
+/// @param flags DICT_FIRST and/or DICT_EXACT
+/// @param thesaurus Thesaurus completion
+static void ins_compl_dictionaries(char_u *dict_start, char_u *pat, int flags, int thesaurus)
+{
+ char_u *dict = dict_start;
+ char_u *ptr;
+ char_u *buf;
regmatch_T regmatch;
- char_u **files;
+ char_u **files;
int count;
int save_p_scs;
Direction dir = compl_direction;
@@ -2890,10 +2907,11 @@ ins_compl_dictionaries (
if (*dict == NUL) {
/* When 'dictionary' is empty and spell checking is enabled use
* "spell". */
- if (!thesaurus && curwin->w_p_spell)
+ if (!thesaurus && curwin->w_p_spell) {
dict = (char_u *)"spell";
- else
+ } else {
return;
+ }
}
buf = xmalloc(LSIZE);
@@ -2901,8 +2919,9 @@ ins_compl_dictionaries (
// If 'infercase' is set, don't use 'smartcase' here
save_p_scs = p_scs;
- if (curbuf->b_p_inf)
+ if (curbuf->b_p_inf) {
p_scs = FALSE;
+ }
/* When invoked to match whole lines for CTRL-X CTRL-L adjust the pattern
* to only match at the start of a line. Otherwise just match the
@@ -2918,8 +2937,9 @@ ins_compl_dictionaries (
xfree(ptr);
} else {
regmatch.regprog = vim_regcomp(pat, p_magic ? RE_MAGIC : 0);
- if (regmatch.regprog == NULL)
+ if (regmatch.regprog == NULL) {
goto theend;
+ }
}
// ignore case depends on 'ignorecase', 'smartcase' and "pat"
@@ -2934,30 +2954,34 @@ ins_compl_dictionaries (
* backticks (for security, the 'dict' option may have been set in
* a modeline). */
copy_option_part(&dict, buf, LSIZE, ",");
- if (!thesaurus && STRCMP(buf, "spell") == 0)
+ if (!thesaurus && STRCMP(buf, "spell") == 0) {
count = -1;
- else if (vim_strchr(buf, '`') != NULL
- || expand_wildcards(1, &buf, &count, &files,
- EW_FILE|EW_SILENT) != OK)
+ } else if (vim_strchr(buf, '`') != NULL
+ || expand_wildcards(1, &buf, &count, &files,
+ EW_FILE|EW_SILENT) != OK) {
count = 0;
+ }
}
if (count == -1) {
/* Complete from active spelling. Skip "\<" in the pattern, we
* don't use it as a RE. */
- if (pat[0] == '\\' && pat[1] == '<')
+ if (pat[0] == '\\' && pat[1] == '<') {
ptr = pat + 2;
- else
+ } else {
ptr = pat;
+ }
spell_dump_compl(ptr, regmatch.rm_ic, &dir, 0);
} else if (count > 0) { // avoid warning for using "files" uninit
ins_compl_files(count, files, thesaurus, flags,
- &regmatch, buf, &dir);
- if (flags != DICT_EXACT)
+ &regmatch, buf, &dir);
+ if (flags != DICT_EXACT) {
FreeWild(count, files);
+ }
}
- if (flags != 0)
+ if (flags != 0) {
break;
+ }
}
theend:
@@ -2966,14 +2990,13 @@ theend:
xfree(buf);
}
-static void ins_compl_files(int count, char_u **files, int thesaurus,
- int flags, regmatch_T *regmatch, char_u *buf,
- Direction *dir)
+static void ins_compl_files(int count, char_u **files, int thesaurus, int flags,
+ regmatch_T *regmatch, char_u *buf, Direction *dir)
FUNC_ATTR_NONNULL_ARG(2, 7)
{
- char_u *ptr;
+ char_u *ptr;
int i;
- FILE *fp;
+ FILE *fp;
int add_r;
for (i = 0; i < count && !got_int && !compl_interrupted; i++) {
@@ -3016,8 +3039,9 @@ static void ins_compl_files(int count, char_u **files, int thesaurus,
/* Find start of the next word. Skip white
* space and punctuation. */
ptr = find_word_start(ptr);
- if (*ptr == NUL || *ptr == NL)
+ if (*ptr == NUL || *ptr == NL) {
break;
+ }
wstart = ptr;
// Find end of the word.
@@ -3095,11 +3119,12 @@ char_u *find_word_end(char_u *ptr)
*/
static char_u *find_line_end(char_u *ptr)
{
- char_u *s;
+ char_u *s;
s = ptr + STRLEN(ptr);
- while (s > ptr && (s[-1] == CAR || s[-1] == NL))
+ while (s > ptr && (s[-1] == CAR || s[-1] == NL)) {
--s;
+ }
return s;
}
@@ -3113,8 +3138,9 @@ static void ins_compl_free(void)
XFREE_CLEAR(compl_pattern);
XFREE_CLEAR(compl_leader);
- if (compl_first_match == NULL)
+ if (compl_first_match == NULL) {
return;
+ }
ins_compl_del_pum();
pum_clear();
@@ -3276,9 +3302,9 @@ void get_complete_info(list_T *what_list, dict_T *retdict)
tv_dict_add_str(di, S_LEN("info"),
(char *)EMPTY_IF_NULL(match->cp_text[CPT_INFO]));
if (match->cp_user_data.v_type == VAR_UNKNOWN) {
- tv_dict_add_str(di, S_LEN("user_data"), "");
+ tv_dict_add_str(di, S_LEN("user_data"), "");
} else {
- tv_dict_add_tv(di, S_LEN("user_data"), &match->cp_user_data);
+ tv_dict_add_tv(di, S_LEN("user_data"), &match->cp_user_data);
}
}
match = match->cp_next;
@@ -3301,7 +3327,7 @@ void get_complete_info(list_T *what_list, dict_T *retdict)
}
// Return Insert completion mode name string
-static char_u * ins_compl_mode(void)
+static char_u *ins_compl_mode(void)
{
if (ctrl_x_mode == CTRL_X_NOT_DEFINED_YET || compl_started) {
return (char_u *)ctrl_x_mode_names[ctrl_x_mode & ~CTRL_X_WANT_IDENT];
@@ -3318,12 +3344,10 @@ static char_u * ins_compl_mode(void)
*/
static int ins_compl_bs(void)
{
- char_u *line;
- char_u *p;
-
- line = get_cursor_line_ptr();
- p = line + curwin->w_cursor.col;
+ char_u *line = get_cursor_line_ptr();
+ char_u *p = line + curwin->w_cursor.col;
MB_PTR_BACK(line, p);
+ ptrdiff_t p_off = p - line;
// Stop completion when the whole word was deleted. For Omni completion
// allow the word to be deleted, we won't match everything.
@@ -3339,11 +3363,16 @@ static int ins_compl_bs(void)
/* Deleted more than what was used to find matches or didn't finish
* finding all matches: need to look for matches all over again. */
if (curwin->w_cursor.col <= compl_col + compl_length
- || ins_compl_need_restart())
+ || ins_compl_need_restart()) {
ins_compl_restart();
+ }
+
+ // ins_compl_restart() calls update_screen(0) which may invalidate the pointer
+ // TODO(bfredl): get rid of random update_screen() calls deep inside completion logic
+ line = get_cursor_line_ptr();
xfree(compl_leader);
- compl_leader = vim_strnsave(line + compl_col, (int)(p - line) - compl_col);
+ compl_leader = vim_strnsave(line + compl_col, (int)p_off - compl_col);
ins_compl_new_leader();
if (compl_shown_match != NULL) {
// Make sure current match is not a hidden item.
@@ -3397,8 +3426,9 @@ static void ins_compl_new_leader(void)
/* Don't let Enter select the original text when there is no popup menu.
* Don't let Enter select when use user function and refresh_always is set */
- if (compl_match_array == NULL || ins_compl_need_restart())
+ if (compl_match_array == NULL || ins_compl_need_restart()) {
compl_enter_selects = FALSE;
+ }
}
/*
@@ -3409,8 +3439,9 @@ static int ins_compl_len(void)
{
int off = (int)curwin->w_cursor.col - (int)compl_col;
- if (off < 0)
+ if (off < 0) {
return 0;
+ }
return off;
}
@@ -3423,7 +3454,7 @@ static void ins_compl_addleader(int c)
int cc;
if (stop_arrow() == FAIL) {
- return;
+ return;
}
if ((cc = utf_char2len(c)) > 1) {
char_u buf[MB_MAXBYTES + 1];
@@ -3488,10 +3519,10 @@ static void ins_compl_set_original_text(char_u *str)
*/
static void ins_compl_addfrommatch(void)
{
- char_u *p;
+ char_u *p;
int len = (int)curwin->w_cursor.col - (int)compl_col;
int c;
- compl_T *cp;
+ compl_T *cp;
assert(compl_shown_match != NULL);
p = compl_shown_match->cp_str;
if ((int)STRLEN(p) <= len) { // the match is too short
@@ -3503,15 +3534,17 @@ static void ins_compl_addfrommatch(void)
&& cp != compl_first_match; cp = cp->cp_next) {
if (compl_leader == NULL
|| ins_compl_equal(cp, compl_leader,
- (int)STRLEN(compl_leader))) {
+ (int)STRLEN(compl_leader))) {
p = cp->cp_str;
break;
}
}
- if (p == NULL || (int)STRLEN(p) <= len)
+ if (p == NULL || (int)STRLEN(p) <= len) {
return;
- } else
+ }
+ } else {
return;
+ }
}
p += len;
c = PTR2CHAR(p);
@@ -3533,8 +3566,9 @@ static bool ins_compl_prep(int c)
/* Forget any previous 'special' messages if this is actually
* a ^X mode key - bar ^R, in which case we wait to see what it gives us.
*/
- if (c != Ctrl_R && vim_is_ctrl_x_key(c))
+ if (c != Ctrl_R && vim_is_ctrl_x_key(c)) {
edit_submode_extra = NULL;
+ }
// Ignore end of Select mode mapping and mouse scroll buttons.
if (c == K_SELECT || c == K_MOUSEDOWN || c == K_MOUSEUP
@@ -3543,6 +3577,26 @@ static bool ins_compl_prep(int c)
return retval;
}
+ if (ctrl_x_mode == CTRL_X_CMDLINE_CTRL_X && c != Ctrl_X) {
+ if (c == Ctrl_V || c == Ctrl_Q || c == Ctrl_Z || ins_compl_pum_key(c)
+ || !vim_is_ctrl_x_key(c)) {
+ // Not starting another completion mode.
+ ctrl_x_mode = CTRL_X_CMDLINE;
+
+ // CTRL-X CTRL-Z should stop completion without inserting anything
+ if (c == Ctrl_Z) {
+ retval = true;
+ }
+ } else {
+ ctrl_x_mode = CTRL_X_CMDLINE;
+
+ // Other CTRL-X keys first stop completion, then start another
+ // completion mode.
+ ins_compl_prep(' ');
+ ctrl_x_mode = CTRL_X_NOT_DEFINED_YET;
+ }
+ }
+
// Set "compl_get_longest" when finding the first matches.
if (ctrl_x_mode == CTRL_X_NOT_DEFINED_YET
|| (ctrl_x_mode == CTRL_X_NORMAL && !compl_started)) {
@@ -3559,10 +3613,11 @@ static bool ins_compl_prep(int c)
case Ctrl_E:
case Ctrl_Y:
ctrl_x_mode = CTRL_X_SCROLL;
- if (!(State & REPLACE_FLAG))
+ if (!(State & REPLACE_FLAG)) {
edit_submode = (char_u *)_(" (insert) Scroll (^E/^Y)");
- else
+ } else {
edit_submode = (char_u *)_(" (replace) Scroll (^E/^Y)");
+ }
edit_submode_pre = NULL;
showmode();
break;
@@ -3608,6 +3663,12 @@ static bool ins_compl_prep(int c)
case Ctrl_Q:
ctrl_x_mode = CTRL_X_CMDLINE;
break;
+ case Ctrl_Z:
+ ctrl_x_mode = CTRL_X_NORMAL;
+ edit_submode = NULL;
+ showmode();
+ retval = true;
+ break;
case Ctrl_P:
case Ctrl_N:
/* ^X^P means LOCAL expansion if nothing interrupted (eg we
@@ -3617,10 +3678,11 @@ static bool ins_compl_prep(int c)
* ^X^F^X^P or ^P^X^X^P, see below)
* nothing changes if interrupting mode 0, (eg, the flag
* doesn't change when going to ADDING mode -- Acevedo */
- if (!(compl_cont_status & CONT_INTRPT))
+ if (!(compl_cont_status & CONT_INTRPT)) {
compl_cont_status |= CONT_LOCAL;
- else if (compl_cont_mode != 0)
+ } else if (compl_cont_mode != 0) {
compl_cont_status &= ~CONT_LOCAL;
+ }
FALLTHROUGH;
default:
/* If we have typed at least 2 ^X's... for modes != 0, we set
@@ -3634,10 +3696,11 @@ static bool ins_compl_prep(int c)
* In mode 0 an extra ^X is needed since ^X^P goes to ADDING
* mode -- Acevedo */
if (c == Ctrl_X) {
- if (compl_cont_mode != 0)
+ if (compl_cont_mode != 0) {
compl_cont_status = 0;
- else
+ } else {
compl_cont_mode = CTRL_X_NOT_DEFINED_YET;
+ }
}
ctrl_x_mode = CTRL_X_NORMAL;
edit_submode = NULL;
@@ -3680,10 +3743,11 @@ static bool ins_compl_prep(int c)
* When using the longest match, edited the match or used
* CTRL-E then don't use the current match.
*/
- if (compl_curr_match != NULL && compl_used_match && c != Ctrl_E)
+ if (compl_curr_match != NULL && compl_used_match && c != Ctrl_E) {
ptr = compl_curr_match->cp_str;
- else
+ } else {
ptr = NULL;
+ }
ins_compl_fixRedoBufForLeader(ptr);
}
@@ -3765,16 +3829,18 @@ static bool ins_compl_prep(int c)
/*
* Indent now if a key was typed that is in 'cinkeys'.
*/
- if (want_cindent && in_cinkeys(KEY_COMPLETE, ' ', inindent(0)))
+ if (want_cindent && in_cinkeys(KEY_COMPLETE, ' ', inindent(0))) {
do_c_expr_indent();
+ }
// Trigger the CompleteDone event to give scripts a chance to act
// upon the end of completion.
ins_apply_autocmds(EVENT_COMPLETEDONE);
}
- } else if (ctrl_x_mode == CTRL_X_LOCAL_MSG)
+ } else if (ctrl_x_mode == CTRL_X_LOCAL_MSG) {
/* Trigger the CompleteDone event to give scripts a chance to act
* upon the (possibly failed) completion. */
ins_apply_autocmds(EVENT_COMPLETEDONE);
+ }
/* reset continue_* if we left expansion-mode, if we stay they'll be
* (re)set properly in ins_complete() */
@@ -3794,8 +3860,8 @@ static bool ins_compl_prep(int c)
static void ins_compl_fixRedoBufForLeader(char_u *ptr_arg)
{
int len;
- char_u *p;
- char_u *ptr = ptr_arg;
+ char_u *p;
+ char_u *ptr = ptr_arg;
if (ptr == NULL) {
if (compl_leader != NULL) {
@@ -3822,7 +3888,7 @@ static void ins_compl_fixRedoBufForLeader(char_u *ptr_arg)
/*
* Loops through the list of windows, loaded-buffers or non-loaded-buffers
* (depending on flag) starting from buf and looking for a non-scanned
- * buffer (other than curbuf). curbuf is special, if it is called with
+ * buffer (other than curbuf). curbuf is special, if it is called with
* buf=curbuf then it has to be the first call for a given flag/expansion.
*
* Returns the buffer to scan, if any, otherwise returns curbuf -- Acevedo
@@ -3837,10 +3903,11 @@ static buf_T *ins_compl_next_buf(buf_T *buf, int flag)
}
assert(wp);
while ((wp = (wp->w_next != NULL ? wp->w_next : firstwin)) != curwin
- && wp->w_buffer->b_scanned)
+ && wp->w_buffer->b_scanned) {
;
+ }
buf = wp->w_buffer;
- } else
+ } else {
/* 'b' (just loaded buffers), 'u' (just non-loaded buffers) or 'U'
* (unlisted buffers)
* When completing whole lines skip unloaded buffers. */
@@ -3849,19 +3916,19 @@ static buf_T *ins_compl_next_buf(buf_T *buf, int flag)
? buf->b_p_bl
: (!buf->b_p_bl
|| (buf->b_ml.ml_mfp == NULL) != (flag == 'u')))
- || buf->b_scanned))
+ || buf->b_scanned)) {
;
+ }
+ }
return buf;
}
-// Execute user defined complete function 'completefunc' or 'omnifunc', and
-// get matches in "matches".
-static void
-expand_by_function(
- int type, // CTRL_X_OMNI or CTRL_X_FUNCTION
- char_u *base
-)
+/// Execute user defined complete function 'completefunc' or 'omnifunc', and
+/// get matches in "matches".
+///
+/// @param type CTRL_X_OMNI or CTRL_X_FUNCTION
+static void expand_by_function(int type, char_u *base)
{
list_T *matchlist = NULL;
dict_T *matchdict = NULL;
@@ -3919,10 +3986,11 @@ expand_by_function(
goto theend;
}
- if (matchlist != NULL)
+ if (matchlist != NULL) {
ins_compl_add_list(matchlist);
- else if (matchdict != NULL)
+ } else if (matchdict != NULL) {
ins_compl_add_dict(matchdict);
+ }
theend:
// Restore State, it might have been changed.
@@ -3959,8 +4027,8 @@ static void ins_compl_add_list(list_T *const list)
*/
static void ins_compl_add_dict(dict_T *dict)
{
- dictitem_T *di_refresh;
- dictitem_T *di_words;
+ dictitem_T *di_refresh;
+ dictitem_T *di_words;
// Check for optional "refresh" item.
compl_opt_refresh_always = false;
@@ -4018,7 +4086,7 @@ int ins_compl_add_tv(typval_T *const tv, const Direction dir, bool fast)
flags |= CP_EQUAL;
}
} else {
- word = (const char *)tv_get_string_chk(tv);
+ word = tv_get_string_chk(tv);
memset(cptext, 0, sizeof(cptext));
}
if (word == NULL || (!empty && *word == NUL)) {
@@ -4043,7 +4111,7 @@ static int ins_compl_get_exp(pos_T *ini)
static pos_T first_match_pos;
static pos_T last_match_pos;
static char_u *e_cpt = (char_u *)""; // curr. entry in 'complete'
- static int found_all = false; // Found all matches of a
+ static bool found_all = false; // Found all matches of a
// certain type.
static buf_T *ins_buf = NULL; // buffer being scanned
@@ -4060,7 +4128,8 @@ static int ins_compl_get_exp(pos_T *ini)
char_u *ptr;
char_u *dict = NULL;
int dict_f = 0;
- int set_match_pos;
+ bool set_match_pos;
+ pos_T prev_pos = { 0, 0, 0 };
int l_ctrl_x_mode = ctrl_x_mode;
assert(curbuf != NULL);
@@ -4069,7 +4138,7 @@ static int ins_compl_get_exp(pos_T *ini)
FOR_ALL_BUFFERS(buf) {
buf->b_scanned = false;
}
- found_all = FALSE;
+ found_all = false;
ins_buf = curbuf;
e_cpt = (compl_cont_status & CONT_LOCAL)
? (char_u *)"." : curbuf->b_p_cpt;
@@ -4084,7 +4153,7 @@ static int ins_compl_get_exp(pos_T *ini)
// For ^N/^P loop over all the flags/windows/buffers in 'complete'
for (;; ) {
found_new_match = FAIL;
- set_match_pos = FALSE;
+ set_match_pos = false;
assert(l_ctrl_x_mode == ctrl_x_mode);
@@ -4094,9 +4163,10 @@ static int ins_compl_get_exp(pos_T *ini)
if ((l_ctrl_x_mode == CTRL_X_NORMAL
|| CTRL_X_MODE_LINE_OR_EVAL(l_ctrl_x_mode))
&& (!compl_started || found_all)) {
- found_all = FALSE;
- while (*e_cpt == ',' || *e_cpt == ' ')
+ found_all = false;
+ while (*e_cpt == ',' || *e_cpt == ' ') {
e_cpt++;
+ }
if (*e_cpt == '.' && !curbuf->b_scanned) {
ins_buf = curbuf;
first_match_pos = *ini;
@@ -4117,7 +4187,7 @@ static int ins_compl_get_exp(pos_T *ini)
set_match_pos = true;
} else if (vim_strchr((char_u *)"buwU", *e_cpt) != NULL
&& (ins_buf =
- ins_compl_next_buf(ins_buf, *e_cpt)) != curbuf) {
+ ins_compl_next_buf(ins_buf, *e_cpt)) != curbuf) {
// Scan a buffer, but not the current one.
if (ins_buf->b_ml.ml_mfp != NULL) { // loaded buffer
compl_started = true;
@@ -4148,10 +4218,11 @@ static int ins_compl_get_exp(pos_T *ini)
if (CTRL_X_MODE_LINE_OR_EVAL(l_ctrl_x_mode)) {
type = -1;
} else if (*e_cpt == 'k' || *e_cpt == 's') {
- if (*e_cpt == 'k')
+ if (*e_cpt == 'k') {
type = CTRL_X_DICTIONARY;
- else
+ } else {
type = CTRL_X_THESAURUS;
+ }
if (*++e_cpt != ',' && *e_cpt != NUL) {
dict = e_cpt;
dict_f = DICT_FIRST;
@@ -4172,9 +4243,10 @@ static int ins_compl_get_exp(pos_T *ini)
// in any case e_cpt is advanced to the next entry
(void)copy_option_part(&e_cpt, IObuff, IOSIZE, ",");
- found_all = TRUE;
- if (type == -1)
+ found_all = true;
+ if (type == -1) {
continue;
+ }
}
}
@@ -4200,18 +4272,17 @@ static int ins_compl_get_exp(pos_T *ini)
case CTRL_X_DICTIONARY:
case CTRL_X_THESAURUS:
- ins_compl_dictionaries(
- dict != NULL ? dict
- : (type == CTRL_X_THESAURUS
+ ins_compl_dictionaries(dict != NULL ? dict
+ : (type == CTRL_X_THESAURUS
? (*curbuf->b_p_tsr == NUL
? p_tsr
: curbuf->b_p_tsr)
- : (*curbuf->b_p_dict == NUL
+ : (*curbuf->b_p_dict == NUL
? p_dict
: curbuf->b_p_dict)),
- compl_pattern,
- dict != NULL ? dict_f
- : 0, type == CTRL_X_THESAURUS);
+ compl_pattern,
+ dict != NULL ? dict_f
+ : 0, type == CTRL_X_THESAURUS);
dict = NULL;
break;
@@ -4241,7 +4312,7 @@ static int ins_compl_get_exp(pos_T *ini)
#ifdef BACKSLASH_IN_FILENAME
if (curbuf->b_p_csl[0] != NUL) {
for (int i = 0; i < num_matches; i++) {
- char_u *ptr = matches[i];
+ char_u *ptr = matches[i];
while (*ptr != NUL) {
if (curbuf->b_p_csl[0] == 's' && *ptr == '\\') {
*ptr = '/';
@@ -4258,10 +4329,12 @@ static int ins_compl_get_exp(pos_T *ini)
break;
case CTRL_X_CMDLINE:
+ case CTRL_X_CMDLINE_CTRL_X:
if (expand_cmdline(&compl_xp, compl_pattern,
- (int)STRLEN(compl_pattern),
- &num_matches, &matches) == EXPAND_OK)
- ins_compl_add_matches(num_matches, matches, FALSE);
+ (int)STRLEN(compl_pattern),
+ &num_matches, &matches) == EXPAND_OK) {
+ ins_compl_add_matches(num_matches, matches, false);
+ }
break;
case CTRL_X_FUNCTION:
@@ -4271,27 +4344,31 @@ static int ins_compl_get_exp(pos_T *ini)
case CTRL_X_SPELL:
num_matches = expand_spelling(first_match_pos.lnum,
- compl_pattern, &matches);
- if (num_matches > 0)
+ compl_pattern, &matches);
+ if (num_matches > 0) {
ins_compl_add_matches(num_matches, matches, p_ic);
+ }
break;
default: // normal ^P/^N and ^X^L
// If 'infercase' is set, don't use 'smartcase' here
save_p_scs = p_scs;
assert(ins_buf);
- if (ins_buf->b_p_inf)
+ if (ins_buf->b_p_inf) {
p_scs = FALSE;
+ }
// Buffers other than curbuf are scanned from the beginning or the
// end but never from the middle, thus setting nowrapscan in this
// buffers is a good idea, on the other hand, we always set
// wrapscan for curbuf to avoid missing matches -- Acevedo,Webb
save_p_ws = p_ws;
- if (ins_buf != curbuf)
+ if (ins_buf != curbuf) {
p_ws = false;
- else if (*e_cpt == '.')
+ } else if (*e_cpt == '.') {
p_ws = true;
+ }
+ bool looped_around = false;
for (;; ) {
bool cont_s_ipos = false;
@@ -4320,10 +4397,30 @@ static int ins_compl_get_exp(pos_T *ini)
} else if (first_match_pos.lnum == last_match_pos.lnum
&& first_match_pos.col == last_match_pos.col) {
found_new_match = FAIL;
+ } else if ((compl_direction == FORWARD)
+ && (prev_pos.lnum > pos->lnum
+ || (prev_pos.lnum == pos->lnum
+ && prev_pos.col >= pos->col))) {
+ if (looped_around) {
+ found_new_match = FAIL;
+ } else {
+ looped_around = true;
+ }
+ } else if ((compl_direction != FORWARD)
+ && (prev_pos.lnum < pos->lnum
+ || (prev_pos.lnum == pos->lnum
+ && prev_pos.col <= pos->col))) {
+ if (looped_around) {
+ found_new_match = FAIL;
+ } else {
+ looped_around = true;
+ }
}
+ prev_pos = *pos;
if (found_new_match == FAIL) {
- if (ins_buf == curbuf)
- found_all = TRUE;
+ if (ins_buf == curbuf) {
+ found_all = true;
+ }
break;
}
@@ -4398,13 +4495,13 @@ static int ins_compl_get_exp(pos_T *ini)
IObuff[len] = NUL;
ptr = IObuff;
}
- if (len == compl_length)
+ if (len == compl_length) {
continue;
+ }
}
}
- if (ins_compl_add_infercase(
- ptr, len, p_ic, ins_buf == curbuf ? NULL : ins_buf->b_sfname,
- 0, cont_s_ipos) != NOTDONE) {
+ if (ins_compl_add_infercase(ptr, len, p_ic, ins_buf == curbuf ? NULL : ins_buf->b_sfname,
+ 0, cont_s_ipos) != NOTDONE) {
found_new_match = OK;
break;
}
@@ -4424,8 +4521,9 @@ static int ins_compl_get_exp(pos_T *ini)
if ((l_ctrl_x_mode != CTRL_X_NORMAL
&& !CTRL_X_MODE_LINE_OR_EVAL(l_ctrl_x_mode))
|| found_new_match != FAIL) {
- if (got_int)
+ if (got_int) {
break;
+ }
// Fill the popup menu as soon as possible.
if (type != -1) {
ins_compl_check_keys(0, false);
@@ -4517,21 +4615,16 @@ static dict_T *ins_compl_dict_alloc(compl_T *match)
{
// { word, abbr, menu, kind, info }
dict_T *dict = tv_dict_alloc_lock(VAR_FIXED);
- tv_dict_add_str(
- dict, S_LEN("word"),
- (const char *)EMPTY_IF_NULL(match->cp_str));
- tv_dict_add_str(
- dict, S_LEN("abbr"),
- (const char *)EMPTY_IF_NULL(match->cp_text[CPT_ABBR]));
- tv_dict_add_str(
- dict, S_LEN("menu"),
- (const char *)EMPTY_IF_NULL(match->cp_text[CPT_MENU]));
- tv_dict_add_str(
- dict, S_LEN("kind"),
- (const char *)EMPTY_IF_NULL(match->cp_text[CPT_KIND]));
- tv_dict_add_str(
- dict, S_LEN("info"),
- (const char *)EMPTY_IF_NULL(match->cp_text[CPT_INFO]));
+ tv_dict_add_str(dict, S_LEN("word"),
+ (const char *)EMPTY_IF_NULL(match->cp_str));
+ tv_dict_add_str(dict, S_LEN("abbr"),
+ (const char *)EMPTY_IF_NULL(match->cp_text[CPT_ABBR]));
+ tv_dict_add_str(dict, S_LEN("menu"),
+ (const char *)EMPTY_IF_NULL(match->cp_text[CPT_MENU]));
+ tv_dict_add_str(dict, S_LEN("kind"),
+ (const char *)EMPTY_IF_NULL(match->cp_text[CPT_KIND]));
+ tv_dict_add_str(dict, S_LEN("info"),
+ (const char *)EMPTY_IF_NULL(match->cp_text[CPT_INFO]));
if (match->cp_user_data.v_type == VAR_UNKNOWN) {
tv_dict_add_str(dict, S_LEN("user_data"), "");
} else {
@@ -4540,30 +4633,25 @@ static dict_T *ins_compl_dict_alloc(compl_T *match)
return dict;
}
-/*
- * Fill in the next completion in the current direction.
- * If "allow_get_expansion" is TRUE, then we may call ins_compl_get_exp() to
- * get more completions. If it is FALSE, then we just do nothing when there
- * are no more completions in a given direction. The latter case is used when
- * we are still in the middle of finding completions, to allow browsing
- * through the ones found so far.
- * Return the total number of matches, or -1 if still unknown -- webb.
- *
- * compl_curr_match is currently being used by ins_compl_get_exp(), so we use
- * compl_shown_match here.
- *
- * Note that this function may be called recursively once only. First with
- * "allow_get_expansion" TRUE, which calls ins_compl_get_exp(), which in turn
- * calls this function with "allow_get_expansion" FALSE.
- */
-static int
-ins_compl_next (
- int allow_get_expansion,
- int count, // Repeat completion this many times; should
- // be at least 1
- int insert_match, // Insert the newly selected match
- int in_compl_func // Called from complete_check()
-)
+/// Fill in the next completion in the current direction.
+/// If "allow_get_expansion" is TRUE, then we may call ins_compl_get_exp() to
+/// get more completions. If it is FALSE, then we just do nothing when there
+/// are no more completions in a given direction. The latter case is used when
+/// we are still in the middle of finding completions, to allow browsing
+/// through the ones found so far.
+/// @return the total number of matches, or -1 if still unknown -- webb.
+///
+/// compl_curr_match is currently being used by ins_compl_get_exp(), so we use
+/// compl_shown_match here.
+///
+/// Note that this function may be called recursively once only. First with
+/// "allow_get_expansion" TRUE, which calls ins_compl_get_exp(), which in turn
+/// calls this function with "allow_get_expansion" FALSE.
+///
+/// @param count Repeat completion this many times; should be at least 1
+/// @param insert_match Insert the newly selected match
+/// @param in_compl_func Called from complete_check()
+static int ins_compl_next(int allow_get_expansion, int count, int insert_match, int in_compl_func)
{
int num_matches = -1;
int todo = count;
@@ -4573,8 +4661,9 @@ ins_compl_next (
/* When user complete function return -1 for findstart which is next
* time of 'always', compl_shown_match become NULL. */
- if (compl_shown_match == NULL)
+ if (compl_shown_match == NULL) {
return -1;
+ }
if (compl_leader != NULL
&& (compl_shown_match->cp_flags & CP_ORIGINAL_TEXT) == 0) {
@@ -4591,21 +4680,23 @@ ins_compl_next (
* backward, find the last match. */
if (compl_shows_dir == BACKWARD
&& !ins_compl_equal(compl_shown_match,
- compl_leader, (int)STRLEN(compl_leader))
+ compl_leader, (int)STRLEN(compl_leader))
&& (compl_shown_match->cp_next == NULL
|| compl_shown_match->cp_next == compl_first_match)) {
while (!ins_compl_equal(compl_shown_match,
- compl_leader, (int)STRLEN(compl_leader))
+ compl_leader, (int)STRLEN(compl_leader))
&& compl_shown_match->cp_prev != NULL
- && compl_shown_match->cp_prev != compl_first_match)
+ && compl_shown_match->cp_prev != compl_first_match) {
compl_shown_match = compl_shown_match->cp_prev;
+ }
}
}
if (allow_get_expansion && insert_match
- && (!(compl_get_longest || compl_restarting) || compl_used_match))
+ && (!(compl_get_longest || compl_restarting) || compl_used_match)) {
// Delete old text to be replaced
ins_compl_delete();
+ }
// When finding the longest common text we stick at the original text,
// don't let CTRL-N or CTRL-P move to the first match.
@@ -4633,19 +4724,21 @@ ins_compl_next (
} else {
if (!allow_get_expansion) {
if (advance) {
- if (compl_shows_dir == BACKWARD)
+ if (compl_shows_dir == BACKWARD) {
compl_pending -= todo + 1;
- else
+ } else {
compl_pending += todo + 1;
+ }
}
return -1;
}
if (!compl_no_select && advance) {
- if (compl_shows_dir == BACKWARD)
+ if (compl_shows_dir == BACKWARD) {
--compl_pending;
- else
+ } else {
++compl_pending;
+ }
}
// Find matches.
@@ -4661,8 +4754,9 @@ ins_compl_next (
if (compl_pending < 0 && compl_shown_match->cp_prev != NULL) {
compl_shown_match = compl_shown_match->cp_prev;
++compl_pending;
- } else
+ } else {
break;
+ }
}
found_end = false;
}
@@ -4727,8 +4821,8 @@ ins_compl_next (
if (compl_shown_match->cp_fname != NULL) {
char *lead = _("match in file");
int space = sc_col - vim_strsize((char_u *)lead) - 2;
- char_u *s;
- char_u *e;
+ char_u *s;
+ char_u *e;
if (space > 0) {
// We need the tail that fits. With double-byte encoding going
@@ -4796,7 +4890,7 @@ void ins_compl_check_keys(int frequency, int in_compl_func)
c = safe_vgetc(); // Eat the character
compl_shows_dir = ins_compl_key2dir(c);
(void)ins_compl_next(false, ins_compl_key2count(c),
- c != K_UP && c != K_DOWN, in_compl_func);
+ c != K_UP && c != K_DOWN, in_compl_func);
} else {
/* Need to get the character to have KeyTyped set. We'll put it
* back with vungetc() below. But skip K_IGNORE. */
@@ -4804,8 +4898,9 @@ void ins_compl_check_keys(int frequency, int in_compl_func)
if (c != K_IGNORE) {
/* Don't interrupt completion when the character wasn't typed,
* e.g., when doing @q to replay keys. */
- if (c != Ctrl_R && KeyTyped)
+ if (c != Ctrl_R && KeyTyped) {
compl_interrupted = TRUE;
+ }
vungetc(c);
}
@@ -4901,7 +4996,7 @@ static bool ins_compl_use_match(int c)
*/
static int ins_complete(int c, bool enable_pum)
{
- char_u *line;
+ char_u *line;
int startcol = 0; // column where searched text starts
colnr_T curs_col; // cursor column
int n;
@@ -4960,9 +5055,8 @@ static int ins_complete(int c, bool enable_pum)
* mode but first we need to redefine compl_startpos */
if (compl_cont_status & CONT_S_IPOS) {
compl_cont_status |= CONT_SOL;
- compl_startpos.col = (colnr_T)(skipwhite(
- line + compl_length
- + compl_startpos.col) - line);
+ compl_startpos.col = (colnr_T)(skipwhite(line + compl_length
+ + compl_startpos.col) - line);
}
compl_col = compl_startpos.col;
}
@@ -4976,14 +5070,17 @@ static int ins_complete(int c, bool enable_pum)
compl_col = curwin->w_cursor.col - compl_length;
}
compl_cont_status |= CONT_ADDING | CONT_N_ADDS;
- if (compl_length < 1)
+ if (compl_length < 1) {
compl_cont_status &= CONT_LOCAL;
+ }
} else if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)) {
compl_cont_status = CONT_ADDING | CONT_N_ADDS;
- } else
+ } else {
compl_cont_status = 0;
- } else
+ }
+ } else {
compl_cont_status &= CONT_LOCAL;
+ }
if (!(compl_cont_status & CONT_ADDING)) { // normal expansion
compl_cont_mode = ctrl_x_mode;
@@ -5002,27 +5099,30 @@ static int ins_complete(int c, bool enable_pum)
if ((compl_cont_status & CONT_SOL)
|| ctrl_x_mode == CTRL_X_PATH_DEFINES) {
if (!(compl_cont_status & CONT_ADDING)) {
- while (--startcol >= 0 && vim_isIDc(line[startcol]))
+ while (--startcol >= 0 && vim_isIDc(line[startcol])) {
;
+ }
compl_col += ++startcol;
compl_length = curs_col - startcol;
}
- if (p_ic)
+ if (p_ic) {
compl_pattern = str_foldcase(line + compl_col, compl_length, NULL, 0);
- else
+ } else {
compl_pattern = vim_strnsave(line + compl_col, compl_length);
+ }
} else if (compl_cont_status & CONT_ADDING) {
- char_u *prefix = (char_u *)"\\<";
+ char_u *prefix = (char_u *)"\\<";
// we need up to 2 extra chars for the prefix
compl_pattern = xmalloc(quote_meta(NULL, line + compl_col,
- compl_length) + 2);
+ compl_length) + 2);
if (!vim_iswordp(line + compl_col)
|| (compl_col > 0
&& (
- vim_iswordp(mb_prevptr(line, line + compl_col))
- )))
+ vim_iswordp(mb_prevptr(line, line + compl_col))
+ ))) {
prefix = (char_u *)"";
+ }
STRCPY((char *)compl_pattern, prefix);
(void)quote_meta(compl_pattern + STRLEN(prefix),
line + compl_col, compl_length);
@@ -5057,10 +5157,10 @@ static int ins_complete(int c, bool enable_pum)
STRCAT((char *)compl_pattern, "\\k");
} else {
compl_pattern = xmalloc(quote_meta(NULL, line + compl_col,
- compl_length) + 2);
+ compl_length) + 2);
STRCPY((char *)compl_pattern, "\\<");
(void)quote_meta(compl_pattern + 2, line + compl_col,
- compl_length);
+ compl_length);
}
}
} else if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)) {
@@ -5077,7 +5177,7 @@ static int ins_complete(int c, bool enable_pum)
} else if (ctrl_x_mode == CTRL_X_FILES) {
// Go back to just before the first filename character.
if (startcol > 0) {
- char_u *p = line + startcol;
+ char_u *p = line + startcol;
MB_PTR_BACK(line, p);
while (p > line && vim_isfilec(PTR2CHAR(p))) {
@@ -5093,7 +5193,7 @@ static int ins_complete(int c, bool enable_pum)
compl_col += startcol;
compl_length = (int)curs_col - startcol;
compl_pattern = addstar(line + compl_col, compl_length, EXPAND_FILES);
- } else if (ctrl_x_mode == CTRL_X_CMDLINE) {
+ } else if (ctrl_x_mode == CTRL_X_CMDLINE || ctrl_x_mode == CTRL_X_CMDLINE_CTRL_X) {
compl_pattern = vim_strnsave(line, curs_col);
set_cmd_context(&compl_xp, compl_pattern,
(int)STRLEN(compl_pattern), curs_col, false);
@@ -5112,10 +5212,10 @@ static int ins_complete(int c, bool enable_pum)
* Call user defined function 'completefunc' with "a:findstart"
* set to 1 to obtain the length of text to use for completion.
*/
- char_u *funcname;
+ char_u *funcname;
pos_T pos;
- win_T *curwin_save;
- buf_T *curbuf_save;
+ win_T *curwin_save;
+ buf_T *curbuf_save;
const int save_State = State;
/* Call 'completefunc' or 'omnifunc' and get pattern length as a
@@ -5157,8 +5257,9 @@ static int ins_complete(int c, bool enable_pum)
/* Return value -2 means the user complete function wants to
* cancel the complete without an error.
* Return value -3 does the same as -2 and leaves CTRL-X mode.*/
- if (col == -2)
+ if (col == -2) {
return FAIL;
+ }
if (col == -3) {
ctrl_x_mode = CTRL_X_NORMAL;
edit_submode = NULL;
@@ -5168,17 +5269,17 @@ static int ins_complete(int c, bool enable_pum)
return FAIL;
}
- /*
- * Reset extended parameters of completion, when start new
- * completion.
- */
- compl_opt_refresh_always = FALSE;
+ // Reset extended parameters of completion, when start new
+ // completion.
+ compl_opt_refresh_always = false;
- if (col < 0)
+ if (col < 0) {
col = curs_col;
+ }
compl_col = col;
- if (compl_col > curs_col)
+ if (compl_col > curs_col) {
compl_col = curs_col;
+ }
/* Setup variables for completion. Need to obtain "line" again,
* it may have become invalid. */
@@ -5189,9 +5290,9 @@ static int ins_complete(int c, bool enable_pum)
if (spell_bad_len > 0) {
assert(spell_bad_len <= INT_MAX);
compl_col = curs_col - (int)spell_bad_len;
- }
- else
+ } else {
compl_col = spell_word_start(startcol);
+ }
if (compl_col >= (colnr_T)startcol) {
compl_length = 0;
compl_col = curs_col;
@@ -5226,10 +5327,11 @@ static int ins_complete(int c, bool enable_pum)
compl_startpos.col = compl_col;
}
- if (compl_cont_status & CONT_LOCAL)
+ if (compl_cont_status & CONT_LOCAL) {
edit_submode = (char_u *)_(ctrl_x_msgs[CTRL_X_LOCAL_MSG]);
- else
+ } else {
edit_submode = (char_u *)_(CTRL_X_MSG(ctrl_x_mode));
+ }
/* If any of the original typed text has been changed we need to fix
* the redo buffer. */
@@ -5334,14 +5436,15 @@ static int ins_complete(int c, bool enable_pum)
* Translations may need more than twice that. */
static char_u match_ref[81];
- if (compl_matches > 0)
+ if (compl_matches > 0) {
vim_snprintf((char *)match_ref, sizeof(match_ref),
- _("match %d of %d"),
- compl_curr_match->cp_number, compl_matches);
- else
+ _("match %d of %d"),
+ compl_curr_match->cp_number, compl_matches);
+ } else {
vim_snprintf((char *)match_ref, sizeof(match_ref),
- _("match %d"),
- compl_curr_match->cp_number);
+ _("match %d"),
+ compl_curr_match->cp_number);
+ }
edit_submode_extra = match_ref;
edit_submode_highl = HLF_R;
if (dollar_vcol >= 0) {
@@ -5393,8 +5496,9 @@ static unsigned quote_meta(char_u *dest, char_u *src, int len)
case '*':
case '[':
if (ctrl_x_mode == CTRL_X_DICTIONARY
- || ctrl_x_mode == CTRL_X_THESAURUS)
+ || ctrl_x_mode == CTRL_X_THESAURUS) {
break;
+ }
FALLTHROUGH;
case '~':
if (!p_magic) { // quote these only if magic is set
@@ -5403,8 +5507,9 @@ static unsigned quote_meta(char_u *dest, char_u *src, int len)
FALLTHROUGH;
case '\\':
if (ctrl_x_mode == CTRL_X_DICTIONARY
- || ctrl_x_mode == CTRL_X_THESAURUS)
+ || ctrl_x_mode == CTRL_X_THESAURUS) {
break;
+ }
FALLTHROUGH;
case '^': // currently it's not needed.
case '$':
@@ -5429,8 +5534,9 @@ static unsigned quote_meta(char_u *dest, char_u *src, int len)
}
}
}
- if (dest != NULL)
+ if (dest != NULL) {
*dest = NUL;
+ }
return m;
}
@@ -5446,12 +5552,13 @@ int get_literal(void)
int cc;
int nc;
int i;
- int hex = FALSE;
- int octal = FALSE;
+ bool hex = false;
+ bool octal = false;
int unicode = 0;
- if (got_int)
+ if (got_int) {
return Ctrl_C;
+ }
no_mapping++; // don't map the next key hits
cc = 0;
@@ -5459,29 +5566,31 @@ int get_literal(void)
for (;; ) {
nc = plain_vgetc();
if (!(State & CMDLINE)
- && MB_BYTE2LEN_CHECK(nc) == 1
- )
+ && MB_BYTE2LEN_CHECK(nc) == 1) {
add_to_showcmd(nc);
- if (nc == 'x' || nc == 'X')
- hex = TRUE;
- else if (nc == 'o' || nc == 'O')
- octal = TRUE;
- else if (nc == 'u' || nc == 'U')
+ }
+ if (nc == 'x' || nc == 'X') {
+ hex = true;
+ } else if (nc == 'o' || nc == 'O') {
+ octal = true;
+ } else if (nc == 'u' || nc == 'U') {
unicode = nc;
- else {
+ } else {
if (hex
- || unicode != 0
- ) {
- if (!ascii_isxdigit(nc))
+ || unicode != 0) {
+ if (!ascii_isxdigit(nc)) {
break;
+ }
cc = cc * 16 + hex2nr(nc);
} else if (octal) {
- if (nc < '0' || nc > '7')
+ if (nc < '0' || nc > '7') {
break;
+ }
cc = cc * 8 + nc - '0';
} else {
- if (!ascii_isdigit(nc))
+ if (!ascii_isdigit(nc)) {
break;
+ }
cc = cc * 10 + nc - '0';
}
@@ -5489,9 +5598,9 @@ int get_literal(void)
}
if (cc > 255
- && unicode == 0
- )
+ && unicode == 0) {
cc = 255; // limit range to 0-255
+ }
nc = 0;
if (hex) { // hex: up to two chars
@@ -5521,8 +5630,9 @@ int get_literal(void)
}
--no_mapping;
- if (nc)
+ if (nc) {
vungetc(nc);
+ }
got_int = false; // CTRL-C typed after CTRL-V is not an interrupt
return cc;
}
@@ -5532,7 +5642,7 @@ int get_literal(void)
/// @param ctrlv `c` was typed after CTRL-V
static void insert_special(int c, int allow_modmask, int ctrlv)
{
- char_u *p;
+ char_u *p;
int len;
// Special function key, translate into "<Key>". Up to the last '>' is
@@ -5548,16 +5658,18 @@ static void insert_special(int c, int allow_modmask, int ctrlv)
len = (int)STRLEN(p);
c = p[len - 1];
if (len > 2) {
- if (stop_arrow() == FAIL)
+ if (stop_arrow() == FAIL) {
return;
+ }
p[len - 1] = NUL;
ins_str(p);
AppendToRedobuffLit(p, -1);
ctrlv = FALSE;
}
}
- if (stop_arrow() == OK)
+ if (stop_arrow() == OK) {
insertchar(c, ctrlv ? INSCHAR_CTRLV : 0, -1);
+ }
}
/*
@@ -5569,29 +5681,28 @@ static void insert_special(int c, int allow_modmask, int ctrlv)
* stop and defer processing to the "normal" mechanism.
* '0' and '^' are special, because they can be followed by CTRL-D.
*/
-# define ISSPECIAL(c) ((c) < ' ' || (c) >= DEL || (c) == '0' || (c) == '^')
+#define ISSPECIAL(c) ((c) < ' ' || (c) >= DEL || (c) == '0' || (c) == '^')
#define WHITECHAR(cc) ( \
- ascii_iswhite(cc) \
- && !utf_iscomposing(utf_ptr2char(get_cursor_pos_ptr() + 1)))
+ ascii_iswhite(cc) \
+ && !utf_iscomposing(utf_ptr2char(get_cursor_pos_ptr() + 1)))
-/*
- * "flags": INSCHAR_FORMAT - force formatting
- * INSCHAR_CTRLV - char typed just after CTRL-V
- * INSCHAR_NO_FEX - don't use 'formatexpr'
- *
- * NOTE: passes the flags value straight through to internal_format() which,
- * beside INSCHAR_FORMAT (above), is also looking for these:
- * INSCHAR_DO_COM - format comments
- * INSCHAR_COM_LIST - format comments with num list or 2nd line indent
- */
-void insertchar(
- int c, // character to insert or NUL
- int flags, // INSCHAR_FORMAT, etc.
- int second_indent // indent for second line if >= 0
-)
+///
+/// "flags": INSCHAR_FORMAT - force formatting
+/// INSCHAR_CTRLV - char typed just after CTRL-V
+/// INSCHAR_NO_FEX - don't use 'formatexpr'
+///
+/// NOTE: passes the flags value straight through to internal_format() which,
+/// beside INSCHAR_FORMAT (above), is also looking for these:
+/// INSCHAR_DO_COM - format comments
+/// INSCHAR_COM_LIST - format comments with num list or 2nd line indent
+///
+/// @param c character to insert or NUL
+/// @param flags INSCHAR_FORMAT, etc.
+/// @param second_indent indent for second line if >= 0
+void insertchar(int c, int flags, int second_indent)
{
- char_u *p;
+ char_u *p;
int force_format = flags & INSCHAR_FORMAT;
const int textwidth = comp_textwidth(force_format);
@@ -5603,14 +5714,14 @@ void insertchar(
* - Always do this when 'formatoptions' has the 'a' flag and the line
* ends in white space.
* - Otherwise:
- * - Don't do this if inserting a blank
- * - Don't do this if an existing character is being replaced, unless
- * we're in VREPLACE mode.
- * - Do this if the cursor is not on the line where insert started
- * or - 'formatoptions' doesn't have 'l' or the line was not too long
- * before the insert.
- * - 'formatoptions' doesn't have 'b' or a blank was inserted at or
- * before 'textwidth'
+ * - Don't do this if inserting a blank
+ * - Don't do this if an existing character is being replaced, unless
+ * we're in VREPLACE mode.
+ * - Do this if the cursor is not on the line where insert started
+ * or - 'formatoptions' doesn't have 'l' or the line was not too long
+ * before the insert.
+ * - 'formatoptions' doesn't have 'b' or a blank was inserted at or
+ * before 'textwidth'
*/
if (textwidth > 0
&& (force_format
@@ -5627,7 +5738,7 @@ void insertchar(
// when 'formatexpr' isn't set or it returns non-zero.
bool do_internal = true;
colnr_T virtcol = get_nolist_virtcol()
- + char2cells(c != NUL ? c : gchar_cursor());
+ + char2cells(c != NUL ? c : gchar_cursor());
if (*curbuf->b_p_fex != NUL && (flags & INSCHAR_NO_FEX) == 0
&& (force_format || virtcol > (colnr_T)textwidth)) {
@@ -5636,8 +5747,9 @@ void insertchar(
// was called.
ins_need_undo = true;
}
- if (do_internal)
+ if (do_internal) {
internal_format(textwidth, second_indent, flags, c == NUL, c);
+ }
}
if (c == NUL) { // only formatting was wanted
@@ -5646,7 +5758,7 @@ void insertchar(
// Check whether this character should end a comment.
if (did_ai && c == end_comment_pending) {
- char_u *line;
+ char_u *line;
char_u lead_end[COM_MAX_LEN]; // end-comment string
int middle_len, end_len;
int i;
@@ -5675,8 +5787,9 @@ void insertchar(
// Skip white space before the cursor
i = curwin->w_cursor.col;
- while (--i >= 0 && ascii_iswhite(line[i]))
+ while (--i >= 0 && ascii_iswhite(line[i])) {
;
+ }
i++;
// Skip to before the middle leader
@@ -5753,10 +5866,12 @@ void insertchar(
if (flags & INSCHAR_CTRLV) {
redo_literal(*buf);
i = 1;
- } else
+ } else {
i = 0;
- if (buf[i] != NUL)
+ }
+ if (buf[i] != NUL) {
AppendToRedobuffLit(buf + i, -1);
+ }
} else {
int cc;
@@ -5778,20 +5893,13 @@ void insertchar(
}
}
-/*
- * Format text at the current insert position.
- *
- * If the INSCHAR_COM_LIST flag is present, then the value of second_indent
- * will be the comment leader length sent to open_line().
- */
-static void
-internal_format (
- int textwidth,
- int second_indent,
- int flags,
- int format_only,
- int c // character to be inserted (can be NUL)
-)
+/// Format text at the current insert position.
+///
+/// If the INSCHAR_COM_LIST flag is present, then the value of second_indent
+/// will be the comment leader length sent to open_line().
+///
+/// @param c character to be inserted (can be NUL)
+static void internal_format(int textwidth, int second_indent, int flags, int format_only, int c)
{
int cc;
int save_char = NUL;
@@ -5814,8 +5922,7 @@ internal_format (
* deleted. Replace it with an 'x' temporarily.
*/
if (!curbuf->b_p_ai
- && !(State & VREPLACE_FLAG)
- ) {
+ && !(State & VREPLACE_FLAG)) {
cc = gchar_cursor();
if (ascii_iswhite(cc)) {
save_char = cc;
@@ -5834,14 +5941,15 @@ internal_format (
colnr_T len;
colnr_T virtcol;
int orig_col = 0;
- char_u *saved_text = NULL;
+ char_u *saved_text = NULL;
colnr_T col;
colnr_T end_col;
virtcol = get_nolist_virtcol()
+ char2cells(c != NUL ? c : gchar_cursor());
- if (virtcol <= (colnr_T)textwidth)
+ if (virtcol <= (colnr_T)textwidth) {
break;
+ }
if (no_leader) {
do_comments = false;
@@ -5889,10 +5997,11 @@ internal_format (
|| (flags & INSCHAR_FORMAT)
|| curwin->w_cursor.lnum != Insstart.lnum
|| curwin->w_cursor.col >= Insstart.col) {
- if (curwin->w_cursor.col == startcol && c != NUL)
+ if (curwin->w_cursor.col == startcol && c != NUL) {
cc = c;
- else
+ } else {
cc = gchar_cursor();
+ }
if (WHITECHAR(cc)) {
// remember position of blank just before text
end_col = curwin->w_cursor.col;
@@ -5947,8 +6056,9 @@ internal_format (
end_foundcol = end_col + 1;
foundcol = curwin->w_cursor.col;
- if (curwin->w_cursor.col <= (colnr_T)wantcol)
+ if (curwin->w_cursor.col <= (colnr_T)wantcol) {
break;
+ }
} else if ((cc >= 0x100 || !utf_allow_break_before(cc))
&& fo_multibyte) {
int ncc;
@@ -5969,14 +6079,16 @@ internal_format (
if (curwin->w_cursor.col != skip_pos && allow_break) {
foundcol = curwin->w_cursor.col;
end_foundcol = foundcol;
- if (curwin->w_cursor.col <= (colnr_T)wantcol)
+ if (curwin->w_cursor.col <= (colnr_T)wantcol) {
break;
+ }
}
curwin->w_cursor.col = col;
}
- if (curwin->w_cursor.col == 0)
+ if (curwin->w_cursor.col == 0) {
break;
+ }
ncc = cc;
col = curwin->w_cursor.col;
@@ -6038,8 +6150,9 @@ internal_format (
}
}
}
- if (curwin->w_cursor.col == 0)
+ if (curwin->w_cursor.col == 0) {
break;
+ }
dec_cursor();
}
@@ -6068,11 +6181,13 @@ internal_format (
*/
curwin->w_cursor.col = foundcol;
while ((cc = gchar_cursor(), WHITECHAR(cc))
- && (!fo_white_par || curwin->w_cursor.col < startcol))
+ && (!fo_white_par || curwin->w_cursor.col < startcol)) {
inc_cursor();
+ }
startcol -= curwin->w_cursor.col;
- if (startcol < 0)
+ if (startcol < 0) {
startcol = 0;
+ }
if (State & VREPLACE_FLAG) {
/*
@@ -6099,12 +6214,13 @@ internal_format (
* Only insert/delete lines, but don't really redraw the window.
*/
open_line(FORWARD, OPENLINE_DELSPACES + OPENLINE_MARKFIX
- + (fo_white_par ? OPENLINE_KEEPTRAIL : 0)
- + (do_comments ? OPENLINE_DO_COM : 0)
- + ((flags & INSCHAR_COM_LIST) ? OPENLINE_COM_LIST : 0)
- , ((flags & INSCHAR_COM_LIST) ? second_indent : old_indent));
- if (!(flags & INSCHAR_COM_LIST))
+ + (fo_white_par ? OPENLINE_KEEPTRAIL : 0)
+ + (do_comments ? OPENLINE_DO_COM : 0)
+ + ((flags & INSCHAR_COM_LIST) ? OPENLINE_COM_LIST : 0)
+ , ((flags & INSCHAR_COM_LIST) ? second_indent : old_indent));
+ if (!(flags & INSCHAR_COM_LIST)) {
old_indent = 0;
+ }
replace_offset = 0;
if (first_line) {
@@ -6155,8 +6271,9 @@ internal_format (
*/
curwin->w_cursor.col += startcol;
len = (colnr_T)STRLEN(get_cursor_line_ptr());
- if (curwin->w_cursor.col > len)
+ if (curwin->w_cursor.col > len) {
curwin->w_cursor.col = len;
+ }
}
haveto_redraw = true;
@@ -6181,27 +6298,26 @@ internal_format (
}
}
-/*
- * Called after inserting or deleting text: When 'formatoptions' includes the
- * 'a' flag format from the current line until the end of the paragraph.
- * Keep the cursor at the same position relative to the text.
- * The caller must have saved the cursor line for undo, following ones will be
- * saved here.
- */
-void auto_format(
- bool trailblank, // when true also format with trailing blank
- bool prev_line // may start in previous line
-)
+/// Called after inserting or deleting text: When 'formatoptions' includes the
+/// 'a' flag format from the current line until the end of the paragraph.
+/// Keep the cursor at the same position relative to the text.
+/// The caller must have saved the cursor line for undo, following ones will be
+/// saved here.
+///
+/// @param trailblank when true also format with trailing blank
+/// @param prev_line may start in previous line
+void auto_format(bool trailblank, bool prev_line)
{
pos_T pos;
colnr_T len;
- char_u *old;
- char_u *new, *pnew;
+ char_u *old;
+ char_u *new, *pnew;
int wasatend;
int cc;
- if (!has_format_option(FO_AUTO))
+ if (!has_format_option(FO_AUTO)) {
return;
+ }
pos = curwin->w_cursor;
old = get_cursor_line_ptr();
@@ -6219,8 +6335,9 @@ void auto_format(
dec_cursor();
cc = gchar_cursor();
if (!WHITECHAR(cc) && curwin->w_cursor.col > 0
- && has_format_option(FO_ONE_LETTER))
+ && has_format_option(FO_ONE_LETTER)) {
dec_cursor();
+ }
cc = gchar_cursor();
if (WHITECHAR(cc)) {
curwin->w_cursor = pos;
@@ -6232,8 +6349,9 @@ void auto_format(
/* With the 'c' flag in 'formatoptions' and 't' missing: only format
* comments. */
if (has_format_option(FO_WRAP_COMS) && !has_format_option(FO_WRAP)
- && get_leader_len(old, NULL, FALSE, TRUE) == 0)
+ && get_leader_len(old, NULL, false, true) == 0) {
return;
+ }
/*
* May start formatting in a previous line, so that after "x" a word is
@@ -6242,8 +6360,9 @@ void auto_format(
*/
if (prev_line && !paragraph_start(curwin->w_cursor.lnum)) {
--curwin->w_cursor.lnum;
- if (u_save_cursor() == FAIL)
+ if (u_save_cursor() == FAIL) {
return;
+ }
}
/*
@@ -6286,14 +6405,12 @@ void auto_format(
check_cursor();
}
-/*
- * When an extra space was added to continue a paragraph for auto-formatting,
- * delete it now. The space must be under the cursor, just after the insert
- * position.
- */
-static void check_auto_format(
- bool end_insert // true when ending Insert mode
-)
+/// When an extra space was added to continue a paragraph for auto-formatting,
+/// delete it now. The space must be under the cursor, just after the insert
+/// position.
+///
+/// @param end_insert true when ending Insert mode
+static void check_auto_format(bool end_insert)
{
int c = ' ';
int cc;
@@ -6318,16 +6435,14 @@ static void check_auto_format(
}
}
-/*
- * Find out textwidth to be used for formatting:
- * if 'textwidth' option is set, use it
- * else if 'wrapmargin' option is set, use curwin->w_width_inner-'wrapmargin'
- * if invalid value, use 0.
- * Set default to window width (maximum 79) for "gq" operator.
- */
-int comp_textwidth(
- bool ff // force formatting (for "gq" command)
-)
+/// Find out textwidth to be used for formatting:
+/// if 'textwidth' option is set, use it
+/// else if 'wrapmargin' option is set, use curwin->w_width_inner-'wrapmargin'
+/// if invalid value, use 0.
+/// Set default to window width (maximum 79) for "gq" operator.
+///
+/// @param ff force formatting (for "gq" command)
+int comp_textwidth(bool ff)
{
int textwidth = curbuf->b_p_tw;
if (textwidth == 0 && curbuf->b_p_wm) {
@@ -6340,11 +6455,13 @@ int comp_textwidth(
textwidth -= win_fdccol_count(curwin);
textwidth -= win_signcol_count(curwin);
- if (curwin->w_p_nu || curwin->w_p_rnu)
+ if (curwin->w_p_nu || curwin->w_p_rnu) {
textwidth -= 8;
+ }
}
- if (textwidth < 0)
+ if (textwidth < 0) {
textwidth = 0;
+ }
if (ff && textwidth == 0) {
textwidth = curwin->w_width_inner - 1;
if (textwidth > 79) {
@@ -6371,17 +6488,18 @@ static void redo_literal(int c)
}
}
-// start_arrow() is called when an arrow key is used in insert mode.
-// For undo/redo it resembles hitting the <ESC> key.
-static void start_arrow(
- pos_T *end_insert_pos // can be NULL
-)
+/// start_arrow() is called when an arrow key is used in insert mode.
+/// For undo/redo it resembles hitting the <ESC> key.
+///
+/// @param end_insert_pos can be NULL
+static void start_arrow(pos_T *end_insert_pos)
{
start_arrow_common(end_insert_pos, true);
}
/// Like start_arrow() but with end_change argument.
-/// Will prepare for redo of CTRL-G U if "end_change" is FALSE.
+/// Will prepare for redo of CTRL-G U if "end_change" is false.
+///
/// @param end_insert_pos can be NULL
/// @param end_change end undoable change
static void start_arrow_with_change(pos_T *end_insert_pos, bool end_change)
@@ -6426,9 +6544,10 @@ static void check_spell_redraw(void)
static void spell_back_to_badword(void)
{
pos_T tpos = curwin->w_cursor;
- spell_bad_len = spell_move_to(curwin, BACKWARD, TRUE, TRUE, NULL);
- if (curwin->w_cursor.col != tpos.col)
+ spell_bad_len = spell_move_to(curwin, BACKWARD, true, true, NULL);
+ if (curwin->w_cursor.col != tpos.col) {
start_arrow(&tpos);
+ }
}
/*
@@ -6443,7 +6562,7 @@ int stop_arrow(void)
if (Insstart.col > Insstart_orig.col && !ins_need_undo) {
// Don't update the original insert position when moved to the
// right, except when nothing was inserted yet.
- update_Insstart_orig = FALSE;
+ update_Insstart_orig = false;
}
Insstart_textlen = (colnr_T)linetabsize(get_cursor_line_ptr());
@@ -6471,20 +6590,16 @@ int stop_arrow(void)
return arrow_used || ins_need_undo ? FAIL : OK;
}
-/*
- * Do a few things to stop inserting.
- * "end_insert_pos" is where insert ended. It is NULL when we already jumped
- * to another window/buffer.
- */
-static void
-stop_insert (
- pos_T *end_insert_pos,
- int esc, // called by ins_esc()
- int nomove // <c-\><c-o>, don't move cursor
-)
+/// Do a few things to stop inserting.
+/// "end_insert_pos" is where insert ended. It is NULL when we already jumped
+/// to another window/buffer.
+///
+/// @param esc called by ins_esc()
+/// @param nomove <c-\><c-o>, don't move cursor
+static void stop_insert(pos_T *end_insert_pos, int esc, int nomove)
{
int cc;
- char_u *ptr;
+ char_u *ptr;
stop_redo_ins();
replace_flush(); // abandon replace stack
@@ -6500,8 +6615,9 @@ stop_insert (
xfree(last_insert);
last_insert = ptr;
last_insert_skip = new_insert_skip;
- } else
+ } else {
xfree(ptr);
+ }
if (!arrow_used && end_insert_pos != NULL) {
// Auto-format now. It may seem strange to do this when stopping an
@@ -6518,21 +6634,24 @@ stop_insert (
if (curwin->w_cursor.col > 0 && gchar_cursor() == NUL) {
dec_cursor();
cc = gchar_cursor();
- if (!ascii_iswhite(cc))
+ if (!ascii_iswhite(cc)) {
curwin->w_cursor = tpos;
+ }
}
auto_format(true, false);
if (ascii_iswhite(cc)) {
- if (gchar_cursor() != NUL)
+ if (gchar_cursor() != NUL) {
inc_cursor();
+ }
/* If the cursor is still at the same character, also keep
* the "coladd". */
if (gchar_cursor() == NUL
&& curwin->w_cursor.lnum == tpos.lnum
- && curwin->w_cursor.col == tpos.col)
+ && curwin->w_cursor.col == tpos.col) {
curwin->w_cursor.coladd = tpos.coladd;
+ }
}
}
@@ -6553,8 +6672,9 @@ stop_insert (
curwin->w_cursor = *end_insert_pos;
check_cursor_col(); // make sure it is not past the line
for (;; ) {
- if (gchar_cursor() == NUL && curwin->w_cursor.col > 0)
+ if (gchar_cursor() == NUL && curwin->w_cursor.col > 0) {
--curwin->w_cursor.col;
+ }
cc = gchar_cursor();
if (!ascii_iswhite(cc)) {
break;
@@ -6606,7 +6726,7 @@ stop_insert (
*/
void set_last_insert(int c)
{
- char_u *s;
+ char_u *s;
xfree(last_insert);
last_insert = xmalloc(MB_MAXBYTES * 3 + 5);
@@ -6660,25 +6780,26 @@ char_u *add_char2buf(int c, char_u *s)
/*
* move cursor to start of line
- * if flags & BL_WHITE move to first non-white
- * if flags & BL_SOL move to first non-white if startofline is set,
- * otherwise keep "curswant" column
- * if flags & BL_FIX don't leave the cursor on a NUL.
+ * if flags & BL_WHITE move to first non-white
+ * if flags & BL_SOL move to first non-white if startofline is set,
+ * otherwise keep "curswant" column
+ * if flags & BL_FIX don't leave the cursor on a NUL.
*/
void beginline(int flags)
{
- if ((flags & BL_SOL) && !p_sol)
+ if ((flags & BL_SOL) && !p_sol) {
coladvance(curwin->w_curswant);
- else {
+ } else {
curwin->w_cursor.col = 0;
curwin->w_cursor.coladd = 0;
if (flags & (BL_WHITE | BL_SOL)) {
- char_u *ptr;
+ char_u *ptr;
for (ptr = get_cursor_line_ptr(); ascii_iswhite(*ptr)
- && !((flags & BL_FIX) && ptr[1] == NUL); ++ptr)
+ && !((flags & BL_FIX) && ptr[1] == NUL); ++ptr) {
++curwin->w_cursor.col;
+ }
}
curwin->w_set_curswant = TRUE;
}
@@ -6694,7 +6815,7 @@ void beginline(int flags)
int oneright(void)
{
- char_u *ptr;
+ char_u *ptr;
int l;
if (virtual_active()) {
@@ -6735,8 +6856,9 @@ int oneleft(void)
int width;
int v = getviscol();
- if (v == 0)
+ if (v == 0) {
return FAIL;
+ }
// We might get stuck on 'showbreak', skip over it.
width = 1;
@@ -6766,8 +6888,9 @@ int oneleft(void)
return OK;
}
- if (curwin->w_cursor.col == 0)
+ if (curwin->w_cursor.col == 0) {
return FAIL;
+ }
curwin->w_set_curswant = TRUE;
--curwin->w_cursor.col;
@@ -6778,11 +6901,8 @@ int oneleft(void)
return OK;
}
-int
-cursor_up (
- long n,
- int upd_topline // When TRUE: update topline
-)
+/// @oaram upd_topline When TRUE: update topline
+int cursor_up(long n, int upd_topline)
{
linenr_T lnum;
@@ -6793,9 +6913,9 @@ cursor_up (
if (lnum <= 1) {
return FAIL;
}
- if (n >= lnum)
+ if (n >= lnum) {
lnum = 1;
- else if (hasAnyFolding(curwin)) {
+ } else if (hasAnyFolding(curwin)) {
/*
* Count each sequence of folded lines as one logical line.
*/
@@ -6815,10 +6935,12 @@ cursor_up (
(void)hasFolding(lnum, &lnum, NULL);
}
}
- if (lnum < 1)
+ if (lnum < 1) {
lnum = 1;
- } else
+ }
+ } else {
lnum -= n;
+ }
curwin->w_cursor.lnum = lnum;
}
@@ -6832,14 +6954,10 @@ cursor_up (
return OK;
}
-/*
- * Cursor down a number of logical lines.
- */
-int
-cursor_down (
- long n,
- int upd_topline // When TRUE: update topline
-)
+/// Cursor down a number of logical lines.
+///
+/// @param upd_topline When TRUE: update topline
+int cursor_down(long n, int upd_topline)
{
linenr_T lnum;
@@ -6852,24 +6970,28 @@ cursor_down (
if (lnum >= curbuf->b_ml.ml_line_count) {
return FAIL;
}
- if (lnum + n >= curbuf->b_ml.ml_line_count)
+ if (lnum + n >= curbuf->b_ml.ml_line_count) {
lnum = curbuf->b_ml.ml_line_count;
- else if (hasAnyFolding(curwin)) {
+ } else if (hasAnyFolding(curwin)) {
linenr_T last;
// count each sequence of folded lines as one logical line
while (n--) {
- if (hasFolding(lnum, NULL, &last))
+ if (hasFolding(lnum, NULL, &last)) {
lnum = last + 1;
- else
+ } else {
++lnum;
- if (lnum >= curbuf->b_ml.ml_line_count)
+ }
+ if (lnum >= curbuf->b_ml.ml_line_count) {
break;
+ }
}
- if (lnum > curbuf->b_ml.ml_line_count)
+ if (lnum > curbuf->b_ml.ml_line_count) {
lnum = curbuf->b_ml.ml_line_count;
- } else
+ }
+ } else {
lnum += n;
+ }
curwin->w_cursor.lnum = lnum;
}
@@ -6883,20 +7005,18 @@ cursor_down (
return OK;
}
-/*
- * Stuff the last inserted text in the read buffer.
- * Last_insert actually is a copy of the redo buffer, so we
- * first have to remove the command.
- */
-int stuff_inserted(
- int c, // Command character to be inserted
- long count, // Repeat this many times
- int no_esc // Don't add an ESC at the end
-)
-{
- char_u *esc_ptr;
- char_u *ptr;
- char_u *last_ptr;
+/// Stuff the last inserted text in the read buffer.
+/// Last_insert actually is a copy of the redo buffer, so we
+/// first have to remove the command.
+///
+/// @param c Command character to be inserted
+/// @param count Repeat this many times
+/// @param no_esc Don't add an ESC at the end
+int stuff_inserted(int c, long count, int no_esc)
+{
+ char_u *esc_ptr;
+ char_u *ptr;
+ char_u *last_ptr;
char_u last = NUL;
ptr = get_last_insert();
@@ -6934,8 +7054,9 @@ int stuff_inserted(
}
} while (--count > 0);
- if (last)
+ if (last) {
*last_ptr = last;
+ }
if (esc_ptr != NULL) {
*esc_ptr = ESC; // put the ESC back
@@ -6951,8 +7072,9 @@ int stuff_inserted(
char_u *get_last_insert(void)
{
- if (last_insert == NULL)
+ if (last_insert == NULL) {
return NULL;
+ }
return last_insert + last_insert_skip;
}
@@ -6962,11 +7084,12 @@ char_u *get_last_insert(void)
*/
char_u *get_last_insert_save(void)
{
- char_u *s;
+ char_u *s;
int len;
- if (last_insert == NULL)
+ if (last_insert == NULL) {
return NULL;
+ }
s = vim_strsave(last_insert + last_insert_skip);
len = (int)STRLEN(s);
if (len > 0 && s[len - 1] == ESC) { // remove trailing ESC
@@ -6994,7 +7117,7 @@ static bool echeck_abbr(int c)
}
return check_abbr(c, get_cursor_line_ptr(), curwin->w_cursor.col,
- curwin->w_cursor.lnum == Insstart.lnum ? Insstart.col : 0);
+ curwin->w_cursor.lnum == Insstart.lnum ? Insstart.col : 0);
}
/*
@@ -7012,7 +7135,7 @@ static bool echeck_abbr(int c)
* that were deleted (always white space).
*/
-static char_u *replace_stack = NULL;
+static char_u *replace_stack = NULL;
static ssize_t replace_stack_nr = 0; // next entry in replace stack
static ssize_t replace_stack_len = 0; // max. number of entries
@@ -7051,8 +7174,9 @@ int replace_push_mb(char_u *p)
int l = (*mb_ptr2len)(p);
int j;
- for (j = l - 1; j >= 0; --j)
+ for (j = l - 1; j >= 0; --j) {
replace_push(p[j]);
+ }
return l;
}
@@ -7064,23 +7188,22 @@ static int replace_pop(void)
return (replace_stack_nr == 0) ? -1 : (int)replace_stack[--replace_stack_nr];
}
-/*
- * Join the top two items on the replace stack. This removes to "off"'th NUL
- * encountered.
- */
-static void replace_join(
- int off // offset for which NUL to remove
-)
+/// Join the top two items on the replace stack. This removes to "off"'th NUL
+/// encountered.
+///
+/// @param off offset for which NUL to remove
+static void replace_join(int off)
{
int i;
- for (i = replace_stack_nr; --i >= 0; )
+ for (i = replace_stack_nr; --i >= 0; ) {
if (replace_stack[i] == NUL && off-- <= 0) {
--replace_stack_nr;
memmove(replace_stack + i, replace_stack + i + 1,
- (size_t)(replace_stack_nr - i));
+ (size_t)(replace_stack_nr - i));
return;
}
+ }
}
/*
@@ -7113,8 +7236,9 @@ static void mb_replace_pop_ins(int cc)
if ((n = MB_BYTE2LEN(cc)) > 1) {
buf[0] = cc;
- for (i = 1; i < n; ++i)
+ for (i = 1; i < n; ++i) {
buf[i] = replace_pop();
+ }
ins_bytes_len(buf, n);
} else {
ins_char(cc);
@@ -7176,7 +7300,7 @@ static void replace_do_bs(int limit_col)
int ins_len;
int orig_vcols = 0;
colnr_T start_vcol;
- char_u *p;
+ char_u *p;
int i;
int vcol;
const int l_State = State;
@@ -7187,7 +7311,7 @@ static void replace_do_bs(int limit_col)
// Get the number of screen cells used by the character we are
// going to delete.
getvcol(curwin, &curwin->w_cursor, NULL, &start_vcol, NULL);
- orig_vcols = chartabsize(get_cursor_pos_ptr(), start_vcol);
+ orig_vcols = win_chartabsize(curwin, get_cursor_pos_ptr(), start_vcol);
}
(void)del_char_after_col(limit_col);
if (l_State & VREPLACE_FLAG) {
@@ -7201,8 +7325,8 @@ static void replace_do_bs(int limit_col)
p = get_cursor_pos_ptr();
ins_len = (int)STRLEN(p) - orig_len;
vcol = start_vcol;
- for (i = 0; i < ins_len; ++i) {
- vcol += chartabsize(p + i, vcol);
+ for (i = 0; i < ins_len; i++) {
+ vcol += win_chartabsize(curwin, p + i, vcol);
i += (*mb_ptr2len)(p) - 1;
}
vcol -= start_vcol;
@@ -7219,8 +7343,9 @@ static void replace_do_bs(int limit_col)
// mark the buffer as changed and prepare for displaying
changed_bytes(curwin->w_cursor.lnum, curwin->w_cursor.col);
- } else if (cc == 0)
+ } else if (cc == 0) {
(void)del_char_after_col(limit_col);
+ }
}
/// Check that C-indenting is on.
@@ -7238,23 +7363,25 @@ static bool cindent_on(void)
*/
void fixthisline(IndentGetter get_the_indent)
{
- int amount = get_the_indent();
+ int amount = get_the_indent();
- if (amount >= 0) {
- change_indent(INDENT_SET, amount, false, 0, true);
- if (linewhite(curwin->w_cursor.lnum)) {
- did_ai = true; // delete the indent if the line stays empty
- }
+ if (amount >= 0) {
+ change_indent(INDENT_SET, amount, false, 0, true);
+ if (linewhite(curwin->w_cursor.lnum)) {
+ did_ai = true; // delete the indent if the line stays empty
}
+ }
}
void fix_indent(void) {
- if (p_paste)
+ if (p_paste) {
return;
- if (curbuf->b_p_lisp && curbuf->b_p_ai)
+ }
+ if (curbuf->b_p_lisp && curbuf->b_p_ai) {
fixthisline(get_lisp_indent);
- else if (cindent_on())
+ } else if (cindent_on()) {
do_c_expr_indent();
+ }
}
/// Check that "cinkeys" contains the key "keytyped",
@@ -7277,7 +7404,7 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty)
int try_match_word;
char_u *p;
char_u *line;
- int icase;
+ bool icase;
if (keytyped == NUL) {
// Can happen with CTRL-Y and CTRL-E on a short line.
@@ -7295,9 +7422,12 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty)
* 'when' and a '*' or '!' before the key.
*/
switch (when) {
- case '*': try_match = (*look == '*'); break;
- case '!': try_match = (*look == '!'); break;
- default: try_match = (*look != '*'); break;
+ case '*':
+ try_match = (*look == '*'); break;
+ case '!':
+ try_match = (*look == '!'); break;
+ default:
+ try_match = (*look != '*'); break;
}
if (*look == '*' || *look == '!') {
look++;
@@ -7322,8 +7452,8 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty)
}
look += 2;
- // 'o' means "o" command, open forward.
- // 'O' means "O" command, open backward.
+ // 'o' means "o" command, open forward.
+ // 'O' means "O" command, open backward.
} else if (*look == 'o') {
if (try_match && keytyped == KEY_OPEN_FORW) {
return true;
@@ -7335,8 +7465,8 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty)
}
look++;
- // 'e' means to check for "else" at start of line and just before the
- // cursor.
+ // 'e' means to check for "else" at start of line and just before the
+ // cursor.
} else if (*look == 'e') {
if (try_match && keytyped == 'e' && curwin->w_cursor.col >= 4) {
p = get_cursor_line_ptr();
@@ -7347,9 +7477,9 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty)
}
look++;
- // ':' only causes an indent if it is at the end of a label or case
- // statement, or when it was before typing the ':' (to fix
- // class::method for C++).
+ // ':' only causes an indent if it is at the end of a label or case
+ // statement, or when it was before typing the ':' (to fix
+ // class::method for C++).
} else if (*look == ':') {
if (try_match && keytyped == ':') {
p = get_cursor_line_ptr();
@@ -7363,8 +7493,8 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty)
&& p[curwin->w_cursor.col - 2] == ':') {
p[curwin->w_cursor.col - 1] = ' ';
const bool i = cin_iscase(p, false)
- || cin_isscopedecl(p)
- || cin_islabel();
+ || cin_isscopedecl(p)
+ || cin_islabel();
p = get_cursor_line_ptr();
p[curwin->w_cursor.col - 1] = ':';
if (i) {
@@ -7374,7 +7504,7 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty)
}
look++;
- // Is it a key in <>, maybe?
+ // Is it a key in <>, maybe?
} else if (*look == '<') {
if (try_match) {
// make up some named keys <o>, <O>, <e>, <0>, <>>, <<>, <*>,
@@ -7389,10 +7519,12 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty)
return true;
}
}
- while (*look && *look != '>')
+ while (*look && *look != '>') {
look++;
- while (*look == '>')
+ }
+ while (*look == '>') {
look++;
+ }
}
/*
* Is it a word: "=word"?
@@ -7400,13 +7532,15 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty)
else if (*look == '=' && look[1] != ',' && look[1] != NUL) {
++look;
if (*look == '~') {
- icase = TRUE;
- ++look;
- } else
- icase = FALSE;
+ icase = true;
+ look++;
+ } else {
+ icase = false;
+ }
p = vim_strchr(look, ',');
- if (p == NULL)
+ if (p == NULL) {
p = look + STRLEN(look);
+ }
if ((try_match || try_match_word)
&& curwin->w_cursor.col >= (colnr_T)(p - look)) {
bool match = false;
@@ -7427,8 +7561,9 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty)
if (s + (p - look) <= line + curwin->w_cursor.col
&& (icase
? mb_strnicmp(s, look, (size_t)(p - look))
- : STRNCMP(s, look, p - look)) == 0)
+ : STRNCMP(s, look, p - look)) == 0) {
match = true;
+ }
} else {
// TODO(@brammool): multi-byte
if (keytyped == (int)p[-1]
@@ -7459,7 +7594,7 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty)
}
look = p;
- // Ok, it's a boring generic character.
+ // Ok, it's a boring generic character.
} else {
if (try_match && *look == keytyped) {
return true;
@@ -7489,15 +7624,15 @@ int hkmap(int c)
PEIsofit, PEI, ZADIsofit, ZADI, KOF, RESH, hSHIN, TAV
};
static char_u map[26] =
- {(char_u)hALEF /*a*/, (char_u)BET /*b*/, (char_u)hKAF /*c*/,
- (char_u)DALET /*d*/, (char_u)-1 /*e*/, (char_u)PEIsofit /*f*/,
- (char_u)GIMEL /*g*/, (char_u)HEI /*h*/, (char_u)IUD /*i*/,
- (char_u)HET /*j*/, (char_u)KOF /*k*/, (char_u)LAMED /*l*/,
- (char_u)MEM /*m*/, (char_u)NUN /*n*/, (char_u)SAMEH /*o*/,
- (char_u)PEI /*p*/, (char_u)-1 /*q*/, (char_u)RESH /*r*/,
- (char_u)ZAIN /*s*/, (char_u)TAV /*t*/, (char_u)TET /*u*/,
- (char_u)VAV /*v*/, (char_u)hSHIN /*w*/, (char_u)-1 /*x*/,
- (char_u)AIN /*y*/, (char_u)ZADI /*z*/};
+ { (char_u)hALEF /*a*/, (char_u)BET /*b*/, (char_u)hKAF /*c*/,
+ (char_u)DALET /*d*/, (char_u)-1 /*e*/, (char_u)PEIsofit /*f*/,
+ (char_u)GIMEL /*g*/, (char_u)HEI /*h*/, (char_u)IUD /*i*/,
+ (char_u)HET /*j*/, (char_u)KOF /*k*/, (char_u)LAMED /*l*/,
+ (char_u)MEM /*m*/, (char_u)NUN /*n*/, (char_u)SAMEH /*o*/,
+ (char_u)PEI /*p*/, (char_u)-1 /*q*/, (char_u)RESH /*r*/,
+ (char_u)ZAIN /*s*/, (char_u)TAV /*t*/, (char_u)TET /*u*/,
+ (char_u)VAV /*v*/, (char_u)hSHIN /*w*/, (char_u)-1 /*x*/,
+ (char_u)AIN /*y*/, (char_u)ZADI /*z*/ };
if (c == 'N' || c == 'M' || c == 'P' || c == 'C' || c == 'Z') {
return (int)(map[CharOrd(c)] - 1 + p_aleph);
@@ -7522,21 +7657,30 @@ int hkmap(int c)
}
} else {
switch (c) {
- case '`': return ';';
- case '/': return '.';
- case '\'': return ',';
- case 'q': return '/';
- case 'w': return '\'';
+ case '`':
+ return ';';
+ case '/':
+ return '.';
+ case '\'':
+ return ',';
+ case 'q':
+ return '/';
+ case 'w':
+ return '\'';
// Hebrew letters - set offset from 'a'
- case ',': c = '{'; break;
- case '.': c = 'v'; break;
- case ';': c = 't'; break;
+ case ',':
+ c = '{'; break;
+ case '.':
+ c = 'v'; break;
+ case ';':
+ c = 't'; break;
default: {
static char str[] = "zqbcxlsjphmkwonu ydafe rig";
- if (c < 'a' || c > 'z')
+ if (c < 'a' || c > 'z') {
return c;
+ }
c = str[CharOrdLow(c)];
break;
}
@@ -7548,7 +7692,7 @@ int hkmap(int c)
static void ins_reg(void)
{
- int need_redraw = FALSE;
+ bool need_redraw = false;
int regname;
int literally = 0;
int vis_active = VIsual_active;
@@ -7659,13 +7803,15 @@ static void ins_ctrl_g(void)
// CTRL-G k and CTRL-G <Up>: cursor up to Insstart.col
case K_UP:
case Ctrl_K:
- case 'k': ins_up(TRUE);
+ case 'k':
+ ins_up(true);
break;
// CTRL-G j and CTRL-G <Down>: cursor down to Insstart.col
case K_DOWN:
case Ctrl_J:
- case 'j': ins_down(TRUE);
+ case 'j':
+ ins_down(true);
break;
// CTRL-G u: start new undoable edit
@@ -7687,7 +7833,8 @@ static void ins_ctrl_g(void)
break;
// Unknown CTRL-G command, reserved for future expansion.
- default: vim_beep(BO_CTRLG);
+ default:
+ vim_beep(BO_CTRLG);
}
}
@@ -7745,8 +7892,9 @@ static bool ins_esc(long *count, int cmdchar, bool nomove)
*/
if (*count > 0) {
line_breakcheck();
- if (got_int)
+ if (got_int) {
*count = 0;
+ }
}
if (--*count > 0) { // repeat what was typed
@@ -7795,8 +7943,7 @@ static bool ins_esc(long *count, int cmdchar, bool nomove)
|| (gchar_cursor() == NUL
&& !VIsual_active
))
- && !revins_on
- ) {
+ && !revins_on) {
if (curwin->w_cursor.coladd > 0 || ve_flags == VE_ALL) {
oneleft();
if (restart_edit != NUL) {
@@ -7835,8 +7982,9 @@ static bool ins_esc(long *count, int cmdchar, bool nomove)
static void ins_ctrl_(void)
{
if (revins_on && revins_chars && revins_scol >= 0) {
- while (gchar_cursor() != NUL && revins_chars--)
+ while (gchar_cursor() != NUL && revins_chars--) {
++curwin->w_cursor.col;
+ }
}
p_ri = !p_ri;
revins_on = (State == INSERT && p_ri);
@@ -7845,8 +7993,9 @@ static void ins_ctrl_(void)
revins_legal++;
revins_chars = 0;
undisplay_dollar();
- } else
+ } else {
revins_scol = -1;
+ }
p_hkmap = curwin->w_p_rl ^ p_ri; // be consistent!
showmode();
}
@@ -7869,8 +8018,9 @@ static bool ins_start_select(int c)
case K_KPAGEUP:
case K_PAGEDOWN:
case K_KPAGEDOWN:
- if (!(mod_mask & MOD_MASK_SHIFT))
+ if (!(mod_mask & MOD_MASK_SHIFT)) {
break;
+ }
FALLTHROUGH;
case K_S_LEFT:
case K_S_RIGHT:
@@ -7919,12 +8069,13 @@ static void ins_insert(int replaceState)
*/
static void ins_ctrl_o(void)
{
- if (State & VREPLACE_FLAG)
+ if (State & VREPLACE_FLAG) {
restart_edit = 'V';
- else if (State & REPLACE_FLAG)
+ } else if (State & REPLACE_FLAG) {
restart_edit = 'R';
- else
+ } else {
restart_edit = 'I';
+ }
if (virtual_active()) {
ins_at_eol = false; // cursor always keeps its column
} else {
@@ -7934,15 +8085,16 @@ static void ins_ctrl_o(void)
/*
* If the cursor is on an indent, ^T/^D insert/delete one
- * shiftwidth. Otherwise ^T/^D behave like a "<<" or ">>".
+ * shiftwidth. Otherwise ^T/^D behave like a "<<" or ">>".
* Always round the indent to 'shiftwidth', this is compatible
* with vi. But vi only supports ^T and ^D after an
* autoindent, we support it everywhere.
*/
static void ins_shift(int c, int lastc)
{
- if (stop_arrow() == FAIL)
+ if (stop_arrow() == FAIL) {
return;
+ }
AppendCharToRedobuff(c);
/*
@@ -7960,8 +8112,9 @@ static void ins_shift(int c, int lastc)
old_indent = get_indent(); // remember curr. indent
}
change_indent(INDENT_SET, 0, TRUE, 0, TRUE);
- } else
+ } else {
change_indent(c == Ctrl_D ? INDENT_DEC : INDENT_INC, 0, TRUE, 0, TRUE);
+ }
if (did_ai && *skipwhite(get_cursor_line_ptr()) != NUL) {
did_ai = false;
@@ -8024,7 +8177,7 @@ static void ins_bs_one(colnr_T *vcolp)
/// Handle Backspace, delete-word and delete-line in Insert mode.
///
-/// @param c charcter that was typed
+/// @param c character that was typed
/// @param mode backspace mode to use
/// @param[in,out] inserted_space_p whether a space was the last
// character inserted
@@ -8047,7 +8200,7 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
// can't backup past first character in buffer
// can't backup past starting point unless 'backspace' > 1
// can backup to a previous line if 'backspace' == 0
- if (BUFEMPTY()
+ if (buf_is_empty(curbuf)
|| (!revins_on
&& ((curwin->w_cursor.lnum == 1 && curwin->w_cursor.col == 0)
|| (!can_bs(BS_START)
@@ -8123,20 +8276,22 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
// again when auto-formatting.
if (has_format_option(FO_AUTO)
&& has_format_option(FO_WHITE_PAR)) {
- char_u *ptr = ml_get_buf(curbuf, curwin->w_cursor.lnum,
- TRUE);
+ char_u *ptr = ml_get_buf(curbuf, curwin->w_cursor.lnum, true);
int len;
len = (int)STRLEN(ptr);
- if (len > 0 && ptr[len - 1] == ' ')
+ if (len > 0 && ptr[len - 1] == ' ') {
ptr[len - 1] = NUL;
+ }
}
do_join(2, FALSE, FALSE, FALSE, false);
- if (temp == NUL && gchar_cursor() != NUL)
+ if (temp == NUL && gchar_cursor() != NUL) {
inc_cursor();
- } else
+ }
+ } else {
dec_cursor();
+ }
/*
* In REPLACE mode we have to put back the text that was replaced
@@ -8178,12 +8333,12 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
&& (curbuf->b_p_ai
|| cindent_on()
)
- && !revins_on
- ) {
+ && !revins_on) {
save_col = curwin->w_cursor.col;
beginline(BL_WHITE);
- if (curwin->w_cursor.col < save_col)
+ if (curwin->w_cursor.col < save_col) {
mincol = curwin->w_cursor.col;
+ }
curwin->w_cursor.col = save_col;
}
@@ -8213,7 +8368,7 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
getvcol(curwin, &curwin->w_cursor, NULL, NULL, &want_vcol);
inc_cursor();
if (p_sta && in_indent) {
- ts = (int)get_sw_value(curbuf);
+ ts = get_sw_value(curbuf);
want_vcol = (want_vcol / ts) * ts;
} else {
want_vcol = tabstop_start(want_vcol,
@@ -8239,8 +8394,9 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
ins_char(' ');
} else {
ins_str((char_u *)" ");
- if ((State & REPLACE_FLAG))
+ if ((State & REPLACE_FLAG)) {
replace_push(NUL);
+ }
}
getvcol(curwin, &curwin->w_cursor, &vcol, NULL, NULL);
}
@@ -8251,7 +8407,7 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
ins_bs_one(&vcol);
}
} else {
- // Delete upto starting point, start of line or previous word.
+ // Delete up to starting point, start of line or previous word.
int prev_cclass = 0;
int cclass = mb_get_class(get_cursor_pos_ptr());
@@ -8294,8 +8450,9 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
revins_chars--;
revins_legal++;
}
- if (revins_on && gchar_cursor() == NUL)
+ if (revins_on && gchar_cursor() == NUL) {
break;
+ }
}
// Just a single backspace?:
if (mode == BACKSPACE_CHAR) {
@@ -8349,12 +8506,12 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
static void ins_mouse(int c)
{
pos_T tpos;
- win_T *old_curwin = curwin;
+ win_T *old_curwin = curwin;
undisplay_dollar();
tpos = curwin->w_cursor;
if (do_mouse(NULL, c, BACKWARD, 1, 0)) {
- win_T *new_curwin = curwin;
+ win_T *new_curwin = curwin;
if (curwin != old_curwin && win_valid(old_curwin)) {
// Mouse took us to another window. We need to go back to the
@@ -8394,21 +8551,22 @@ static void ins_mousescroll(int dir)
curwin = wp;
curbuf = curwin->w_buffer;
}
- if (curwin == old_curwin)
+ if (curwin == old_curwin) {
undisplay_dollar();
+ }
// Don't scroll the window in which completion is being done.
if (!pum_visible()
- || curwin != old_curwin
- ) {
+ || curwin != old_curwin) {
if (dir == MSCR_DOWN || dir == MSCR_UP) {
- if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL))
+ if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) {
scroll_redraw(dir,
- (long)(curwin->w_botline - curwin->w_topline));
- else
+ (curwin->w_botline - curwin->w_topline));
+ } else {
scroll_redraw(dir, 3L);
+ }
} else {
- mouse_scroll_horiz(dir);
+ mouse_scroll_horiz(dir);
}
}
@@ -8430,8 +8588,9 @@ static void ins_left(void)
pos_T tpos;
const bool end_change = dont_sync_undo == kFalse; // end undoable change
- if ((fdo_flags & FDO_HOR) && KeyTyped)
+ if ((fdo_flags & FDO_HOR) && KeyTyped) {
foldOpenCursor();
+ }
undisplay_dollar();
tpos = curwin->w_cursor;
if (oneleft() == OK) {
@@ -8461,12 +8620,14 @@ static void ins_home(int c)
{
pos_T tpos;
- if ((fdo_flags & FDO_HOR) && KeyTyped)
+ if ((fdo_flags & FDO_HOR) && KeyTyped) {
foldOpenCursor();
+ }
undisplay_dollar();
tpos = curwin->w_cursor;
- if (c == K_C_HOME)
+ if (c == K_C_HOME) {
curwin->w_cursor.lnum = 1;
+ }
curwin->w_cursor.col = 0;
curwin->w_cursor.coladd = 0;
curwin->w_curswant = 0;
@@ -8477,12 +8638,14 @@ static void ins_end(int c)
{
pos_T tpos;
- if ((fdo_flags & FDO_HOR) && KeyTyped)
+ if ((fdo_flags & FDO_HOR) && KeyTyped) {
foldOpenCursor();
+ }
undisplay_dollar();
tpos = curwin->w_cursor;
- if (c == K_C_END)
+ if (c == K_C_END) {
curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+ }
coladvance(MAXCOL);
curwin->w_curswant = MAXCOL;
@@ -8530,8 +8693,9 @@ static void ins_right(void)
}
revins_legal++;
- if (revins_chars)
+ if (revins_chars) {
revins_chars--;
+ }
} else if (vim_strchr(p_ww, ']') != NULL
&& curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) {
// if 'whichwrap' set for cursor in insert mode, may move the
@@ -8567,9 +8731,8 @@ static void ins_s_right(void)
dont_sync_undo = kFalse;
}
-static void ins_up(
- bool startcol // when true move to Insstart.col
-)
+/// @param startcol when true move to Insstart.col
+static void ins_up(bool startcol)
{
pos_T tpos;
linenr_T old_topline = curwin->w_topline;
@@ -8578,12 +8741,13 @@ static void ins_up(
undisplay_dollar();
tpos = curwin->w_cursor;
if (cursor_up(1L, TRUE) == OK) {
- if (startcol)
+ if (startcol) {
coladvance(getvcol_nolist(&Insstart));
+ }
if (old_topline != curwin->w_topline
- || old_topfill != curwin->w_topfill
- )
+ || old_topfill != curwin->w_topfill) {
redraw_later(curwin, VALID);
+ }
start_arrow(&tpos);
can_cindent = true;
} else {
@@ -8615,9 +8779,8 @@ static void ins_pageup(void)
}
}
-static void ins_down(
- bool startcol // when true move to Insstart.col
-)
+/// @param startcol when true move to Insstart.col
+static void ins_down(bool startcol)
{
pos_T tpos;
linenr_T old_topline = curwin->w_topline;
@@ -8626,12 +8789,13 @@ static void ins_down(
undisplay_dollar();
tpos = curwin->w_cursor;
if (cursor_down(1L, TRUE) == OK) {
- if (startcol)
+ if (startcol) {
coladvance(getvcol_nolist(&Insstart));
+ }
if (old_topline != curwin->w_topline
- || old_topfill != curwin->w_topfill
- )
+ || old_topfill != curwin->w_topfill) {
redraw_later(curwin, VALID);
+ }
start_arrow(&tpos);
can_cindent = true;
} else {
@@ -8687,15 +8851,15 @@ static bool ins_tab(void)
// When nothing special, insert TAB like a normal character.
if (!curbuf->b_p_et
&& !(
- p_sta
- && ind
- // These five lines mean 'tabstop' != 'shiftwidth'
- && ((tabstop_count(curbuf->b_p_vts_array) > 1)
- || (tabstop_count(curbuf->b_p_vts_array) == 1
- && tabstop_first(curbuf->b_p_vts_array)
- != get_sw_value(curbuf))
- || (tabstop_count(curbuf->b_p_vts_array) == 0
- && curbuf->b_p_ts != get_sw_value(curbuf))))
+ p_sta
+ && ind
+ // These five lines mean 'tabstop' != 'shiftwidth'
+ && ((tabstop_count(curbuf->b_p_vts_array) > 1)
+ || (tabstop_count(curbuf->b_p_vts_array) == 1
+ && tabstop_first(curbuf->b_p_vts_array)
+ != get_sw_value(curbuf))
+ || (tabstop_count(curbuf->b_p_vts_array) == 0
+ && curbuf->b_p_ts != get_sw_value(curbuf))))
&& tabstop_count(curbuf->b_p_vsts_array) == 0 && get_sts_value() == 0) {
return true;
}
@@ -8711,7 +8875,7 @@ static bool ins_tab(void)
AppendToRedobuff("\t");
if (p_sta && ind) { // insert tab in indent, use 'shiftwidth'
- temp = (int)get_sw_value(curbuf);
+ temp = get_sw_value(curbuf);
temp -= get_nolist_virtcol() % temp;
} else if (tabstop_count(curbuf->b_p_vsts_array) > 0
|| curbuf->b_p_sts != 0) {
@@ -8727,7 +8891,7 @@ static bool ins_tab(void)
}
/*
- * Insert the first space with ins_char(). It will delete one char in
+ * Insert the first space with ins_char(). It will delete one char in
* replace mode. Insert the rest with ins_str(); it will not delete any
* chars. For VREPLACE mode, we use ins_char() for all characters.
*/
@@ -8749,11 +8913,11 @@ static bool ins_tab(void)
if (!curbuf->b_p_et && (tabstop_count(curbuf->b_p_vsts_array) > 0
|| get_sts_value() > 0
|| (p_sta && ind))) {
- char_u *ptr;
- char_u *saved_line = NULL; // init for GCC
+ char_u *ptr;
+ char_u *saved_line = NULL; // init for GCC
pos_T pos;
pos_T fpos;
- pos_T *cursor;
+ pos_T *cursor;
colnr_T want_vcol, vcol;
int change_col = -1;
int save_list = curwin->w_p_list;
@@ -8800,8 +8964,9 @@ static bool ins_tab(void)
// and 'linebreak' adding extra virtual columns.
while (ascii_iswhite(*ptr)) {
i = lbr_chartabsize(NULL, (char_u *)"\t", vcol);
- if (vcol + i > want_vcol)
+ if (vcol + i > want_vcol) {
break;
+ }
if (*ptr != TAB) {
*ptr = TAB;
if (change_col < 0) {
@@ -8865,12 +9030,13 @@ static bool ins_tab(void)
// Insert each char in saved_line from changed_col to
// ptr-cursor
ins_bytes_len(saved_line + change_col,
- cursor->col - change_col);
+ cursor->col - change_col);
}
}
- if (State & VREPLACE_FLAG)
+ if (State & VREPLACE_FLAG) {
xfree(saved_line);
+ }
curwin->w_p_list = save_list;
}
@@ -8896,9 +9062,9 @@ static bool ins_eol(int c)
* nothing to put back when the NL is deleted.
*/
if ((State & REPLACE_FLAG)
- && !(State & VREPLACE_FLAG)
- )
+ && !(State & VREPLACE_FLAG)) {
replace_push(NUL);
+ }
/*
* In VREPLACE mode, a NL replaces the rest of the line, and starts
@@ -9008,8 +9174,8 @@ int ins_copychar(linenr_T lnum)
{
int c;
int temp;
- char_u *ptr, *prev_ptr;
- char_u *line;
+ char_u *ptr, *prev_ptr;
+ char_u *line;
if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) {
vim_beep(BO_COPY);
@@ -9025,8 +9191,9 @@ int ins_copychar(linenr_T lnum)
prev_ptr = ptr;
temp += lbr_chartabsize_adv(line, &ptr, (colnr_T)temp);
}
- if ((colnr_T)temp > curwin->w_virtcol)
+ if ((colnr_T)temp > curwin->w_virtcol) {
ptr = prev_ptr;
+ }
c = utf_ptr2char(ptr);
if (c == NUL) {
@@ -9043,10 +9210,11 @@ static int ins_ctrl_ey(int tc)
int c = tc;
if (ctrl_x_mode == CTRL_X_SCROLL) {
- if (c == Ctrl_Y)
+ if (c == Ctrl_Y) {
scrolldown_clamp();
- else
+ } else {
scrollup_clamp();
+ }
redraw_later(curwin, VALID);
} else {
c = ins_copychar(curwin->w_cursor.lnum + (c == Ctrl_Y ? -1 : 1));
@@ -9079,10 +9247,10 @@ static int ins_ctrl_ey(int tc)
*/
static void ins_try_si(int c)
{
- pos_T *pos, old_pos;
- char_u *ptr;
+ pos_T *pos, old_pos;
+ char_u *ptr;
int i;
- int temp;
+ bool temp;
/*
* do some very smart indenting when entering '{' or '}'
@@ -9108,20 +9276,20 @@ static void ins_try_si(int c)
}
curwin->w_cursor.lnum = pos->lnum;
curwin->w_cursor.col = i;
- if (ptr[i] == ')' && (pos = findmatch(NULL, '(')) != NULL)
+ if (ptr[i] == ')' && (pos = findmatch(NULL, '(')) != NULL) {
curwin->w_cursor = *pos;
+ }
i = get_indent();
curwin->w_cursor = old_pos;
- if (State & VREPLACE_FLAG)
+ if (State & VREPLACE_FLAG) {
change_indent(INDENT_SET, i, FALSE, NUL, TRUE);
- else
+ } else {
(void)set_indent(i, SIN_CHANGED);
+ }
} else if (curwin->w_cursor.col > 0) {
- /*
- * when inserting '{' after "O" reduce indent, but not
- * more than indent of previous line
- */
- temp = TRUE;
+ // when inserting '{' after "O" reduce indent, but not
+ // more than indent of previous line
+ temp = true;
if (c == '{' && can_si_back && curwin->w_cursor.lnum > 1) {
old_pos = curwin->w_cursor;
i = get_indent();
@@ -9133,12 +9301,14 @@ static void ins_try_si(int c)
break;
}
}
- if (get_indent() >= i)
- temp = FALSE;
+ if (get_indent() >= i) {
+ temp = false;
+ }
curwin->w_cursor = old_pos;
}
- if (temp)
+ if (temp) {
shift_line(TRUE, FALSE, 1, TRUE);
+ }
}
}
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index ff019d1e07..768b82b464 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -20,12 +20,12 @@
#include "nvim/charset.h"
#include "nvim/cursor.h"
#include "nvim/edit.h"
-#include "nvim/eval/userfunc.h"
#include "nvim/eval.h"
#include "nvim/eval/encode.h"
#include "nvim/eval/executor.h"
#include "nvim/eval/gc.h"
#include "nvim/eval/typval.h"
+#include "nvim/eval/userfunc.h"
#include "nvim/ex_cmds2.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_getln.h"
@@ -65,8 +65,11 @@ static char *e_missbrac = N_("E111: Missing ']'");
static char *e_dictrange = N_("E719: Cannot use [:] with a Dictionary");
static char *e_illvar = N_("E461: Illegal variable name: %s");
static char *e_cannot_mod = N_("E995: Cannot modify existing variable");
+static char *e_nowhitespace
+ = N_("E274: No white space allowed before parenthesis");
static char *e_invalwindow = N_("E957: Invalid window number");
static char *e_lock_unlock = N_("E940: Cannot lock or unlock variable %s");
+static char *e_write2 = N_("E80: Error while writing: %s");
// TODO(ZyX-I): move to eval/executor
static char *e_letwrong = N_("E734: Wrong variable type for %s=");
@@ -94,7 +97,7 @@ typedef struct {
dict_T sv_dict;
} scriptvar_T;
-static garray_T ga_scripts = {0, 0, sizeof(scriptvar_T *), 4, NULL};
+static garray_T ga_scripts = { 0, 0, sizeof(scriptvar_T *), 4, NULL };
#define SCRIPT_SV(id) (((scriptvar_T **)ga_scripts.ga_data)[(id) - 1])
#define SCRIPT_VARS(id) (SCRIPT_SV(id)->sv_dict.dv_hashtab)
@@ -110,7 +113,9 @@ typedef struct {
int fi_semicolon; // TRUE if ending in '; var]'
int fi_varcount; // nr of variables in the list
listwatch_T fi_lw; // keep an eye on the item used.
- list_T *fi_list; // list being used
+ list_T *fi_list; // list being used
+ int fi_bi; // index of blob
+ blob_T *fi_blob; // blob being used
} forinfo_T;
// values for vv_flags:
@@ -134,7 +139,7 @@ typedef struct {
// The reason to use this table anyway is for very quick access to the
// variables with the VV_ defines.
static struct vimvar {
- char *vv_name; ///< Name of the variable, without v:.
+ char *vv_name; ///< Name of the variable, without v:.
TV_DICTITEM_STRUCT(17) vv_di; ///< Value and name for key (max 16 chars).
char vv_flags; ///< Flags: #VV_COMPAT, #VV_RO, #VV_RO_SBX.
} vimvars[] =
@@ -225,6 +230,7 @@ static struct vimvar {
VV(VV_TYPE_DICT, "t_dict", VAR_NUMBER, VV_RO),
VV(VV_TYPE_FLOAT, "t_float", VAR_NUMBER, VV_RO),
VV(VV_TYPE_BOOL, "t_bool", VAR_NUMBER, VV_RO),
+ VV(VV_TYPE_BLOB, "t_blob", VAR_NUMBER, VV_RO),
VV(VV_EVENT, "event", VAR_DICT, VV_RO),
VV(VV_ECHOSPACE, "echospace", VAR_NUMBER, VV_RO),
VV(VV_ARGV, "argv", VAR_LIST, VV_RO),
@@ -236,6 +242,7 @@ static struct vimvar {
VV(VV__NULL_STRING, "_null_string", VAR_STRING, VV_RO),
VV(VV__NULL_LIST, "_null_list", VAR_LIST, VV_RO),
VV(VV__NULL_DICT, "_null_dict", VAR_DICT, VV_RO),
+ VV(VV__NULL_BLOB, "_null_blob", VAR_BLOB, VV_RO),
VV(VV_LUA, "lua", VAR_PARTIAL, VV_RO),
};
#undef VV
@@ -249,6 +256,7 @@ static struct vimvar {
#define vv_str vv_di.di_tv.vval.v_string
#define vv_list vv_di.di_tv.vval.v_list
#define vv_dict vv_di.di_tv.vval.v_dict
+#define vv_blob vv_di.di_tv.vval.v_blob
#define vv_partial vv_di.di_tv.vval.v_partial
#define vv_tv vv_di.di_tv
@@ -265,7 +273,7 @@ static partial_T *vvlua_partial;
#endif
static uint64_t last_timer_id = 1;
-static PMap(uint64_t) *timers = NULL;
+static PMap(uint64_t) timers = MAP_INIT;
static const char *const msgpack_type_names[] = {
[kMPNil] = "nil",
@@ -326,8 +334,7 @@ void eval_init(void)
{
vimvars[VV_VERSION].vv_nr = VIM_VERSION_100;
- timers = pmap_new(uint64_t)();
- struct vimvar *p;
+ struct vimvar *p;
init_var_dict(&globvardict, &globvars_var, VAR_DEF_SCOPE);
init_var_dict(&vimvardict, &vimvars_var, VAR_SCOPE);
@@ -339,12 +346,13 @@ void eval_init(void)
p = &vimvars[i];
assert(STRLEN(p->vv_name) <= 16);
STRCPY(p->vv_di.di_key, p->vv_name);
- if (p->vv_flags & VV_RO)
+ if (p->vv_flags & VV_RO) {
p->vv_di.di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
- else if (p->vv_flags & VV_RO_SBX)
+ } else if (p->vv_flags & VV_RO_SBX) {
p->vv_di.di_flags = DI_FLAGS_RO_SBX | DI_FLAGS_FIX;
- else
+ } else {
p->vv_di.di_flags = DI_FLAGS_FIX;
+ }
// add to v: scope dict, unless the value is not always available
if (p->vv_type != VAR_UNKNOWN) {
@@ -392,6 +400,7 @@ void eval_init(void)
set_vim_var_nr(VV_TYPE_DICT, VAR_TYPE_DICT);
set_vim_var_nr(VV_TYPE_FLOAT, VAR_TYPE_FLOAT);
set_vim_var_nr(VV_TYPE_BOOL, VAR_TYPE_BOOL);
+ set_vim_var_nr(VV_TYPE_BLOB, VAR_TYPE_BLOB);
set_vim_var_bool(VV_FALSE, kBoolVarFalse);
set_vim_var_bool(VV_TRUE, kBoolVarTrue);
@@ -416,7 +425,7 @@ void eval_init(void)
#if defined(EXITFREE)
void eval_clear(void)
{
- struct vimvar *p;
+ struct vimvar *p;
for (size_t i = 0; i < ARRAY_SIZE(vimvars); i++) {
p = &vimvars[i];
@@ -443,10 +452,12 @@ void eval_clear(void)
/* Script-local variables. First clear all the variables and in a second
* loop free the scriptvar_T, because a variable in one script might hold
* a reference to the whole scope of another script. */
- for (int i = 1; i <= ga_scripts.ga_len; ++i)
+ for (int i = 1; i <= ga_scripts.ga_len; ++i) {
vars_clear(&SCRIPT_VARS(i));
- for (int i = 1; i <= ga_scripts.ga_len; ++i)
+ }
+ for (int i = 1; i <= ga_scripts.ga_len; ++i) {
xfree(SCRIPT_SV(i));
+ }
ga_clear(&ga_scripts);
// unreferenced lists and dicts
@@ -473,20 +484,16 @@ void set_internal_string_var(const char *name, char_u *value)
set_var(name, strlen(name), &tv, true);
}
-static lval_T *redir_lval = NULL;
+static lval_T *redir_lval = NULL;
static garray_T redir_ga; // Only valid when redir_lval is not NULL.
static char_u *redir_endp = NULL;
-static char_u *redir_varname = NULL;
+static char_u *redir_varname = NULL;
-/*
- * Start recording command output to a variable
- * Returns OK if successfully completed the setup. FAIL otherwise.
- */
-int
-var_redir_start(
- char_u *name,
- int append // append to an existing variable
-)
+/// Start recording command output to a variable
+/// Returns OK if successfully completed the setup. FAIL otherwise.
+///
+/// @param append append to an existing variable
+int var_redir_start(char_u *name, int append)
{
int save_emsg;
int err;
@@ -559,8 +566,9 @@ void var_redir_str(char_u *value, int value_len)
{
int len;
- if (redir_lval == NULL)
+ if (redir_lval == NULL) {
return;
+ }
if (value_len == -1) {
len = (int)STRLEN(value); // Append the entire string
@@ -647,8 +655,7 @@ int eval_printexpr(const char *const fname, const char *const args)
return OK;
}
-void eval_diff(const char *const origfile, const char *const newfile,
- const char *const outfile)
+void eval_diff(const char *const origfile, const char *const newfile, const char *const outfile)
{
bool err = false;
@@ -661,8 +668,7 @@ void eval_diff(const char *const origfile, const char *const newfile,
set_vim_var_string(VV_FNAME_OUT, NULL, -1);
}
-void eval_patch(const char *const origfile, const char *const difffile,
- const char *const outfile)
+void eval_patch(const char *const origfile, const char *const difffile, const char *const outfile)
{
bool err = false;
@@ -675,18 +681,13 @@ void eval_patch(const char *const origfile, const char *const difffile,
set_vim_var_string(VV_FNAME_OUT, NULL, -1);
}
-/*
- * Top level evaluation function, returning a boolean.
- * Sets "error" to TRUE if there was an error.
- * Return TRUE or FALSE.
- */
-int
-eval_to_bool(
- char_u *arg,
- bool *error,
- char_u **nextcmd,
- int skip // only parse, don't execute
-)
+/// Top level evaluation function, returning a boolean.
+/// Sets "error" to TRUE if there was an error.
+///
+/// @param skip only parse, don't execute
+///
+/// @return TRUE or FALSE.
+int eval_to_bool(char_u *arg, bool *error, char_u **nextcmd, int skip)
{
typval_T tv;
bool retval = false;
@@ -733,19 +734,18 @@ static int eval1_emsg(char_u **arg, typval_T *rettv, bool evaluate)
return ret;
}
-int eval_expr_typval(const typval_T *expr, typval_T *argv,
- int argc, typval_T *rettv)
+int eval_expr_typval(const typval_T *expr, typval_T *argv, int argc, typval_T *rettv)
FUNC_ATTR_NONNULL_ARG(1, 2, 4)
{
- int dummy;
+ funcexe_T funcexe = FUNCEXE_INIT;
if (expr->v_type == VAR_FUNC) {
const char_u *const s = expr->vval.v_string;
if (s == NULL || *s == NUL) {
return FAIL;
}
- if (call_func(s, -1, rettv, argc, argv, NULL,
- 0L, 0L, &dummy, true, NULL, NULL) == FAIL) {
+ funcexe.evaluate = true;
+ if (call_func(s, -1, rettv, argc, argv, &funcexe) == FAIL) {
return FAIL;
}
} else if (expr->v_type == VAR_PARTIAL) {
@@ -754,8 +754,9 @@ int eval_expr_typval(const typval_T *expr, typval_T *argv,
if (s == NULL || *s == NUL) {
return FAIL;
}
- if (call_func(s, -1, rettv, argc, argv, NULL,
- 0L, 0L, &dummy, true, partial, NULL) == FAIL) {
+ funcexe.evaluate = true;
+ funcexe.partial = partial;
+ if (call_func(s, -1, rettv, argc, argv, &funcexe) == FAIL) {
return FAIL;
}
} else {
@@ -802,8 +803,7 @@ bool eval_expr_to_bool(const typval_T *expr, bool *error)
///
/// @return [allocated] string result of evaluation or NULL in case of error or
/// when skipping.
-char *eval_to_string_skip(const char *arg, const char **nextcmd,
- const bool skip)
+char *eval_to_string_skip(const char *arg, const char **nextcmd, const bool skip)
FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_WARN_UNUSED_RESULT
{
typval_T tv;
@@ -837,13 +837,13 @@ int skip_expr(char_u **pp)
return eval1(pp, &rettv, FALSE);
}
-/*
- * Top level evaluation function, returning a string.
- * When "convert" is TRUE convert a List into a sequence of lines and convert
- * a Float to a String.
- * Return pointer to allocated memory, or NULL for failure.
- */
-char_u *eval_to_string(char_u *arg, char_u **nextcmd, int convert)
+/// Top level evaluation function, returning a string.
+///
+/// @param convert when true convert a List into a sequence of lines and convert
+/// a Float to a String.
+///
+/// @return pointer to allocated memory, or NULL for failure.
+char_u *eval_to_string(char_u *arg, char_u **nextcmd, bool convert)
{
typval_T tv;
char *retval;
@@ -881,7 +881,7 @@ char_u *eval_to_string(char_u *arg, char_u **nextcmd, int convert)
*/
char_u *eval_to_string_safe(char_u *arg, char_u **nextcmd, int use_sandbox)
{
- char_u *retval;
+ char_u *retval;
funccal_entry_T funccal_entry;
save_funccal(&funccal_entry);
@@ -907,7 +907,7 @@ varnumber_T eval_to_number(char_u *expr)
{
typval_T rettv;
varnumber_T retval;
- char_u *p = skipwhite(expr);
+ char_u *p = skipwhite(expr);
++emsg_off;
@@ -942,8 +942,9 @@ typval_T *eval_expr(char_u *arg)
void prepare_vimvar(int idx, typval_T *save_tv)
{
*save_tv = vimvars[idx].vv_tv;
- if (vimvars[idx].vv_type == VAR_UNKNOWN)
+ if (vimvars[idx].vv_type == VAR_UNKNOWN) {
hash_add(&vimvarht, vimvars[idx].vv_di.di_key);
+ }
}
/*
@@ -952,7 +953,7 @@ void prepare_vimvar(int idx, typval_T *save_tv)
*/
void restore_vimvar(int idx, typval_T *save_tv)
{
- hashitem_T *hi;
+ hashitem_T *hi;
vimvars[idx].vv_tv = *save_tv;
if (vimvars[idx].vv_type == VAR_UNKNOWN) {
@@ -985,15 +986,16 @@ list_T *eval_spell_expr(char_u *badword, char_u *expr)
{
typval_T save_val;
typval_T rettv;
- list_T *list = NULL;
- char_u *p = skipwhite(expr);
+ list_T *list = NULL;
+ char_u *p = skipwhite(expr);
// Set "v:val" to the bad word.
prepare_vimvar(VV_VAL, &save_val);
vimvars[VV_VAL].vv_type = VAR_STRING;
vimvars[VV_VAL].vv_str = badword;
- if (p_verbose == 0)
+ if (p_verbose == 0) {
++emsg_off;
+ }
if (eval1(&p, &rettv, true) == OK) {
if (rettv.v_type != VAR_LIST) {
@@ -1003,8 +1005,9 @@ list_T *eval_spell_expr(char_u *badword, char_u *expr)
}
}
- if (p_verbose == 0)
+ if (p_verbose == 0) {
--emsg_off;
+ }
restore_vimvar(VV_VAL, &save_val);
return list;
@@ -1043,15 +1046,9 @@ int get_spellword(list_T *const list, const char **ret_word)
// should have type VAR_UNKNOWN.
//
// Return OK or FAIL.
-int call_vim_function(
- const char_u *func,
- int argc,
- typval_T *argv,
- typval_T *rettv
-)
+int call_vim_function(const char_u *func, int argc, typval_T *argv, typval_T *rettv)
FUNC_ATTR_NONNULL_ALL
{
- int doesrange;
int ret;
int len = (int)STRLEN(func);
partial_T *pt = NULL;
@@ -1067,9 +1064,12 @@ int call_vim_function(
}
rettv->v_type = VAR_UNKNOWN; // tv_clear() uses this.
- ret = call_func(func, len, rettv, argc, argv, NULL,
- curwin->w_cursor.lnum, curwin->w_cursor.lnum,
- &doesrange, true, pt, NULL);
+ funcexe_T funcexe = FUNCEXE_INIT;
+ funcexe.firstline = curwin->w_cursor.lnum;
+ funcexe.lastline = curwin->w_cursor.lnum;
+ funcexe.evaluate = true;
+ funcexe.partial = pt;
+ ret = call_func(func, len, rettv, argc, argv, &funcexe);
fail:
if (ret == FAIL) {
@@ -1085,8 +1085,7 @@ fail:
/// @param[in] argv Array with typval_T arguments.
///
/// @return -1 when calling function fails, result of function otherwise.
-varnumber_T call_func_retnr(const char_u *func, int argc,
- typval_T *argv)
+varnumber_T call_func_retnr(const char_u *func, int argc, typval_T *argv)
FUNC_ATTR_NONNULL_ALL
{
typval_T rettv;
@@ -1107,8 +1106,7 @@ varnumber_T call_func_retnr(const char_u *func, int argc,
///
/// @return [allocated] NULL when calling function fails, allocated string
/// otherwise.
-char *call_func_retstr(const char *const func, int argc,
- typval_T *argv)
+char *call_func_retstr(const char *const func, int argc, typval_T *argv)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_MALLOC
{
typval_T rettv;
@@ -1148,14 +1146,12 @@ void *call_func_retlist(const char_u *func, int argc, typval_T *argv)
return rettv.vval.v_list;
}
-/*
- * Prepare profiling for entering a child or something else that is not
- * counted for the script/function itself.
- * Should always be called in pair with prof_child_exit().
- */
-void prof_child_enter(
- proftime_T *tm // place to store waittime
-)
+/// Prepare profiling for entering a child or something else that is not
+/// counted for the script/function itself.
+/// Should always be called in pair with prof_child_exit().
+///
+/// @param tm place to store waittime
+void prof_child_enter(proftime_T *tm)
{
funccall_T *fc = get_current_funccal();
@@ -1166,13 +1162,11 @@ void prof_child_enter(
script_prof_save(tm);
}
-/*
- * Take care of time spent in a child.
- * Should always be called after prof_child_enter().
- */
-void prof_child_exit(
- proftime_T *tm // where waittime was stored
-)
+/// Take care of time spent in a child.
+/// Should always be called after prof_child_enter().
+///
+/// @param tm where waittime was stored
+void prof_child_exit(proftime_T *tm)
{
funccall_T *fc = get_current_funccal();
@@ -1200,8 +1194,9 @@ int eval_foldexpr(char_u *arg, int *cp)
int use_sandbox = was_set_insecurely(curwin, (char_u *)"foldexpr", OPT_LOCAL);
++emsg_off;
- if (use_sandbox)
+ if (use_sandbox) {
++sandbox;
+ }
++textlock;
*cp = NUL;
if (eval0(arg, &tv, NULL, true) == FAIL) {
@@ -1224,8 +1219,9 @@ int eval_foldexpr(char_u *arg, int *cp)
tv_clear(&tv);
}
--emsg_off;
- if (use_sandbox)
+ if (use_sandbox) {
--sandbox;
+ }
--textlock;
return (int)retval;
@@ -1251,8 +1247,7 @@ void ex_const(exarg_T *eap)
// marker, then the leading indentation before the lines (matching the
// indentation in the 'cmd' line) is stripped.
// Returns a List with {lines} or NULL.
-static list_T *
-heredoc_get(exarg_T *eap, char_u *cmd)
+static list_T *heredoc_get(exarg_T *eap, char_u *cmd)
{
char_u *marker;
char_u *p;
@@ -1316,29 +1311,29 @@ heredoc_get(exarg_T *eap, char_u *cmd)
// marker
if (marker_indent_len > 0
&& STRNCMP(theline, *eap->cmdlinep, marker_indent_len) == 0) {
- mi = marker_indent_len;
+ mi = marker_indent_len;
}
if (STRCMP(marker, theline + mi) == 0) {
xfree(theline);
break;
}
if (text_indent_len == -1 && *theline != NUL) {
- // set the text indent from the first line.
- p = theline;
- text_indent_len = 0;
- while (ascii_iswhite(*p)) {
- p++;
- text_indent_len++;
- }
- text_indent = vim_strnsave(theline, text_indent_len);
+ // set the text indent from the first line.
+ p = theline;
+ text_indent_len = 0;
+ while (ascii_iswhite(*p)) {
+ p++;
+ text_indent_len++;
+ }
+ text_indent = vim_strnsave(theline, text_indent_len);
}
// with "trim": skip the indent matching the first line
if (text_indent != NULL) {
- for (ti = 0; ti < text_indent_len; ti++) {
- if (theline[ti] != text_indent[ti]) {
- break;
- }
+ for (ti = 0; ti < text_indent_len; ti++) {
+ if (theline[ti] != text_indent[ti]) {
+ break;
}
+ }
}
tv_list_append_string(l, (char *)(theline + ti), -1);
@@ -1368,14 +1363,14 @@ void ex_let(exarg_T *eap)
static void ex_let_const(exarg_T *eap, const bool is_const)
{
- char_u *arg = eap->arg;
- char_u *expr = NULL;
+ char_u *arg = eap->arg;
+ char_u *expr = NULL;
typval_T rettv;
int i;
int var_count = 0;
int semicolon = 0;
char_u op[2];
- char_u *argend;
+ char_u *argend;
int first = TRUE;
argend = (char_u *)skip_var_list(arg, &var_count, &semicolon);
@@ -1433,8 +1428,9 @@ static void ex_let_const(exarg_T *eap, const bool is_const)
expr = skipwhite(expr + 1);
}
- if (eap->skip)
+ if (eap->skip) {
++emsg_skip;
+ }
i = eval0(expr, &rettv, &eap->nextcmd, !eap->skip);
if (eap->skip) {
if (i != FAIL) {
@@ -1449,24 +1445,20 @@ static void ex_let_const(exarg_T *eap, const bool is_const)
}
}
-/*
- * Assign the typevalue "tv" to the variable or variables at "arg_start".
- * Handles both "var" with any type and "[var, var; var]" with a list type.
- * When "nextchars" is not NULL it points to a string with characters that
- * must appear after the variable(s). Use "+", "-" or "." for add, subtract
- * or concatenate.
- * Returns OK or FAIL;
- */
-static int
-ex_let_vars(
- char_u *arg_start,
- typval_T *tv,
- int copy, // copy values from "tv", don't move
- int semicolon, // from skip_var_list()
- int var_count, // from skip_var_list()
- int is_const, // lock variables for :const
- char_u *nextchars
-)
+/// Assign the typevalue "tv" to the variable or variables at "arg_start".
+/// Handles both "var" with any type and "[var, var; var]" with a list type.
+/// When "op" is not NULL it points to a string with characters that
+/// must appear after the variable(s). Use "+", "-" or "." for add, subtract
+/// or concatenate.
+///
+/// @param copy copy values from "tv", don't move
+/// @param semicolon from skip_var_list()
+/// @param var_count from skip_var_list()
+/// @param is_const lock variables for :const
+///
+/// @return OK or FAIL;
+static int ex_let_vars(char_u *arg_start, typval_T *tv, int copy, int semicolon, int var_count,
+ int is_const, char_u *op)
{
char_u *arg = arg_start;
typval_T ltv;
@@ -1475,7 +1467,7 @@ ex_let_vars(
/*
* ":let var = expr" or ":for var in list"
*/
- if (ex_let_one(arg, tv, copy, is_const, nextchars, nextchars) == NULL) {
+ if (ex_let_one(arg, tv, copy, is_const, op, op) == NULL) {
return FAIL;
}
return OK;
@@ -1506,7 +1498,7 @@ ex_let_vars(
while (*arg != ']') {
arg = skipwhite(arg + 1);
arg = ex_let_one(arg, TV_LIST_ITEM_TV(item), true, is_const,
- (const char_u *)",;]", nextchars);
+ (const char_u *)",;]", op);
if (arg == NULL) {
return FAIL;
}
@@ -1528,8 +1520,8 @@ ex_let_vars(
ltv.vval.v_list = rest_list;
tv_list_ref(rest_list);
- arg = ex_let_one(skipwhite(arg + 1), &ltv, false, is_const,
- (char_u *)"]", nextchars);
+ arg = ex_let_one(skipwhite(arg + 1), &ltv, false, is_const, (char_u *)"]",
+ op);
tv_clear(&ltv);
if (arg == NULL) {
return FAIL;
@@ -1551,8 +1543,7 @@ ex_let_vars(
* for "[var, var; var]" set "semicolon".
* Return NULL for an error.
*/
-static const char_u *skip_var_list(const char_u *arg, int *var_count,
- int *semicolon)
+static const char_u *skip_var_list(const char_u *arg, int *var_count, int *semicolon)
{
const char_u *p;
const char_u *s;
@@ -1570,9 +1561,9 @@ static const char_u *skip_var_list(const char_u *arg, int *var_count,
++*var_count;
p = skipwhite(s);
- if (*p == ']')
+ if (*p == ']') {
break;
- else if (*p == ';') {
+ } else if (*p == ';') {
if (*semicolon == 1) {
EMSG(_("E452: Double ; in list of variables"));
return NULL;
@@ -1584,8 +1575,9 @@ static const char_u *skip_var_list(const char_u *arg, int *var_count,
}
}
return p + 1;
- } else
+ } else {
return skip_var_one(arg);
+ }
}
/*
@@ -1594,21 +1586,21 @@ static const char_u *skip_var_list(const char_u *arg, int *var_count,
*/
static const char_u *skip_var_one(const char_u *arg)
{
- if (*arg == '@' && arg[1] != NUL)
+ if (*arg == '@' && arg[1] != NUL) {
return arg + 2;
+ }
return find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg,
- NULL, NULL, FNE_INCL_BR | FNE_CHECK_START);
+ NULL, NULL, FNE_INCL_BR | FNE_CHECK_START);
}
/*
* List variables for hashtab "ht" with prefix "prefix".
* If "empty" is TRUE also list NULL strings as empty strings.
*/
-void list_hashtable_vars(hashtab_T *ht, const char *prefix, int empty,
- int *first)
+void list_hashtable_vars(hashtab_T *ht, const char *prefix, int empty, int *first)
{
- hashitem_T *hi;
- dictitem_T *di;
+ hashitem_T *hi;
+ dictitem_T *di;
int todo;
todo = (int)ht->ht_used;
@@ -1725,18 +1717,27 @@ static const char *list_arg_vars(exarg_T *eap, const char *arg, int *first)
} else {
// handle d.key, l[idx], f(expr)
const char *const arg_subsc = arg;
- if (handle_subscript(&arg, &tv, true, true) == FAIL) {
+ if (handle_subscript(&arg, &tv, true, true, (const char_u *)name,
+ (const char_u **)&name)
+ == FAIL) {
error = true;
} else {
if (arg == arg_subsc && len == 2 && name[1] == ':') {
switch (*name) {
- case 'g': list_glob_vars(first); break;
- case 'b': list_buf_vars(first); break;
- case 'w': list_win_vars(first); break;
- case 't': list_tab_vars(first); break;
- case 'v': list_vim_vars(first); break;
- case 's': list_script_vars(first); break;
- case 'l': list_func_vars(first); break;
+ case 'g':
+ list_glob_vars(first); break;
+ case 'b':
+ list_buf_vars(first); break;
+ case 'w':
+ list_win_vars(first); break;
+ case 't':
+ list_tab_vars(first); break;
+ case 'v':
+ list_vim_vars(first); break;
+ case 's':
+ list_script_vars(first); break;
+ case 'l':
+ list_func_vars(first); break;
default:
EMSG2(_("E738: Can't list variables for %s"), name);
}
@@ -1779,8 +1780,7 @@ static const char *list_arg_vars(exarg_T *eap, const char *arg, int *first)
///
/// @return a pointer to the char just after the var name or NULL in case of
/// error.
-static char_u *ex_let_one(char_u *arg, typval_T *const tv,
- const bool copy, const bool is_const,
+static char_u *ex_let_one(char_u *arg, typval_T *const tv, const bool copy, const bool is_const,
const char_u *const endchars, const char_u *const op)
FUNC_ATTR_NONNULL_ARG(1, 2) FUNC_ATTR_WARN_UNUSED_RESULT
{
@@ -1838,9 +1838,9 @@ static char_u *ex_let_one(char_u *arg, typval_T *const tv,
xfree(tofree);
}
}
- // ":let &option = expr": Set option value.
- // ":let &l:option = expr": Set local option value.
- // ":let &g:option = expr": Set global option value.
+ // ":let &option = expr": Set option value.
+ // ":let &l:option = expr": Set local option value.
+ // ":let &g:option = expr": Set global option value.
} else if (*arg == '&') {
if (is_const) {
EMSG(_("E996: Cannot lock an option"));
@@ -1875,11 +1875,16 @@ static char_u *ex_let_one(char_u *arg, typval_T *const tv,
} else {
if (opt_type == 1) { // number
switch (*op) {
- case '+': n = numval + n; break;
- case '-': n = numval - n; break;
- case '*': n = numval * n; break;
- case '/': n = num_divide(numval, n); break;
- case '%': n = num_modulus(numval, n); break;
+ case '+':
+ n = numval + n; break;
+ case '-':
+ n = numval - n; break;
+ case '*':
+ n = numval * n; break;
+ case '/':
+ n = num_divide(numval, n); break;
+ case '%':
+ n = num_modulus(numval, n); break;
}
} else if (opt_type == 0 && stringval != NULL) { // string
char *const oldstringval = stringval;
@@ -1898,7 +1903,7 @@ static char_u *ex_let_one(char_u *arg, typval_T *const tv,
*p = c1;
xfree(stringval);
}
- // ":let @r = expr": Set register contents.
+ // ":let @r = expr": Set register contents.
} else if (*arg == '@') {
if (is_const) {
EMSG(_("E996: Cannot lock a register"));
@@ -1911,7 +1916,7 @@ static char_u *ex_let_one(char_u *arg, typval_T *const tv,
&& vim_strchr(endchars, *skipwhite(arg + 1)) == NULL) {
EMSG(_(e_letunexp));
} else {
- char_u *s;
+ char_u *s;
char_u *ptofree = NULL;
const char *p = tv_get_string_chk(tv);
@@ -1948,8 +1953,9 @@ static char_u *ex_let_one(char_u *arg, typval_T *const tv,
}
}
clear_lval(&lv);
- } else
+ } else {
EMSG2(_(e_invarg2), arg);
+ }
return arg_end;
}
@@ -1979,16 +1985,15 @@ static char_u *ex_let_one(char_u *arg, typval_T *const tv,
///
/// @return A pointer to just after the name, including indexes. Returns NULL
/// for a parsing error, but it is still needed to free items in lp.
-char_u *get_lval(char_u *const name, typval_T *const rettv,
- lval_T *const lp, const bool unlet, const bool skip,
- const int flags, const int fne_flags)
+char_u *get_lval(char_u *const name, typval_T *const rettv, lval_T *const lp, const bool unlet,
+ const bool skip, const int flags, const int fne_flags)
FUNC_ATTR_NONNULL_ARG(1, 3)
{
- dictitem_T *v;
+ dictitem_T *v;
typval_T var1;
typval_T var2;
int empty1 = FALSE;
- listitem_T *ni;
+ listitem_T *ni;
hashtab_T *ht = NULL;
int quiet = flags & GLV_QUIET;
@@ -2056,23 +2061,23 @@ char_u *get_lval(char_u *const name, typval_T *const rettv,
return NULL;
}
- /*
- * Loop until no more [idx] or .key is following.
- */
+ // Loop until no more [idx] or .key is following.
lp->ll_tv = &v->di_tv;
var1.v_type = VAR_UNKNOWN;
var2.v_type = VAR_UNKNOWN;
while (*p == '[' || (*p == '.' && lp->ll_tv->v_type == VAR_DICT)) {
if (!(lp->ll_tv->v_type == VAR_LIST && lp->ll_tv->vval.v_list != NULL)
- && !(lp->ll_tv->v_type == VAR_DICT
- && lp->ll_tv->vval.v_dict != NULL)) {
- if (!quiet)
- EMSG(_("E689: Can only index a List or Dictionary"));
+ && !(lp->ll_tv->v_type == VAR_DICT && lp->ll_tv->vval.v_dict != NULL)
+ && !(lp->ll_tv->v_type == VAR_BLOB && lp->ll_tv->vval.v_blob != NULL)) {
+ if (!quiet) {
+ EMSG(_("E689: Can only index a List, Dictionary or Blob"));
+ }
return NULL;
}
if (lp->ll_range) {
- if (!quiet)
+ if (!quiet) {
EMSG(_("E708: [:] must come last"));
+ }
return NULL;
}
@@ -2116,10 +2121,11 @@ char_u *get_lval(char_u *const name, typval_T *const rettv,
tv_clear(&var1);
return NULL;
}
- if (rettv != NULL && (rettv->v_type != VAR_LIST
- || rettv->vval.v_list == NULL)) {
+ if (rettv != NULL
+ && !(rettv->v_type == VAR_LIST && rettv->vval.v_list != NULL)
+ && !(rettv->v_type == VAR_BLOB && rettv->vval.v_blob != NULL)) {
if (!quiet) {
- EMSG(_("E709: [:] requires a List value"));
+ EMSG(_("E709: [:] requires a List or Blob value"));
}
tv_clear(&var1);
return NULL;
@@ -2223,7 +2229,7 @@ char_u *get_lval(char_u *const name, typval_T *const rettv,
}
tv_clear(&var1);
break;
- // existing variable, need to check if it can be changed
+ // existing variable, need to check if it can be changed
} else if (!(flags & GLV_READ_ONLY) && var_check_ro(lp->ll_di->di_flags,
(const char *)name,
(size_t)(p - name))) {
@@ -2233,6 +2239,38 @@ char_u *get_lval(char_u *const name, typval_T *const rettv,
tv_clear(&var1);
lp->ll_tv = &lp->ll_di->di_tv;
+ } else if (lp->ll_tv->v_type == VAR_BLOB) {
+ // Get the number and item for the only or first index of the List.
+ if (empty1) {
+ lp->ll_n1 = 0;
+ } else {
+ // Is number or string.
+ lp->ll_n1 = (long)tv_get_number(&var1);
+ }
+ tv_clear(&var1);
+
+ const int bloblen = tv_blob_len(lp->ll_tv->vval.v_blob);
+ if (lp->ll_n1 < 0 || lp->ll_n1 > bloblen
+ || (lp->ll_range && lp->ll_n1 == bloblen)) {
+ if (!quiet) {
+ EMSGN(_(e_blobidx), lp->ll_n1);
+ }
+ tv_clear(&var2);
+ return NULL;
+ }
+ if (lp->ll_range && !lp->ll_empty2) {
+ lp->ll_n2 = (long)tv_get_number(&var2);
+ tv_clear(&var2);
+ if (lp->ll_n2 < 0 || lp->ll_n2 >= bloblen || lp->ll_n2 < lp->ll_n1) {
+ if (!quiet) {
+ EMSGN(_(e_blobidx), lp->ll_n2);
+ }
+ return NULL;
+ }
+ }
+ lp->ll_blob = lp->ll_tv->vval.v_blob;
+ lp->ll_tv = NULL;
+ break;
} else {
// Get the number and item for the only or first index of the List.
if (empty1) {
@@ -2270,8 +2308,9 @@ char_u *get_lval(char_u *const name, typval_T *const rettv,
if (lp->ll_n2 < 0) {
ni = tv_list_find(lp->ll_list, lp->ll_n2);
if (ni == NULL) {
- if (!quiet)
+ if (!quiet) {
EMSGN(_(e_listidx), lp->ll_n2);
+ }
return NULL;
}
lp->ll_n2 = tv_list_idx_of_item(lp->ll_list, ni);
@@ -2316,17 +2355,60 @@ void clear_lval(lval_T *lp)
* "op" is NULL, "+" for "+=", "-" for "-=", "*" for "*=", "/" for "/=",
* "%" for "%=", "." for ".=" or "=" for "=".
*/
-static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv,
- int copy, const bool is_const, const char *op)
+static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv, int copy, const bool is_const,
+ const char *op)
{
int cc;
- listitem_T *ri;
- dictitem_T *di;
+ listitem_T *ri;
+ dictitem_T *di;
if (lp->ll_tv == NULL) {
cc = *endp;
*endp = NUL;
- if (op != NULL && *op != '=') {
+ if (lp->ll_blob != NULL) {
+ if (op != NULL && *op != '=') {
+ EMSG2(_(e_letwrong), op);
+ return;
+ }
+ if (var_check_lock(lp->ll_blob->bv_lock, lp->ll_name, TV_CSTRING)) {
+ return;
+ }
+
+ if (lp->ll_range && rettv->v_type == VAR_BLOB) {
+ if (lp->ll_empty2) {
+ lp->ll_n2 = tv_blob_len(lp->ll_blob) - 1;
+ }
+
+ if (lp->ll_n2 - lp->ll_n1 + 1 != tv_blob_len(rettv->vval.v_blob)) {
+ EMSG(_("E972: Blob value does not have the right number of bytes"));
+ return;
+ }
+ if (lp->ll_empty2) {
+ lp->ll_n2 = tv_blob_len(lp->ll_blob);
+ }
+
+ for (int il = lp->ll_n1, ir = 0; il <= lp->ll_n2; il++) {
+ tv_blob_set(lp->ll_blob, il, tv_blob_get(rettv->vval.v_blob, ir++));
+ }
+ } else {
+ bool error = false;
+ const char_u val = tv_get_number_chk(rettv, &error);
+ if (!error) {
+ garray_T *const gap = &lp->ll_blob->bv_ga;
+
+ // Allow for appending a byte. Setting a byte beyond
+ // the end is an error otherwise.
+ if (lp->ll_n1 < gap->ga_len || lp->ll_n1 == gap->ga_len) {
+ ga_grow(&lp->ll_blob->bv_ga, 1);
+ tv_blob_set(lp->ll_blob, lp->ll_n1, val);
+ if (lp->ll_n1 == gap->ga_len) {
+ gap->ga_len++;
+ }
+ }
+ // error for invalid range was already given in get_lval()
+ }
+ }
+ } else if (op != NULL && *op != '=') {
typval_T tv;
if (is_const) {
@@ -2483,16 +2565,17 @@ notify:
*/
void *eval_for_line(const char_u *arg, bool *errp, char_u **nextcmdp, int skip)
{
- forinfo_T *fi = xcalloc(1, sizeof(forinfo_T));
+ forinfo_T *fi = xcalloc(1, sizeof(forinfo_T));
const char_u *expr;
typval_T tv;
- list_T *l;
+ list_T *l;
*errp = true; // Default: there is an error.
expr = skip_var_list(arg, &fi->fi_varcount, &fi->fi_semicolon);
- if (expr == NULL)
+ if (expr == NULL) {
return fi;
+ }
expr = skipwhite(expr);
if (expr[0] != 'i' || expr[1] != 'n' || !ascii_iswhite(expr[2])) {
@@ -2500,29 +2583,44 @@ void *eval_for_line(const char_u *arg, bool *errp, char_u **nextcmdp, int skip)
return fi;
}
- if (skip)
+ if (skip) {
++emsg_skip;
+ }
if (eval0(skipwhite(expr + 2), &tv, nextcmdp, !skip) == OK) {
*errp = false;
if (!skip) {
- l = tv.vval.v_list;
- if (tv.v_type != VAR_LIST) {
- EMSG(_(e_listreq));
- tv_clear(&tv);
- } else if (l == NULL) {
- // a null list is like an empty list: do nothing
+ if (tv.v_type == VAR_LIST) {
+ l = tv.vval.v_list;
+ if (l == NULL) {
+ // a null list is like an empty list: do nothing
+ tv_clear(&tv);
+ } else {
+ // No need to increment the refcount, it's already set for
+ // the list being used in "tv".
+ fi->fi_list = l;
+ tv_list_watch_add(l, &fi->fi_lw);
+ fi->fi_lw.lw_item = tv_list_first(l);
+ }
+ } else if (tv.v_type == VAR_BLOB) {
+ fi->fi_bi = 0;
+ if (tv.vval.v_blob != NULL) {
+ typval_T btv;
+
+ // Make a copy, so that the iteration still works when the
+ // blob is changed.
+ tv_blob_copy(&tv, &btv);
+ fi->fi_blob = btv.vval.v_blob;
+ }
tv_clear(&tv);
} else {
- /* No need to increment the refcount, it's already set for the
- * list being used in "tv". */
- fi->fi_list = l;
- tv_list_watch_add(l, &fi->fi_lw);
- fi->fi_lw.lw_item = tv_list_first(l);
+ EMSG(_(e_listblobreq));
+ tv_clear(&tv);
}
}
}
- if (skip)
+ if (skip) {
--emsg_skip;
+ }
return fi;
}
@@ -2539,6 +2637,19 @@ bool next_for_item(void *fi_void, char_u *arg)
{
forinfo_T *fi = (forinfo_T *)fi_void;
+ if (fi->fi_blob != NULL) {
+ if (fi->fi_bi >= tv_blob_len(fi->fi_blob)) {
+ return false;
+ }
+ typval_T tv;
+ tv.v_type = VAR_NUMBER;
+ tv.v_lock = VAR_FIXED;
+ tv.vval.v_number = tv_blob_get(fi->fi_blob, fi->fi_bi);
+ fi->fi_bi++;
+ return ex_let_vars(arg, &tv, true,
+ fi->fi_semicolon, fi->fi_varcount, false, NULL) == OK;
+ }
+
listitem_T *item = fi->fi_lw.lw_item;
if (item == NULL) {
return false;
@@ -2556,12 +2667,15 @@ bool next_for_item(void *fi_void, char_u *arg)
*/
void free_for_info(void *fi_void)
{
- forinfo_T *fi = (forinfo_T *)fi_void;
+ forinfo_T *fi = (forinfo_T *)fi_void;
if (fi != NULL && fi->fi_list != NULL) {
tv_list_watch_remove(fi->fi_list, &fi->fi_lw);
tv_list_unref(fi->fi_list);
}
+ if (fi != NULL && fi->fi_blob != NULL) {
+ tv_blob_unref(fi->fi_blob);
+ }
xfree(fi);
}
@@ -2571,7 +2685,7 @@ void set_context_for_expression(expand_T *xp, char_u *arg, cmdidx_T cmdidx)
{
int got_eq = FALSE;
int c;
- char_u *p;
+ char_u *p;
if (cmdidx == CMD_let || cmdidx == CMD_const) {
xp->xp_context = EXPAND_USER_VARS;
@@ -2586,11 +2700,12 @@ void set_context_for_expression(expand_T *xp, char_u *arg, cmdidx_T cmdidx)
}
return;
}
- } else
+ } else {
xp->xp_context = cmdidx == CMD_call ? EXPAND_FUNCTIONS
- : EXPAND_EXPRESSION;
+ : EXPAND_EXPRESSION;
+ }
while ((xp->xp_pattern = vim_strpbrk(arg,
- (char_u *)"\"'+-*/%.=!?~|&$([<>,#")) != NULL) {
+ (char_u *)"\"'+-*/%.=!?~|&$([<>,#")) != NULL) {
c = *xp->xp_pattern;
if (c == '&') {
c = xp->xp_pattern[1];
@@ -2600,9 +2715,9 @@ void set_context_for_expression(expand_T *xp, char_u *arg, cmdidx_T cmdidx)
? EXPAND_EXPRESSION : EXPAND_NOTHING;
} else if (c != ' ') {
xp->xp_context = EXPAND_SETTINGS;
- if ((c == 'l' || c == 'g') && xp->xp_pattern[2] == ':')
+ if ((c == 'l' || c == 'g') && xp->xp_pattern[2] == ':') {
xp->xp_pattern += 2;
-
+ }
}
} else if (c == '$') {
// environment variable
@@ -2636,14 +2751,17 @@ void set_context_for_expression(expand_T *xp, char_u *arg, cmdidx_T cmdidx)
if (xp->xp_pattern[1] == '|') {
++xp->xp_pattern;
xp->xp_context = EXPAND_EXPRESSION;
- } else
+ } else {
xp->xp_context = EXPAND_COMMANDS;
- } else
+ }
+ } else {
xp->xp_context = EXPAND_EXPRESSION;
- } else
+ }
+ } else {
/* Doesn't look like something valid, expand as an expression
* anyway. */
xp->xp_context = EXPAND_EXPRESSION;
+ }
arg = xp->xp_pattern;
if (*arg != NUL) {
while ((c = *++arg) != NUL && (c == ' ' || c == '\t')) {
@@ -2705,8 +2823,7 @@ void ex_lockvar(exarg_T *eap)
/// @param[in] deep Levels to (un)lock for :(un)lockvar, -1 to (un)lock
/// everything.
/// @param[in] callback Appropriate handler for the command.
-static void ex_unletlock(exarg_T *eap, char_u *argstart, int deep,
- ex_unletlock_callback callback)
+static void ex_unletlock(exarg_T *eap, char_u *argstart, int deep, ex_unletlock_callback callback)
FUNC_ATTR_NONNULL_ALL
{
char_u *arg = argstart;
@@ -2770,8 +2887,7 @@ static void ex_unletlock(exarg_T *eap, char_u *argstart, int deep,
/// @param[in] deep Unused.
///
/// @return OK on success, or FAIL on failure.
-static int do_unlet_var(lval_T *lp, char_u *name_end, exarg_T *eap,
- int deep FUNC_ATTR_UNUSED)
+static int do_unlet_var(lval_T *lp, char_u *name_end, exarg_T *eap, int deep FUNC_ATTR_UNUSED)
FUNC_ATTR_NONNULL_ALL
{
int forceit = eap->forceit;
@@ -2875,7 +2991,7 @@ int do_unlet(const char *const name, const size_t name_len, const bool forceit)
if (ht == &globvarht) {
d = &globvardict;
} else if (ht == &compat_hashtab) {
- d = &vimvardict;
+ d = &vimvardict;
} else {
dictitem_T *const di = find_var_in_ht(ht, *name, "", 0, false);
d = di->di_tv.vval.v_dict;
@@ -2918,8 +3034,9 @@ int do_unlet(const char *const name, const size_t name_len, const bool forceit)
return OK;
}
}
- if (forceit)
+ if (forceit) {
return OK;
+ }
EMSG2(_("E108: No such variable: \"%s\""), name);
return FAIL;
}
@@ -2936,8 +3053,7 @@ int do_unlet(const char *const name, const size_t name_len, const bool forceit)
/// @param[in] deep Levels to (un)lock, -1 to (un)lock everything.
///
/// @return OK on success, or FAIL on failure.
-static int do_lock_var(lval_T *lp, char_u *name_end FUNC_ATTR_UNUSED,
- exarg_T *eap, int deep)
+static int do_lock_var(lval_T *lp, char_u *name_end FUNC_ATTR_UNUSED, exarg_T *eap, int deep)
FUNC_ATTR_NONNULL_ARG(1, 3)
{
bool lock = eap->cmdidx == CMD_lockvar;
@@ -2953,9 +3069,8 @@ static int do_lock_var(lval_T *lp, char_u *name_end FUNC_ATTR_UNUSED,
ret = FAIL;
} else {
// Normal name or expanded name.
- dictitem_T *const di = find_var(
- (const char *)lp->ll_name, lp->ll_name_len, NULL,
- true);
+ dictitem_T *const di = find_var((const char *)lp->ll_name, lp->ll_name_len, NULL,
+ true);
if (di == NULL) {
ret = FAIL;
} else if ((di->di_flags & DI_FLAGS_FIX)
@@ -2971,24 +3086,24 @@ static int do_lock_var(lval_T *lp, char_u *name_end FUNC_ATTR_UNUSED,
} else {
di->di_flags &= ~DI_FLAGS_LOCK;
}
- tv_item_lock(&di->di_tv, deep, lock);
+ tv_item_lock(&di->di_tv, deep, lock, false);
}
}
} else if (lp->ll_range) {
- listitem_T *li = lp->ll_li;
+ listitem_T *li = lp->ll_li;
// (un)lock a range of List items.
while (li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) {
- tv_item_lock(TV_LIST_ITEM_TV(li), deep, lock);
+ tv_item_lock(TV_LIST_ITEM_TV(li), deep, lock, false);
li = TV_LIST_ITEM_NEXT(lp->ll_list, li);
lp->ll_n1++;
}
} else if (lp->ll_list != NULL) {
// (un)lock a List item.
- tv_item_lock(TV_LIST_ITEM_TV(lp->ll_li), deep, lock);
+ tv_item_lock(TV_LIST_ITEM_TV(lp->ll_li), deep, lock, false);
} else {
// (un)lock a Dictionary item.
- tv_item_lock(&lp->ll_di->di_tv, deep, lock);
+ tv_item_lock(&lp->ll_di->di_tv, deep, lock, false);
}
return ret;
@@ -3015,7 +3130,7 @@ void del_menutrans_vars(void)
*/
-static char_u *varnamebuf = NULL;
+static char_u *varnamebuf = NULL;
static size_t varnamebuflen = 0;
/*
@@ -3049,7 +3164,7 @@ char_u *get_user_var_name(expand_T *xp, int idx)
static size_t wdone;
static size_t tdone;
static size_t vidx;
- static hashitem_T *hi;
+ static hashitem_T *hi;
if (idx == 0) {
gdone = bdone = wdone = vidx = 0;
@@ -3058,14 +3173,17 @@ char_u *get_user_var_name(expand_T *xp, int idx)
// Global variables
if (gdone < globvarht.ht_used) {
- if (gdone++ == 0)
+ if (gdone++ == 0) {
hi = globvarht.ht_array;
- else
+ } else {
++hi;
- while (HASHITEM_EMPTY(hi))
+ }
+ while (HASHITEM_EMPTY(hi)) {
++hi;
- if (STRNCMP("g:", xp->xp_pattern, 2) == 0)
+ }
+ if (STRNCMP("g:", xp->xp_pattern, 2) == 0) {
return cat_prefix_varname('g', hi->hi_key);
+ }
return hi->hi_key;
}
@@ -3075,12 +3193,14 @@ char_u *get_user_var_name(expand_T *xp, int idx)
? &prevwin->w_buffer->b_vars->dv_hashtab
: &curbuf->b_vars->dv_hashtab;
if (bdone < ht->ht_used) {
- if (bdone++ == 0)
+ if (bdone++ == 0) {
hi = ht->ht_array;
- else
+ } else {
++hi;
- while (HASHITEM_EMPTY(hi))
+ }
+ while (HASHITEM_EMPTY(hi)) {
++hi;
+ }
return cat_prefix_varname('b', hi->hi_key);
}
@@ -3090,24 +3210,28 @@ char_u *get_user_var_name(expand_T *xp, int idx)
? &prevwin->w_vars->dv_hashtab
: &curwin->w_vars->dv_hashtab;
if (wdone < ht->ht_used) {
- if (wdone++ == 0)
+ if (wdone++ == 0) {
hi = ht->ht_array;
- else
+ } else {
++hi;
- while (HASHITEM_EMPTY(hi))
+ }
+ while (HASHITEM_EMPTY(hi)) {
++hi;
+ }
return cat_prefix_varname('w', hi->hi_key);
}
// t: variables
ht = &curtab->tp_vars->dv_hashtab;
if (tdone < ht->ht_used) {
- if (tdone++ == 0)
+ if (tdone++ == 0) {
hi = ht->ht_array;
- else
+ } else {
++hi;
- while (HASHITEM_EMPTY(hi))
+ }
+ while (HASHITEM_EMPTY(hi)) {
++hi;
+ }
return cat_prefix_varname('t', hi->hi_key);
}
@@ -3143,6 +3267,64 @@ static int pattern_match(char_u *pat, char_u *text, bool ic)
return matches;
}
+/// Handle a name followed by "(". Both for just "name(arg)" and for
+/// "expr->name(arg)".
+//
+/// @param arg Points to "(", will be advanced
+/// @param basetv "expr" for "expr->name(arg)"
+//
+/// @return OK or FAIL.
+static int eval_func(char_u **const arg, char_u *const name, const int name_len,
+ typval_T *const rettv, const bool evaluate, typval_T *const basetv)
+ FUNC_ATTR_NONNULL_ARG(1, 2, 4)
+{
+ char_u *s = name;
+ int len = name_len;
+
+ if (!evaluate) {
+ check_vars((const char *)s, len);
+ }
+
+ // If "s" is the name of a variable of type VAR_FUNC
+ // use its contents.
+ partial_T *partial;
+ s = deref_func_name((const char *)s, &len, &partial, !evaluate);
+
+ // Need to make a copy, in case evaluating the arguments makes
+ // the name invalid.
+ s = xmemdupz(s, len);
+
+ // Invoke the function.
+ funcexe_T funcexe = FUNCEXE_INIT;
+ funcexe.firstline = curwin->w_cursor.lnum;
+ funcexe.lastline = curwin->w_cursor.lnum;
+ funcexe.evaluate = evaluate;
+ funcexe.partial = partial;
+ funcexe.basetv = basetv;
+ int ret = get_func_tv(s, len, rettv, arg, &funcexe);
+
+ xfree(s);
+
+ // If evaluate is false rettv->v_type was not set in
+ // get_func_tv, but it's needed in handle_subscript() to parse
+ // what follows. So set it here.
+ if (rettv->v_type == VAR_UNKNOWN && !evaluate && **arg == '(') {
+ rettv->vval.v_string = (char_u *)tv_empty_string;
+ rettv->v_type = VAR_FUNC;
+ }
+
+ // Stop the expression evaluation when immediately
+ // aborting on error, or when an interrupt occurred or
+ // an exception was thrown but not caught.
+ if (evaluate && aborting()) {
+ if (ret == OK) {
+ tv_clear(rettv);
+ }
+ ret = FAIL;
+ }
+ return ret;
+}
+
// TODO(ZyX-I): move to eval/expressions
/*
@@ -3161,7 +3343,9 @@ static int pattern_match(char_u *pat, char_u *text, bool ic)
int eval0(char_u *arg, typval_T *rettv, char_u **nextcmd, int evaluate)
{
int ret;
- char_u *p;
+ char_u *p;
+ const int did_emsg_before = did_emsg;
+ const int called_emsg_before = called_emsg;
p = skipwhite(arg);
ret = eval1(&p, rettv, evaluate);
@@ -3171,14 +3355,17 @@ int eval0(char_u *arg, typval_T *rettv, char_u **nextcmd, int evaluate)
}
// Report the invalid expression unless the expression evaluation has
// been cancelled due to an aborting error, an interrupt, or an
- // exception.
- if (!aborting()) {
+ // exception, or we already gave a more specific error.
+ // Also check called_emsg for when using assert_fails().
+ if (!aborting() && did_emsg == did_emsg_before
+ && called_emsg == called_emsg_before) {
emsgf(_(e_invexpr2), arg);
}
ret = FAIL;
}
- if (nextcmd != NULL)
+ if (nextcmd != NULL) {
*nextcmd = check_nextcmd(p);
+ }
return ret;
}
@@ -3187,7 +3374,7 @@ int eval0(char_u *arg, typval_T *rettv, char_u **nextcmd, int evaluate)
/*
* Handle top level expression:
- * expr2 ? expr1 : expr1
+ * expr2 ? expr1 : expr1
*
* "arg" must point to the first non-white of the expression.
* "arg" is advanced to the next non-white after the recognized expression.
@@ -3204,8 +3391,9 @@ int eval1(char_u **arg, typval_T *rettv, int evaluate)
/*
* Get the first variable.
*/
- if (eval2(arg, rettv, evaluate) == FAIL)
+ if (eval2(arg, rettv, evaluate) == FAIL) {
return FAIL;
+ }
if ((*arg)[0] == '?') {
result = FALSE;
@@ -3250,8 +3438,9 @@ int eval1(char_u **arg, typval_T *rettv, int evaluate)
}
return FAIL;
}
- if (evaluate && !result)
+ if (evaluate && !result) {
*rettv = var2;
+ }
}
return OK;
@@ -3261,7 +3450,7 @@ int eval1(char_u **arg, typval_T *rettv, int evaluate)
/*
* Handle first level expression:
- * expr2 || expr2 || expr2 logical OR
+ * expr2 || expr2 || expr2 logical OR
*
* "arg" must point to the first non-white of the expression.
* "arg" is advanced to the next non-white after the recognized expression.
@@ -3278,8 +3467,9 @@ static int eval2(char_u **arg, typval_T *rettv, int evaluate)
/*
* Get the first variable.
*/
- if (eval3(arg, rettv, evaluate) == FAIL)
+ if (eval3(arg, rettv, evaluate) == FAIL) {
return FAIL;
+ }
/*
* Repeat until there is no following "||".
@@ -3302,8 +3492,9 @@ static int eval2(char_u **arg, typval_T *rettv, int evaluate)
* Get the second variable.
*/
*arg = skipwhite(*arg + 2);
- if (eval3(arg, &var2, evaluate && !result) == FAIL)
+ if (eval3(arg, &var2, evaluate && !result) == FAIL) {
return FAIL;
+ }
/*
* Compute the result.
@@ -3330,7 +3521,7 @@ static int eval2(char_u **arg, typval_T *rettv, int evaluate)
/*
* Handle second level expression:
- * expr3 && expr3 && expr3 logical AND
+ * expr3 && expr3 && expr3 logical AND
*
* "arg" must point to the first non-white of the expression.
* "arg" is advanced to the next non-white after the recognized expression.
@@ -3347,8 +3538,9 @@ static int eval3(char_u **arg, typval_T *rettv, int evaluate)
/*
* Get the first variable.
*/
- if (eval4(arg, rettv, evaluate) == FAIL)
+ if (eval4(arg, rettv, evaluate) == FAIL) {
return FAIL;
+ }
/*
* Repeat until there is no following "&&".
@@ -3371,8 +3563,9 @@ static int eval3(char_u **arg, typval_T *rettv, int evaluate)
* Get the second variable.
*/
*arg = skipwhite(*arg + 2);
- if (eval4(arg, &var2, evaluate && result) == FAIL)
+ if (eval4(arg, &var2, evaluate && result) == FAIL) {
return FAIL;
+ }
/*
* Compute the result.
@@ -3399,16 +3592,16 @@ static int eval3(char_u **arg, typval_T *rettv, int evaluate)
/*
* Handle third level expression:
- * var1 == var2
- * var1 =~ var2
- * var1 != var2
- * var1 !~ var2
- * var1 > var2
- * var1 >= var2
- * var1 < var2
- * var1 <= var2
- * var1 is var2
- * var1 isnot var2
+ * var1 == var2
+ * var1 =~ var2
+ * var1 != var2
+ * var1 !~ var2
+ * var1 > var2
+ * var1 >= var2
+ * var1 < var2
+ * var1 <= var2
+ * var1 is var2
+ * var1 isnot var2
*
* "arg" must point to the first non-white of the expression.
* "arg" is advanced to the next non-white after the recognized expression.
@@ -3418,7 +3611,7 @@ static int eval3(char_u **arg, typval_T *rettv, int evaluate)
static int eval4(char_u **arg, typval_T *rettv, int evaluate)
{
typval_T var2;
- char_u *p;
+ char_u *p;
exprtype_T type = EXPR_UNKNOWN;
int len = 2;
bool ic;
@@ -3426,8 +3619,9 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate)
/*
* Get the first variable.
*/
- if (eval5(arg, rettv, evaluate) == FAIL)
+ if (eval5(arg, rettv, evaluate) == FAIL) {
return FAIL;
+ }
p = *arg;
switch (p[0]) {
@@ -3461,14 +3655,15 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate)
type = EXPR_SEQUAL;
}
break;
- case 'i': if (p[1] == 's') {
+ case 'i':
+ if (p[1] == 's') {
if (p[2] == 'n' && p[3] == 'o' && p[4] == 't') {
len = 5;
}
if (!isalnum(p[len]) && p[len] != '_') {
type = len == 2 ? EXPR_IS : EXPR_ISNOT;
}
- }
+ }
break;
}
@@ -3508,10 +3703,10 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate)
/*
* Handle fourth level expression:
- * + number addition
- * - number subtraction
- * . string concatenation
- * .. string concatenation
+ * + number addition
+ * - number subtraction
+ * . string concatenation
+ * .. string concatenation
*
* "arg" must point to the first non-white of the expression.
* "arg" is advanced to the next non-white after the recognized expression.
@@ -3525,23 +3720,25 @@ static int eval5(char_u **arg, typval_T *rettv, int evaluate)
int op;
varnumber_T n1, n2;
float_T f1 = 0, f2 = 0;
- char_u *p;
+ char_u *p;
/*
* Get the first variable.
*/
- if (eval6(arg, rettv, evaluate, FALSE) == FAIL)
+ if (eval6(arg, rettv, evaluate, FALSE) == FAIL) {
return FAIL;
+ }
/*
* Repeat computing, until no '+', '-' or '.' is following.
*/
for (;; ) {
op = **arg;
- if (op != '+' && op != '-' && op != '.')
+ if (op != '+' && op != '-' && op != '.') {
break;
+ }
- if ((op != '+' || rettv->v_type != VAR_LIST)
+ if ((op != '+' || (rettv->v_type != VAR_LIST && rettv->v_type != VAR_BLOB))
&& (op == '.' || rettv->v_type != VAR_FLOAT)) {
// For "list + ...", an illegal use of the first operand as
// a number cannot be determined before evaluating the 2nd
@@ -3587,6 +3784,21 @@ static int eval5(char_u **arg, typval_T *rettv, int evaluate)
tv_clear(rettv);
rettv->v_type = VAR_STRING;
rettv->vval.v_string = p;
+ } else if (op == '+' && rettv->v_type == VAR_BLOB
+ && var2.v_type == VAR_BLOB) {
+ const blob_T *const b1 = rettv->vval.v_blob;
+ const blob_T *const b2 = var2.vval.v_blob;
+ blob_T *const b = tv_blob_alloc();
+
+ for (int i = 0; i < tv_blob_len(b1); i++) {
+ ga_append(&b->bv_ga, tv_blob_get(b1, i));
+ }
+ for (int i = 0; i < tv_blob_len(b2); i++) {
+ ga_append(&b->bv_ga, tv_blob_get(b2, i));
+ }
+
+ tv_clear(rettv);
+ tv_blob_set_ret(rettv, b);
} else if (op == '+' && rettv->v_type == VAR_LIST
&& var2.v_type == VAR_LIST) {
// Concatenate Lists.
@@ -3607,14 +3819,17 @@ static int eval5(char_u **arg, typval_T *rettv, int evaluate)
} else {
n1 = tv_get_number_chk(rettv, &error);
if (error) {
- /* This can only happen for "list + non-list". For
- * "non-list + ..." or "something - ...", we returned
- * before evaluating the 2nd operand. */
+ // This can only happen for "list + non-list" or
+ // "blob + non-blob". For "non-list + ..." or
+ // "something - ...", we returned before evaluating the
+ // 2nd operand.
tv_clear(rettv);
+ tv_clear(&var2);
return FAIL;
}
- if (var2.v_type == VAR_FLOAT)
+ if (var2.v_type == VAR_FLOAT) {
f1 = n1;
+ }
}
if (var2.v_type == VAR_FLOAT) {
f2 = var2.vval.v_float;
@@ -3626,24 +3841,27 @@ static int eval5(char_u **arg, typval_T *rettv, int evaluate)
tv_clear(&var2);
return FAIL;
}
- if (rettv->v_type == VAR_FLOAT)
+ if (rettv->v_type == VAR_FLOAT) {
f2 = n2;
+ }
}
tv_clear(rettv);
// If there is a float on either side the result is a float.
if (rettv->v_type == VAR_FLOAT || var2.v_type == VAR_FLOAT) {
- if (op == '+')
+ if (op == '+') {
f1 = f1 + f2;
- else
+ } else {
f1 = f1 - f2;
+ }
rettv->v_type = VAR_FLOAT;
rettv->vval.v_float = f1;
} else {
- if (op == '+')
+ if (op == '+') {
n1 = n1 + n2;
- else
+ } else {
n1 = n1 - n2;
+ }
rettv->v_type = VAR_NUMBER;
rettv->vval.v_number = n1;
}
@@ -3682,8 +3900,9 @@ static int eval6(char_u **arg, typval_T *rettv, int evaluate, int want_string)
/*
* Get the first variable.
*/
- if (eval7(arg, rettv, evaluate, want_string) == FAIL)
+ if (eval7(arg, rettv, evaluate, want_string) == FAIL) {
return FAIL;
+ }
/*
* Repeat computing, until no '*', '/' or '%' is following.
@@ -3714,8 +3933,9 @@ static int eval6(char_u **arg, typval_T *rettv, int evaluate, int want_string)
* Get the second variable.
*/
*arg = skipwhite(*arg + 1);
- if (eval7(arg, &var2, evaluate, FALSE) == FAIL)
+ if (eval7(arg, &var2, evaluate, FALSE) == FAIL) {
return FAIL;
+ }
if (evaluate) {
if (var2.v_type == VAR_FLOAT) {
@@ -3748,15 +3968,15 @@ static int eval6(char_u **arg, typval_T *rettv, int evaluate, int want_string)
f1 = (f2 == 0
? (
#ifdef NAN
- f1 == 0
+ f1 == 0
? NAN
:
#endif
- (f1 > 0
+ (f1 > 0
? INFINITY
: -INFINITY)
- )
- : f1 / f2);
+ )
+ : f1 / f2);
} else {
EMSG(_("E804: Cannot use '%' with Float"));
return FAIL;
@@ -3782,44 +4002,43 @@ static int eval6(char_u **arg, typval_T *rettv, int evaluate, int want_string)
// TODO(ZyX-I): move to eval/expressions
-// Handle sixth level expression:
-// number number constant
-// "string" string constant
-// 'string' literal string constant
-// &option-name option value
-// @r register contents
-// identifier variable value
-// function() function call
-// $VAR environment variable
-// (expression) nested expression
-// [expr, expr] List
-// {key: val, key: val} Dictionary
-// #{key: val, key: val} Dictionary with literal keys
-//
-// Also handle:
-// ! in front logical NOT
-// - in front unary minus
-// + in front unary plus (ignored)
-// trailing [] subscript in String or List
-// trailing .name entry in Dictionary
-//
-// "arg" must point to the first non-white of the expression.
-// "arg" is advanced to the next non-white after the recognized expression.
-//
-// Return OK or FAIL.
-static int eval7(
- char_u **arg,
- typval_T *rettv,
- int evaluate,
- int want_string // after "." operator
-)
+/// Handle sixth level expression:
+/// number number constant
+/// 0zFFFFFFFF Blob constant
+/// "string" string constant
+/// 'string' literal string constant
+/// &option-name option value
+/// @r register contents
+/// identifier variable value
+/// function() function call
+/// $VAR environment variable
+/// (expression) nested expression
+/// [expr, expr] List
+/// {key: val, key: val} Dictionary
+/// #{key: val, key: val} Dictionary with literal keys
+///
+/// Also handle:
+/// ! in front logical NOT
+/// - in front unary minus
+/// + in front unary plus (ignored)
+/// trailing [] subscript in String or List
+/// trailing .name entry in Dictionary
+/// trailing ->name() method call
+///
+/// "arg" must point to the first non-white of the expression.
+/// "arg" is advanced to the next non-white after the recognized expression.
+///
+/// @param want_string after "." operator
+///
+/// @return OK or FAIL.
+static int eval7(char_u **arg, typval_T *rettv, int evaluate, int want_string)
{
varnumber_T n;
int len;
- char_u *s;
- char_u *start_leader, *end_leader;
+ char_u *s;
+ const char_u *start_leader, *end_leader;
int ret = OK;
- char_u *alias;
+ char_u *alias;
// Initialise variable so that tv_clear() can't mistake this for a
// string and free a string that isn't there.
@@ -3843,8 +4062,7 @@ static int eval7(
case '6':
case '7':
case '8':
- case '9':
- {
+ case '9': {
char_u *p = skipdigits(*arg + 1);
int get_float = false;
@@ -3874,13 +4092,48 @@ static int eval7(
if (get_float) {
float_T f;
- *arg += string2float((char *) *arg, &f);
+ *arg += string2float((char *)*arg, &f);
if (evaluate) {
rettv->v_type = VAR_FLOAT;
rettv->vval.v_float = f;
}
+ } else if (**arg == '0' && ((*arg)[1] == 'z' || (*arg)[1] == 'Z')) {
+ blob_T *blob = NULL;
+ // Blob constant: 0z0123456789abcdef
+ if (evaluate) {
+ blob = tv_blob_alloc();
+ }
+ char_u *bp;
+ for (bp = *arg + 2; ascii_isxdigit(bp[0]); bp += 2) {
+ if (!ascii_isxdigit(bp[1])) {
+ if (blob != NULL) {
+ EMSG(_("E973: Blob literal should have an even number of hex "
+ "characters"));
+ ga_clear(&blob->bv_ga);
+ XFREE_CLEAR(blob);
+ }
+ ret = FAIL;
+ break;
+ }
+ if (blob != NULL) {
+ ga_append(&blob->bv_ga, (hex2nr(*bp) << 4) + hex2nr(*(bp + 1)));
+ }
+ if (bp[2] == '.' && ascii_isxdigit(bp[3])) {
+ bp++;
+ }
+ }
+ if (blob != NULL) {
+ tv_blob_set_ret(rettv, blob);
+ }
+ *arg = bp;
} else {
- vim_str2nr(*arg, NULL, &len, STR2NR_ALL, &n, NULL, 0);
+ // decimal, hex or octal number
+ vim_str2nr(*arg, NULL, &len, STR2NR_ALL, &n, NULL, 0, true);
+ if (len == 0) {
+ EMSG2(_(e_invexpr2), *arg);
+ ret = FAIL;
+ break;
+ }
*arg += len;
if (evaluate) {
rettv->v_type = VAR_NUMBER;
@@ -3891,15 +4144,18 @@ static int eval7(
}
// String constant: "string".
- case '"': ret = get_string_tv(arg, rettv, evaluate);
+ case '"':
+ ret = get_string_tv(arg, rettv, evaluate);
break;
// Literal string constant: 'str''ing'.
- case '\'': ret = get_lit_string_tv(arg, rettv, evaluate);
+ case '\'':
+ ret = get_lit_string_tv(arg, rettv, evaluate);
break;
// List: [expr, expr]
- case '[': ret = get_list_tv(arg, rettv, evaluate);
+ case '[':
+ ret = get_list_tv(arg, rettv, evaluate);
break;
// Dictionary: #{key: val, key: val}
@@ -3914,23 +4170,25 @@ static int eval7(
// Lambda: {arg, arg -> expr}
// Dictionary: {'key': val, 'key': val}
- case '{': ret = get_lambda_tv(arg, rettv, evaluate);
- if (ret == NOTDONE) {
- ret = dict_get_tv(arg, rettv, evaluate, false);
- }
+ case '{':
+ ret = get_lambda_tv(arg, rettv, evaluate);
+ if (ret == NOTDONE) {
+ ret = dict_get_tv(arg, rettv, evaluate, false);
+ }
break;
// Option value: &name
- case '&': {
+ case '&':
ret = get_option_tv((const char **)arg, rettv, evaluate);
break;
- }
// Environment variable: $VAR.
- case '$': ret = get_env_tv(arg, rettv, evaluate);
+ case '$':
+ ret = get_env_tv(arg, rettv, evaluate);
break;
// Register contents: @r.
- case '@': ++*arg;
+ case '@':
+ ++*arg;
if (evaluate) {
rettv->v_type = VAR_STRING;
rettv->vval.v_string = get_reg_contents(**arg, kGRegExprSrc);
@@ -3941,7 +4199,8 @@ static int eval7(
break;
// nested expression: (expression).
- case '(': *arg = skipwhite(*arg + 1);
+ case '(':
+ *arg = skipwhite(*arg + 1);
ret = eval1(arg, rettv, evaluate); // recursive!
if (**arg == ')') {
++*arg;
@@ -3952,7 +4211,8 @@ static int eval7(
}
break;
- default: ret = NOTDONE;
+ default:
+ ret = NOTDONE;
break;
}
@@ -3969,44 +4229,7 @@ static int eval7(
ret = FAIL;
} else {
if (**arg == '(') { // recursive!
- partial_T *partial;
-
- if (!evaluate) {
- check_vars((const char *)s, len);
- }
-
- // If "s" is the name of a variable of type VAR_FUNC
- // use its contents.
- s = deref_func_name((const char *)s, &len, &partial, !evaluate);
-
- // Need to make a copy, in case evaluating the arguments makes
- // the name invalid.
- s = xmemdupz(s, len);
-
- // Invoke the function.
- ret = get_func_tv(s, len, rettv, arg,
- curwin->w_cursor.lnum, curwin->w_cursor.lnum,
- &len, evaluate, partial, NULL);
-
- xfree(s);
-
- // If evaluate is false rettv->v_type was not set in
- // get_func_tv, but it's needed in handle_subscript() to parse
- // what follows. So set it here.
- if (rettv->v_type == VAR_UNKNOWN && !evaluate && **arg == '(') {
- rettv->vval.v_string = (char_u *)tv_empty_string;
- rettv->v_type = VAR_FUNC;
- }
-
- // Stop the expression evaluation when immediately
- // aborting on error, or when an interrupt occurred or
- // an exception was thrown but not caught.
- if (evaluate && aborting()) {
- if (ret == OK) {
- tv_clear(rettv);
- }
- ret = FAIL;
- }
+ ret = eval_func(arg, s, len, rettv, evaluate, NULL);
} else if (evaluate) {
ret = get_var_tv((const char *)s, len, rettv, NULL, true, false);
} else {
@@ -4020,111 +4243,277 @@ static int eval7(
*arg = skipwhite(*arg);
// Handle following '[', '(' and '.' for expr[expr], expr.name,
- // expr(expr).
+ // expr(expr), expr->name(expr)
if (ret == OK) {
- ret = handle_subscript((const char **)arg, rettv, evaluate, true);
+ ret = handle_subscript((const char **)arg, rettv, evaluate, true,
+ start_leader, &end_leader);
}
// Apply logical NOT and unary '-', from right to left, ignore '+'.
if (ret == OK && evaluate && end_leader > start_leader) {
- bool error = false;
- varnumber_T val = 0;
- float_T f = 0.0;
+ ret = eval7_leader(rettv, start_leader, &end_leader);
+ }
+ return ret;
+}
+/// Apply the leading "!" and "-" before an eval7 expression to "rettv".
+/// Adjusts "end_leaderp" until it is at "start_leader".
+/// @return OK on success, FAIL on failure.
+static int eval7_leader(typval_T *const rettv, const char_u *const start_leader,
+ const char_u **const end_leaderp)
+ FUNC_ATTR_NONNULL_ALL
+{
+ const char_u *end_leader = *end_leaderp;
+ int ret = OK;
+ bool error = false;
+ varnumber_T val = 0;
+ float_T f = 0.0;
+
+ if (rettv->v_type == VAR_FLOAT) {
+ f = rettv->vval.v_float;
+ } else {
+ val = tv_get_number_chk(rettv, &error);
+ }
+ if (error) {
+ tv_clear(rettv);
+ ret = FAIL;
+ } else {
+ while (end_leader > start_leader) {
+ end_leader--;
+ if (*end_leader == '!') {
+ if (rettv->v_type == VAR_FLOAT) {
+ f = !f;
+ } else {
+ val = !val;
+ }
+ } else if (*end_leader == '-') {
+ if (rettv->v_type == VAR_FLOAT) {
+ f = -f;
+ } else {
+ val = -val;
+ }
+ }
+ }
if (rettv->v_type == VAR_FLOAT) {
- f = rettv->vval.v_float;
+ tv_clear(rettv);
+ rettv->vval.v_float = f;
} else {
- val = tv_get_number_chk(rettv, &error);
- }
- if (error) {
tv_clear(rettv);
- ret = FAIL;
+ rettv->v_type = VAR_NUMBER;
+ rettv->vval.v_number = val;
+ }
+ }
+
+ *end_leaderp = end_leader;
+ return ret;
+}
+
+/// Call the function referred to in "rettv".
+/// @param lua_funcname If `rettv` refers to a v:lua function, this must point
+/// to the name of the Lua function to call (after the
+/// "v:lua." prefix).
+/// @return OK on success, FAIL on failure.
+static int call_func_rettv(char_u **const arg, typval_T *const rettv, const bool evaluate,
+ dict_T *const selfdict, typval_T *const basetv,
+ const char_u *const lua_funcname)
+ FUNC_ATTR_NONNULL_ARG(1, 2)
+{
+ partial_T *pt = NULL;
+ typval_T functv;
+ const char_u *funcname;
+ bool is_lua = false;
+
+ // need to copy the funcref so that we can clear rettv
+ if (evaluate) {
+ functv = *rettv;
+ rettv->v_type = VAR_UNKNOWN;
+
+ // Invoke the function. Recursive!
+ if (functv.v_type == VAR_PARTIAL) {
+ pt = functv.vval.v_partial;
+ is_lua = is_luafunc(pt);
+ funcname = is_lua ? lua_funcname : partial_name(pt);
} else {
- while (end_leader > start_leader) {
- --end_leader;
- if (*end_leader == '!') {
- if (rettv->v_type == VAR_FLOAT) {
- f = !f;
- } else {
- val = !val;
- }
- } else if (*end_leader == '-') {
- if (rettv->v_type == VAR_FLOAT) {
- f = -f;
- } else {
- val = -val;
- }
- }
+ funcname = functv.vval.v_string;
+ }
+ } else {
+ funcname = (char_u *)"";
+ }
+
+ funcexe_T funcexe = FUNCEXE_INIT;
+ funcexe.firstline = curwin->w_cursor.lnum;
+ funcexe.lastline = curwin->w_cursor.lnum;
+ funcexe.evaluate = evaluate;
+ funcexe.partial = pt;
+ funcexe.selfdict = selfdict;
+ funcexe.basetv = basetv;
+ const int ret = get_func_tv(funcname, is_lua ? *arg - funcname : -1, rettv,
+ (char_u **)arg, &funcexe);
+
+ // Clear the funcref afterwards, so that deleting it while
+ // evaluating the arguments is possible (see test55).
+ if (evaluate) {
+ tv_clear(&functv);
+ }
+
+ return ret;
+}
+
+/// Evaluate "->method()".
+/// @param verbose if true, give error messages.
+/// @note "*arg" points to the '-'.
+/// @return FAIL or OK. @note "*arg" is advanced to after the ')'.
+static int eval_lambda(char_u **const arg, typval_T *const rettv, const bool evaluate,
+ const bool verbose)
+ FUNC_ATTR_NONNULL_ALL
+{
+ // Skip over the ->.
+ *arg += 2;
+ typval_T base = *rettv;
+ rettv->v_type = VAR_UNKNOWN;
+
+ int ret = get_lambda_tv(arg, rettv, evaluate);
+ if (ret == NOTDONE) {
+ return FAIL;
+ } else if (**arg != '(') {
+ if (verbose) {
+ if (*skipwhite(*arg) == '(') {
+ EMSG(_(e_nowhitespace));
+ } else {
+ EMSG2(_(e_missingparen), "lambda");
}
- if (rettv->v_type == VAR_FLOAT) {
- tv_clear(rettv);
- rettv->vval.v_float = f;
+ }
+ tv_clear(rettv);
+ ret = FAIL;
+ } else {
+ ret = call_func_rettv(arg, rettv, evaluate, NULL, &base, NULL);
+ }
+
+ // Clear the funcref afterwards, so that deleting it while
+ // evaluating the arguments is possible (see test55).
+ if (evaluate) {
+ tv_clear(&base);
+ }
+
+ return ret;
+}
+
+/// Evaluate "->method()" or "->v:lua.method()".
+/// @note "*arg" points to the '-'.
+/// @return FAIL or OK. "*arg" is advanced to after the ')'.
+static int eval_method(char_u **const arg, typval_T *const rettv, const bool evaluate,
+ const bool verbose)
+ FUNC_ATTR_NONNULL_ALL
+{
+ // Skip over the ->.
+ *arg += 2;
+ typval_T base = *rettv;
+ rettv->v_type = VAR_UNKNOWN;
+
+ // Locate the method name.
+ int len;
+ char_u *name = *arg;
+ char_u *lua_funcname = NULL;
+ if (STRNCMP(name, "v:lua.", 6) == 0) {
+ lua_funcname = name + 6;
+ *arg = (char_u *)skip_luafunc_name((const char *)lua_funcname);
+ *arg = skipwhite(*arg); // to detect trailing whitespace later
+ len = *arg - lua_funcname;
+ } else {
+ char_u *alias;
+ len = get_name_len((const char **)arg, (char **)&alias, evaluate, true);
+ if (alias != NULL) {
+ name = alias;
+ }
+ }
+
+ int ret;
+ if (len <= 0) {
+ if (verbose) {
+ if (lua_funcname == NULL) {
+ EMSG(_("E260: Missing name after ->"));
} else {
- tv_clear(rettv);
- rettv->v_type = VAR_NUMBER;
- rettv->vval.v_number = val;
+ EMSG2(_(e_invexpr2), name);
+ }
+ }
+ ret = FAIL;
+ } else {
+ if (**arg != '(') {
+ if (verbose) {
+ EMSG2(_(e_missingparen), name);
}
+ ret = FAIL;
+ } else if (ascii_iswhite((*arg)[-1])) {
+ if (verbose) {
+ EMSG(_(e_nowhitespace));
+ }
+ ret = FAIL;
+ } else if (lua_funcname != NULL) {
+ if (evaluate) {
+ rettv->v_type = VAR_PARTIAL;
+ rettv->vval.v_partial = vvlua_partial;
+ rettv->vval.v_partial->pt_refcount++;
+ }
+ ret = call_func_rettv(arg, rettv, evaluate, NULL, &base, lua_funcname);
+ } else {
+ ret = eval_func(arg, name, len, rettv, evaluate, &base);
}
}
+ // Clear the funcref afterwards, so that deleting it while
+ // evaluating the arguments is possible (see test55).
+ if (evaluate) {
+ tv_clear(&base);
+ }
+
return ret;
}
// TODO(ZyX-I): move to eval/expressions
-/*
- * Evaluate an "[expr]" or "[expr:expr]" index. Also "dict.key".
- * "*arg" points to the '[' or '.'.
- * Returns FAIL or OK. "*arg" is advanced to after the ']'.
- */
-static int
-eval_index(
- char_u **arg,
- typval_T *rettv,
- int evaluate,
- int verbose // give error messages
-)
+/// Evaluate an "[expr]" or "[expr:expr]" index. Also "dict.key".
+/// "*arg" points to the '[' or '.'.
+/// Returns FAIL or OK. "*arg" is advanced to after the ']'.
+///
+/// @param verbose give error messages
+static int eval_index(char_u **arg, typval_T *rettv, int evaluate, int verbose)
{
bool empty1 = false;
bool empty2 = false;
long n1, n2 = 0;
ptrdiff_t len = -1;
int range = false;
- char_u *key = NULL;
+ char_u *key = NULL;
switch (rettv->v_type) {
- case VAR_FUNC:
- case VAR_PARTIAL: {
- if (verbose) {
- EMSG(_("E695: Cannot index a Funcref"));
- }
- return FAIL;
- }
- case VAR_FLOAT: {
- if (verbose) {
- EMSG(_(e_float_as_string));
- }
- return FAIL;
+ case VAR_FUNC:
+ case VAR_PARTIAL:
+ if (verbose) {
+ EMSG(_("E695: Cannot index a Funcref"));
}
- case VAR_BOOL:
- case VAR_SPECIAL: {
- if (verbose) {
- EMSG(_("E909: Cannot index a special variable"));
- }
- return FAIL;
+ return FAIL;
+ case VAR_FLOAT:
+ if (verbose) {
+ EMSG(_(e_float_as_string));
}
- case VAR_UNKNOWN: {
- if (evaluate) {
- return FAIL;
- }
- FALLTHROUGH;
+ return FAIL;
+ case VAR_BOOL:
+ case VAR_SPECIAL:
+ if (verbose) {
+ EMSG(_("E909: Cannot index a special variable"));
}
- case VAR_STRING:
- case VAR_NUMBER:
- case VAR_LIST:
- case VAR_DICT: {
- break;
+ return FAIL;
+ case VAR_UNKNOWN:
+ if (evaluate) {
+ return FAIL;
}
+ FALLTHROUGH;
+ case VAR_STRING:
+ case VAR_NUMBER:
+ case VAR_LIST:
+ case VAR_DICT:
+ case VAR_BLOB:
+ break;
}
typval_T var1 = TV_INITIAL_VALUE;
@@ -4134,10 +4523,12 @@ eval_index(
* dict.name
*/
key = *arg + 1;
- for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len)
+ for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) {
;
- if (len == 0)
+ }
+ if (len == 0) {
return FAIL;
+ }
*arg = skipwhite(key + len);
} else {
/*
@@ -4209,133 +4600,177 @@ eval_index(
}
switch (rettv->v_type) {
- case VAR_NUMBER:
- case VAR_STRING: {
- const char *const s = tv_get_string(rettv);
- char *v;
- len = (ptrdiff_t)strlen(s);
- if (range) {
- // The resulting variable is a substring. If the indexes
- // are out of range the result is empty.
+ case VAR_NUMBER:
+ case VAR_STRING: {
+ const char *const s = tv_get_string(rettv);
+ char *v;
+ len = (ptrdiff_t)strlen(s);
+ if (range) {
+ // The resulting variable is a substring. If the indexes
+ // are out of range the result is empty.
+ if (n1 < 0) {
+ n1 = len + n1;
if (n1 < 0) {
- n1 = len + n1;
- if (n1 < 0) {
- n1 = 0;
- }
- }
- if (n2 < 0) {
- n2 = len + n2;
- } else if (n2 >= len) {
- n2 = len;
- }
- if (n1 >= len || n2 < 0 || n1 > n2) {
- v = NULL;
- } else {
- v = xmemdupz(s + n1, (size_t)(n2 - n1 + 1));
+ n1 = 0;
}
+ }
+ if (n2 < 0) {
+ n2 = len + n2;
+ } else if (n2 >= len) {
+ n2 = len;
+ }
+ if (n1 >= len || n2 < 0 || n1 > n2) {
+ v = NULL;
} else {
- // The resulting variable is a string of a single
- // character. If the index is too big or negative the
- // result is empty.
- if (n1 >= len || n1 < 0) {
- v = NULL;
- } else {
- v = xmemdupz(s + n1, 1);
- }
+ v = xmemdupz(s + n1, (size_t)(n2 - n1 + 1));
+ }
+ } else {
+ // The resulting variable is a string of a single
+ // character. If the index is too big or negative the
+ // result is empty.
+ if (n1 >= len || n1 < 0) {
+ v = NULL;
+ } else {
+ v = xmemdupz(s + n1, 1);
}
- tv_clear(rettv);
- rettv->v_type = VAR_STRING;
- rettv->vval.v_string = (char_u *)v;
- break;
}
- case VAR_LIST: {
- len = tv_list_len(rettv->vval.v_list);
+ tv_clear(rettv);
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = (char_u *)v;
+ break;
+ }
+ case VAR_BLOB:
+ len = tv_blob_len(rettv->vval.v_blob);
+ if (range) {
+ // The resulting variable is a sub-blob. If the indexes
+ // are out of range the result is empty.
if (n1 < 0) {
n1 = len + n1;
- }
- if (!empty1 && (n1 < 0 || n1 >= len)) {
- // For a range we allow invalid values and return an empty
- // list. A list index out of range is an error.
- if (!range) {
- if (verbose) {
- EMSGN(_(e_listidx), n1);
- }
- return FAIL;
+ if (n1 < 0) {
+ n1 = 0;
}
- n1 = len;
}
- if (range) {
- list_T *l;
- listitem_T *item;
-
- if (n2 < 0) {
- n2 = len + n2;
- } else if (n2 >= len) {
- n2 = len - 1;
- }
- if (!empty2 && (n2 < 0 || n2 + 1 < n1)) {
- n2 = -1;
- }
- l = tv_list_alloc(n2 - n1 + 1);
- item = tv_list_find(rettv->vval.v_list, n1);
- while (n1++ <= n2) {
- tv_list_append_tv(l, TV_LIST_ITEM_TV(item));
- item = TV_LIST_ITEM_NEXT(rettv->vval.v_list, item);
- }
+ if (n2 < 0) {
+ n2 = len + n2;
+ } else if (n2 >= len) {
+ n2 = len - 1;
+ }
+ if (n1 >= len || n2 < 0 || n1 > n2) {
tv_clear(rettv);
- tv_list_set_ret(rettv, l);
+ rettv->v_type = VAR_BLOB;
+ rettv->vval.v_blob = NULL;
} else {
- tv_copy(TV_LIST_ITEM_TV(tv_list_find(rettv->vval.v_list, n1)), &var1);
+ blob_T *const blob = tv_blob_alloc();
+ ga_grow(&blob->bv_ga, n2 - n1 + 1);
+ blob->bv_ga.ga_len = n2 - n1 + 1;
+ for (long i = n1; i <= n2; i++) {
+ tv_blob_set(blob, i - n1, tv_blob_get(rettv->vval.v_blob, i));
+ }
tv_clear(rettv);
- *rettv = var1;
+ tv_blob_set_ret(rettv, blob);
+ }
+ } else {
+ // The resulting variable is a byte value.
+ // If the index is too big or negative that is an error.
+ if (n1 < 0) {
+ n1 = len + n1;
+ }
+ if (n1 < len && n1 >= 0) {
+ const int v = (int)tv_blob_get(rettv->vval.v_blob, n1);
+ tv_clear(rettv);
+ rettv->v_type = VAR_NUMBER;
+ rettv->vval.v_number = v;
+ } else {
+ EMSGN(_(e_blobidx), n1);
}
- break;
}
- case VAR_DICT: {
- if (range) {
+ break;
+ case VAR_LIST:
+ len = tv_list_len(rettv->vval.v_list);
+ if (n1 < 0) {
+ n1 = len + n1;
+ }
+ if (!empty1 && (n1 < 0 || n1 >= len)) {
+ // For a range we allow invalid values and return an empty
+ // list. A list index out of range is an error.
+ if (!range) {
if (verbose) {
- EMSG(_(e_dictrange));
- }
- if (len == -1) {
- tv_clear(&var1);
+ EMSGN(_(e_listidx), n1);
}
return FAIL;
}
+ n1 = len;
+ }
+ if (range) {
+ list_T *l;
+ listitem_T *item;
- if (len == -1) {
- key = (char_u *)tv_get_string_chk(&var1);
- if (key == NULL) {
- tv_clear(&var1);
- return FAIL;
- }
+ if (n2 < 0) {
+ n2 = len + n2;
+ } else if (n2 >= len) {
+ n2 = len - 1;
}
-
- dictitem_T *const item = tv_dict_find(rettv->vval.v_dict,
- (const char *)key, len);
-
- if (item == NULL && verbose) {
- emsgf(_(e_dictkey), key);
+ if (!empty2 && (n2 < 0 || n2 + 1 < n1)) {
+ n2 = -1;
+ }
+ l = tv_list_alloc(n2 - n1 + 1);
+ item = tv_list_find(rettv->vval.v_list, n1);
+ while (n1++ <= n2) {
+ tv_list_append_tv(l, TV_LIST_ITEM_TV(item));
+ item = TV_LIST_ITEM_NEXT(rettv->vval.v_list, item);
+ }
+ tv_clear(rettv);
+ tv_list_set_ret(rettv, l);
+ } else {
+ tv_copy(TV_LIST_ITEM_TV(tv_list_find(rettv->vval.v_list, n1)), &var1);
+ tv_clear(rettv);
+ *rettv = var1;
+ }
+ break;
+ case VAR_DICT: {
+ if (range) {
+ if (verbose) {
+ EMSG(_(e_dictrange));
}
if (len == -1) {
tv_clear(&var1);
}
- if (item == NULL || tv_is_luafunc(&item->di_tv)) {
+ return FAIL;
+ }
+
+ if (len == -1) {
+ key = (char_u *)tv_get_string_chk(&var1);
+ if (key == NULL) {
+ tv_clear(&var1);
return FAIL;
}
+ }
- tv_copy(&item->di_tv, &var1);
- tv_clear(rettv);
- *rettv = var1;
- break;
+ dictitem_T *const item = tv_dict_find(rettv->vval.v_dict,
+ (const char *)key, len);
+
+ if (item == NULL && verbose) {
+ emsgf(_(e_dictkey), key);
}
- case VAR_BOOL:
- case VAR_SPECIAL:
- case VAR_FUNC:
- case VAR_FLOAT:
- case VAR_PARTIAL:
- case VAR_UNKNOWN: {
- break; // Not evaluating, skipping over subscript
+ if (len == -1) {
+ tv_clear(&var1);
}
+ if (item == NULL || tv_is_luafunc(&item->di_tv)) {
+ return FAIL;
+ }
+
+ tv_copy(&item->di_tv, &var1);
+ tv_clear(rettv);
+ *rettv = var1;
+ break;
+ }
+ case VAR_BOOL:
+ case VAR_SPECIAL:
+ case VAR_FUNC:
+ case VAR_FLOAT:
+ case VAR_PARTIAL:
+ case VAR_UNKNOWN:
+ break; // Not evaluating, skipping over subscript
}
}
@@ -4352,12 +4787,11 @@ eval_index(
/// @param[in] evaluate If not true, rettv is not populated.
///
/// @return OK or FAIL.
-int get_option_tv(const char **const arg, typval_T *const rettv,
- const bool evaluate)
+int get_option_tv(const char **const arg, typval_T *const rettv, const bool evaluate)
FUNC_ATTR_NONNULL_ARG(1)
{
long numval;
- char_u *stringval;
+ char_u *stringval;
int opt_type;
int c;
bool working = (**arg == '+'); // has("+option")
@@ -4388,7 +4822,7 @@ int get_option_tv(const char **const arg, typval_T *const rettv,
EMSG2(_("E113: Unknown option: %s"), *arg);
}
ret = FAIL;
- } else if (rettv != NULL) {
+ } else if (rettv != NULL) {
if (opt_type == -2) { // hidden string option
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
@@ -4402,8 +4836,9 @@ int get_option_tv(const char **const arg, typval_T *const rettv,
rettv->v_type = VAR_STRING;
rettv->vval.v_string = stringval;
}
- } else if (working && (opt_type == -2 || opt_type == -1))
+ } else if (working && (opt_type == -2 || opt_type == -1)) {
ret = FAIL;
+ }
*option_end = c; // put back for error messages
*arg = option_end;
@@ -4417,7 +4852,7 @@ int get_option_tv(const char **const arg, typval_T *const rettv,
*/
static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate)
{
- char_u *p;
+ char_u *p;
unsigned int extra = 0;
/*
@@ -4459,12 +4894,18 @@ static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate)
for (p = *arg + 1; *p != NUL && *p != '"'; ) {
if (*p == '\\') {
switch (*++p) {
- case 'b': *name++ = BS; ++p; break;
- case 'e': *name++ = ESC; ++p; break;
- case 'f': *name++ = FF; ++p; break;
- case 'n': *name++ = NL; ++p; break;
- case 'r': *name++ = CAR; ++p; break;
- case 't': *name++ = TAB; ++p; break;
+ case 'b':
+ *name++ = BS; ++p; break;
+ case 'e':
+ *name++ = ESC; ++p; break;
+ case 'f':
+ *name++ = FF; ++p; break;
+ case 'n':
+ *name++ = NL; ++p; break;
+ case 'r':
+ *name++ = CAR; ++p; break;
+ case 't':
+ *name++ = TAB; ++p; break;
case 'X': // hex: "\x1", "\x12"
case 'x':
@@ -4505,11 +4946,13 @@ static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate)
case '4':
case '5':
case '6':
- case '7': *name = *p++ - '0';
+ case '7':
+ *name = *p++ - '0';
if (*p >= '0' && *p <= '7') {
*name = (*name << 3) + *p++ - '0';
- if (*p >= '0' && *p <= '7')
+ if (*p >= '0' && *p <= '7') {
*name = (*name << 3) + *p++ - '0';
+ }
}
++name;
break;
@@ -4526,12 +4969,13 @@ static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate)
}
FALLTHROUGH;
- default: MB_COPY_CHAR(p, name);
+ default:
+ MB_COPY_CHAR(p, name);
break;
}
- } else
+ } else {
MB_COPY_CHAR(p, name);
-
+ }
}
*name = NUL;
if (*p != NUL) { // just in case
@@ -4548,8 +4992,8 @@ static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate)
*/
static int get_lit_string_tv(char_u **arg, typval_T *rettv, int evaluate)
{
- char_u *p;
- char_u *str;
+ char_u *p;
+ char_u *str;
int reduce = 0;
/*
@@ -4557,8 +5001,9 @@ static int get_lit_string_tv(char_u **arg, typval_T *rettv, int evaluate)
*/
for (p = *arg + 1; *p != NUL; MB_PTR_ADV(p)) {
if (*p == '\'') {
- if (p[1] != '\'')
+ if (p[1] != '\'') {
break;
+ }
++reduce;
++p;
}
@@ -4584,8 +5029,9 @@ static int get_lit_string_tv(char_u **arg, typval_T *rettv, int evaluate)
for (p = *arg + 1; *p != NUL; ) {
if (*p == '\'') {
- if (p[1] != '\'')
+ if (p[1] != '\'') {
break;
+ }
++p;
}
MB_COPY_CHAR(p, str);
@@ -4638,7 +5084,7 @@ void partial_unref(partial_T *pt)
/// Return OK or FAIL.
static int get_list_tv(char_u **arg, typval_T *rettv, int evaluate)
{
- list_T *l = NULL;
+ list_T *l = NULL;
if (evaluate) {
l = tv_list_alloc(kListLenShouldKnow);
@@ -4682,23 +5128,20 @@ failret:
return OK;
}
-bool func_equal(
- typval_T *tv1,
- typval_T *tv2,
- bool ic // ignore case
-) {
+/// @param ic ignore case
+bool func_equal(typval_T *tv1, typval_T *tv2, bool ic) {
char_u *s1, *s2;
dict_T *d1, *d2;
int a1, a2;
// empty and NULL function name considered the same
s1 = tv1->v_type == VAR_FUNC ? tv1->vval.v_string
- : partial_name(tv1->vval.v_partial);
+ : partial_name(tv1->vval.v_partial);
if (s1 != NULL && *s1 == NUL) {
s1 = NULL;
}
s2 = tv2->v_type == VAR_FUNC ? tv2->vval.v_string
- : partial_name(tv2->vval.v_partial);
+ : partial_name(tv2->vval.v_partial);
if (s2 != NULL && *s2 == NUL) {
s2 = NULL;
}
@@ -4759,9 +5202,9 @@ int get_copyID(void)
* are no longer used. But for composite items it's possible that it becomes
* unused while the reference count is > 0: When there is a recursive
* reference. Example:
- * :let l = [1, 2, 3]
- * :let d = {9: l}
- * :let l[1] = d
+ * :let l = [1, 2, 3]
+ * :let d = {9: l}
+ * :let l[1] = d
*
* Since this is quite unusual we handle this with garbage collection: every
* once in a while find out which lists and dicts are not referenced from any
@@ -4769,7 +5212,7 @@ int get_copyID(void)
*
* Here is a good reference text about garbage collection (refers to Python
* but it applies to all reference-counting mechanisms):
- * http://python.ca/nas/python/gc/
+ * http://python.ca/nas/python/gc/
*/
/// Do garbage collection for lists and dicts.
@@ -4883,7 +5326,7 @@ bool garbage_collect(bool testing)
// Channels
{
Channel *data;
- map_foreach_value(channels, data, {
+ map_foreach_value(&channels, data, {
set_ref_in_callback_reader(&data->on_data, copyID, NULL, NULL);
set_ref_in_callback_reader(&data->on_stderr, copyID, NULL, NULL);
set_ref_in_callback(&data->on_exit, copyID, NULL, NULL);
@@ -4893,7 +5336,7 @@ bool garbage_collect(bool testing)
// Timers
{
timer_T *timer;
- map_foreach_value(timers, timer, {
+ map_foreach_value(&timers, timer, {
set_ref_in_callback(&timer->callback, copyID, NULL, NULL);
})
}
@@ -4945,8 +5388,7 @@ bool garbage_collect(bool testing)
// This may call us back recursively.
did_free = free_unref_funccal(copyID, testing) || did_free;
} else if (p_verbose > 0) {
- verb_msg(_(
- "Not enough memory to set references, garbage collection aborted!"));
+ verb_msg(_("Not enough memory to set references, garbage collection aborted!"));
}
#undef ABORTING
return did_free;
@@ -5040,8 +5482,7 @@ bool set_ref_in_ht(hashtab_T *ht, int copyID, list_stack_T **list_stack)
// it is added to ht_stack, if it contains a list it is added to
// list_stack.
HASHTAB_ITER(cur_ht, hi, {
- abort = abort || set_ref_in_item(
- &TV_DICT_HI2DI(hi)->di_tv, copyID, &ht_stack, list_stack);
+ abort = abort || set_ref_in_item(&TV_DICT_HI2DI(hi)->di_tv, copyID, &ht_stack, list_stack);
});
}
@@ -5107,86 +5548,85 @@ bool set_ref_in_list(list_T *l, int copyID, ht_stack_T **ht_stack)
/// @param list_stack Used to add lists to be marked. Can be NULL.
///
/// @returns true if setting references failed somehow.
-bool set_ref_in_item(typval_T *tv, int copyID, ht_stack_T **ht_stack,
- list_stack_T **list_stack)
+bool set_ref_in_item(typval_T *tv, int copyID, ht_stack_T **ht_stack, list_stack_T **list_stack)
FUNC_ATTR_WARN_UNUSED_RESULT
{
bool abort = false;
switch (tv->v_type) {
- case VAR_DICT: {
- dict_T *dd = tv->vval.v_dict;
- if (dd != NULL && dd->dv_copyID != copyID) {
- // Didn't see this dict yet.
- dd->dv_copyID = copyID;
- if (ht_stack == NULL) {
- abort = set_ref_in_ht(&dd->dv_hashtab, copyID, list_stack);
- } else {
- ht_stack_T *const newitem = xmalloc(sizeof(ht_stack_T));
- newitem->ht = &dd->dv_hashtab;
- newitem->prev = *ht_stack;
- *ht_stack = newitem;
- }
+ case VAR_DICT: {
+ dict_T *dd = tv->vval.v_dict;
+ if (dd != NULL && dd->dv_copyID != copyID) {
+ // Didn't see this dict yet.
+ dd->dv_copyID = copyID;
+ if (ht_stack == NULL) {
+ abort = set_ref_in_ht(&dd->dv_hashtab, copyID, list_stack);
+ } else {
+ ht_stack_T *const newitem = xmalloc(sizeof(ht_stack_T));
+ newitem->ht = &dd->dv_hashtab;
+ newitem->prev = *ht_stack;
+ *ht_stack = newitem;
+ }
- QUEUE *w = NULL;
- DictWatcher *watcher = NULL;
- QUEUE_FOREACH(w, &dd->watchers, {
+ QUEUE *w = NULL;
+ DictWatcher *watcher = NULL;
+ QUEUE_FOREACH(w, &dd->watchers, {
watcher = tv_dict_watcher_node_data(w);
set_ref_in_callback(&watcher->callback, copyID, ht_stack, list_stack);
})
- }
- break;
}
+ break;
+ }
- case VAR_LIST: {
- list_T *ll = tv->vval.v_list;
- if (ll != NULL && ll->lv_copyID != copyID) {
- // Didn't see this list yet.
- ll->lv_copyID = copyID;
- if (list_stack == NULL) {
- abort = set_ref_in_list(ll, copyID, ht_stack);
- } else {
- list_stack_T *const newitem = xmalloc(sizeof(list_stack_T));
- newitem->list = ll;
- newitem->prev = *list_stack;
- *list_stack = newitem;
- }
+ case VAR_LIST: {
+ list_T *ll = tv->vval.v_list;
+ if (ll != NULL && ll->lv_copyID != copyID) {
+ // Didn't see this list yet.
+ ll->lv_copyID = copyID;
+ if (list_stack == NULL) {
+ abort = set_ref_in_list(ll, copyID, ht_stack);
+ } else {
+ list_stack_T *const newitem = xmalloc(sizeof(list_stack_T));
+ newitem->list = ll;
+ newitem->prev = *list_stack;
+ *list_stack = newitem;
}
- break;
}
+ break;
+ }
- case VAR_PARTIAL: {
- partial_T *pt = tv->vval.v_partial;
+ case VAR_PARTIAL: {
+ partial_T *pt = tv->vval.v_partial;
- // A partial does not have a copyID, because it cannot contain itself.
- if (pt != NULL) {
- abort = set_ref_in_func(pt->pt_name, pt->pt_func, copyID);
- if (pt->pt_dict != NULL) {
- typval_T dtv;
+ // A partial does not have a copyID, because it cannot contain itself.
+ if (pt != NULL) {
+ abort = set_ref_in_func(pt->pt_name, pt->pt_func, copyID);
+ if (pt->pt_dict != NULL) {
+ typval_T dtv;
- dtv.v_type = VAR_DICT;
- dtv.vval.v_dict = pt->pt_dict;
- abort = abort || set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
- }
+ dtv.v_type = VAR_DICT;
+ dtv.vval.v_dict = pt->pt_dict;
+ abort = abort || set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
+ }
- for (int i = 0; i < pt->pt_argc; i++) {
- abort = abort || set_ref_in_item(&pt->pt_argv[i], copyID,
- ht_stack, list_stack);
- }
+ for (int i = 0; i < pt->pt_argc; i++) {
+ abort = abort || set_ref_in_item(&pt->pt_argv[i], copyID,
+ ht_stack, list_stack);
}
- break;
- }
- case VAR_FUNC:
- abort = set_ref_in_func(tv->vval.v_string, NULL, copyID);
- break;
- case VAR_UNKNOWN:
- case VAR_BOOL:
- case VAR_SPECIAL:
- case VAR_FLOAT:
- case VAR_NUMBER:
- case VAR_STRING: {
- break;
}
+ break;
+ }
+ case VAR_FUNC:
+ abort = set_ref_in_func(tv->vval.v_string, NULL, copyID);
+ break;
+ case VAR_UNKNOWN:
+ case VAR_BOOL:
+ case VAR_SPECIAL:
+ case VAR_FLOAT:
+ case VAR_NUMBER:
+ case VAR_STRING:
+ case VAR_BLOB:
+ break;
}
return abort;
}
@@ -5262,15 +5702,14 @@ static int get_literal_key(char_u **arg, typval_T *tv)
// Allocate a variable for a Dictionary and fill it from "*arg".
// "literal" is true for *{key: val}
// Return OK or FAIL. Returns NOTDONE for {expr}.
-static int dict_get_tv(char_u **arg, typval_T *rettv, int evaluate,
- bool literal)
+static int dict_get_tv(char_u **arg, typval_T *rettv, int evaluate, bool literal)
{
- dict_T *d = NULL;
+ dict_T *d = NULL;
typval_T tvkey;
typval_T tv;
- char_u *key = NULL;
- dictitem_T *item;
- char_u *start = skipwhite(*arg + 1);
+ char_u *key = NULL;
+ dictitem_T *item;
+ char_u *start = skipwhite(*arg + 1);
char buf[NUMBUFLEN];
/*
@@ -5340,8 +5779,9 @@ static int dict_get_tv(char_u **arg, typval_T *rettv, int evaluate,
}
tv_clear(&tvkey);
- if (**arg == '}')
+ if (**arg == '}') {
break;
+ }
if (**arg != ',') {
EMSG2(_("E722: Missing comma in Dictionary: %s"), *arg);
goto failret;
@@ -5394,7 +5834,7 @@ size_t string2float(const char *const text, float_T *const ret_value)
return 3;
}
*ret_value = strtod(text, &s);
- return (size_t) (s - text);
+ return (size_t)(s - text);
}
/// Get the value of an environment variable.
@@ -5408,8 +5848,8 @@ static int get_env_tv(char_u **arg, typval_T *rettv, int evaluate)
{
char_u *name;
char_u *string = NULL;
- int len;
- int cc;
+ int len;
+ int cc;
++*arg;
name = *arg;
@@ -5441,8 +5881,7 @@ static int get_env_tv(char_u **arg, typval_T *rettv, int evaluate)
}
/// Get the argument list for a given window
-void get_arglist_as_rettv(aentry_T *arglist, int argcount,
- typval_T *rettv)
+void get_arglist_as_rettv(aentry_T *arglist, int argcount, typval_T *rettv)
{
tv_list_alloc_ret(rettv, argcount);
if (arglist != NULL) {
@@ -5487,21 +5926,28 @@ static void ga_concat_esc(garray_T *gap, const char_u *p, int clen)
ga_concat(gap, buf);
} else {
switch (*p) {
- case BS: ga_concat(gap, (char_u *)"\\b"); break;
- case ESC: ga_concat(gap, (char_u *)"\\e"); break;
- case FF: ga_concat(gap, (char_u *)"\\f"); break;
- case NL: ga_concat(gap, (char_u *)"\\n"); break;
- case TAB: ga_concat(gap, (char_u *)"\\t"); break;
- case CAR: ga_concat(gap, (char_u *)"\\r"); break;
- case '\\': ga_concat(gap, (char_u *)"\\\\"); break;
- default:
- if (*p < ' ') {
- vim_snprintf((char *)buf, NUMBUFLEN, "\\x%02x", *p);
- ga_concat(gap, buf);
- } else {
- ga_append(gap, *p);
- }
- break;
+ case BS:
+ ga_concat(gap, (char_u *)"\\b"); break;
+ case ESC:
+ ga_concat(gap, (char_u *)"\\e"); break;
+ case FF:
+ ga_concat(gap, (char_u *)"\\f"); break;
+ case NL:
+ ga_concat(gap, (char_u *)"\\n"); break;
+ case TAB:
+ ga_concat(gap, (char_u *)"\\t"); break;
+ case CAR:
+ ga_concat(gap, (char_u *)"\\r"); break;
+ case '\\':
+ ga_concat(gap, (char_u *)"\\\\"); break;
+ default:
+ if (*p < ' ') {
+ vim_snprintf((char *)buf, NUMBUFLEN, "\\x%02x", *p);
+ ga_concat(gap, buf);
+ } else {
+ ga_append(gap, *p);
+ }
+ break;
}
}
}
@@ -5542,8 +5988,7 @@ static void ga_concat_shorten_esc(garray_T *gap, const char_u *str)
}
// Fill "gap" with information about an assert error.
-void fill_assert_error(garray_T *gap, typval_T *opt_msg_tv,
- char_u *exp_str, typval_T *exp_tv,
+void fill_assert_error(garray_T *gap, typval_T *opt_msg_tv, char_u *exp_str, typval_T *exp_tv,
typval_T *got_tv, assert_type_T atype)
{
char_u *tofree;
@@ -5748,7 +6193,7 @@ int assert_inrange(typval_T *argvars)
char msg[55];
vim_snprintf(msg, sizeof(msg),
"range %" PRIdVARNUMBER " - %" PRIdVARNUMBER ",",
- lower, upper);
+ lower, upper); // -V576
fill_assert_error(&ga, &argvars[3], (char_u *)msg, NULL, &argvars[2],
ASSERT_INRANGE);
assert_error(&ga);
@@ -5809,8 +6254,7 @@ int assert_exception(typval_T *argvars)
return 0;
}
-static void assert_append_cmd_or_arg(garray_T *gap, typval_T *argvars,
- const char *cmd)
+static void assert_append_cmd_or_arg(garray_T *gap, typval_T *argvars, const char *cmd)
FUNC_ATTR_NONNULL_ALL
{
if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN) {
@@ -5855,9 +6299,9 @@ int assert_fails(typval_T *argvars)
FUNC_ATTR_NONNULL_ALL
{
const char *const cmd = tv_get_string_chk(&argvars[0]);
- garray_T ga;
+ garray_T ga;
int ret = 0;
- int save_trylevel = trylevel;
+ int save_trylevel = trylevel;
// trylevel must be zero for a ":throw" command to be considered failed
trylevel = 0;
@@ -5923,7 +6367,7 @@ int assert_match_common(typval_T *argvars, assert_type_T atype)
/// Find a window: When using a Window ID in any tab page, when using a number
/// in the current tab page.
-win_T * find_win_by_nr_or_id(typval_T *vp)
+win_T *find_win_by_nr_or_id(typval_T *vp)
{
int nr = (int)tv_get_number_chk(vp, NULL);
@@ -5939,14 +6383,15 @@ win_T * find_win_by_nr_or_id(typval_T *vp)
*/
void filter_map(typval_T *argvars, typval_T *rettv, int map)
{
- typval_T *expr;
- list_T *l = NULL;
- dictitem_T *di;
- hashtab_T *ht;
- hashitem_T *hi;
- dict_T *d = NULL;
+ typval_T *expr;
+ list_T *l = NULL;
+ dictitem_T *di;
+ hashtab_T *ht;
+ hashitem_T *hi;
+ dict_T *d = NULL;
typval_T save_val;
typval_T save_key;
+ blob_T *b = NULL;
int rem = false;
int todo;
char_u *ermsg = (char_u *)(map ? "map()" : "filter()");
@@ -5956,7 +6401,12 @@ void filter_map(typval_T *argvars, typval_T *rettv, int map)
int save_did_emsg;
int idx = 0;
- if (argvars[0].v_type == VAR_LIST) {
+ if (argvars[0].v_type == VAR_BLOB) {
+ tv_copy(&argvars[0], rettv);
+ if ((b = argvars[0].vval.v_blob) == NULL) {
+ return;
+ }
+ } else if (argvars[0].v_type == VAR_LIST) {
tv_copy(&argvars[0], rettv);
if ((l = argvars[0].vval.v_list) == NULL
|| (!map
@@ -5970,7 +6420,7 @@ void filter_map(typval_T *argvars, typval_T *rettv, int map)
return;
}
} else {
- EMSG2(_(e_listdictarg), ermsg);
+ EMSG2(_(e_listdictblobarg), ermsg);
return;
}
@@ -6020,6 +6470,34 @@ void filter_map(typval_T *argvars, typval_T *rettv, int map)
}
}
hash_unlock(ht);
+ } else if (argvars[0].v_type == VAR_BLOB) {
+ vimvars[VV_KEY].vv_type = VAR_NUMBER;
+
+ for (int i = 0; i < b->bv_ga.ga_len; i++) {
+ typval_T tv;
+ tv.v_type = VAR_NUMBER;
+ const varnumber_T val = tv_blob_get(b, i);
+ tv.vval.v_number = val;
+ vimvars[VV_KEY].vv_nr = idx;
+ if (filter_map_one(&tv, expr, map, &rem) == FAIL || did_emsg) {
+ break;
+ }
+ if (tv.v_type != VAR_NUMBER) {
+ EMSG(_(e_invalblob));
+ return;
+ }
+ if (map) {
+ if (tv.vval.v_number != val) {
+ tv_blob_set(b, i, tv.vval.v_number);
+ }
+ } else if (rem) {
+ char_u *const p = (char_u *)argvars[0].vval.v_blob->bv_ga.ga_data;
+ memmove(p + i, p + i + 1, (size_t)b->bv_ga.ga_len - i - 1);
+ b->bv_ga.ga_len--;
+ i--;
+ }
+ idx++;
+ }
} else {
assert(argvars[0].v_type == VAR_LIST);
vimvars[VV_KEY].vv_type = VAR_NUMBER;
@@ -6087,11 +6565,10 @@ theend:
return retval;
}
-void common_function(typval_T *argvars, typval_T *rettv,
- bool is_funcref, FunPtr fptr)
+void common_function(typval_T *argvars, typval_T *rettv, bool is_funcref, FunPtr fptr)
{
- char_u *s;
- char_u *name;
+ char_u *s;
+ char_u *name;
bool use_string = false;
partial_T *arg_pt = NULL;
char_u *trans_name = NULL;
@@ -6128,7 +6605,7 @@ void common_function(typval_T *argvars, typval_T *rettv,
// Don't check an autoload name for existence here.
} else if (trans_name != NULL
&& (is_funcref ? find_func(trans_name) == NULL
- : !translated_function_exists((const char *)trans_name))) {
+ : !translated_function_exists((const char *)trans_name))) {
emsgf(_("E700: Unknown function: %s"), s);
} else {
int dict_idx = 0;
@@ -6304,8 +6781,7 @@ dict_T *get_buffer_info(buf_T *buf)
/// be NULL, in this case "$" results in zero return.
///
/// @return Line number or 0 in case of error.
-linenr_T tv_get_lnum_buf(const typval_T *const tv,
- const buf_T *const buf)
+linenr_T tv_get_lnum_buf(const typval_T *const tv, const buf_T *const buf)
FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_WARN_UNUSED_RESULT
{
if (tv->v_type == VAR_STRING
@@ -6317,8 +6793,7 @@ linenr_T tv_get_lnum_buf(const typval_T *const tv,
return tv_get_number_chk(tv, NULL);
}
-void get_qf_loc_list(int is_qf, win_T *wp, typval_T *what_arg,
- typval_T *rettv)
+void get_qf_loc_list(int is_qf, win_T *wp, typval_T *what_arg, typval_T *rettv)
{
if (what_arg->v_type == VAR_UNKNOWN) {
tv_list_alloc_ret(rettv, kListLenMayKnow);
@@ -6389,12 +6864,10 @@ dict_T *get_win_info(win_T *wp, int16_t tpnr, int16_t winnr)
return dict;
}
-// Find window specified by "vp" in tabpage "tp".
-win_T *
-find_win_by_nr(
- typval_T *vp,
- tabpage_T *tp // NULL for current tab page
-)
+/// Find window specified by "vp" in tabpage "tp".
+///
+/// @param tp NULL for current tab page
+win_T *find_win_by_nr(typval_T *vp, tabpage_T *tp)
{
int nr = (int)tv_get_number_chk(vp, NULL);
@@ -6408,7 +6881,7 @@ find_win_by_nr(
// This method accepts NULL as an alias for curtab.
if (tp == NULL) {
- tp = curtab;
+ tp = curtab;
}
FOR_ALL_WINDOWS_IN_TAB(wp, tp) {
@@ -6449,15 +6922,10 @@ win_T *find_tabwin(typval_T *wvp, typval_T *tvp)
return wp;
}
-/*
- * getwinvar() and gettabwinvar()
- */
-void
-getwinvar(
- typval_T *argvars,
- typval_T *rettv,
- int off // 1 for gettabwinvar()
-)
+/// getwinvar() and gettabwinvar()
+///
+/// @param off 1 for gettabwinvar()
+void getwinvar(typval_T *argvars, typval_T *rettv, int off)
{
win_T *win, *oldcurwin;
dictitem_T *v;
@@ -6528,9 +6996,7 @@ getwinvar(
* prompt. The third argument to f_inputdialog() specifies the value to return
* when the user cancels the prompt.
*/
-void get_user_input(const typval_T *const argvars,
- typval_T *const rettv,
- const bool inputdialog,
+void get_user_input(const typval_T *const argvars, typval_T *const rettv, const bool inputdialog,
const bool secret)
FUNC_ATTR_NONNULL_ALL
{
@@ -6665,8 +7131,7 @@ void get_user_input(const typval_T *const argvars,
/// a dictionary, will give an error if not.
/// @param[out] rettv Location where result will be saved.
/// @param[in] what What to save in rettv.
-void dict_list(typval_T *const tv, typval_T *const rettv,
- const DictListType what)
+void dict_list(typval_T *const tv, typval_T *const rettv, const DictListType what)
{
if (tv->v_type != VAR_DICT) {
EMSG(_(e_dictreq));
@@ -6682,32 +7147,30 @@ void dict_list(typval_T *const tv, typval_T *const rettv,
typval_T tv_item = { .v_lock = VAR_UNLOCKED };
switch (what) {
- case kDictListKeys: {
- tv_item.v_type = VAR_STRING;
- tv_item.vval.v_string = vim_strsave(di->di_key);
- break;
- }
- case kDictListValues: {
- tv_copy(&di->di_tv, &tv_item);
- break;
- }
- case kDictListItems: {
- // items()
- list_T *const sub_l = tv_list_alloc(2);
- tv_item.v_type = VAR_LIST;
- tv_item.vval.v_list = sub_l;
- tv_list_ref(sub_l);
-
- tv_list_append_owned_tv(sub_l, (typval_T) {
+ case kDictListKeys:
+ tv_item.v_type = VAR_STRING;
+ tv_item.vval.v_string = vim_strsave(di->di_key);
+ break;
+ case kDictListValues:
+ tv_copy(&di->di_tv, &tv_item);
+ break;
+ case kDictListItems: {
+ // items()
+ list_T *const sub_l = tv_list_alloc(2);
+ tv_item.v_type = VAR_LIST;
+ tv_item.vval.v_list = sub_l;
+ tv_list_ref(sub_l);
+
+ tv_list_append_owned_tv(sub_l, (typval_T) {
.v_type = VAR_STRING,
.v_lock = VAR_UNLOCKED,
.vval.v_string = (char_u *)xstrdup((const char *)di->di_key),
});
- tv_list_append_tv(sub_l, &di->di_tv);
+ tv_list_append_tv(sub_l, &di->di_tv);
- break;
- }
+ break;
+ }
}
tv_list_append_owned_tv(rettv->vval.v_list, tv_item);
@@ -6788,9 +7251,7 @@ char **tv_to_argv(typval_T *cmd_tv, const char **cmd, bool *executable)
/// @param mp The maphash that contains the mapping information
/// @param buffer_value The "buffer" value
/// @param compatible True for compatible with old maparg() dict
-void mapblock_fill_dict(dict_T *const dict,
- const mapblock_T *const mp,
- long buffer_value,
+void mapblock_fill_dict(dict_T *const dict, const mapblock_T *const mp, long buffer_value,
bool compatible)
FUNC_ATTR_NONNULL_ALL
{
@@ -6828,8 +7289,7 @@ void mapblock_fill_dict(dict_T *const dict,
tv_dict_add_allocated_str(dict, S_LEN("mode"), mapmode);
}
-int matchadd_dict_arg(typval_T *tv, const char **conceal_char,
- win_T **win)
+int matchadd_dict_arg(typval_T *tv, const char **conceal_char, win_T **win)
{
dictitem_T *di;
@@ -6877,18 +7337,18 @@ void screenchar_adjust_grid(ScreenGrid **grid, int *row, int *col)
}
/// Set line or list of lines in buffer "buf".
-void set_buffer_lines(buf_T *buf, linenr_T lnum_arg, bool append,
- const typval_T *lines, typval_T *rettv)
+void set_buffer_lines(buf_T *buf, linenr_T lnum_arg, bool append, const typval_T *lines,
+ typval_T *rettv)
FUNC_ATTR_NONNULL_ARG(4, 5)
{
linenr_T lnum = lnum_arg + (append ? 1 : 0);
const char *line = NULL;
- list_T *l = NULL;
- listitem_T *li = NULL;
- long added = 0;
+ list_T *l = NULL;
+ listitem_T *li = NULL;
+ long added = 0;
linenr_T append_lnum;
- buf_T *curbuf_save = NULL;
- win_T *curwin_save = NULL;
+ buf_T *curbuf_save = NULL;
+ win_T *curwin_save = NULL;
const bool is_curbuf = buf == curbuf;
// When using the current buffer ml_mfp will be set if needed. Useful when
@@ -6988,8 +7448,8 @@ void set_buffer_lines(buf_T *buf, linenr_T lnum_arg, bool append,
}
if (!is_curbuf) {
- curbuf = curbuf_save;
- curwin = curwin_save;
+ curbuf = curbuf_save;
+ curwin = curwin_save;
}
}
@@ -7014,8 +7474,8 @@ void setwinvar(typval_T *argvars, typval_T *rettv, int off)
typval_T *varp = &argvars[off + 2];
if (win != NULL && varname != NULL && varp != NULL) {
- win_T *save_curwin;
- tabpage_T *save_curtab;
+ win_T *save_curwin;
+ tabpage_T *save_curtab;
bool need_switch_win = tp != curtab || win != curwin;
if (!need_switch_win
|| switch_win(&save_curwin, &save_curtab, win, tp, true) == OK) {
@@ -7083,8 +7543,7 @@ static list_T *string_to_list(const char *str, size_t len, const bool keepempty)
}
// os_system wrapper. Handles 'verbose', :profile, and v:shell_error.
-void get_system_output_as_rettv(typval_T *argvars, typval_T *rettv,
- bool retlist)
+void get_system_output_as_rettv(typval_T *argvars, typval_T *rettv, bool retlist)
{
proftime_T wait_time;
bool profiling = do_profiling == PROF_YES;
@@ -7139,14 +7598,14 @@ void get_system_output_as_rettv(typval_T *argvars, typval_T *rettv,
xfree(input);
- set_vim_var_nr(VV_SHELL_ERROR, (long) status);
+ set_vim_var_nr(VV_SHELL_ERROR, (long)status);
if (res == NULL) {
if (retlist) {
// return an empty list when there's no output
tv_list_alloc_ret(rettv, 0);
} else {
- rettv->vval.v_string = (char_u *) xstrdup("");
+ rettv->vval.v_string = (char_u *)xstrdup("");
}
return;
}
@@ -7178,7 +7637,7 @@ void get_system_output_as_rettv(typval_T *argvars, typval_T *rettv,
*d = NUL;
#endif
- rettv->vval.v_string = (char_u *) res;
+ rettv->vval.v_string = (char_u *)res;
}
}
@@ -7231,62 +7690,62 @@ bool callback_from_typval(Callback *const callback, typval_T *const arg)
return true;
}
-bool callback_call(Callback *const callback, const int argcount_in,
- typval_T *const argvars_in, typval_T *const rettv)
+bool callback_call(Callback *const callback, const int argcount_in, typval_T *const argvars_in,
+ typval_T *const rettv)
FUNC_ATTR_NONNULL_ALL
{
partial_T *partial;
char_u *name;
switch (callback->type) {
- case kCallbackFuncref:
- name = callback->data.funcref;
- partial = NULL;
- break;
+ case kCallbackFuncref:
+ name = callback->data.funcref;
+ partial = NULL;
+ break;
- case kCallbackPartial:
- partial = callback->data.partial;
- name = partial_name(partial);
- break;
+ case kCallbackPartial:
+ partial = callback->data.partial;
+ name = partial_name(partial);
+ break;
- case kCallbackNone:
- return false;
- break;
+ case kCallbackNone:
+ return false;
+ break;
- default:
- abort();
+ default:
+ abort();
}
- int dummy;
- return call_func(name, -1, rettv, argcount_in, argvars_in,
- NULL, curwin->w_cursor.lnum, curwin->w_cursor.lnum, &dummy,
- true, partial, NULL);
+ funcexe_T funcexe = FUNCEXE_INIT;
+ funcexe.firstline = curwin->w_cursor.lnum;
+ funcexe.lastline = curwin->w_cursor.lnum;
+ funcexe.evaluate = true;
+ funcexe.partial = partial;
+ return call_func(name, -1, rettv, argcount_in, argvars_in, &funcexe);
}
-static bool set_ref_in_callback(Callback *callback, int copyID,
- ht_stack_T **ht_stack,
+static bool set_ref_in_callback(Callback *callback, int copyID, ht_stack_T **ht_stack,
list_stack_T **list_stack)
{
typval_T tv;
switch (callback->type) {
- case kCallbackFuncref:
- case kCallbackNone:
- break;
+ case kCallbackFuncref:
+ case kCallbackNone:
+ break;
- case kCallbackPartial:
- tv.v_type = VAR_PARTIAL;
- tv.vval.v_partial = callback->data.partial;
- return set_ref_in_item(&tv, copyID, ht_stack, list_stack);
- break;
+ case kCallbackPartial:
+ tv.v_type = VAR_PARTIAL;
+ tv.vval.v_partial = callback->data.partial;
+ return set_ref_in_item(&tv, copyID, ht_stack, list_stack);
+ break;
- default:
- abort();
+ default:
+ abort();
}
return false;
}
-static bool set_ref_in_callback_reader(CallbackReader *reader, int copyID,
- ht_stack_T **ht_stack,
+static bool set_ref_in_callback_reader(CallbackReader *reader, int copyID, ht_stack_T **ht_stack,
list_stack_T **list_stack)
{
if (set_ref_in_callback(&reader->cb, copyID, ht_stack, list_stack)) {
@@ -7304,7 +7763,7 @@ static bool set_ref_in_callback_reader(CallbackReader *reader, int copyID,
timer_T *find_timer_by_nr(varnumber_T xx)
{
- return pmap_get(uint64_t)(timers, xx);
+ return pmap_get(uint64_t)(&timers, xx);
}
void add_timer_info(typval_T *rettv, timer_T *timer)
@@ -7331,9 +7790,9 @@ void add_timer_info(typval_T *rettv, timer_T *timer)
void add_timer_info_all(typval_T *rettv)
{
- tv_list_alloc_ret(rettv, timers->table->n_occupied);
+ tv_list_alloc_ret(rettv, map_size(&timers));
timer_T *timer;
- map_foreach_value(timers, timer, {
+ map_foreach_value(&timers, timer, {
if (!timer->stopped) {
add_timer_info(rettv, timer);
}
@@ -7393,9 +7852,7 @@ void timer_due_cb(TimeWatcher *tw, void *data)
timer_decref(timer);
}
-uint64_t timer_start(const long timeout,
- const int repeat_count,
- const Callback *const callback)
+uint64_t timer_start(const long timeout, const int repeat_count, const Callback *const callback)
{
timer_T *timer = xmalloc(sizeof *timer);
timer->refcount = 1;
@@ -7413,7 +7870,7 @@ uint64_t timer_start(const long timeout,
timer->tw.blockable = true;
time_watcher_start(&timer->tw, timer_due_cb, timeout, timeout);
- pmap_put(uint64_t)(timers, timer->timer_id, timer);
+ pmap_put(uint64_t)(&timers, timer->timer_id, timer);
return timer->timer_id;
}
@@ -7435,7 +7892,7 @@ static void timer_close_cb(TimeWatcher *tw, void *data)
timer_T *timer = (timer_T *)data;
multiqueue_free(timer->tw.events);
callback_free(&timer->callback);
- pmap_del(uint64_t)(timers, timer->timer_id);
+ pmap_del(uint64_t)(&timers, timer->timer_id);
timer_decref(timer);
}
@@ -7449,7 +7906,7 @@ static void timer_decref(timer_T *timer)
void timer_stop_all(void)
{
timer_T *timer;
- map_foreach_value(timers, timer, {
+ map_foreach_value(&timers, timer, {
timer_stop(timer);
})
}
@@ -7466,8 +7923,7 @@ void timer_teardown(void)
/// @param[in] binary Whether to write in binary mode.
///
/// @return true in case of success, false otherwise.
-bool write_list(FileDescriptor *const fp, const list_T *const list,
- const bool binary)
+bool write_list(FileDescriptor *const fp, const list_T *const list, const bool binary)
FUNC_ATTR_NONNULL_ARG(1)
{
int error = 0;
@@ -7512,10 +7968,61 @@ bool write_list(FileDescriptor *const fp, const list_T *const list,
}
return true;
write_list_error:
- emsgf(_("E80: Error while writing: %s"), os_strerror(error));
+ emsgf(_(e_write2), os_strerror(error));
return false;
}
+/// Write a blob to file with descriptor `fp`.
+///
+/// @param[in] fp File to write to.
+/// @param[in] blob Blob to write.
+///
+/// @return true on success, or false on failure.
+bool write_blob(FileDescriptor *const fp, const blob_T *const blob)
+ FUNC_ATTR_NONNULL_ARG(1)
+{
+ int error = 0;
+ const int len = tv_blob_len(blob);
+ if (len > 0) {
+ const ptrdiff_t written = file_write(fp, blob->bv_ga.ga_data, (size_t)len);
+ if (written < (ptrdiff_t)len) {
+ error = (int)written;
+ goto write_blob_error;
+ }
+ }
+ error = file_flush(fp);
+ if (error != 0) {
+ goto write_blob_error;
+ }
+ return true;
+write_blob_error:
+ EMSG2(_(e_write2), os_strerror(error));
+ return false;
+}
+
+/// Read a blob from a file `fd`.
+///
+/// @param[in] fd File to read from.
+/// @param[in,out] blob Blob to write to.
+///
+/// @return true on success, or false on failure.
+bool read_blob(FILE *const fd, blob_T *const blob)
+ FUNC_ATTR_NONNULL_ALL
+{
+ FileInfo file_info;
+ if (!os_fileinfo_fd(fileno(fd), &file_info)) {
+ return false;
+ }
+ const int size = (int)os_fileinfo_size(&file_info);
+ ga_grow(&blob->bv_ga, size);
+ blob->bv_ga.ga_len = size;
+ if (fread(blob->bv_ga.ga_data, 1, blob->bv_ga.ga_len, fd)
+ < (size_t)blob->bv_ga.ga_len) {
+ return false;
+ }
+ return true;
+}
+
/// Saves a typval_T as a string.
///
/// For lists or buffers, replaces NLs with NUL and separates items with NLs.
@@ -7614,16 +8121,15 @@ char *save_tv_as_string(typval_T *tv, ptrdiff_t *const len, bool endnl)
/// @param[out] ret_fnum Set to fnum for marks.
///
/// @return Pointer to position or NULL in case of error (e.g. invalid type).
-pos_T *var2fpos(const typval_T *const tv, const bool dollar_lnum,
- int *const ret_fnum)
+pos_T *var2fpos(const typval_T *const tv, const bool dollar_lnum, int *const ret_fnum)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
static pos_T pos;
- pos_T *pp;
+ pos_T *pp;
// Argument can be [lnum, col, coladd].
if (tv->v_type == VAR_LIST) {
- list_T *l;
+ list_T *l;
int len;
bool error = false;
listitem_T *li;
@@ -7841,10 +8347,7 @@ int get_id_len(const char **const arg)
* If the name contains 'magic' {}'s, expand them and return the
* expanded name in an allocated string via 'alias' - caller must free.
*/
-int get_name_len(const char **const arg,
- char **alias,
- bool evaluate,
- bool verbose)
+int get_name_len(const char **const arg, char **alias, bool evaluate, bool verbose)
{
int len;
@@ -7863,8 +8366,8 @@ int get_name_len(const char **const arg,
}
// Find the end of the name; check for {} construction.
- char_u *expr_start;
- char_u *expr_end;
+ char_u *expr_start;
+ char_u *expr_end;
const char *p = (const char *)find_name_end((char_u *)(*arg),
(const char_u **)&expr_start,
(const char_u **)&expr_end,
@@ -7906,8 +8409,8 @@ int get_name_len(const char **const arg,
// "flags" can have FNE_INCL_BR and FNE_CHECK_START.
// Return a pointer to just after the name. Equal to "arg" if there is no
// valid name.
-const char_u *find_name_end(const char_u *arg, const char_u **expr_start,
- const char_u **expr_end, int flags)
+const char_u *find_name_end(const char_u *arg, const char_u **expr_start, const char_u **expr_end,
+ int flags)
{
int mb_nest = 0;
int br_nest = 0;
@@ -7988,30 +8491,31 @@ const char_u *find_name_end(const char_u *arg, const char_u **expr_start,
* Note that this can call itself recursively, to deal with
* constructs like foo{bar}{baz}{bam}
* The four pointer arguments point to "foo{expre}ss{ion}bar"
- * "in_start" ^
- * "expr_start" ^
- * "expr_end" ^
- * "in_end" ^
+ * "in_start" ^
+ * "expr_start" ^
+ * "expr_end" ^
+ * "in_end" ^
*
* Returns a new allocated string, which the caller must free.
* Returns NULL for failure.
*/
-static char_u *make_expanded_name(const char_u *in_start, char_u *expr_start,
- char_u *expr_end, char_u *in_end)
+static char_u *make_expanded_name(const char_u *in_start, char_u *expr_start, char_u *expr_end,
+ char_u *in_end)
{
char_u c1;
- char_u *retval = NULL;
- char_u *temp_result;
- char_u *nextcmd = NULL;
+ char_u *retval = NULL;
+ char_u *temp_result;
+ char_u *nextcmd = NULL;
- if (expr_end == NULL || in_end == NULL)
+ if (expr_end == NULL || in_end == NULL) {
return NULL;
+ }
*expr_start = NUL;
*expr_end = NUL;
c1 = *in_end;
*in_end = NUL;
- temp_result = eval_to_string(expr_start + 1, &nextcmd, FALSE);
+ temp_result = eval_to_string(expr_start + 1, &nextcmd, false);
if (temp_result != NULL && nextcmd == NULL) {
retval = xmalloc(STRLEN(temp_result) + (expr_start - in_start)
+ (in_end - expr_end) + 1);
@@ -8032,7 +8536,7 @@ static char_u *make_expanded_name(const char_u *in_start, char_u *expr_start,
if (expr_start != NULL) {
// Further expansion!
temp_result = make_expanded_name(retval, expr_start,
- expr_end, temp_result);
+ expr_end, temp_result);
xfree(retval);
retval = temp_result;
}
@@ -8108,8 +8612,9 @@ void set_vim_var_char(int c)
*/
void set_vcount(long count, long count1, int set_prevcount)
{
- if (set_prevcount)
+ if (set_prevcount) {
vimvars[VV_PREVCOUNT].vv_nr = vimvars[VV_COUNT].vv_nr;
+ }
vimvars[VV_COUNT].vv_nr = count;
vimvars[VV_COUNT1].vv_nr = count1;
}
@@ -8151,19 +8656,18 @@ void set_vim_var_special(const VimVarIndex idx, const SpecialVarValue val)
///
/// @param[in] idx Index of variable to set.
/// @param[in] val Value to set to. Will be copied.
-/// @param[in] len Legth of that value or -1 in which case strlen() will be
+/// @param[in] len Length of that value or -1 in which case strlen() will be
/// used.
-void set_vim_var_string(const VimVarIndex idx, const char *const val,
- const ptrdiff_t len)
+void set_vim_var_string(const VimVarIndex idx, const char *const val, const ptrdiff_t len)
{
tv_clear(&vimvars[idx].vv_di.di_tv);
vimvars[idx].vv_type = VAR_STRING;
if (val == NULL) {
vimvars[idx].vv_str = NULL;
} else if (len == -1) {
- vimvars[idx].vv_str = (char_u *) xstrdup(val);
+ vimvars[idx].vv_str = (char_u *)xstrdup(val);
} else {
- vimvars[idx].vv_str = (char_u *) xstrndup(val, (size_t) len);
+ vimvars[idx].vv_str = (char_u *)xstrndup(val, (size_t)len);
}
}
@@ -8239,8 +8743,9 @@ void set_reg_var(int c)
*/
char_u *v_exception(char_u *oldval)
{
- if (oldval == NULL)
+ if (oldval == NULL) {
return vimvars[VV_EXCEPTION].vv_str;
+ }
vimvars[VV_EXCEPTION].vv_str = oldval;
return NULL;
@@ -8254,8 +8759,9 @@ char_u *v_exception(char_u *oldval)
*/
char_u *v_throwpoint(char_u *oldval)
{
- if (oldval == NULL)
+ if (oldval == NULL) {
return vimvars[VV_THROWPOINT].vv_str;
+ }
vimvars[VV_THROWPOINT].vv_str = oldval;
return NULL;
@@ -8277,13 +8783,15 @@ char_u *set_cmdarg(exarg_T *eap, char_u *oldarg)
}
size_t len = 0;
- if (eap->force_bin == FORCE_BIN)
+ if (eap->force_bin == FORCE_BIN) {
len = 6;
- else if (eap->force_bin == FORCE_NOBIN)
+ } else if (eap->force_bin == FORCE_NOBIN) {
len = 8;
+ }
- if (eap->read_edit)
+ if (eap->read_edit) {
len += 7;
+ }
if (eap->force_ff != 0) {
len += 10; // " ++ff=unix"
@@ -8298,15 +8806,17 @@ char_u *set_cmdarg(exarg_T *eap, char_u *oldarg)
const size_t newval_len = len + 1;
char_u *newval = xmalloc(newval_len);
- if (eap->force_bin == FORCE_BIN)
- sprintf((char *)newval, " ++bin");
- else if (eap->force_bin == FORCE_NOBIN)
- sprintf((char *)newval, " ++nobin");
- else
+ if (eap->force_bin == FORCE_BIN) {
+ snprintf((char *)newval, newval_len, " ++bin");
+ } else if (eap->force_bin == FORCE_NOBIN) {
+ snprintf((char *)newval, newval_len, " ++nobin");
+ } else {
*newval = NUL;
+ }
- if (eap->read_edit)
+ if (eap->read_edit) {
STRCAT(newval, " ++edit");
+ }
if (eap->force_ff != 0) {
snprintf((char *)newval + STRLEN(newval), newval_len, " ++ff=%s",
@@ -8329,20 +8839,20 @@ char_u *set_cmdarg(exarg_T *eap, char_u *oldarg)
return oldval;
}
-// Get the value of internal variable "name".
-// Return OK or FAIL. If OK is returned "rettv" must be cleared.
-int get_var_tv(
- const char *name,
- int len, // length of "name"
- typval_T *rettv, // NULL when only checking existence
- dictitem_T **dip, // non-NULL when typval's dict item is needed
- int verbose, // may give error message
- int no_autoload // do not use script autoloading
-)
+/// Get the value of internal variable "name".
+/// Return OK or FAIL. If OK is returned "rettv" must be cleared.
+///
+/// @param len length of "name"
+/// @param rettv NULL when only checking existence
+/// @param dip non-NULL when typval's dict item is needed
+/// @param verbose may give error message
+/// @param no_autoload do not use script autoloading
+int get_var_tv(const char *name, int len, typval_T *rettv, dictitem_T **dip, int verbose,
+ int no_autoload)
{
int ret = OK;
- typval_T *tv = NULL;
- dictitem_T *v;
+ typval_T *tv = NULL;
+ dictitem_T *v;
v = find_var(name, (size_t)len, NULL, no_autoload);
if (v != NULL) {
@@ -8394,13 +8904,23 @@ static bool tv_is_luafunc(typval_T *tv)
return tv->v_type == VAR_PARTIAL && is_luafunc(tv->vval.v_partial);
}
-/// check the function name after "v:lua."
-int check_luafunc_name(const char *str, bool paren)
+/// Skips one character past the end of the name of a v:lua function.
+/// @param p Pointer to the char AFTER the "v:lua." prefix.
+/// @return Pointer to the char one past the end of the function's name.
+const char *skip_luafunc_name(const char *p)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
- const char *p = str;
while (ASCII_ISALNUM(*p) || *p == '_' || *p == '.' || *p == '\'') {
p++;
}
+ return p;
+}
+
+/// check the function name after "v:lua."
+int check_luafunc_name(const char *const str, const bool paren)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ const char *const p = skip_luafunc_name(str);
if (*p != (paren ? '(' : NUL)) {
return 0;
} else {
@@ -8408,24 +8928,24 @@ int check_luafunc_name(const char *str, bool paren)
}
}
-/// Handle expr[expr], expr[expr:expr] subscript and .name lookup.
-/// Also handle function call with Funcref variable: func(expr)
-/// Can all be combined: dict.func(expr)[idx]['func'](expr)
-int
-handle_subscript(
- const char **const arg,
- typval_T *rettv,
- int evaluate, // do more than finding the end
- int verbose // give error messages
-)
+/// Handle:
+/// - expr[expr], expr[expr:expr] subscript
+/// - ".name" lookup
+/// - function call with Funcref variable: func(expr)
+/// - method call: var->method()
+///
+/// Can all be combined in any order: dict.func(expr)[idx]['func'](expr)->len()
+///
+/// @param evaluate do more than finding the end
+/// @param verbose give error messages
+/// @param start_leader start of '!' and '-' prefixes
+/// @param end_leaderp end of '!' and '-' prefixes
+int handle_subscript(const char **const arg, typval_T *rettv, int evaluate, int verbose,
+ const char_u *const start_leader, const char_u **const end_leaderp)
{
int ret = OK;
- dict_T *selfdict = NULL;
- const char_u *s;
- int len;
- typval_T functv;
- int slen = 0;
- bool lua = false;
+ dict_T *selfdict = NULL;
+ const char_u *lua_funcname = NULL;
if (tv_is_luafunc(rettv)) {
if (**arg != '.') {
@@ -8434,55 +8954,29 @@ handle_subscript(
} else {
(*arg)++;
- lua = true;
- s = (char_u *)(*arg);
- slen = check_luafunc_name(*arg, true);
- if (slen == 0) {
+ lua_funcname = (char_u *)(*arg);
+ const int len = check_luafunc_name(*arg, true);
+ if (len == 0) {
tv_clear(rettv);
ret = FAIL;
}
- (*arg) += slen;
+ (*arg) += len;
}
}
-
+ // "." is ".name" lookup when we found a dict.
while (ret == OK
- && (**arg == '['
- || (**arg == '.' && rettv->v_type == VAR_DICT)
- || (**arg == '(' && (!evaluate || tv_is_func(*rettv))))
- && !ascii_iswhite(*(*arg - 1))) {
+ && (((**arg == '[' || (**arg == '.' && rettv->v_type == VAR_DICT)
+ || (**arg == '(' && (!evaluate || tv_is_func(*rettv))))
+ && !ascii_iswhite(*(*arg - 1)))
+ || (**arg == '-' && (*arg)[1] == '>'))) {
if (**arg == '(') {
- partial_T *pt = NULL;
- // need to copy the funcref so that we can clear rettv
- if (evaluate) {
- functv = *rettv;
- rettv->v_type = VAR_UNKNOWN;
-
- // Invoke the function. Recursive!
- if (functv.v_type == VAR_PARTIAL) {
- pt = functv.vval.v_partial;
- if (!lua) {
- s = partial_name(pt);
- }
- } else {
- s = functv.vval.v_string;
- }
- } else {
- s = (char_u *)"";
- }
- ret = get_func_tv(s, lua ? slen : -1, rettv, (char_u **)arg,
- curwin->w_cursor.lnum, curwin->w_cursor.lnum,
- &len, evaluate, pt, selfdict);
-
- // Clear the funcref afterwards, so that deleting it while
- // evaluating the arguments is possible (see test55).
- if (evaluate) {
- tv_clear(&functv);
- }
+ ret = call_func_rettv((char_u **)arg, rettv, evaluate, selfdict, NULL,
+ lua_funcname);
- /* Stop the expression evaluation when immediately aborting on
- * error, or when an interrupt occurred or an exception was thrown
- * but not caught. */
+ // Stop the expression evaluation when immediately aborting on
+ // error, or when an interrupt occurred or an exception was thrown
+ // but not caught.
if (aborting()) {
if (ret == OK) {
tv_clear(rettv);
@@ -8491,14 +8985,31 @@ handle_subscript(
}
tv_dict_unref(selfdict);
selfdict = NULL;
+ } else if (**arg == '-') {
+ // Expression "-1.0->method()" applies the leader "-" before
+ // applying ->.
+ if (evaluate && *end_leaderp > start_leader) {
+ ret = eval7_leader(rettv, start_leader, end_leaderp);
+ }
+ if (ret == OK) {
+ if ((*arg)[2] == '{') {
+ // expr->{lambda}()
+ ret = eval_lambda((char_u **)arg, rettv, evaluate, verbose);
+ } else {
+ // expr->name()
+ ret = eval_method((char_u **)arg, rettv, evaluate, verbose);
+ }
+ }
} else { // **arg == '[' || **arg == '.'
tv_dict_unref(selfdict);
if (rettv->v_type == VAR_DICT) {
selfdict = rettv->vval.v_dict;
- if (selfdict != NULL)
+ if (selfdict != NULL) {
++selfdict->dv_refcount;
- } else
+ }
+ } else {
selfdict = NULL;
+ }
if (eval_index((char_u **)arg, rettv, evaluate, verbose) == FAIL) {
tv_clear(rettv);
ret = FAIL;
@@ -8531,8 +9042,8 @@ void set_selfdict(typval_T *const rettv, dict_T *const selfdict)
// Careful: "a:0" variables don't have a name.
// When "htp" is not NULL we are writing to the variable, set "htp" to the
// hashtab_T used.
-dictitem_T *find_var(const char *const name, const size_t name_len,
- hashtab_T **htp, int no_autoload)
+dictitem_T *find_var(const char *const name, const size_t name_len, hashtab_T **htp,
+ int no_autoload)
{
const char *varname;
hashtab_T *const ht = find_var_ht(name, name_len, &varname);
@@ -8566,26 +9077,31 @@ dictitem_T *find_var(const char *const name, const size_t name_len,
///
/// @return pointer to the dictionary item with the found variable or NULL if it
/// was not found.
-dictitem_T *find_var_in_ht(hashtab_T *const ht,
- int htname,
- const char *const varname,
- const size_t varname_len,
- int no_autoload)
+dictitem_T *find_var_in_ht(hashtab_T *const ht, int htname, const char *const varname,
+ const size_t varname_len, int no_autoload)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
- hashitem_T *hi;
+ hashitem_T *hi;
if (varname_len == 0) {
// Must be something like "s:", otherwise "ht" would be NULL.
switch (htname) {
- case 's': return (dictitem_T *)&SCRIPT_SV(current_sctx.sc_sid)->sv_var;
- case 'g': return (dictitem_T *)&globvars_var;
- case 'v': return (dictitem_T *)&vimvars_var;
- case 'b': return (dictitem_T *)&curbuf->b_bufvar;
- case 'w': return (dictitem_T *)&curwin->w_winvar;
- case 't': return (dictitem_T *)&curtab->tp_winvar;
- case 'l': return get_funccal_local_var();
- case 'a': return get_funccal_args_var();
+ case 's':
+ return (dictitem_T *)&SCRIPT_SV(current_sctx.sc_sid)->sv_var;
+ case 'g':
+ return (dictitem_T *)&globvars_var;
+ case 'v':
+ return (dictitem_T *)&vimvars_var;
+ case 'b':
+ return (dictitem_T *)&curbuf->b_bufvar;
+ case 'w':
+ return (dictitem_T *)&curwin->w_winvar;
+ case 't':
+ return (dictitem_T *)&curtab->tp_winvar;
+ case 'l':
+ return get_funccal_local_var();
+ case 'a':
+ return get_funccal_args_var();
}
return NULL;
}
@@ -8620,8 +9136,8 @@ dictitem_T *find_var_in_ht(hashtab_T *const ht,
/// @param[out] d Scope dictionary.
///
/// @return Scope hashtab, NULL if name is not valid.
-static hashtab_T *find_var_ht_dict(const char *name, const size_t name_len,
- const char **varname, dict_T **d)
+static hashtab_T *find_var_ht_dict(const char *name, const size_t name_len, const char **varname,
+ dict_T **d)
{
hashitem_T *hi;
funccall_T *funccal = get_funccal();
@@ -8692,8 +9208,7 @@ end:
/// prefix.
///
/// @return Scope hashtab, NULL if name is not valid.
-hashtab_T *find_var_ht(const char *name, const size_t name_len,
- const char **varname)
+hashtab_T *find_var_ht(const char *name, const size_t name_len, const char **varname)
{
dict_T *d;
return find_var_ht_dict(name, name_len, varname, &d);
@@ -8706,7 +9221,7 @@ hashtab_T *find_var_ht(const char *name, const size_t name_len,
*/
char_u *get_var_value(const char *const name)
{
- dictitem_T *v;
+ dictitem_T *v;
v = find_var(name, strlen(name), NULL, false);
if (v == NULL) {
@@ -8721,7 +9236,7 @@ char_u *get_var_value(const char *const name)
*/
void new_script_vars(scid_T id)
{
- hashtab_T *ht;
+ hashtab_T *ht;
scriptvar_T *sv;
ga_grow(&ga_scripts, (int)(id - ga_scripts.ga_len));
@@ -8731,8 +9246,9 @@ void new_script_vars(scid_T id)
* at its init value. Also reset "v_dict", it's always the same. */
for (int i = 1; i <= ga_scripts.ga_len; ++i) {
ht = &SCRIPT_VARS(i);
- if (ht->ht_mask == HT_INIT_SIZE - 1)
+ if (ht->ht_mask == HT_INIT_SIZE - 1) {
ht->ht_array = ht->ht_smallarray;
+ }
sv = SCRIPT_SV(i);
sv->sv_var.di_tv.vval.v_dict = &sv->sv_dict;
}
@@ -8791,8 +9307,8 @@ void vars_clear(hashtab_T *ht)
void vars_clear_ext(hashtab_T *ht, int free_val)
{
int todo;
- hashitem_T *hi;
- dictitem_T *v;
+ hashitem_T *hi;
+ dictitem_T *v;
hash_lock(ht);
todo = (int)ht->ht_used;
@@ -8822,7 +9338,7 @@ void vars_clear_ext(hashtab_T *ht, int free_val)
*/
static void delete_var(hashtab_T *ht, hashitem_T *hi)
{
- dictitem_T *di = TV_DICT_HI2DI(hi);
+ dictitem_T *di = TV_DICT_HI2DI(hi);
hash_remove(ht, hi);
tv_clear(&di->di_tv);
@@ -8843,9 +9359,8 @@ static void list_one_var(dictitem_T *v, const char *prefix, int *first)
/// @param[in] name_len Length of the name. May be -1, in this case strlen()
/// will be used.
/// @param[in,out] first When true clear rest of screen and set to false.
-static void list_one_var_a(const char *prefix, const char *name,
- const ptrdiff_t name_len, const int type,
- const char *string, int *first)
+static void list_one_var_a(const char *prefix, const char *name, const ptrdiff_t name_len,
+ const int type, const char *string, int *first)
{
// don't use msg() or msg_attr() to avoid overwriting "v:statusmsg"
msg_start();
@@ -8861,14 +9376,17 @@ static void list_one_var_a(const char *prefix, const char *name,
msg_putchar('*');
} else if (type == VAR_LIST) {
msg_putchar('[');
- if (*string == '[')
+ if (*string == '[') {
++string;
+ }
} else if (type == VAR_DICT) {
msg_putchar('{');
- if (*string == '{')
+ if (*string == '{') {
++string;
- } else
+ }
+ } else {
msg_putchar(' ');
+ }
msg_outtrans((char_u *)string);
@@ -8890,8 +9408,7 @@ static void list_one_var_a(const char *prefix, const char *name,
/// @param[in] name_len Length of the variable name.
/// @param tv Variable value.
/// @param[in] copy True if value in tv is to be copied.
-void set_var(const char *name, const size_t name_len, typval_T *const tv,
- const bool copy)
+void set_var(const char *name, const size_t name_len, typval_T *const tv, const bool copy)
FUNC_ATTR_NONNULL_ALL
{
set_var_const(name, name_len, tv, copy, false);
@@ -8907,13 +9424,12 @@ void set_var(const char *name, const size_t name_len, typval_T *const tv,
/// @param tv Variable value.
/// @param[in] copy True if value in tv is to be copied.
/// @param[in] is_const True if value in tv is to be locked.
-static void set_var_const(const char *name, const size_t name_len,
- typval_T *const tv, const bool copy,
- const bool is_const)
+static void set_var_const(const char *name, const size_t name_len, typval_T *const tv,
+ const bool copy, const bool is_const)
FUNC_ATTR_NONNULL_ALL
{
- dictitem_T *v;
- hashtab_T *ht;
+ dictitem_T *v;
+ hashtab_T *ht;
dict_T *dict;
const char *varname;
@@ -8957,7 +9473,7 @@ static void set_var_const(const char *name, const size_t name_len,
const char *const val = tv_get_string(tv);
// Careful: when assigning to v:errmsg and tv_get_string()
- // causes an error message the variable will alrady be set.
+ // causes an error message the variable will already be set.
if (v->di_tv.vval.v_string == NULL) {
v->di_tv.vval.v_string = (char_u *)xstrdup(val);
}
@@ -9031,7 +9547,10 @@ static void set_var_const(const char *name, const size_t name_len,
}
if (is_const) {
- tv_item_lock(&v->di_tv, 1, true);
+ // Like :lockvar! name: lock the value and what it contains, but only
+ // if the reference count is up to one. That locks only literal
+ // values.
+ tv_item_lock(&v->di_tv, DICT_MAXNEST, true, true);
}
}
@@ -9054,8 +9573,7 @@ static void set_var_const(const char *name, const size_t name_len,
///
/// @return True if variable is read-only: either always or in sandbox when
/// sandbox is enabled, false otherwise.
-bool var_check_ro(const int flags, const char *name,
- size_t name_len)
+bool var_check_ro(const int flags, const char *name, size_t name_len)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
const char *error_message = NULL;
@@ -9098,8 +9616,7 @@ bool var_check_ro(const int flags, const char *name,
/// gettext.
///
/// @return True if variable is fixed, false otherwise.
-bool var_check_fixed(const int flags, const char *name,
- size_t name_len)
+bool var_check_fixed(const int flags, const char *name, size_t name_len)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
if (flags & DI_FLAGS_FIX) {
@@ -9183,11 +9700,8 @@ bool valid_varname(const char *varname)
/// a copy with (`copy[0] isnot copy[1]`), with non-zero it
/// will emit a copy with (`copy[0] is copy[1]`) like in the
/// original list. Not used when deep is false.
-int var_item_copy(const vimconv_T *const conv,
- typval_T *const from,
- typval_T *const to,
- const bool deep,
- const int copyID)
+int var_item_copy(const vimconv_T *const conv, typval_T *const from, typval_T *const to,
+ const bool deep, const int copyID)
FUNC_ATTR_NONNULL_ARG(2, 3)
{
static int recurse = 0;
@@ -9219,7 +9733,7 @@ int var_item_copy(const vimconv_T *const conv,
from->vval.v_string,
NULL))
== NULL) {
- to->vval.v_string = (char_u *) xstrdup((char *) from->vval.v_string);
+ to->vval.v_string = (char_u *)xstrdup((char *)from->vval.v_string);
}
}
break;
@@ -9239,6 +9753,9 @@ int var_item_copy(const vimconv_T *const conv,
ret = FAIL;
}
break;
+ case VAR_BLOB:
+ tv_blob_copy(from, to);
+ break;
case VAR_DICT:
to->v_type = VAR_DICT;
to->v_lock = VAR_UNLOCKED;
@@ -9264,20 +9781,22 @@ int var_item_copy(const vimconv_T *const conv,
}
/*
- * ":echo expr1 ..." print each argument separated with a space, add a
- * newline at the end.
- * ":echon expr1 ..." print each argument plain.
+ * ":echo expr1 ..." print each argument separated with a space, add a
+ * newline at the end.
+ * ":echon expr1 ..." print each argument plain.
*/
void ex_echo(exarg_T *eap)
{
- char_u *arg = eap->arg;
+ char_u *arg = eap->arg;
typval_T rettv;
bool atstart = true;
bool need_clear = true;
const int did_emsg_before = did_emsg;
+ const int called_emsg_before = called_emsg;
- if (eap->skip)
+ if (eap->skip) {
++emsg_skip;
+ }
while (*arg != NUL && *arg != '|' && *arg != '\n' && !got_int) {
// If eval1() causes an error message the text from the command may
// still need to be cleared. E.g., "echo 22,44".
@@ -9289,7 +9808,8 @@ void ex_echo(exarg_T *eap)
// Report the invalid expression unless the expression evaluation
// has been cancelled due to an aborting error, an interrupt, or an
// exception.
- if (!aborting() && did_emsg == did_emsg_before) {
+ if (!aborting() && did_emsg == did_emsg_before
+ && called_emsg == called_emsg_before) {
EMSG2(_(e_invexpr2), p);
}
need_clr_eos = false;
@@ -9347,9 +9867,9 @@ void ex_echohl(exarg_T *eap)
}
/*
- * ":execute expr1 ..." execute the result of an expression.
- * ":echomsg expr1 ..." Print a message
- * ":echoerr expr1 ..." Print an error
+ * ":execute expr1 ..." execute the result of an expression.
+ * ":echomsg expr1 ..." Print a message
+ * ":echoerr expr1 ..." Print an error
* Each gets spaces around each argument and a newline at the end for
* echo commands
*/
@@ -9363,8 +9883,9 @@ void ex_execute(exarg_T *eap)
ga_init(&ga, 1, 80);
- if (eap->skip)
+ if (eap->skip) {
++emsg_skip;
+ }
while (*arg != NUL && *arg != '|' && *arg != '\n') {
ret = eval1_emsg(&arg, &rettv, !eap->skip);
if (ret == FAIL) {
@@ -9410,17 +9931,20 @@ void ex_execute(exarg_T *eap)
save_did_emsg = did_emsg;
msg_ext_set_kind("echoerr");
EMSG((char_u *)ga.ga_data);
- if (!force_abort)
+ if (!force_abort) {
did_emsg = save_did_emsg;
- } else if (eap->cmdidx == CMD_execute)
+ }
+ } else if (eap->cmdidx == CMD_execute) {
do_cmdline((char_u *)ga.ga_data,
- eap->getline, eap->cookie, DOCMD_NOWAIT|DOCMD_VERBOSE);
+ eap->getline, eap->cookie, DOCMD_NOWAIT|DOCMD_VERBOSE);
+ }
}
ga_clear(&ga);
- if (eap->skip)
+ if (eap->skip) {
--emsg_skip;
+ }
eap->nextcmd = check_nextcmd(arg);
}
@@ -9498,10 +10022,10 @@ void func_do_profile(ufunc_T *fp)
*/
void func_dump_profile(FILE *fd)
{
- hashitem_T *hi;
+ hashitem_T *hi;
int todo;
- ufunc_T *fp;
- ufunc_T **sorttab;
+ ufunc_T *fp;
+ ufunc_T **sorttab;
int st_len = 0;
todo = (int)func_hashtab.ht_used;
@@ -9527,7 +10051,7 @@ void func_dump_profile(FILE *fd)
bool should_free;
const LastSet last_set = (LastSet){
.script_ctx = fp->uf_script_ctx,
- .channel_id = 0,
+ .channel_id = 0,
};
char_u *p = get_scriptname(last_set, &should_free);
fprintf(fd, " Defined: %s:%" PRIdLINENR "\n",
@@ -9547,10 +10071,11 @@ void func_dump_profile(FILE *fd)
fprintf(fd, "count total (s) self (s)\n");
for (int i = 0; i < fp->uf_lines.ga_len; ++i) {
- if (FUNCLINE(fp, i) == NULL)
+ if (FUNCLINE(fp, i) == NULL) {
continue;
+ }
prof_func_line(fd, fp->uf_tml_count[i],
- &fp->uf_tml_total[i], &fp->uf_tml_self[i], TRUE);
+ &fp->uf_tml_total[i], &fp->uf_tml_self[i], TRUE);
fprintf(fd, "%s\n", FUNCLINE(fp, i));
}
fprintf(fd, "\n");
@@ -9560,65 +10085,58 @@ void func_dump_profile(FILE *fd)
if (st_len > 0) {
qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *),
- prof_total_cmp);
+ prof_total_cmp);
prof_sort_list(fd, sorttab, st_len, "TOTAL", FALSE);
qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *),
- prof_self_cmp);
+ prof_self_cmp);
prof_sort_list(fd, sorttab, st_len, "SELF", TRUE);
}
xfree(sorttab);
}
-static void
-prof_sort_list(
- FILE *fd,
- ufunc_T **sorttab,
- int st_len,
- char *title,
- int prefer_self // when equal print only self time
-)
+/// @param prefer_self when equal print only self time
+static void prof_sort_list(FILE *fd, ufunc_T **sorttab, int st_len, char *title, int prefer_self)
{
int i;
- ufunc_T *fp;
+ ufunc_T *fp;
fprintf(fd, "FUNCTIONS SORTED ON %s TIME\n", title);
fprintf(fd, "count total (s) self (s) function\n");
for (i = 0; i < 20 && i < st_len; ++i) {
fp = sorttab[i];
prof_func_line(fd, fp->uf_tm_count, &fp->uf_tm_total, &fp->uf_tm_self,
- prefer_self);
- if (fp->uf_name[0] == K_SPECIAL)
+ prefer_self);
+ if (fp->uf_name[0] == K_SPECIAL) {
fprintf(fd, " <SNR>%s()\n", fp->uf_name + 3);
- else
+ } else {
fprintf(fd, " %s()\n", fp->uf_name);
+ }
}
fprintf(fd, "\n");
}
-/*
- * Print the count and times for one function or function line.
- */
-static void prof_func_line(
- FILE *fd,
- int count,
- proftime_T *total,
- proftime_T *self,
- int prefer_self // when equal print only self time
-)
+/// Print the count and times for one function or function line.
+///
+/// @param prefer_self when equal print only self time
+static void prof_func_line(FILE *fd, int count, proftime_T *total, proftime_T *self,
+ int prefer_self)
{
if (count > 0) {
fprintf(fd, "%5d ", count);
- if (prefer_self && profile_equal(*total, *self))
+ if (prefer_self && profile_equal(*total, *self)) {
fprintf(fd, " ");
- else
+ } else {
fprintf(fd, "%s ", profile_msg(*total));
- if (!prefer_self && profile_equal(*total, *self))
+ }
+ if (!prefer_self && profile_equal(*total, *self)) {
fprintf(fd, " ");
- else
+ } else {
fprintf(fd, "%s ", profile_msg(*self));
- } else
+ }
+ } else {
fprintf(fd, " ");
+ }
}
/*
@@ -9676,8 +10194,7 @@ char *autoload_name(const char *const name, const size_t name_len)
/// @param[in] reload If true, load script again when already loaded.
///
/// @return true if a package was loaded.
-bool script_autoload(const char *const name, const size_t name_len,
- const bool reload)
+bool script_autoload(const char *const name, const size_t name_len, const bool reload)
{
// If there is no '#' after name[0] there is no package name.
const char *p = memchr(name, AUTOLOAD_CHAR, name_len);
@@ -9724,8 +10241,8 @@ bool script_autoload(const char *const name, const size_t name_len,
*/
void func_line_start(void *cookie)
{
- funccall_T *fcp = (funccall_T *)cookie;
- ufunc_T *fp = fcp->func;
+ funccall_T *fcp = (funccall_T *)cookie;
+ ufunc_T *fp = fcp->func;
if (fp->uf_profiling && sourcing_lnum >= 1
&& sourcing_lnum <= fp->uf_lines.ga_len) {
@@ -9746,11 +10263,12 @@ void func_line_start(void *cookie)
*/
void func_line_exec(void *cookie)
{
- funccall_T *fcp = (funccall_T *)cookie;
- ufunc_T *fp = fcp->func;
+ funccall_T *fcp = (funccall_T *)cookie;
+ ufunc_T *fp = fcp->func;
- if (fp->uf_profiling && fp->uf_tml_idx >= 0)
+ if (fp->uf_profiling && fp->uf_tml_idx >= 0) {
fp->uf_tml_execed = TRUE;
+ }
}
/*
@@ -9758,8 +10276,8 @@ void func_line_exec(void *cookie)
*/
void func_line_end(void *cookie)
{
- funccall_T *fcp = (funccall_T *)cookie;
- ufunc_T *fp = fcp->func;
+ funccall_T *fcp = (funccall_T *)cookie;
+ ufunc_T *fp = fcp->func;
if (fp->uf_profiling && fp->uf_tml_idx >= 0) {
if (fp->uf_tml_execed) {
@@ -9770,7 +10288,7 @@ void func_line_end(void *cookie)
profile_add(fp->uf_tml_total[fp->uf_tml_idx], fp->uf_tml_start);
fp->uf_tml_self[fp->uf_tml_idx] =
profile_self(fp->uf_tml_self[fp->uf_tml_idx], fp->uf_tml_start,
- fp->uf_tml_children);
+ fp->uf_tml_children);
}
fp->uf_tml_idx = -1;
}
@@ -9781,10 +10299,11 @@ static var_flavour_T var_flavour(char_u *varname)
char_u *p = varname;
if (ASCII_ISUPPER(*p)) {
- while (*(++p))
+ while (*(++p)) {
if (ASCII_ISLOWER(*p)) {
return VAR_FLAVOUR_SESSION;
}
+ }
return VAR_FLAVOUR_SHADA;
} else {
return VAR_FLAVOUR_DEFAULT;
@@ -9802,26 +10321,26 @@ static var_flavour_T var_flavour(char_u *varname)
///
/// @return Pointer that needs to be passed to next `var_shada_iter` invocation
/// or NULL to indicate that iteration is over.
-const void *var_shada_iter(const void *const iter, const char **const name,
- typval_T *rettv, var_flavour_T flavour)
+const void *var_shada_iter(const void *const iter, const char **const name, typval_T *rettv,
+ var_flavour_T flavour)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ARG(2, 3)
{
const hashitem_T *hi;
const hashitem_T *hifirst = globvarht.ht_array;
- const size_t hinum = (size_t) globvarht.ht_mask + 1;
+ const size_t hinum = (size_t)globvarht.ht_mask + 1;
*name = NULL;
if (iter == NULL) {
hi = globvarht.ht_array;
- while ((size_t) (hi - hifirst) < hinum
+ while ((size_t)(hi - hifirst) < hinum
&& (HASHITEM_EMPTY(hi)
|| !(var_flavour(hi->hi_key) & flavour))) {
hi++;
}
- if ((size_t) (hi - hifirst) == hinum) {
+ if ((size_t)(hi - hifirst) == hinum) {
return NULL;
}
} else {
- hi = (const hashitem_T *) iter;
+ hi = (const hashitem_T *)iter;
}
*name = (char *)TV_DICT_HI2DI(hi)->di_key;
tv_copy(&TV_DICT_HI2DI(hi)->di_tv, rettv);
@@ -9850,9 +10369,8 @@ int store_session_globals(FILE *fd)
&& var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) {
// Escape special characters with a backslash. Turn a LF and
// CR into \n and \r.
- char_u *const p = vim_strsave_escaped(
- (const char_u *)tv_get_string(&this_var->di_tv),
- (const char_u *)"\\\"\n\r");
+ char_u *const p = vim_strsave_escaped((const char_u *)tv_get_string(&this_var->di_tv),
+ (const char_u *)"\\\"\n\r");
for (char_u *t = p; *t != NUL; t++) {
if (*t == '\n') {
*t = 'n';
@@ -9863,10 +10381,10 @@ int store_session_globals(FILE *fd)
if ((fprintf(fd, "let %s = %c%s%c",
this_var->di_key,
((this_var->di_tv.v_type == VAR_STRING) ? '"'
- : ' '),
+ : ' '),
p,
((this_var->di_tv.v_type == VAR_STRING) ? '"'
- : ' ')) < 0)
+ : ' ')) < 0)
|| put_eol(fd) == FAIL) {
xfree(p);
return FAIL;
@@ -9933,26 +10451,24 @@ void reset_v_option_vars(void)
set_vim_var_string(VV_OPTION_TYPE, NULL, -1);
}
-/*
- * Adjust a filename, according to a string of modifiers.
- * *fnamep must be NUL terminated when called. When returning, the length is
- * determined by *fnamelen.
- * Returns VALID_ flags or -1 for failure.
- * When there is an error, *fnamep is set to NULL.
- */
-int
-modify_fname(
- char_u *src, // string with modifiers
- bool tilde_file, // "~" is a file name, not $HOME
- size_t *usedlen, // characters after src that are used
- char_u **fnamep, // file name so far
- char_u **bufp, // buffer for allocated file name or NULL
- size_t *fnamelen // length of fnamep
-)
+/// Adjust a filename, according to a string of modifiers.
+/// *fnamep must be NUL terminated when called. When returning, the length is
+/// determined by *fnamelen.
+/// Returns VALID_ flags or -1 for failure.
+/// When there is an error, *fnamep is set to NULL.
+///
+/// @param src string with modifiers
+/// @param tilde_file "~" is a file name, not $HOME
+/// @param usedlen characters after src that are used
+/// @param fnamep file name so far
+/// @param bufp buffer for allocated file name or NULL
+/// @param fnamelen length of fnamep
+int modify_fname(char_u *src, bool tilde_file, size_t *usedlen, char_u **fnamep, char_u **bufp,
+ size_t *fnamelen)
{
int valid = 0;
- char_u *tail;
- char_u *s, *p, *pbuf;
+ char_u *tail;
+ char_u *s, *p, *pbuf;
char_u dirname[MAXPATHL];
int c;
int has_fullname = 0;
@@ -9974,13 +10490,13 @@ repeat:
# endif
|| (*fnamep)[1] == NUL)
#endif
- && !(tilde_file && (*fnamep)[1] == NUL)
- ) {
+ && !(tilde_file && (*fnamep)[1] == NUL)) {
*fnamep = expand_env_save(*fnamep);
xfree(*bufp); // free any allocated file name
*bufp = *fnamep;
- if (*fnamep == NULL)
+ if (*fnamep == NULL) {
return -1;
+ }
}
// When "/." or "/.." is used: force expansion to get rid of it.
@@ -10000,8 +10516,9 @@ repeat:
*fnamep = (char_u *)FullName_save((char *)(*fnamep), *p != NUL);
xfree(*bufp); // free any allocated file name
*bufp = *fnamep;
- if (*fnamep == NULL)
+ if (*fnamep == NULL) {
return -1;
+ }
}
// Append a path separator to a directory.
@@ -10010,8 +10527,9 @@ repeat:
*fnamep = vim_strnsave(*fnamep, STRLEN(*fnamep) + 2);
xfree(*bufp); // free any allocated file name
*bufp = *fnamep;
- if (*fnamep == NULL)
+ if (*fnamep == NULL) {
return -1;
+ }
add_pathsep((char *)*fnamep);
}
}
@@ -10028,12 +10546,14 @@ repeat:
pbuf = NULL;
// Need full path first (use expand_env() to remove a "~/")
if (!has_fullname) {
- if (c == '.' && **fnamep == '~')
+ if (c == '.' && **fnamep == '~') {
p = pbuf = expand_env_save(*fnamep);
- else
+ } else {
p = pbuf = (char_u *)FullName_save((char *)*fnamep, FALSE);
- } else
+ }
+ } else {
p = *fnamep;
+ }
has_fullname = 0;
@@ -10160,7 +10680,7 @@ repeat:
&& (src[*usedlen + 1] == 's'
|| (src[*usedlen + 1] == 'g' && src[*usedlen + 2] == 's'))) {
int sep;
- char_u *flags;
+ char_u *flags;
int didit = FALSE;
flags = (char_u *)"";
@@ -10224,17 +10744,16 @@ repeat:
/// When "sub" is NULL "expr" is used, must be a VAR_FUNC or VAR_PARTIAL.
/// "flags" can be "g" to do a global substitute.
/// Returns an allocated string, NULL for error.
-char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub,
- typval_T *expr, char_u *flags)
+char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub, typval_T *expr, char_u *flags)
{
int sublen;
regmatch_T regmatch;
int do_all;
- char_u *tail;
- char_u *end;
+ char_u *tail;
+ char_u *end;
garray_T ga;
- char_u *save_cpo;
- char_u *zero_width = NULL;
+ char_u *save_cpo;
+ char_u *zero_width = NULL;
// Make 'cpoptions' empty, so that the 'l' flag doesn't work here
save_cpo = p_cpo;
@@ -10270,7 +10789,7 @@ char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub,
// - The text after the match.
sublen = vim_regsub(&regmatch, sub, expr, tail, false, true, false);
ga_grow(&ga, (int)((end - tail) + sublen -
- (regmatch.endp[0] - regmatch.startp[0])));
+ (regmatch.endp[0] - regmatch.startp[0])));
// copy the text up to where the match is
int i = (int)(regmatch.startp[0] - tail);
@@ -10280,14 +10799,17 @@ char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub,
+ ga.ga_len + i, true, true, false);
ga.ga_len += i + sublen - 1;
tail = regmatch.endp[0];
- if (*tail == NUL)
+ if (*tail == NUL) {
break;
- if (!do_all)
+ }
+ if (!do_all) {
break;
+ }
}
- if (ga.ga_data != NULL)
+ if (ga.ga_data != NULL) {
STRCPY((char *)ga.ga_data + ga.ga_len, tail);
+ }
vim_regfree(regmatch.regprog);
}
@@ -10307,9 +10829,7 @@ char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub,
/// common code for getting job callbacks for jobstart, termopen and rpcstart
///
/// @return true/false on success/failure.
-bool common_job_callbacks(dict_T *vopts,
- CallbackReader *on_stdout,
- CallbackReader *on_stderr,
+bool common_job_callbacks(dict_T *vopts, CallbackReader *on_stdout, CallbackReader *on_stderr,
Callback *on_exit)
{
if (tv_dict_get_callback(vopts, S_LEN("on_stdout"), &on_stdout->cb)
@@ -10370,8 +10890,7 @@ void script_host_eval(char *name, typval_T *argvars, typval_T *rettv)
/// @param discard Clears the value returned by the provider and returns
/// an empty typval_T.
-typval_T eval_call_provider(char *provider, char *method, list_T *arguments,
- bool discard)
+typval_T eval_call_provider(char *provider, char *method, list_T *arguments, bool discard)
{
if (!eval_has_provider(provider)) {
emsgf("E319: No \"%s\" provider found. Run \":checkhealth provider\"",
@@ -10410,19 +10929,11 @@ typval_T eval_call_provider(char *provider, char *method, list_T *arguments,
typval_T rettv = { .v_type = VAR_UNKNOWN, .v_lock = VAR_UNLOCKED };
tv_list_ref(arguments);
- int dummy;
- (void)call_func((const char_u *)func,
- name_len,
- &rettv,
- 2,
- argvars,
- NULL,
- curwin->w_cursor.lnum,
- curwin->w_cursor.lnum,
- &dummy,
- true,
- NULL,
- NULL);
+ funcexe_T funcexe = FUNCEXE_INIT;
+ funcexe.firstline = curwin->w_cursor.lnum;
+ funcexe.lastline = curwin->w_cursor.lnum;
+ funcexe.evaluate = true;
+ (void)call_func((const char_u *)func, name_len, &rettv, 2, argvars, &funcexe);
tv_list_unref(arguments);
// Restore caller scope information
@@ -10542,59 +11053,59 @@ void ex_checkhealth(exarg_T *eap)
void invoke_prompt_callback(void)
{
- typval_T rettv;
- typval_T argv[2];
- char_u *text;
- char_u *prompt;
- linenr_T lnum = curbuf->b_ml.ml_line_count;
-
- // Add a new line for the prompt before invoking the callback, so that
- // text can always be inserted above the last line.
- ml_append(lnum, (char_u *)"", 0, false);
- curwin->w_cursor.lnum = lnum + 1;
- curwin->w_cursor.col = 0;
-
- if (curbuf->b_prompt_callback.type == kCallbackNone) {
- return;
- }
- text = ml_get(lnum);
- prompt = prompt_text();
- if (STRLEN(text) >= STRLEN(prompt)) {
- text += STRLEN(prompt);
- }
- argv[0].v_type = VAR_STRING;
- argv[0].vval.v_string = vim_strsave(text);
- argv[1].v_type = VAR_UNKNOWN;
+ typval_T rettv;
+ typval_T argv[2];
+ char_u *text;
+ char_u *prompt;
+ linenr_T lnum = curbuf->b_ml.ml_line_count;
+
+ // Add a new line for the prompt before invoking the callback, so that
+ // text can always be inserted above the last line.
+ ml_append(lnum, (char_u *)"", 0, false);
+ curwin->w_cursor.lnum = lnum + 1;
+ curwin->w_cursor.col = 0;
+
+ if (curbuf->b_prompt_callback.type == kCallbackNone) {
+ return;
+ }
+ text = ml_get(lnum);
+ prompt = prompt_text();
+ if (STRLEN(text) >= STRLEN(prompt)) {
+ text += STRLEN(prompt);
+ }
+ argv[0].v_type = VAR_STRING;
+ argv[0].vval.v_string = vim_strsave(text);
+ argv[1].v_type = VAR_UNKNOWN;
- callback_call(&curbuf->b_prompt_callback, 1, argv, &rettv);
- tv_clear(&argv[0]);
- tv_clear(&rettv);
+ callback_call(&curbuf->b_prompt_callback, 1, argv, &rettv);
+ tv_clear(&argv[0]);
+ tv_clear(&rettv);
}
// Return true When the interrupt callback was invoked.
bool invoke_prompt_interrupt(void)
{
- typval_T rettv;
- typval_T argv[1];
+ typval_T rettv;
+ typval_T argv[1];
- if (curbuf->b_prompt_interrupt.type == kCallbackNone) {
- return false;
- }
- argv[0].v_type = VAR_UNKNOWN;
+ if (curbuf->b_prompt_interrupt.type == kCallbackNone) {
+ return false;
+ }
+ argv[0].v_type = VAR_UNKNOWN;
- got_int = false; // don't skip executing commands
- callback_call(&curbuf->b_prompt_interrupt, 0, argv, &rettv);
- tv_clear(&rettv);
- return true;
+ got_int = false; // don't skip executing commands
+ callback_call(&curbuf->b_prompt_interrupt, 0, argv, &rettv);
+ tv_clear(&rettv);
+ return true;
}
-// Compare "typ1" and "typ2". Put the result in "typ1".
-int typval_compare(
- typval_T *typ1, // first operand
- typval_T *typ2, // second operand
- exprtype_T type, // operator
- bool ic // ignore case
-)
+/// Compare "typ1" and "typ2". Put the result in "typ1".
+///
+/// @param typ1 first operand
+/// @param typ2 second operand
+/// @param type operator
+/// @param ic ignore case
+int typval_compare(typval_T *typ1, typval_T *typ2, exprtype_T type, bool ic)
FUNC_ATTR_NONNULL_ALL
{
varnumber_T n1, n2;
@@ -10604,10 +11115,33 @@ int typval_compare(
// For "is" a different type always means false, for "notis"
// it means true.
n1 = type == EXPR_ISNOT;
+ } else if (typ1->v_type == VAR_BLOB || typ2->v_type == VAR_BLOB) {
+ if (type_is) {
+ n1 = typ1->v_type == typ2->v_type
+ && typ1->vval.v_blob == typ2->vval.v_blob;
+ if (type == EXPR_ISNOT) {
+ n1 = !n1;
+ }
+ } else if (typ1->v_type != typ2->v_type
+ || (type != EXPR_EQUAL && type != EXPR_NEQUAL)) {
+ if (typ1->v_type != typ2->v_type) {
+ EMSG(_("E977: Can only compare Blob with Blob"));
+ } else {
+ EMSG(_(e_invalblob));
+ }
+ tv_clear(typ1);
+ return FAIL;
+ } else {
+ // Compare two Blobs for being equal or unequal.
+ n1 = tv_blob_equal(typ1->vval.v_blob, typ2->vval.v_blob);
+ if (type == EXPR_NEQUAL) {
+ n1 = !n1;
+ }
+ }
} else if (typ1->v_type == VAR_LIST || typ2->v_type == VAR_LIST) {
if (type_is) {
n1 = typ1->v_type == typ2->v_type
- && typ1->vval.v_list == typ2->vval.v_list;
+ && typ1->vval.v_list == typ2->vval.v_list;
if (type == EXPR_ISNOT) {
n1 = !n1;
}
@@ -10630,7 +11164,7 @@ int typval_compare(
} else if (typ1->v_type == VAR_DICT || typ2->v_type == VAR_DICT) {
if (type_is) {
n1 = typ1->v_type == typ2->v_type
- && typ1->vval.v_dict == typ2->vval.v_dict;
+ && typ1->vval.v_dict == typ2->vval.v_dict;
if (type == EXPR_ISNOT) {
n1 = !n1;
}
@@ -10685,17 +11219,24 @@ int typval_compare(
const float_T f2 = tv_get_float(typ2);
n1 = false;
switch (type) {
- case EXPR_IS:
- case EXPR_EQUAL: n1 = f1 == f2; break;
- case EXPR_ISNOT:
- case EXPR_NEQUAL: n1 = f1 != f2; break;
- case EXPR_GREATER: n1 = f1 > f2; break;
- case EXPR_GEQUAL: n1 = f1 >= f2; break;
- case EXPR_SMALLER: n1 = f1 < f2; break;
- case EXPR_SEQUAL: n1 = f1 <= f2; break;
- case EXPR_UNKNOWN:
- case EXPR_MATCH:
- case EXPR_NOMATCH: break; // avoid gcc warning
+ case EXPR_IS:
+ case EXPR_EQUAL:
+ n1 = f1 == f2; break;
+ case EXPR_ISNOT:
+ case EXPR_NEQUAL:
+ n1 = f1 != f2; break;
+ case EXPR_GREATER:
+ n1 = f1 > f2; break;
+ case EXPR_GEQUAL:
+ n1 = f1 >= f2; break;
+ case EXPR_SMALLER:
+ n1 = f1 < f2; break;
+ case EXPR_SEQUAL:
+ n1 = f1 <= f2; break;
+ case EXPR_UNKNOWN:
+ case EXPR_MATCH:
+ case EXPR_NOMATCH:
+ break; // avoid gcc warning
}
} else if ((typ1->v_type == VAR_NUMBER || typ2->v_type == VAR_NUMBER)
&& type != EXPR_MATCH && type != EXPR_NOMATCH) {
@@ -10704,17 +11245,24 @@ int typval_compare(
n1 = tv_get_number(typ1);
n2 = tv_get_number(typ2);
switch (type) {
- case EXPR_IS:
- case EXPR_EQUAL: n1 = n1 == n2; break;
- case EXPR_ISNOT:
- case EXPR_NEQUAL: n1 = n1 != n2; break;
- case EXPR_GREATER: n1 = n1 > n2; break;
- case EXPR_GEQUAL: n1 = n1 >= n2; break;
- case EXPR_SMALLER: n1 = n1 < n2; break;
- case EXPR_SEQUAL: n1 = n1 <= n2; break;
- case EXPR_UNKNOWN:
- case EXPR_MATCH:
- case EXPR_NOMATCH: break; // avoid gcc warning
+ case EXPR_IS:
+ case EXPR_EQUAL:
+ n1 = n1 == n2; break;
+ case EXPR_ISNOT:
+ case EXPR_NEQUAL:
+ n1 = n1 != n2; break;
+ case EXPR_GREATER:
+ n1 = n1 > n2; break;
+ case EXPR_GEQUAL:
+ n1 = n1 >= n2; break;
+ case EXPR_SMALLER:
+ n1 = n1 < n2; break;
+ case EXPR_SEQUAL:
+ n1 = n1 <= n2; break;
+ case EXPR_UNKNOWN:
+ case EXPR_MATCH:
+ case EXPR_NOMATCH:
+ break; // avoid gcc warning
}
} else {
char buf1[NUMBUFLEN];
@@ -10729,23 +11277,30 @@ int typval_compare(
}
n1 = false;
switch (type) {
- case EXPR_IS:
- case EXPR_EQUAL: n1 = i == 0; break;
- case EXPR_ISNOT:
- case EXPR_NEQUAL: n1 = i != 0; break;
- case EXPR_GREATER: n1 = i > 0; break;
- case EXPR_GEQUAL: n1 = i >= 0; break;
- case EXPR_SMALLER: n1 = i < 0; break;
- case EXPR_SEQUAL: n1 = i <= 0; break;
-
- case EXPR_MATCH:
- case EXPR_NOMATCH:
- n1 = pattern_match((char_u *)s2, (char_u *)s1, ic);
- if (type == EXPR_NOMATCH) {
- n1 = !n1;
- }
- break;
- case EXPR_UNKNOWN: break; // avoid gcc warning
+ case EXPR_IS:
+ case EXPR_EQUAL:
+ n1 = i == 0; break;
+ case EXPR_ISNOT:
+ case EXPR_NEQUAL:
+ n1 = i != 0; break;
+ case EXPR_GREATER:
+ n1 = i > 0; break;
+ case EXPR_GEQUAL:
+ n1 = i >= 0; break;
+ case EXPR_SMALLER:
+ n1 = i < 0; break;
+ case EXPR_SEQUAL:
+ n1 = i <= 0; break;
+
+ case EXPR_MATCH:
+ case EXPR_NOMATCH:
+ n1 = pattern_match((char_u *)s2, (char_u *)s1, ic);
+ if (type == EXPR_NOMATCH) {
+ n1 = !n1;
+ }
+ break;
+ case EXPR_UNKNOWN:
+ break; // avoid gcc warning
}
}
tv_clear(typ1);
@@ -10780,7 +11335,9 @@ bool var_exists(const char *var)
n = get_var_tv(name, len, &tv, NULL, false, true) == OK;
if (n) {
// Handle d.key, l[idx], f(expr).
- n = handle_subscript(&var, &tv, true, false) == OK;
+ n = handle_subscript(&var, &tv, true, false, (const char_u *)name,
+ (const char_u **)&name)
+ == OK;
if (n) {
tv_clear(&tv);
}
diff --git a/src/nvim/eval.h b/src/nvim/eval.h
index 41120b3c78..2452a0a8c8 100644
--- a/src/nvim/eval.h
+++ b/src/nvim/eval.h
@@ -63,6 +63,7 @@ typedef struct lval_S {
dict_T *ll_dict; ///< The Dictionary or NULL.
dictitem_T *ll_di; ///< The dictitem or NULL.
char_u *ll_newkey; ///< New key for Dict in allocated memory or NULL.
+ blob_T *ll_blob; ///< The Blob or NULL.
} lval_T;
/// enum used by var_flavour()
@@ -154,6 +155,7 @@ typedef enum {
VV_TYPE_DICT,
VV_TYPE_FLOAT,
VV_TYPE_BOOL,
+ VV_TYPE_BLOB,
VV_EVENT,
VV_ECHOSPACE,
VV_ARGV,
@@ -165,6 +167,7 @@ typedef enum {
VV__NULL_STRING, // String with NULL value. For test purposes only.
VV__NULL_LIST, // List with NULL value. For test purposes only.
VV__NULL_DICT, // Dictionary with NULL value. For test purposes only.
+ VV__NULL_BLOB, // Blob with NULL value. For test purposes only.
VV_LUA,
} VimVarIndex;
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua
index 33c6fae5cf..c6ac27b269 100644
--- a/src/nvim/eval.lua
+++ b/src/nvim/eval.lua
@@ -5,6 +5,9 @@
-- args Number of arguments, list with maximum and minimum number of arguments
-- or list with a minimum number of arguments only. Defaults to zero
-- arguments.
+-- base For methods: the argument to use as the base argument (1-indexed):
+-- base->method()
+-- Defaults to BASE_NONE (function cannot be used as a method).
-- func Name of the C function which implements the VimL function. Defaults to
-- `f_{funcname}`.
@@ -12,111 +15,115 @@ local varargs = function(nr)
return {nr}
end
+-- Usable with the base key: use the last function argument as the method base.
+-- Value is from funcs.h file. "BASE_" prefix is omitted.
+local LAST = "BASE_LAST"
+
return {
funcs={
- abs={args=1},
- acos={args=1, func="float_op_wrapper", data="&acos"}, -- WJMc
- add={args=2},
- ['and']={args=2},
+ abs={args=1, base=1},
+ acos={args=1, base=1, func="float_op_wrapper", data="&acos"}, -- WJMc
+ add={args=2, base=1},
+ ['and']={args=2, base=1},
api_info={},
- append={args=2},
- appendbufline={args=3},
+ append={args=2, base=LAST},
+ appendbufline={args=3, base=LAST},
argc={args={0, 1}},
argidx={},
arglistid={args={0, 2}},
argv={args={0, 2}},
- asin={args=1, func="float_op_wrapper", data="&asin"}, -- WJMc
- assert_beeps={args={1}},
- assert_equal={args={2, 3}},
- assert_equalfile={args={2, 3}},
+ asin={args=1, base=1, func="float_op_wrapper", data="&asin"}, -- WJMc
+ assert_beeps={args={1}, base=1},
+ assert_equal={args={2, 3}, base=2},
+ assert_equalfile={args={2, 3}, base=1},
assert_exception={args={1, 2}},
- assert_fails={args={1, 3}},
- assert_false={args={1, 2}},
- assert_inrange={args={3, 4}},
- assert_match={args={2, 3}},
+ assert_fails={args={1, 3}, base=1},
+ assert_false={args={1, 2}, base=1},
+ assert_inrange={args={3, 4}, base=3},
+ assert_match={args={2, 3}, base=2},
assert_nobeep={args={1}},
- assert_notequal={args={2, 3}},
- assert_notmatch={args={2, 3}},
- assert_report={args=1},
- assert_true={args={1, 2}},
- atan={args=1, func="float_op_wrapper", data="&atan"},
- atan2={args=2},
+ assert_notequal={args={2, 3}, base=2},
+ assert_notmatch={args={2, 3}, base=2},
+ assert_report={args=1, base=1},
+ assert_true={args={1, 2}, base=1},
+ atan={args=1, base=1, func="float_op_wrapper", data="&atan"},
+ atan2={args=2, base=1},
browse={args=4},
browsedir={args=2},
- bufadd={args=1},
- bufexists={args=1},
- buffer_exists={args=1, func='f_bufexists'}, -- obsolete
+ bufadd={args=1, base=1},
+ bufexists={args=1, base=1},
+ buffer_exists={args=1, base=1, func='f_bufexists'}, -- obsolete
buffer_name={args={0, 1}, func='f_bufname'}, -- obsolete
buffer_number={args={0, 1}, func='f_bufnr'}, -- obsolete
- buflisted={args=1},
- bufload={args=1},
- bufloaded={args=1},
- bufname={args={0, 1}},
- bufnr={args={0, 2}},
- bufwinid={args=1},
- bufwinnr={args=1},
- byte2line={args=1},
- byteidx={args=2},
- byteidxcomp={args=2},
- call={args={2, 3}},
- ceil={args=1, func="float_op_wrapper", data="&ceil"},
+ buflisted={args=1, base=1},
+ bufload={args=1, base=1},
+ bufloaded={args=1, base=1},
+ bufname={args={0, 1}, base=1},
+ bufnr={args={0, 2}, base=1},
+ bufwinid={args=1, base=1},
+ bufwinnr={args=1, base=1},
+ byte2line={args=1, base=1},
+ byteidx={args=2, base=1},
+ byteidxcomp={args=2, base=1},
+ call={args={2, 3}, base=1},
+ ceil={args=1, base=1, func="float_op_wrapper", data="&ceil"},
changenr={},
chanclose={args={1, 2}},
chansend={args=2},
- char2nr={args={1, 2}},
+ char2nr={args={1, 2}, base=1},
charidx={args={2, 3}},
- cindent={args=1},
- clearmatches={args={0, 1}},
- col={args=1},
- complete={args=2},
- complete_add={args=1},
+ cindent={args=1, base=1},
+ clearmatches={args={0, 1}, base=1},
+ col={args=1, base=1},
+ complete={args=2, base=2},
+ complete_add={args=1, base=1},
complete_check={},
- complete_info={args={0, 1}},
- confirm={args={1, 4}},
- copy={args=1},
- cos={args=1, func="float_op_wrapper", data="&cos"},
- cosh={args=1, func="float_op_wrapper", data="&cosh"},
- count={args={2, 4}},
+ complete_info={args={0, 1}, base=1},
+ confirm={args={1, 4}, base=1},
+ copy={args=1, base=1},
+ cos={args=1, base=1, func="float_op_wrapper", data="&cos"},
+ cosh={args=1, base=1, func="float_op_wrapper", data="&cosh"},
+ count={args={2, 4}, base=1},
cscope_connection={args={0, 3}},
ctxget={args={0, 1}},
ctxpop={},
ctxpush={args={0, 1}},
ctxset={args={1, 2}},
ctxsize={},
- cursor={args={1, 3}},
- debugbreak={args={1, 1}},
- deepcopy={args={1, 2}},
- delete={args={1,2}},
- deletebufline={args={2,3}},
+ cursor={args={1, 3}, base=1},
+ debugbreak={args={1, 1}, base=1},
+ deepcopy={args={1, 2}, base=1},
+ delete={args={1,2}, base=1},
+ deletebufline={args={2,3}, base=1},
dictwatcheradd={args=3},
dictwatcherdel={args=3},
did_filetype={},
- diff_filler={args=1},
- diff_hlID={args=2},
- empty={args=1},
+ diff_filler={args=1, base=1},
+ diff_hlID={args=2, base=1},
+ empty={args=1, base=1},
environ={},
escape={args=2},
- eval={args=1},
+ eval={args=1, base=1},
eventhandler={},
executable={args=1},
execute={args={1, 2}},
exepath={args=1},
exists={args=1},
- exp={args=1, func="float_op_wrapper", data="&exp"},
+ exp={args=1, base=1, func="float_op_wrapper", data="&exp"},
expand={args={1, 3}},
expandcmd={args=1},
- extend={args={2, 3}},
+ extend={args={2, 3}, base=1},
feedkeys={args={1, 2}},
file_readable={args=1, func='f_filereadable'}, -- obsolete
filereadable={args=1},
filewritable={args=1},
- filter={args=2},
+ filter={args=2, base=1},
finddir={args={1, 3}},
findfile={args={1, 3}},
flatten={args={1, 2}},
- float2nr={args=1},
- floor={args=1, func="float_op_wrapper", data="&floor"},
- fmod={args=2},
+ float2nr={args=1, base=1},
+ floor={args=1, base=1, func="float_op_wrapper", data="&floor"},
+ fmod={args=2, base=1},
fnameescape={args=1},
fnamemodify={args=2},
foldclosed={args=1},
@@ -128,7 +135,7 @@ return {
funcref={args={1, 3}},
['function']={args={1, 3}},
garbagecollect={args={0, 1}},
- get={args={2, 3}},
+ get={args={2, 3}, base=1},
getbufinfo={args={0, 1}},
getbufline={args={2, 3}},
getbufvar={args={2, 3}},
@@ -136,6 +143,7 @@ return {
getchar={args={0, 1}},
getcharmod={},
getcharsearch={},
+ getcharstr={args={0, 1}},
getcmdline={},
getcmdpos={},
getcmdtype={},
@@ -154,10 +162,12 @@ return {
getloclist={args={1, 2}},
getmarklist={args={0, 1}},
getmatches={args={0, 1}},
+ getmousepos={},
getpid={},
getpos={args=1},
getqflist={args={0, 1}},
getreg={args={0, 3}},
+ getreginfo={args={0, 1}, base=1},
getregtype={args={0, 1}},
gettabinfo={args={0, 1}},
gettabvar={args={2, 3}},
@@ -172,7 +182,7 @@ return {
glob2regpat={args=1},
globpath={args={2, 5}},
has={args=1},
- has_key={args=2},
+ has_key={args=2, base=1},
haslocaldir={args={0,2}},
hasmapto={args={1, 3}},
highlightID={args=1, func='f_hlID'}, -- obsolete
@@ -186,22 +196,22 @@ return {
hostname={},
iconv={args=3},
indent={args=1},
- index={args={2, 4}},
+ index={args={2, 4}, base=1},
input={args={1, 3}},
inputdialog={args={1, 3}},
inputlist={args=1},
inputrestore={},
inputsave={},
inputsecret={args={1, 2}},
- insert={args={2, 3}},
+ insert={args={2, 3}, base=1},
interrupt={args=0},
- invert={args=1},
+ invert={args=1, base=1},
isdirectory={args=1},
- isinf={args=1},
+ isinf={args=1, base=1},
islocked={args=1},
- isnan={args=1},
+ isnan={args=1, base=1},
id={args=1},
- items={args=1},
+ items={args=1, base=1},
jobclose={args={1, 2}, func="f_chanclose"},
jobpid={args=1},
jobresize={args=3},
@@ -209,12 +219,12 @@ return {
jobstart={args={1, 2}},
jobstop={args=1},
jobwait={args={1, 2}},
- join={args={1, 2}},
+ join={args={1, 2}, base=1},
json_decode={args=1},
json_encode={args=1},
- keys={args=1},
+ keys={args=1, base=1},
last_buffer_nr={}, -- obsolete
- len={args=1},
+ len={args=1, base=1},
libcall={args=3},
libcallnr={args=3},
line={args={1, 2}},
@@ -222,10 +232,10 @@ return {
lispindent={args=1},
list2str={args={1, 2}},
localtime={},
- log={args=1, func="float_op_wrapper", data="&log"},
- log10={args=1, func="float_op_wrapper", data="&log10"},
+ log={args=1, base=1, func="float_op_wrapper", data="&log"},
+ log10={args=1, base=1, func="float_op_wrapper", data="&log10"},
luaeval={args={1, 2}},
- map={args=2},
+ map={args=2, base=1},
maparg={args={1, 4}},
mapcheck={args={1, 3}},
match={args={2, 4}},
@@ -237,20 +247,20 @@ return {
matchlist={args={2, 4}},
matchstr={args={2, 4}},
matchstrpos={args={2,4}},
- max={args=1},
+ max={args=1, base=1},
menu_get={args={1, 2}},
- min={args=1},
+ min={args=1, base=1},
mkdir={args={1, 3}},
mode={args={0, 1}},
- msgpackdump={args=1},
+ msgpackdump={args={1, 2}},
msgpackparse={args=1},
nextnonblank={args=1},
nr2char={args={1, 2}},
- ['or']={args=2},
+ ['or']={args=2, base=1},
pathshorten={args=1},
- pow={args=2},
+ pow={args=2, base=1},
prevnonblank={args=1},
- printf={args=varargs(1)},
+ printf={args=varargs(1), base=2},
prompt_getprompt={args=1},
prompt_setcallback={args={2, 2}},
prompt_setinterrupt={args={2, 2}},
@@ -269,12 +279,12 @@ return {
reltime={args={0, 2}},
reltimefloat={args=1},
reltimestr={args=1},
- remove={args={2, 3}},
+ remove={args={2, 3}, base=1},
rename={args=2},
- ['repeat']={args=2},
+ ['repeat']={args=2, base=1},
resolve={args=1},
- reverse={args=1},
- round={args=1, func="float_op_wrapper", data="&round"},
+ reverse={args=1, base=1},
+ round={args=1, base=1, func="float_op_wrapper", data="&round"},
rpcnotify={args=varargs(2)},
rpcrequest={args=varargs(2)},
rpcstart={args={1, 2}},
@@ -282,9 +292,11 @@ return {
rubyeval={args=1},
screenattr={args=2},
screenchar={args=2},
+ screenchars={args=2},
screencol={},
screenpos={args=3},
screenrow={},
+ screenstring={args=2},
search={args={1, 4}},
searchcount={args={0,1}},
searchdecl={args={1, 3}},
@@ -323,51 +335,51 @@ return {
sign_unplace={args={1, 2}},
sign_unplacelist={args={1}},
simplify={args=1},
- sin={args=1, func="float_op_wrapper", data="&sin"},
- sinh={args=1, func="float_op_wrapper", data="&sinh"},
+ sin={args=1, base=1, func="float_op_wrapper", data="&sin"},
+ sinh={args=1, base=1, func="float_op_wrapper", data="&sinh"},
sockconnect={args={2,3}},
- sort={args={1, 3}},
+ sort={args={1, 3}, base=1},
soundfold={args=1},
stdioopen={args=1},
spellbadword={args={0, 1}},
spellsuggest={args={1, 3}},
- split={args={1, 3}},
- sqrt={args=1, func="float_op_wrapper", data="&sqrt"},
+ split={args={1, 3}, base=1},
+ sqrt={args=1, base=1, func="float_op_wrapper", data="&sqrt"},
stdpath={args=1},
- str2float={args=1},
- str2list={args={1, 2}},
- str2nr={args={1, 2}},
+ str2float={args=1, base=1},
+ str2list={args={1, 2}, base=1},
+ str2nr={args={1, 3}},
strcharpart={args={2, 3}},
strchars={args={1,2}},
strdisplaywidth={args={1, 2}},
strftime={args={1, 2}},
strgetchar={args={2, 2}},
stridx={args={2, 3}},
- string={args=1},
- strlen={args=1},
+ string={args=1, base=1},
+ strlen={args=1, base=1},
strpart={args={2, 4}},
strptime={args=2},
strridx={args={2, 3}},
- strtrans={args=1},
- strwidth={args=1},
+ strtrans={args=1, base=1},
+ strwidth={args=1, base=1},
submatch={args={1, 2}},
- substitute={args=4},
+ substitute={args=4, base=1},
swapinfo={args={1}},
swapname={args={1}},
synID={args=3},
- synIDattr={args={2, 3}},
- synIDtrans={args=1},
+ synIDattr={args={2, 3}, base=1},
+ synIDtrans={args=1, base=1},
synconcealed={args=2},
synstack={args=2},
- system={args={1, 2}},
- systemlist={args={1, 3}},
+ system={args={1, 2}, base=1},
+ systemlist={args={1, 3}, base=1},
tabpagebuflist={args={0, 1}},
tabpagenr={args={0, 1}},
tabpagewinnr={args={1, 2}},
tagfiles={},
taglist={args={1, 2}},
- tan={args=1, func="float_op_wrapper", data="&tan"},
- tanh={args=1, func="float_op_wrapper", data="&tanh"},
+ tan={args=1, base=1, func="float_op_wrapper", data="&tan"},
+ tanh={args=1, base=1, func="float_op_wrapper", data="&tanh"},
tempname={},
termopen={args={1, 2}},
test_garbagecollect_now={},
@@ -381,12 +393,12 @@ return {
toupper={args=1},
tr={args=3},
trim={args={1,3}},
- trunc={args=1, func="float_op_wrapper", data="&trunc"},
- type={args=1},
+ trunc={args=1, base=1, func="float_op_wrapper", data="&trunc"},
+ type={args=1, base=1},
undofile={args=1},
undotree={},
- uniq={args={1, 3}},
- values={args=1},
+ uniq={args={1, 3}, base=1},
+ values={args=1, base=1},
virtcol={args=1},
visualmode={args={0, 1}},
wait={args={2,3}},
@@ -400,7 +412,7 @@ return {
win_id2win={args=1},
win_screenpos={args=1},
win_splitmove={args={2, 3}},
- winbufnr={args=1},
+ winbufnr={args=1, base=1},
wincol={},
windowsversion={},
winheight={args=1},
@@ -413,6 +425,6 @@ return {
winwidth={args=1},
wordcount={},
writefile={args={2, 3}},
- xor={args=2},
+ xor={args=2, base=1},
},
}
diff --git a/src/nvim/eval/decode.c b/src/nvim/eval/decode.c
index bd4dc87d31..c8734c9b9c 100644
--- a/src/nvim/eval/decode.c
+++ b/src/nvim/eval/decode.c
@@ -1,20 +1,19 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
-#include <stddef.h>
-
#include <msgpack.h>
+#include <stddef.h>
-#include "nvim/eval/typval.h"
+#include "nvim/ascii.h"
+#include "nvim/charset.h" // vim_str2nr
#include "nvim/eval.h"
#include "nvim/eval/decode.h"
#include "nvim/eval/encode.h"
-#include "nvim/ascii.h"
-#include "nvim/macros.h"
-#include "nvim/message.h"
+#include "nvim/eval/typval.h"
#include "nvim/globals.h"
-#include "nvim/charset.h" // vim_str2nr
#include "nvim/lib/kvec.h"
+#include "nvim/macros.h"
+#include "nvim/message.h"
#include "nvim/vim.h" // OK, FAIL
/// Helper structure for container_struct
@@ -52,8 +51,7 @@ typedef kvec_t(ContainerStackItem) ContainerStack;
/// @param[out] rettv Location where created dictionary will be saved.
/// @param[in] type Type of the dictionary.
/// @param[in] val Value associated with the _VAL key.
-static inline void create_special_dict(typval_T *const rettv,
- const MessagePackType type,
+static inline void create_special_dict(typval_T *const rettv, const MessagePackType type,
typval_T val)
FUNC_ATTR_NONNULL_ALL
{
@@ -97,12 +95,9 @@ static inline void create_special_dict(typval_T *const rettv,
/// value when decoder is restarted, otherwise unused.
///
/// @return OK in case of success, FAIL in case of error.
-static inline int json_decoder_pop(ValuesStackItem obj,
- ValuesStack *const stack,
- ContainerStack *const container_stack,
- const char **const pp,
- bool *const next_map_special,
- bool *const didcomma,
+static inline int json_decoder_pop(ValuesStackItem obj, ValuesStack *const stack,
+ ContainerStack *const container_stack, const char **const pp,
+ bool *const next_map_special, bool *const didcomma,
bool *const didcolon)
FUNC_ATTR_NONNULL_ALL
{
@@ -114,9 +109,9 @@ static inline int json_decoder_pop(ValuesStackItem obj,
const char *val_location = *pp;
if (obj.val.v_type == last_container.container.v_type
// vval.v_list and vval.v_dict should have the same size and offset
- && ((void *) obj.val.vval.v_list
- == (void *) last_container.container.vval.v_list)) {
- (void) kv_pop(*container_stack);
+ && ((void *)obj.val.vval.v_list
+ == (void *)last_container.container.vval.v_list)) {
+ (void)kv_pop(*container_stack);
val_location = last_container.s;
last_container = kv_last(*container_stack);
}
@@ -142,8 +137,7 @@ static inline int json_decoder_pop(ValuesStackItem obj,
assert(!(key.is_special_string
|| key.val.vval.v_string == NULL
|| *key.val.vval.v_string == NUL));
- dictitem_T *const obj_di = tv_dict_item_alloc(
- (const char *)key.val.vval.v_string);
+ dictitem_T *const obj_di = tv_dict_item_alloc((const char *)key.val.vval.v_string);
tv_clear(&key.val);
if (tv_dict_add(last_container.container.vval.v_dict, obj_di)
== FAIL) {
@@ -179,9 +173,9 @@ static inline int json_decoder_pop(ValuesStackItem obj,
tv_clear(&obj.val);
// Restart
- (void) kv_pop(*container_stack);
+ (void)kv_pop(*container_stack);
ValuesStackItem last_container_val =
- kv_A(*stack, last_container.stack_index);
+ kv_A(*stack, last_container.stack_index);
while (kv_size(*stack) > last_container.stack_index) {
tv_clear(&(kv_pop(*stack).val));
}
@@ -197,7 +191,7 @@ static inline int json_decoder_pop(ValuesStackItem obj,
}
#define LENP(p, e) \
- ((int) ((e) - (p))), (p)
+ ((int)((e) - (p))), (p)
#define OBJ(obj_tv, is_sp_string, didcomma_, didcolon_) \
((ValuesStackItem) { \
.is_special_string = (is_sp_string), \
@@ -229,8 +223,7 @@ static inline int json_decoder_pop(ValuesStackItem obj,
///
/// @return [allocated] list which should contain key-value pairs. Return value
/// may be safely ignored.
-list_T *decode_create_map_special_dict(typval_T *const ret_tv,
- const ptrdiff_t len)
+list_T *decode_create_map_special_dict(typval_T *const ret_tv, const ptrdiff_t len)
FUNC_ATTR_NONNULL_ALL
{
list_T *const list = tv_list_alloc(len);
@@ -246,22 +239,22 @@ list_T *decode_create_map_special_dict(typval_T *const ret_tv,
/// Convert char* string to typval_T
///
/// Depending on whether string has (no) NUL bytes, it may use a special
-/// dictionary or decode string to VAR_STRING.
+/// dictionary, VAR_BLOB, or decode string to VAR_STRING.
///
/// @param[in] s String to decode.
/// @param[in] len String length.
/// @param[in] hasnul Whether string has NUL byte, not or it was not yet
/// determined.
-/// @param[in] binary If true, save special string type as kMPBinary,
-/// otherwise kMPString.
+/// @param[in] binary Determines decode type if string has NUL bytes.
+/// If true convert string to VAR_BLOB, otherwise to the
+/// kMPString special type.
/// @param[in] s_allocated If true, then `s` was allocated and can be saved in
/// a returned structure. If it is not saved there, it
/// will be freed.
///
/// @return Decoded string.
-typval_T decode_string(const char *const s, const size_t len,
- const TriState hasnul, const bool binary,
- const bool s_allocated)
+typval_T decode_string(const char *const s, const size_t len, const TriState hasnul,
+ const bool binary, const bool s_allocated)
FUNC_ATTR_WARN_UNUSED_RESULT
{
assert(s != NULL || len == 0);
@@ -269,21 +262,28 @@ typval_T decode_string(const char *const s, const size_t len,
? ((s != NULL) && (memchr(s, NUL, len) != NULL))
: (bool)hasnul);
if (really_hasnul) {
- list_T *const list = tv_list_alloc(kListLenMayKnow);
- tv_list_ref(list);
typval_T tv;
- create_special_dict(&tv, binary ? kMPBinary : kMPString, ((typval_T) {
- .v_type = VAR_LIST,
- .v_lock = VAR_UNLOCKED,
- .vval = { .v_list = list },
- }));
- const int elw_ret = encode_list_write((void *)list, s, len);
- if (s_allocated) {
- xfree((void *)s);
- }
- if (elw_ret == -1) {
- tv_clear(&tv);
- return (typval_T) { .v_type = VAR_UNKNOWN, .v_lock = VAR_UNLOCKED };
+ tv.v_lock = VAR_UNLOCKED;
+ if (binary) {
+ tv_blob_alloc_ret(&tv);
+ ga_concat_len(&tv.vval.v_blob->bv_ga, s, len);
+ } else {
+ list_T *const list = tv_list_alloc(kListLenMayKnow);
+ tv_list_ref(list);
+ create_special_dict(&tv, kMPString,
+ ((typval_T){
+ .v_type = VAR_LIST,
+ .v_lock = VAR_UNLOCKED,
+ .vval = { .v_list = list },
+ }));
+ const int elw_ret = encode_list_write((void *)list, s, len);
+ if (s_allocated) {
+ xfree((void *)s);
+ }
+ if (elw_ret == -1) {
+ tv_clear(&tv);
+ return (typval_T) { .v_type = VAR_UNKNOWN, .v_lock = VAR_UNLOCKED };
+ }
}
return tv;
} else {
@@ -291,7 +291,7 @@ typval_T decode_string(const char *const s, const size_t len,
.v_type = VAR_STRING,
.v_lock = VAR_UNLOCKED,
.vval = { .v_string = (char_u *)(
- (s == NULL || s_allocated) ? (char *)s : xmemdupz(s, len)) },
+ (s == NULL || s_allocated) ? (char *)s : xmemdupz(s, len)) },
};
}
}
@@ -315,11 +315,9 @@ typval_T decode_string(const char *const s, const size_t len,
///
/// @return OK in case of success, FAIL in case of error.
static inline int parse_json_string(const char *const buf, const size_t buf_len,
- const char **const pp,
- ValuesStack *const stack,
+ const char **const pp, ValuesStack *const stack,
ContainerStack *const container_stack,
- bool *const next_map_special,
- bool *const didcomma,
+ bool *const next_map_special, bool *const didcomma,
bool *const didcolon)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_ALWAYS_INLINE
{
@@ -333,55 +331,52 @@ static inline int parse_json_string(const char *const buf, const size_t buf_len,
p++;
if (p == e) {
emsgf(_("E474: Unfinished escape sequence: %.*s"),
- (int) buf_len, buf);
+ (int)buf_len, buf);
goto parse_json_string_fail;
}
switch (*p) {
- case 'u': {
- if (p + 4 >= e) {
- emsgf(_("E474: Unfinished unicode escape sequence: %.*s"),
- (int) buf_len, buf);
- goto parse_json_string_fail;
- } else if (!ascii_isxdigit(p[1])
- || !ascii_isxdigit(p[2])
- || !ascii_isxdigit(p[3])
- || !ascii_isxdigit(p[4])) {
- emsgf(_("E474: Expected four hex digits after \\u: %.*s"),
- LENP(p - 1, e));
- goto parse_json_string_fail;
- }
- // One UTF-8 character below U+10000 can take up to 3 bytes,
- // above up to 6, but they are encoded using two \u escapes.
- len += 3;
- p += 5;
- break;
- }
- case '\\':
- case '/':
- case '"':
- case 't':
- case 'b':
- case 'n':
- case 'r':
- case 'f': {
- len++;
- p++;
- break;
- }
- default: {
- emsgf(_("E474: Unknown escape sequence: %.*s"), LENP(p - 1, e));
+ case 'u':
+ if (p + 4 >= e) {
+ emsgf(_("E474: Unfinished unicode escape sequence: %.*s"),
+ (int)buf_len, buf);
+ goto parse_json_string_fail;
+ } else if (!ascii_isxdigit(p[1])
+ || !ascii_isxdigit(p[2])
+ || !ascii_isxdigit(p[3])
+ || !ascii_isxdigit(p[4])) {
+ emsgf(_("E474: Expected four hex digits after \\u: %.*s"),
+ LENP(p - 1, e));
goto parse_json_string_fail;
}
+ // One UTF-8 character below U+10000 can take up to 3 bytes,
+ // above up to 6, but they are encoded using two \u escapes.
+ len += 3;
+ p += 5;
+ break;
+ case '\\':
+ case '/':
+ case '"':
+ case 't':
+ case 'b':
+ case 'n':
+ case 'r':
+ case 'f':
+ len++;
+ p++;
+ break;
+ default:
+ emsgf(_("E474: Unknown escape sequence: %.*s"), LENP(p - 1, e));
+ goto parse_json_string_fail;
}
} else {
- uint8_t p_byte = (uint8_t) *p;
+ uint8_t p_byte = (uint8_t)*p;
// unescaped = %x20-21 / %x23-5B / %x5D-10FFFF
if (p_byte < 0x20) {
emsgf(_("E474: ASCII control characters cannot be present "
"inside string: %.*s"), LENP(p, e));
goto parse_json_string_fail;
}
- const int ch = utf_ptr2char((char_u *) p);
+ const int ch = utf_ptr2char((char_u *)p);
// All characters above U+007F are encoded using two or more bytes
// and thus cannot possibly be equal to *p. But utf_ptr2char({0xFF,
// 0}) will return 0xFF, even though 0xFF cannot start any UTF-8
@@ -389,7 +384,7 @@ static inline int parse_json_string(const char *const buf, const size_t buf_len,
//
// The only exception is U+00C3 which is represented as 0xC3 0x83.
if (ch >= 0x80 && p_byte == ch
- && !(ch == 0xC3 && p + 1 < e && (uint8_t) p[1] == 0x83)) {
+ && !(ch == 0xC3 && p + 1 < e && (uint8_t)p[1] == 0x83)) {
emsgf(_("E474: Only UTF-8 strings allowed: %.*s"), LENP(p, e));
goto parse_json_string_fail;
} else if (ch > 0x10FFFF) {
@@ -397,14 +392,14 @@ static inline int parse_json_string(const char *const buf, const size_t buf_len,
"are allowed to appear unescaped: %.*s"), LENP(p, e));
goto parse_json_string_fail;
}
- const size_t ch_len = (size_t) utf_char2len(ch);
- assert(ch_len == (size_t) (ch ? utf_ptr2len((char_u *) p) : 1));
+ const size_t ch_len = (size_t)utf_char2len(ch);
+ assert(ch_len == (size_t)(ch ? utf_ptr2len((char_u *)p) : 1));
len += ch_len;
p += ch_len;
}
}
if (p == e || *p != '"') {
- emsgf(_("E474: Expected string end: %.*s"), (int) buf_len, buf);
+ emsgf(_("E474: Expected string end: %.*s"), (int)buf_len, buf);
goto parse_json_string_fail;
}
if (len == 0) {
@@ -421,7 +416,7 @@ static inline int parse_json_string(const char *const buf, const size_t buf_len,
#define PUT_FST_IN_PAIR(fst_in_pair, str_end) \
do { \
if (fst_in_pair != 0) { \
- str_end += utf_char2bytes(fst_in_pair, (char_u *) str_end); \
+ str_end += utf_char2bytes(fst_in_pair, (char_u *)str_end); \
fst_in_pair = 0; \
} \
} while (0)
@@ -432,56 +427,55 @@ static inline int parse_json_string(const char *const buf, const size_t buf_len,
if (*t == '\\') {
t++;
switch (*t) {
- case 'u': {
- const char ubuf[] = { t[1], t[2], t[3], t[4] };
- t += 4;
- uvarnumber_T ch;
- vim_str2nr((char_u *)ubuf, NULL, NULL,
- STR2NR_HEX | STR2NR_FORCE, NULL, &ch, 4);
- if (ch == 0) {
- hasnul = true;
- }
- if (SURROGATE_HI_START <= ch && ch <= SURROGATE_HI_END) {
- PUT_FST_IN_PAIR(fst_in_pair, str_end);
- fst_in_pair = (int) ch;
- } else if (SURROGATE_LO_START <= ch && ch <= SURROGATE_LO_END
- && fst_in_pair != 0) {
- const int full_char = (
- (int) (ch - SURROGATE_LO_START)
- + ((fst_in_pair - SURROGATE_HI_START) << 10)
- + SURROGATE_FIRST_CHAR);
- str_end += utf_char2bytes(full_char, (char_u *) str_end);
- fst_in_pair = 0;
- } else {
- PUT_FST_IN_PAIR(fst_in_pair, str_end);
- str_end += utf_char2bytes((int) ch, (char_u *) str_end);
- }
- break;
+ case 'u': {
+ const char ubuf[] = { t[1], t[2], t[3], t[4] };
+ t += 4;
+ uvarnumber_T ch;
+ vim_str2nr((char_u *)ubuf, NULL, NULL,
+ STR2NR_HEX | STR2NR_FORCE, NULL, &ch, 4, true);
+ if (ch == 0) {
+ hasnul = true;
}
- case '\\':
- case '/':
- case '"':
- case 't':
- case 'b':
- case 'n':
- case 'r':
- case 'f': {
- static const char escapes[] = {
- ['\\'] = '\\',
- ['/'] = '/',
- ['"'] = '"',
- ['t'] = TAB,
- ['b'] = BS,
- ['n'] = NL,
- ['r'] = CAR,
- ['f'] = FF,
- };
- *str_end++ = escapes[(int) *t];
- break;
- }
- default: {
- abort();
+ if (SURROGATE_HI_START <= ch && ch <= SURROGATE_HI_END) {
+ PUT_FST_IN_PAIR(fst_in_pair, str_end);
+ fst_in_pair = (int)ch;
+ } else if (SURROGATE_LO_START <= ch && ch <= SURROGATE_LO_END
+ && fst_in_pair != 0) {
+ const int full_char = (
+ (int)(ch - SURROGATE_LO_START)
+ + ((fst_in_pair - SURROGATE_HI_START) << 10)
+ + SURROGATE_FIRST_CHAR);
+ str_end += utf_char2bytes(full_char, (char_u *)str_end);
+ fst_in_pair = 0;
+ } else {
+ PUT_FST_IN_PAIR(fst_in_pair, str_end);
+ str_end += utf_char2bytes((int)ch, (char_u *)str_end);
}
+ break;
+ }
+ case '\\':
+ case '/':
+ case '"':
+ case 't':
+ case 'b':
+ case 'n':
+ case 'r':
+ case 'f': {
+ static const char escapes[] = {
+ ['\\'] = '\\',
+ ['/'] = '/',
+ ['"'] = '"',
+ ['t'] = TAB,
+ ['b'] = BS,
+ ['n'] = NL,
+ ['r'] = CAR,
+ ['f'] = FF,
+ };
+ *str_end++ = escapes[(int)*t];
+ break;
+ }
+ default:
+ abort();
}
} else {
*str_end++ = *t;
@@ -490,8 +484,7 @@ static inline int parse_json_string(const char *const buf, const size_t buf_len,
PUT_FST_IN_PAIR(fst_in_pair, str_end);
#undef PUT_FST_IN_PAIR
*str_end = NUL;
- typval_T obj = decode_string(
- str, (size_t)(str_end - str), hasnul ? kTrue : kFalse, false, true);
+ typval_T obj = decode_string(str, (size_t)(str_end - str), hasnul ? kTrue : kFalse, false, true);
if (obj.v_type == VAR_UNKNOWN) {
goto parse_json_string_fail;
}
@@ -528,11 +521,9 @@ parse_json_string_ret:
///
/// @return OK in case of success, FAIL in case of error.
static inline int parse_json_number(const char *const buf, const size_t buf_len,
- const char **const pp,
- ValuesStack *const stack,
+ const char **const pp, ValuesStack *const stack,
ContainerStack *const container_stack,
- bool *const next_map_special,
- bool *const didcomma,
+ bool *const next_map_special, bool *const didcomma,
bool *const didcolon)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_ALWAYS_INLINE
{
@@ -597,25 +588,25 @@ parse_json_number_check:
.v_type = VAR_NUMBER,
.v_lock = VAR_UNLOCKED,
};
- const size_t exp_num_len = (size_t) (p - s);
+ const size_t exp_num_len = (size_t)(p - s);
if (fracs || exps) {
// Convert floating-point number
const size_t num_len = string2float(s, &tv.vval.v_float);
if (exp_num_len != num_len) {
emsgf(_("E685: internal error: while converting number \"%.*s\" "
"to float string2float consumed %zu bytes in place of %zu"),
- (int) exp_num_len, s, num_len, exp_num_len);
+ (int)exp_num_len, s, num_len, exp_num_len);
}
tv.v_type = VAR_FLOAT;
} else {
// Convert integer
varnumber_T nr;
int num_len;
- vim_str2nr((char_u *) s, NULL, &num_len, 0, &nr, NULL, (int) (p - s));
- if ((int) exp_num_len != num_len) {
+ vim_str2nr((char_u *)s, NULL, &num_len, 0, &nr, NULL, (int)(p - s), true);
+ if ((int)exp_num_len != num_len) {
emsgf(_("E685: internal error: while converting number \"%.*s\" "
"to integer vim_str2nr consumed %i bytes in place of %zu"),
- (int) exp_num_len, s, num_len, exp_num_len);
+ (int)exp_num_len, s, num_len, exp_num_len);
}
tv.vval.v_number = nr;
}
@@ -656,8 +647,7 @@ parse_json_number_ret:
/// @param[out] rettv Location where to save results.
///
/// @return OK in case of success, FAIL otherwise.
-int json_decode_string(const char *const buf, const size_t buf_len,
- typval_T *const rettv)
+int json_decode_string(const char *const buf, const size_t buf_len, typval_T *const rettv)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
const char *p = buf;
@@ -680,219 +670,212 @@ int json_decode_string(const char *const buf, const size_t buf_len,
json_decode_string_cycle_start:
assert(*p == '{' || next_map_special == false);
switch (*p) {
- case '}':
- case ']': {
- if (kv_size(container_stack) == 0) {
- emsgf(_("E474: No container to close: %.*s"), LENP(p, e));
- goto json_decode_string_fail;
- }
- ContainerStackItem last_container = kv_last(container_stack);
- if (*p == '}' && last_container.container.v_type != VAR_DICT) {
- emsgf(_("E474: Closing list with curly bracket: %.*s"), LENP(p, e));
- goto json_decode_string_fail;
- } else if (*p == ']' && last_container.container.v_type != VAR_LIST) {
- emsgf(_("E474: Closing dictionary with square bracket: %.*s"),
- LENP(p, e));
- goto json_decode_string_fail;
- } else if (didcomma) {
- emsgf(_("E474: Trailing comma: %.*s"), LENP(p, e));
- goto json_decode_string_fail;
- } else if (didcolon) {
- emsgf(_("E474: Expected value after colon: %.*s"), LENP(p, e));
- goto json_decode_string_fail;
- } else if (last_container.stack_index != kv_size(stack) - 1) {
- assert(last_container.stack_index < kv_size(stack) - 1);
- emsgf(_("E474: Expected value: %.*s"), LENP(p, e));
- goto json_decode_string_fail;
- }
- if (kv_size(stack) == 1) {
- p++;
- (void) kv_pop(container_stack);
- goto json_decode_string_after_cycle;
- } else {
- if (json_decoder_pop(kv_pop(stack), &stack, &container_stack, &p,
- &next_map_special, &didcomma, &didcolon)
- == FAIL) {
- goto json_decode_string_fail;
- }
- assert(!next_map_special);
- break;
- }
+ case '}':
+ case ']': {
+ if (kv_size(container_stack) == 0) {
+ emsgf(_("E474: No container to close: %.*s"), LENP(p, e));
+ goto json_decode_string_fail;
}
- case ',': {
- if (kv_size(container_stack) == 0) {
- emsgf(_("E474: Comma not inside container: %.*s"), LENP(p, e));
+ ContainerStackItem last_container = kv_last(container_stack);
+ if (*p == '}' && last_container.container.v_type != VAR_DICT) {
+ emsgf(_("E474: Closing list with curly bracket: %.*s"), LENP(p, e));
+ goto json_decode_string_fail;
+ } else if (*p == ']' && last_container.container.v_type != VAR_LIST) {
+ emsgf(_("E474: Closing dictionary with square bracket: %.*s"),
+ LENP(p, e));
+ goto json_decode_string_fail;
+ } else if (didcomma) {
+ emsgf(_("E474: Trailing comma: %.*s"), LENP(p, e));
+ goto json_decode_string_fail;
+ } else if (didcolon) {
+ emsgf(_("E474: Expected value after colon: %.*s"), LENP(p, e));
+ goto json_decode_string_fail;
+ } else if (last_container.stack_index != kv_size(stack) - 1) {
+ assert(last_container.stack_index < kv_size(stack) - 1);
+ emsgf(_("E474: Expected value: %.*s"), LENP(p, e));
+ goto json_decode_string_fail;
+ }
+ if (kv_size(stack) == 1) {
+ p++;
+ (void)kv_pop(container_stack);
+ goto json_decode_string_after_cycle;
+ } else {
+ if (json_decoder_pop(kv_pop(stack), &stack, &container_stack, &p,
+ &next_map_special, &didcomma, &didcolon)
+ == FAIL) {
goto json_decode_string_fail;
}
- ContainerStackItem last_container = kv_last(container_stack);
- if (didcomma) {
- emsgf(_("E474: Duplicate comma: %.*s"), LENP(p, e));
- goto json_decode_string_fail;
- } else if (didcolon) {
- emsgf(_("E474: Comma after colon: %.*s"), LENP(p, e));
- goto json_decode_string_fail;
- } else if (last_container.container.v_type == VAR_DICT
- && last_container.stack_index != kv_size(stack) - 1) {
- emsgf(_("E474: Using comma in place of colon: %.*s"), LENP(p, e));
- goto json_decode_string_fail;
- } else if (last_container.special_val == NULL
+ assert(!next_map_special);
+ break;
+ }
+ }
+ case ',': {
+ if (kv_size(container_stack) == 0) {
+ emsgf(_("E474: Comma not inside container: %.*s"), LENP(p, e));
+ goto json_decode_string_fail;
+ }
+ ContainerStackItem last_container = kv_last(container_stack);
+ if (didcomma) {
+ emsgf(_("E474: Duplicate comma: %.*s"), LENP(p, e));
+ goto json_decode_string_fail;
+ } else if (didcolon) {
+ emsgf(_("E474: Comma after colon: %.*s"), LENP(p, e));
+ goto json_decode_string_fail;
+ } else if (last_container.container.v_type == VAR_DICT
+ && last_container.stack_index != kv_size(stack) - 1) {
+ emsgf(_("E474: Using comma in place of colon: %.*s"), LENP(p, e));
+ goto json_decode_string_fail;
+ } else if (last_container.special_val == NULL
? (last_container.container.v_type == VAR_DICT
? (DICT_LEN(last_container.container.vval.v_dict) == 0)
: (tv_list_len(last_container.container.vval.v_list)
== 0))
- : (tv_list_len(last_container.special_val) == 0)) {
- emsgf(_("E474: Leading comma: %.*s"), LENP(p, e));
- goto json_decode_string_fail;
- }
- didcomma = true;
- continue;
+ : (tv_list_len(last_container.special_val) == 0)) {
+ emsgf(_("E474: Leading comma: %.*s"), LENP(p, e));
+ goto json_decode_string_fail;
}
- case ':': {
- if (kv_size(container_stack) == 0) {
- emsgf(_("E474: Colon not inside container: %.*s"), LENP(p, e));
- goto json_decode_string_fail;
- }
- ContainerStackItem last_container = kv_last(container_stack);
- if (last_container.container.v_type != VAR_DICT) {
- emsgf(_("E474: Using colon not in dictionary: %.*s"), LENP(p, e));
- goto json_decode_string_fail;
- } else if (last_container.stack_index != kv_size(stack) - 2) {
- emsgf(_("E474: Unexpected colon: %.*s"), LENP(p, e));
- goto json_decode_string_fail;
- } else if (didcomma) {
- emsgf(_("E474: Colon after comma: %.*s"), LENP(p, e));
- goto json_decode_string_fail;
- } else if (didcolon) {
- emsgf(_("E474: Duplicate colon: %.*s"), LENP(p, e));
- goto json_decode_string_fail;
- }
- didcolon = true;
- continue;
+ didcomma = true;
+ continue;
+ }
+ case ':': {
+ if (kv_size(container_stack) == 0) {
+ emsgf(_("E474: Colon not inside container: %.*s"), LENP(p, e));
+ goto json_decode_string_fail;
}
- case ' ':
- case TAB:
- case NL:
- case CAR: {
- continue;
+ ContainerStackItem last_container = kv_last(container_stack);
+ if (last_container.container.v_type != VAR_DICT) {
+ emsgf(_("E474: Using colon not in dictionary: %.*s"), LENP(p, e));
+ goto json_decode_string_fail;
+ } else if (last_container.stack_index != kv_size(stack) - 2) {
+ emsgf(_("E474: Unexpected colon: %.*s"), LENP(p, e));
+ goto json_decode_string_fail;
+ } else if (didcomma) {
+ emsgf(_("E474: Colon after comma: %.*s"), LENP(p, e));
+ goto json_decode_string_fail;
+ } else if (didcolon) {
+ emsgf(_("E474: Duplicate colon: %.*s"), LENP(p, e));
+ goto json_decode_string_fail;
}
- case 'n': {
- if ((p + 3) >= e || strncmp(p + 1, "ull", 3) != 0) {
- emsgf(_("E474: Expected null: %.*s"), LENP(p, e));
- goto json_decode_string_fail;
- }
- p += 3;
- POP(((typval_T) {
- .v_type = VAR_SPECIAL,
- .v_lock = VAR_UNLOCKED,
- .vval = { .v_special = kSpecialVarNull },
- }), false);
- break;
+ didcolon = true;
+ continue;
+ }
+ case ' ':
+ case TAB:
+ case NL:
+ case CAR:
+ continue;
+ case 'n':
+ if ((p + 3) >= e || strncmp(p + 1, "ull", 3) != 0) {
+ emsgf(_("E474: Expected null: %.*s"), LENP(p, e));
+ goto json_decode_string_fail;
}
- case 't': {
- if ((p + 3) >= e || strncmp(p + 1, "rue", 3) != 0) {
- emsgf(_("E474: Expected true: %.*s"), LENP(p, e));
- goto json_decode_string_fail;
- }
- p += 3;
- POP(((typval_T) {
- .v_type = VAR_BOOL,
- .v_lock = VAR_UNLOCKED,
- .vval = { .v_bool = kBoolVarTrue },
- }), false);
- break;
+ p += 3;
+ POP(((typval_T) {
+ .v_type = VAR_SPECIAL,
+ .v_lock = VAR_UNLOCKED,
+ .vval = { .v_special = kSpecialVarNull },
+ }), false);
+ break;
+ case 't':
+ if ((p + 3) >= e || strncmp(p + 1, "rue", 3) != 0) {
+ emsgf(_("E474: Expected true: %.*s"), LENP(p, e));
+ goto json_decode_string_fail;
}
- case 'f': {
- if ((p + 4) >= e || strncmp(p + 1, "alse", 4) != 0) {
- emsgf(_("E474: Expected false: %.*s"), LENP(p, e));
- goto json_decode_string_fail;
- }
- p += 4;
- POP(((typval_T) {
- .v_type = VAR_BOOL,
- .v_lock = VAR_UNLOCKED,
- .vval = { .v_bool = kBoolVarFalse },
- }), false);
- break;
+ p += 3;
+ POP(((typval_T) {
+ .v_type = VAR_BOOL,
+ .v_lock = VAR_UNLOCKED,
+ .vval = { .v_bool = kBoolVarTrue },
+ }), false);
+ break;
+ case 'f':
+ if ((p + 4) >= e || strncmp(p + 1, "alse", 4) != 0) {
+ emsgf(_("E474: Expected false: %.*s"), LENP(p, e));
+ goto json_decode_string_fail;
}
- case '"': {
- if (parse_json_string(buf, buf_len, &p, &stack, &container_stack,
- &next_map_special, &didcomma, &didcolon)
- == FAIL) {
- // Error message was already given
- goto json_decode_string_fail;
- }
- if (next_map_special) {
- goto json_decode_string_cycle_start;
- }
- break;
+ p += 4;
+ POP(((typval_T) {
+ .v_type = VAR_BOOL,
+ .v_lock = VAR_UNLOCKED,
+ .vval = { .v_bool = kBoolVarFalse },
+ }), false);
+ break;
+ case '"':
+ if (parse_json_string(buf, buf_len, &p, &stack, &container_stack,
+ &next_map_special, &didcomma, &didcolon)
+ == FAIL) {
+ // Error message was already given
+ goto json_decode_string_fail;
}
- case '-':
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9': {
- if (parse_json_number(buf, buf_len, &p, &stack, &container_stack,
- &next_map_special, &didcomma, &didcolon)
- == FAIL) {
- // Error message was already given
- goto json_decode_string_fail;
- }
- if (next_map_special) {
- goto json_decode_string_cycle_start;
- }
- break;
+ if (next_map_special) {
+ goto json_decode_string_cycle_start;
}
- case '[': {
- list_T *list = tv_list_alloc(kListLenMayKnow);
- tv_list_ref(list);
- typval_T tv = {
- .v_type = VAR_LIST,
- .v_lock = VAR_UNLOCKED,
- .vval = { .v_list = list },
- };
- kv_push(container_stack, ((ContainerStackItem) {
+ break;
+ case '-':
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ if (parse_json_number(buf, buf_len, &p, &stack, &container_stack,
+ &next_map_special, &didcomma, &didcolon)
+ == FAIL) {
+ // Error message was already given
+ goto json_decode_string_fail;
+ }
+ if (next_map_special) {
+ goto json_decode_string_cycle_start;
+ }
+ break;
+ case '[': {
+ list_T *list = tv_list_alloc(kListLenMayKnow);
+ tv_list_ref(list);
+ typval_T tv = {
+ .v_type = VAR_LIST,
+ .v_lock = VAR_UNLOCKED,
+ .vval = { .v_list = list },
+ };
+ kv_push(container_stack, ((ContainerStackItem) {
.stack_index = kv_size(stack),
.s = p,
.container = tv,
.special_val = NULL,
}));
- kv_push(stack, OBJ(tv, false, didcomma, didcolon));
- break;
+ kv_push(stack, OBJ(tv, false, didcomma, didcolon));
+ break;
+ }
+ case '{': {
+ typval_T tv;
+ list_T *val_list = NULL;
+ if (next_map_special) {
+ next_map_special = false;
+ val_list = decode_create_map_special_dict(&tv, kListLenMayKnow);
+ } else {
+ dict_T *dict = tv_dict_alloc();
+ dict->dv_refcount++;
+ tv = (typval_T) {
+ .v_type = VAR_DICT,
+ .v_lock = VAR_UNLOCKED,
+ .vval = { .v_dict = dict },
+ };
}
- case '{': {
- typval_T tv;
- list_T *val_list = NULL;
- if (next_map_special) {
- next_map_special = false;
- val_list = decode_create_map_special_dict(&tv, kListLenMayKnow);
- } else {
- dict_T *dict = tv_dict_alloc();
- dict->dv_refcount++;
- tv = (typval_T) {
- .v_type = VAR_DICT,
- .v_lock = VAR_UNLOCKED,
- .vval = { .v_dict = dict },
- };
- }
- kv_push(container_stack, ((ContainerStackItem) {
+ kv_push(container_stack, ((ContainerStackItem) {
.stack_index = kv_size(stack),
.s = p,
.container = tv,
.special_val = val_list,
}));
- kv_push(stack, OBJ(tv, false, didcomma, didcolon));
- break;
- }
- default: {
- emsgf(_("E474: Unidentified byte: %.*s"), LENP(p, e));
- goto json_decode_string_fail;
- }
+ kv_push(stack, OBJ(tv, false, didcomma, didcolon));
+ break;
+ }
+ default:
+ emsgf(_("E474: Unidentified byte: %.*s"), LENP(p, e));
+ goto json_decode_string_fail;
}
didcomma = false;
didcolon = false;
@@ -904,23 +887,21 @@ json_decode_string_cycle_start:
json_decode_string_after_cycle:
for (; p < e; p++) {
switch (*p) {
- case NL:
- case ' ':
- case TAB:
- case CAR: {
- break;
- }
- default: {
- emsgf(_("E474: Trailing characters: %.*s"), LENP(p, e));
- goto json_decode_string_fail;
- }
+ case NL:
+ case ' ':
+ case TAB:
+ case CAR:
+ break;
+ default:
+ emsgf(_("E474: Trailing characters: %.*s"), LENP(p, e));
+ goto json_decode_string_fail;
}
}
if (kv_size(stack) == 1 && kv_size(container_stack) == 0) {
*rettv = kv_pop(stack).val;
goto json_decode_string_ret;
}
- emsgf(_("E474: Unexpected end of input: %.*s"), (int) buf_len, buf);
+ emsgf(_("E474: Unexpected end of input: %.*s"), (int)buf_len, buf);
json_decode_string_fail:
ret = FAIL;
while (kv_size(stack)) {
@@ -944,192 +925,183 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
switch (mobj.type) {
- case MSGPACK_OBJECT_NIL: {
+ case MSGPACK_OBJECT_NIL:
+ *rettv = (typval_T) {
+ .v_type = VAR_SPECIAL,
+ .v_lock = VAR_UNLOCKED,
+ .vval = { .v_special = kSpecialVarNull },
+ };
+ break;
+ case MSGPACK_OBJECT_BOOLEAN:
+ *rettv = (typval_T) {
+ .v_type = VAR_BOOL,
+ .v_lock = VAR_UNLOCKED,
+ .vval = {
+ .v_bool = mobj.via.boolean ? kBoolVarTrue : kBoolVarFalse
+ },
+ };
+ break;
+ case MSGPACK_OBJECT_POSITIVE_INTEGER:
+ if (mobj.via.u64 <= VARNUMBER_MAX) {
*rettv = (typval_T) {
- .v_type = VAR_SPECIAL,
+ .v_type = VAR_NUMBER,
.v_lock = VAR_UNLOCKED,
- .vval = { .v_special = kSpecialVarNull },
+ .vval = { .v_number = (varnumber_T)mobj.via.u64 },
};
- break;
+ } else {
+ list_T *const list = tv_list_alloc(4);
+ tv_list_ref(list);
+ create_special_dict(rettv, kMPInteger, ((typval_T) {
+ .v_type = VAR_LIST,
+ .v_lock = VAR_UNLOCKED,
+ .vval = { .v_list = list },
+ }));
+ uint64_t n = mobj.via.u64;
+ tv_list_append_number(list, 1);
+ tv_list_append_number(list, (varnumber_T)((n >> 62) & 0x3));
+ tv_list_append_number(list, (varnumber_T)((n >> 31) & 0x7FFFFFFF));
+ tv_list_append_number(list, (varnumber_T)(n & 0x7FFFFFFF));
}
- case MSGPACK_OBJECT_BOOLEAN: {
+ break;
+ case MSGPACK_OBJECT_NEGATIVE_INTEGER:
+ if (mobj.via.i64 >= VARNUMBER_MIN) { // -V547
*rettv = (typval_T) {
- .v_type = VAR_BOOL,
+ .v_type = VAR_NUMBER,
.v_lock = VAR_UNLOCKED,
- .vval = {
- .v_bool = mobj.via.boolean ? kBoolVarTrue : kBoolVarFalse
- },
+ .vval = { .v_number = (varnumber_T)mobj.via.i64 },
};
- break;
- }
- case MSGPACK_OBJECT_POSITIVE_INTEGER: {
- if (mobj.via.u64 <= VARNUMBER_MAX) {
- *rettv = (typval_T) {
- .v_type = VAR_NUMBER,
- .v_lock = VAR_UNLOCKED,
- .vval = { .v_number = (varnumber_T) mobj.via.u64 },
- };
- } else {
- list_T *const list = tv_list_alloc(4);
- tv_list_ref(list);
- create_special_dict(rettv, kMPInteger, ((typval_T) {
- .v_type = VAR_LIST,
- .v_lock = VAR_UNLOCKED,
- .vval = { .v_list = list },
- }));
- uint64_t n = mobj.via.u64;
- tv_list_append_number(list, 1);
- tv_list_append_number(list, (varnumber_T)((n >> 62) & 0x3));
- tv_list_append_number(list, (varnumber_T)((n >> 31) & 0x7FFFFFFF));
- tv_list_append_number(list, (varnumber_T)(n & 0x7FFFFFFF));
- }
- break;
- }
- case MSGPACK_OBJECT_NEGATIVE_INTEGER: {
- if (mobj.via.i64 >= VARNUMBER_MIN) { // -V547
- *rettv = (typval_T) {
- .v_type = VAR_NUMBER,
- .v_lock = VAR_UNLOCKED,
- .vval = { .v_number = (varnumber_T) mobj.via.i64 },
- };
- } else {
- list_T *const list = tv_list_alloc(4);
- tv_list_ref(list);
- create_special_dict(rettv, kMPInteger, ((typval_T) {
- .v_type = VAR_LIST,
- .v_lock = VAR_UNLOCKED,
- .vval = { .v_list = list },
- }));
- uint64_t n = -((uint64_t)mobj.via.i64);
- tv_list_append_number(list, -1);
- tv_list_append_number(list, (varnumber_T)((n >> 62) & 0x3));
- tv_list_append_number(list, (varnumber_T)((n >> 31) & 0x7FFFFFFF));
- tv_list_append_number(list, (varnumber_T)(n & 0x7FFFFFFF));
- }
- break;
+ } else {
+ list_T *const list = tv_list_alloc(4);
+ tv_list_ref(list);
+ create_special_dict(rettv, kMPInteger, ((typval_T) {
+ .v_type = VAR_LIST,
+ .v_lock = VAR_UNLOCKED,
+ .vval = { .v_list = list },
+ }));
+ uint64_t n = -((uint64_t)mobj.via.i64);
+ tv_list_append_number(list, -1);
+ tv_list_append_number(list, (varnumber_T)((n >> 62) & 0x3));
+ tv_list_append_number(list, (varnumber_T)((n >> 31) & 0x7FFFFFFF));
+ tv_list_append_number(list, (varnumber_T)(n & 0x7FFFFFFF));
}
+ break;
#ifdef NVIM_MSGPACK_HAS_FLOAT32
- case MSGPACK_OBJECT_FLOAT32:
- case MSGPACK_OBJECT_FLOAT64:
+ case MSGPACK_OBJECT_FLOAT32:
+ case MSGPACK_OBJECT_FLOAT64:
#else
- case MSGPACK_OBJECT_FLOAT:
+ case MSGPACK_OBJECT_FLOAT:
#endif
- {
- *rettv = (typval_T) {
- .v_type = VAR_FLOAT,
- .v_lock = VAR_UNLOCKED,
- .vval = { .v_float = mobj.via.f64 },
- };
- break;
+ *rettv = (typval_T) {
+ .v_type = VAR_FLOAT,
+ .v_lock = VAR_UNLOCKED,
+ .vval = { .v_float = mobj.via.f64 },
+ };
+ break;
+ case MSGPACK_OBJECT_STR:
+ *rettv = decode_string(mobj.via.bin.ptr, mobj.via.bin.size, kTrue, false,
+ false);
+ if (rettv->v_type == VAR_UNKNOWN) {
+ return FAIL;
}
- case MSGPACK_OBJECT_STR: {
- *rettv = decode_string(mobj.via.bin.ptr, mobj.via.bin.size, kTrue, false,
- false);
- if (rettv->v_type == VAR_UNKNOWN) {
- return FAIL;
- }
- break;
+ break;
+ case MSGPACK_OBJECT_BIN:
+ *rettv = decode_string(mobj.via.bin.ptr, mobj.via.bin.size, kNone, true,
+ false);
+ if (rettv->v_type == VAR_UNKNOWN) {
+ return FAIL;
}
- case MSGPACK_OBJECT_BIN: {
- *rettv = decode_string(mobj.via.bin.ptr, mobj.via.bin.size, kNone, true,
- false);
- if (rettv->v_type == VAR_UNKNOWN) {
+ break;
+ case MSGPACK_OBJECT_ARRAY: {
+ list_T *const list = tv_list_alloc((ptrdiff_t)mobj.via.array.size);
+ tv_list_ref(list);
+ *rettv = (typval_T) {
+ .v_type = VAR_LIST,
+ .v_lock = VAR_UNLOCKED,
+ .vval = { .v_list = list },
+ };
+ for (size_t i = 0; i < mobj.via.array.size; i++) {
+ // Not populated yet, need to create list item to push.
+ tv_list_append_owned_tv(list, (typval_T) { .v_type = VAR_UNKNOWN });
+ if (msgpack_to_vim(mobj.via.array.ptr[i],
+ TV_LIST_ITEM_TV(tv_list_last(list)))
+ == FAIL) {
return FAIL;
}
- break;
}
- case MSGPACK_OBJECT_ARRAY: {
- list_T *const list = tv_list_alloc((ptrdiff_t)mobj.via.array.size);
- tv_list_ref(list);
- *rettv = (typval_T) {
- .v_type = VAR_LIST,
- .v_lock = VAR_UNLOCKED,
- .vval = { .v_list = list },
- };
- for (size_t i = 0; i < mobj.via.array.size; i++) {
- // Not populated yet, need to create list item to push.
- tv_list_append_owned_tv(list, (typval_T) { .v_type = VAR_UNKNOWN });
- if (msgpack_to_vim(mobj.via.array.ptr[i],
- TV_LIST_ITEM_TV(tv_list_last(list)))
- == FAIL) {
- return FAIL;
- }
+ break;
+ }
+ case MSGPACK_OBJECT_MAP: {
+ for (size_t i = 0; i < mobj.via.map.size; i++) {
+ if (mobj.via.map.ptr[i].key.type != MSGPACK_OBJECT_STR
+ || mobj.via.map.ptr[i].key.via.str.size == 0
+ || memchr(mobj.via.map.ptr[i].key.via.str.ptr, NUL,
+ mobj.via.map.ptr[i].key.via.str.size) != NULL) {
+ goto msgpack_to_vim_generic_map;
}
- break;
}
- case MSGPACK_OBJECT_MAP: {
- for (size_t i = 0; i < mobj.via.map.size; i++) {
- if (mobj.via.map.ptr[i].key.type != MSGPACK_OBJECT_STR
- || mobj.via.map.ptr[i].key.via.str.size == 0
- || memchr(mobj.via.map.ptr[i].key.via.str.ptr, NUL,
- mobj.via.map.ptr[i].key.via.str.size) != NULL) {
- goto msgpack_to_vim_generic_map;
- }
+ dict_T *const dict = tv_dict_alloc();
+ dict->dv_refcount++;
+ *rettv = (typval_T) {
+ .v_type = VAR_DICT,
+ .v_lock = VAR_UNLOCKED,
+ .vval = { .v_dict = dict },
+ };
+ for (size_t i = 0; i < mobj.via.map.size; i++) {
+ dictitem_T *const di = xmallocz(offsetof(dictitem_T, di_key)
+ + mobj.via.map.ptr[i].key.via.str.size);
+ memcpy(&di->di_key[0], mobj.via.map.ptr[i].key.via.str.ptr,
+ mobj.via.map.ptr[i].key.via.str.size);
+ di->di_tv.v_type = VAR_UNKNOWN;
+ if (tv_dict_add(dict, di) == FAIL) {
+ // Duplicate key: fallback to generic map
+ tv_clear(rettv);
+ xfree(di);
+ goto msgpack_to_vim_generic_map;
}
- dict_T *const dict = tv_dict_alloc();
- dict->dv_refcount++;
- *rettv = (typval_T) {
- .v_type = VAR_DICT,
- .v_lock = VAR_UNLOCKED,
- .vval = { .v_dict = dict },
- };
- for (size_t i = 0; i < mobj.via.map.size; i++) {
- dictitem_T *const di = xmallocz(offsetof(dictitem_T, di_key)
- + mobj.via.map.ptr[i].key.via.str.size);
- memcpy(&di->di_key[0], mobj.via.map.ptr[i].key.via.str.ptr,
- mobj.via.map.ptr[i].key.via.str.size);
- di->di_tv.v_type = VAR_UNKNOWN;
- if (tv_dict_add(dict, di) == FAIL) {
- // Duplicate key: fallback to generic map
- tv_clear(rettv);
- xfree(di);
- goto msgpack_to_vim_generic_map;
- }
- if (msgpack_to_vim(mobj.via.map.ptr[i].val, &di->di_tv) == FAIL) {
- return FAIL;
- }
+ if (msgpack_to_vim(mobj.via.map.ptr[i].val, &di->di_tv) == FAIL) {
+ return FAIL;
}
- break;
+ }
+ break;
msgpack_to_vim_generic_map: {}
- list_T *const list = decode_create_map_special_dict(
- rettv, (ptrdiff_t)mobj.via.map.size);
- for (size_t i = 0; i < mobj.via.map.size; i++) {
- list_T *const kv_pair = tv_list_alloc(2);
- tv_list_append_list(list, kv_pair);
+ list_T *const list = decode_create_map_special_dict(rettv, (ptrdiff_t)mobj.via.map.size);
+ for (size_t i = 0; i < mobj.via.map.size; i++) {
+ list_T *const kv_pair = tv_list_alloc(2);
+ tv_list_append_list(list, kv_pair);
- typval_T key_tv = { .v_type = VAR_UNKNOWN };
- if (msgpack_to_vim(mobj.via.map.ptr[i].key, &key_tv) == FAIL) {
- tv_clear(&key_tv);
- return FAIL;
- }
- tv_list_append_owned_tv(kv_pair, key_tv);
+ typval_T key_tv = { .v_type = VAR_UNKNOWN };
+ if (msgpack_to_vim(mobj.via.map.ptr[i].key, &key_tv) == FAIL) {
+ tv_clear(&key_tv);
+ return FAIL;
+ }
+ tv_list_append_owned_tv(kv_pair, key_tv);
- typval_T val_tv = { .v_type = VAR_UNKNOWN };
- if (msgpack_to_vim(mobj.via.map.ptr[i].val, &val_tv) == FAIL) {
- tv_clear(&val_tv);
- return FAIL;
- }
- tv_list_append_owned_tv(kv_pair, val_tv);
+ typval_T val_tv = { .v_type = VAR_UNKNOWN };
+ if (msgpack_to_vim(mobj.via.map.ptr[i].val, &val_tv) == FAIL) {
+ tv_clear(&val_tv);
+ return FAIL;
}
- break;
+ tv_list_append_owned_tv(kv_pair, val_tv);
}
- case MSGPACK_OBJECT_EXT: {
- list_T *const list = tv_list_alloc(2);
- tv_list_ref(list);
- tv_list_append_number(list, mobj.via.ext.type);
- list_T *const ext_val_list = tv_list_alloc(kListLenMayKnow);
- tv_list_append_list(list, ext_val_list);
- create_special_dict(rettv, kMPExt, ((typval_T) {
+ break;
+ }
+ case MSGPACK_OBJECT_EXT: {
+ list_T *const list = tv_list_alloc(2);
+ tv_list_ref(list);
+ tv_list_append_number(list, mobj.via.ext.type);
+ list_T *const ext_val_list = tv_list_alloc(kListLenMayKnow);
+ tv_list_append_list(list, ext_val_list);
+ create_special_dict(rettv, kMPExt, ((typval_T) {
.v_type = VAR_LIST,
.v_lock = VAR_UNLOCKED,
.vval = { .v_list = list },
}));
- if (encode_list_write((void *) ext_val_list, mobj.via.ext.ptr,
- mobj.via.ext.size) == -1) {
- return FAIL;
- }
- break;
+ if (encode_list_write((void *)ext_val_list, mobj.via.ext.ptr,
+ mobj.via.ext.size) == -1) {
+ return FAIL;
}
+ break;
+ }
}
return OK;
}
diff --git a/src/nvim/eval/encode.c b/src/nvim/eval/encode.c
index a4d7af7971..1c0afc89f5 100644
--- a/src/nvim/eval/encode.c
+++ b/src/nvim/eval/encode.c
@@ -7,27 +7,27 @@
///
/// Split out from eval.c.
-#include <msgpack.h>
-#include <inttypes.h>
-#include <stddef.h>
#include <assert.h>
+#include <inttypes.h>
#include <math.h>
+#include <msgpack.h>
+#include <stddef.h>
-#include "nvim/eval/encode.h"
+#include "nvim/ascii.h"
#include "nvim/buffer_defs.h"
+#include "nvim/charset.h" // vim_isprintc()
#include "nvim/eval.h"
+#include "nvim/eval/encode.h"
#include "nvim/eval/typval.h"
+#include "nvim/eval/typval_encode.h"
#include "nvim/garray.h"
-#include "nvim/mbyte.h"
+#include "nvim/lib/kvec.h"
+#include "nvim/macros.h"
#include "nvim/math.h"
-#include "nvim/message.h"
+#include "nvim/mbyte.h"
#include "nvim/memory.h"
-#include "nvim/charset.h" // vim_isprintc()
-#include "nvim/macros.h"
-#include "nvim/ascii.h"
+#include "nvim/message.h"
#include "nvim/vim.h" // For _()
-#include "nvim/lib/kvec.h"
-#include "nvim/eval/typval_encode.h"
#define ga_concat(a, b) ga_concat(a, (char_u *)b)
#define utf_ptr2char(b) utf_ptr2char((char_u *)b)
@@ -47,6 +47,14 @@ const char *const encode_special_var_names[] = {
# include "eval/encode.c.generated.h"
#endif
+/// Msgpack callback for writing to a Blob
+int encode_blob_write(void *const data, const char *const buf, const size_t len)
+ FUNC_ATTR_NONNULL_ARG(1)
+{
+ ga_concat_len(&((blob_T *)data)->bv_ga, buf, len);
+ return (int)len;
+}
+
/// Msgpack callback for writing to readfile()-style list
int encode_list_write(void *const data, const char *const buf, const size_t len)
FUNC_ATTR_NONNULL_ARG(1)
@@ -54,7 +62,7 @@ int encode_list_write(void *const data, const char *const buf, const size_t len)
if (len == 0) {
return 0;
}
- list_T *const list = (list_T *) data;
+ list_T *const list = (list_T *)data;
const char *const end = buf + len;
const char *line_end = buf;
listitem_T *li = tv_list_last(list);
@@ -66,8 +74,7 @@ int encode_list_write(void *const data, const char *const buf, const size_t len)
const size_t line_length = (size_t)(line_end - buf);
char *str = (char *)TV_LIST_ITEM_TV(li)->vval.v_string;
const size_t li_len = (str == NULL ? 0 : strlen(str));
- TV_LIST_ITEM_TV(li)->vval.v_string = xrealloc(
- str, li_len + line_length + 1);
+ TV_LIST_ITEM_TV(li)->vval.v_string = xrealloc(str, li_len + line_length + 1);
str = (char *)TV_LIST_ITEM_TV(li)->vval.v_string + li_len;
memcpy(str, buf, line_length);
str[line_length] = 0;
@@ -78,7 +85,7 @@ int encode_list_write(void *const data, const char *const buf, const size_t len)
while (line_end < end) {
const char *line_start = line_end;
- line_end = xmemscan(line_start, NL, (size_t) (end - line_start));
+ line_end = xmemscan(line_start, NL, (size_t)(end - line_start));
char *str = NULL;
if (line_end != line_start) {
const size_t line_length = (size_t)(line_end - line_start);
@@ -125,75 +132,70 @@ static int conv_error(const char *const msg, const MPConvStack *const mpstack,
}
MPConvStackVal v = kv_A(*mpstack, i);
switch (v.type) {
- case kMPConvDict: {
- typval_T key_tv = {
- .v_type = VAR_STRING,
- .vval = { .v_string = (v.data.d.hi == NULL
+ case kMPConvDict: {
+ typval_T key_tv = {
+ .v_type = VAR_STRING,
+ .vval = { .v_string = (v.data.d.hi == NULL
? v.data.d.dict->dv_hashtab.ht_array
: (v.data.d.hi - 1))->hi_key },
- };
- char *const key = encode_tv2string(&key_tv, NULL);
- vim_snprintf((char *) IObuff, IOSIZE, key_msg, key);
- xfree(key);
- ga_concat(&msg_ga, IObuff);
- break;
- }
- case kMPConvPairs:
- case kMPConvList: {
- const int idx = (v.data.l.li == tv_list_first(v.data.l.list)
+ };
+ char *const key = encode_tv2string(&key_tv, NULL);
+ vim_snprintf((char *)IObuff, IOSIZE, key_msg, key);
+ xfree(key);
+ ga_concat(&msg_ga, IObuff);
+ break;
+ }
+ case kMPConvPairs:
+ case kMPConvList: {
+ const int idx = (v.data.l.li == tv_list_first(v.data.l.list)
? 0
: (v.data.l.li == NULL
? tv_list_len(v.data.l.list) - 1
- : (int)tv_list_idx_of_item(
- v.data.l.list,
- TV_LIST_ITEM_PREV(v.data.l.list,
- v.data.l.li))));
- const listitem_T *const li = (v.data.l.li == NULL
+ : (int)tv_list_idx_of_item(v.data.l.list,
+ TV_LIST_ITEM_PREV(v.data.l.list,
+ v.data.l.li))));
+ const listitem_T *const li = (v.data.l.li == NULL
? tv_list_last(v.data.l.list)
: TV_LIST_ITEM_PREV(v.data.l.list,
v.data.l.li));
- if (v.type == kMPConvList
- || li == NULL
- || (TV_LIST_ITEM_TV(li)->v_type != VAR_LIST
- && tv_list_len(TV_LIST_ITEM_TV(li)->vval.v_list) <= 0)) {
- vim_snprintf((char *)IObuff, IOSIZE, idx_msg, idx);
- ga_concat(&msg_ga, IObuff);
- } else {
- assert(li != NULL);
- listitem_T *const first_item =
- tv_list_first(TV_LIST_ITEM_TV(li)->vval.v_list);
- assert(first_item != NULL);
- typval_T key_tv = *TV_LIST_ITEM_TV(first_item);
- char *const key = encode_tv2echo(&key_tv, NULL);
- vim_snprintf((char *) IObuff, IOSIZE, key_pair_msg, key, idx);
- xfree(key);
- ga_concat(&msg_ga, IObuff);
- }
- break;
+ if (v.type == kMPConvList
+ || li == NULL
+ || (TV_LIST_ITEM_TV(li)->v_type != VAR_LIST
+ && tv_list_len(TV_LIST_ITEM_TV(li)->vval.v_list) <= 0)) {
+ vim_snprintf((char *)IObuff, IOSIZE, idx_msg, idx);
+ ga_concat(&msg_ga, IObuff);
+ } else {
+ assert(li != NULL);
+ listitem_T *const first_item =
+ tv_list_first(TV_LIST_ITEM_TV(li)->vval.v_list);
+ assert(first_item != NULL);
+ typval_T key_tv = *TV_LIST_ITEM_TV(first_item);
+ char *const key = encode_tv2echo(&key_tv, NULL);
+ vim_snprintf((char *)IObuff, IOSIZE, key_pair_msg, key, idx);
+ xfree(key);
+ ga_concat(&msg_ga, IObuff);
}
- case kMPConvPartial: {
- switch (v.data.p.stage) {
- case kMPConvPartialArgs: {
- abort();
- break;
- }
- case kMPConvPartialSelf: {
- ga_concat(&msg_ga, partial_arg_msg);
- break;
- }
- case kMPConvPartialEnd: {
- ga_concat(&msg_ga, partial_self_msg);
- break;
- }
- }
+ break;
+ }
+ case kMPConvPartial:
+ switch (v.data.p.stage) {
+ case kMPConvPartialArgs:
+ abort();
break;
- }
- case kMPConvPartialList: {
- const int idx = (int)(v.data.a.arg - v.data.a.argv) - 1;
- vim_snprintf((char *)IObuff, IOSIZE, partial_arg_i_msg, idx);
- ga_concat(&msg_ga, IObuff);
+ case kMPConvPartialSelf:
+ ga_concat(&msg_ga, partial_arg_msg);
+ break;
+ case kMPConvPartialEnd:
+ ga_concat(&msg_ga, partial_self_msg);
break;
}
+ break;
+ case kMPConvPartialList: {
+ const int idx = (int)(v.data.a.arg - v.data.a.argv) - 1;
+ vim_snprintf((char *)IObuff, IOSIZE, partial_arg_i_msg, idx);
+ ga_concat(&msg_ga, IObuff);
+ break;
+ }
}
}
emsgf(msg, _(objname), (kv_size(*mpstack) == 0
@@ -211,8 +213,7 @@ static int conv_error(const char *const msg, const MPConvStack *const mpstack,
/// zero.
///
/// @return true in case of success, false in case of failure.
-bool encode_vim_list_to_buf(const list_T *const list, size_t *const ret_len,
- char **const ret_buf)
+bool encode_vim_list_to_buf(const list_T *const list, size_t *const ret_len, char **const ret_buf)
FUNC_ATTR_NONNULL_ARG(2, 3) FUNC_ATTR_WARN_UNUSED_RESULT
{
size_t len = 0;
@@ -256,8 +257,8 @@ bool encode_vim_list_to_buf(const list_T *const list, size_t *const ret_len,
/// @return OK when reading was finished, FAIL in case of error (i.e. list item
/// was not a string), NOTDONE if reading was successful, but there are
/// more bytes to read.
-int encode_read_from_list(ListReaderState *const state, char *const buf,
- const size_t nbuf, size_t *const read_bytes)
+int encode_read_from_list(ListReaderState *const state, char *const buf, const size_t nbuf,
+ size_t *const read_bytes)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
char *const buf_end = buf + nbuf;
@@ -268,13 +269,13 @@ int encode_read_from_list(ListReaderState *const state, char *const buf,
for (size_t i = state->offset; i < state->li_length && p < buf_end; i++) {
assert(TV_LIST_ITEM_TV(state->li)->vval.v_string != NULL);
const char ch = (char)(
- TV_LIST_ITEM_TV(state->li)->vval.v_string[state->offset++]);
+ TV_LIST_ITEM_TV(state->li)->vval.v_string[state->offset++]);
*p++ = (char)((char)ch == (char)NL ? (char)NUL : (char)ch);
}
if (p < buf_end) {
state->li = TV_LIST_ITEM_NEXT(state->list, state->li);
if (state->li == NULL) {
- *read_bytes = (size_t) (p - buf);
+ *read_bytes = (size_t)(p - buf);
return OK;
}
*p++ = NL;
@@ -296,157 +297,181 @@ int encode_read_from_list(ListReaderState *const state, char *const buf,
}
#define TYPVAL_ENCODE_CONV_STRING(tv, buf, len) \
- do { \
- const char *const buf_ = (const char *) buf; \
- if (buf == NULL) { \
- ga_concat(gap, "''"); \
- } else { \
- const size_t len_ = (len); \
- ga_grow(gap, (int) (2 + len_ + memcnt(buf_, '\'', len_))); \
- ga_append(gap, '\''); \
- for (size_t i_ = 0; i_ < len_; i_++) { \
- if (buf_[i_] == '\'') { \
- ga_append(gap, '\''); \
- } \
- ga_append(gap, buf_[i_]); \
+ do { \
+ const char *const buf_ = (const char *)buf; \
+ if (buf == NULL) { \
+ ga_concat(gap, "''"); \
+ } else { \
+ const size_t len_ = (len); \
+ ga_grow(gap, (int)(2 + len_ + memcnt(buf_, '\'', len_))); \
+ ga_append(gap, '\''); \
+ for (size_t i_ = 0; i_ < len_; i_++) { \
+ if (buf_[i_] == '\'') { \
+ ga_append(gap, '\''); \
} \
- ga_append(gap, '\''); \
+ ga_append(gap, buf_[i_]); \
} \
- } while (0)
+ ga_append(gap, '\''); \
+ } \
+ } while (0)
#define TYPVAL_ENCODE_CONV_STR_STRING(tv, buf, len) \
- TYPVAL_ENCODE_CONV_STRING(tv, buf, len)
+ TYPVAL_ENCODE_CONV_STRING(tv, buf, len)
#define TYPVAL_ENCODE_CONV_EXT_STRING(tv, buf, len, type)
-#define TYPVAL_ENCODE_CONV_NUMBER(tv, num) \
- do { \
+#define TYPVAL_ENCODE_CONV_BLOB(tv, blob, len) \
+ do { \
+ const blob_T *const blob_ = (blob); \
+ const int len_ = (len); \
+ if (len_ == 0) { \
+ ga_concat(gap, "0z"); \
+ } else { \
+ /* Allocate space for "0z", the two hex chars per byte, and a */ \
+ /* "." separator after every eight hex chars. */ \
+ /* Example: "0z00112233.44556677.8899" */ \
+ ga_grow(gap, 2 + 2 * len_ + (len_ - 1) / 4); \
+ ga_concat(gap, "0z"); \
char numbuf[NUMBUFLEN]; \
- vim_snprintf(numbuf, ARRAY_SIZE(numbuf), "%" PRId64, (int64_t) (num)); \
- ga_concat(gap, numbuf); \
- } while (0)
+ for (int i_ = 0; i_ < len_; i_++) { \
+ if (i_ > 0 && (i_ & 3) == 0) { \
+ ga_append(gap, '.'); \
+ } \
+ vim_snprintf((char *)numbuf, ARRAY_SIZE(numbuf), "%02X", \
+ (int)tv_blob_get(blob_, i_)); \
+ ga_concat(gap, numbuf); \
+ } \
+ } \
+ } while (0)
+
+#define TYPVAL_ENCODE_CONV_NUMBER(tv, num) \
+ do { \
+ char numbuf[NUMBUFLEN]; \
+ vim_snprintf(numbuf, ARRAY_SIZE(numbuf), "%" PRId64, (int64_t)(num)); \
+ ga_concat(gap, numbuf); \
+ } while (0)
#define TYPVAL_ENCODE_CONV_FLOAT(tv, flt) \
- do { \
- const float_T flt_ = (flt); \
- switch (xfpclassify(flt_)) { \
- case FP_NAN: { \
- ga_concat(gap, (char_u *) "str2float('nan')"); \
- break; \
- } \
- case FP_INFINITE: { \
- if (flt_ < 0) { \
- ga_append(gap, '-'); \
- } \
- ga_concat(gap, (char_u *) "str2float('inf')"); \
- break; \
- } \
- default: { \
- char numbuf[NUMBUFLEN]; \
- vim_snprintf(numbuf, ARRAY_SIZE(numbuf), "%g", flt_); \
- ga_concat(gap, (char_u *) numbuf); \
- } \
+ do { \
+ const float_T flt_ = (flt); \
+ switch (xfpclassify(flt_)) { \
+ case FP_NAN: { \
+ ga_concat(gap, (char_u *)"str2float('nan')"); \
+ break; \
+ } \
+ case FP_INFINITE: { \
+ if (flt_ < 0) { \
+ ga_append(gap, '-'); \
} \
- } while (0)
+ ga_concat(gap, (char_u *)"str2float('inf')"); \
+ break; \
+ } \
+ default: { \
+ char numbuf[NUMBUFLEN]; \
+ vim_snprintf(numbuf, ARRAY_SIZE(numbuf), "%g", flt_); \
+ ga_concat(gap, (char_u *)numbuf); \
+ } \
+ } \
+ } while (0)
#define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun) \
- do { \
- const char *const fun_ = (const char *)(fun); \
- if (fun_ == NULL) { \
- internal_error("string(): NULL function name"); \
- ga_concat(gap, "function(NULL"); \
- } else { \
- ga_concat(gap, "function("); \
- TYPVAL_ENCODE_CONV_STRING(tv, fun_, strlen(fun_)); \
- }\
- } while (0)
+ do { \
+ const char *const fun_ = (const char *)(fun); \
+ if (fun_ == NULL) { \
+ internal_error("string(): NULL function name"); \
+ ga_concat(gap, "function(NULL"); \
+ } else { \
+ ga_concat(gap, "function("); \
+ TYPVAL_ENCODE_CONV_STRING(tv, fun_, strlen(fun_)); \
+ }\
+ } while (0)
#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, len) \
- do { \
- if (len != 0) { \
- ga_concat(gap, ", "); \
- } \
- } while (0)
+ do { \
+ if (len != 0) { \
+ ga_concat(gap, ", "); \
+ } \
+ } while (0)
#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, len) \
- do { \
- if ((ptrdiff_t)len != -1) { \
- ga_concat(gap, ", "); \
- } \
- } while (0)
+ do { \
+ if ((ptrdiff_t)len != -1) { \
+ ga_concat(gap, ", "); \
+ } \
+ } while (0)
#define TYPVAL_ENCODE_CONV_FUNC_END(tv) \
- ga_append(gap, ')')
+ ga_append(gap, ')')
#define TYPVAL_ENCODE_CONV_EMPTY_LIST(tv) \
- ga_concat(gap, "[]")
+ ga_concat(gap, "[]")
#define TYPVAL_ENCODE_CONV_LIST_START(tv, len) \
- ga_append(gap, '[')
+ ga_append(gap, '[')
#define TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START(tv, mpsv)
#define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, dict) \
- ga_concat(gap, "{}")
+ ga_concat(gap, "{}")
#define TYPVAL_ENCODE_CONV_NIL(tv) \
- ga_concat(gap, "v:null")
+ ga_concat(gap, "v:null")
#define TYPVAL_ENCODE_CONV_BOOL(tv, num) \
- ga_concat(gap, ((num)? "v:true": "v:false"))
+ ga_concat(gap, ((num)? "v:true": "v:false"))
#define TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(tv, num)
#define TYPVAL_ENCODE_CONV_DICT_START(tv, dict, len) \
- ga_append(gap, '{')
+ ga_append(gap, '{')
#define TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START(tv, dict, mpsv)
#define TYPVAL_ENCODE_CONV_DICT_END(tv, dict) \
- ga_append(gap, '}')
+ ga_append(gap, '}')
#define TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(tv, dict) \
- ga_concat(gap, ": ")
+ ga_concat(gap, ": ")
#define TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(tv, dict) \
- ga_concat(gap, ", ")
+ ga_concat(gap, ", ")
#define TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK(label, key)
#define TYPVAL_ENCODE_CONV_LIST_END(tv) \
- ga_append(gap, ']')
+ ga_append(gap, ']')
#define TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(tv) \
- TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(tv, NULL)
+ TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(tv, NULL)
#define TYPVAL_ENCODE_CONV_RECURSE(val, conv_type) \
- do { \
- if (!did_echo_string_emsg) { \
- /* Only give this message once for a recursive call to avoid */ \
- /* flooding the user with errors. */ \
- did_echo_string_emsg = true; \
- EMSG(_("E724: unable to correctly dump variable " \
- "with self-referencing container")); \
- } \
- char ebuf[NUMBUFLEN + 7]; \
- size_t backref = 0; \
- for (; backref < kv_size(*mpstack); backref++) { \
- const MPConvStackVal mpval = kv_A(*mpstack, backref); \
- if (mpval.type == conv_type) { \
- if (conv_type == kMPConvDict) { \
- if ((void *) mpval.data.d.dict == (void *) (val)) { \
- break; \
- } \
- } else if (conv_type == kMPConvList) { \
- if ((void *) mpval.data.l.list == (void *) (val)) { \
- break; \
- } \
+ do { \
+ if (!did_echo_string_emsg) { \
+ /* Only give this message once for a recursive call to avoid */ \
+ /* flooding the user with errors. */ \
+ did_echo_string_emsg = true; \
+ EMSG(_("E724: unable to correctly dump variable " \
+ "with self-referencing container")); \
+ } \
+ char ebuf[NUMBUFLEN + 7]; \
+ size_t backref = 0; \
+ for (; backref < kv_size(*mpstack); backref++) { \
+ const MPConvStackVal mpval = kv_A(*mpstack, backref); \
+ if (mpval.type == conv_type) { \
+ if (conv_type == kMPConvDict) { \
+ if ((void *)mpval.data.d.dict == (void *)(val)) { \
+ break; \
+ } \
+ } else if (conv_type == kMPConvList) { \
+ if ((void *)mpval.data.l.list == (void *)(val)) { \
+ break; \
} \
} \
} \
- vim_snprintf(ebuf, ARRAY_SIZE(ebuf), "{E724@%zu}", backref); \
- ga_concat(gap, &ebuf[0]); \
- } while (0)
+ } \
+ vim_snprintf(ebuf, ARRAY_SIZE(ebuf), "{E724@%zu}", backref); \
+ ga_concat(gap, &ebuf[0]); \
+ } while (0)
#define TYPVAL_ENCODE_ALLOW_SPECIALS false
@@ -462,31 +487,31 @@ int encode_read_from_list(ListReaderState *const state, char *const buf,
#undef TYPVAL_ENCODE_CONV_RECURSE
#define TYPVAL_ENCODE_CONV_RECURSE(val, conv_type) \
- do { \
- char ebuf[NUMBUFLEN + 7]; \
- size_t backref = 0; \
- for (; backref < kv_size(*mpstack); backref++) { \
- const MPConvStackVal mpval = kv_A(*mpstack, backref); \
- if (mpval.type == conv_type) { \
- if (conv_type == kMPConvDict) { \
- if ((void *) mpval.data.d.dict == (void *) val) { \
- break; \
- } \
- } else if (conv_type == kMPConvList) { \
- if ((void *) mpval.data.l.list == (void *) val) { \
- break; \
- } \
+ do { \
+ char ebuf[NUMBUFLEN + 7]; \
+ size_t backref = 0; \
+ for (; backref < kv_size(*mpstack); backref++) { \
+ const MPConvStackVal mpval = kv_A(*mpstack, backref); \
+ if (mpval.type == conv_type) { \
+ if (conv_type == kMPConvDict) { \
+ if ((void *)mpval.data.d.dict == (void *)val) { \
+ break; \
+ } \
+ } else if (conv_type == kMPConvList) { \
+ if ((void *)mpval.data.l.list == (void *)val) { \
+ break; \
} \
} \
} \
- if (conv_type == kMPConvDict) { \
- vim_snprintf(ebuf, ARRAY_SIZE(ebuf), "{...@%zu}", backref); \
- } else { \
- vim_snprintf(ebuf, ARRAY_SIZE(ebuf), "[...@%zu]", backref); \
- } \
- ga_concat(gap, &ebuf[0]); \
- return OK; \
- } while (0)
+ } \
+ if (conv_type == kMPConvDict) { \
+ vim_snprintf(ebuf, ARRAY_SIZE(ebuf), "{...@%zu}", backref); \
+ } else { \
+ vim_snprintf(ebuf, ARRAY_SIZE(ebuf), "[...@%zu]", backref); \
+ } \
+ ga_concat(gap, &ebuf[0]); \
+ return OK; \
+ } while (0)
#define TYPVAL_ENCODE_SCOPE
#define TYPVAL_ENCODE_NAME echo
@@ -500,56 +525,56 @@ int encode_read_from_list(ListReaderState *const state, char *const buf,
#undef TYPVAL_ENCODE_CONV_RECURSE
#define TYPVAL_ENCODE_CONV_RECURSE(val, conv_type) \
- do { \
- if (!did_echo_string_emsg) { \
- /* Only give this message once for a recursive call to avoid */ \
- /* flooding the user with errors. */ \
- did_echo_string_emsg = true; \
- EMSG(_("E724: unable to correctly dump variable " \
- "with self-referencing container")); \
- } \
- } while (0)
+ do { \
+ if (!did_echo_string_emsg) { \
+ /* Only give this message once for a recursive call to avoid */ \
+ /* flooding the user with errors. */ \
+ did_echo_string_emsg = true; \
+ EMSG(_("E724: unable to correctly dump variable " \
+ "with self-referencing container")); \
+ } \
+ } while (0)
#undef TYPVAL_ENCODE_ALLOW_SPECIALS
#define TYPVAL_ENCODE_ALLOW_SPECIALS true
#undef TYPVAL_ENCODE_CONV_NIL
#define TYPVAL_ENCODE_CONV_NIL(tv) \
- ga_concat(gap, "null")
+ ga_concat(gap, "null")
#undef TYPVAL_ENCODE_CONV_BOOL
#define TYPVAL_ENCODE_CONV_BOOL(tv, num) \
- ga_concat(gap, ((num)? "true": "false"))
+ ga_concat(gap, ((num)? "true": "false"))
#undef TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER
#define TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(tv, num) \
- do { \
- char numbuf[NUMBUFLEN]; \
- vim_snprintf(numbuf, ARRAY_SIZE(numbuf), "%" PRIu64, (num)); \
- ga_concat(gap, numbuf); \
- } while (0)
+ do { \
+ char numbuf[NUMBUFLEN]; \
+ vim_snprintf(numbuf, ARRAY_SIZE(numbuf), "%" PRIu64, (num)); \
+ ga_concat(gap, numbuf); \
+ } while (0)
#undef TYPVAL_ENCODE_CONV_FLOAT
#define TYPVAL_ENCODE_CONV_FLOAT(tv, flt) \
- do { \
- const float_T flt_ = (flt); \
- switch (xfpclassify(flt_)) { \
- case FP_NAN: { \
- EMSG(_("E474: Unable to represent NaN value in JSON")); \
- return FAIL; \
- } \
- case FP_INFINITE: { \
- EMSG(_("E474: Unable to represent infinity in JSON")); \
- return FAIL; \
- } \
- default: { \
- char numbuf[NUMBUFLEN]; \
- vim_snprintf(numbuf, ARRAY_SIZE(numbuf), "%g", flt_); \
- ga_concat(gap, (char_u *) numbuf); \
- break; \
- } \
- } \
- } while (0)
+ do { \
+ const float_T flt_ = (flt); \
+ switch (xfpclassify(flt_)) { \
+ case FP_NAN: { \
+ EMSG(_("E474: Unable to represent NaN value in JSON")); \
+ return FAIL; \
+ } \
+ case FP_INFINITE: { \
+ EMSG(_("E474: Unable to represent infinity in JSON")); \
+ return FAIL; \
+ } \
+ default: { \
+ char numbuf[NUMBUFLEN]; \
+ vim_snprintf(numbuf, ARRAY_SIZE(numbuf), "%g", flt_); \
+ ga_concat(gap, (char_u *)numbuf); \
+ break; \
+ } \
+ } \
+ } while (0)
/// Escape sequences used in JSON
static const char escapes[][3] = {
@@ -571,8 +596,7 @@ static const char xdigits[] = "0123456789ABCDEF";
/// @param[in] len Converted string length.
///
/// @return OK in case of success, FAIL otherwise.
-static inline int convert_to_json_string(garray_T *const gap,
- const char *const buf,
+static inline int convert_to_json_string(garray_T *const gap, const char *const buf,
const size_t len)
FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_ALWAYS_INLINE
{
@@ -590,49 +614,47 @@ static inline int convert_to_json_string(garray_T *const gap,
// This is done to make resulting values displayable on screen also not from
// Neovim.
#define ENCODE_RAW(ch) \
- (ch >= 0x20 && utf_printable(ch))
+ (ch >= 0x20 && utf_printable(ch))
for (size_t i = 0; i < utf_len;) {
const int ch = utf_ptr2char(utf_buf + i);
const size_t shift = (ch == 0? 1: utf_ptr2len(utf_buf + i));
assert(shift > 0);
i += shift;
switch (ch) {
- case BS:
- case TAB:
- case NL:
- case FF:
- case CAR:
- case '"':
- case '\\': {
- str_len += 2;
- break;
- }
- default: {
- if (ch > 0x7F && shift == 1) {
- emsgf(_("E474: String \"%.*s\" contains byte that does not start "
- "any UTF-8 character"),
- (int)(utf_len - (i - shift)), utf_buf + i - shift);
- xfree(tofree);
- return FAIL;
- } else if ((SURROGATE_HI_START <= ch && ch <= SURROGATE_HI_END)
- || (SURROGATE_LO_START <= ch && ch <= SURROGATE_LO_END)) {
- emsgf(_("E474: UTF-8 string contains code point which belongs "
- "to a surrogate pair: %.*s"),
- (int)(utf_len - (i - shift)), utf_buf + i - shift);
- xfree(tofree);
- return FAIL;
- } else if (ENCODE_RAW(ch)) {
- str_len += shift;
- } else {
- str_len += ((sizeof("\\u1234") - 1)
- * (size_t) (1 + (ch >= SURROGATE_FIRST_CHAR)));
- }
- break;
+ case BS:
+ case TAB:
+ case NL:
+ case FF:
+ case CAR:
+ case '"':
+ case '\\':
+ str_len += 2;
+ break;
+ default:
+ if (ch > 0x7F && shift == 1) {
+ emsgf(_("E474: String \"%.*s\" contains byte that does not start "
+ "any UTF-8 character"),
+ (int)(utf_len - (i - shift)), utf_buf + i - shift);
+ xfree(tofree);
+ return FAIL;
+ } else if ((SURROGATE_HI_START <= ch && ch <= SURROGATE_HI_END)
+ || (SURROGATE_LO_START <= ch && ch <= SURROGATE_LO_END)) {
+ emsgf(_("E474: UTF-8 string contains code point which belongs "
+ "to a surrogate pair: %.*s"),
+ (int)(utf_len - (i - shift)), utf_buf + i - shift);
+ xfree(tofree);
+ return FAIL;
+ } else if (ENCODE_RAW(ch)) {
+ str_len += shift;
+ } else {
+ str_len += ((sizeof("\\u1234") - 1)
+ * (size_t)(1 + (ch >= SURROGATE_FIRST_CHAR)));
}
+ break;
}
}
ga_append(gap, '"');
- ga_grow(gap, (int) str_len);
+ ga_grow(gap, (int)str_len);
for (size_t i = 0; i < utf_len;) {
const int ch = utf_ptr2char(utf_buf + i);
const size_t shift = (ch == 0? 1: utf_char2len(ch));
@@ -640,46 +662,44 @@ static inline int convert_to_json_string(garray_T *const gap,
// Is false on invalid unicode, but this should already be handled.
assert(ch == 0 || shift == utf_ptr2len(utf_buf + i));
switch (ch) {
- case BS:
- case TAB:
- case NL:
- case FF:
- case CAR:
- case '"':
- case '\\': {
- ga_concat_len(gap, escapes[ch], 2);
- break;
- }
- default: {
- if (ENCODE_RAW(ch)) {
- ga_concat_len(gap, utf_buf + i, shift);
- } else if (ch < SURROGATE_FIRST_CHAR) {
- ga_concat_len(gap, ((const char[]) {
- '\\', 'u',
- xdigits[(ch >> (4 * 3)) & 0xF],
- xdigits[(ch >> (4 * 2)) & 0xF],
- xdigits[(ch >> (4 * 1)) & 0xF],
- xdigits[(ch >> (4 * 0)) & 0xF],
- }), sizeof("\\u1234") - 1);
- } else {
- const int tmp = ch - SURROGATE_FIRST_CHAR;
- const int hi = SURROGATE_HI_START + ((tmp >> 10) & ((1 << 10) - 1));
- const int lo = SURROGATE_LO_END + ((tmp >> 0) & ((1 << 10) - 1));
- ga_concat_len(gap, ((const char[]) {
- '\\', 'u',
- xdigits[(hi >> (4 * 3)) & 0xF],
- xdigits[(hi >> (4 * 2)) & 0xF],
- xdigits[(hi >> (4 * 1)) & 0xF],
- xdigits[(hi >> (4 * 0)) & 0xF],
- '\\', 'u',
- xdigits[(lo >> (4 * 3)) & 0xF],
- xdigits[(lo >> (4 * 2)) & 0xF],
- xdigits[(lo >> (4 * 1)) & 0xF],
- xdigits[(lo >> (4 * 0)) & 0xF],
- }), (sizeof("\\u1234") - 1) * 2);
- }
- break;
+ case BS:
+ case TAB:
+ case NL:
+ case FF:
+ case CAR:
+ case '"':
+ case '\\':
+ ga_concat_len(gap, escapes[ch], 2);
+ break;
+ default:
+ if (ENCODE_RAW(ch)) {
+ ga_concat_len(gap, utf_buf + i, shift);
+ } else if (ch < SURROGATE_FIRST_CHAR) {
+ ga_concat_len(gap, ((const char[]) {
+ '\\', 'u',
+ xdigits[(ch >> (4 * 3)) & 0xF],
+ xdigits[(ch >> (4 * 2)) & 0xF],
+ xdigits[(ch >> (4 * 1)) & 0xF],
+ xdigits[(ch >> (4 * 0)) & 0xF],
+ }), sizeof("\\u1234") - 1);
+ } else {
+ const int tmp = ch - SURROGATE_FIRST_CHAR;
+ const int hi = SURROGATE_HI_START + ((tmp >> 10) & ((1 << 10) - 1));
+ const int lo = SURROGATE_LO_END + ((tmp >> 0) & ((1 << 10) - 1));
+ ga_concat_len(gap, ((const char[]) {
+ '\\', 'u',
+ xdigits[(hi >> (4 * 3)) & 0xF],
+ xdigits[(hi >> (4 * 2)) & 0xF],
+ xdigits[(hi >> (4 * 1)) & 0xF],
+ xdigits[(hi >> (4 * 0)) & 0xF],
+ '\\', 'u',
+ xdigits[(lo >> (4 * 3)) & 0xF],
+ xdigits[(lo >> (4 * 2)) & 0xF],
+ xdigits[(lo >> (4 * 1)) & 0xF],
+ xdigits[(lo >> (4 * 0)) & 0xF],
+ }), (sizeof("\\u1234") - 1) * 2);
}
+ break;
}
i += shift;
}
@@ -691,25 +711,47 @@ static inline int convert_to_json_string(garray_T *const gap,
#undef TYPVAL_ENCODE_CONV_STRING
#define TYPVAL_ENCODE_CONV_STRING(tv, buf, len) \
- do { \
- if (convert_to_json_string(gap, (const char *) (buf), (len)) != OK) { \
- return FAIL; \
- } \
- } while (0)
+ do { \
+ if (convert_to_json_string(gap, (const char *)(buf), (len)) != OK) { \
+ return FAIL; \
+ } \
+ } while (0)
#undef TYPVAL_ENCODE_CONV_EXT_STRING
#define TYPVAL_ENCODE_CONV_EXT_STRING(tv, buf, len, type) \
- do { \
- xfree(buf); \
- EMSG(_("E474: Unable to convert EXT string to JSON")); \
- return FAIL; \
- } while (0)
+ do { \
+ xfree(buf); \
+ EMSG(_("E474: Unable to convert EXT string to JSON")); \
+ return FAIL; \
+ } while (0)
+
+#undef TYPVAL_ENCODE_CONV_BLOB
+#define TYPVAL_ENCODE_CONV_BLOB(tv, blob, len) \
+ do { \
+ const blob_T *const blob_ = (blob); \
+ const int len_ = (len); \
+ if (len_ == 0) { \
+ ga_concat(gap, "[]"); \
+ } else { \
+ ga_append(gap, '['); \
+ char numbuf[NUMBUFLEN]; \
+ for (int i_ = 0; i_ < len_; i_++) { \
+ if (i_ > 0) { \
+ ga_concat(gap, ", "); \
+ } \
+ vim_snprintf((char *)numbuf, ARRAY_SIZE(numbuf), "%d", \
+ (int)tv_blob_get(blob_, i_)); \
+ ga_concat(gap, numbuf); \
+ } \
+ ga_append(gap, ']'); \
+ } \
+ } while (0)
#undef TYPVAL_ENCODE_CONV_FUNC_START
#define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun) \
- return conv_error(_("E474: Error while dumping %s, %s: " \
- "attempt to dump function reference"), \
- mpstack, objname)
+ return conv_error(_("E474: Error while dumping %s, %s: " \
+ "attempt to dump function reference"), \
+ mpstack, objname)
/// Check whether given key can be used in json_encode()
///
@@ -750,12 +792,12 @@ bool encode_check_json_key(const typval_T *const tv)
#undef TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK
#define TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK(label, key) \
- do { \
- if (!encode_check_json_key(&key)) { \
- EMSG(_("E474: Invalid key in special dictionary")); \
- goto label; \
- } \
- } while (0)
+ do { \
+ if (!encode_check_json_key(&key)) { \
+ EMSG(_("E474: Invalid key in special dictionary")); \
+ goto label; \
+ } \
+ } while (0)
#define TYPVAL_ENCODE_SCOPE static
#define TYPVAL_ENCODE_NAME json
@@ -770,6 +812,7 @@ bool encode_check_json_key(const typval_T *const tv)
#undef TYPVAL_ENCODE_CONV_STRING
#undef TYPVAL_ENCODE_CONV_STR_STRING
#undef TYPVAL_ENCODE_CONV_EXT_STRING
+#undef TYPVAL_ENCODE_CONV_BLOB
#undef TYPVAL_ENCODE_CONV_NUMBER
#undef TYPVAL_ENCODE_CONV_FLOAT
#undef TYPVAL_ENCODE_CONV_FUNC_START
@@ -812,10 +855,10 @@ char *encode_tv2string(typval_T *tv, size_t *len)
assert(evs_ret == OK);
did_echo_string_emsg = false;
if (len != NULL) {
- *len = (size_t) ga.ga_len;
+ *len = (size_t)ga.ga_len;
}
ga_append(&ga, '\0');
- return (char *) ga.ga_data;
+ return (char *)ga.ga_data;
}
/// Return a string with the string representation of a variable.
@@ -840,10 +883,10 @@ char *encode_tv2echo(typval_T *tv, size_t *len)
assert(eve_ret == OK);
}
if (len != NULL) {
- *len = (size_t) ga.ga_len;
+ *len = (size_t)ga.ga_len;
}
ga_append(&ga, '\0');
- return (char *) ga.ga_data;
+ return (char *)ga.ga_data;
}
/// Return a string with the string representation of a variable.
@@ -872,81 +915,90 @@ char *encode_tv2json(typval_T *tv, size_t *len)
}
#define TYPVAL_ENCODE_CONV_STRING(tv, buf, len) \
- do { \
- if (buf == NULL) { \
- msgpack_pack_bin(packer, 0); \
- } else { \
- const size_t len_ = (len); \
- msgpack_pack_bin(packer, len_); \
- msgpack_pack_bin_body(packer, buf, len_); \
- } \
- } while (0)
+ do { \
+ if (buf == NULL) { \
+ msgpack_pack_bin(packer, 0); \
+ } else { \
+ const size_t len_ = (len); \
+ msgpack_pack_bin(packer, len_); \
+ msgpack_pack_bin_body(packer, buf, len_); \
+ } \
+ } while (0)
#define TYPVAL_ENCODE_CONV_STR_STRING(tv, buf, len) \
- do { \
- if (buf == NULL) { \
- msgpack_pack_str(packer, 0); \
- } else { \
- const size_t len_ = (len); \
- msgpack_pack_str(packer, len_); \
- msgpack_pack_str_body(packer, buf, len_); \
- } \
- } while (0)
+ do { \
+ if (buf == NULL) { \
+ msgpack_pack_str(packer, 0); \
+ } else { \
+ const size_t len_ = (len); \
+ msgpack_pack_str(packer, len_); \
+ msgpack_pack_str_body(packer, buf, len_); \
+ } \
+ } while (0)
#define TYPVAL_ENCODE_CONV_EXT_STRING(tv, buf, len, type) \
- do { \
- if (buf == NULL) { \
- msgpack_pack_ext(packer, 0, (int8_t) type); \
- } else { \
- const size_t len_ = (len); \
- msgpack_pack_ext(packer, len_, (int8_t) type); \
- msgpack_pack_ext_body(packer, buf, len_); \
- } \
- } while (0)
+ do { \
+ if (buf == NULL) { \
+ msgpack_pack_ext(packer, 0, (int8_t)type); \
+ } else { \
+ const size_t len_ = (len); \
+ msgpack_pack_ext(packer, len_, (int8_t)type); \
+ msgpack_pack_ext_body(packer, buf, len_); \
+ } \
+ } while (0)
+
+#define TYPVAL_ENCODE_CONV_BLOB(tv, blob, len) \
+ do { \
+ const size_t len_ = (size_t)(len); \
+ msgpack_pack_bin(packer, len_); \
+ if (len_ > 0) { \
+ msgpack_pack_bin_body(packer, (blob)->bv_ga.ga_data, len_); \
+ } \
+ } while (0)
#define TYPVAL_ENCODE_CONV_NUMBER(tv, num) \
- msgpack_pack_int64(packer, (int64_t)(num))
+ msgpack_pack_int64(packer, (int64_t)(num))
#define TYPVAL_ENCODE_CONV_FLOAT(tv, flt) \
- msgpack_pack_double(packer, (double)(flt))
+ msgpack_pack_double(packer, (double)(flt))
#define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun) \
- return conv_error(_("E5004: Error while dumping %s, %s: " \
- "attempt to dump function reference"), \
- mpstack, objname)
+ return conv_error(_("E5004: Error while dumping %s, %s: " \
+ "attempt to dump function reference"), \
+ mpstack, objname)
#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, len)
#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, len)
#define TYPVAL_ENCODE_CONV_FUNC_END(tv)
#define TYPVAL_ENCODE_CONV_EMPTY_LIST(tv) \
- msgpack_pack_array(packer, 0)
+ msgpack_pack_array(packer, 0)
#define TYPVAL_ENCODE_CONV_LIST_START(tv, len) \
- msgpack_pack_array(packer, (size_t)(len))
+ msgpack_pack_array(packer, (size_t)(len))
#define TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START(tv, mpsv)
#define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, dict) \
- msgpack_pack_map(packer, 0)
+ msgpack_pack_map(packer, 0)
#define TYPVAL_ENCODE_CONV_NIL(tv) \
- msgpack_pack_nil(packer)
+ msgpack_pack_nil(packer)
#define TYPVAL_ENCODE_CONV_BOOL(tv, num) \
- do { \
- if (num) { \
- msgpack_pack_true(packer); \
- } else { \
- msgpack_pack_false(packer); \
- } \
- } while (0)
+ do { \
+ if (num) { \
+ msgpack_pack_true(packer); \
+ } else { \
+ msgpack_pack_false(packer); \
+ } \
+ } while (0)
#define TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(tv, num) \
- msgpack_pack_uint64(packer, (num))
+ msgpack_pack_uint64(packer, (num))
#define TYPVAL_ENCODE_CONV_DICT_START(tv, dict, len) \
- msgpack_pack_map(packer, (size_t)(len))
+ msgpack_pack_map(packer, (size_t)(len))
#define TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START(tv, dict, mpsv)
@@ -963,9 +1015,9 @@ char *encode_tv2json(typval_T *tv, size_t *len)
#define TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(tv)
#define TYPVAL_ENCODE_CONV_RECURSE(val, conv_type) \
- return conv_error(_("E5005: Unable to dump %s: " \
- "container references itself in %s"), \
- mpstack, objname)
+ return conv_error(_("E5005: Unable to dump %s: " \
+ "container references itself in %s"), \
+ mpstack, objname)
#define TYPVAL_ENCODE_ALLOW_SPECIALS true
@@ -982,6 +1034,7 @@ char *encode_tv2json(typval_T *tv, size_t *len)
#undef TYPVAL_ENCODE_CONV_STRING
#undef TYPVAL_ENCODE_CONV_STR_STRING
#undef TYPVAL_ENCODE_CONV_EXT_STRING
+#undef TYPVAL_ENCODE_CONV_BLOB
#undef TYPVAL_ENCODE_CONV_NUMBER
#undef TYPVAL_ENCODE_CONV_FLOAT
#undef TYPVAL_ENCODE_CONV_FUNC_START
diff --git a/src/nvim/eval/executor.c b/src/nvim/eval/executor.c
index bbba9d12f2..8eceda84cf 100644
--- a/src/nvim/eval/executor.c
+++ b/src/nvim/eval/executor.c
@@ -1,12 +1,12 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
-#include "nvim/eval/typval.h"
-#include "nvim/eval/executor.h"
#include "nvim/eval.h"
+#include "nvim/eval/executor.h"
+#include "nvim/eval/typval.h"
+#include "nvim/globals.h"
#include "nvim/message.h"
#include "nvim/vim.h"
-#include "nvim/globals.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "eval/executor.c.generated.h"
@@ -16,110 +16,131 @@ static char *e_letwrong = N_("E734: Wrong variable type for %s=");
char *e_listidx = N_("E684: list index out of range: %" PRId64);
-/// Hanle tv1 += tv2, -=, *=, /=, %=, .=
+/// Handle tv1 += tv2, -=, *=, /=, %=, .=
///
/// @param[in,out] tv1 First operand, modified typval.
/// @param[in] tv2 Second operand.
/// @param[in] op Used operator.
///
/// @return OK or FAIL.
-int eexe_mod_op(typval_T *const tv1, const typval_T *const tv2,
- const char *const op)
+int eexe_mod_op(typval_T *const tv1, const typval_T *const tv2, const char *const op)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NO_SANITIZE_UNDEFINED
{
// Can't do anything with a Funcref, a Dict or special value on the right.
if (tv2->v_type != VAR_FUNC && tv2->v_type != VAR_DICT
&& tv2->v_type != VAR_BOOL && tv2->v_type != VAR_SPECIAL) {
switch (tv1->v_type) {
- case VAR_DICT:
- case VAR_FUNC:
- case VAR_PARTIAL:
- case VAR_BOOL:
- case VAR_SPECIAL: {
+ case VAR_DICT:
+ case VAR_FUNC:
+ case VAR_PARTIAL:
+ case VAR_BOOL:
+ case VAR_SPECIAL:
+ break;
+ case VAR_BLOB:
+ if (*op != '+' || tv2->v_type != VAR_BLOB) {
break;
}
- case VAR_LIST: {
- if (*op != '+' || tv2->v_type != VAR_LIST) {
- break;
+ // Blob += Blob
+ if (tv1->vval.v_blob != NULL && tv2->vval.v_blob != NULL) {
+ blob_T *const b1 = tv1->vval.v_blob;
+ blob_T *const b2 = tv2->vval.v_blob;
+ for (int i = 0; i < tv_blob_len(b2); i++) {
+ ga_append(&b1->bv_ga, (char)tv_blob_get(b2, i));
}
- // List += List
- if (tv1->vval.v_list != NULL && tv2->vval.v_list != NULL) {
- tv_list_extend(tv1->vval.v_list, tv2->vval.v_list, NULL);
- }
- return OK;
}
- case VAR_NUMBER:
- case VAR_STRING: {
- if (tv2->v_type == VAR_LIST) {
- break;
- }
- if (vim_strchr((char_u *)"+-*/%", *op) != NULL) {
- // nr += nr or nr -= nr, nr *= nr, nr /= nr, nr %= nr
- varnumber_T n = tv_get_number(tv1);
- if (tv2->v_type == VAR_FLOAT) {
- float_T f = (float_T)n;
+ return OK;
+ case VAR_LIST:
+ if (*op != '+' || tv2->v_type != VAR_LIST) {
+ break;
+ }
+ // List += List
+ if (tv1->vval.v_list != NULL && tv2->vval.v_list != NULL) {
+ tv_list_extend(tv1->vval.v_list, tv2->vval.v_list, NULL);
+ }
+ return OK;
+ case VAR_NUMBER:
+ case VAR_STRING:
+ if (tv2->v_type == VAR_LIST) {
+ break;
+ }
+ if (vim_strchr((char_u *)"+-*/%", *op) != NULL) {
+ // nr += nr or nr -= nr, nr *= nr, nr /= nr, nr %= nr
+ varnumber_T n = tv_get_number(tv1);
+ if (tv2->v_type == VAR_FLOAT) {
+ float_T f = (float_T)n;
- if (*op == '%') {
- break;
- }
- switch (*op) {
- case '+': f += tv2->vval.v_float; break;
- case '-': f -= tv2->vval.v_float; break;
- case '*': f *= tv2->vval.v_float; break;
- case '/': f /= tv2->vval.v_float; break;
- }
- tv_clear(tv1);
- tv1->v_type = VAR_FLOAT;
- tv1->vval.v_float = f;
- } else {
- switch (*op) {
- case '+': n += tv_get_number(tv2); break;
- case '-': n -= tv_get_number(tv2); break;
- case '*': n *= tv_get_number(tv2); break;
- case '/': n = num_divide(n, tv_get_number(tv2)); break;
- case '%': n = num_modulus(n, tv_get_number(tv2)); break;
- }
- tv_clear(tv1);
- tv1->v_type = VAR_NUMBER;
- tv1->vval.v_number = n;
+ if (*op == '%') {
+ break;
+ }
+ switch (*op) {
+ case '+':
+ f += tv2->vval.v_float; break;
+ case '-':
+ f -= tv2->vval.v_float; break;
+ case '*':
+ f *= tv2->vval.v_float; break;
+ case '/':
+ f /= tv2->vval.v_float; break;
}
+ tv_clear(tv1);
+ tv1->v_type = VAR_FLOAT;
+ tv1->vval.v_float = f;
} else {
- // str .= str
- if (tv2->v_type == VAR_FLOAT) {
- break;
+ switch (*op) {
+ case '+':
+ n += tv_get_number(tv2); break;
+ case '-':
+ n -= tv_get_number(tv2); break;
+ case '*':
+ n *= tv_get_number(tv2); break;
+ case '/':
+ n = num_divide(n, tv_get_number(tv2)); break;
+ case '%':
+ n = num_modulus(n, tv_get_number(tv2)); break;
}
- const char *tvs = tv_get_string(tv1);
- char numbuf[NUMBUFLEN];
- char *const s = (char *)concat_str(
- (const char_u *)tvs, (const char_u *)tv_get_string_buf(tv2,
- numbuf));
tv_clear(tv1);
- tv1->v_type = VAR_STRING;
- tv1->vval.v_string = (char_u *)s;
+ tv1->v_type = VAR_NUMBER;
+ tv1->vval.v_number = n;
}
- return OK;
- }
- case VAR_FLOAT: {
- if (*op == '%' || *op == '.'
- || (tv2->v_type != VAR_FLOAT
- && tv2->v_type != VAR_NUMBER
- && tv2->v_type != VAR_STRING)) {
+ } else {
+ // str .= str
+ if (tv2->v_type == VAR_FLOAT) {
break;
}
- const float_T f = (tv2->v_type == VAR_FLOAT
+ const char *tvs = tv_get_string(tv1);
+ char numbuf[NUMBUFLEN];
+ char *const s =
+ (char *)concat_str((const char_u *)tvs, (const char_u *)tv_get_string_buf(tv2,
+ numbuf));
+ tv_clear(tv1);
+ tv1->v_type = VAR_STRING;
+ tv1->vval.v_string = (char_u *)s;
+ }
+ return OK;
+ case VAR_FLOAT: {
+ if (*op == '%' || *op == '.'
+ || (tv2->v_type != VAR_FLOAT
+ && tv2->v_type != VAR_NUMBER
+ && tv2->v_type != VAR_STRING)) {
+ break;
+ }
+ const float_T f = (tv2->v_type == VAR_FLOAT
? tv2->vval.v_float
: (float_T)tv_get_number(tv2));
- switch (*op) {
- case '+': tv1->vval.v_float += f; break;
- case '-': tv1->vval.v_float -= f; break;
- case '*': tv1->vval.v_float *= f; break;
- case '/': tv1->vval.v_float /= f; break;
- }
- return OK;
- }
- case VAR_UNKNOWN: {
- abort();
+ switch (*op) {
+ case '+':
+ tv1->vval.v_float += f; break;
+ case '-':
+ tv1->vval.v_float -= f; break;
+ case '*':
+ tv1->vval.v_float *= f; break;
+ case '/':
+ tv1->vval.v_float /= f; break;
}
+ return OK;
+ }
+ case VAR_UNKNOWN:
+ abort();
}
}
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index 1ba31bfe68..5569d74413 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -47,6 +47,7 @@
#include "nvim/os/input.h"
#include "nvim/os/shell.h"
#include "nvim/path.h"
+#include "nvim/plines.h"
#include "nvim/popupmnu.h"
#include "nvim/quickfix.h"
#include "nvim/regexp.h"
@@ -79,22 +80,23 @@ KHASH_MAP_INIT_STR(functions, VimLFuncDef)
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "eval/funcs.c.generated.h"
-#ifdef _MSC_VER
+# ifdef _MSC_VER
// This prevents MSVC from replacing the functions with intrinsics,
// and causing errors when trying to get their addresses in funcs.generated.h
-#pragma function(ceil)
-#pragma function(floor)
-#endif
+# pragma function(ceil)
+# pragma function(floor)
+# endif
PRAGMA_DIAG_PUSH_IGNORE_MISSING_PROTOTYPES
PRAGMA_DIAG_PUSH_IGNORE_IMPLICIT_FALLTHROUGH
-#include "funcs.generated.h"
+# include "funcs.generated.h"
PRAGMA_DIAG_POP
PRAGMA_DIAG_POP
#endif
static char *e_listarg = N_("E686: Argument of %s must be a List");
+static char *e_listblobarg = N_("E899: Argument of %s must be a List or Blob");
static char *e_invalwindow = N_("E957: Invalid window number");
/// Dummy va_list for passing to vim_snprintf
@@ -113,12 +115,14 @@ char_u *get_function_name(expand_T *xp, int idx)
static int intidx = -1;
char_u *name;
- if (idx == 0)
+ if (idx == 0) {
intidx = -1;
+ }
if (intidx < 0) {
name = get_user_func_name(xp, idx);
if (name != NULL) {
- if (*name != '<' && STRNCMP("g:", xp->xp_pattern, 2) == 0) {
+ if (*name != NUL && *name != '<'
+ && STRNCMP("g:", xp->xp_pattern, 2) == 0) {
return cat_prefix_varname('g', name);
}
return name;
@@ -152,12 +156,14 @@ char_u *get_expr_name(expand_T *xp, int idx)
static int intidx = -1;
char_u *name;
- if (idx == 0)
+ if (idx == 0) {
intidx = -1;
+ }
if (intidx < 0) {
name = get_function_name(xp, idx);
- if (name != NULL)
+ if (name != NULL) {
return name;
+ }
}
return get_user_var_name(xp, ++intidx);
}
@@ -174,6 +180,52 @@ const VimLFuncDef *find_internal_func(const char *const name)
return find_internal_func_gperf(name, len);
}
+int call_internal_func(const char_u *const fname, const int argcount, typval_T *const argvars,
+ typval_T *const rettv)
+ FUNC_ATTR_NONNULL_ALL
+{
+ const VimLFuncDef *const fdef = find_internal_func((const char *)fname);
+ if (fdef == NULL) {
+ return ERROR_UNKNOWN;
+ } else if (argcount < fdef->min_argc) {
+ return ERROR_TOOFEW;
+ } else if (argcount > fdef->max_argc) {
+ return ERROR_TOOMANY;
+ }
+ argvars[argcount].v_type = VAR_UNKNOWN;
+ fdef->func(argvars, rettv, fdef->data);
+ return ERROR_NONE;
+}
+
+/// Invoke a method for base->method().
+int call_internal_method(const char_u *const fname, const int argcount, typval_T *const argvars,
+ typval_T *const rettv, typval_T *const basetv)
+ FUNC_ATTR_NONNULL_ALL
+{
+ const VimLFuncDef *const fdef = find_internal_func((const char *)fname);
+ if (fdef == NULL) {
+ return ERROR_UNKNOWN;
+ } else if (fdef->base_arg == BASE_NONE) {
+ return ERROR_NOTMETHOD;
+ } else if (argcount + 1 < fdef->min_argc) {
+ return ERROR_TOOFEW;
+ } else if (argcount + 1 > fdef->max_argc) {
+ return ERROR_TOOMANY;
+ }
+
+ typval_T argv[MAX_FUNC_ARGS + 1];
+ const ptrdiff_t base_index
+ = fdef->base_arg == BASE_LAST ? argcount : fdef->base_arg - 1;
+ memcpy(argv, argvars, base_index * sizeof(typval_T));
+ argv[base_index] = *basetv;
+ memcpy(argv + base_index + 1, argvars + base_index,
+ (argcount - base_index) * sizeof(typval_T));
+ argv[argcount + 1].v_type = VAR_UNKNOWN;
+
+ fdef->func(argv, rettv, fdef->data);
+ return ERROR_NONE;
+}
+
/*
* Return TRUE for a non-zero Number and a non-empty String.
*/
@@ -196,7 +248,7 @@ static int non_zero_arg(typval_T *argvars)
static void float_op_wrapper(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
float_T f;
- float_T (*function)(float_T) = (float_T (*)(float_T))fptr;
+ float_T (*function)(float_T) = (float_T (*)(float_T)) fptr;
rettv->v_type = VAR_FLOAT;
if (tv_get_float_chk(argvars, &f)) {
@@ -273,8 +325,20 @@ static void f_add(typval_T *argvars, typval_T *rettv, FunPtr fptr)
tv_list_append_tv(l, &argvars[1]);
tv_copy(&argvars[0], rettv);
}
+ } else if (argvars[0].v_type == VAR_BLOB) {
+ blob_T *const b = argvars[0].vval.v_blob;
+ if (b != NULL
+ && !var_check_lock(b->bv_lock, N_("add() argument"), TV_TRANSLATE)) {
+ bool error = false;
+ const varnumber_T n = tv_get_number_chk(&argvars[1], &error);
+
+ if (!error) {
+ ga_append(&b->bv_ga, (int)n);
+ tv_copy(&argvars[0], rettv);
+ }
+ }
} else {
- EMSG(_(e_listreq));
+ EMSG(_(e_listblobreq));
}
}
@@ -382,8 +446,7 @@ static void f_argv(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_string = NULL;
int idx = tv_get_number_chk(&argvars[0], NULL);
if (arglist != NULL && idx >= 0 && idx < argcount) {
- rettv->vval.v_string = (char_u *)xstrdup(
- (const char *)alist_name(&arglist[idx]));
+ rettv->vval.v_string = (char_u *)xstrdup((const char *)alist_name(&arglist[idx]));
} else if (idx == -1) {
get_arglist_as_rettv(arglist, argcount, rettv);
}
@@ -425,13 +488,13 @@ static void f_assert_notequal(typval_T *argvars, typval_T *rettv, FunPtr fptr)
/// "assert_report(msg)
static void f_assert_report(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- garray_T ga;
+ garray_T ga;
- prepare_assert_error(&ga);
- ga_concat(&ga, (const char_u *)tv_get_string(&argvars[0]));
- assert_error(&ga);
- ga_clear(&ga);
- rettv->vval.v_number = 1;
+ prepare_assert_error(&ga);
+ ga_concat(&ga, (const char_u *)tv_get_string(&argvars[0]));
+ assert_error(&ga);
+ ga_clear(&ga);
+ rettv->vval.v_number = 1;
}
/// "assert_exception(string[, msg])" function
@@ -515,11 +578,11 @@ static void f_browsedir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static buf_T *find_buffer(typval_T *avar)
{
- buf_T *buf = NULL;
+ buf_T *buf = NULL;
- if (avar->v_type == VAR_NUMBER)
+ if (avar->v_type == VAR_NUMBER) {
buf = buflist_findnr((int)avar->vval.v_number);
- else if (avar->v_type == VAR_STRING && avar->vval.v_string != NULL) {
+ } else if (avar->v_type == VAR_STRING && avar->vval.v_string != NULL) {
buf = buflist_findname_exp(avar->vval.v_string);
if (buf == NULL) {
/* No full path name match, try a match with a URL or a "nofile"
@@ -560,7 +623,7 @@ static void f_bufexists(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_buflisted(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- buf_T *buf;
+ buf_T *buf;
buf = find_buffer(&argvars[0]);
rettv->vval.v_number = (buf != NULL && buf->b_p_bl);
@@ -586,7 +649,7 @@ static void f_bufload(typval_T *argvars, typval_T *unused, FunPtr fptr)
*/
static void f_bufloaded(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- buf_T *buf;
+ buf_T *buf;
buf = find_buffer(&argvars[0]);
rettv->vval.v_number = (buf != NULL && buf->b_ml.ml_mfp != NULL);
@@ -688,19 +751,23 @@ static void f_bufwinnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
buf_T *tv_get_buf(typval_T *tv, int curtab_only)
{
- char_u *name = tv->vval.v_string;
+ char_u *name = tv->vval.v_string;
int save_magic;
- char_u *save_cpo;
- buf_T *buf;
+ char_u *save_cpo;
+ buf_T *buf;
- if (tv->v_type == VAR_NUMBER)
+ if (tv->v_type == VAR_NUMBER) {
return buflist_findnr((int)tv->vval.v_number);
- if (tv->v_type != VAR_STRING)
+ }
+ if (tv->v_type != VAR_STRING) {
return NULL;
- if (name == NULL || *name == NUL)
+ }
+ if (name == NULL || *name == NUL) {
return curbuf;
- if (name[0] == '$' && name[1] == NUL)
+ }
+ if (name[0] == '$' && name[1] == NUL) {
return lastbuf;
+ }
// Ignore 'magic' and 'cpoptions' here to make scripts portable
save_magic = p_magic;
@@ -736,7 +803,7 @@ buf_T *tv_get_buf_from_arg(typval_T *const tv) FUNC_ATTR_NONNULL_ALL
/// Get the buffer from "arg" and give an error and return NULL if it is not
/// valid.
-buf_T * get_buf_arg(typval_T *arg)
+buf_T *get_buf_arg(typval_T *arg)
{
buf_T *buf;
@@ -814,9 +881,9 @@ static void f_call(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
bool owned = false;
- char_u *func;
- partial_T *partial = NULL;
- dict_T *selfdict = NULL;
+ char_u *func;
+ partial_T *partial = NULL;
+ dict_T *selfdict = NULL;
if (argvars[0].v_type == VAR_FUNC) {
func = argvars[0].vval.v_string;
} else if (argvars[0].v_type == VAR_PARTIAL) {
@@ -866,7 +933,7 @@ static void f_chanclose(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
if (argvars[0].v_type != VAR_NUMBER || (argvars[1].v_type != VAR_STRING
- && argvars[1].v_type != VAR_UNKNOWN)) {
+ && argvars[1].v_type != VAR_UNKNOWN)) {
EMSG(_(e_invarg));
return;
}
@@ -911,7 +978,17 @@ static void f_chansend(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
ptrdiff_t input_len = 0;
- char *input = save_tv_as_string(&argvars[1], &input_len, false);
+ char *input = NULL;
+ if (argvars[1].v_type == VAR_BLOB) {
+ const blob_T *const b = argvars[1].vval.v_blob;
+ input_len = tv_blob_len(b);
+ if (input_len > 0) {
+ input = xmemdup(b->bv_ga.ga_data, input_len);
+ }
+ } else {
+ input = save_tv_as_string(&argvars[1], &input_len, false);
+ }
+
if (!input) {
// Either the error has been handled by save_tv_as_string(),
// or there is no input to send.
@@ -936,8 +1013,7 @@ static void f_char2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
- rettv->vval.v_number = utf_ptr2char(
- (const char_u *)tv_get_string(&argvars[0]));
+ rettv->vval.v_number = utf_ptr2char((const char_u *)tv_get_string(&argvars[0]));
}
// "charidx()" function
@@ -1000,11 +1076,12 @@ static void f_cindent(typval_T *argvars, typval_T *rettv, FunPtr fptr)
curwin->w_cursor.lnum = lnum;
rettv->vval.v_number = get_c_indent();
curwin->w_cursor = pos;
- } else
+ } else {
rettv->vval.v_number = -1;
+ }
}
-static win_T * get_optional_window(typval_T *argvars, int idx)
+static win_T *get_optional_window(typval_T *argvars, int idx)
{
win_T *win = curwin;
@@ -1036,7 +1113,7 @@ static void f_clearmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_col(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
colnr_T col = 0;
- pos_T *fp;
+ pos_T *fp;
int fnum = curbuf->b_fnum;
fp = var2fpos(&argvars[0], FALSE, &fnum);
@@ -1053,14 +1130,17 @@ static void f_col(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// col(".") when the cursor is on the NUL at the end of the line
// because of "coladd" can be seen as an extra column.
if (virtual_active() && fp == &curwin->w_cursor) {
- char_u *p = get_cursor_pos_ptr();
+ char_u *p = get_cursor_pos_ptr();
- if (curwin->w_cursor.coladd >= (colnr_T)chartabsize(p,
- curwin->w_virtcol - curwin->w_cursor.coladd)) {
+ if (curwin->w_cursor.coladd
+ >= (colnr_T)win_chartabsize(curwin, p,
+ (curwin->w_virtcol
+ - curwin->w_cursor.coladd))) {
int l;
- if (*p != NUL && p[(l = (*mb_ptr2len)(p))] == NUL)
+ if (*p != NUL && p[(l = (*mb_ptr2len)(p))] == NUL) {
col += l;
+ }
}
}
}
@@ -1078,10 +1158,11 @@ static void f_complete(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
- /* Check for undo allowed here, because if something was already inserted
- * the line was already saved for undo and this check isn't done. */
- if (!undo_allowed())
+ // Check for undo allowed here, because if something was already inserted
+ // the line was already saved for undo and this check isn't done.
+ if (!undo_allowed(curbuf)) {
return;
+ }
if (argvars[1].v_type != VAR_LIST) {
EMSG(_(e_invarg));
@@ -1165,11 +1246,16 @@ static void f_confirm(typval_T *argvars, typval_T *rettv, FunPtr fptr)
error = true;
} else {
switch (TOUPPER_ASC(*typestr)) {
- case 'E': type = VIM_ERROR; break;
- case 'Q': type = VIM_QUESTION; break;
- case 'I': type = VIM_INFO; break;
- case 'W': type = VIM_WARNING; break;
- case 'G': type = VIM_GENERIC; break;
+ case 'E':
+ type = VIM_ERROR; break;
+ case 'Q':
+ type = VIM_QUESTION; break;
+ case 'I':
+ type = VIM_INFO; break;
+ case 'W':
+ type = VIM_WARNING; break;
+ case 'G':
+ type = VIM_GENERIC; break;
}
}
}
@@ -1181,8 +1267,8 @@ static void f_confirm(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
if (!error) {
- rettv->vval.v_number = do_dialog(
- type, NULL, (char_u *)message, (char_u *)buttons, def, NULL, false);
+ rettv->vval.v_number = do_dialog(type, NULL, (char_u *)message, (char_u *)buttons, def, NULL,
+ false);
}
}
@@ -1232,8 +1318,8 @@ static void f_count(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
} else if (argvars[0].v_type == VAR_LIST) {
- listitem_T *li;
- list_T *l;
+ listitem_T *li;
+ list_T *l;
long idx;
if ((l = argvars[0].vval.v_list) != NULL) {
@@ -1248,8 +1334,9 @@ static void f_count(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
}
- if (error)
+ if (error) {
li = NULL;
+ }
}
for (; li != NULL; li = TV_LIST_ITEM_NEXT(l, li)) {
@@ -1260,8 +1347,8 @@ static void f_count(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
} else if (argvars[0].v_type == VAR_DICT) {
int todo;
- dict_T *d;
- hashitem_T *hi;
+ dict_T *d;
+ hashitem_T *hi;
if ((d = argvars[0].vval.v_dict) != NULL) {
if (argvars[2].v_type != VAR_UNKNOWN) {
@@ -1715,7 +1802,7 @@ static void f_did_filetype(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_diff_filler(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- rettv->vval.v_number = diff_check_fill(curwin, tv_get_lnum(argvars));
+ rettv->vval.v_number = MAX(0, diff_check(curwin, tv_get_lnum(argvars)));
}
/*
@@ -1780,53 +1867,45 @@ static void f_empty(typval_T *argvars, typval_T *rettv, FunPtr fptr)
bool n = true;
switch (argvars[0].v_type) {
- case VAR_STRING:
- case VAR_FUNC: {
- n = argvars[0].vval.v_string == NULL
- || *argvars[0].vval.v_string == NUL;
- break;
- }
- case VAR_PARTIAL: {
+ case VAR_STRING:
+ case VAR_FUNC:
+ n = argvars[0].vval.v_string == NULL
+ || *argvars[0].vval.v_string == NUL;
+ break;
+ case VAR_PARTIAL:
+ n = false;
+ break;
+ case VAR_NUMBER:
+ n = argvars[0].vval.v_number == 0;
+ break;
+ case VAR_FLOAT:
+ n = argvars[0].vval.v_float == 0.0;
+ break;
+ case VAR_LIST:
+ n = (tv_list_len(argvars[0].vval.v_list) == 0);
+ break;
+ case VAR_DICT:
+ n = (tv_dict_len(argvars[0].vval.v_dict) == 0);
+ break;
+ case VAR_BOOL:
+ switch (argvars[0].vval.v_bool) {
+ case kBoolVarTrue:
n = false;
break;
- }
- case VAR_NUMBER: {
- n = argvars[0].vval.v_number == 0;
- break;
- }
- case VAR_FLOAT: {
- n = argvars[0].vval.v_float == 0.0;
- break;
- }
- case VAR_LIST: {
- n = (tv_list_len(argvars[0].vval.v_list) == 0);
- break;
- }
- case VAR_DICT: {
- n = (tv_dict_len(argvars[0].vval.v_dict) == 0);
- break;
- }
- case VAR_BOOL: {
- switch (argvars[0].vval.v_bool) {
- case kBoolVarTrue: {
- n = false;
- break;
- }
- case kBoolVarFalse: {
- n = true;
- break;
- }
- }
- break;
- }
- case VAR_SPECIAL: {
- n = argvars[0].vval.v_special == kSpecialVarNull;
- break;
- }
- case VAR_UNKNOWN: {
- internal_error("f_empty(UNKNOWN)");
+ case kBoolVarFalse:
+ n = true;
break;
}
+ break;
+ case VAR_SPECIAL:
+ n = argvars[0].vval.v_special == kSpecialVarNull;
+ break;
+ case VAR_BLOB:
+ n = (tv_blob_len(argvars[0].vval.v_blob) == 0);
+ break;
+ case VAR_UNKNOWN:
+ internal_error("f_empty(UNKNOWN)");
+ break;
}
rettv->vval.v_number = n;
@@ -1886,9 +1965,8 @@ static void f_escape(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char buf[NUMBUFLEN];
- rettv->vval.v_string = vim_strsave_escaped(
- (const char_u *)tv_get_string(&argvars[0]),
- (const char_u *)tv_get_string_buf(&argvars[1], buf));
+ rettv->vval.v_string = vim_strsave_escaped((const char_u *)tv_get_string(&argvars[0]),
+ (const char_u *)tv_get_string_buf(&argvars[1], buf));
rettv->v_type = VAR_STRING;
}
@@ -1921,7 +1999,7 @@ static void f_eval(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (expr_start != NULL && !aborting()) {
EMSG2(_(e_invexpr2), expr_start);
}
- need_clr_eos = FALSE;
+ need_clr_eos = false;
rettv->v_type = VAR_NUMBER;
rettv->vval.v_number = 0;
} else if (*s != NUL) {
@@ -1969,8 +2047,7 @@ static char_u *get_list_line(int c, void *cookie, int indent, bool do_concat)
return (char_u *)(s == NULL ? NULL : xstrdup(s));
}
-static void execute_common(typval_T *argvars, typval_T *rettv, FunPtr fptr,
- int arg_off)
+static void execute_common(typval_T *argvars, typval_T *rettv, FunPtr fptr, int arg_off)
{
const int save_msg_silent = msg_silent;
const int save_emsg_silent = emsg_silent;
@@ -2076,7 +2153,7 @@ static void f_win_execute(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// Update the status line if the cursor moved.
if (win_valid(wp) && !equalpos(curpos, wp->w_cursor)) {
- wp->w_redr_status = true;
+ wp->w_redr_status = true;
}
}
}
@@ -2144,7 +2221,7 @@ static void f_exists(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_expand(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
size_t len;
- char_u *errormsg;
+ char_u *errormsg;
int options = WILD_SILENT|WILD_USE_NL|WILD_LIST_NOTFOUND;
expand_T xpc;
bool error = false;
@@ -2443,8 +2520,9 @@ static void findfilendir(typval_T *argvars, typval_T *rettv, int find_what)
if (*fname != NUL && !error) {
do {
- if (rettv->v_type == VAR_STRING || rettv->v_type == VAR_LIST)
+ if (rettv->v_type == VAR_STRING || rettv->v_type == VAR_LIST) {
xfree(fresult);
+ }
fresult = find_file_in_path_option(first ? (char_u *)fname : NULL,
first ? strlen(fname) : 0,
0, first, path,
@@ -2460,8 +2538,9 @@ static void findfilendir(typval_T *argvars, typval_T *rettv, int find_what)
} while ((rettv->v_type == VAR_LIST || --count > 0) && fresult != NULL);
}
- if (rettv->v_type == VAR_STRING)
+ if (rettv->v_type == VAR_STRING) {
rettv->vval.v_string = fresult;
+ }
}
@@ -2528,8 +2607,7 @@ static void f_fmod(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_fnameescape(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- rettv->vval.v_string = (char_u *)vim_strsave_fnameescape(
- tv_get_string(&argvars[0]), false);
+ rettv->vval.v_string = (char_u *)vim_strsave_fnameescape(tv_get_string(&argvars[0]), false);
rettv->v_type = VAR_STRING;
}
@@ -2617,14 +2695,14 @@ static void f_foldlevel(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_foldtext(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- linenr_T foldstart;
- linenr_T foldend;
- char_u *dashes;
- linenr_T lnum;
- char_u *s;
- char_u *r;
- int len;
- char *txt;
+ linenr_T foldstart;
+ linenr_T foldend;
+ char_u *dashes;
+ linenr_T lnum;
+ char_u *s;
+ char_u *r;
+ int len;
+ char *txt;
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
@@ -2647,8 +2725,9 @@ static void f_foldtext(typval_T *argvars, typval_T *rettv, FunPtr fptr)
s = skipwhite(s + 2);
if (*skipwhite(s) == NUL && lnum + 1 < foldend) {
s = skipwhite(ml_get(lnum + 1));
- if (*s == '*')
+ if (*s == '*') {
s = skipwhite(s + 1);
+ }
}
}
unsigned long count = (unsigned long)(foldend - foldstart + 1);
@@ -2671,7 +2750,7 @@ static void f_foldtext(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_foldtextresult(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *text;
+ char_u *text;
char_u buf[FOLD_TEXT_LEN];
static bool entered = false;
@@ -2733,14 +2812,30 @@ static void f_garbagecollect(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_get(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- listitem_T *li;
- list_T *l;
- dictitem_T *di;
- dict_T *d;
- typval_T *tv = NULL;
+ listitem_T *li;
+ list_T *l;
+ dictitem_T *di;
+ dict_T *d;
+ typval_T *tv = NULL;
bool what_is_dict = false;
- if (argvars[0].v_type == VAR_LIST) {
+ if (argvars[0].v_type == VAR_BLOB) {
+ bool error = false;
+ int idx = tv_get_number_chk(&argvars[1], &error);
+
+ if (!error) {
+ rettv->v_type = VAR_NUMBER;
+ if (idx < 0) {
+ idx = tv_blob_len(argvars[0].vval.v_blob) + idx;
+ }
+ if (idx < 0 || idx >= tv_blob_len(argvars[0].vval.v_blob)) {
+ rettv->vval.v_number = -1;
+ } else {
+ rettv->vval.v_number = tv_blob_get(argvars[0].vval.v_blob, idx);
+ tv = rettv;
+ }
+ }
+ } else if (argvars[0].v_type == VAR_LIST) {
if ((l = argvars[0].vval.v_list) != NULL) {
bool error = false;
@@ -2801,7 +2896,7 @@ static void f_get(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
} else {
- EMSG2(_(e_listdictarg), "get()");
+ EMSG2(_(e_listdictblobarg), "get()");
}
if (tv == NULL) {
@@ -2880,11 +2975,7 @@ static void f_getbufinfo(typval_T *argvars, typval_T *rettv, FunPtr fptr)
* buffer.
* If 'retlist' is TRUE, then the lines are returned as a Vim List.
*/
-static void get_buffer_lines(buf_T *buf,
- linenr_T start,
- linenr_T end,
- int retlist,
- typval_T *rettv)
+static void get_buffer_lines(buf_T *buf, linenr_T start, linenr_T end, int retlist, typval_T *rettv)
{
rettv->v_type = (retlist ? VAR_LIST : VAR_STRING);
rettv->vval.v_string = NULL;
@@ -3027,10 +3118,9 @@ static void f_getchangelist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "getchar()" function
- */
-static void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+// "getchar()" and "getcharstr()" functions
+static void getchar_common(typval_T *argvars, typval_T *rettv)
+ FUNC_ATTR_NONNULL_ALL
{
varnumber_T n;
bool error = false;
@@ -3097,6 +3187,7 @@ static void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
} else {
i += utf_char2bytes(n, temp + i);
}
+ assert(i < 10);
temp[i++] = NUL;
rettv->v_type = VAR_STRING;
rettv->vval.v_string = vim_strsave(temp);
@@ -3105,21 +3196,21 @@ static void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
int row = mouse_row;
int col = mouse_col;
int grid = mouse_grid;
- win_T *win;
linenr_T lnum;
- win_T *wp;
+ win_T *wp;
int winnr = 1;
if (row >= 0 && col >= 0) {
- /* Find the window at the mouse coordinates and compute the
- * text position. */
- win = mouse_find_win(&grid, &row, &col);
+ // Find the window at the mouse coordinates and compute the
+ // text position.
+ win_T *const win = mouse_find_win(&grid, &row, &col);
if (win == NULL) {
return;
}
(void)mouse_comp_pos(win, &row, &col, &lnum);
- for (wp = firstwin; wp != win; wp = wp->w_next)
+ for (wp = firstwin; wp != win; wp = wp->w_next) {
++winnr;
+ }
set_vim_var_nr(VV_MOUSE_WIN, winnr);
set_vim_var_nr(VV_MOUSE_WINID, wp->handle);
set_vim_var_nr(VV_MOUSE_LNUM, lnum);
@@ -3129,6 +3220,32 @@ static void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
+// "getchar()" function
+static void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ getchar_common(argvars, rettv);
+}
+
+// "getcharstr()" function
+static void f_getcharstr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ getchar_common(argvars, rettv);
+
+ if (rettv->v_type == VAR_NUMBER) {
+ char_u temp[7]; // mbyte-char: 6, NUL: 1
+ const varnumber_T n = rettv->vval.v_number;
+ int i = 0;
+
+ if (n != 0) {
+ i += utf_char2bytes(n, temp);
+ }
+ assert(i < 7);
+ temp[i++] = NUL;
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = vim_strsave(temp);
+ }
+}
+
/*
* "getcharmod()" function
*/
@@ -3192,11 +3309,11 @@ static void f_getcmdwintype(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// "getcompletion()" function
static void f_getcompletion(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *pat;
- expand_T xpc;
- bool filtered = false;
- int options = WILD_SILENT | WILD_USE_NL | WILD_ADD_SLASH
- | WILD_NO_BEEP;
+ char_u *pat;
+ expand_T xpc;
+ bool filtered = false;
+ int options = WILD_SILENT | WILD_USE_NL | WILD_ADD_SLASH
+ | WILD_NO_BEEP;
if (argvars[1].v_type != VAR_STRING) {
EMSG2(_(e_invarg2), "type must be a string");
@@ -3290,7 +3407,7 @@ static void f_getcwd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
char_u *from = NULL; // The original string to copy
tabpage_T *tp = curtab; // The tabpage to look at.
- win_T *win = curwin; // The window to look at.
+ win_T *win = curwin; // The window to look at.
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
@@ -3353,29 +3470,29 @@ static void f_getcwd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
cwd = xmalloc(MAXPATHL);
switch (scope) {
- case kCdScopeWindow:
- assert(win);
- from = win->w_localdir;
- if (from) {
- break;
- }
- FALLTHROUGH;
- case kCdScopeTab:
- assert(tp);
- from = tp->tp_localdir;
- if (from) {
- break;
- }
- FALLTHROUGH;
- case kCdScopeGlobal:
- if (globaldir) { // `globaldir` is not always set.
- from = globaldir;
- } else if (os_dirname(cwd, MAXPATHL) == FAIL) { // Get the OS CWD.
- from = (char_u *)""; // Return empty string on failure.
- }
+ case kCdScopeWindow:
+ assert(win);
+ from = win->w_localdir;
+ if (from) {
+ break;
+ }
+ FALLTHROUGH;
+ case kCdScopeTab:
+ assert(tp);
+ from = tp->tp_localdir;
+ if (from) {
break;
- case kCdScopeInvalid: // We should never get here
- abort();
+ }
+ FALLTHROUGH;
+ case kCdScopeGlobal:
+ if (globaldir) { // `globaldir` is not always set.
+ from = globaldir;
+ } else if (os_dirname(cwd, MAXPATHL) == FAIL) { // Get the OS CWD.
+ from = (char_u *)""; // Return empty string on failure.
+ }
+ break;
+ case kCdScopeInvalid: // We should never get here
+ abort();
}
if (from) {
@@ -3468,8 +3585,8 @@ static void f_getftime(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_getftype(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *type = NULL;
- char *t;
+ char_u *type = NULL;
+ char *t;
const char *fname = tv_get_string(&argvars[0]);
@@ -3596,7 +3713,7 @@ static void f_getmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (cur->match.regprog == NULL) {
// match added with matchaddpos()
for (i = 0; i < MAXPOSMATCH; i++) {
- llpos_T *llpos;
+ llpos_T *llpos;
char buf[30]; // use 30 to avoid compiler warning
llpos = &cur->pos.pos[i];
@@ -3633,6 +3750,59 @@ static void f_getmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
+// "getmousepos()" function
+void f_getmousepos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ dict_T *d;
+ win_T *wp;
+ int row = mouse_row;
+ int col = mouse_col;
+ int grid = mouse_grid;
+ varnumber_T winid = 0;
+ varnumber_T winrow = 0;
+ varnumber_T wincol = 0;
+ linenr_T line = 0;
+ varnumber_T column = 0;
+
+ tv_dict_alloc_ret(rettv);
+ d = rettv->vval.v_dict;
+
+ tv_dict_add_nr(d, S_LEN("screenrow"), (varnumber_T)mouse_row + 1);
+ tv_dict_add_nr(d, S_LEN("screencol"), (varnumber_T)mouse_col + 1);
+
+ wp = mouse_find_win(&grid, &row, &col);
+ if (wp != NULL) {
+ int height = wp->w_height + wp->w_status_height;
+ // The height is adjusted by 1 when there is a bottom border. This is not
+ // necessary for a top border since `row` starts at -1 in that case.
+ if (row < height + wp->w_border_adj[2]) {
+ winid = wp->handle;
+ winrow = row + 1 + wp->w_border_adj[0]; // Adjust by 1 for top border
+ wincol = col + 1 + wp->w_border_adj[3]; // Adjust by 1 for left border
+ if (row >= 0 && row < wp->w_height && col >= 0 && col < wp->w_width) {
+ char_u *p;
+ int count;
+
+ mouse_comp_pos(wp, &row, &col, &line);
+
+ // limit to text length plus one
+ p = ml_get_buf(wp->w_buffer, line, false);
+ count = (int)STRLEN(p);
+ if (col > count) {
+ col = count;
+ }
+
+ column = col + 1;
+ }
+ }
+ }
+ tv_dict_add_nr(d, S_LEN("winid"), winid);
+ tv_dict_add_nr(d, S_LEN("winrow"), winrow);
+ tv_dict_add_nr(d, S_LEN("wincol"), wincol);
+ tv_dict_add_nr(d, S_LEN("line"), (varnumber_T)line);
+ tv_dict_add_nr(d, S_LEN("column"), column);
+}
+
/*
* "getpid()" function
*/
@@ -3657,12 +3827,10 @@ static void getpos_both(typval_T *argvars, typval_T *rettv, bool getcurpos)
tv_list_append_number(l, ((fp != NULL)
? (varnumber_T)fp->lnum
: (varnumber_T)0));
- tv_list_append_number(
- l, ((fp != NULL)
+ tv_list_append_number(l, ((fp != NULL)
? (varnumber_T)(fp->col == MAXCOL ? MAXCOL : fp->col + 1)
- : (varnumber_T)0));
- tv_list_append_number(
- l, (fp != NULL) ? (varnumber_T)fp->coladd : (varnumber_T)0);
+ : (varnumber_T)0));
+ tv_list_append_number(l, (fp != NULL) ? (varnumber_T)fp->coladd : (varnumber_T)0);
if (getcurpos) {
const int save_set_curswant = curwin->w_set_curswant;
const colnr_T save_curswant = curwin->w_curswant;
@@ -3867,18 +4035,18 @@ static void f_gettabwinvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// "gettagstack()" function
static void f_gettagstack(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- win_T *wp = curwin; // default is current window
+ win_T *wp = curwin; // default is current window
- tv_dict_alloc_ret(rettv);
+ tv_dict_alloc_ret(rettv);
- if (argvars[0].v_type != VAR_UNKNOWN) {
- wp = find_win_by_nr_or_id(&argvars[0]);
- if (wp == NULL) {
- return;
- }
+ if (argvars[0].v_type != VAR_UNKNOWN) {
+ wp = find_win_by_nr_or_id(&argvars[0]);
+ if (wp == NULL) {
+ return;
}
+ }
- get_tagstack(wp, rettv->vval.v_dict);
+ get_tagstack(wp, rettv->vval.v_dict);
}
/// "getwininfo()" function
@@ -3996,12 +4164,11 @@ static void f_win_screenpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
//
// Move the window wp into a new split of targetwin in a given direction
//
-static void win_move_into_split(win_T *wp, win_T *targetwin,
- int size, int flags)
+static void win_move_into_split(win_T *wp, win_T *targetwin, int size, int flags)
{
- int dir;
- int height = wp->w_height;
- win_T *oldwin = curwin;
+ int dir;
+ int height = wp->w_height;
+ win_T *oldwin = curwin;
if (wp == targetwin) {
return;
@@ -4037,9 +4204,9 @@ static void win_move_into_split(win_T *wp, win_T *targetwin,
// "win_splitmove()" function
static void f_win_splitmove(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- win_T *wp;
- win_T *targetwin;
- int flags = 0, size = 0;
+ win_T *wp;
+ win_T *targetwin;
+ int flags = 0, size = 0;
wp = find_win_by_nr_or_id(&argvars[0]);
targetwin = find_win_by_nr_or_id(&argvars[1]);
@@ -4053,8 +4220,8 @@ static void f_win_splitmove(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
if (argvars[2].v_type != VAR_UNKNOWN) {
- dict_T *d;
- dictitem_T *di;
+ dict_T *d;
+ dictitem_T *di;
if (argvars[2].v_type != VAR_DICT || argvars[2].vval.v_dict == NULL) {
EMSG(_(e_invarg));
@@ -4133,11 +4300,12 @@ static void f_glob(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (!error) {
ExpandInit(&xpc);
xpc.xp_context = EXPAND_FILES;
- if (p_wic)
+ if (p_wic) {
options += WILD_ICASE;
+ }
if (rettv->v_type == VAR_STRING) {
- rettv->vval.v_string = ExpandOne(
- &xpc, (char_u *)tv_get_string(&argvars[0]), NULL, options, WILD_ALL);
+ rettv->vval.v_string = ExpandOne(&xpc, (char_u *)tv_get_string(&argvars[0]), NULL, options,
+ WILD_ALL);
} else {
ExpandOne(&xpc, (char_u *)tv_get_string(&argvars[0]), NULL, options,
WILD_ALL_KEEP);
@@ -4148,8 +4316,9 @@ static void f_glob(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
ExpandCleanup(&xpc);
}
- } else
+ } else {
rettv->vval.v_string = NULL;
+ }
}
/// "globpath()" function
@@ -4327,6 +4496,7 @@ static void f_has(typval_T *argvars, typval_T *rettv, FunPtr fptr)
"user_commands",
"vartabs",
"vertsplit",
+ "vimscript-1",
"virtualedit",
"visual",
"visualextra",
@@ -4408,8 +4578,9 @@ static void f_has_key(typval_T *argvars, typval_T *rettv, FunPtr fptr)
EMSG(_(e_dictreq));
return;
}
- if (argvars[0].vval.v_dict == NULL)
+ if (argvars[0].vval.v_dict == NULL) {
return;
+ }
rettv->vval.v_number = tv_dict_find(argvars[0].vval.v_dict,
tv_get_string(&argvars[1]),
@@ -4440,7 +4611,7 @@ static void f_haslocaldir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
};
tabpage_T *tp = curtab; // The tabpage to look at.
- win_T *win = curwin; // The window to look at.
+ win_T *win = curwin; // The window to look at.
rettv->v_type = VAR_NUMBER;
rettv->vval.v_number = 0;
@@ -4499,20 +4670,20 @@ static void f_haslocaldir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
switch (scope) {
- case kCdScopeWindow:
- assert(win);
- rettv->vval.v_number = win->w_localdir ? 1 : 0;
- break;
- case kCdScopeTab:
- assert(tp);
- rettv->vval.v_number = tp->tp_localdir ? 1 : 0;
- break;
- case kCdScopeGlobal:
- // The global scope never has a local directory
- break;
- case kCdScopeInvalid:
- // We should never get here
- abort();
+ case kCdScopeWindow:
+ assert(win);
+ rettv->vval.v_number = win->w_localdir ? 1 : 0;
+ break;
+ case kCdScopeTab:
+ assert(tp);
+ rettv->vval.v_number = tp->tp_localdir ? 1 : 0;
+ break;
+ case kCdScopeGlobal:
+ // The global scope never has a local directory
+ break;
+ case kCdScopeInvalid:
+ // We should never get here
+ abort();
}
}
@@ -4635,8 +4806,7 @@ static void f_histnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_hlID(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- rettv->vval.v_number = syn_name2id(
- (const char_u *)tv_get_string(&argvars[0]));
+ rettv->vval.v_number = syn_name2id((const char_u *)tv_get_string(&argvars[0]));
}
/*
@@ -4644,8 +4814,7 @@ static void f_hlID(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_hlexists(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- rettv->vval.v_number = highlight_exists(
- (const char_u *)tv_get_string(&argvars[0]));
+ rettv->vval.v_number = highlight_exists((const char_u *)tv_get_string(&argvars[0]));
}
/*
@@ -4672,11 +4841,9 @@ static void f_iconv(typval_T *argvars, typval_T *rettv, FunPtr fptr)
const char *const str = tv_get_string(&argvars[0]);
char buf1[NUMBUFLEN];
- char_u *const from = enc_canonize(enc_skip(
- (char_u *)tv_get_string_buf(&argvars[1], buf1)));
+ char_u *const from = enc_canonize(enc_skip((char_u *)tv_get_string_buf(&argvars[1], buf1)));
char buf2[NUMBUFLEN];
- char_u *const to = enc_canonize(enc_skip(
- (char_u *)tv_get_string_buf(&argvars[2], buf2)));
+ char_u *const to = enc_canonize(enc_skip((char_u *)tv_get_string_buf(&argvars[2], buf2)));
vimconv.vc_type = CONV_NONE;
convert_setup(&vimconv, from, to);
@@ -4714,8 +4881,38 @@ static void f_index(typval_T *argvars, typval_T *rettv, FunPtr fptr)
bool ic = false;
rettv->vval.v_number = -1;
- if (argvars[0].v_type != VAR_LIST) {
- EMSG(_(e_listreq));
+ if (argvars[0].v_type == VAR_BLOB) {
+ bool error = false;
+ int start = 0;
+
+ if (argvars[2].v_type != VAR_UNKNOWN) {
+ start = tv_get_number_chk(&argvars[2], &error);
+ if (error) {
+ return;
+ }
+ }
+ blob_T *const b = argvars[0].vval.v_blob;
+ if (b == NULL) {
+ return;
+ }
+ if (start < 0) {
+ start = tv_blob_len(b) + start;
+ if (start < 0) {
+ start = 0;
+ }
+ }
+ for (idx = start; idx < tv_blob_len(b); idx++) {
+ typval_T tv;
+ tv.v_type = VAR_NUMBER;
+ tv.vval.v_number = tv_blob_get(b, idx);
+ if (tv_equal(&tv, &argvars[1], ic, false)) {
+ rettv->vval.v_number = idx;
+ return;
+ }
+ }
+ return;
+ } else if (argvars[0].v_type != VAR_LIST) {
+ EMSG(_(e_listblobreq));
return;
}
list_T *const l = argvars[0].vval.v_list;
@@ -4844,8 +5041,46 @@ static void f_insert(typval_T *argvars, typval_T *rettv, FunPtr fptr)
list_T *l;
bool error = false;
- if (argvars[0].v_type != VAR_LIST) {
- EMSG2(_(e_listarg), "insert()");
+ if (argvars[0].v_type == VAR_BLOB) {
+ blob_T *const b = argvars[0].vval.v_blob;
+
+ if (b == NULL
+ || var_check_lock(b->bv_lock, N_("insert() argument"),
+ TV_TRANSLATE)) {
+ return;
+ }
+
+ long before = 0;
+ const int len = tv_blob_len(b);
+
+ if (argvars[2].v_type != VAR_UNKNOWN) {
+ before = (long)tv_get_number_chk(&argvars[2], &error);
+ if (error) {
+ return; // type error; errmsg already given
+ }
+ if (before < 0 || before > len) {
+ EMSG2(_(e_invarg2), tv_get_string(&argvars[2]));
+ return;
+ }
+ }
+ const int val = tv_get_number_chk(&argvars[1], &error);
+ if (error) {
+ return;
+ }
+ if (val < 0 || val > 255) {
+ EMSG2(_(e_invarg2), tv_get_string(&argvars[1]));
+ return;
+ }
+
+ ga_grow(&b->bv_ga, 1);
+ char_u *const p = (char_u *)b->bv_ga.ga_data;
+ memmove(p + before + 1, p + before, (size_t)len - before);
+ *(p + before) = val;
+ b->bv_ga.ga_len++;
+
+ tv_copy(&argvars[0], rettv);
+ } else if (argvars[0].v_type != VAR_LIST) {
+ EMSG2(_(e_listblobarg), "insert()");
} else if (!var_check_lock(tv_list_locked((l = argvars[0].vval.v_list)),
N_("insert() argument"), TV_TRANSLATE)) {
long before = 0;
@@ -4873,8 +5108,7 @@ static void f_insert(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
// "interrupt()" function
-static void f_interrupt(typval_T *argvars FUNC_ATTR_UNUSED,
- typval_T *rettv FUNC_ATTR_UNUSED,
+static void f_interrupt(typval_T *argvars FUNC_ATTR_UNUSED, typval_T *rettv FUNC_ATTR_UNUSED,
FunPtr fptr FUNC_ATTR_UNUSED)
{
got_int = true;
@@ -4902,7 +5136,7 @@ static void f_isdirectory(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_islocked(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
lval_T lv;
- dictitem_T *di;
+ dictitem_T *di;
rettv->vval.v_number = -1;
const char_u *const end = get_lval((char_u *)tv_get_string(&argvars[0]),
@@ -4954,7 +5188,7 @@ static void f_isinf(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_isnan(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = argvars[0].v_type == VAR_FLOAT
- && xisnan(argvars[0].vval.v_float);
+ && xisnan(argvars[0].vval.v_float);
}
/// "id()" function
@@ -5062,9 +5296,7 @@ static const char *required_env_vars[] = {
NULL
};
-static dict_T *create_environment(const dictitem_T *job_env,
- const bool clear_env,
- const bool pty,
+static dict_T *create_environment(const dictitem_T *job_env, const bool clear_env, const bool pty,
const char * const pty_term_name)
{
dict_T * env = tv_dict_alloc();
@@ -5181,6 +5413,7 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
bool pty = false;
bool clear_env = false;
bool overlapped = false;
+ ChannelStdinMode stdin_mode = kChannelStdinPipe;
CallbackReader on_stdout = CALLBACK_READER_INIT,
on_stderr = CALLBACK_READER_INIT;
Callback on_exit = CALLBACK_NONE;
@@ -5195,6 +5428,17 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
clear_env = tv_dict_get_number(job_opts, "clear_env") != 0;
overlapped = tv_dict_get_number(job_opts, "overlapped") != 0;
+ char *s = tv_dict_get_string(job_opts, "stdin", false);
+ if (s) {
+ if (!strncmp(s, "null", NUMBUFLEN)) {
+ stdin_mode = kChannelStdinNull;
+ } else if (!strncmp(s, "pipe", NUMBUFLEN)) {
+ // Nothing to do, default value
+ } else {
+ EMSG3(_(e_invargNval), "stdin", s);
+ }
+ }
+
if (pty && rpc) {
EMSG2(_(e_invarg2), "job cannot have both 'pty' and 'rpc' options set");
shell_free_argv(argv);
@@ -5251,8 +5495,8 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
env = create_environment(job_env, clear_env, pty, term_name);
Channel *chan = channel_job_start(argv, on_stdout, on_stderr, on_exit, pty,
- rpc, overlapped, detach, cwd, width, height,
- env, &rettv->vval.v_number);
+ rpc, overlapped, detach, stdin_mode, cwd,
+ width, height, env, &rettv->vval.v_number);
if (chan) {
channel_create_event(chan, NULL);
}
@@ -5301,7 +5545,7 @@ static void f_jobwait(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
if (argvars[0].v_type != VAR_LIST || (argvars[1].v_type != VAR_NUMBER
- && argvars[1].v_type != VAR_UNKNOWN)) {
+ && argvars[1].v_type != VAR_UNKNOWN)) {
EMSG(_(e_invarg));
return;
}
@@ -5316,14 +5560,19 @@ static void f_jobwait(typval_T *argvars, typval_T *rettv, FunPtr fptr)
TV_LIST_ITER_CONST(args, arg, {
Channel *chan = NULL;
if (TV_LIST_ITEM_TV(arg)->v_type != VAR_NUMBER
- || !(chan = find_job(TV_LIST_ITEM_TV(arg)->vval.v_number, false))) {
+ || !(chan = find_channel(TV_LIST_ITEM_TV(arg)->vval.v_number))
+ || chan->streamtype != kChannelStreamProc) {
+ jobs[i] = NULL; // Invalid job.
+ } else if (process_is_stopped(&chan->stream.proc)) {
+ // Job is stopped but not fully destroyed.
+ // Ensure all callbacks on its event queue are executed. #15402
+ process_wait(&chan->stream.proc, -1, NULL);
jobs[i] = NULL; // Invalid job.
} else {
jobs[i] = chan;
channel_incref(chan);
if (chan->stream.proc.status < 0) {
- // Process any pending events on the job's queue before temporarily
- // replacing it.
+ // Flush any events in the job's queue before temporarily replacing it.
multiqueue_process_events(chan->events);
multiqueue_replace_parent(chan->events, waiting_jobs);
}
@@ -5482,29 +5731,27 @@ static void f_last_buffer_nr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_len(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
switch (argvars[0].v_type) {
- case VAR_STRING:
- case VAR_NUMBER: {
- rettv->vval.v_number = (varnumber_T)strlen(
- tv_get_string(&argvars[0]));
- break;
- }
- case VAR_LIST: {
- rettv->vval.v_number = tv_list_len(argvars[0].vval.v_list);
- break;
- }
- case VAR_DICT: {
- rettv->vval.v_number = tv_dict_len(argvars[0].vval.v_dict);
- break;
- }
- case VAR_UNKNOWN:
- case VAR_BOOL:
- case VAR_SPECIAL:
- case VAR_FLOAT:
- case VAR_PARTIAL:
- case VAR_FUNC: {
- EMSG(_("E701: Invalid type for len()"));
- break;
- }
+ case VAR_STRING:
+ case VAR_NUMBER:
+ rettv->vval.v_number = (varnumber_T)strlen(tv_get_string(&argvars[0]));
+ break;
+ case VAR_BLOB:
+ rettv->vval.v_number = tv_blob_len(argvars[0].vval.v_blob);
+ break;
+ case VAR_LIST:
+ rettv->vval.v_number = tv_list_len(argvars[0].vval.v_list);
+ break;
+ case VAR_DICT:
+ rettv->vval.v_number = tv_dict_len(argvars[0].vval.v_dict);
+ break;
+ case VAR_UNKNOWN:
+ case VAR_BOOL:
+ case VAR_SPECIAL:
+ case VAR_FLOAT:
+ case VAR_PARTIAL:
+ case VAR_FUNC:
+ EMSG(_("E701: Invalid type for len()"));
+ break;
}
}
@@ -5549,7 +5796,7 @@ static void libcall_common(typval_T *argvars, typval_T *rettv, int out_type)
}
if (out_type == VAR_NUMBER) {
- rettv->vval.v_number = (varnumber_T)int_out;
+ rettv->vval.v_number = (varnumber_T)int_out;
}
}
@@ -5679,7 +5926,7 @@ static void get_maparg(typval_T *argvars, typval_T *rettv, int exact)
int mode;
int abbr = FALSE;
int get_dict = FALSE;
- mapblock_T *mp;
+ mapblock_T *mp;
int buffer_local;
// Return empty string for failure.
@@ -5721,11 +5968,9 @@ static void get_maparg(typval_T *argvars, typval_T *rettv, int exact)
if (*rhs == NUL) {
rettv->vval.v_string = vim_strsave((char_u *)"<Nop>");
} else {
- rettv->vval.v_string = (char_u *)str2special_save(
- (char *)rhs, false, false);
+ rettv->vval.v_string = (char_u *)str2special_save((char *)rhs, false, false);
}
}
-
} else {
tv_dict_alloc_ret(rettv);
if (rhs != NULL) {
@@ -5775,19 +6020,19 @@ static void f_mapcheck(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void find_some_match(typval_T *const argvars, typval_T *const rettv,
const SomeMatchType type)
{
- char_u *str = NULL;
- long len = 0;
- char_u *expr = NULL;
+ char_u *str = NULL;
+ long len = 0;
+ char_u *expr = NULL;
regmatch_T regmatch;
- char_u *save_cpo;
+ char_u *save_cpo;
long start = 0;
long nth = 1;
colnr_T startcol = 0;
bool match = false;
- list_T *l = NULL;
- listitem_T *li = NULL;
+ list_T *l = NULL;
+ listitem_T *li = NULL;
long idx = 0;
- char_u *tofree = NULL;
+ char_u *tofree = NULL;
// Make 'cpoptions' empty, the 'l' flag should not be used here.
save_cpo = p_cpo;
@@ -5795,30 +6040,26 @@ static void find_some_match(typval_T *const argvars, typval_T *const rettv,
rettv->vval.v_number = -1;
switch (type) {
- // matchlist(): return empty list when there are no matches.
- case kSomeMatchList: {
- tv_list_alloc_ret(rettv, kListLenMayKnow);
- break;
- }
- // matchstrpos(): return ["", -1, -1, -1]
- case kSomeMatchStrPos: {
- tv_list_alloc_ret(rettv, 4);
- tv_list_append_string(rettv->vval.v_list, "", 0);
- tv_list_append_number(rettv->vval.v_list, -1);
- tv_list_append_number(rettv->vval.v_list, -1);
- tv_list_append_number(rettv->vval.v_list, -1);
- break;
- }
- case kSomeMatchStr: {
- rettv->v_type = VAR_STRING;
- rettv->vval.v_string = NULL;
- break;
- }
- case kSomeMatch:
- case kSomeMatchEnd: {
- // Do nothing: zero is default.
- break;
- }
+ // matchlist(): return empty list when there are no matches.
+ case kSomeMatchList:
+ tv_list_alloc_ret(rettv, kListLenMayKnow);
+ break;
+ // matchstrpos(): return ["", -1, -1, -1]
+ case kSomeMatchStrPos:
+ tv_list_alloc_ret(rettv, 4);
+ tv_list_append_string(rettv->vval.v_list, "", 0);
+ tv_list_append_number(rettv->vval.v_list, -1);
+ tv_list_append_number(rettv->vval.v_list, -1);
+ tv_list_append_number(rettv->vval.v_list, -1);
+ break;
+ case kSomeMatchStr:
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = NULL;
+ break;
+ case kSomeMatch:
+ case kSomeMatchEnd:
+ // Do nothing: zero is default.
+ break;
}
if (argvars[0].v_type == VAR_LIST) {
@@ -5851,10 +6092,12 @@ static void find_some_match(typval_T *const argvars, typval_T *const rettv,
}
li = tv_list_find(l, idx);
} else {
- if (start < 0)
+ if (start < 0) {
start = 0;
- if (start > len)
+ }
+ if (start > len) {
goto theend;
+ }
// When "count" argument is there ignore matches before "start",
// otherwise skip part of the string. Differs when pattern is "^"
// or "\<".
@@ -5894,10 +6137,12 @@ static void find_some_match(typval_T *const argvars, typval_T *const rettv,
match = vim_regexec_nl(&regmatch, str, (colnr_T)startcol);
- if (match && --nth <= 0)
+ if (match && --nth <= 0) {
break;
- if (l == NULL && !match)
+ }
+ if (l == NULL && !match) {
break;
+ }
// Advance to just after the match.
if (l != NULL) {
@@ -5907,74 +6152,70 @@ static void find_some_match(typval_T *const argvars, typval_T *const rettv,
startcol = (colnr_T)(regmatch.startp[0]
+ (*mb_ptr2len)(regmatch.startp[0]) - str);
if (startcol > (colnr_T)len || str + startcol <= regmatch.startp[0]) {
- match = false;
- break;
+ match = false;
+ break;
}
}
}
if (match) {
switch (type) {
- case kSomeMatchStrPos: {
- list_T *const ret_l = rettv->vval.v_list;
- listitem_T *li1 = tv_list_first(ret_l);
- listitem_T *li2 = TV_LIST_ITEM_NEXT(ret_l, li1);
- listitem_T *li3 = TV_LIST_ITEM_NEXT(ret_l, li2);
- listitem_T *li4 = TV_LIST_ITEM_NEXT(ret_l, li3);
- xfree(TV_LIST_ITEM_TV(li1)->vval.v_string);
-
- const size_t rd = (size_t)(regmatch.endp[0] - regmatch.startp[0]);
- TV_LIST_ITEM_TV(li1)->vval.v_string = xmemdupz(
- (const char *)regmatch.startp[0], rd);
- TV_LIST_ITEM_TV(li3)->vval.v_number = (varnumber_T)(
- regmatch.startp[0] - expr);
- TV_LIST_ITEM_TV(li4)->vval.v_number = (varnumber_T)(
- regmatch.endp[0] - expr);
- if (l != NULL) {
- TV_LIST_ITEM_TV(li2)->vval.v_number = (varnumber_T)idx;
- }
- break;
- }
- case kSomeMatchList: {
- // Return list with matched string and submatches.
- for (int i = 0; i < NSUBEXP; i++) {
- if (regmatch.endp[i] == NULL) {
- tv_list_append_string(rettv->vval.v_list, NULL, 0);
- } else {
- tv_list_append_string(rettv->vval.v_list,
- (const char *)regmatch.startp[i],
- (regmatch.endp[i] - regmatch.startp[i]));
- }
- }
- break;
+ case kSomeMatchStrPos: {
+ list_T *const ret_l = rettv->vval.v_list;
+ listitem_T *li1 = tv_list_first(ret_l);
+ listitem_T *li2 = TV_LIST_ITEM_NEXT(ret_l, li1);
+ listitem_T *li3 = TV_LIST_ITEM_NEXT(ret_l, li2);
+ listitem_T *li4 = TV_LIST_ITEM_NEXT(ret_l, li3);
+ xfree(TV_LIST_ITEM_TV(li1)->vval.v_string);
+
+ const size_t rd = (size_t)(regmatch.endp[0] - regmatch.startp[0]);
+ TV_LIST_ITEM_TV(li1)->vval.v_string = xmemdupz((const char *)regmatch.startp[0], rd);
+ TV_LIST_ITEM_TV(li3)->vval.v_number = (varnumber_T)(
+ regmatch.startp[0] - expr);
+ TV_LIST_ITEM_TV(li4)->vval.v_number = (varnumber_T)(
+ regmatch.endp[0] - expr);
+ if (l != NULL) {
+ TV_LIST_ITEM_TV(li2)->vval.v_number = (varnumber_T)idx;
}
- case kSomeMatchStr: {
- // Return matched string.
- if (l != NULL) {
- tv_copy(TV_LIST_ITEM_TV(li), rettv);
+ break;
+ }
+ case kSomeMatchList:
+ // Return list with matched string and submatches.
+ for (int i = 0; i < NSUBEXP; i++) {
+ if (regmatch.endp[i] == NULL) {
+ tv_list_append_string(rettv->vval.v_list, NULL, 0);
} else {
- rettv->vval.v_string = (char_u *)xmemdupz(
- (const char *)regmatch.startp[0],
- (size_t)(regmatch.endp[0] - regmatch.startp[0]));
+ tv_list_append_string(rettv->vval.v_list,
+ (const char *)regmatch.startp[i],
+ (regmatch.endp[i] - regmatch.startp[i]));
}
- break;
}
- case kSomeMatch:
- case kSomeMatchEnd: {
- if (l != NULL) {
- rettv->vval.v_number = idx;
+ break;
+ case kSomeMatchStr:
+ // Return matched string.
+ if (l != NULL) {
+ tv_copy(TV_LIST_ITEM_TV(li), rettv);
+ } else {
+ rettv->vval.v_string = (char_u *)xmemdupz((const char *)regmatch.startp[0],
+ (size_t)(regmatch.endp[0] -
+ regmatch.startp[0]));
+ }
+ break;
+ case kSomeMatch:
+ case kSomeMatchEnd:
+ if (l != NULL) {
+ rettv->vval.v_number = idx;
+ } else {
+ if (type == kSomeMatch) {
+ rettv->vval.v_number =
+ (varnumber_T)(regmatch.startp[0] - str);
} else {
- if (type == kSomeMatch) {
- rettv->vval.v_number =
- (varnumber_T)(regmatch.startp[0] - str);
- } else {
- rettv->vval.v_number =
- (varnumber_T)(regmatch.endp[0] - str);
- }
- rettv->vval.v_number += (varnumber_T)(str - expr);
+ rettv->vval.v_number =
+ (varnumber_T)(regmatch.endp[0] - str);
}
- break;
+ rettv->vval.v_number += (varnumber_T)(str - expr);
}
+ break;
}
}
vim_regfree(regmatch.regprog);
@@ -6123,7 +6364,7 @@ static void f_matcharg(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_matchdelete(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- win_T *win = get_optional_window(argvars, 1);
+ win_T *win = get_optional_window(argvars, 1);
if (win == NULL) {
rettv->vval.v_number = -1;
} else {
@@ -6171,8 +6412,7 @@ static void f_matchstrpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
/// vval.v_number, type is not touched. Returns zero for
/// empty lists/dictionaries.
/// @param[in] domax Determines whether maximal or minimal value is desired.
-static void max_min(const typval_T *const tv, typval_T *const rettv,
- const bool domax)
+static void max_min(const typval_T *const tv, typval_T *const rettv, const bool domax)
FUNC_ATTR_NONNULL_ALL
{
bool error = false;
@@ -6298,9 +6538,16 @@ static void f_msgpackdump(typval_T *argvars, typval_T *rettv, FunPtr fptr)
EMSG2(_(e_listarg), "msgpackdump()");
return;
}
- list_T *const ret_list = tv_list_alloc_ret(rettv, kListLenMayKnow);
list_T *const list = argvars[0].vval.v_list;
- msgpack_packer *lpacker = msgpack_packer_new(ret_list, &encode_list_write);
+ msgpack_packer *packer;
+ if (argvars[1].v_type != VAR_UNKNOWN
+ && strequal(tv_get_string(&argvars[1]), "B")) {
+ tv_blob_alloc_ret(rettv);
+ packer = msgpack_packer_new(rettv->vval.v_blob, &encode_blob_write);
+ } else {
+ packer = msgpack_packer_new(tv_list_alloc_ret(rettv, kListLenMayKnow),
+ &encode_list_write);
+ }
const char *const msg = _("msgpackdump() argument, index %i");
// Assume that translation will not take more then 4 times more space
char msgbuf[sizeof("msgpackdump() argument, index ") * 4 + NUMBUFLEN];
@@ -6308,23 +6555,47 @@ static void f_msgpackdump(typval_T *argvars, typval_T *rettv, FunPtr fptr)
TV_LIST_ITER(list, li, {
vim_snprintf(msgbuf, sizeof(msgbuf), (char *)msg, idx);
idx++;
- if (encode_vim_to_msgpack(lpacker, TV_LIST_ITEM_TV(li), msgbuf) == FAIL) {
+ if (encode_vim_to_msgpack(packer, TV_LIST_ITEM_TV(li), msgbuf) == FAIL) {
break;
}
});
- msgpack_packer_free(lpacker);
+ msgpack_packer_free(packer);
}
-/// "msgpackparse" function
-static void f_msgpackparse(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+static int msgpackparse_convert_item(const msgpack_object data, const msgpack_unpack_return result,
+ list_T *const ret_list, const bool fail_if_incomplete)
FUNC_ATTR_NONNULL_ALL
{
- if (argvars[0].v_type != VAR_LIST) {
- EMSG2(_(e_listarg), "msgpackparse()");
- return;
+ switch (result) {
+ case MSGPACK_UNPACK_PARSE_ERROR:
+ EMSG2(_(e_invarg2), "Failed to parse msgpack string");
+ return FAIL;
+ case MSGPACK_UNPACK_NOMEM_ERROR:
+ EMSG(_(e_outofmem));
+ return FAIL;
+ case MSGPACK_UNPACK_CONTINUE:
+ if (fail_if_incomplete) {
+ EMSG2(_(e_invarg2), "Incomplete msgpack string");
+ return FAIL;
+ }
+ return NOTDONE;
+ case MSGPACK_UNPACK_SUCCESS: {
+ typval_T tv = { .v_type = VAR_UNKNOWN };
+ if (msgpack_to_vim(data, &tv) == FAIL) {
+ EMSG2(_(e_invarg2), "Failed to convert msgpack string");
+ return FAIL;
+ }
+ tv_list_append_owned_tv(ret_list, tv);
+ return OK;
}
- list_T *const ret_list = tv_list_alloc_ret(rettv, kListLenMayKnow);
- const list_T *const list = argvars[0].vval.v_list;
+ default:
+ abort();
+ }
+}
+
+static void msgpackparse_unpack_list(const list_T *const list, list_T *const ret_list)
+ FUNC_ATTR_NONNULL_ARG(2)
+{
if (tv_list_len(list) == 0) {
return;
}
@@ -6343,43 +6614,28 @@ static void f_msgpackparse(typval_T *argvars, typval_T *rettv, FunPtr fptr)
do {
if (!msgpack_unpacker_reserve_buffer(unpacker, IOSIZE)) {
EMSG(_(e_outofmem));
- goto f_msgpackparse_exit;
+ goto end;
}
size_t read_bytes;
- const int rlret = encode_read_from_list(
- &lrstate, msgpack_unpacker_buffer(unpacker), IOSIZE, &read_bytes);
+ const int rlret = encode_read_from_list(&lrstate, msgpack_unpacker_buffer(unpacker), IOSIZE,
+ &read_bytes);
if (rlret == FAIL) {
EMSG2(_(e_invarg2), "List item is not a string");
- goto f_msgpackparse_exit;
+ goto end;
}
msgpack_unpacker_buffer_consumed(unpacker, read_bytes);
if (read_bytes == 0) {
break;
}
while (unpacker->off < unpacker->used) {
- const msgpack_unpack_return result = msgpack_unpacker_next(unpacker,
- &unpacked);
- if (result == MSGPACK_UNPACK_PARSE_ERROR) {
- EMSG2(_(e_invarg2), "Failed to parse msgpack string");
- goto f_msgpackparse_exit;
- }
- if (result == MSGPACK_UNPACK_NOMEM_ERROR) {
- EMSG(_(e_outofmem));
- goto f_msgpackparse_exit;
- }
- if (result == MSGPACK_UNPACK_SUCCESS) {
- typval_T tv = { .v_type = VAR_UNKNOWN };
- if (msgpack_to_vim(unpacked.data, &tv) == FAIL) {
- EMSG2(_(e_invarg2), "Failed to convert msgpack string");
- goto f_msgpackparse_exit;
- }
- tv_list_append_owned_tv(ret_list, tv);
- }
- if (result == MSGPACK_UNPACK_CONTINUE) {
- if (rlret == OK) {
- EMSG2(_(e_invarg2), "Incomplete msgpack string");
- }
+ const msgpack_unpack_return result
+ = msgpack_unpacker_next(unpacker, &unpacked);
+ const int conv_result = msgpackparse_convert_item(unpacked.data, result,
+ ret_list, rlret == OK);
+ if (conv_result == NOTDONE) {
break;
+ } else if (conv_result == FAIL) {
+ goto end;
}
}
if (rlret == OK) {
@@ -6387,10 +6643,46 @@ static void f_msgpackparse(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
} while (true);
-f_msgpackparse_exit:
- msgpack_unpacked_destroy(&unpacked);
+end:
msgpack_unpacker_free(unpacker);
- return;
+ msgpack_unpacked_destroy(&unpacked);
+}
+
+static void msgpackparse_unpack_blob(const blob_T *const blob, list_T *const ret_list)
+ FUNC_ATTR_NONNULL_ARG(2)
+{
+ const int len = tv_blob_len(blob);
+ if (len == 0) {
+ return;
+ }
+ msgpack_unpacked unpacked;
+ msgpack_unpacked_init(&unpacked);
+ for (size_t offset = 0; offset < (size_t)len;) {
+ const msgpack_unpack_return result
+ = msgpack_unpack_next(&unpacked, blob->bv_ga.ga_data, len, &offset);
+ if (msgpackparse_convert_item(unpacked.data, result, ret_list, true)
+ != OK) {
+ break;
+ }
+ }
+
+ msgpack_unpacked_destroy(&unpacked);
+}
+
+/// "msgpackparse" function
+static void f_msgpackparse(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+ FUNC_ATTR_NONNULL_ALL
+{
+ if (argvars[0].v_type != VAR_LIST && argvars[0].v_type != VAR_BLOB) {
+ EMSG2(_(e_listblobarg), "msgpackparse()");
+ return;
+ }
+ list_T *const ret_list = tv_list_alloc_ret(rettv, kListLenMayKnow);
+ if (argvars[0].v_type == VAR_LIST) {
+ msgpackparse_unpack_list(argvars[0].vval.v_list, ret_list);
+ } else {
+ msgpackparse_unpack_blob(argvars[0].vval.v_blob, ret_list);
+ }
}
/*
@@ -6525,53 +6817,51 @@ static void f_printf(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
// "prompt_setcallback({buffer}, {callback})" function
-static void f_prompt_setcallback(typval_T *argvars,
- typval_T *rettv, FunPtr fptr)
+static void f_prompt_setcallback(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- buf_T *buf;
- Callback prompt_callback = { .type = kCallbackNone };
+ buf_T *buf;
+ Callback prompt_callback = { .type = kCallbackNone };
- if (check_secure()) {
- return;
- }
- buf = tv_get_buf(&argvars[0], false);
- if (buf == NULL) {
- return;
- }
+ if (check_secure()) {
+ return;
+ }
+ buf = tv_get_buf(&argvars[0], false);
+ if (buf == NULL) {
+ return;
+ }
- if (argvars[1].v_type != VAR_STRING || *argvars[1].vval.v_string != NUL) {
- if (!callback_from_typval(&prompt_callback, &argvars[1])) {
- return;
- }
+ if (argvars[1].v_type != VAR_STRING || *argvars[1].vval.v_string != NUL) {
+ if (!callback_from_typval(&prompt_callback, &argvars[1])) {
+ return;
}
+ }
- callback_free(&buf->b_prompt_callback);
- buf->b_prompt_callback = prompt_callback;
+ callback_free(&buf->b_prompt_callback);
+ buf->b_prompt_callback = prompt_callback;
}
// "prompt_setinterrupt({buffer}, {callback})" function
-static void f_prompt_setinterrupt(typval_T *argvars,
- typval_T *rettv, FunPtr fptr)
+static void f_prompt_setinterrupt(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- buf_T *buf;
- Callback interrupt_callback = { .type = kCallbackNone };
+ buf_T *buf;
+ Callback interrupt_callback = { .type = kCallbackNone };
- if (check_secure()) {
- return;
- }
- buf = tv_get_buf(&argvars[0], false);
- if (buf == NULL) {
- return;
- }
+ if (check_secure()) {
+ return;
+ }
+ buf = tv_get_buf(&argvars[0], false);
+ if (buf == NULL) {
+ return;
+ }
- if (argvars[1].v_type != VAR_STRING || *argvars[1].vval.v_string != NUL) {
- if (!callback_from_typval(&interrupt_callback, &argvars[1])) {
- return;
- }
+ if (argvars[1].v_type != VAR_STRING || *argvars[1].vval.v_string != NUL) {
+ if (!callback_from_typval(&interrupt_callback, &argvars[1])) {
+ return;
}
+ }
- callback_free(&buf->b_prompt_interrupt);
- buf->b_prompt_interrupt= interrupt_callback;
+ callback_free(&buf->b_prompt_interrupt);
+ buf->b_prompt_interrupt= interrupt_callback;
}
/// "prompt_getprompt({buffer})" function
@@ -6595,23 +6885,22 @@ void f_prompt_getprompt(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
// "prompt_setprompt({buffer}, {text})" function
-static void f_prompt_setprompt(typval_T *argvars,
- typval_T *rettv, FunPtr fptr)
+static void f_prompt_setprompt(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- buf_T *buf;
- const char_u *text;
+ buf_T *buf;
+ const char_u *text;
- if (check_secure()) {
- return;
- }
- buf = tv_get_buf(&argvars[0], false);
- if (buf == NULL) {
- return;
- }
+ if (check_secure()) {
+ return;
+ }
+ buf = tv_get_buf(&argvars[0], false);
+ if (buf == NULL) {
+ return;
+ }
- text = (const char_u *)tv_get_string(&argvars[1]);
- xfree(buf->b_prompt_text);
- buf->b_prompt_text = vim_strsave(text);
+ text = (const char_u *)tv_get_string(&argvars[1]);
+ xfree(buf->b_prompt_text);
+ buf->b_prompt_text = vim_strsave(text);
}
// "pum_getpos()" function
@@ -6626,8 +6915,9 @@ static void f_pum_getpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_pumvisible(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- if (pum_visible())
+ if (pum_visible()) {
rettv->vval.v_number = 1;
+ }
}
/*
@@ -6801,11 +7091,12 @@ static void f_readdir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
bool binary = false;
- FILE *fd;
+ bool blob = false;
+ FILE *fd;
char_u buf[(IOSIZE/256) * 256]; // rounded to avoid odd + 1
int io_size = sizeof(buf);
int readlen; // size of last fread()
- char_u *prev = NULL; // previously read bytes, if any
+ char_u *prev = NULL; // previously read bytes, if any
long prevlen = 0; // length of data in prev
long prevsize = 0; // size of prev buffer
long maxline = MAXLNUM;
@@ -6813,22 +7104,41 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (argvars[1].v_type != VAR_UNKNOWN) {
if (strcmp(tv_get_string(&argvars[1]), "b") == 0) {
binary = true;
+ } else if (strcmp(tv_get_string(&argvars[1]), "B") == 0) {
+ blob = true;
}
if (argvars[2].v_type != VAR_UNKNOWN) {
maxline = tv_get_number(&argvars[2]);
}
}
- list_T *const l = tv_list_alloc_ret(rettv, kListLenUnknown);
-
// Always open the file in binary mode, library functions have a mind of
// their own about CR-LF conversion.
const char *const fname = tv_get_string(&argvars[0]);
+
+ if (os_isdir((const char_u *)fname)) {
+ EMSG2(_(e_isadir2), fname);
+ return;
+ }
if (*fname == NUL || (fd = os_fopen(fname, READBIN)) == NULL) {
EMSG2(_(e_notopen), *fname == NUL ? _("<empty>") : fname);
return;
}
+ if (blob) {
+ tv_blob_alloc_ret(rettv);
+ if (!read_blob(fd, rettv->vval.v_blob)) {
+ EMSG2(_(e_notread), fname);
+ // An empty blob is returned on error.
+ tv_blob_free(rettv->vval.v_blob);
+ rettv->vval.v_blob = NULL;
+ }
+ fclose(fd);
+ return;
+ }
+
+ list_T *const l = tv_list_alloc_ret(rettv, kListLenUnknown);
+
while (maxline < 0 || tv_list_len(l) < maxline) {
readlen = (int)fread(buf, 1, io_size, fd);
@@ -6843,7 +7153,7 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
p < buf + readlen || (readlen <= 0 && (prevlen > 0 || binary));
p++) {
if (*p == '\n' || readlen <= 0) {
- char_u *s = NULL;
+ char_u *s = NULL;
size_t len = p - start;
// Finished a line. Remove CRs before NL.
@@ -6893,16 +7203,17 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
} else if (*p == NUL) {
*p = '\n';
- // Check for utf8 "bom"; U+FEFF is encoded as EF BB BF. Do this
- // when finding the BF and check the previous two bytes.
+ // Check for utf8 "bom"; U+FEFF is encoded as EF BB BF. Do this
+ // when finding the BF and check the previous two bytes.
} else if (*p == 0xbf && !binary) {
// Find the two bytes before the 0xbf. If p is at buf, or buf + 1,
// these may be in the "prev" string.
char_u back1 = p >= buf + 1 ? p[-1]
- : prevlen >= 1 ? prev[prevlen - 1] : NUL;
+ : prevlen >= 1 ? prev[prevlen - 1] : NUL;
char_u back2 = p >= buf + 2 ? p[-2]
- : p == buf + 1 && prevlen >= 1 ? prev[prevlen - 1]
- : prevlen >= 2 ? prev[prevlen - 2] : NUL;
+ : p == buf + 1 && prevlen >= 1 ? prev[prevlen - 1]
+ : prevlen >=
+ 2 ? prev[prevlen - 2] : NUL;
if (back2 == 0xef && back1 == 0xbb) {
char_u *dest = p - 2;
@@ -6920,8 +7231,9 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// adjust_prevlen must be 1 or 2.
dest = buf;
}
- if (readlen > p - buf + 1)
+ if (readlen > p - buf + 1) {
memmove(dest, p + 1, readlen - (p - buf) - 1);
+ }
readlen -= 3 - adjust_prevlen;
prevlen -= adjust_prevlen;
p = dest - 1;
@@ -6940,9 +7252,9 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
* fragment of a line, so the first allocation is made
* small, to avoid repeatedly 'allocing' large and
* 'reallocing' small. */
- if (prevsize == 0)
+ if (prevsize == 0) {
prevsize = (long)(p - start);
- else {
+ } else {
long grow50pc = (prevsize * 3) / 2;
long growmin = (long)((p - start) * 2 + prevlen);
prevsize = grow50pc > growmin ? grow50pc : growmin;
@@ -6959,6 +7271,61 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
fclose(fd);
}
+/// "getreginfo()" function
+static void f_getreginfo(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ const char *strregname;
+ if (argvars[0].v_type != VAR_UNKNOWN) {
+ strregname = tv_get_string_chk(&argvars[0]);
+ if (strregname == NULL) {
+ return;
+ }
+ } else {
+ strregname = (const char *)get_vim_var_str(VV_REG);
+ }
+
+ int regname = (strregname == NULL ? '"' : *strregname);
+ if (regname == 0 || regname == '@') {
+ regname = '"';
+ }
+
+ tv_dict_alloc_ret(rettv);
+ dict_T *const dict = rettv->vval.v_dict;
+
+ list_T *const list = get_reg_contents(regname, kGRegExprSrc | kGRegList);
+ if (list == NULL) {
+ return;
+ }
+ tv_dict_add_list(dict, S_LEN("regcontents"), list);
+
+ char buf[NUMBUFLEN + 2];
+ buf[0] = NUL;
+ buf[1] = NUL;
+ colnr_T reglen = 0;
+ switch (get_reg_type(regname, &reglen)) {
+ case kMTLineWise:
+ buf[0] = 'V';
+ break;
+ case kMTCharWise:
+ buf[0] = 'v';
+ break;
+ case kMTBlockWise:
+ vim_snprintf(buf, sizeof(buf), "%c%d", Ctrl_V, reglen + 1);
+ break;
+ case kMTUnknown:
+ abort();
+ }
+ tv_dict_add_str(dict, S_LEN("regtype"), buf);
+
+ buf[0] = get_register_name(get_unname_register());
+ buf[1] = NUL;
+ if (regname == '"') {
+ tv_dict_add_str(dict, S_LEN("points_to"), buf);
+ } else {
+ tv_dict_add_bool(dict, S_LEN("isunnamed"), regname == buf[0] ? kBoolVarTrue : kBoolVarFalse);
+ }
+}
+
// "reg_executing()" function
static void f_reg_executing(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
@@ -7042,7 +7409,7 @@ static void f_reltime(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// results, if varnumber_T or proftime_T change, the union cast will need
// to be revised.
STATIC_ASSERT(sizeof(u.prof) == sizeof(u) && sizeof(u.split) == sizeof(u),
- "type punning will produce incorrect results on this platform");
+ "type punning will produce incorrect results on this platform");
tv_list_alloc_ret(rettv, 2);
tv_list_append_number(rettv->vval.v_list, u.split.high);
@@ -7067,13 +7434,13 @@ static void f_reltimestr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_remove(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- list_T *l;
- listitem_T *item, *item2;
- listitem_T *li;
+ list_T *l;
+ listitem_T *item, *item2;
+ listitem_T *li;
long idx;
long end;
- dict_T *d;
- dictitem_T *di;
+ dict_T *d;
+ dictitem_T *di;
const char *const arg_errmsg = N_("remove() argument");
if (argvars[0].v_type == VAR_DICT) {
@@ -7097,8 +7464,64 @@ static void f_remove(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
}
+ } else if (argvars[0].v_type == VAR_BLOB) {
+ blob_T *const b = argvars[0].vval.v_blob;
+
+ if (b != NULL && var_check_lock(b->bv_lock, arg_errmsg, TV_TRANSLATE)) {
+ return;
+ }
+
+ bool error = false;
+ idx = (long)tv_get_number_chk(&argvars[1], &error);
+
+ if (!error) {
+ const int len = tv_blob_len(b);
+
+ if (idx < 0) {
+ // count from the end
+ idx = len + idx;
+ }
+ if (idx < 0 || idx >= len) {
+ EMSGN(_(e_blobidx), idx);
+ return;
+ }
+ if (argvars[2].v_type == VAR_UNKNOWN) {
+ // Remove one item, return its value.
+ char_u *const p = (char_u *)b->bv_ga.ga_data;
+ rettv->vval.v_number = (varnumber_T)(*(p + idx));
+ memmove(p + idx, p + idx + 1, (size_t)len - idx - 1);
+ b->bv_ga.ga_len--;
+ } else {
+ // Remove range of items, return blob with values.
+ end = (long)tv_get_number_chk(&argvars[2], &error);
+ if (error) {
+ return;
+ }
+ if (end < 0) {
+ // count from the end
+ end = len + end;
+ }
+ if (end >= len || idx > end) {
+ EMSGN(_(e_blobidx), end);
+ return;
+ }
+ blob_T *const blob = tv_blob_alloc();
+ blob->bv_ga.ga_len = end - idx + 1;
+ ga_grow(&blob->bv_ga, end - idx + 1);
+
+ char_u *const p = (char_u *)b->bv_ga.ga_data;
+ memmove((char_u *)blob->bv_ga.ga_data, p + idx,
+ (size_t)(end - idx + 1));
+ tv_blob_set_ret(rettv, blob);
+
+ if (len - end - 1 > 0) {
+ memmove(p + idx, p + end + 1, (size_t)(len - end - 1));
+ }
+ b->bv_ga.ga_len -= end - idx + 1;
+ }
+ }
} else if (argvars[0].v_type != VAR_LIST) {
- EMSG2(_(e_listdictarg), "remove()");
+ EMSG2(_(e_listdictblobarg), "remove()");
} else if (!var_check_lock(tv_list_locked((l = argvars[0].vval.v_list)),
arg_errmsg, TV_TRANSLATE)) {
bool error = false;
@@ -7151,9 +7574,8 @@ static void f_rename(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = -1;
} else {
char buf[NUMBUFLEN];
- rettv->vval.v_number = vim_rename(
- (const char_u *)tv_get_string(&argvars[0]),
- (const char_u *)tv_get_string_buf(&argvars[1], buf));
+ rettv->vval.v_number = vim_rename((const char_u *)tv_get_string(&argvars[0]),
+ (const char_u *)tv_get_string_buf(&argvars[1], buf));
}
}
@@ -7372,13 +7794,25 @@ static void f_resolve(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_reverse(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- list_T *l;
- if (argvars[0].v_type != VAR_LIST) {
- EMSG2(_(e_listarg), "reverse()");
- } else if (!var_check_lock(tv_list_locked((l = argvars[0].vval.v_list)),
- N_("reverse() argument"), TV_TRANSLATE)) {
- tv_list_reverse(l);
- tv_list_set_ret(rettv, l);
+ if (argvars[0].v_type == VAR_BLOB) {
+ blob_T *const b = argvars[0].vval.v_blob;
+ const int len = tv_blob_len(b);
+
+ for (int i = 0; i < len / 2; i++) {
+ const char_u tmp = tv_blob_get(b, i);
+ tv_blob_set(b, i, tv_blob_get(b, len - i - 1));
+ tv_blob_set(b, len - i - 1, tmp);
+ }
+ tv_blob_set_ret(rettv, b);
+ } else if (argvars[0].v_type != VAR_LIST) {
+ EMSG2(_(e_listblobarg), "reverse()");
+ } else {
+ list_T *const l = argvars[0].vval.v_list;
+ if (!var_check_lock(tv_list_locked(l), N_("reverse() argument"),
+ TV_TRANSLATE)) {
+ tv_list_reverse(l);
+ tv_list_set_ret(rettv, l);
+ }
}
}
@@ -7409,30 +7843,40 @@ static int get_search_arg(typval_T *varp, int *flagsp)
}
while (*flags != NUL) {
switch (*flags) {
- case 'b': dir = BACKWARD; break;
- case 'w': p_ws = true; break;
- case 'W': p_ws = false; break;
- default: {
- mask = 0;
- if (flagsp != NULL) {
- switch (*flags) {
- case 'c': mask = SP_START; break;
- case 'e': mask = SP_END; break;
- case 'm': mask = SP_RETCOUNT; break;
- case 'n': mask = SP_NOMOVE; break;
- case 'p': mask = SP_SUBPAT; break;
- case 'r': mask = SP_REPEAT; break;
- case 's': mask = SP_SETPCMARK; break;
- case 'z': mask = SP_COLUMN; break;
- }
- }
- if (mask == 0) {
- emsgf(_(e_invarg2), flags);
- dir = 0;
- } else {
- *flagsp |= mask;
+ case 'b':
+ dir = BACKWARD; break;
+ case 'w':
+ p_ws = true; break;
+ case 'W':
+ p_ws = false; break;
+ default:
+ mask = 0;
+ if (flagsp != NULL) {
+ switch (*flags) {
+ case 'c':
+ mask = SP_START; break;
+ case 'e':
+ mask = SP_END; break;
+ case 'm':
+ mask = SP_RETCOUNT; break;
+ case 'n':
+ mask = SP_NOMOVE; break;
+ case 'p':
+ mask = SP_SUBPAT; break;
+ case 'r':
+ mask = SP_REPEAT; break;
+ case 's':
+ mask = SP_SETPCMARK; break;
+ case 'z':
+ mask = SP_COLUMN; break;
}
}
+ if (mask == 0) {
+ emsgf(_(e_invarg2), flags);
+ dir = 0;
+ } else {
+ *flagsp |= mask;
+ }
}
if (dir == 0) {
break;
@@ -7511,12 +7955,14 @@ static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
subpatnum = searchit(curwin, curbuf, &pos, NULL, dir, (char_u *)pat, 1,
options, RE_SEARCH, &sia);
if (subpatnum != FAIL) {
- if (flags & SP_SUBPAT)
+ if (flags & SP_SUBPAT) {
retval = subpatnum;
- else
+ } else {
retval = pos.lnum;
- if (flags & SP_SETPCMARK)
+ }
+ if (flags & SP_SETPCMARK) {
setpcmark();
+ }
curwin->w_cursor = pos;
if (match_pos != NULL) {
// Store the match cursor position
@@ -7654,10 +8100,10 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
msg_ext_set_kind("rpc_error");
if (name) {
- emsgf_multiline("Error invoking '%s' on channel %"PRIu64" (%s):\n%s",
+ emsgf_multiline("Error invoking '%s' on channel %" PRIu64 " (%s):\n%s",
method, chan_id, name, err.msg);
} else {
- emsgf_multiline("Error invoking '%s' on channel %"PRIu64":\n%s",
+ emsgf_multiline("Error invoking '%s' on channel %" PRIu64 ":\n%s",
method, chan_id, err.msg);
}
@@ -7732,8 +8178,9 @@ static void f_rpcstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
Channel *chan = channel_job_start(argv, CALLBACK_READER_INIT,
CALLBACK_READER_INIT, CALLBACK_NONE,
- false, true, false, false, NULL, 0, 0,
- NULL, &rettv->vval.v_number);
+ false, true, false, false,
+ kChannelStdinPipe, NULL, 0, 0, NULL,
+ &rettv->vval.v_number);
if (chan) {
channel_create_event(chan, NULL);
}
@@ -7769,9 +8216,7 @@ static void f_rpcstop(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "screenattr()" function
- */
+// "screenattr()" function
static void f_screenattr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int c;
@@ -7789,9 +8234,7 @@ static void f_screenattr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = c;
}
-/*
- * "screenchar()" function
- */
+// "screenchar()" function
static void f_screenchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int c;
@@ -7809,11 +8252,34 @@ static void f_screenchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = c;
}
-/*
- * "screencol()" function
- *
- * First column is 1 to be consistent with virtcol().
- */
+// "screenchars()" function
+static void f_screenchars(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ int row = tv_get_number_chk(&argvars[0], NULL) - 1;
+ int col = tv_get_number_chk(&argvars[1], NULL) - 1;
+ if (row < 0 || row >= default_grid.Rows
+ || col < 0 || col >= default_grid.Columns) {
+ tv_list_alloc_ret(rettv, 0);
+ return;
+ }
+ ScreenGrid *grid = &default_grid;
+ screenchar_adjust_grid(&grid, &row, &col);
+ int pcc[MAX_MCO];
+ int c = utfc_ptr2char(grid->chars[grid->line_offset[row] + col], pcc);
+ int composing_len = 0;
+ while (pcc[composing_len] != 0) {
+ composing_len++;
+ }
+ tv_list_alloc_ret(rettv, composing_len + 1);
+ tv_list_append_number(rettv->vval.v_list, c);
+ for (int i = 0; i < composing_len; i++) {
+ tv_list_append_number(rettv->vval.v_list, pcc[i]);
+ }
+}
+
+// "screencol()" function
+//
+// First column is 1 to be consistent with virtcol().
static void f_screencol(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = ui_current_col() + 1;
@@ -7845,17 +8311,29 @@ static void f_screenpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
tv_dict_add_nr(dict, S_LEN("endcol"), ecol);
}
-/*
- * "screenrow()" function
- */
+// "screenrow()" function
static void f_screenrow(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = ui_current_row() + 1;
}
-/*
- * "search()" function
- */
+// "screenstring()" function
+static void f_screenstring(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ rettv->vval.v_string = NULL;
+ rettv->v_type = VAR_STRING;
+ int row = tv_get_number_chk(&argvars[0], NULL) - 1;
+ int col = tv_get_number_chk(&argvars[1], NULL) - 1;
+ if (row < 0 || row >= default_grid.Rows
+ || col < 0 || col >= default_grid.Columns) {
+ return;
+ }
+ ScreenGrid *grid = &default_grid;
+ screenchar_adjust_grid(&grid, &row, &col);
+ rettv->vval.v_string = vim_strsave(grid->chars[grid->line_offset[row] + col]);
+}
+
+// "search()" function
static void f_search(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int flags = 0;
@@ -7958,9 +8436,8 @@ static int searchpair_cmn(typval_T *argvars, pos_T *match_pos)
}
}
- retval = do_searchpair(
- spat, mpat, epat, dir, skip,
- flags, match_pos, lnum_stop, time_limit);
+ retval = do_searchpair(spat, mpat, epat, dir, skip,
+ flags, match_pos, lnum_stop, time_limit);
theend:
p_ws = save_p_ws;
@@ -8001,22 +8478,19 @@ static void f_searchpairpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
* Used by searchpair(), see its documentation for the details.
* Returns 0 or -1 for no match,
*/
-long
-do_searchpair(
- const char *spat, // start pattern
- const char *mpat, // middle pattern
- const char *epat, // end pattern
- int dir, // BACKWARD or FORWARD
- const typval_T *skip, // skip expression
- int flags, // SP_SETPCMARK and other SP_ values
- pos_T *match_pos,
- linenr_T lnum_stop, // stop at this line if not zero
- long time_limit // stop after this many msec
-)
+long do_searchpair(const char *spat, // start pattern
+ const char *mpat, // middle pattern
+ const char *epat, // end pattern
+ int dir, // BACKWARD or FORWARD
+ const typval_T *skip, // skip expression
+ int flags, // SP_SETPCMARK and other SP_ values
+ pos_T *match_pos, linenr_T lnum_stop, // stop at this line if not zero
+ long time_limit // stop after this many msec
+ )
FUNC_ATTR_NONNULL_ARG(1, 2, 3)
{
- char_u *save_cpo;
- char_u *pat, *pat2 = NULL, *pat3 = NULL;
+ char_u *save_cpo;
+ char_u *pat, *pat2 = NULL, *pat3 = NULL;
long retval = 0;
pos_T pos;
pos_T firstpos;
@@ -8078,8 +8552,9 @@ do_searchpair(
break;
}
- if (firstpos.lnum == 0)
+ if (firstpos.lnum == 0) {
firstpos = pos;
+ }
if (equalpos(pos, foundpos)) {
// Found the same position again. Can happen with a pattern that
// has "\zs" at the end and searching backwards. Advance one
@@ -8108,8 +8583,9 @@ do_searchpair(
retval = -1;
break;
}
- if (r)
+ if (r) {
continue;
+ }
}
if ((dir == BACKWARD && n == 3) || (dir == FORWARD && n == 2)) {
@@ -8136,8 +8612,9 @@ do_searchpair(
setpcmark();
}
curwin->w_cursor = pos;
- if (!(flags & SP_REPEAT))
+ if (!(flags & SP_REPEAT)) {
break;
+ }
nest = 1; // search for next unmatched
}
}
@@ -8269,16 +8746,16 @@ static void f_serverstop(typval_T *argvars, typval_T *rettv, FunPtr fptr)
/// "setbufline()" function
static void f_setbufline(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- linenr_T lnum;
- buf_T *buf;
+ linenr_T lnum;
+ buf_T *buf;
- buf = tv_get_buf(&argvars[0], false);
- if (buf == NULL) {
- rettv->vval.v_number = 1; // FAIL
- } else {
- lnum = tv_get_lnum_buf(&argvars[1], buf);
- set_buffer_lines(buf, lnum, false, &argvars[2], rettv);
- }
+ buf = tv_get_buf(&argvars[0], false);
+ if (buf == NULL) {
+ rettv->vval.v_number = 1; // FAIL
+ } else {
+ lnum = tv_get_lnum_buf(&argvars[1], buf);
+ set_buffer_lines(buf, lnum, false, &argvars[2], rettv);
+ }
}
/*
@@ -8329,8 +8806,8 @@ static void f_setbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_setcharsearch(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- dict_T *d;
- dictitem_T *di;
+ dict_T *d;
+ dictitem_T *di;
if (argvars[0].v_type != VAR_DICT) {
EMSG(_(e_dictreq));
@@ -8510,7 +8987,7 @@ skip_args:
*/
static void f_setloclist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- win_T *win;
+ win_T *win;
rettv->vval.v_number = -1;
@@ -8632,7 +9109,7 @@ static void f_setpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
pos_T pos;
int fnum;
- colnr_T curswant = -1;
+ colnr_T curswant = -1;
rettv->vval.v_number = -1;
const char *const name = tv_get_string_chk(argvars);
@@ -8650,7 +9127,7 @@ static void f_setpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
check_cursor();
rettv->vval.v_number = 0;
- } else if (name[0] == '\'' && name[1] != NUL && name[2] == NUL) {
+ } else if (name[0] == '\'' && name[1] != NUL && name[2] == NUL) {
// set mark
if (setmark_pos((uint8_t)name[1], &pos, fnum) == OK) {
rettv->vval.v_number = 0;
@@ -8670,6 +9147,36 @@ static void f_setqflist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
set_qf_ll_list(NULL, argvars, rettv);
}
+/// Translate a register type string to the yank type and block length
+static int get_yank_type(char_u **const pp, MotionType *const yank_type, long *const block_len)
+ FUNC_ATTR_NONNULL_ALL
+{
+ char_u *stropt = *pp;
+ switch (*stropt) {
+ case 'v':
+ case 'c': // character-wise selection
+ *yank_type = kMTCharWise;
+ break;
+ case 'V':
+ case 'l': // line-wise selection
+ *yank_type = kMTLineWise;
+ break;
+ case 'b':
+ case Ctrl_V: // block-wise selection
+ *yank_type = kMTBlockWise;
+ if (ascii_isdigit(stropt[1])) {
+ stropt++;
+ *block_len = getdigits_long(&stropt, false, 0) - 1;
+ stropt--;
+ }
+ break;
+ default:
+ return FAIL;
+ }
+ *pp = stropt;
+ return OK;
+}
+
/*
* "setreg()" function
*/
@@ -8694,45 +9201,75 @@ static void f_setreg(typval_T *argvars, typval_T *rettv, FunPtr fptr)
regname = '"';
}
+ const typval_T *regcontents = NULL;
+ int pointreg = 0;
+ if (argvars[1].v_type == VAR_DICT) {
+ dict_T *const d = argvars[1].vval.v_dict;
+
+ if (tv_dict_len(d) == 0) {
+ // Empty dict, clear the register (like setreg(0, []))
+ char_u *lstval[2] = { NULL, NULL };
+ write_reg_contents_lst(regname, lstval, false, kMTUnknown, -1);
+ return;
+ }
+
+ dictitem_T *const di = tv_dict_find(d, "regcontents", -1);
+ if (di != NULL) {
+ regcontents = &di->di_tv;
+ }
+
+ const char *stropt = tv_dict_get_string(d, "regtype", false);
+ if (stropt != NULL) {
+ const int ret = get_yank_type((char_u **)&stropt, &yank_type, &block_len);
+
+ if (ret == FAIL || *(++stropt) != NUL) {
+ EMSG2(_(e_invargval), "value");
+ return;
+ }
+ }
+
+ if (regname == '"') {
+ stropt = tv_dict_get_string(d, "points_to", false);
+ if (stropt != NULL) {
+ pointreg = *stropt;
+ regname = pointreg;
+ }
+ } else if (tv_dict_get_number(d, "isunnamed")) {
+ pointreg = regname;
+ }
+ } else {
+ regcontents = &argvars[1];
+ }
+
bool set_unnamed = false;
if (argvars[2].v_type != VAR_UNKNOWN) {
+ if (yank_type != kMTUnknown) {
+ EMSG2(_(e_toomanyarg), "setreg");
+ return;
+ }
+
const char *stropt = tv_get_string_chk(&argvars[2]);
if (stropt == NULL) {
return; // Type error.
}
for (; *stropt != NUL; stropt++) {
switch (*stropt) {
- case 'a': case 'A': { // append
- append = true;
- break;
- }
- case 'v': case 'c': { // character-wise selection
- yank_type = kMTCharWise;
- break;
- }
- case 'V': case 'l': { // line-wise selection
- yank_type = kMTLineWise;
- break;
- }
- case 'b': case Ctrl_V: { // block-wise selection
- yank_type = kMTBlockWise;
- if (ascii_isdigit(stropt[1])) {
- stropt++;
- block_len = getdigits_long((char_u **)&stropt, true, 0) - 1;
- stropt--;
- }
- break;
- }
- case 'u': case '"': { // unnamed register
- set_unnamed = true;
- break;
- }
+ case 'a':
+ case 'A': // append
+ append = true;
+ break;
+ case 'u':
+ case '"': // unnamed register
+ set_unnamed = true;
+ break;
+ default:
+ get_yank_type((char_u **)&stropt, &yank_type, &block_len);
}
}
}
- if (argvars[1].v_type == VAR_LIST) {
- list_T *ll = argvars[1].vval.v_list;
+ if (regcontents != NULL && regcontents->v_type == VAR_LIST) {
+ list_T *const ll = regcontents->vval.v_list;
// If the list is NULL handle like an empty list.
const int len = tv_list_len(ll);
@@ -8768,19 +9305,23 @@ free_lstval:
xfree(*--curallocval);
}
xfree(lstval);
- } else {
- const char *strval = tv_get_string_chk(&argvars[1]);
+ } else if (regcontents != NULL) {
+ const char *const strval = tv_get_string_chk(regcontents);
if (strval == NULL) {
return;
}
write_reg_contents_ex(regname, (const char_u *)strval, STRLEN(strval),
append, yank_type, block_len);
}
+ if (pointreg != 0) {
+ get_yank_register(pointreg, YREG_YANK);
+ }
rettv->vval.v_number = 0;
if (set_unnamed) {
// Discard the result. We already handle the error case.
- if (op_reg_set_previous(regname)) { }
+ if (op_reg_set_previous(regname)) {
+ }
}
}
@@ -8828,54 +9369,54 @@ static void f_settabwinvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// "settagstack()" function
static void f_settagstack(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- static char *e_invact2 = N_("E962: Invalid action: '%s'");
- win_T *wp;
- dict_T *d;
- int action = 'r';
+ static char *e_invact2 = N_("E962: Invalid action: '%s'");
+ win_T *wp;
+ dict_T *d;
+ int action = 'r';
- rettv->vval.v_number = -1;
+ rettv->vval.v_number = -1;
- // first argument: window number or id
- wp = find_win_by_nr_or_id(&argvars[0]);
- if (wp == NULL) {
- return;
- }
+ // first argument: window number or id
+ wp = find_win_by_nr_or_id(&argvars[0]);
+ if (wp == NULL) {
+ return;
+ }
- // second argument: dict with items to set in the tag stack
- if (argvars[1].v_type != VAR_DICT) {
- EMSG(_(e_dictreq));
- return;
- }
- d = argvars[1].vval.v_dict;
- if (d == NULL) {
+ // second argument: dict with items to set in the tag stack
+ if (argvars[1].v_type != VAR_DICT) {
+ EMSG(_(e_dictreq));
+ return;
+ }
+ d = argvars[1].vval.v_dict;
+ if (d == NULL) {
+ return;
+ }
+
+ // third argument: action - 'a' for append and 'r' for replace.
+ // default is to replace the stack.
+ if (argvars[2].v_type == VAR_UNKNOWN) {
+ action = 'r';
+ } else if (argvars[2].v_type == VAR_STRING) {
+ const char *actstr;
+ actstr = tv_get_string_chk(&argvars[2]);
+ if (actstr == NULL) {
return;
}
-
- // third argument: action - 'a' for append and 'r' for replace.
- // default is to replace the stack.
- if (argvars[2].v_type == VAR_UNKNOWN) {
- action = 'r';
- } else if (argvars[2].v_type == VAR_STRING) {
- const char *actstr;
- actstr = tv_get_string_chk(&argvars[2]);
- if (actstr == NULL) {
- return;
- }
- if ((*actstr == 'r' || *actstr == 'a' || *actstr == 't')
- && actstr[1] == NUL) {
- action = *actstr;
- } else {
- EMSG2(_(e_invact2), actstr);
- return;
- }
+ if ((*actstr == 'r' || *actstr == 'a' || *actstr == 't')
+ && actstr[1] == NUL) {
+ action = *actstr;
} else {
- EMSG(_(e_stringreq));
- return;
+ EMSG2(_(e_invact2), actstr);
+ return;
}
+ } else {
+ EMSG(_(e_stringreq));
+ return;
+ }
- if (set_tagstack(wp, d, action) == OK) {
- rettv->vval.v_number = 0;
- }
+ if (set_tagstack(wp, d, action) == OK) {
+ rettv->vval.v_number = 0;
+ }
}
/*
@@ -8890,7 +9431,7 @@ static void f_setwinvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_sha256(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const char *p = tv_get_string(&argvars[0]);
- const char *hash = sha256_bytes((const uint8_t *)p, strlen(p) , NULL, 0);
+ const char *hash = sha256_bytes((const uint8_t *)p, strlen(p), NULL, 0);
// make a copy of the hash (sha256_bytes returns a static buffer)
rettv->vval.v_string = (char_u *)xstrdup(hash);
@@ -8904,8 +9445,9 @@ static void f_shellescape(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const bool do_special = non_zero_arg(&argvars[1]);
- rettv->vval.v_string = vim_strsave_shellescape(
- (const char_u *)tv_get_string(&argvars[0]), do_special, do_special);
+ rettv->vval.v_string = vim_strsave_shellescape((const char_u *)tv_get_string(
+ &argvars[0]), do_special,
+ do_special);
rettv->v_type = VAR_STRING;
}
@@ -8955,8 +9497,9 @@ static void f_sign_define(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
- rettv->vval.v_number = sign_define_from_dict(
- name, argvars[1].v_type == VAR_DICT ? argvars[1].vval.v_dict : NULL);
+ rettv->vval.v_number = sign_define_from_dict(name,
+ argvars[1].v_type ==
+ VAR_DICT ? argvars[1].vval.v_dict : NULL);
}
/// "sign_getdefined()" function
@@ -9088,8 +9631,8 @@ static void f_sign_place(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
- rettv->vval.v_number = sign_place_from_dict(
- &argvars[0], &argvars[1], &argvars[2], &argvars[3], dict);
+ rettv->vval.v_number = sign_place_from_dict(&argvars[0], &argvars[1], &argvars[2], &argvars[3],
+ dict);
}
/// "sign_placelist()" function. Place multiple signs.
@@ -9108,8 +9651,7 @@ static void f_sign_placelist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
TV_LIST_ITER_CONST(argvars[0].vval.v_list, li, {
sign_id = -1;
if (TV_LIST_ITEM_TV(li)->v_type == VAR_DICT) {
- sign_id = sign_place_from_dict(
- NULL, NULL, NULL, NULL, TV_LIST_ITEM_TV(li)->vval.v_dict);
+ sign_id = sign_place_from_dict(NULL, NULL, NULL, NULL, TV_LIST_ITEM_TV(li)->vval.v_dict);
} else {
EMSG(_(e_dictreq));
}
@@ -9378,7 +9920,6 @@ static int item_compare2(const void *s1, const void *s2, bool keep_zero)
int res;
typval_T rettv;
typval_T argv[3];
- int dummy;
const char *func_name;
partial_T *partial = sortinfo->item_compare_partial;
@@ -9402,10 +9943,11 @@ static int item_compare2(const void *s1, const void *s2, bool keep_zero)
tv_copy(TV_LIST_ITEM_TV(si2->item), &argv[1]);
rettv.v_type = VAR_UNKNOWN; // tv_clear() uses this
- res = call_func((const char_u *)func_name,
- -1,
- &rettv, 2, argv, NULL, 0L, 0L, &dummy, true,
- partial, sortinfo->item_compare_selfdict);
+ funcexe_T funcexe = FUNCEXE_INIT;
+ funcexe.evaluate = true;
+ funcexe.partial = partial;
+ funcexe.selfdict = sortinfo->item_compare_selfdict;
+ res = call_func((const char_u *)func_name, -1, &rettv, 2, argv, &funcexe);
tv_clear(&argv[0]);
tv_clear(&argv[1]);
@@ -9445,7 +9987,7 @@ static int item_compare2_not_keeping_zero(const void *s1, const void *s2)
*/
static void do_sort_uniq(typval_T *argvars, typval_T *rettv, bool sort)
{
- ListSortItem *ptrs;
+ ListSortItem *ptrs;
long len;
long i;
@@ -9632,7 +10174,7 @@ static void f_uniq(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
// "reltimefloat()" function
-static void f_reltimefloat(typval_T *argvars , typval_T *rettv, FunPtr fptr)
+static void f_reltimefloat(typval_T *argvars, typval_T *rettv, FunPtr fptr)
FUNC_ATTR_NONNULL_ALL
{
proftime_T tm;
@@ -9707,10 +10249,12 @@ static void f_spellbadword(typval_T *argvars, typval_T *rettv, FunPtr fptr)
tv_list_append_string(rettv->vval.v_list, word, len);
tv_list_append_string(rettv->vval.v_list,
(attr == HLF_SPB ? "bad"
- : attr == HLF_SPR ? "rare"
- : attr == HLF_SPL ? "local"
- : attr == HLF_SPC ? "caps"
- : NULL), -1);
+ : attr == HLF_SPR ? "rare"
+ : attr == HLF_SPL ? "local"
+ : attr ==
+ HLF_SPC ? "caps"
+ :
+ NULL), -1);
}
/*
@@ -9767,7 +10311,7 @@ f_spellsuggest_return:
static void f_split(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *save_cpo;
+ char_u *save_cpo;
int match;
colnr_T col = 0;
bool keepempty = false;
@@ -9904,7 +10448,7 @@ static void f_str2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int base = 10;
varnumber_T n;
- int what;
+ int what = 0;
if (argvars[1].v_type != VAR_UNKNOWN) {
base = tv_get_number(&argvars[1]);
@@ -9912,6 +10456,9 @@ static void f_str2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
EMSG(_(e_invarg));
return;
}
+ if (argvars[2].v_type != VAR_UNKNOWN && tv_get_number(&argvars[2])) {
+ what |= STR2NR_QUOTE;
+ }
}
char_u *p = skipwhite((const char_u *)tv_get_string(&argvars[0]));
@@ -9920,23 +10467,18 @@ static void f_str2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
p = skipwhite(p + 1);
}
switch (base) {
- case 2: {
- what = STR2NR_BIN | STR2NR_FORCE;
- break;
- }
- case 8: {
- what = STR2NR_OCT | STR2NR_FORCE;
- break;
- }
- case 16: {
- what = STR2NR_HEX | STR2NR_FORCE;
- break;
- }
- default: {
- what = 0;
- }
+ case 2:
+ what |= STR2NR_BIN | STR2NR_FORCE;
+ break;
+ case 8:
+ what |= STR2NR_OCT | STR2NR_OOCT | STR2NR_FORCE;
+ break;
+ case 16:
+ what |= STR2NR_HEX | STR2NR_FORCE;
+ break;
}
- vim_str2nr(p, NULL, NULL, what, &n, NULL, 0);
+ vim_str2nr(p, NULL, NULL, what, &n, NULL, 0, false);
+ // Text after the number is silently ignored.
if (isneg) {
rettv->vval.v_number = -n;
} else {
@@ -9967,7 +10509,7 @@ static void f_strftime(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_string = vim_strsave((char_u *)_("(Invalid)"));
} else {
vimconv_T conv;
- char_u *enc;
+ char_u *enc;
conv.vc_type = CONV_NONE;
enc = enc_locale();
@@ -10312,7 +10854,7 @@ static void f_strridx(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_strtrans(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = (char_u *)transstr(tv_get_string(&argvars[0]));
+ rettv->vval.v_string = (char_u *)transstr(tv_get_string(&argvars[0]), true);
}
/*
@@ -10443,53 +10985,46 @@ static void f_synIDattr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
const char *p = NULL;
switch (TOLOWER_ASC(what[0])) {
- case 'b': {
- if (TOLOWER_ASC(what[1]) == 'g') { // bg[#]
- p = highlight_color(id, what, modec);
- } else { // bold
- p = highlight_has_attr(id, HL_BOLD, modec);
- }
- break;
- }
- case 'f': { // fg[#] or font
+ case 'b':
+ if (TOLOWER_ASC(what[1]) == 'g') { // bg[#]
p = highlight_color(id, what, modec);
- break;
- }
- case 'i': {
- if (TOLOWER_ASC(what[1]) == 'n') { // inverse
- p = highlight_has_attr(id, HL_INVERSE, modec);
- } else { // italic
- p = highlight_has_attr(id, HL_ITALIC, modec);
- }
- break;
+ } else { // bold
+ p = highlight_has_attr(id, HL_BOLD, modec);
}
- case 'n': { // name
- p = get_highlight_name_ext(NULL, id - 1, false);
- break;
- }
- case 'r': { // reverse
+ break;
+ case 'f': // fg[#] or font
+ p = highlight_color(id, what, modec);
+ break;
+ case 'i':
+ if (TOLOWER_ASC(what[1]) == 'n') { // inverse
p = highlight_has_attr(id, HL_INVERSE, modec);
- break;
+ } else { // italic
+ p = highlight_has_attr(id, HL_ITALIC, modec);
}
- case 's': {
- if (TOLOWER_ASC(what[1]) == 'p') { // sp[#]
- p = highlight_color(id, what, modec);
- } else if (TOLOWER_ASC(what[1]) == 't'
- && TOLOWER_ASC(what[2]) == 'r') { // strikethrough
- p = highlight_has_attr(id, HL_STRIKETHROUGH, modec);
- } else { // standout
- p = highlight_has_attr(id, HL_STANDOUT, modec);
- }
- break;
+ break;
+ case 'n': // name
+ p = get_highlight_name_ext(NULL, id - 1, false);
+ break;
+ case 'r': // reverse
+ p = highlight_has_attr(id, HL_INVERSE, modec);
+ break;
+ case 's':
+ if (TOLOWER_ASC(what[1]) == 'p') { // sp[#]
+ p = highlight_color(id, what, modec);
+ } else if (TOLOWER_ASC(what[1]) == 't'
+ && TOLOWER_ASC(what[2]) == 'r') { // strikethrough
+ p = highlight_has_attr(id, HL_STRIKETHROUGH, modec);
+ } else { // standout
+ p = highlight_has_attr(id, HL_STANDOUT, modec);
}
- case 'u': {
- if (STRLEN(what) <= 5 || TOLOWER_ASC(what[5]) != 'c') { // underline
- p = highlight_has_attr(id, HL_UNDERLINE, modec);
- } else { // undercurl
- p = highlight_has_attr(id, HL_UNDERCURL, modec);
- }
- break;
+ break;
+ case 'u':
+ if (STRLEN(what) <= 5 || TOLOWER_ASC(what[5]) != 'c') { // underline
+ p = highlight_has_attr(id, HL_UNDERLINE, modec);
+ } else { // undercurl
+ p = highlight_has_attr(id, HL_UNDERCURL, modec);
}
+ break;
}
rettv->v_type = VAR_STRING;
@@ -10599,7 +11134,7 @@ static void f_systemlist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_tabpagebuflist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- win_T *wp = NULL;
+ win_T *wp = NULL;
if (argvars[0].v_type == VAR_UNKNOWN) {
wp = firstwin;
@@ -10652,9 +11187,9 @@ static void f_tabpagenr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static int get_winnr(tabpage_T *tp, typval_T *argvar)
{
- win_T *twin;
+ win_T *twin;
int nr = 1;
- win_T *wp;
+ win_T *wp;
twin = (tp == curtab) ? curwin : tp->tp_curwin;
if (argvar->v_type != VAR_UNKNOWN) {
@@ -10700,7 +11235,7 @@ static int get_winnr(tabpage_T *tp, typval_T *argvar)
}
}
- if (nr > 0)
+ if (nr > 0) {
for (wp = (tp == curtab) ? firstwin : tp->tp_firstwin;
wp != twin; wp = wp->w_next) {
if (wp == NULL) {
@@ -10710,6 +11245,7 @@ static int get_winnr(tabpage_T *tp, typval_T *argvar)
}
++nr;
}
+ }
return nr;
}
@@ -10849,10 +11385,11 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr)
const bool rpc = false;
const bool overlapped = false;
const bool detach = false;
+ ChannelStdinMode stdin_mode = kChannelStdinPipe;
uint16_t term_width = MAX(0, curwin->w_width_inner - win_col_off(curwin));
Channel *chan = channel_job_start(argv, on_stdout, on_stderr, on_exit,
- pty, rpc, overlapped, detach, cwd,
- term_width, curwin->w_height_inner,
+ pty, rpc, overlapped, detach, stdin_mode,
+ cwd, term_width, curwin->w_height_inner,
env, &rettv->vval.v_number);
if (rettv->vval.v_number <= 0) {
return;
@@ -10891,8 +11428,7 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
// "test_garbagecollect_now()" function
-static void f_test_garbagecollect_now(typval_T *argvars,
- typval_T *rettv, FunPtr fptr)
+static void f_test_garbagecollect_now(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
// This is dangerous, any Lists and Dicts used internally may be freed
// while still in use.
@@ -10900,9 +11436,7 @@ static void f_test_garbagecollect_now(typval_T *argvars,
}
// "test_write_list_log()" function
-static void f_test_write_list_log(typval_T *const argvars,
- typval_T *const rettv,
- FunPtr fptr)
+static void f_test_write_list_log(typval_T *const argvars, typval_T *const rettv, FunPtr fptr)
{
const char *const fname = tv_get_string_chk(&argvars[0]);
if (fname == NULL) {
@@ -10977,24 +11511,24 @@ static void f_timer_start(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
rettv->vval.v_number =
- timer_start(tv_get_number(&argvars[0]), repeat, &callback);
+ timer_start(tv_get_number(&argvars[0]), repeat, &callback);
}
// "timer_stop(timerid)" function
static void f_timer_stop(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- if (argvars[0].v_type != VAR_NUMBER) {
- EMSG(_(e_number_exp));
- return;
- }
+ if (argvars[0].v_type != VAR_NUMBER) {
+ EMSG(_(e_number_exp));
+ return;
+ }
- timer_T *timer = find_timer_by_nr(tv_get_number(&argvars[0]));
- if (timer == NULL) {
- return;
- }
+ timer_T *timer = find_timer_by_nr(tv_get_number(&argvars[0]));
+ if (timer == NULL) {
+ return;
+ }
- timer_stop(timer);
+ timer_stop(timer);
}
static void f_timer_stopall(typval_T *argvars, typval_T *unused, FunPtr fptr)
@@ -11195,19 +11729,28 @@ static void f_type(typval_T *argvars, typval_T *rettv, FunPtr fptr)
int n = -1;
switch (argvars[0].v_type) {
- case VAR_NUMBER: n = VAR_TYPE_NUMBER; break;
- case VAR_STRING: n = VAR_TYPE_STRING; break;
- case VAR_PARTIAL:
- case VAR_FUNC: n = VAR_TYPE_FUNC; break;
- case VAR_LIST: n = VAR_TYPE_LIST; break;
- case VAR_DICT: n = VAR_TYPE_DICT; break;
- case VAR_FLOAT: n = VAR_TYPE_FLOAT; break;
- case VAR_BOOL: n = VAR_TYPE_BOOL; break;
- case VAR_SPECIAL:n = VAR_TYPE_SPECIAL; break;
- case VAR_UNKNOWN: {
- internal_error("f_type(UNKNOWN)");
- break;
- }
+ case VAR_NUMBER:
+ n = VAR_TYPE_NUMBER; break;
+ case VAR_STRING:
+ n = VAR_TYPE_STRING; break;
+ case VAR_PARTIAL:
+ case VAR_FUNC:
+ n = VAR_TYPE_FUNC; break;
+ case VAR_LIST:
+ n = VAR_TYPE_LIST; break;
+ case VAR_DICT:
+ n = VAR_TYPE_DICT; break;
+ case VAR_FLOAT:
+ n = VAR_TYPE_FLOAT; break;
+ case VAR_BOOL:
+ n = VAR_TYPE_BOOL; break;
+ case VAR_SPECIAL:
+ n = VAR_TYPE_SPECIAL; break;
+ case VAR_BLOB:
+ n = VAR_TYPE_BLOB; break;
+ case VAR_UNKNOWN:
+ internal_error("f_type(UNKNOWN)");
+ break;
}
rettv->vval.v_number = n;
}
@@ -11267,7 +11810,7 @@ static void f_values(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_virtcol(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
colnr_T vcol = 0;
- pos_T *fp;
+ pos_T *fp;
int fnum = curbuf->b_fnum;
fp = var2fpos(&argvars[0], FALSE, &fnum);
@@ -11352,6 +11895,9 @@ static void f_win_gettype(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_string = vim_strsave((char_u *)"popup");
} else if (wp == curwin && cmdwin_type != 0) {
rettv->vval.v_string = vim_strsave((char_u *)"command");
+ } else if (bt_quickfix(wp->w_buffer)) {
+ rettv->vval.v_string = vim_strsave((char_u *)(wp->w_llist_ref != NULL ?
+ "loclist" : "quickfix"));
}
}
@@ -11515,10 +12061,12 @@ static void f_winrestview(typval_T *argvars, typval_T *rettv, FunPtr fptr)
win_new_width(curwin, curwin->w_width);
changed_window_setting();
- if (curwin->w_topline <= 0)
+ if (curwin->w_topline <= 0) {
curwin->w_topline = 1;
- if (curwin->w_topline > curbuf->b_ml.ml_line_count)
+ }
+ if (curwin->w_topline > curbuf->b_ml.ml_line_count) {
curwin->w_topline = curbuf->b_ml.ml_line_count;
+ }
check_topfill(curwin, true);
}
}
@@ -11528,7 +12076,7 @@ static void f_winrestview(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_winsaveview(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- dict_T *dict;
+ dict_T *dict;
tv_dict_alloc_ret(rettv);
dict = rettv->vval.v_dict;
@@ -11579,16 +12127,17 @@ static void f_writefile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
- if (argvars[0].v_type != VAR_LIST) {
- EMSG2(_(e_listarg), "writefile()");
+ if (argvars[0].v_type == VAR_LIST) {
+ TV_LIST_ITER_CONST(argvars[0].vval.v_list, li, {
+ if (!tv_check_str_or_nr(TV_LIST_ITEM_TV(li))) {
+ return;
+ }
+ });
+ } else if (argvars[0].v_type != VAR_BLOB) {
+ EMSG2(_(e_invarg2),
+ _("writefile() first argument must be a List or a Blob"));
return;
}
- const list_T *const list = argvars[0].vval.v_list;
- TV_LIST_ITER_CONST(list, li, {
- if (!tv_check_str_or_nr(TV_LIST_ITEM_TV(li))) {
- return;
- }
- });
bool binary = false;
bool append = false;
@@ -11600,15 +12149,18 @@ static void f_writefile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
for (const char *p = flags; *p; p++) {
switch (*p) {
- case 'b': { binary = true; break; }
- case 'a': { append = true; break; }
- case 's': { do_fsync = true; break; }
- case 'S': { do_fsync = false; break; }
- default: {
- // Using %s, p and not %c, *p to preserve multibyte characters
- emsgf(_("E5060: Unknown flag: %s"), p);
- return;
- }
+ case 'b':
+ binary = true; break;
+ case 'a':
+ append = true; break;
+ case 's':
+ do_fsync = true; break;
+ case 'S':
+ do_fsync = false; break;
+ default:
+ // Using %s, p and not %c, *p to preserve multibyte characters
+ emsgf(_("E5060: Unknown flag: %s"), p);
+ return;
}
}
}
@@ -11628,7 +12180,13 @@ static void f_writefile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
emsgf(_("E482: Can't open file %s for writing: %s"),
fname, os_strerror(error));
} else {
- if (write_list(&fp, list, binary)) {
+ bool write_ok;
+ if (argvars[0].v_type == VAR_BLOB) {
+ write_ok = write_blob(&fp, argvars[0].vval.v_blob);
+ } else {
+ write_ok = write_list(&fp, argvars[0].vval.v_list, binary);
+ }
+ if (write_ok) {
rettv->vval.v_number = 0;
}
if ((error = file_close(&fp, do_fsync)) != 0) {
diff --git a/src/nvim/eval/funcs.h b/src/nvim/eval/funcs.h
index a343290734..c6a0cb959e 100644
--- a/src/nvim/eval/funcs.h
+++ b/src/nvim/eval/funcs.h
@@ -9,11 +9,16 @@ typedef void (*FunPtr)(void);
/// Prototype of C function that implements VimL function
typedef void (*VimLFunc)(typval_T *args, typval_T *rvar, FunPtr data);
+/// Special flags for base_arg @see VimLFuncDef
+#define BASE_NONE 0 ///< Not a method (no base argument).
+#define BASE_LAST UINT8_MAX ///< Use the last argument as the method base.
+
/// Structure holding VimL function definition
typedef struct fst {
char *name; ///< Name of the function.
uint8_t min_argc; ///< Minimal number of arguments.
uint8_t max_argc; ///< Maximal number of arguments.
+ uint8_t base_arg; ///< Method base arg # (1-indexed), BASE_NONE or BASE_LAST.
VimLFunc func; ///< Function implementation.
FunPtr data; ///< Userdata for function implementation.
} VimLFuncDef;
diff --git a/src/nvim/eval/gc.c b/src/nvim/eval/gc.c
index 2bbf78d827..633e6abacf 100644
--- a/src/nvim/eval/gc.c
+++ b/src/nvim/eval/gc.c
@@ -1,8 +1,8 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
-#include "nvim/eval/typval.h"
#include "nvim/eval/gc.h"
+#include "nvim/eval/typval.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "eval/gc.c.generated.h"
diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c
index 7221dc8bc9..075b50a366 100644
--- a/src/nvim/eval/typval.c
+++ b/src/nvim/eval/typval.c
@@ -1,36 +1,36 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
-#include <stdio.h>
+#include <assert.h>
+#include <stdbool.h>
#include <stddef.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <assert.h>
-#include <stdbool.h>
-#include "nvim/lib/queue.h"
-#include "nvim/eval/typval.h"
-#include "nvim/eval/gc.h"
-#include "nvim/eval/executor.h"
+#include "nvim/ascii.h"
+#include "nvim/assert.h"
+#include "nvim/charset.h"
+#include "nvim/eval.h"
#include "nvim/eval/encode.h"
+#include "nvim/eval/executor.h"
+#include "nvim/eval/gc.h"
+#include "nvim/eval/typval.h"
#include "nvim/eval/typval_encode.h"
-#include "nvim/eval.h"
#include "nvim/eval/userfunc.h"
-#include "nvim/lua/executor.h"
-#include "nvim/types.h"
-#include "nvim/assert.h"
-#include "nvim/memory.h"
-#include "nvim/globals.h"
-#include "nvim/hashtab.h"
-#include "nvim/vim.h"
-#include "nvim/ascii.h"
-#include "nvim/pos.h"
-#include "nvim/charset.h"
#include "nvim/garray.h"
#include "nvim/gettext.h"
+#include "nvim/globals.h"
+#include "nvim/hashtab.h"
+#include "nvim/lib/queue.h"
+#include "nvim/lua/executor.h"
#include "nvim/macros.h"
#include "nvim/mbyte.h"
+#include "nvim/memory.h"
#include "nvim/message.h"
+#include "nvim/pos.h"
+#include "nvim/types.h"
+#include "nvim/vim.h"
// TODO(ZyX-I): Move line_breakcheck out of misc1
#include "nvim/misc1.h" // For line_breakcheck
#include "nvim/os/fileio.h"
@@ -71,11 +71,11 @@ void list_write_log(const char *const fname)
char buf[10 + 1 + ((16 + 3) * 3) + (8 + 2) + 2];
// act : hex " c:" len "[]" "\n\0"
const ListLogEntry entry = chunk->entries[i];
- const size_t snp_len = (size_t)snprintf(
- buf, sizeof(buf),
- "%-10.10s: l:%016" PRIxPTR "[%08d] 1:%016" PRIxPTR " 2:%016" PRIxPTR
- "\n",
- entry.action, entry.l, entry.len, entry.li1, entry.li2);
+ const size_t snp_len = (size_t)snprintf(buf, sizeof(buf),
+ "%-10.10s: l:%016" PRIxPTR "[%08d] 1:%016" PRIxPTR " 2:%016" PRIxPTR
+ "\n",
+ entry.action, entry.l, entry.len, entry.li1,
+ entry.li2);
assert(snp_len + 1 == sizeof(buf));
const ptrdiff_t fw_ret = file_write(&fp, buf, snp_len);
if (fw_ret != (ptrdiff_t)snp_len) {
@@ -100,7 +100,7 @@ void list_write_log(const char *const fname)
}
}
-#ifdef EXITFREE
+# ifdef EXITFREE
/// Free list log
void list_free_log(void)
{
@@ -110,7 +110,7 @@ void list_free_log(void)
chunk = list_log_first;
}
}
-#endif
+# endif
#endif
//{{{2 List item
@@ -343,8 +343,7 @@ void tv_list_unref(list_T *const l)
/// @param[out] l List to remove from.
/// @param[in] item First item to remove.
/// @param[in] item2 Last item to remove.
-void tv_list_drop_items(list_T *const l, listitem_T *const item,
- listitem_T *const item2)
+void tv_list_drop_items(list_T *const l, listitem_T *const item, listitem_T *const item2)
FUNC_ATTR_NONNULL_ALL
{
list_log(l, item, item2, "drop");
@@ -369,8 +368,7 @@ void tv_list_drop_items(list_T *const l, listitem_T *const item,
}
/// Like tv_list_drop_items, but also frees all removed items
-void tv_list_remove_items(list_T *const l, listitem_T *const item,
- listitem_T *const item2)
+void tv_list_remove_items(list_T *const l, listitem_T *const item, listitem_T *const item2)
FUNC_ATTR_NONNULL_ALL
{
list_log(l, item, item2, "remove");
@@ -393,9 +391,8 @@ void tv_list_remove_items(list_T *const l, listitem_T *const item,
/// @param[in] item2 Last item to move.
/// @param[out] tgt_l List to move to.
/// @param[in] cnt Number of items moved.
-void tv_list_move_items(list_T *const l, listitem_T *const item,
- listitem_T *const item2, list_T *const tgt_l,
- const int cnt)
+void tv_list_move_items(list_T *const l, listitem_T *const item, listitem_T *const item2,
+ list_T *const tgt_l, const int cnt)
FUNC_ATTR_NONNULL_ALL
{
list_log(l, item, item2, "move");
@@ -418,8 +415,7 @@ void tv_list_move_items(list_T *const l, listitem_T *const item,
/// @param[in,out] ni Item to insert.
/// @param[in] item Item to insert before. If NULL, inserts at the end of the
/// list.
-void tv_list_insert(list_T *const l, listitem_T *const ni,
- listitem_T *const item)
+void tv_list_insert(list_T *const l, listitem_T *const ni, listitem_T *const item)
FUNC_ATTR_NONNULL_ARG(1, 2)
{
if (item == NULL) {
@@ -449,8 +445,7 @@ void tv_list_insert(list_T *const l, listitem_T *const ni,
/// allocated listitem_T and inserted.
/// @param[in] item Item to insert before. If NULL, inserts at the end of the
/// list.
-void tv_list_insert_tv(list_T *const l, typval_T *const tv,
- listitem_T *const item)
+void tv_list_insert_tv(list_T *const l, typval_T *const tv, listitem_T *const item)
{
listitem_T *const ni = tv_list_item_alloc();
@@ -544,8 +539,7 @@ void tv_list_append_dict(list_T *const l, dict_T *const dict)
/// @param[in] len Length of the appended string. May be -1, in this
/// case string is considered to be usual zero-terminated
/// string or NULL “empty” string.
-void tv_list_append_string(list_T *const l, const char *const str,
- const ssize_t len)
+void tv_list_append_string(list_T *const l, const char *const str, const ssize_t len)
FUNC_ATTR_NONNULL_ARG(1)
{
tv_list_append_owned_tv(l, (typval_T) {
@@ -601,8 +595,8 @@ void tv_list_append_number(list_T *const l, const varnumber_T n)
///
/// @return Copied list. May be NULL in case original list is NULL or some
/// failure happens. The refcount of the new list is set to 1.
-list_T *tv_list_copy(const vimconv_T *const conv, list_T *const orig,
- const bool deep, const int copyID)
+list_T *tv_list_copy(const vimconv_T *const conv, list_T *const orig, const bool deep,
+ const int copyID)
FUNC_ATTR_WARN_UNUSED_RESULT
{
if (orig == NULL) {
@@ -697,8 +691,7 @@ int tv_list_flatten(list_T *list, long maxdepth)
/// @param[out] l1 List to extend.
/// @param[in] l2 List to extend with.
/// @param[in] bef If not NULL, extends before this item.
-void tv_list_extend(list_T *const l1, list_T *const l2,
- listitem_T *const bef)
+void tv_list_extend(list_T *const l1, list_T *const l2, listitem_T *const bef)
FUNC_ATTR_NONNULL_ARG(1)
{
int todo = tv_list_len(l2);
@@ -758,8 +751,8 @@ typedef struct {
/// @param[in] join_gap Garray to keep each list item string.
///
/// @return OK in case of success, FAIL otherwise.
-static int list_join_inner(garray_T *const gap, list_T *const l,
- const char *const sep, garray_T *const join_gap)
+static int list_join_inner(garray_T *const gap, list_T *const l, const char *const sep,
+ garray_T *const join_gap)
FUNC_ATTR_NONNULL_ALL
{
size_t sumlen = 0;
@@ -836,7 +829,7 @@ int tv_list_join(garray_T *const gap, list_T *const l, const char *const sep)
return retval;
}
-/// Chech whether two lists are equal
+/// Check whether two lists are equal
///
/// @param[in] l1 First list to compare.
/// @param[in] l2 Second list to compare.
@@ -844,8 +837,7 @@ int tv_list_join(garray_T *const gap, list_T *const l, const char *const sep)
/// @param[in] recursive True when used recursively.
///
/// @return True if lists are equal, false otherwise.
-bool tv_list_equal(list_T *const l1, list_T *const l2, const bool ic,
- const bool recursive)
+bool tv_list_equal(list_T *const l1, list_T *const l2, const bool ic, const bool recursive)
FUNC_ATTR_WARN_UNUSED_RESULT
{
if (l1 == l2) {
@@ -915,8 +907,7 @@ void tv_list_reverse(list_T *const l)
/// true list will not be modified. Must be initialized to false
/// by the caller.
void tv_list_item_sort(list_T *const l, ListSortItem *const ptrs,
- const ListSorter item_compare_func,
- bool *errp)
+ const ListSorter item_compare_func, bool *errp)
FUNC_ATTR_NONNULL_ARG(3, 4)
{
const int len = tv_list_len(l);
@@ -968,7 +959,7 @@ listitem_T *tv_list_find(list_T *const l, int n)
}
int idx;
- listitem_T *item;
+ listitem_T *item;
// When there is a cached index may start search from there.
if (l->lv_idx_item != NULL) {
@@ -1127,17 +1118,14 @@ bool tv_callback_equal(const Callback *cb1, const Callback *cb2)
return false;
}
switch (cb1->type) {
- case kCallbackFuncref: {
- return STRCMP(cb1->data.funcref, cb2->data.funcref) == 0;
- }
- case kCallbackPartial: {
- // FIXME: this is inconsistent with tv_equal but is needed for precision
- // maybe change dictwatcheradd to return a watcher id instead?
- return cb1->data.partial == cb2->data.partial;
- }
- case kCallbackNone: {
- return true;
- }
+ case kCallbackFuncref:
+ return STRCMP(cb1->data.funcref, cb2->data.funcref) == 0;
+ case kCallbackPartial:
+ // FIXME: this is inconsistent with tv_equal but is needed for precision
+ // maybe change dictwatcheradd to return a watcher id instead?
+ return cb1->data.partial == cb2->data.partial;
+ case kCallbackNone:
+ return true;
}
abort();
return false;
@@ -1148,18 +1136,15 @@ void callback_free(Callback *callback)
FUNC_ATTR_NONNULL_ALL
{
switch (callback->type) {
- case kCallbackFuncref: {
- func_unref(callback->data.funcref);
- xfree(callback->data.funcref);
- break;
- }
- case kCallbackPartial: {
- partial_unref(callback->data.partial);
- break;
- }
- case kCallbackNone: {
- break;
- }
+ case kCallbackFuncref:
+ func_unref(callback->data.funcref);
+ xfree(callback->data.funcref);
+ break;
+ case kCallbackPartial:
+ partial_unref(callback->data.partial);
+ break;
+ case kCallbackNone:
+ break;
}
callback->type = kCallbackNone;
callback->data.funcref = NULL;
@@ -1170,20 +1155,20 @@ void callback_put(Callback *cb, typval_T *tv)
FUNC_ATTR_NONNULL_ALL
{
switch (cb->type) {
- case kCallbackPartial:
- tv->v_type = VAR_PARTIAL;
- tv->vval.v_partial = cb->data.partial;
- cb->data.partial->pt_refcount++;
- break;
- case kCallbackFuncref:
- tv->v_type = VAR_FUNC;
- tv->vval.v_string = vim_strsave(cb->data.funcref);
- func_ref(cb->data.funcref);
- break;
- default:
- tv->v_type = VAR_SPECIAL;
- tv->vval.v_special = kSpecialVarNull;
- break;
+ case kCallbackPartial:
+ tv->v_type = VAR_PARTIAL;
+ tv->vval.v_partial = cb->data.partial;
+ cb->data.partial->pt_refcount++;
+ break;
+ case kCallbackFuncref:
+ tv->v_type = VAR_FUNC;
+ tv->vval.v_string = vim_strsave(cb->data.funcref);
+ func_ref(cb->data.funcref);
+ break;
+ default:
+ tv->v_type = VAR_SPECIAL;
+ tv->vval.v_special = kSpecialVarNull;
+ break;
}
}
@@ -1193,17 +1178,17 @@ void callback_copy(Callback *dest, Callback *src)
{
dest->type = src->type;
switch (src->type) {
- case kCallbackPartial:
- dest->data.partial = src->data.partial;
- dest->data.partial->pt_refcount++;
- break;
- case kCallbackFuncref:
- dest->data.funcref = vim_strsave(src->data.funcref);
- func_ref(src->data.funcref);
- break;
- default:
- dest->data.funcref = NULL;
- break;
+ case kCallbackPartial:
+ dest->data.partial = src->data.partial;
+ dest->data.partial->pt_refcount++;
+ break;
+ case kCallbackFuncref:
+ dest->data.funcref = vim_strsave(src->data.funcref);
+ func_ref(src->data.funcref);
+ break;
+ default:
+ dest->data.funcref = NULL;
+ break;
}
}
@@ -1216,8 +1201,7 @@ void callback_copy(Callback *dest, Callback *src)
///
/// @return True on success, false if relevant watcher was not found.
bool tv_dict_watcher_remove(dict_T *const dict, const char *const key_pattern,
- const size_t key_pattern_len,
- Callback callback)
+ const size_t key_pattern_len, Callback callback)
FUNC_ATTR_NONNULL_ARG(2)
{
if (dict == NULL) {
@@ -1280,8 +1264,8 @@ static bool tv_dict_watcher_matches(DictWatcher *watcher, const char *const key)
/// @param[in] key Key which was modified.
/// @param[in] newtv New key value.
/// @param[in] oldtv Old key value.
-void tv_dict_watcher_notify(dict_T *const dict, const char *const key,
- typval_T *const newtv, typval_T *const oldtv)
+void tv_dict_watcher_notify(dict_T *const dict, const char *const key, typval_T *const newtv,
+ typval_T *const oldtv)
FUNC_ATTR_NONNULL_ARG(1, 2)
{
typval_T argv[3];
@@ -1540,8 +1524,7 @@ void tv_dict_unref(dict_T *const d)
/// @param[in] len Key length. If negative, then strlen(key) is used.
///
/// @return found item or NULL if nothing was found.
-dictitem_T *tv_dict_find(const dict_T *const d, const char *const key,
- const ptrdiff_t len)
+dictitem_T *tv_dict_find(const dict_T *const d, const char *const key, const ptrdiff_t len)
FUNC_ATTR_NONNULL_ARG(2) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
if (d == NULL) {
@@ -1628,8 +1611,7 @@ char **tv_dict_to_env(dict_T *denv)
/// @return NULL if key does not exist, empty string in case of type error,
/// string item value otherwise. If returned value is not NULL, it may
/// be allocated depending on `save` argument.
-char *tv_dict_get_string(const dict_T *const d, const char *const key,
- const bool save)
+char *tv_dict_get_string(const dict_T *const d, const char *const key, const bool save)
FUNC_ATTR_WARN_UNUSED_RESULT
{
static char numbuf[NUMBUFLEN];
@@ -1649,8 +1631,7 @@ char *tv_dict_get_string(const dict_T *const d, const char *const key,
///
/// @return NULL if key does not exist, empty string in case of type error,
/// string item value otherwise.
-const char *tv_dict_get_string_buf(const dict_T *const d, const char *const key,
- char *const numbuf)
+const char *tv_dict_get_string_buf(const dict_T *const d, const char *const key, char *const numbuf)
FUNC_ATTR_WARN_UNUSED_RESULT
{
const dictitem_T *const di = tv_dict_find(d, key, -1);
@@ -1672,10 +1653,8 @@ const char *tv_dict_get_string_buf(const dict_T *const d, const char *const key,
/// @return `def` when key does not exist,
/// NULL in case of type error,
/// string item value in case of success.
-const char *tv_dict_get_string_buf_chk(const dict_T *const d,
- const char *const key,
- const ptrdiff_t key_len,
- char *const numbuf,
+const char *tv_dict_get_string_buf_chk(const dict_T *const d, const char *const key,
+ const ptrdiff_t key_len, char *const numbuf,
const char *const def)
FUNC_ATTR_WARN_UNUSED_RESULT
{
@@ -1695,8 +1674,7 @@ const char *tv_dict_get_string_buf_chk(const dict_T *const d,
/// will be left.
///
/// @return true/false on success/failure.
-bool tv_dict_get_callback(dict_T *const d,
- const char *const key, const ptrdiff_t key_len,
+bool tv_dict_get_callback(dict_T *const d, const char *const key, const ptrdiff_t key_len,
Callback *const result)
FUNC_ATTR_NONNULL_ARG(2, 4) FUNC_ATTR_WARN_UNUSED_RESULT
{
@@ -1743,8 +1721,8 @@ int tv_dict_add(dict_T *const d, dictitem_T *const item)
/// @param list List to add. Will have reference count incremented.
///
/// @return OK in case of success, FAIL when key already exists.
-int tv_dict_add_list(dict_T *const d, const char *const key,
- const size_t key_len, list_T *const list)
+int tv_dict_add_list(dict_T *const d, const char *const key, const size_t key_len,
+ list_T *const list)
FUNC_ATTR_NONNULL_ALL
{
dictitem_T *const item = tv_dict_item_alloc_len(key, key_len);
@@ -1766,15 +1744,14 @@ int tv_dict_add_list(dict_T *const d, const char *const key,
/// @param[in] key_len Key length.
///
/// @return FAIL if out of memory or key already exists.
-int tv_dict_add_tv(dict_T *d, const char *key, const size_t key_len,
- typval_T *tv)
+int tv_dict_add_tv(dict_T *d, const char *key, const size_t key_len, typval_T *tv)
{
dictitem_T *const item = tv_dict_item_alloc_len(key, key_len);
tv_copy(tv, &item->di_tv);
if (tv_dict_add(d, item) == FAIL) {
- tv_dict_item_free(item);
- return FAIL;
+ tv_dict_item_free(item);
+ return FAIL;
}
return OK;
}
@@ -1787,8 +1764,8 @@ int tv_dict_add_tv(dict_T *d, const char *key, const size_t key_len,
/// @param dict Dictionary to add. Will have reference count incremented.
///
/// @return OK in case of success, FAIL when key already exists.
-int tv_dict_add_dict(dict_T *const d, const char *const key,
- const size_t key_len, dict_T *const dict)
+int tv_dict_add_dict(dict_T *const d, const char *const key, const size_t key_len,
+ dict_T *const dict)
FUNC_ATTR_NONNULL_ALL
{
dictitem_T *const item = tv_dict_item_alloc_len(key, key_len);
@@ -1811,8 +1788,8 @@ int tv_dict_add_dict(dict_T *const d, const char *const key,
/// @param[in] nr Number to add.
///
/// @return OK in case of success, FAIL when key already exists.
-int tv_dict_add_nr(dict_T *const d, const char *const key,
- const size_t key_len, const varnumber_T nr)
+int tv_dict_add_nr(dict_T *const d, const char *const key, const size_t key_len,
+ const varnumber_T nr)
{
dictitem_T *const item = tv_dict_item_alloc_len(key, key_len);
@@ -1833,8 +1810,8 @@ int tv_dict_add_nr(dict_T *const d, const char *const key,
/// @param[in] nr Floating point number to add.
///
/// @return OK in case of success, FAIL when key already exists.
-int tv_dict_add_float(dict_T *const d, const char *const key,
- const size_t key_len, const float_T nr)
+int tv_dict_add_float(dict_T *const d, const char *const key, const size_t key_len,
+ const float_T nr)
{
dictitem_T *const item = tv_dict_item_alloc_len(key, key_len);
@@ -1855,8 +1832,7 @@ int tv_dict_add_float(dict_T *const d, const char *const key,
/// @param[in] val BoolVarValue to add.
///
/// @return OK in case of success, FAIL when key already exists.
-int tv_dict_add_bool(dict_T *const d, const char *const key,
- const size_t key_len, BoolVarValue val)
+int tv_dict_add_bool(dict_T *const d, const char *const key, const size_t key_len, BoolVarValue val)
{
dictitem_T *const item = tv_dict_item_alloc_len(key, key_len);
@@ -1872,8 +1848,7 @@ int tv_dict_add_bool(dict_T *const d, const char *const key,
/// Add a string entry to dictionary
///
/// @see tv_dict_add_allocated_str
-int tv_dict_add_str(dict_T *const d,
- const char *const key, const size_t key_len,
+int tv_dict_add_str(dict_T *const d, const char *const key, const size_t key_len,
const char *const val)
FUNC_ATTR_NONNULL_ARG(1, 2)
{
@@ -1889,8 +1864,7 @@ int tv_dict_add_str(dict_T *const d,
/// @param[in] len Use this many bytes from `val`, or -1 for whole string.
///
/// @return OK in case of success, FAIL when key already exists.
-int tv_dict_add_str_len(dict_T *const d,
- const char *const key, const size_t key_len,
+int tv_dict_add_str_len(dict_T *const d, const char *const key, const size_t key_len,
const char *const val, int len)
FUNC_ATTR_NONNULL_ARG(1, 2)
{
@@ -1914,8 +1888,7 @@ int tv_dict_add_str_len(dict_T *const d,
/// @param[in] val String to add.
///
/// @return OK in case of success, FAIL when key already exists.
-int tv_dict_add_allocated_str(dict_T *const d,
- const char *const key, const size_t key_len,
+int tv_dict_add_allocated_str(dict_T *const d, const char *const key, const size_t key_len,
char *const val)
FUNC_ATTR_NONNULL_ARG(1, 2)
{
@@ -1958,8 +1931,7 @@ void tv_dict_clear(dict_T *const d)
/// e*, including "error": duplicate key gives an error.
/// f*, including "force": duplicate d2 keys override d1.
/// other, including "keep": duplicate d2 keys ignored.
-void tv_dict_extend(dict_T *const d1, dict_T *const d2,
- const char *const action)
+void tv_dict_extend(dict_T *const d1, dict_T *const d2, const char *const action)
FUNC_ATTR_NONNULL_ALL
{
const bool watched = tv_dict_is_watched(d1);
@@ -2021,8 +1993,7 @@ void tv_dict_extend(dict_T *const d1, dict_T *const d2,
/// @param[in] d2 Second dictionary.
/// @param[in] ic True if case is to be ignored.
/// @param[in] recursive True when used recursively.
-bool tv_dict_equal(dict_T *const d1, dict_T *const d2,
- const bool ic, const bool recursive)
+bool tv_dict_equal(dict_T *const d1, dict_T *const d2, const bool ic, const bool recursive)
FUNC_ATTR_WARN_UNUSED_RESULT
{
if (d1 == d2) {
@@ -2057,9 +2028,7 @@ bool tv_dict_equal(dict_T *const d1, dict_T *const d2,
/// @return Copied dictionary. May be NULL in case original dictionary is NULL
/// or some failure happens. The refcount of the new dictionary is set
/// to 1.
-dict_T *tv_dict_copy(const vimconv_T *const conv,
- dict_T *const orig,
- const bool deep,
+dict_T *tv_dict_copy(const vimconv_T *const conv, dict_T *const orig, const bool deep,
const int copyID)
{
if (orig == NULL) {
@@ -2125,6 +2094,77 @@ void tv_dict_set_keys_readonly(dict_T *const dict)
});
}
+//{{{1 Blobs
+//{{{2 Alloc/free
+
+/// Allocate an empty blob.
+///
+/// Caller should take care of the reference count.
+///
+/// @return [allocated] new blob.
+blob_T *tv_blob_alloc(void)
+ FUNC_ATTR_NONNULL_RET
+{
+ blob_T *const blob = xcalloc(1, sizeof(blob_T));
+ ga_init(&blob->bv_ga, 1, 100);
+ return blob;
+}
+
+/// Free a blob. Ignores the reference count.
+///
+/// @param[in,out] b Blob to free.
+void tv_blob_free(blob_T *const b)
+ FUNC_ATTR_NONNULL_ALL
+{
+ ga_clear(&b->bv_ga);
+ xfree(b);
+}
+
+/// Unreference a blob.
+///
+/// Decrements the reference count and frees blob when it becomes zero.
+///
+/// @param[in,out] b Blob to operate on.
+void tv_blob_unref(blob_T *const b)
+{
+ if (b != NULL && --b->bv_refcount <= 0) {
+ tv_blob_free(b);
+ }
+}
+
+//{{{2 Operations on the whole blob
+
+/// Check whether two blobs are equal.
+///
+/// @param[in] b1 First blob.
+/// @param[in] b2 Second blob.
+///
+/// @return true if blobs are equal, false otherwise.
+bool tv_blob_equal(const blob_T *const b1, const blob_T *const b2)
+ FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ const int len1 = tv_blob_len(b1);
+ const int len2 = tv_blob_len(b2);
+
+ // empty and NULL are considered the same
+ if (len1 == 0 && len2 == 0) {
+ return true;
+ }
+ if (b1 == b2) {
+ return true;
+ }
+ if (len1 != len2) {
+ return false;
+ }
+
+ for (int i = 0; i < b1->bv_ga.ga_len; i++) {
+ if (tv_blob_get(b1, i) != tv_blob_get(b2, i)) {
+ return false;
+ }
+ }
+ return true;
+}
+
//{{{1 Generic typval operations
//{{{2 Init/alloc/clear
//{{{3 Alloc
@@ -2169,49 +2209,93 @@ void tv_dict_alloc_ret(typval_T *const ret_tv)
tv_dict_set_ret(ret_tv, d);
}
+/// Allocate an empty blob for a return value.
+///
+/// Also sets reference count.
+///
+/// @param[out] ret_tv Structure where blob is saved.
+void tv_blob_alloc_ret(typval_T *const ret_tv)
+ FUNC_ATTR_NONNULL_ALL
+{
+ blob_T *const b = tv_blob_alloc();
+ tv_blob_set_ret(ret_tv, b);
+}
+
+/// Copy a blob typval to a different typval.
+///
+/// @param[in] from Blob object to copy from.
+/// @param[out] to Blob object to copy to.
+void tv_blob_copy(typval_T *const from, typval_T *const to)
+ FUNC_ATTR_NONNULL_ALL
+{
+ assert(from->v_type == VAR_BLOB);
+
+ to->v_type = VAR_BLOB;
+ to->v_lock = VAR_UNLOCKED;
+ if (from->vval.v_blob == NULL) {
+ to->vval.v_blob = NULL;
+ } else {
+ tv_blob_alloc_ret(to);
+ int len = from->vval.v_blob->bv_ga.ga_len;
+
+ if (len > 0) {
+ to->vval.v_blob->bv_ga.ga_data
+ = xmemdup(from->vval.v_blob->bv_ga.ga_data, (size_t)len);
+ }
+ to->vval.v_blob->bv_ga.ga_len = len;
+ to->vval.v_blob->bv_ga.ga_maxlen = len;
+ }
+}
+
//{{{3 Clear
#define TYPVAL_ENCODE_ALLOW_SPECIALS false
#define TYPVAL_ENCODE_CONV_NIL(tv) \
- do { \
- tv->vval.v_special = kSpecialVarNull; \
- tv->v_lock = VAR_UNLOCKED; \
- } while (0)
+ do { \
+ tv->vval.v_special = kSpecialVarNull; \
+ tv->v_lock = VAR_UNLOCKED; \
+ } while (0)
#define TYPVAL_ENCODE_CONV_BOOL(tv, num) \
- do { \
- tv->vval.v_bool = kBoolVarFalse; \
- tv->v_lock = VAR_UNLOCKED; \
- } while (0)
+ do { \
+ tv->vval.v_bool = kBoolVarFalse; \
+ tv->v_lock = VAR_UNLOCKED; \
+ } while (0)
#define TYPVAL_ENCODE_CONV_NUMBER(tv, num) \
- do { \
- (void)num; \
- tv->vval.v_number = 0; \
- tv->v_lock = VAR_UNLOCKED; \
- } while (0)
+ do { \
+ (void)num; \
+ tv->vval.v_number = 0; \
+ tv->v_lock = VAR_UNLOCKED; \
+ } while (0)
#define TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(tv, num)
#define TYPVAL_ENCODE_CONV_FLOAT(tv, flt) \
- do { \
- tv->vval.v_float = 0; \
- tv->v_lock = VAR_UNLOCKED; \
- } while (0)
+ do { \
+ tv->vval.v_float = 0; \
+ tv->v_lock = VAR_UNLOCKED; \
+ } while (0)
#define TYPVAL_ENCODE_CONV_STRING(tv, buf, len) \
- do { \
- xfree(buf); \
- tv->vval.v_string = NULL; \
- tv->v_lock = VAR_UNLOCKED; \
- } while (0)
+ do { \
+ xfree(buf); \
+ tv->vval.v_string = NULL; \
+ tv->v_lock = VAR_UNLOCKED; \
+ } while (0)
#define TYPVAL_ENCODE_CONV_STR_STRING(tv, buf, len)
#define TYPVAL_ENCODE_CONV_EXT_STRING(tv, buf, len, type)
-static inline int _nothing_conv_func_start(typval_T *const tv,
- char_u *const fun)
+#define TYPVAL_ENCODE_CONV_BLOB(tv, blob, len) \
+ do { \
+ tv_blob_unref(tv->vval.v_blob); \
+ tv->vval.v_blob = NULL; \
+ tv->v_lock = VAR_UNLOCKED; \
+ } while (0)
+
+static inline int _nothing_conv_func_start(typval_T *const tv, char_u *const fun)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ARG(1)
{
tv->v_lock = VAR_UNLOCKED;
@@ -2232,11 +2316,11 @@ static inline int _nothing_conv_func_start(typval_T *const tv,
return NOTDONE;
}
#define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun) \
- do { \
- if (_nothing_conv_func_start(tv, fun) != NOTDONE) { \
- return OK; \
- } \
- } while (0)
+ do { \
+ if (_nothing_conv_func_start(tv, fun) != NOTDONE) { \
+ return OK; \
+ } \
+ } while (0)
#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, len)
#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, len)
@@ -2264,14 +2348,13 @@ static inline void _nothing_conv_func_end(typval_T *const tv, const int copyID)
#define TYPVAL_ENCODE_CONV_FUNC_END(tv) _nothing_conv_func_end(tv, copyID)
#define TYPVAL_ENCODE_CONV_EMPTY_LIST(tv) \
- do { \
- tv_list_unref(tv->vval.v_list); \
- tv->vval.v_list = NULL; \
- tv->v_lock = VAR_UNLOCKED; \
- } while (0)
-
-static inline void _nothing_conv_empty_dict(typval_T *const tv,
- dict_T **const dictp)
+ do { \
+ tv_list_unref(tv->vval.v_list); \
+ tv->vval.v_list = NULL; \
+ tv->v_lock = VAR_UNLOCKED; \
+ } while (0)
+
+static inline void _nothing_conv_empty_dict(typval_T *const tv, dict_T **const dictp)
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ARG(2)
{
tv_dict_unref(*dictp);
@@ -2281,13 +2364,13 @@ static inline void _nothing_conv_empty_dict(typval_T *const tv,
}
}
#define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, dict) \
- do { \
- assert((void *)&dict != (void *)&TYPVAL_ENCODE_NODICT_VAR); \
- _nothing_conv_empty_dict(tv, ((dict_T **)&dict)); \
- } while (0)
+ do { \
+ assert((void *)&dict != (void *)&TYPVAL_ENCODE_NODICT_VAR); \
+ _nothing_conv_empty_dict(tv, ((dict_T **)&dict)); \
+ } while (0)
-static inline int _nothing_conv_real_list_after_start(
- typval_T *const tv, MPConvStackVal *const mpsv)
+static inline int _nothing_conv_real_list_after_start(typval_T *const tv,
+ MPConvStackVal *const mpsv)
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_WARN_UNUSED_RESULT
{
assert(tv != NULL);
@@ -2303,11 +2386,11 @@ static inline int _nothing_conv_real_list_after_start(
#define TYPVAL_ENCODE_CONV_LIST_START(tv, len)
#define TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START(tv, mpsv) \
- do { \
- if (_nothing_conv_real_list_after_start(tv, &mpsv) != NOTDONE) { \
- goto typval_encode_stop_converting_one_item; \
- } \
- } while (0)
+ do { \
+ if (_nothing_conv_real_list_after_start(tv, &mpsv) != NOTDONE) { \
+ goto typval_encode_stop_converting_one_item; \
+ } \
+ } while (0)
#define TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(tv)
@@ -2324,9 +2407,9 @@ static inline void _nothing_conv_list_end(typval_T *const tv)
}
#define TYPVAL_ENCODE_CONV_LIST_END(tv) _nothing_conv_list_end(tv)
-static inline int _nothing_conv_real_dict_after_start(
- typval_T *const tv, dict_T **const dictp, const void *const nodictvar,
- MPConvStackVal *const mpsv)
+static inline int _nothing_conv_real_dict_after_start(typval_T *const tv, dict_T **const dictp,
+ const void *const nodictvar,
+ MPConvStackVal *const mpsv)
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_WARN_UNUSED_RESULT
{
if (tv != NULL) {
@@ -2343,20 +2426,18 @@ static inline int _nothing_conv_real_dict_after_start(
#define TYPVAL_ENCODE_CONV_DICT_START(tv, dict, len)
#define TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START(tv, dict, mpsv) \
- do { \
- if (_nothing_conv_real_dict_after_start( \
- tv, (dict_T **)&dict, (void *)&TYPVAL_ENCODE_NODICT_VAR, \
- &mpsv) != NOTDONE) { \
- goto typval_encode_stop_converting_one_item; \
- } \
- } while (0)
+ do { \
+ if (_nothing_conv_real_dict_after_start(tv, (dict_T **)&dict, (void *)&TYPVAL_ENCODE_NODICT_VAR, \
+ &mpsv) != NOTDONE) { \
+ goto typval_encode_stop_converting_one_item; \
+ } \
+ } while (0)
#define TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK(tv, dict)
#define TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(tv, dict)
#define TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(tv, dict)
-static inline void _nothing_conv_dict_end(typval_T *const tv,
- dict_T **const dictp,
+static inline void _nothing_conv_dict_end(typval_T *const tv, dict_T **const dictp,
const void *const nodictvar)
FUNC_ATTR_ALWAYS_INLINE
{
@@ -2366,8 +2447,8 @@ static inline void _nothing_conv_dict_end(typval_T *const tv,
}
}
#define TYPVAL_ENCODE_CONV_DICT_END(tv, dict) \
- _nothing_conv_dict_end(tv, (dict_T **)&dict, \
- (void *)&TYPVAL_ENCODE_NODICT_VAR)
+ _nothing_conv_dict_end(tv, (dict_T **)&dict, \
+ (void *)&TYPVAL_ENCODE_NODICT_VAR)
#define TYPVAL_ENCODE_CONV_RECURSE(val, conv_type)
@@ -2392,6 +2473,7 @@ static inline void _nothing_conv_dict_end(typval_T *const tv,
#undef TYPVAL_ENCODE_CONV_STRING
#undef TYPVAL_ENCODE_CONV_STR_STRING
#undef TYPVAL_ENCODE_CONV_EXT_STRING
+#undef TYPVAL_ENCODE_CONV_BLOB
#undef TYPVAL_ENCODE_CONV_FUNC_START
#undef TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS
#undef TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF
@@ -2437,33 +2519,30 @@ void tv_free(typval_T *tv)
{
if (tv != NULL) {
switch (tv->v_type) {
- case VAR_PARTIAL: {
- partial_unref(tv->vval.v_partial);
- break;
- }
- case VAR_FUNC: {
- func_unref(tv->vval.v_string);
- FALLTHROUGH;
- }
- case VAR_STRING: {
- xfree(tv->vval.v_string);
- break;
- }
- case VAR_LIST: {
- tv_list_unref(tv->vval.v_list);
- break;
- }
- case VAR_DICT: {
- tv_dict_unref(tv->vval.v_dict);
- break;
- }
- case VAR_BOOL:
- case VAR_SPECIAL:
- case VAR_NUMBER:
- case VAR_FLOAT:
- case VAR_UNKNOWN: {
- break;
- }
+ case VAR_PARTIAL:
+ partial_unref(tv->vval.v_partial);
+ break;
+ case VAR_FUNC:
+ func_unref(tv->vval.v_string);
+ FALLTHROUGH;
+ case VAR_STRING:
+ xfree(tv->vval.v_string);
+ break;
+ case VAR_BLOB:
+ tv_blob_unref(tv->vval.v_blob);
+ break;
+ case VAR_LIST:
+ tv_list_unref(tv->vval.v_list);
+ break;
+ case VAR_DICT:
+ tv_dict_unref(tv->vval.v_dict);
+ break;
+ case VAR_BOOL:
+ case VAR_SPECIAL:
+ case VAR_NUMBER:
+ case VAR_FLOAT:
+ case VAR_UNKNOWN:
+ break;
}
xfree(tv);
}
@@ -2487,42 +2566,41 @@ void tv_copy(const typval_T *const from, typval_T *const to)
to->v_lock = VAR_UNLOCKED;
memmove(&to->vval, &from->vval, sizeof(to->vval));
switch (from->v_type) {
- case VAR_NUMBER:
- case VAR_FLOAT:
- case VAR_BOOL:
- case VAR_SPECIAL: {
- break;
- }
- case VAR_STRING:
- case VAR_FUNC: {
- if (from->vval.v_string != NULL) {
- to->vval.v_string = vim_strsave(from->vval.v_string);
- if (from->v_type == VAR_FUNC) {
- func_ref(to->vval.v_string);
- }
- }
- break;
- }
- case VAR_PARTIAL: {
- if (to->vval.v_partial != NULL) {
- to->vval.v_partial->pt_refcount++;
+ case VAR_NUMBER:
+ case VAR_FLOAT:
+ case VAR_BOOL:
+ case VAR_SPECIAL:
+ break;
+ case VAR_STRING:
+ case VAR_FUNC:
+ if (from->vval.v_string != NULL) {
+ to->vval.v_string = vim_strsave(from->vval.v_string);
+ if (from->v_type == VAR_FUNC) {
+ func_ref(to->vval.v_string);
}
- break;
}
- case VAR_LIST: {
- tv_list_ref(to->vval.v_list);
- break;
+ break;
+ case VAR_PARTIAL:
+ if (to->vval.v_partial != NULL) {
+ to->vval.v_partial->pt_refcount++;
}
- case VAR_DICT: {
- if (from->vval.v_dict != NULL) {
- to->vval.v_dict->dv_refcount++;
- }
- break;
+ break;
+ case VAR_BLOB:
+ if (from->vval.v_blob != NULL) {
+ to->vval.v_blob->bv_refcount++;
}
- case VAR_UNKNOWN: {
- emsgf(_(e_intern2), "tv_copy(UNKNOWN)");
- break;
+ break;
+ case VAR_LIST:
+ tv_list_ref(to->vval.v_list);
+ break;
+ case VAR_DICT:
+ if (from->vval.v_dict != NULL) {
+ to->vval.v_dict->dv_refcount++;
}
+ break;
+ case VAR_UNKNOWN:
+ emsgf(_(e_intern2), "tv_copy(UNKNOWN)");
+ break;
}
}
@@ -2533,7 +2611,9 @@ void tv_copy(const typval_T *const from, typval_T *const to)
/// @param[out] tv Item to (un)lock.
/// @param[in] deep Levels to (un)lock, -1 to (un)lock everything.
/// @param[in] lock True if it is needed to lock an item, false to unlock.
-void tv_item_lock(typval_T *const tv, const int deep, const bool lock)
+/// @param[in] check_refcount If true, do not lock a list or dict with a
+/// reference count larger than 1.
+void tv_item_lock(typval_T *const tv, const int deep, const bool lock, const bool check_refcount)
FUNC_ATTR_NONNULL_ALL
{
// TODO(ZyX-I): Make this not recursive
@@ -2560,44 +2640,49 @@ void tv_item_lock(typval_T *const tv, const int deep, const bool lock)
CHANGE_LOCK(lock, tv->v_lock);
switch (tv->v_type) {
- case VAR_LIST: {
- list_T *const l = tv->vval.v_list;
- if (l != NULL) {
- CHANGE_LOCK(lock, l->lv_lock);
- if (deep < 0 || deep > 1) {
- // Recursive: lock/unlock the items the List contains.
- TV_LIST_ITER(l, li, {
- tv_item_lock(TV_LIST_ITEM_TV(li), deep - 1, lock);
+ case VAR_BLOB: {
+ blob_T *const b = tv->vval.v_blob;
+ if (b != NULL && !(check_refcount && b->bv_refcount > 1)) {
+ CHANGE_LOCK(lock, b->bv_lock);
+ }
+ break;
+ }
+ case VAR_LIST: {
+ list_T *const l = tv->vval.v_list;
+ if (l != NULL && !(check_refcount && l->lv_refcount > 1)) {
+ CHANGE_LOCK(lock, l->lv_lock);
+ if (deep < 0 || deep > 1) {
+ // Recursive: lock/unlock the items the List contains.
+ TV_LIST_ITER(l, li, {
+ tv_item_lock(TV_LIST_ITEM_TV(li), deep - 1, lock, check_refcount);
});
- }
}
- break;
}
- case VAR_DICT: {
- dict_T *const d = tv->vval.v_dict;
- if (d != NULL) {
- CHANGE_LOCK(lock, d->dv_lock);
- if (deep < 0 || deep > 1) {
- // recursive: lock/unlock the items the List contains
- TV_DICT_ITER(d, di, {
- tv_item_lock(&di->di_tv, deep - 1, lock);
+ break;
+ }
+ case VAR_DICT: {
+ dict_T *const d = tv->vval.v_dict;
+ if (d != NULL && !(check_refcount && d->dv_refcount > 1)) {
+ CHANGE_LOCK(lock, d->dv_lock);
+ if (deep < 0 || deep > 1) {
+ // recursive: lock/unlock the items the List contains
+ TV_DICT_ITER(d, di, {
+ tv_item_lock(&di->di_tv, deep - 1, lock, check_refcount);
});
- }
}
- break;
- }
- case VAR_NUMBER:
- case VAR_FLOAT:
- case VAR_STRING:
- case VAR_FUNC:
- case VAR_PARTIAL:
- case VAR_BOOL:
- case VAR_SPECIAL: {
- break;
- }
- case VAR_UNKNOWN: {
- abort();
}
+ break;
+ }
+ case VAR_NUMBER:
+ case VAR_FLOAT:
+ case VAR_STRING:
+ case VAR_FUNC:
+ case VAR_PARTIAL:
+ case VAR_BOOL:
+ case VAR_SPECIAL:
+ break;
+ case VAR_UNKNOWN:
+ abort();
}
#undef CHANGE_LOCK
recurse--;
@@ -2639,32 +2724,32 @@ bool tv_islocked(const typval_T *const tv)
/// gettext.
///
/// @return true if variable is locked, false otherwise.
-bool tv_check_lock(const typval_T *tv, const char *name,
- size_t name_len)
+bool tv_check_lock(const typval_T *tv, const char *name, size_t name_len)
FUNC_ATTR_WARN_UNUSED_RESULT
{
VarLockStatus lock = VAR_UNLOCKED;
switch (tv->v_type) {
- // case VAR_BLOB:
- // if (tv->vval.v_blob != NULL)
- // lock = tv->vval.v_blob->bv_lock;
- // break;
- case VAR_LIST:
- if (tv->vval.v_list != NULL) {
- lock = tv->vval.v_list->lv_lock;
- }
- break;
- case VAR_DICT:
- if (tv->vval.v_dict != NULL) {
- lock = tv->vval.v_dict->dv_lock;
- }
- break;
- default:
- break;
+ case VAR_BLOB:
+ if (tv->vval.v_blob != NULL) {
+ lock = tv->vval.v_blob->bv_lock;
+ }
+ break;
+ case VAR_LIST:
+ if (tv->vval.v_list != NULL) {
+ lock = tv->vval.v_list->lv_lock;
+ }
+ break;
+ case VAR_DICT:
+ if (tv->vval.v_dict != NULL) {
+ lock = tv->vval.v_dict->dv_lock;
+ }
+ break;
+ default:
+ break;
}
return var_check_lock(tv->v_lock, name, name_len)
- || (lock != VAR_UNLOCKED && var_check_lock(lock, name, name_len));
+ || (lock != VAR_UNLOCKED && var_check_lock(lock, name, name_len));
}
/// @return true if variable "name" is locked (immutable)
@@ -2672,17 +2757,14 @@ bool var_check_lock(VarLockStatus lock, const char *name, size_t name_len)
{
const char *error_message = NULL;
switch (lock) {
- case VAR_UNLOCKED: {
- return false;
- }
- case VAR_LOCKED: {
- error_message = N_("E741: Value is locked: %.*s");
- break;
- }
- case VAR_FIXED: {
- error_message = N_("E742: Cannot change value of %.*s");
- break;
- }
+ case VAR_UNLOCKED:
+ return false;
+ case VAR_LOCKED:
+ error_message = N_("E741: Value is locked: %.*s");
+ break;
+ case VAR_FIXED:
+ error_message = N_("E742: Cannot change value of %.*s");
+ break;
}
assert(error_message != NULL);
@@ -2718,8 +2800,7 @@ static int tv_equal_recurse_limit;
/// @param[in] recursive True when used recursively.
///
/// @return true if values are equal.
-bool tv_equal(typval_T *const tv1, typval_T *const tv2, const bool ic,
- const bool recursive)
+bool tv_equal(typval_T *const tv1, typval_T *const tv2, const bool ic, const bool recursive)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
// TODO(ZyX-I): Make this not recursive
@@ -2744,55 +2825,52 @@ bool tv_equal(typval_T *const tv1, typval_T *const tv2, const bool ic,
}
switch (tv1->v_type) {
- case VAR_LIST: {
- recursive_cnt++;
- const bool r = tv_list_equal(tv1->vval.v_list, tv2->vval.v_list, ic,
- true);
- recursive_cnt--;
- return r;
- }
- case VAR_DICT: {
- recursive_cnt++;
- const bool r = tv_dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic,
- true);
- recursive_cnt--;
- return r;
- }
- case VAR_PARTIAL:
- case VAR_FUNC: {
- if ((tv1->v_type == VAR_PARTIAL && tv1->vval.v_partial == NULL)
- || (tv2->v_type == VAR_PARTIAL && tv2->vval.v_partial == NULL)) {
- return false;
- }
- recursive_cnt++;
- const bool r = func_equal(tv1, tv2, ic);
- recursive_cnt--;
- return r;
- }
- case VAR_NUMBER: {
- return tv1->vval.v_number == tv2->vval.v_number;
- }
- case VAR_FLOAT: {
- return tv1->vval.v_float == tv2->vval.v_float;
- }
- case VAR_STRING: {
- char buf1[NUMBUFLEN];
- char buf2[NUMBUFLEN];
- const char *s1 = tv_get_string_buf(tv1, buf1);
- const char *s2 = tv_get_string_buf(tv2, buf2);
- return mb_strcmp_ic((bool)ic, s1, s2) == 0;
- }
- case VAR_BOOL: {
- return tv1->vval.v_bool == tv2->vval.v_bool;
- }
- case VAR_SPECIAL: {
- return tv1->vval.v_special == tv2->vval.v_special;
- }
- case VAR_UNKNOWN: {
- // VAR_UNKNOWN can be the result of an invalid expression, let’s say it
- // does not equal anything, not even self.
+ case VAR_LIST: {
+ recursive_cnt++;
+ const bool r = tv_list_equal(tv1->vval.v_list, tv2->vval.v_list, ic,
+ true);
+ recursive_cnt--;
+ return r;
+ }
+ case VAR_DICT: {
+ recursive_cnt++;
+ const bool r = tv_dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic,
+ true);
+ recursive_cnt--;
+ return r;
+ }
+ case VAR_PARTIAL:
+ case VAR_FUNC: {
+ if ((tv1->v_type == VAR_PARTIAL && tv1->vval.v_partial == NULL)
+ || (tv2->v_type == VAR_PARTIAL && tv2->vval.v_partial == NULL)) {
return false;
}
+ recursive_cnt++;
+ const bool r = func_equal(tv1, tv2, ic);
+ recursive_cnt--;
+ return r;
+ }
+ case VAR_BLOB:
+ return tv_blob_equal(tv1->vval.v_blob, tv2->vval.v_blob);
+ case VAR_NUMBER:
+ return tv1->vval.v_number == tv2->vval.v_number;
+ case VAR_FLOAT:
+ return tv1->vval.v_float == tv2->vval.v_float;
+ case VAR_STRING: {
+ char buf1[NUMBUFLEN];
+ char buf2[NUMBUFLEN];
+ const char *s1 = tv_get_string_buf(tv1, buf1);
+ const char *s2 = tv_get_string_buf(tv2, buf2);
+ return mb_strcmp_ic((bool)ic, s1, s2) == 0;
+ }
+ case VAR_BOOL:
+ return tv1->vval.v_bool == tv2->vval.v_bool;
+ case VAR_SPECIAL:
+ return tv1->vval.v_special == tv2->vval.v_special;
+ case VAR_UNKNOWN:
+ // VAR_UNKNOWN can be the result of an invalid expression, let’s say it
+ // does not equal anything, not even self.
+ return false;
}
abort();
@@ -2814,39 +2892,34 @@ bool tv_check_str_or_nr(const typval_T *const tv)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
switch (tv->v_type) {
- case VAR_NUMBER:
- case VAR_STRING: {
- return true;
- }
- case VAR_FLOAT: {
- EMSG(_("E805: Expected a Number or a String, Float found"));
- return false;
- }
- case VAR_PARTIAL:
- case VAR_FUNC: {
- EMSG(_("E703: Expected a Number or a String, Funcref found"));
- return false;
- }
- case VAR_LIST: {
- EMSG(_("E745: Expected a Number or a String, List found"));
- return false;
- }
- case VAR_DICT: {
- EMSG(_("E728: Expected a Number or a String, Dictionary found"));
- return false;
- }
- case VAR_BOOL: {
- EMSG(_("E5299: Expected a Number or a String, Boolean found"));
- return false;
- }
- case VAR_SPECIAL: {
- EMSG(_("E5300: Expected a Number or a String"));
- return false;
- }
- case VAR_UNKNOWN: {
- EMSG2(_(e_intern2), "tv_check_str_or_nr(UNKNOWN)");
- return false;
- }
+ case VAR_NUMBER:
+ case VAR_STRING:
+ return true;
+ case VAR_FLOAT:
+ EMSG(_("E805: Expected a Number or a String, Float found"));
+ return false;
+ case VAR_PARTIAL:
+ case VAR_FUNC:
+ EMSG(_("E703: Expected a Number or a String, Funcref found"));
+ return false;
+ case VAR_LIST:
+ EMSG(_("E745: Expected a Number or a String, List found"));
+ return false;
+ case VAR_DICT:
+ EMSG(_("E728: Expected a Number or a String, Dictionary found"));
+ return false;
+ case VAR_BLOB:
+ EMSG(_("E974: Expected a Number or a String, Blob found"));
+ return false;
+ case VAR_BOOL:
+ EMSG(_("E5299: Expected a Number or a String, Boolean found"));
+ return false;
+ case VAR_SPECIAL:
+ EMSG(_("E5300: Expected a Number or a String"));
+ return false;
+ case VAR_UNKNOWN:
+ EMSG2(_(e_intern2), "tv_check_str_or_nr(UNKNOWN)");
+ return false;
}
abort();
return false;
@@ -2860,6 +2933,7 @@ static const char *const num_errors[] = {
[VAR_LIST]=N_("E745: Using a List as a Number"),
[VAR_DICT]=N_("E728: Using a Dictionary as a Number"),
[VAR_FLOAT]=N_("E805: Using a Float as a Number"),
+ [VAR_BLOB]=N_("E974: Using a Blob as a Number"),
[VAR_UNKNOWN]=N_("E685: using an invalid value as a Number"),
};
@@ -2877,21 +2951,20 @@ bool tv_check_num(const typval_T *const tv)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
switch (tv->v_type) {
- case VAR_NUMBER:
- case VAR_BOOL:
- case VAR_SPECIAL:
- case VAR_STRING: {
- return true;
- }
- case VAR_FUNC:
- case VAR_PARTIAL:
- case VAR_LIST:
- case VAR_DICT:
- case VAR_FLOAT:
- case VAR_UNKNOWN: {
- EMSG(_(num_errors[tv->v_type]));
- return false;
- }
+ case VAR_NUMBER:
+ case VAR_BOOL:
+ case VAR_SPECIAL:
+ case VAR_STRING:
+ return true;
+ case VAR_FUNC:
+ case VAR_PARTIAL:
+ case VAR_LIST:
+ case VAR_DICT:
+ case VAR_FLOAT:
+ case VAR_BLOB:
+ case VAR_UNKNOWN:
+ EMSG(_(num_errors[tv->v_type]));
+ return false;
}
abort();
return false;
@@ -2905,6 +2978,7 @@ static const char *const str_errors[] = {
[VAR_LIST]=N_("E730: using List as a String"),
[VAR_DICT]=N_("E731: using Dictionary as a String"),
[VAR_FLOAT]=((const char *)e_float_as_string),
+ [VAR_BLOB]=N_("E976: using Blob as a String"),
[VAR_UNKNOWN]=N_("E908: using an invalid value as a String"),
};
@@ -2922,21 +2996,20 @@ bool tv_check_str(const typval_T *const tv)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
switch (tv->v_type) {
- case VAR_NUMBER:
- case VAR_BOOL:
- case VAR_SPECIAL:
- case VAR_STRING: {
- return true;
- }
- case VAR_PARTIAL:
- case VAR_FUNC:
- case VAR_LIST:
- case VAR_DICT:
- case VAR_FLOAT:
- case VAR_UNKNOWN: {
- EMSG(_(str_errors[tv->v_type]));
- return false;
- }
+ case VAR_NUMBER:
+ case VAR_BOOL:
+ case VAR_SPECIAL:
+ case VAR_STRING:
+ return true;
+ case VAR_PARTIAL:
+ case VAR_FUNC:
+ case VAR_LIST:
+ case VAR_DICT:
+ case VAR_FLOAT:
+ case VAR_BLOB:
+ case VAR_UNKNOWN:
+ EMSG(_(str_errors[tv->v_type]));
+ return false;
}
abort();
return false;
@@ -2976,34 +3049,31 @@ varnumber_T tv_get_number_chk(const typval_T *const tv, bool *const ret_error)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ARG(1)
{
switch (tv->v_type) {
- case VAR_FUNC:
- case VAR_PARTIAL:
- case VAR_LIST:
- case VAR_DICT:
- case VAR_FLOAT: {
- EMSG(_(num_errors[tv->v_type]));
- break;
- }
- case VAR_NUMBER: {
- return tv->vval.v_number;
- }
- case VAR_STRING: {
- varnumber_T n = 0;
- if (tv->vval.v_string != NULL) {
- vim_str2nr(tv->vval.v_string, NULL, NULL, STR2NR_ALL, &n, NULL, 0);
- }
- return n;
- }
- case VAR_BOOL: {
- return tv->vval.v_bool == kBoolVarTrue ? 1 : 0;
- }
- case VAR_SPECIAL: {
- return 0;
- }
- case VAR_UNKNOWN: {
- emsgf(_(e_intern2), "tv_get_number(UNKNOWN)");
- break;
- }
+ case VAR_FUNC:
+ case VAR_PARTIAL:
+ case VAR_LIST:
+ case VAR_DICT:
+ case VAR_BLOB:
+ case VAR_FLOAT:
+ EMSG(_(num_errors[tv->v_type]));
+ break;
+ case VAR_NUMBER:
+ return tv->vval.v_number;
+ case VAR_STRING: {
+ varnumber_T n = 0;
+ if (tv->vval.v_string != NULL) {
+ vim_str2nr(tv->vval.v_string, NULL, NULL, STR2NR_ALL, &n, NULL, 0,
+ false);
+ }
+ return n;
+ }
+ case VAR_BOOL:
+ return tv->vval.v_bool == kBoolVarTrue ? 1 : 0;
+ case VAR_SPECIAL:
+ return 0;
+ case VAR_UNKNOWN:
+ emsgf(_(e_intern2), "tv_get_number(UNKNOWN)");
+ break;
}
if (ret_error != NULL) {
*ret_error = true;
@@ -3043,41 +3113,35 @@ float_T tv_get_float(const typval_T *const tv)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
switch (tv->v_type) {
- case VAR_NUMBER: {
- return (float_T)(tv->vval.v_number);
- }
- case VAR_FLOAT: {
- return tv->vval.v_float;
- }
- case VAR_PARTIAL:
- case VAR_FUNC: {
- EMSG(_("E891: Using a Funcref as a Float"));
- break;
- }
- case VAR_STRING: {
- EMSG(_("E892: Using a String as a Float"));
- break;
- }
- case VAR_LIST: {
- EMSG(_("E893: Using a List as a Float"));
- break;
- }
- case VAR_DICT: {
- EMSG(_("E894: Using a Dictionary as a Float"));
- break;
- }
- case VAR_BOOL: {
- EMSG(_("E362: Using a boolean value as a Float"));
- break;
- }
- case VAR_SPECIAL: {
- EMSG(_("E907: Using a special value as a Float"));
- break;
- }
- case VAR_UNKNOWN: {
- emsgf(_(e_intern2), "tv_get_float(UNKNOWN)");
- break;
- }
+ case VAR_NUMBER:
+ return (float_T)(tv->vval.v_number);
+ case VAR_FLOAT:
+ return tv->vval.v_float;
+ case VAR_PARTIAL:
+ case VAR_FUNC:
+ EMSG(_("E891: Using a Funcref as a Float"));
+ break;
+ case VAR_STRING:
+ EMSG(_("E892: Using a String as a Float"));
+ break;
+ case VAR_LIST:
+ EMSG(_("E893: Using a List as a Float"));
+ break;
+ case VAR_DICT:
+ EMSG(_("E894: Using a Dictionary as a Float"));
+ break;
+ case VAR_BOOL:
+ EMSG(_("E362: Using a boolean value as a Float"));
+ break;
+ case VAR_SPECIAL:
+ EMSG(_("E907: Using a special value as a Float"));
+ break;
+ case VAR_BLOB:
+ EMSG(_("E975: Using a Blob as a Float"));
+ break;
+ case VAR_UNKNOWN:
+ emsgf(_(e_intern2), "tv_get_float(UNKNOWN)");
+ break;
}
return 0;
}
@@ -3110,33 +3174,29 @@ const char *tv_get_string_buf_chk(const typval_T *const tv, char *const buf)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
switch (tv->v_type) {
- case VAR_NUMBER: {
- snprintf(buf, NUMBUFLEN, "%" PRIdVARNUMBER, tv->vval.v_number); // -V576
- return buf;
- }
- case VAR_STRING: {
- if (tv->vval.v_string != NULL) {
- return (const char *)tv->vval.v_string;
- }
- return "";
- }
- case VAR_BOOL: {
- STRCPY(buf, encode_bool_var_names[tv->vval.v_bool]);
- return buf;
- }
- case VAR_SPECIAL: {
- STRCPY(buf, encode_special_var_names[tv->vval.v_special]);
- return buf;
- }
- case VAR_PARTIAL:
- case VAR_FUNC:
- case VAR_LIST:
- case VAR_DICT:
- case VAR_FLOAT:
- case VAR_UNKNOWN: {
- EMSG(_(str_errors[tv->v_type]));
- return false;
- }
+ case VAR_NUMBER:
+ snprintf(buf, NUMBUFLEN, "%" PRIdVARNUMBER, tv->vval.v_number); // -V576
+ return buf;
+ case VAR_STRING:
+ if (tv->vval.v_string != NULL) {
+ return (const char *)tv->vval.v_string;
+ }
+ return "";
+ case VAR_BOOL:
+ STRCPY(buf, encode_bool_var_names[tv->vval.v_bool]);
+ return buf;
+ case VAR_SPECIAL:
+ STRCPY(buf, encode_special_var_names[tv->vval.v_special]);
+ return buf;
+ case VAR_PARTIAL:
+ case VAR_FUNC:
+ case VAR_LIST:
+ case VAR_DICT:
+ case VAR_FLOAT:
+ case VAR_BLOB:
+ case VAR_UNKNOWN:
+ EMSG(_(str_errors[tv->v_type]));
+ return false;
}
return NULL;
}
diff --git a/src/nvim/eval/typval.h b/src/nvim/eval/typval.h
index 050b84efec..5aecaccee9 100644
--- a/src/nvim/eval/typval.h
+++ b/src/nvim/eval/typval.h
@@ -55,7 +55,7 @@ enum ListLenSpecials {
#define VARNUMBER_MAX INT64_MAX
#define UVARNUMBER_MAX UINT64_MAX
-/// Mimimal possible value of varnumber_T variable
+/// Minimal possible value of varnumber_T variable
#define VARNUMBER_MIN INT64_MIN
/// %d printf format specifier for varnumber_T
@@ -64,6 +64,7 @@ enum ListLenSpecials {
typedef struct listvar_S list_T;
typedef struct dictvar_S dict_T;
typedef struct partial_S partial_T;
+typedef struct blobvar_S blob_T;
typedef struct ufunc ufunc_T;
@@ -123,6 +124,7 @@ typedef enum {
VAR_SPECIAL, ///< Special value (null), .v_special
///< is used.
VAR_PARTIAL, ///< Partial, .v_partial is used.
+ VAR_BLOB, ///< Blob, .v_blob is used.
} VarType;
/// Structure that holds an internal variable value
@@ -138,6 +140,7 @@ typedef struct {
list_T *v_list; ///< List for VAR_LIST, can be NULL.
dict_T *v_dict; ///< Dictionary for VAR_DICT, can be NULL.
partial_T *v_partial; ///< Closure: function with args.
+ blob_T *v_blob; ///< Blob for VAR_BLOB, can be NULL.
} vval; ///< Actual value.
} typval_T;
@@ -252,6 +255,13 @@ struct dictvar_S {
LuaRef lua_table_ref;
};
+/// Structure to hold info about a Blob
+struct blobvar_S {
+ garray_T bv_ga; ///< Growarray with the data.
+ int bv_refcount; ///< Reference count.
+ VarLockStatus bv_lock; ///< VAR_UNLOCKED, VAR_LOCKED, VAR_FIXED.
+};
+
/// Type used for script ID
typedef int scid_T;
/// Format argument for scid_T
@@ -322,7 +332,7 @@ struct ufunc {
int uf_prof_initialized;
// Managing cfuncs
cfunc_T uf_cb; ///< C function extension callback
- cfunc_free_T uf_cb_free; ///< C function extesion free callback
+ cfunc_free_T uf_cb_free; ///< C function extension free callback
void *uf_cb_state; ///< State of C function extension.
// Profiling the function as a whole.
int uf_tm_count; ///< nr of calls
@@ -711,6 +721,65 @@ static inline bool tv_dict_is_watched(const dict_T *const d)
return d && !QUEUE_EMPTY(&d->watchers);
}
+static inline void tv_blob_set_ret(typval_T *const tv, blob_T *const b)
+ REAL_FATTR_ALWAYS_INLINE REAL_FATTR_NONNULL_ARG(1);
+
+/// Set a blob as the return value.
+///
+/// Increments the reference count.
+///
+/// @param[out] tv Object to receive the blob.
+/// @param[in,out] b Blob to pass to the object.
+static inline void tv_blob_set_ret(typval_T *const tv, blob_T *const b)
+{
+ tv->v_type = VAR_BLOB;
+ tv->vval.v_blob = b;
+ if (b != NULL) {
+ b->bv_refcount++;
+ }
+}
+
+static inline int tv_blob_len(const blob_T *const b)
+ REAL_FATTR_PURE REAL_FATTR_WARN_UNUSED_RESULT;
+
+/// Get the length of the data in the blob, in bytes.
+///
+/// @param[in] b Blob to check.
+static inline int tv_blob_len(const blob_T *const b)
+{
+ if (b == NULL) {
+ return 0;
+ }
+ return b->bv_ga.ga_len;
+}
+
+static inline char_u tv_blob_get(const blob_T *const b, int idx)
+ REAL_FATTR_ALWAYS_INLINE REAL_FATTR_NONNULL_ALL REAL_FATTR_WARN_UNUSED_RESULT;
+
+/// Get the byte at index `idx` in the blob.
+///
+/// @param[in] b Blob to index. Cannot be NULL.
+/// @param[in] idx Index in a blob. Must be valid.
+///
+/// @return Byte value at the given index.
+static inline char_u tv_blob_get(const blob_T *const b, int idx)
+{
+ return ((char_u *)b->bv_ga.ga_data)[idx];
+}
+
+static inline void tv_blob_set(blob_T *const b, int idx, char_u c)
+ REAL_FATTR_ALWAYS_INLINE REAL_FATTR_NONNULL_ALL;
+
+/// Store the byte `c` at index `idx` in the blob.
+///
+/// @param[in] b Blob to index. Cannot be NULL.
+/// @param[in] idx Index in a blob. Must be valid.
+/// @param[in] c Value to store.
+static inline void tv_blob_set(blob_T *const b, int idx, char_u c)
+{
+ ((char_u *)b->bv_ga.ga_data)[idx] = c;
+}
+
/// Initialize VimL object
///
/// Initializes to unlocked VAR_UNKNOWN object.
diff --git a/src/nvim/eval/typval_encode.c.h b/src/nvim/eval/typval_encode.c.h
index 91c948ce7e..cd1be1eecc 100644
--- a/src/nvim/eval/typval_encode.c.h
+++ b/src/nvim/eval/typval_encode.c.h
@@ -83,6 +83,13 @@
/// @param len String length.
/// @param type EXT type.
+/// @def TYPVAL_ENCODE_CONV_BLOB
+/// @brief Macros used to convert a blob
+///
+/// @param tv Pointer to typval where value is stored. May not be NULL.
+/// @param blob Pointer to the blob to convert.
+/// @param len Blob length.
+
/// @def TYPVAL_ENCODE_CONV_FUNC_START
/// @brief Macros used when starting to convert a funcref or a partial
///
@@ -330,6 +337,11 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
TYPVAL_ENCODE_CONV_FLOAT(tv, tv->vval.v_float);
break;
}
+ case VAR_BLOB: {
+ TYPVAL_ENCODE_CONV_BLOB(tv, tv->vval.v_blob,
+ tv_blob_len(tv->vval.v_blob));
+ break;
+ }
case VAR_FUNC: {
TYPVAL_ENCODE_CONV_FUNC_START(tv, tv->vval.v_string);
TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, 0);
diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c
index 5ffc06ec44..657777d7db 100644
--- a/src/nvim/eval/userfunc.c
+++ b/src/nvim/eval/userfunc.c
@@ -5,6 +5,7 @@
#include "nvim/ascii.h"
#include "nvim/charset.h"
+#include "nvim/debugger.h"
#include "nvim/edit.h"
#include "nvim/eval.h"
#include "nvim/eval/encode.h"
@@ -12,7 +13,6 @@
#include "nvim/ex_cmds2.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_getln.h"
-#include "nvim/ex_getln.h"
#include "nvim/fileio.h"
#include "nvim/getchar.h"
#include "nvim/globals.h"
@@ -39,7 +39,7 @@
#define FC_CFUNC 0x800 // C function extension
#ifdef INCLUDE_GENERATED_DECLARATIONS
-#include "eval/userfunc.c.generated.h"
+# include "eval/userfunc.c.generated.h"
#endif
hashtab_T func_hashtab;
@@ -54,26 +54,25 @@ static funccall_T *current_funccal = NULL;
// item in it is still being used.
static funccall_T *previous_funccal = NULL;
-static char *e_funcexts = N_(
- "E122: Function %s already exists, add ! to replace it");
+static char *e_funcexts = N_("E122: Function %s already exists, add ! to replace it");
static char *e_funcdict = N_("E717: Dictionary entry already exists");
static char *e_funcref = N_("E718: Funcref required");
static char *e_nofunc = N_("E130: Unknown function: %s");
void func_init(void)
{
- hash_init(&func_hashtab);
+ hash_init(&func_hashtab);
}
/// Get function arguments.
-static int get_function_args(char_u **argp, char_u endchar, garray_T *newargs,
- int *varargs, garray_T *default_args, bool skip)
+static int get_function_args(char_u **argp, char_u endchar, garray_T *newargs, int *varargs,
+ garray_T *default_args, bool skip)
{
- bool mustend = false;
- char_u *arg = *argp;
- char_u *p = arg;
- int c;
- int i;
+ bool mustend = false;
+ char_u *arg = *argp;
+ char_u *p = arg;
+ int c;
+ int i;
if (newargs != NULL) {
ga_init(newargs, (int)sizeof(char_u *), 3);
@@ -145,7 +144,7 @@ static int get_function_args(char_u **argp, char_u endchar, garray_T *newargs,
*p = NUL;
expr = vim_strsave(expr);
((char_u **)(default_args->ga_data))
- [default_args->ga_len] = expr;
+ [default_args->ga_len] = expr;
default_args->ga_len++;
*p = c;
} else {
@@ -199,18 +198,18 @@ static void register_closure(ufunc_T *fp)
current_funccal->fc_refcount++;
ga_grow(&current_funccal->fc_funcs, 1);
((ufunc_T **)current_funccal->fc_funcs.ga_data)
- [current_funccal->fc_funcs.ga_len++] = fp;
+ [current_funccal->fc_funcs.ga_len++] = fp;
}
/// Get a name for a lambda. Returned in static memory.
-char_u * get_lambda_name(void)
+char_u *get_lambda_name(void)
{
- static char_u name[30];
- static int lambda_no = 0;
+ static char_u name[30];
+ static int lambda_no = 0;
- snprintf((char *)name, sizeof(name), "<lambda>%d", ++lambda_no);
- return name;
+ snprintf((char *)name, sizeof(name), "<lambda>%d", ++lambda_no);
+ return name;
}
/// Parse a lambda expression and get a Funcref from "*arg".
@@ -218,16 +217,16 @@ char_u * get_lambda_name(void)
/// @return OK or FAIL. Returns NOTDONE for dict or {expr}.
int get_lambda_tv(char_u **arg, typval_T *rettv, bool evaluate)
{
- garray_T newargs = GA_EMPTY_INIT_VALUE;
- garray_T *pnewargs;
- ufunc_T *fp = NULL;
+ garray_T newargs = GA_EMPTY_INIT_VALUE;
+ garray_T *pnewargs;
+ ufunc_T *fp = NULL;
partial_T *pt = NULL;
- int varargs;
- int ret;
- char_u *start = skipwhite(*arg + 1);
- char_u *s, *e;
- bool *old_eval_lavars = eval_lavars_used;
- bool eval_lavars = false;
+ int varargs;
+ int ret;
+ char_u *start = skipwhite(*arg + 1);
+ char_u *s, *e;
+ bool *old_eval_lavars = eval_lavars_used;
+ bool eval_lavars = false;
// First, check if this is a lambda expression. "->" must exists.
ret = get_function_args(&start, '-', NULL, NULL, NULL, true);
@@ -347,8 +346,7 @@ errret:
/// was not found.
///
/// @return name of the function.
-char_u *deref_func_name(const char *name, int *lenp,
- partial_T **const partialp, bool no_autoload)
+char_u *deref_func_name(const char *name, int *lenp, partial_T **const partialp, bool no_autoload)
FUNC_ATTR_NONNULL_ARG(1, 2)
{
if (partialp != NULL) {
@@ -408,46 +406,41 @@ void emsg_funcname(char *ermsg, const char_u *name)
* Allocate a variable for the result of a function.
* Return OK or FAIL.
*/
-int
-get_func_tv(
- const char_u *name, // name of the function
- int len, // length of "name" or -1 to use strlen()
- typval_T *rettv,
- char_u **arg, // argument, pointing to the '('
- linenr_T firstline, // first line of range
- linenr_T lastline, // last line of range
- int *doesrange, // return: function handled range
- int evaluate,
- partial_T *partial, // for extra arguments
- dict_T *selfdict // Dictionary for "self"
-)
-{
- char_u *argp;
+int get_func_tv(const char_u *name, // name of the function
+ int len, // length of "name" or -1 to use strlen()
+ typval_T *rettv, char_u **arg, // argument, pointing to the '('
+ funcexe_T *funcexe // various values
+ )
+{
+ char_u *argp;
int ret = OK;
- typval_T argvars[MAX_FUNC_ARGS + 1]; /* vars for arguments */
- int argcount = 0; /* number of arguments found */
+ typval_T argvars[MAX_FUNC_ARGS + 1]; // vars for arguments
+ int argcount = 0; // number of arguments found
/*
* Get the arguments.
*/
argp = *arg;
- while (argcount < MAX_FUNC_ARGS - (partial == NULL ? 0 : partial->pt_argc)) {
+ while (argcount < MAX_FUNC_ARGS
+ - (funcexe->partial == NULL ? 0 : funcexe->partial->pt_argc)) {
argp = skipwhite(argp + 1); // skip the '(' or ','
if (*argp == ')' || *argp == ',' || *argp == NUL) {
break;
}
- if (eval1(&argp, &argvars[argcount], evaluate) == FAIL) {
+ if (eval1(&argp, &argvars[argcount], funcexe->evaluate) == FAIL) {
ret = FAIL;
break;
}
++argcount;
- if (*argp != ',')
+ if (*argp != ',') {
break;
+ }
}
- if (*argp == ')')
+ if (*argp == ')') {
++argp;
- else
+ } else {
ret = FAIL;
+ }
if (ret == OK) {
int i = 0;
@@ -463,9 +456,7 @@ get_func_tv(
((typval_T **)funcargs.ga_data)[funcargs.ga_len++] = &argvars[i];
}
}
- ret = call_func(name, len, rettv, argcount, argvars, NULL,
- firstline, lastline, doesrange, evaluate,
- partial, selfdict);
+ ret = call_func(name, len, rettv, argcount, argvars, funcexe);
funcargs.ga_len -= i;
} else if (!aborting()) {
@@ -517,8 +508,7 @@ static inline bool eval_fname_sid(const char *const name)
///
/// @return transformed name: either `fname_buf` or a pointer to an allocated
/// memory.
-static char_u *fname_trans_sid(const char_u *const name,
- char_u *const fname_buf,
+static char_u *fname_trans_sid(const char_u *const name, char_u *const fname_buf,
char_u **const tofree, int *const error)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
@@ -558,11 +548,12 @@ static char_u *fname_trans_sid(const char_u *const name,
/// @return NULL for unknown function.
ufunc_T *find_func(const char_u *name)
{
- hashitem_T *hi;
+ hashitem_T *hi;
hi = hash_find(&func_hashtab, name);
- if (!HASHITEM_EMPTY(hi))
+ if (!HASHITEM_EMPTY(hi)) {
return HI2UF(hi);
+ }
return NULL;
}
@@ -576,8 +567,9 @@ static void cat_func_name(char_u *buf, ufunc_T *fp)
if (fp->uf_name[0] == K_SPECIAL) {
STRCPY(buf, "<SNR>");
STRCAT(buf, fp->uf_name + 3);
- } else
+ } else {
STRCPY(buf, fp->uf_name);
+ }
}
/*
@@ -667,7 +659,6 @@ static void cleanup_function_call(funccall_T *fc)
if (may_free_fc && fc->l_varlist.lv_refcount // NOLINT(runtime/deprecated)
== DO_NOT_FREE_CNT) {
fc->l_varlist.lv_first = NULL; // NOLINT(runtime/deprecated)
-
} else {
free_fc = false;
@@ -812,23 +803,22 @@ static void func_clear_free(ufunc_T *fp, bool force)
/// @param[in] firstline First line of range.
/// @param[in] lastline Last line of range.
/// @param selfdict Dictionary for "self" for dictionary functions.
-void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars,
- typval_T *rettv, linenr_T firstline, linenr_T lastline,
- dict_T *selfdict)
+void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rettv,
+ linenr_T firstline, linenr_T lastline, dict_T *selfdict)
FUNC_ATTR_NONNULL_ARG(1, 3, 4)
{
- char_u *save_sourcing_name;
+ char_u *save_sourcing_name;
linenr_T save_sourcing_lnum;
bool using_sandbox = false;
- funccall_T *fc;
+ funccall_T *fc;
int save_did_emsg;
static int depth = 0;
- dictitem_T *v;
+ dictitem_T *v;
int fixvar_idx = 0; // index in fixvar[]
int ai;
bool islambda = false;
char_u numbuf[NUMBUFLEN];
- char_u *name;
+ char_u *name;
typval_T *tv_to_free[MAX_FUNC_ARGS];
int tv_to_free_len = 0;
proftime_T wait_start;
@@ -954,7 +944,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars,
def_rettv.vval.v_number = -1;
default_expr = ((char_u **)(fp->uf_def_args.ga_data))
- [ai + fp->uf_def_args.ga_len];
+ [ai + fp->uf_def_args.ga_len];
if (eval1(&default_expr, &def_rettv, true) == FAIL) {
default_arg_err = true;
break;
@@ -1140,7 +1130,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars,
call_start = profile_sub_wait(wait_start, call_start); // -V614
fp->uf_tm_total = profile_add(fp->uf_tm_total, call_start);
fp->uf_tm_self = profile_self(fp->uf_tm_self, call_start,
- fp->uf_tm_children);
+ fp->uf_tm_children);
if (fc->caller != NULL && fc->caller->func->uf_profiling) {
fc->caller->func->uf_tm_children =
profile_add(fc->caller->func->uf_tm_children, call_start);
@@ -1158,19 +1148,19 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars,
++no_wait_return;
verbose_enter_scroll();
- if (aborting())
+ if (aborting()) {
smsg(_("%s aborted"), sourcing_name);
- else if (fc->rettv->v_type == VAR_NUMBER)
+ } else if (fc->rettv->v_type == VAR_NUMBER) {
smsg(_("%s returning #%" PRId64 ""),
sourcing_name, (int64_t)fc->rettv->vval.v_number);
- else {
+ } else {
char_u buf[MSG_BUF_LEN];
// The value may be very long. Skip the middle part, so that we
// have some idea how it starts and ends. smsg() would always
// truncate it at the end. Don't want errors such as E724 here.
emsg_off++;
- char_u *s = (char_u *) encode_tv2string(fc->rettv, NULL);
+ char_u *s = (char_u *)encode_tv2string(fc->rettv, NULL);
char_u *tofree = s;
emsg_off--;
if (s != NULL) {
@@ -1274,8 +1264,8 @@ void set_current_funccal(funccall_T *fc)
#if defined(EXITFREE)
void free_all_functions(void)
{
- hashitem_T *hi;
- ufunc_T *fp;
+ hashitem_T *hi;
+ ufunc_T *fp;
uint64_t skipped = 0;
uint64_t todo = 1;
uint64_t used;
@@ -1362,12 +1352,10 @@ static bool builtin_function(const char *name, int len)
return p == NULL;
}
-int func_call(char_u *name, typval_T *args, partial_T *partial,
- dict_T *selfdict, typval_T *rettv)
+int func_call(char_u *name, typval_T *args, partial_T *partial, dict_T *selfdict, typval_T *rettv)
{
typval_T argv[MAX_FUNC_ARGS + 1];
int argc = 0;
- int dummy;
int r = 0;
TV_LIST_ITER(args->vval.v_list, item, {
@@ -1380,9 +1368,13 @@ int func_call(char_u *name, typval_T *args, partial_T *partial,
tv_copy(TV_LIST_ITEM_TV(item), &argv[argc++]);
});
- r = call_func(name, -1, rettv, argc, argv, NULL,
- curwin->w_cursor.lnum, curwin->w_cursor.lnum,
- &dummy, true, partial, selfdict);
+ funcexe_T funcexe = FUNCEXE_INIT;
+ funcexe.firstline = curwin->w_cursor.lnum;
+ funcexe.lastline = curwin->w_cursor.lnum;
+ funcexe.evaluate = true;
+ funcexe.partial = partial;
+ funcexe.selfdict = selfdict;
+ r = call_func(name, -1, rettv, argc, argv, &funcexe);
func_call_skip_call:
// Free the arguments.
@@ -1399,56 +1391,63 @@ static void user_func_error(int error, const char_u *name)
FUNC_ATTR_NONNULL_ALL
{
switch (error) {
- case ERROR_UNKNOWN:
- emsg_funcname(N_("E117: Unknown function: %s"), name);
- break;
- case ERROR_DELETED:
- emsg_funcname(N_("E933: Function was deleted: %s"), name);
- break;
- case ERROR_TOOMANY:
- emsg_funcname(_(e_toomanyarg), name);
- break;
- case ERROR_TOOFEW:
- emsg_funcname(N_("E119: Not enough arguments for function: %s"),
- name);
- break;
- case ERROR_SCRIPT:
- emsg_funcname(N_("E120: Using <SID> not in a script context: %s"),
- name);
- break;
- case ERROR_DICT:
- emsg_funcname(N_("E725: Calling dict function without Dictionary: %s"),
- name);
- break;
+ case ERROR_UNKNOWN:
+ emsg_funcname(N_("E117: Unknown function: %s"), name);
+ break;
+ case ERROR_NOTMETHOD:
+ emsg_funcname(N_("E276: Cannot use function as a method: %s"), name);
+ break;
+ case ERROR_DELETED:
+ emsg_funcname(N_("E933: Function was deleted: %s"), name);
+ break;
+ case ERROR_TOOMANY:
+ emsg_funcname(_(e_toomanyarg), name);
+ break;
+ case ERROR_TOOFEW:
+ emsg_funcname(N_("E119: Not enough arguments for function: %s"),
+ name);
+ break;
+ case ERROR_SCRIPT:
+ emsg_funcname(N_("E120: Using <SID> not in a script context: %s"),
+ name);
+ break;
+ case ERROR_DICT:
+ emsg_funcname(N_("E725: Calling dict function without Dictionary: %s"),
+ name);
+ break;
+ }
+}
+
+/// Used by call_func to add a method base (if any) to a function argument list
+/// as the first argument. @see call_func
+static void argv_add_base(typval_T *const basetv, typval_T **const argvars, int *const argcount,
+ typval_T *const new_argvars, int *const argv_base)
+ FUNC_ATTR_NONNULL_ARG(2, 3, 4, 5)
+{
+ if (basetv != NULL) {
+ // Method call: base->Method()
+ memmove(&new_argvars[1], *argvars, sizeof(typval_T) * (*argcount));
+ new_argvars[0] = *basetv;
+ (*argcount)++;
+ *argvars = new_argvars;
+ *argv_base = 1;
}
}
/// Call a function with its resolved parameters
///
-/// "argv_func", when not NULL, can be used to fill in arguments only when the
-/// invoked function uses them. It is called like this:
-/// new_argcount = argv_func(current_argcount, argv, called_func_argcount)
-///
/// @return FAIL if function cannot be called, else OK (even if an error
/// occurred while executing the function! Set `msg_list` to capture
/// the error, see do_cmdline()).
-int
-call_func(
- const char_u *funcname, // name of the function
- int len, // length of "name" or -1 to use strlen()
- typval_T *rettv, // [out] value goes here
- int argcount_in, // number of "argvars"
- typval_T *argvars_in, // vars for arguments, must have "argcount"
- // PLUS ONE elements!
- ArgvFunc argv_func, // function to fill in argvars
- linenr_T firstline, // first line of range
- linenr_T lastline, // last line of range
- int *doesrange, // [out] function handled range
- bool evaluate,
- partial_T *partial, // optional, can be NULL
- dict_T *selfdict_in // Dictionary for "self"
-)
- FUNC_ATTR_NONNULL_ARG(1, 3, 5, 9)
+int call_func(const char_u *funcname, // name of the function
+ int len, // length of "name" or -1 to use strlen()
+ typval_T *rettv, // [out] value goes here
+ int argcount_in, // number of "argvars"
+ typval_T *argvars_in, // vars for arguments, must have "argcount"
+ // PLUS ONE elements!
+ funcexe_T *funcexe // more arguments
+ )
+ FUNC_ATTR_NONNULL_ARG(1, 3, 5, 6)
{
int ret = FAIL;
int error = ERROR_NONE;
@@ -1459,9 +1458,12 @@ call_func(
char_u *name = NULL;
int argcount = argcount_in;
typval_T *argvars = argvars_in;
- dict_T *selfdict = selfdict_in;
- typval_T argv[MAX_FUNC_ARGS + 1]; // used when "partial" is not NULL
+ dict_T *selfdict = funcexe->selfdict;
+ typval_T argv[MAX_FUNC_ARGS + 1]; // used when "partial" or
+ // "funcexe->basetv" is not NULL
int argv_clear = 0;
+ int argv_base = 0;
+ partial_T *partial = funcexe->partial;
// Initialize rettv so that it is safe for caller to invoke clear_tv(rettv)
// even when call_func() returns FAIL.
@@ -1480,14 +1482,15 @@ call_func(
fname = fname_trans_sid(name, fname_buf, &tofree, &error);
}
- *doesrange = false;
+ if (funcexe->doesrange != NULL) {
+ *funcexe->doesrange = false;
+ }
if (partial != NULL) {
// When the function has a partial with a dict and there is a dict
// argument, use the dict argument. That is backwards compatible.
// When the dict was bound explicitly use the one from the partial.
- if (partial->pt_dict != NULL
- && (selfdict_in == NULL || !partial->pt_auto)) {
+ if (partial->pt_dict != NULL && (selfdict == NULL || !partial->pt_auto)) {
selfdict = partial->pt_dict;
}
if (error == ERROR_NONE && partial->pt_argc > 0) {
@@ -1506,7 +1509,7 @@ call_func(
}
}
- if (error == ERROR_NONE && evaluate) {
+ if (error == ERROR_NONE && funcexe->evaluate) {
char_u *rfname = fname;
// Ignore "g:" before a function name.
@@ -1521,7 +1524,12 @@ call_func(
if (is_luafunc(partial)) {
if (len > 0) {
error = ERROR_NONE;
+ argv_add_base(funcexe->basetv, &argvars, &argcount, argv, &argv_base);
nlua_typval_call((const char *)funcname, len, argvars, argcount, rettv);
+ } else {
+ // v:lua was called directly; show its name in the emsg
+ XFREE_CLEAR(name);
+ funcname = (const char_u *)"v:lua";
}
} else if (fp != NULL || !builtin_function((const char *)rfname, -1)) {
// User defined function.
@@ -1531,7 +1539,7 @@ call_func(
// Trigger FuncUndefined event, may load the function.
if (fp == NULL
- && apply_autocmds(EVENT_FUNCUNDEFINED, rfname, rfname, TRUE, NULL)
+ && apply_autocmds(EVENT_FUNCUNDEFINED, rfname, rfname, true, NULL)
&& !aborting()) {
// executed an autocommand, search for the function again
fp = find_func(rfname);
@@ -1549,13 +1557,16 @@ call_func(
cfunc_T cb = fp->uf_cb;
error = (*cb)(argcount, argvars, rettv, fp->uf_cb_state);
} else if (fp != NULL) {
- if (argv_func != NULL) {
+ if (funcexe->argv_func != NULL) {
// postponed filling in the arguments, do it now
- argcount = argv_func(argcount, argvars, argv_clear,
- fp->uf_args.ga_len);
+ argcount = funcexe->argv_func(argcount, argvars, argv_clear,
+ fp->uf_args.ga_len);
}
- if (fp->uf_flags & FC_RANGE) {
- *doesrange = true;
+
+ argv_add_base(funcexe->basetv, &argvars, &argcount, argv, &argv_base);
+
+ if (fp->uf_flags & FC_RANGE && funcexe->doesrange != NULL) {
+ *funcexe->doesrange = true;
}
if (argcount < fp->uf_args.ga_len - fp->uf_def_args.ga_len) {
error = ERROR_TOOFEW;
@@ -1565,25 +1576,20 @@ call_func(
error = ERROR_DICT;
} else {
// Call the user function.
- call_user_func(fp, argcount, argvars, rettv, firstline, lastline,
+ call_user_func(fp, argcount, argvars, rettv, funcexe->firstline,
+ funcexe->lastline,
(fp->uf_flags & FC_DICT) ? selfdict : NULL);
error = ERROR_NONE;
}
}
+ } else if (funcexe->basetv != NULL) {
+ // expr->method(): Find the method name in the table, call its
+ // implementation with the base as one of the arguments.
+ error = call_internal_method(fname, argcount, argvars, rettv,
+ funcexe->basetv);
} else {
// Find the function name in the table, call its implementation.
- const VimLFuncDef *const fdef = find_internal_func((const char *)fname);
- if (fdef != NULL) {
- if (argcount < fdef->min_argc) {
- error = ERROR_TOOFEW;
- } else if (argcount > fdef->max_argc) {
- error = ERROR_TOOMANY;
- } else {
- argvars[argcount].v_type = VAR_UNKNOWN;
- fdef->func(argvars, rettv, fdef->data);
- error = ERROR_NONE;
- }
- }
+ error = call_internal_func(fname, argcount, argvars, rettv);
}
/*
* The function call (or "FuncUndefined" autocommand sequence) might
@@ -1597,8 +1603,9 @@ call_func(
*/
update_force_abort();
}
- if (error == ERROR_NONE)
+ if (error == ERROR_NONE) {
ret = OK;
+ }
theend:
// Report an error unless the argument evaluation or function call has been
@@ -1607,9 +1614,11 @@ theend:
user_func_error(error, (name != NULL) ? name : funcname);
}
+ // clear the copies made from the partial
while (argv_clear > 0) {
- tv_clear(&argv[--argv_clear]);
+ tv_clear(&argv[--argv_clear + argv_base]);
}
+
xfree(tofree);
xfree(name);
@@ -1624,8 +1633,9 @@ theend:
static void list_func_head(ufunc_T *fp, int indent, bool force)
{
msg_start();
- if (indent)
+ if (indent) {
MSG_PUTS(" ");
+ }
MSG_PUTS(force ? "function! " : "function ");
if (fp->uf_name[0] == K_SPECIAL) {
MSG_PUTS_ATTR("<SNR>", HL_ATTR(HLF_8));
@@ -1681,25 +1691,22 @@ static void list_func_head(ufunc_T *fp, int indent, bool force)
/// Advances "pp" to just after the function name (if no error).
///
/// @return the function name in allocated memory, or NULL for failure.
-char_u *
-trans_function_name(
- char_u **pp,
- bool skip, // only find the end, don't evaluate
- int flags,
- funcdict_T *fdp, // return: info about dictionary used
- partial_T **partial // return: partial of a FuncRef
-)
+char_u *trans_function_name(char_u **pp, bool skip, // only find the end, don't evaluate
+ int flags, funcdict_T *fdp, // return: info about dictionary used
+ partial_T **partial // return: partial of a FuncRef
+ )
FUNC_ATTR_NONNULL_ARG(1)
{
- char_u *name = NULL;
+ char_u *name = NULL;
const char_u *start;
const char_u *end;
int lead;
int len;
lval_T lv;
- if (fdp != NULL)
+ if (fdp != NULL) {
memset(fdp, 0, sizeof(funcdict_T));
+ }
start = *pp;
/* Check for hard coded <SNR>: already translated function ID (from a user
@@ -1722,8 +1729,9 @@ trans_function_name(
end = get_lval((char_u *)start, NULL, &lv, false, skip, flags | GLV_READ_ONLY,
lead > 2 ? 0 : FNE_CHECK_START);
if (end == start) {
- if (!skip)
+ if (!skip) {
EMSG(_("E129: Function name required"));
+ }
goto theend;
}
if (end == NULL || (lv.ll_tv != NULL && (lead > 2 || lv.ll_range))) {
@@ -1789,7 +1797,7 @@ trans_function_name(
goto theend;
}
- /* Check if the name is a Funcref. If so, use the value. */
+ // Check if the name is a Funcref. If so, use the value.
if (lv.ll_exp_name != NULL) {
len = (int)strlen(lv.ll_exp_name);
name = deref_func_name(lv.ll_exp_name, &len, partial,
@@ -1898,31 +1906,31 @@ theend:
*/
void ex_function(exarg_T *eap)
{
- char_u *theline;
- char_u *line_to_free = NULL;
+ char_u *theline;
+ char_u *line_to_free = NULL;
int c;
int saved_did_emsg;
- int saved_wait_return = need_wait_return;
- char_u *name = NULL;
- char_u *p;
- char_u *arg;
- char_u *line_arg = NULL;
+ bool saved_wait_return = need_wait_return;
+ char_u *name = NULL;
+ char_u *p;
+ char_u *arg;
+ char_u *line_arg = NULL;
garray_T newargs;
garray_T default_args;
garray_T newlines;
int varargs = false;
int flags = 0;
- ufunc_T *fp;
+ ufunc_T *fp;
bool overwrite = false;
int indent;
int nesting;
- dictitem_T *v;
+ dictitem_T *v;
funcdict_T fudi;
static int func_nr = 0; // number for nameless function
int paren;
- hashtab_T *ht;
+ hashtab_T *ht;
int todo;
- hashitem_T *hi;
+ hashitem_T *hi;
linenr_T sourcing_lnum_off;
linenr_T sourcing_lnum_top;
bool is_heredoc = false;
@@ -1975,15 +1983,17 @@ void ex_function(exarg_T *eap)
--todo;
fp = HI2UF(hi);
if (!isdigit(*fp->uf_name)
- && vim_regexec(&regmatch, fp->uf_name, 0))
+ && vim_regexec(&regmatch, fp->uf_name, 0)) {
list_func_head(fp, false, false);
+ }
}
}
vim_regfree(regmatch.regprog);
}
}
- if (*p == '/')
+ if (*p == '/') {
++p;
+ }
eap->nextcmd = check_nextcmd(p);
return;
}
@@ -2017,8 +2027,9 @@ void ex_function(exarg_T *eap)
}
xfree(fudi.fd_newkey);
return;
- } else
+ } else {
eap->skip = TRUE;
+ }
}
/* An error in a function call during evaluation of an expression in magic
@@ -2038,8 +2049,9 @@ void ex_function(exarg_T *eap)
goto ret_free;
}
eap->nextcmd = check_nextcmd(p);
- if (eap->nextcmd != NULL)
+ if (eap->nextcmd != NULL) {
*p = NUL;
+ }
if (!eap->skip && !got_int) {
fp = find_func(name);
if (fp != NULL) {
@@ -2066,8 +2078,9 @@ void ex_function(exarg_T *eap)
msg_putchar('\n');
msg_puts(eap->forceit ? "endfunction" : " endfunction");
}
- } else
+ } else {
emsg_funcname(N_("E123: Undefined function: %s"), name);
+ }
}
goto ret_free;
}
@@ -2094,17 +2107,20 @@ void ex_function(exarg_T *eap)
if (!eap->skip) {
/* Check the name of the function. Unless it's a dictionary function
* (that we are overwriting). */
- if (name != NULL)
+ if (name != NULL) {
arg = name;
- else
+ } else {
arg = fudi.fd_newkey;
+ }
if (arg != NULL && (fudi.fd_di == NULL || !tv_is_func(fudi.fd_di->di_tv))) {
int j = (*arg == K_SPECIAL) ? 3 : 0;
while (arg[j] != NUL && (j == 0 ? eval_isnamec1(arg[j])
- : eval_isnamec(arg[j])))
+ : eval_isnamec(arg[j]))) {
++j;
- if (arg[j] != NUL)
+ }
+ if (arg[j] != NUL) {
emsg_funcname((char *)e_invarg2, arg);
+ }
}
// Disallow using the g: dict.
if (fudi.fd_dict != NULL && fudi.fd_dict->dv_scope == VAR_DEF_SCOPE) {
@@ -2139,7 +2155,7 @@ void ex_function(exarg_T *eap)
p += 7;
if (current_funccal == NULL) {
emsg_funcname(N_
- ("E932: Closure function should not be at top level: %s"),
+ ("E932: Closure function should not be at top level: %s"),
name == NULL ? (char_u *)"" : name);
goto erret;
}
@@ -2164,14 +2180,16 @@ void ex_function(exarg_T *eap)
* whole function before telling him it doesn't work! For a script we
* need to skip the body to be able to find what follows. */
if (!eap->skip && !eap->forceit) {
- if (fudi.fd_dict != NULL && fudi.fd_newkey == NULL)
+ if (fudi.fd_dict != NULL && fudi.fd_newkey == NULL) {
EMSG(_(e_funcdict));
- else if (name != NULL && find_func(name) != NULL)
+ } else if (name != NULL && find_func(name) != NULL) {
emsg_funcname(e_funcexts, name);
+ }
}
- if (!eap->skip && did_emsg)
+ if (!eap->skip && did_emsg) {
goto erret;
+ }
if (!ui_has(kUICmdline)) {
msg_putchar('\n'); // don't overwrite the function name
@@ -2195,9 +2213,9 @@ void ex_function(exarg_T *eap)
// Use eap->arg, split up in parts by line breaks.
theline = line_arg;
p = vim_strchr(theline, '\n');
- if (p == NULL)
+ if (p == NULL) {
line_arg += STRLEN(line_arg);
- else {
+ } else {
*p = NUL;
line_arg = p + 1;
}
@@ -2225,7 +2243,7 @@ void ex_function(exarg_T *eap)
// Detect line continuation: sourcing_lnum increased more than one.
sourcing_lnum_off = get_sourced_lnum(eap->getline, eap->cookie);
if (sourcing_lnum < sourcing_lnum_off) {
- sourcing_lnum_off -= sourcing_lnum;
+ sourcing_lnum_off -= sourcing_lnum;
} else {
sourcing_lnum_off = 0;
}
@@ -2289,13 +2307,14 @@ void ex_function(exarg_T *eap)
/* Increase indent inside "if", "while", "for" and "try", decrease
* at "end". */
- if (indent > 2 && STRNCMP(p, "end", 3) == 0)
+ if (indent > 2 && STRNCMP(p, "end", 3) == 0) {
indent -= 2;
- else if (STRNCMP(p, "if", 2) == 0
- || STRNCMP(p, "wh", 2) == 0
- || STRNCMP(p, "for", 3) == 0
- || STRNCMP(p, "try", 3) == 0)
+ } else if (STRNCMP(p, "if", 2) == 0
+ || STRNCMP(p, "wh", 2) == 0
+ || STRNCMP(p, "for", 3) == 0
+ || STRNCMP(p, "try", 3) == 0) {
indent += 2;
+ }
// Check for defining a function inside this function.
if (checkforcmd(&p, "function", 2)) {
@@ -2345,10 +2364,11 @@ void ex_function(exarg_T *eap)
&& (!ASCII_ISALPHA(p[2]) || p[2] == 's')))) {
// ":python <<" continues until a dot, like ":append"
p = skipwhite(arg + 2);
- if (*p == NUL)
+ if (*p == NUL) {
skip_until = vim_strsave((char_u *)".");
- else
+ } else {
skip_until = vim_strsave(p);
+ }
}
// Check for ":let v =<< [trim] EOF"
@@ -2391,8 +2411,9 @@ void ex_function(exarg_T *eap)
/* Add NULL lines for continuation lines, so that the line count is
* equal to the index in the growarray. */
- while (sourcing_lnum_off-- > 0)
+ while (sourcing_lnum_off-- > 0) {
((char_u **)(newlines.ga_data))[newlines.ga_len++] = NULL;
+ }
// Check for end of eap->arg.
if (line_arg != NULL && *line_arg == NUL) {
@@ -2402,8 +2423,9 @@ void ex_function(exarg_T *eap)
/* Don't define the function when skipping commands or when an error was
* detected. */
- if (eap->skip || did_emsg)
+ if (eap->skip || did_emsg) {
goto erret;
+ }
/*
* If there are no errors, add the function
@@ -2412,7 +2434,7 @@ void ex_function(exarg_T *eap)
v = find_var((const char *)name, STRLEN(name), &ht, false);
if (v != NULL && v->di_tv.v_type == VAR_FUNC) {
emsg_funcname(N_("E707: Function name conflicts with variable: %s"),
- name);
+ name);
goto erret;
}
@@ -2428,7 +2450,7 @@ void ex_function(exarg_T *eap)
}
if (fp->uf_calls > 0) {
emsg_funcname(N_("E127: Cannot redefine function %s: It is in use"),
- name);
+ name);
goto erret;
}
if (fp->uf_refcount > 1) {
@@ -2476,7 +2498,7 @@ void ex_function(exarg_T *eap)
if (fp == NULL) {
if (fudi.fd_dict == NULL && vim_strchr(name, AUTOLOAD_CHAR) != NULL) {
int slen, plen;
- char_u *scriptname;
+ char_u *scriptname;
// Check that the autoload name matches the script name.
int j = FAIL;
@@ -2486,14 +2508,14 @@ void ex_function(exarg_T *eap)
plen = (int)STRLEN(p);
slen = (int)STRLEN(sourcing_name);
if (slen > plen && fnamecmp(p,
- sourcing_name + slen - plen) == 0)
+ sourcing_name + slen - plen) == 0) {
j = OK;
+ }
xfree(scriptname);
}
if (j == FAIL) {
- EMSG2(_(
- "E746: Function name does not match script file name: %s"),
- name);
+ EMSG2(_("E746: Function name does not match script file name: %s"),
+ name);
goto erret;
}
}
@@ -2634,8 +2656,8 @@ bool function_exists(const char *const name, bool no_deref)
char_u *get_user_func_name(expand_T *xp, int idx)
{
static size_t done;
- static hashitem_T *hi;
- ufunc_T *fp;
+ static hashitem_T *hi;
+ ufunc_T *fp;
if (idx == 0) {
done = 0;
@@ -2643,10 +2665,12 @@ char_u *get_user_func_name(expand_T *xp, int idx)
}
assert(hi);
if (done < func_hashtab.ht_used) {
- if (done++ > 0)
+ if (done++ > 0) {
++hi;
- while (HASHITEM_EMPTY(hi))
+ }
+ while (HASHITEM_EMPTY(hi)) {
++hi;
+ }
fp = HI2UF(hi);
if ((fp->uf_flags & FC_DICT)
@@ -2661,8 +2685,9 @@ char_u *get_user_func_name(expand_T *xp, int idx)
cat_func_name(IObuff, fp);
if (xp->xp_context != EXPAND_USER_FUNC) {
STRCAT(IObuff, "(");
- if (!fp->uf_varargs && GA_EMPTY(&fp->uf_args))
+ if (!fp->uf_varargs && GA_EMPTY(&fp->uf_args)) {
STRCAT(IObuff, ")");
+ }
}
return IObuff;
}
@@ -2672,17 +2697,18 @@ char_u *get_user_func_name(expand_T *xp, int idx)
/// ":delfunction {name}"
void ex_delfunction(exarg_T *eap)
{
- ufunc_T *fp = NULL;
- char_u *p;
- char_u *name;
+ ufunc_T *fp = NULL;
+ char_u *p;
+ char_u *name;
funcdict_T fudi;
p = eap->arg;
name = trans_function_name(&p, eap->skip, 0, &fudi, NULL);
xfree(fudi.fd_newkey);
if (name == NULL) {
- if (fudi.fd_dict != NULL && !eap->skip)
+ if (fudi.fd_dict != NULL && !eap->skip) {
EMSG(_(e_funcref));
+ }
return;
}
if (!ends_excmd(*skipwhite(p))) {
@@ -2691,11 +2717,13 @@ void ex_delfunction(exarg_T *eap)
return;
}
eap->nextcmd = check_nextcmd(p);
- if (eap->nextcmd != NULL)
+ if (eap->nextcmd != NULL) {
*p = NUL;
+ }
- if (!eap->skip)
+ if (!eap->skip) {
fp = find_func(name);
+ }
xfree(name);
if (!eap->skip) {
@@ -2713,7 +2741,7 @@ void ex_delfunction(exarg_T *eap)
// the reference count, and 1 is the initial refcount.
if (fp->uf_refcount > 2) {
EMSG2(_("Cannot delete function %s: It is being used internally"),
- eap->arg);
+ eap->arg);
return;
}
@@ -2761,8 +2789,8 @@ void func_unref(char_u *name)
abort();
}
#else
- internal_error("func_unref()");
- abort();
+ internal_error("func_unref()");
+ abort();
#endif
}
func_ptr_unref(fp);
@@ -2843,7 +2871,7 @@ static int can_free_funccal(funccall_T *fc, int copyID)
*/
void ex_return(exarg_T *eap)
{
- char_u *arg = eap->arg;
+ char_u *arg = eap->arg;
typval_T rettv;
int returning = FALSE;
@@ -2852,8 +2880,9 @@ void ex_return(exarg_T *eap)
return;
}
- if (eap->skip)
+ if (eap->skip) {
++emsg_skip;
+ }
eap->nextcmd = NULL;
if ((*arg != NUL && *arg != '|' && *arg != '\n')
@@ -2883,25 +2912,26 @@ void ex_return(exarg_T *eap)
eap->nextcmd = check_nextcmd(arg);
}
- if (eap->skip)
+ if (eap->skip) {
--emsg_skip;
+ }
}
// TODO(ZyX-I): move to eval/ex_cmds
/*
- * ":1,25call func(arg1, arg2)" function call.
+ * ":1,25call func(arg1, arg2)" function call.
*/
void ex_call(exarg_T *eap)
{
- char_u *arg = eap->arg;
- char_u *startarg;
- char_u *name;
- char_u *tofree;
+ char_u *arg = eap->arg;
+ char_u *startarg;
+ char_u *name;
+ char_u *tofree;
int len;
typval_T rettv;
linenr_T lnum;
- int doesrange;
+ bool doesrange;
bool failed = false;
funcdict_T fudi;
partial_T *partial = NULL;
@@ -2947,7 +2977,7 @@ void ex_call(exarg_T *eap)
rettv.v_type = VAR_UNKNOWN; // tv_clear() uses this.
if (*startarg != '(') {
- EMSG2(_("E107: Missing parentheses: %s"), eap->arg);
+ EMSG2(_(e_missingparen), eap->arg);
goto end;
}
@@ -2965,15 +2995,22 @@ void ex_call(exarg_T *eap)
curwin->w_cursor.coladd = 0;
}
arg = startarg;
- if (get_func_tv(name, -1, &rettv, &arg,
- eap->line1, eap->line2, &doesrange,
- true, partial, fudi.fd_dict) == FAIL) {
+
+ funcexe_T funcexe = FUNCEXE_INIT;
+ funcexe.firstline = eap->line1;
+ funcexe.lastline = eap->line2;
+ funcexe.doesrange = &doesrange;
+ funcexe.evaluate = true;
+ funcexe.partial = partial;
+ funcexe.selfdict = fudi.fd_dict;
+ if (get_func_tv(name, -1, &rettv, &arg, &funcexe) == FAIL) {
failed = true;
break;
}
// Handle a function returning a Funcref, Dictionary or List.
- if (handle_subscript((const char **)&arg, &rettv, true, true)
+ if (handle_subscript((const char **)&arg, &rettv, true, true,
+ (const char_u *)name, (const char_u **)&name)
== FAIL) {
failed = true;
break;
@@ -3029,22 +3066,22 @@ int do_return(exarg_T *eap, int reanimate, int is_cmd, void *rettv)
current_funccal->returned = false;
}
- /*
- * Cleanup (and inactivate) conditionals, but stop when a try conditional
- * not in its finally clause (which then is to be executed next) is found.
- * In this case, make the ":return" pending for execution at the ":endtry".
- * Otherwise, return normally.
- */
- idx = cleanup_conditionals(eap->cstack, 0, TRUE);
+ //
+ // Cleanup (and deactivate) conditionals, but stop when a try conditional
+ // not in its finally clause (which then is to be executed next) is found.
+ // In this case, make the ":return" pending for execution at the ":endtry".
+ // Otherwise, return normally.
+ //
+ idx = cleanup_conditionals(eap->cstack, 0, true);
if (idx >= 0) {
cstack->cs_pending[idx] = CSTP_RETURN;
- if (!is_cmd && !reanimate)
+ if (!is_cmd && !reanimate) {
/* A pending return again gets pending. "rettv" points to an
* allocated variable with the rettv of the original ":return"'s
* argument if present or is NULL else. */
cstack->cs_rettv[idx] = rettv;
- else {
+ } else {
/* When undoing a return in order to make it pending, get the stored
* return rettv. */
if (reanimate) {
@@ -3056,8 +3093,9 @@ int do_return(exarg_T *eap, int reanimate, int is_cmd, void *rettv)
// Store the value of the pending return.
cstack->cs_rettv[idx] = xcalloc(1, sizeof(typval_T));
*(typval_T *)cstack->cs_rettv[idx] = *(typval_T *)rettv;
- } else
+ } else {
cstack->cs_rettv[idx] = NULL;
+ }
if (reanimate) {
/* The pending return value could be overwritten by a ":return"
@@ -3077,8 +3115,9 @@ int do_return(exarg_T *eap, int reanimate, int is_cmd, void *rettv)
if (!reanimate && rettv != NULL) {
tv_clear(current_funccal->rettv);
*current_funccal->rettv = *(typval_T *)rettv;
- if (!is_cmd)
+ if (!is_cmd) {
xfree(rettv);
+ }
}
}
@@ -3095,7 +3134,7 @@ char_u *get_return_cmd(void *rettv)
char_u *tofree = NULL;
if (rettv != NULL) {
- tofree = s = (char_u *) encode_tv2echo((typval_T *) rettv, NULL);
+ tofree = s = (char_u *)encode_tv2echo((typval_T *)rettv, NULL);
}
if (s == NULL) {
s = (char_u *)"";
@@ -3103,8 +3142,9 @@ char_u *get_return_cmd(void *rettv)
STRCPY(IObuff, ":return ");
STRLCPY(IObuff + 8, s, IOSIZE - 8);
- if (STRLEN(s) + 8 >= IOSIZE)
+ if (STRLEN(s) + 8 >= IOSIZE) {
STRCPY(IObuff + IOSIZE - 4, "...");
+ }
xfree(tofree);
return vim_strsave(IObuff);
}
@@ -3116,19 +3156,20 @@ char_u *get_return_cmd(void *rettv)
*/
char_u *get_func_line(int c, void *cookie, int indent, bool do_concat)
{
- funccall_T *fcp = (funccall_T *)cookie;
- ufunc_T *fp = fcp->func;
- char_u *retval;
- garray_T *gap; // growarray with function lines
+ funccall_T *fcp = (funccall_T *)cookie;
+ ufunc_T *fp = fcp->func;
+ char_u *retval;
+ garray_T *gap; // growarray with function lines
// If breakpoints have been added/deleted need to check for it.
if (fcp->dbg_tick != debug_tick) {
fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name,
- sourcing_lnum);
+ sourcing_lnum);
fcp->dbg_tick = debug_tick;
}
- if (do_profiling == PROF_YES)
+ if (do_profiling == PROF_YES) {
func_line_end(cookie);
+ }
gap = &fp->uf_lines;
if (((fp->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try())
@@ -3145,8 +3186,9 @@ char_u *get_func_line(int c, void *cookie, int indent, bool do_concat)
} else {
retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]);
sourcing_lnum = fcp->linenr;
- if (do_profiling == PROF_YES)
+ if (do_profiling == PROF_YES) {
func_line_start(cookie);
+ }
}
}
@@ -3168,7 +3210,7 @@ char_u *get_func_line(int c, void *cookie, int indent, bool do_concat)
*/
int func_has_ended(void *cookie)
{
- funccall_T *fcp = (funccall_T *)cookie;
+ funccall_T *fcp = (funccall_T *)cookie;
/* Ignore the "abort" flag if the abortion behavior has been changed due to
* an error inside a try conditional. */
@@ -3424,8 +3466,7 @@ hashitem_T *find_hi_in_scoped_ht(const char *name, hashtab_T **pht)
}
/// Search variable in parent scope.
-dictitem_T *find_var_in_scoped_ht(const char *name, const size_t namelen,
- int no_autoload)
+dictitem_T *find_var_in_scoped_ht(const char *name, const size_t namelen, int no_autoload)
{
if (current_funccal == NULL || current_funccal->func->uf_scoped == NULL) {
return NULL;
@@ -3459,54 +3500,54 @@ dictitem_T *find_var_in_scoped_ht(const char *name, const size_t namelen,
/// Set "copyID + 1" in previous_funccal and callers.
bool set_ref_in_previous_funccal(int copyID)
{
- bool abort = false;
-
- for (funccall_T *fc = previous_funccal; !abort && fc != NULL;
+ for (funccall_T *fc = previous_funccal; fc != NULL;
fc = fc->caller) {
fc->fc_copyID = copyID + 1;
- abort = abort
- || set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID + 1, NULL)
- || set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID + 1, NULL)
- || set_ref_in_list(&fc->l_varlist, copyID + 1, NULL);
+ if (set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID + 1, NULL)
+ || set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID + 1, NULL)
+ || set_ref_in_list(&fc->l_varlist, copyID + 1, NULL)) {
+ return true;
+ }
}
- return abort;
+ return false;
}
static bool set_ref_in_funccal(funccall_T *fc, int copyID)
{
- bool abort = false;
-
if (fc->fc_copyID != copyID) {
fc->fc_copyID = copyID;
- abort = abort
- || set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID, NULL)
- || set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID, NULL)
- || set_ref_in_list(&fc->l_varlist, copyID, NULL)
- || set_ref_in_func(NULL, fc->func, copyID);
+ if (set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID, NULL)
+ || set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID, NULL)
+ || set_ref_in_list(&fc->l_varlist, copyID, NULL)
+ || set_ref_in_func(NULL, fc->func, copyID)) {
+ return true;
+ }
}
- return abort;
+ return false;
}
/// Set "copyID" in all local vars and arguments in the call stack.
bool set_ref_in_call_stack(int copyID)
{
- bool abort = false;
-
- for (funccall_T *fc = current_funccal; !abort && fc != NULL;
+ for (funccall_T *fc = current_funccal; fc != NULL;
fc = fc->caller) {
- abort = abort || set_ref_in_funccal(fc, copyID);
+ if (set_ref_in_funccal(fc, copyID)) {
+ return true;
+ }
}
// Also go through the funccal_stack.
- for (funccal_entry_T *entry = funccal_stack; !abort && entry != NULL;
+ for (funccal_entry_T *entry = funccal_stack; entry != NULL;
entry = entry->next) {
- for (funccall_T *fc = entry->top_funccal; !abort && fc != NULL;
+ for (funccall_T *fc = entry->top_funccal; fc != NULL;
fc = fc->caller) {
- abort = abort || set_ref_in_funccal(fc, copyID);
+ if (set_ref_in_funccal(fc, copyID)) {
+ return true;
+ }
}
}
- return abort;
+ return false;
}
/// Set "copyID" in all functions available by name.
@@ -3514,7 +3555,6 @@ bool set_ref_in_functions(int copyID)
{
int todo;
hashitem_T *hi = NULL;
- bool abort = false;
ufunc_T *fp;
todo = (int)func_hashtab.ht_used;
@@ -3522,24 +3562,25 @@ bool set_ref_in_functions(int copyID)
if (!HASHITEM_EMPTY(hi)) {
todo--;
fp = HI2UF(hi);
- if (!func_name_refcount(fp->uf_name)) {
- abort = abort || set_ref_in_func(NULL, fp, copyID);
+ if (!func_name_refcount(fp->uf_name)
+ && set_ref_in_func(NULL, fp, copyID)) {
+ return true;
}
}
}
- return abort;
+ return false;
}
/// Set "copyID" in all function arguments.
bool set_ref_in_func_args(int copyID)
{
- bool abort = false;
-
for (int i = 0; i < funcargs.ga_len; i++) {
- abort = abort || set_ref_in_item(((typval_T **)funcargs.ga_data)[i],
- copyID, NULL, NULL);
+ if (set_ref_in_item(((typval_T **)funcargs.ga_data)[i],
+ copyID, NULL, NULL)) {
+ return true;
+ }
}
- return abort;
+ return false;
}
/// Mark all lists and dicts referenced through function "name" with "copyID".
diff --git a/src/nvim/eval/userfunc.h b/src/nvim/eval/userfunc.h
index e8ad0bf1da..3f111343d2 100644
--- a/src/nvim/eval/userfunc.h
+++ b/src/nvim/eval/userfunc.h
@@ -28,11 +28,37 @@ typedef enum {
ERROR_OTHER,
ERROR_BOTH,
ERROR_DELETED,
+ ERROR_NOTMETHOD,
} FnameTransError;
+/// Used in funcexe_T. Returns the new argcount.
typedef int (*ArgvFunc)(int current_argcount, typval_T *argv, int argskip,
int called_func_argcount);
+/// Structure passed between functions dealing with function call execution.
+typedef struct {
+ ArgvFunc argv_func; ///< when not NULL, can be used to fill in arguments only
+ ///< when the invoked function uses them
+ linenr_T firstline; ///< first line of range
+ linenr_T lastline; ///< last line of range
+ bool *doesrange; ///< [out] if not NULL: function handled range
+ bool evaluate; ///< actually evaluate expressions
+ partial_T *partial; ///< for extra arguments
+ dict_T *selfdict; ///< Dictionary for "self"
+ typval_T *basetv; ///< base for base->method()
+} funcexe_T;
+
+#define FUNCEXE_INIT (funcexe_T) { \
+ .argv_func = NULL, \
+ .firstline = 0, \
+ .lastline = 0, \
+ .doesrange = NULL, \
+ .evaluate = false, \
+ .partial = NULL, \
+ .selfdict = NULL, \
+ .basetv = NULL, \
+}
+
#define FUNCARG(fp, j) ((char_u **)(fp->uf_args.ga_data))[j]
#define FUNCLINE(fp, j) ((char_u **)(fp->uf_lines.ga_data))[j]
diff --git a/src/nvim/event/libuv_process.c b/src/nvim/event/libuv_process.c
index c02f730431..0251ea9957 100644
--- a/src/nvim/event/libuv_process.c
+++ b/src/nvim/event/libuv_process.c
@@ -2,14 +2,13 @@
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
#include <assert.h>
-
#include <uv.h>
+#include "nvim/event/libuv_process.h"
#include "nvim/event/loop.h"
+#include "nvim/event/process.h"
#include "nvim/event/rstream.h"
#include "nvim/event/wstream.h"
-#include "nvim/event/process.h"
-#include "nvim/event/libuv_process.h"
#include "nvim/log.h"
#include "nvim/macros.h"
#include "nvim/os/os.h"
@@ -68,7 +67,7 @@ int libuv_process_spawn(LibuvProcess *uvproc)
#ifdef WIN32
// pipe must be readable for IOCP to work on Windows.
uvproc->uvstdio[1].flags |= proc->overlapped ?
- (UV_READABLE_PIPE | UV_OVERLAPPED_PIPE) : 0;
+ (UV_READABLE_PIPE | UV_OVERLAPPED_PIPE) : 0;
#endif
uvproc->uvstdio[1].data.stream = STRUCT_CAST(uv_stream_t,
&proc->out.uv.pipe);
diff --git a/src/nvim/event/loop.c b/src/nvim/event/loop.c
index e341513ae1..892c46dd04 100644
--- a/src/nvim/event/loop.c
+++ b/src/nvim/event/loop.c
@@ -3,7 +3,6 @@
#include <stdarg.h>
#include <stdint.h>
-
#include <uv.h>
#include "nvim/event/loop.h"
diff --git a/src/nvim/event/multiqueue.c b/src/nvim/event/multiqueue.c
index f534fc483f..a90cbc4e80 100644
--- a/src/nvim/event/multiqueue.c
+++ b/src/nvim/event/multiqueue.c
@@ -49,8 +49,6 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
-
-
#include <uv.h>
#include "nvim/event/multiqueue.h"
@@ -89,7 +87,7 @@ typedef struct {
# include "event/multiqueue.c.generated.h"
#endif
-static Event NILEVENT = { .handler = NULL, .argv = {NULL} };
+static Event NILEVENT = { .handler = NULL, .argv = { NULL } };
MultiQueue *multiqueue_new_parent(PutCallback put_cb, void *data)
{
@@ -104,8 +102,7 @@ MultiQueue *multiqueue_new_child(MultiQueue *parent)
return multiqueue_new(parent, NULL, NULL);
}
-static MultiQueue *multiqueue_new(MultiQueue *parent, PutCallback put_cb,
- void *data)
+static MultiQueue *multiqueue_new(MultiQueue *parent, PutCallback put_cb, void *data)
{
MultiQueue *rv = xmalloc(sizeof(MultiQueue));
QUEUE_INIT(&rv->headtail);
diff --git a/src/nvim/event/process.c b/src/nvim/event/process.c
index b93d6cc0ab..dae4dad16d 100644
--- a/src/nvim/event/process.c
+++ b/src/nvim/event/process.c
@@ -3,20 +3,19 @@
#include <assert.h>
#include <stdlib.h>
-
#include <uv.h>
-#include "nvim/os/shell.h"
+#include "nvim/event/libuv_process.h"
#include "nvim/event/loop.h"
+#include "nvim/event/process.h"
#include "nvim/event/rstream.h"
#include "nvim/event/wstream.h"
-#include "nvim/event/process.h"
-#include "nvim/event/libuv_process.h"
-#include "nvim/os/process.h"
-#include "nvim/os/pty_process.h"
#include "nvim/globals.h"
-#include "nvim/macros.h"
#include "nvim/log.h"
+#include "nvim/macros.h"
+#include "nvim/os/process.h"
+#include "nvim/os/pty_process.h"
+#include "nvim/os/shell.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "event/process.c.generated.h"
@@ -62,14 +61,14 @@ int process_spawn(Process *proc, bool in, bool out, bool err)
int status;
switch (proc->type) {
- case kProcessTypeUv:
- status = libuv_process_spawn((LibuvProcess *)proc);
- break;
- case kProcessTypePty:
- status = pty_process_spawn((PtyProcess *)proc);
- break;
- default:
- abort();
+ case kProcessTypeUv:
+ status = libuv_process_spawn((LibuvProcess *)proc);
+ break;
+ case kProcessTypePty:
+ status = pty_process_spawn((PtyProcess *)proc);
+ break;
+ default:
+ abort();
}
if (status) {
@@ -88,7 +87,7 @@ int process_spawn(Process *proc, bool in, bool out, bool err)
} else {
process_close(proc);
}
- shell_free_argv(proc->argv);
+ process_free(proc);
proc->status = -1;
return status;
}
@@ -139,9 +138,8 @@ void process_teardown(Loop *loop) FUNC_ATTR_NONNULL_ALL
}
// Wait until all children exit and all close events are processed.
- LOOP_PROCESS_EVENTS_UNTIL(
- loop, loop->events, -1,
- kl_empty(loop->children) && multiqueue_empty(loop->events));
+ LOOP_PROCESS_EVENTS_UNTIL(loop, loop->events, -1,
+ kl_empty(loop->children) && multiqueue_empty(loop->events));
pty_process_teardown(loop);
}
@@ -189,7 +187,7 @@ int process_wait(Process *proc, int ms, MultiQueue *events)
// We can only return if all streams/handles are closed and the job
// exited.
LOOP_PROCESS_EVENTS_UNTIL(proc->loop, events, -1,
- proc->refcount == 1);
+ proc->refcount == 1);
} else {
LOOP_PROCESS_EVENTS(proc->loop, events, 0);
}
@@ -200,9 +198,9 @@ int process_wait(Process *proc, int ms, MultiQueue *events)
if (proc->refcount == 1) {
// Job exited, free its resources.
decref(proc);
- if (events) {
- // the decref call created an exit event, process it now
- multiqueue_process_events(events);
+ if (proc->events) {
+ // decref() created an exit event, process it now.
+ multiqueue_process_events(proc->events);
}
} else {
proc->refcount--;
@@ -222,16 +220,16 @@ void process_stop(Process *proc) FUNC_ATTR_NONNULL_ALL
proc->exit_signal = SIGTERM;
switch (proc->type) {
- case kProcessTypeUv:
- os_proc_tree_kill(proc->pid, SIGTERM);
- break;
- case kProcessTypePty:
- // close all streams for pty processes to send SIGHUP to the process
- process_close_streams(proc);
- pty_process_close_master((PtyProcess *)proc);
- break;
- default:
- abort();
+ case kProcessTypeUv:
+ os_proc_tree_kill(proc->pid, SIGTERM);
+ break;
+ case kProcessTypePty:
+ // close all streams for pty processes to send SIGHUP to the process
+ process_close_streams(proc);
+ pty_process_close_master((PtyProcess *)proc);
+ break;
+ default:
+ abort();
}
// (Re)start timer to verify that stopped process(es) died.
@@ -239,6 +237,15 @@ void process_stop(Process *proc) FUNC_ATTR_NONNULL_ALL
KILL_TIMEOUT_MS, 0);
}
+// Frees process-owned resources.
+void process_free(Process *proc) FUNC_ATTR_NONNULL_ALL
+{
+ if (proc->argv != NULL) {
+ shell_free_argv(proc->argv);
+ proc->argv = NULL;
+ }
+}
+
/// Sends SIGKILL (or SIGTERM..SIGKILL for PTY jobs) to processes that did
/// not terminate after process_stop().
static void children_kill_cb(uv_timer_t *handle)
@@ -269,9 +276,12 @@ static void children_kill_cb(uv_timer_t *handle)
static void process_close_event(void **argv)
{
Process *proc = argv[0];
- shell_free_argv(proc->argv);
- if (proc->cb) { // "on_exit" for jobstart(). See channel_job_start().
+ if (proc->cb) {
+ // User (hint: channel_job_start) is responsible for calling
+ // process_free().
proc->cb(proc, proc->status, proc->data);
+ } else {
+ process_free(proc);
}
}
@@ -313,14 +323,14 @@ static void process_close(Process *proc)
}
switch (proc->type) {
- case kProcessTypeUv:
- libuv_process_close((LibuvProcess *)proc);
- break;
- case kProcessTypePty:
- pty_process_close((PtyProcess *)proc);
- break;
- default:
- abort();
+ case kProcessTypeUv:
+ libuv_process_close((LibuvProcess *)proc);
+ break;
+ case kProcessTypePty:
+ pty_process_close((PtyProcess *)proc);
+ break;
+ default:
+ abort();
}
}
@@ -357,7 +367,7 @@ static void flush_stream(Process *proc, Stream *stream)
// Poll for data and process the generated events.
loop_poll_events(proc->loop, 0);
if (stream->events) {
- multiqueue_process_events(stream->events);
+ multiqueue_process_events(stream->events);
}
// Stream can be closed if it is empty.
diff --git a/src/nvim/event/process.h b/src/nvim/event/process.h
index 24debdb276..20c02e4900 100644
--- a/src/nvim/event/process.h
+++ b/src/nvim/event/process.h
@@ -26,6 +26,7 @@ struct process {
char **argv;
dict_T *env;
Stream in, out, err;
+ /// Exit handler. If set, user must call process_free().
process_exit_cb cb;
internal_process_cb internal_exit_cb, internal_close_cb;
bool closed, detach, overlapped;
diff --git a/src/nvim/event/rstream.c b/src/nvim/event/rstream.c
index efa56932d2..f070c8179f 100644
--- a/src/nvim/event/rstream.c
+++ b/src/nvim/event/rstream.c
@@ -2,19 +2,18 @@
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
#include <assert.h>
-#include <stdint.h>
#include <stdbool.h>
+#include <stdint.h>
#include <stdlib.h>
-
#include <uv.h>
-#include "nvim/event/rstream.h"
#include "nvim/ascii.h"
-#include "nvim/vim.h"
-#include "nvim/memory.h"
+#include "nvim/event/loop.h"
+#include "nvim/event/rstream.h"
#include "nvim/log.h"
+#include "nvim/memory.h"
#include "nvim/misc1.h"
-#include "nvim/event/loop.h"
+#include "nvim/vim.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "event/rstream.c.generated.h"
@@ -160,14 +159,13 @@ static void fread_idle_cb(uv_idle_t *handle)
}
// Synchronous read
- uv_fs_read(
- handle->loop,
- &req,
- stream->fd,
- &stream->uvbuf,
- 1,
- (int64_t) stream->fpos,
- NULL);
+ uv_fs_read(handle->loop,
+ &req,
+ stream->fd,
+ &stream->uvbuf,
+ 1,
+ (int64_t)stream->fpos,
+ NULL);
uv_fs_req_cleanup(&req);
@@ -178,7 +176,7 @@ static void fread_idle_cb(uv_idle_t *handle)
}
// no errors (req.result (ssize_t) is positive), it's safe to cast.
- size_t nread = (size_t) req.result;
+ size_t nread = (size_t)req.result;
rbuffer_produced(stream->buffer, nread);
stream->fpos += nread;
invoke_read_cb(stream, nread, false);
diff --git a/src/nvim/event/socket.c b/src/nvim/event/socket.c
index 23228aa63a..7948a7be83 100644
--- a/src/nvim/event/socket.c
+++ b/src/nvim/event/socket.c
@@ -3,30 +3,28 @@
#include <assert.h>
#include <stdint.h>
-
#include <uv.h>
+#include "nvim/ascii.h"
+#include "nvim/charset.h"
#include "nvim/event/loop.h"
-#include "nvim/event/socket.h"
#include "nvim/event/rstream.h"
+#include "nvim/event/socket.h"
#include "nvim/event/wstream.h"
-#include "nvim/os/os.h"
-#include "nvim/ascii.h"
-#include "nvim/vim.h"
-#include "nvim/strings.h"
-#include "nvim/path.h"
+#include "nvim/log.h"
+#include "nvim/macros.h"
#include "nvim/main.h"
#include "nvim/memory.h"
-#include "nvim/macros.h"
-#include "nvim/charset.h"
-#include "nvim/log.h"
+#include "nvim/os/os.h"
+#include "nvim/path.h"
+#include "nvim/strings.h"
+#include "nvim/vim.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "event/socket.c.generated.h"
#endif
-int socket_watcher_init(Loop *loop, SocketWatcher *watcher,
- const char *endpoint)
+int socket_watcher_init(Loop *loop, SocketWatcher *watcher, const char *endpoint)
FUNC_ATTR_NONNULL_ALL
{
xstrlcpy(watcher->addr, endpoint, sizeof(watcher->addr));
@@ -56,9 +54,9 @@ int socket_watcher_init(Loop *loop, SocketWatcher *watcher,
int retval = uv_getaddrinfo(&loop->uv, &request, NULL, addr, port,
&(struct addrinfo){
- .ai_family = AF_UNSPEC,
- .ai_socktype = SOCK_STREAM,
- });
+ .ai_family = AF_UNSPEC,
+ .ai_socktype = SOCK_STREAM,
+ });
if (retval != 0) {
ELOG("Host lookup failed: %s", endpoint);
return retval;
@@ -106,7 +104,7 @@ int socket_watcher_start(SocketWatcher *watcher, int backlog, socket_cb cb)
uv_tcp_getsockname(&watcher->uv.tcp.handle, (struct sockaddr *)&sas,
&(int){ sizeof(sas) });
uint16_t port = (uint16_t)(
- (sas.ss_family == AF_INET)
+ (sas.ss_family == AF_INET)
? (STRUCT_CAST(struct sockaddr_in, &sas))->sin_port
: (STRUCT_CAST(struct sockaddr_in6, &sas))->sin6_port);
// v:servername uses the string from watcher->addr
@@ -183,7 +181,7 @@ static void connection_cb(uv_stream_t *handle, int status)
{
SocketWatcher *watcher = handle->data;
CREATE_EVENT(watcher->events, connection_event, 2, watcher,
- (void *)(uintptr_t)status);
+ (void *)(uintptr_t)status);
}
static void close_cb(uv_handle_t *handle)
@@ -203,9 +201,8 @@ static void connect_cb(uv_connect_t *req, int status)
}
}
-bool socket_connect(Loop *loop, Stream *stream,
- bool is_tcp, const char *address,
- int timeout, const char **error)
+bool socket_connect(Loop *loop, Stream *stream, bool is_tcp, const char *address, int timeout,
+ const char **error)
{
bool success = false;
int status;
@@ -243,7 +240,6 @@ tcp_retry:
uv_tcp_nodelay(tcp, true);
uv_tcp_connect(&req, tcp, addrinfo->ai_addr, connect_cb);
uv_stream = (uv_stream_t *)tcp;
-
} else {
uv_pipe_t *pipe = &stream->uv.pipe;
uv_pipe_init(&loop->uv, pipe, 0);
diff --git a/src/nvim/event/stream.c b/src/nvim/event/stream.c
index 1e9e530a42..b34fd73d52 100644
--- a/src/nvim/event/stream.c
+++ b/src/nvim/event/stream.c
@@ -2,15 +2,14 @@
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
#include <assert.h>
-#include <stdio.h>
#include <stdbool.h>
-
+#include <stdio.h>
#include <uv.h>
+#include "nvim/event/stream.h"
#include "nvim/log.h"
-#include "nvim/rbuffer.h"
#include "nvim/macros.h"
-#include "nvim/event/stream.h"
+#include "nvim/rbuffer.h"
#ifdef WIN32
# include "nvim/os/os_win_console.h"
#endif
@@ -19,9 +18,9 @@
# include "event/stream.c.generated.h"
#endif
-// For compatbility with libuv < 1.19.0 (tested on 1.18.0)
+// For compatibility with libuv < 1.19.0 (tested on 1.18.0)
#if UV_VERSION_MINOR < 19
-#define uv_stream_get_write_queue_size(stream) stream->write_queue_size
+# define uv_stream_get_write_queue_size(stream) stream->write_queue_size
#endif
/// Sets the stream associated with `fd` to "blocking" mode.
@@ -77,7 +76,7 @@ void stream_init(Loop *loop, Stream *stream, int fd, uv_stream_t *uvstream)
uv_pipe_open(&stream->uv.pipe, fd);
stream->uvstream = STRUCT_CAST(uv_stream_t, &stream->uv.pipe);
#ifdef WIN32
- }
+ }
#endif
}
}
diff --git a/src/nvim/event/time.c b/src/nvim/event/time.c
index b7e30e392b..aa7b9cf2a1 100644
--- a/src/nvim/event/time.c
+++ b/src/nvim/event/time.c
@@ -2,7 +2,6 @@
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
#include <stdint.h>
-
#include <uv.h>
#include "nvim/event/loop.h"
@@ -23,8 +22,7 @@ void time_watcher_init(Loop *loop, TimeWatcher *watcher, void *data)
watcher->blockable = false;
}
-void time_watcher_start(TimeWatcher *watcher, time_cb cb, uint64_t timeout,
- uint64_t repeat)
+void time_watcher_start(TimeWatcher *watcher, time_cb cb, uint64_t timeout, uint64_t repeat)
FUNC_ATTR_NONNULL_ALL
{
watcher->cb = cb;
diff --git a/src/nvim/event/wstream.c b/src/nvim/event/wstream.c
index 2baa667e7d..d81ffa5c15 100644
--- a/src/nvim/event/wstream.c
+++ b/src/nvim/event/wstream.c
@@ -2,17 +2,16 @@
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
#include <assert.h>
-#include <stdint.h>
#include <stdbool.h>
+#include <stdint.h>
#include <stdlib.h>
-
#include <uv.h>
-#include "nvim/log.h"
#include "nvim/event/loop.h"
#include "nvim/event/wstream.h"
-#include "nvim/vim.h"
+#include "nvim/log.h"
#include "nvim/memory.h"
+#include "nvim/vim.h"
#define DEFAULT_MAXMEM 1024 * 1024 * 2000
@@ -117,10 +116,7 @@ err:
/// @param cb Pointer to function that will be responsible for freeing
/// the buffer data(passing 'free' will work as expected).
/// @return The allocated WBuffer instance
-WBuffer *wstream_new_buffer(char *data,
- size_t size,
- size_t refcount,
- wbuffer_data_finalizer cb)
+WBuffer *wstream_new_buffer(char *data, size_t size, size_t refcount, wbuffer_data_finalizer cb)
FUNC_ATTR_NONNULL_ARG(1)
{
WBuffer *rv = xmalloc(sizeof(WBuffer));
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index 4af7794317..bbc1dd9717 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -7,54 +7,58 @@
#include <assert.h>
#include <float.h>
-#include <stdbool.h>
-#include <string.h>
-#include <stdlib.h>
#include <inttypes.h>
#include <math.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include "nvim/api/buffer.h"
#include "nvim/api/private/defs.h"
#include "nvim/api/vim.h"
-#include "nvim/api/buffer.h"
-#include "nvim/log.h"
-#include "nvim/vim.h"
#include "nvim/ascii.h"
-#include "nvim/ex_cmds.h"
#include "nvim/buffer.h"
+#include "nvim/buffer_updates.h"
#include "nvim/change.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
+#include "nvim/decoration.h"
#include "nvim/diff.h"
#include "nvim/digraph.h"
#include "nvim/edit.h"
#include "nvim/eval.h"
+#include "nvim/ex_cmds.h"
#include "nvim/ex_cmds2.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_eval.h"
#include "nvim/ex_getln.h"
+#include "nvim/extmark.h"
#include "nvim/fileio.h"
#include "nvim/fold.h"
+#include "nvim/garray.h"
#include "nvim/getchar.h"
#include "nvim/highlight.h"
#include "nvim/indent.h"
-#include "nvim/buffer_updates.h"
+#include "nvim/log.h"
#include "nvim/main.h"
#include "nvim/mark.h"
-#include "nvim/extmark.h"
-#include "nvim/decoration.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
+#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/garray.h"
-#include "nvim/memory.h"
-#include "nvim/move.h"
#include "nvim/mouse.h"
+#include "nvim/move.h"
#include "nvim/normal.h"
#include "nvim/ops.h"
#include "nvim/option.h"
+#include "nvim/os/input.h"
+#include "nvim/os/os.h"
+#include "nvim/os/shell.h"
+#include "nvim/os/time.h"
#include "nvim/os_unix.h"
#include "nvim/path.h"
+#include "nvim/plines.h"
#include "nvim/quickfix.h"
#include "nvim/regexp.h"
#include "nvim/screen.h"
@@ -65,11 +69,8 @@
#include "nvim/tag.h"
#include "nvim/ui.h"
#include "nvim/undo.h"
+#include "nvim/vim.h"
#include "nvim/window.h"
-#include "nvim/os/os.h"
-#include "nvim/os/shell.h"
-#include "nvim/os/input.h"
-#include "nvim/os/time.h"
/// Case matching style to use for :substitute
@@ -103,7 +104,7 @@ typedef struct {
// the preview window
typedef struct {
kvec_t(SubResult) subresults;
- linenr_T lines_needed; // lines neede in the preview window
+ linenr_T lines_needed; // lines needed in the preview window
} PreviewLines;
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -146,17 +147,17 @@ void do_ascii(const exarg_T *const eap)
dig = get_digraph_for_char(cval);
if (dig != NULL) {
- iobuff_len += (
- vim_snprintf((char *)IObuff + iobuff_len,
- sizeof(IObuff) - iobuff_len,
- _("<%s>%s%s %d, Hex %02x, Oct %03o, Digr %s"),
- transchar(c), buf1, buf2, cval, cval, cval, dig));
+ iobuff_len += (
+ vim_snprintf((char *)IObuff + iobuff_len,
+ sizeof(IObuff) - iobuff_len,
+ _("<%s>%s%s %d, Hex %02x, Oct %03o, Digr %s"),
+ transchar(c), buf1, buf2, cval, cval, cval, dig));
} else {
- iobuff_len += (
- vim_snprintf((char *)IObuff + iobuff_len,
- sizeof(IObuff) - iobuff_len,
- _("<%s>%s%s %d, Hex %02x, Octal %03o"),
- transchar(c), buf1, buf2, cval, cval, cval));
+ iobuff_len += (
+ vim_snprintf((char *)IObuff + iobuff_len,
+ sizeof(IObuff) - iobuff_len,
+ _("<%s>%s%s %d, Hex %02x, Octal %03o"),
+ transchar(c), buf1, buf2, cval, cval, cval));
}
c = cc[ci++];
@@ -196,21 +197,21 @@ void do_ascii(const exarg_T *const eap)
dig = get_digraph_for_char(c);
if (dig != NULL) {
- iobuff_len += (
- vim_snprintf((char *)IObuff + iobuff_len,
- sizeof(IObuff) - iobuff_len,
- (c < 0x10000
+ iobuff_len += (
+ vim_snprintf((char *)IObuff + iobuff_len,
+ sizeof(IObuff) - iobuff_len,
+ (c < 0x10000
? _("> %d, Hex %04x, Oct %o, Digr %s")
: _("> %d, Hex %08x, Oct %o, Digr %s")),
- c, c, c, dig));
+ c, c, c, dig));
} else {
- iobuff_len += (
- vim_snprintf((char *)IObuff + iobuff_len,
- sizeof(IObuff) - iobuff_len,
- (c < 0x10000
+ iobuff_len += (
+ vim_snprintf((char *)IObuff + iobuff_len,
+ sizeof(IObuff) - iobuff_len,
+ (c < 0x10000
? _("> %d, Hex %04x, Octal %o")
: _("> %d, Hex %08x, Octal %o")),
- c, c, c));
+ c, c, c));
}
if (ci == MAX_MCO) {
break;
@@ -237,26 +238,29 @@ void ex_align(exarg_T *eap)
int width;
if (curwin->w_p_rl) {
- /* switch left and right aligning */
- if (eap->cmdidx == CMD_right)
+ // switch left and right aligning
+ if (eap->cmdidx == CMD_right) {
eap->cmdidx = CMD_left;
- else if (eap->cmdidx == CMD_left)
+ } else if (eap->cmdidx == CMD_left) {
eap->cmdidx = CMD_right;
+ }
}
width = atoi((char *)eap->arg);
save_curpos = curwin->w_cursor;
- if (eap->cmdidx == CMD_left) { /* width is used for new indent */
- if (width >= 0)
+ if (eap->cmdidx == CMD_left) { // width is used for new indent
+ if (width >= 0) {
indent = width;
+ }
} else {
/*
* if 'textwidth' set, use it
* else if 'wrapmargin' set, use it
* if invalid value, use 80
*/
- if (width <= 0)
+ if (width <= 0) {
width = curbuf->b_p_tw;
+ }
if (width == 0 && curbuf->b_p_wm > 0) {
width = curwin->w_width_inner - curbuf->b_p_wm;
}
@@ -265,31 +269,33 @@ void ex_align(exarg_T *eap)
}
}
- if (u_save((linenr_T)(eap->line1 - 1), (linenr_T)(eap->line2 + 1)) == FAIL)
+ if (u_save((linenr_T)(eap->line1 - 1), (linenr_T)(eap->line2 + 1)) == FAIL) {
return;
+ }
for (curwin->w_cursor.lnum = eap->line1;
curwin->w_cursor.lnum <= eap->line2; ++curwin->w_cursor.lnum) {
- if (eap->cmdidx == CMD_left) /* left align */
+ if (eap->cmdidx == CMD_left) { // left align
new_indent = indent;
- else {
- has_tab = FALSE; /* avoid uninit warnings */
+ } else {
+ has_tab = FALSE; // avoid uninit warnings
len = linelen(eap->cmdidx == CMD_right ? &has_tab
- : NULL) - get_indent();
+ : NULL) - get_indent();
- if (len <= 0) /* skip blank lines */
+ if (len <= 0) { // skip blank lines
continue;
+ }
- if (eap->cmdidx == CMD_center)
+ if (eap->cmdidx == CMD_center) {
new_indent = (width - len) / 2;
- else {
- new_indent = width - len; /* right align */
+ } else {
+ new_indent = width - len; // right align
/*
* Make sure that embedded TABs don't make the text go too far
* to the right.
*/
- if (has_tab)
+ if (has_tab) {
while (new_indent > 0) {
(void)set_indent(new_indent, 0);
if (linelen(NULL) <= width) {
@@ -305,11 +311,13 @@ void ex_align(exarg_T *eap)
}
--new_indent;
}
+ }
}
}
- if (new_indent < 0)
+ if (new_indent < 0) {
new_indent = 0;
- (void)set_indent(new_indent, 0); /* set indent */
+ }
+ (void)set_indent(new_indent, 0); // set indent
}
changed_lines(eap->line1, 0, eap->line2 + 1, 0L, true);
curwin->w_cursor = save_curpos;
@@ -321,9 +329,9 @@ void ex_align(exarg_T *eap)
*/
static int linelen(int *has_tab)
{
- char_u *line;
- char_u *first;
- char_u *last;
+ char_u *line;
+ char_u *first;
+ char_u *last;
int save;
int len;
@@ -355,8 +363,8 @@ static int linelen(int *has_tab)
/* Buffer for two lines used during sorting. They are allocated to
* contain the longest line being sorted. */
-static char_u *sortbuf1;
-static char_u *sortbuf2;
+static char_u *sortbuf1;
+static char_u *sortbuf2;
static int sort_lc; ///< sort using locale
static int sort_ic; ///< ignore case
@@ -399,11 +407,13 @@ static int sort_compare(const void *s1, const void *s2)
/* If the user interrupts, there's no way to stop qsort() immediately, but
* if we return 0 every time, qsort will assume it's done sorting and
* exit. */
- if (sort_abort)
+ if (sort_abort) {
return 0;
+ }
fast_breakcheck();
- if (got_int)
+ if (got_int) {
sort_abort = TRUE;
+ }
// When sorting numbers "start_col_nr" is the number, not the column
// number.
@@ -435,9 +445,10 @@ static int sort_compare(const void *s1, const void *s2)
result = string_compare(sortbuf1, sortbuf2);
}
- /* If two lines have the same value, preserve the original line order. */
- if (result == 0)
+ // If two lines have the same value, preserve the original line order.
+ if (result == 0) {
return (int)(l1.lnum - l2.lnum);
+ }
return result;
}
@@ -450,9 +461,9 @@ void ex_sort(exarg_T *eap)
long maxlen = 0;
size_t count = (size_t)(eap->line2 - eap->line1 + 1);
size_t i;
- char_u *p;
- char_u *s;
- char_u *s2;
+ char_u *p;
+ char_u *s;
+ char_u *s2;
char_u c; // temporary character storage
bool unique = false;
long deleted;
@@ -598,7 +609,7 @@ void ex_sort(exarg_T *eap)
} else {
nrs[lnum - eap->line1].st_u.num.is_number = true;
vim_str2nr(s, NULL, NULL, sort_what,
- &nrs[lnum - eap->line1].st_u.num.value, NULL, 0);
+ &nrs[lnum - eap->line1].st_u.num.value, NULL, 0, false);
}
} else {
s = skipwhite(p);
@@ -622,10 +633,12 @@ void ex_sort(exarg_T *eap)
nrs[lnum - eap->line1].lnum = lnum;
- if (regmatch.regprog != NULL)
+ if (regmatch.regprog != NULL) {
fast_breakcheck();
- if (got_int)
+ }
+ if (got_int) {
goto sortend;
+ }
}
// Allocate a buffer that can hold the longest line.
@@ -635,8 +648,9 @@ void ex_sort(exarg_T *eap)
// Sort the array of line numbers. Note: can't be interrupted!
qsort((void *)nrs, count, sizeof(sorti_T), sort_compare);
- if (sort_abort)
+ if (sort_abort) {
goto sortend;
+ }
bcount_t old_count = 0, new_count = 0;
@@ -664,8 +678,9 @@ void ex_sort(exarg_T *eap)
new_count += bytelen;
}
fast_breakcheck();
- if (got_int)
+ if (got_int) {
goto sortend;
+ }
}
// delete the original lines if appending worked
@@ -714,7 +729,7 @@ sortend:
void ex_retab(exarg_T *eap)
{
linenr_T lnum;
- int got_tab = FALSE;
+ bool got_tab = false;
long num_spaces = 0;
long num_tabs;
long len;
@@ -723,18 +738,18 @@ void ex_retab(exarg_T *eap)
long start_col = 0; // For start of white-space string
long start_vcol = 0; // For start of white-space string
long old_len;
- char_u *ptr;
- char_u *new_line = (char_u *)1; // init to non-NULL
- int did_undo; // called u_save for current line
+ char_u *ptr;
+ char_u *new_line = (char_u *)1; // init to non-NULL
+ bool did_undo; // called u_save for current line
long *new_vts_array = NULL;
char_u *new_ts_str; // string value of tab argument
int save_list;
- linenr_T first_line = 0; /* first changed line */
- linenr_T last_line = 0; /* last changed line */
+ linenr_T first_line = 0; // first changed line
+ linenr_T last_line = 0; // last changed line
save_list = curwin->w_p_list;
- curwin->w_p_list = 0; /* don't want list mode here */
+ curwin->w_p_list = 0; // don't want list mode here
new_ts_str = eap->arg;
if (!tabstop_set(eap->arg, &new_vts_array)) {
@@ -757,23 +772,24 @@ void ex_retab(exarg_T *eap)
ptr = ml_get(lnum);
col = 0;
vcol = 0;
- did_undo = FALSE;
+ did_undo = false;
for (;; ) {
if (ascii_iswhite(ptr[col])) {
if (!got_tab && num_spaces == 0) {
- /* First consecutive white-space */
+ // First consecutive white-space
start_vcol = vcol;
start_col = col;
}
- if (ptr[col] == ' ')
+ if (ptr[col] == ' ') {
num_spaces++;
- else
- got_tab = TRUE;
+ } else {
+ got_tab = true;
+ }
} else {
if (got_tab || (eap->forceit && num_spaces > 1)) {
- /* Retabulate this string of white-space */
+ // Retabulate this string of white-space
- /* len is virtual length of white string */
+ // len is virtual length of white string
len = num_spaces = vcol - start_vcol;
num_tabs = 0;
if (!curbuf->b_p_et) {
@@ -795,16 +811,17 @@ void ex_retab(exarg_T *eap)
}
}
- /* len is actual number of white characters used */
+ // len is actual number of white characters used
len = num_spaces + num_tabs;
old_len = (long)STRLEN(ptr);
long new_len = old_len - col + start_col + len + 1;
new_line = xmalloc(new_len);
- if (start_col > 0)
+ if (start_col > 0) {
memmove(new_line, ptr, (size_t)start_col);
+ }
memmove(new_line + start_col + len,
- ptr + col, (size_t)(old_len - col + 1));
+ ptr + col, (size_t)(old_len - col + 1));
ptr = new_line + start_col;
for (col = 0; col < len; col++) {
ptr[col] = (col < num_tabs) ? '\t' : ' ';
@@ -823,20 +840,23 @@ void ex_retab(exarg_T *eap)
col = start_col + len;
}
}
- got_tab = FALSE;
+ got_tab = false;
num_spaces = 0;
}
- if (ptr[col] == NUL)
+ if (ptr[col] == NUL) {
break;
- vcol += chartabsize(ptr + col, (colnr_T)vcol);
+ }
+ vcol += win_chartabsize(curwin, ptr + col, (colnr_T)vcol);
col += utfc_ptr2len(ptr + col);
}
- if (new_line == NULL) /* out of memory */
+ if (new_line == NULL) { // out of memory
break;
+ }
line_breakcheck();
}
- if (got_int)
+ if (got_int) {
EMSG(_(e_interr));
+ }
// If a single value was given then it can be considered equal to
// either the value of 'tabstop' or the value of 'vartabstop'.
@@ -854,7 +874,7 @@ void ex_retab(exarg_T *eap)
changed_lines(first_line, 0, last_line + 1, 0L, true);
}
- curwin->w_p_list = save_list; /* restore 'list' */
+ curwin->w_p_list = save_list; // restore 'list'
if (new_ts_str != NULL) { // set the new tabstop
// If 'vartabstop' is in use or if the value given to retab has more
@@ -886,7 +906,7 @@ void ex_retab(exarg_T *eap)
*/
int do_move(linenr_T line1, linenr_T line2, linenr_T dest)
{
- char_u *str;
+ char_u *str;
linenr_T l;
linenr_T extra; // Num lines added before line1
linenr_T num_lines; // Num lines moved
@@ -921,14 +941,16 @@ int do_move(linenr_T line1, linenr_T line2, linenr_T dest)
* First we copy the old text to its new location -- webb
* Also copy the flag that ":global" command uses.
*/
- if (u_save(dest, dest + 1) == FAIL)
+ if (u_save(dest, dest + 1) == FAIL) {
return FAIL;
+ }
for (extra = 0, l = line1; l <= line2; l++) {
str = vim_strsave(ml_get(l + extra));
ml_append(dest + l - line1, str, (colnr_T)0, false);
xfree(str);
- if (dest < line1)
+ if (dest < line1) {
extra++;
+ }
}
/*
@@ -984,17 +1006,19 @@ int do_move(linenr_T line1, linenr_T line2, linenr_T dest)
/*
* Now we delete the original text -- webb
*/
- if (u_save(line1 + extra - 1, line2 + extra + 1) == FAIL)
+ if (u_save(line1 + extra - 1, line2 + extra + 1) == FAIL) {
return FAIL;
+ }
for (l = line1; l <= line2; l++) {
ml_delete(line1 + extra, true);
}
if (!global_busy && num_lines > p_report) {
- if (num_lines == 1)
+ if (num_lines == 1) {
MSG(_("1 line moved"));
- else
+ } else {
smsg(_("%" PRId64 " lines moved"), (int64_t)num_lines);
+ }
}
extmark_move_region(curbuf, line1-1, 0, start_byte,
@@ -1005,16 +1029,18 @@ int do_move(linenr_T line1, linenr_T line2, linenr_T dest)
/*
* Leave the cursor on the last of the moved lines.
*/
- if (dest >= line1)
+ if (dest >= line1) {
curwin->w_cursor.lnum = dest;
- else
+ } else {
curwin->w_cursor.lnum = dest + (line2 - line1) + 1;
+ }
if (line1 < dest) {
dest += num_lines + 1;
last_line = curbuf->b_ml.ml_line_count;
- if (dest > last_line + 1)
+ if (dest > last_line + 1) {
dest = last_line + 1;
+ }
changed_lines(line1, 0, dest, 0L, false);
} else {
changed_lines(dest + 1, 0, line1 + num_lines, 0L, false);
@@ -1032,7 +1058,7 @@ int do_move(linenr_T line1, linenr_T line2, linenr_T dest)
void ex_copy(linenr_T line1, linenr_T line2, linenr_T n)
{
linenr_T count;
- char_u *p;
+ char_u *p;
count = line2 - line1 + 1;
curbuf->b_op_start.lnum = n + 1;
@@ -1050,8 +1076,9 @@ void ex_copy(linenr_T line1, linenr_T line2, linenr_T n)
* line1 = start of source (while copying)
* line2 = end of source (while copying)
*/
- if (u_save(n, n + 1) == FAIL)
+ if (u_save(n, n + 1) == FAIL) {
return;
+ }
curwin->w_cursor.lnum = n;
while (line1 <= line2) {
@@ -1061,14 +1088,17 @@ void ex_copy(linenr_T line1, linenr_T line2, linenr_T n)
ml_append(curwin->w_cursor.lnum, p, (colnr_T)0, false);
xfree(p);
- /* situation 2: skip already copied lines */
- if (line1 == n)
+ // situation 2: skip already copied lines
+ if (line1 == n) {
line1 = curwin->w_cursor.lnum;
+ }
++line1;
- if (curwin->w_cursor.lnum < line1)
+ if (curwin->w_cursor.lnum < line1) {
++line1;
- if (curwin->w_cursor.lnum < line2)
+ }
+ if (curwin->w_cursor.lnum < line2) {
++line2;
+ }
++curwin->w_cursor.lnum;
}
@@ -1077,7 +1107,7 @@ void ex_copy(linenr_T line1, linenr_T line2, linenr_T n)
msgmore((long)count);
}
-static char_u *prevcmd = NULL; /* the previous command */
+static char_u *prevcmd = NULL; // the previous command
#if defined(EXITFREE)
void free_prev_shellcmd(void)
@@ -1088,12 +1118,11 @@ void free_prev_shellcmd(void)
#endif
/*
- * Handle the ":!cmd" command. Also for ":r !cmd" and ":w !cmd"
+ * Handle the ":!cmd" command. Also for ":r !cmd" and ":w !cmd"
* Bangs in the argument are replaced with the previously entered command.
* Remember the argument.
*/
-void do_bang(int addr_count, exarg_T *eap, bool forceit,
- bool do_in, bool do_out)
+void do_bang(int addr_count, exarg_T *eap, bool forceit, bool do_in, bool do_out)
FUNC_ATTR_NONNULL_ALL
{
char_u *arg = eap->arg; // command
@@ -1101,9 +1130,9 @@ void do_bang(int addr_count, exarg_T *eap, bool forceit,
linenr_T line2 = eap->line2; // end of range
char_u *newcmd = NULL; // the new command
bool free_newcmd = false; // need to free() newcmd
- char_u *t;
- char_u *p;
- char_u *trailarg;
+ char_u *t;
+ char_u *p;
+ char_u *trailarg;
int len;
int scroll_save = msg_scroll;
@@ -1115,8 +1144,8 @@ void do_bang(int addr_count, exarg_T *eap, bool forceit,
return;
}
- if (addr_count == 0) { /* :! */
- msg_scroll = FALSE; /* don't scroll here */
+ if (addr_count == 0) { // :!
+ msg_scroll = FALSE; // don't scroll here
autowrite_all();
msg_scroll = scroll_save;
}
@@ -1129,8 +1158,9 @@ void do_bang(int addr_count, exarg_T *eap, bool forceit,
trailarg = arg;
do {
len = (int)STRLEN(trailarg) + 1;
- if (newcmd != NULL)
+ if (newcmd != NULL) {
len += (int)STRLEN(newcmd);
+ }
if (ins_prevcmd) {
if (prevcmd == NULL) {
EMSG(_(e_noprev));
@@ -1141,10 +1171,12 @@ void do_bang(int addr_count, exarg_T *eap, bool forceit,
}
t = xmalloc(len);
*t = NUL;
- if (newcmd != NULL)
+ if (newcmd != NULL) {
STRCAT(t, newcmd);
- if (ins_prevcmd)
+ }
+ if (ins_prevcmd) {
STRCAT(t, prevcmd);
+ }
p = t + STRLEN(t);
STRCAT(t, trailarg);
xfree(newcmd);
@@ -1157,9 +1189,9 @@ void do_bang(int addr_count, exarg_T *eap, bool forceit,
trailarg = NULL;
while (*p) {
if (*p == '!') {
- if (p > newcmd && p[-1] == '\\')
+ if (p > newcmd && p[-1] == '\\') {
STRMOVE(p - 1, p);
- else {
+ } else {
trailarg = p;
*trailarg++ = NUL;
ins_prevcmd = true;
@@ -1173,7 +1205,7 @@ void do_bang(int addr_count, exarg_T *eap, bool forceit,
xfree(prevcmd);
prevcmd = newcmd;
- if (bangredo) { /* put cmd in redo buffer for ! command */
+ if (bangredo) { // put cmd in redo buffer for ! command
/* If % or # appears in the command, it must have been escaped.
* Reescape them, so that redoing them does not substitute them by the
* buffername. */
@@ -1194,8 +1226,8 @@ void do_bang(int addr_count, exarg_T *eap, bool forceit,
STRCAT(newcmd, p_shq);
free_newcmd = true;
}
- if (addr_count == 0) { /* :! */
- /* echo the command */
+ if (addr_count == 0) { // :!
+ // echo the command
msg_start();
msg_putchar(':');
msg_putchar('!');
@@ -1204,49 +1236,48 @@ void do_bang(int addr_count, exarg_T *eap, bool forceit,
ui_cursor_goto(msg_row, msg_col);
do_shell(newcmd, 0);
- } else { /* :range! */
+ } else { // :range!
/* Careful: This may recursively call do_bang() again! (because of
* autocommands) */
do_filter(line1, line2, eap, newcmd, do_in, do_out);
- apply_autocmds(EVENT_SHELLFILTERPOST, NULL, NULL, FALSE, curbuf);
+ apply_autocmds(EVENT_SHELLFILTERPOST, NULL, NULL, false, curbuf);
}
- if (free_newcmd)
+ if (free_newcmd) {
xfree(newcmd);
+ }
}
-// do_filter: filter lines through a command given by the user
-//
-// We mostly use temp files and the call_shell() routine here. This would
-// normally be done using pipes on a Unix system, but this is more portable
-// to non-Unix systems. The call_shell() routine needs to be able
-// to deal with redirection somehow, and should handle things like looking
-// at the PATH env. variable, and adding reasonable extensions to the
-// command name given by the user. All reasonable versions of call_shell()
-// do this.
-// Alternatively, if on Unix and redirecting input or output, but not both,
-// and the 'shelltemp' option isn't set, use pipes.
-// We use input redirection if do_in is true.
-// We use output redirection if do_out is true.
-static void do_filter(
- linenr_T line1,
- linenr_T line2,
- exarg_T *eap, /* for forced 'ff' and 'fenc' */
- char_u *cmd,
- bool do_in,
- bool do_out)
+/// do_filter: filter lines through a command given by the user
+///
+/// We mostly use temp files and the call_shell() routine here. This would
+/// normally be done using pipes on a Unix system, but this is more portable
+/// to non-Unix systems. The call_shell() routine needs to be able
+/// to deal with redirection somehow, and should handle things like looking
+/// at the PATH env. variable, and adding reasonable extensions to the
+/// command name given by the user. All reasonable versions of call_shell()
+/// do this.
+/// Alternatively, if on Unix and redirecting input or output, but not both,
+/// and the 'shelltemp' option isn't set, use pipes.
+/// We use input redirection if do_in is true.
+/// We use output redirection if do_out is true.
+///
+/// @param eap for forced 'ff' and 'fenc'
+static void do_filter(linenr_T line1, linenr_T line2, exarg_T *eap, char_u *cmd, bool do_in,
+ bool do_out)
{
- char_u *itmp = NULL;
- char_u *otmp = NULL;
+ char_u *itmp = NULL;
+ char_u *otmp = NULL;
linenr_T linecount;
linenr_T read_linecount;
pos_T cursor_save;
- char_u *cmd_buf;
- buf_T *old_curbuf = curbuf;
+ char_u *cmd_buf;
+ buf_T *old_curbuf = curbuf;
int shell_flags = 0;
const int stmp = p_stmp;
- if (*cmd == NUL) /* no filter command */
+ if (*cmd == NUL) { // no filter command
return;
+ }
cursor_save = curwin->w_cursor;
@@ -1269,8 +1300,9 @@ static void do_filter(
* pipe only need to do 3.
*/
- if (do_out)
+ if (do_out) {
shell_flags |= kShellOptDoOut;
+ }
if (!do_in && do_out && !stmp) {
// Use a pipe to fetch stdout of the command, do not use a temp file.
@@ -1289,7 +1321,7 @@ static void do_filter(
curbuf->b_op_end.lnum = line2;
curwin->w_cursor.lnum = line2;
} else if ((do_in && (itmp = vim_tempname()) == NULL)
- || (do_out && (otmp = vim_tempname()) == NULL)) {
+ || (do_out && (otmp = vim_tempname()) == NULL)) {
EMSG(_(e_notmp));
goto filterend;
}
@@ -1298,7 +1330,7 @@ static void do_filter(
* The writing and reading of temp files will not be shown.
* Vi also doesn't do this and the messages are not very informative.
*/
- ++no_wait_return; /* don't call wait_return() while busy */
+ ++no_wait_return; // don't call wait_return() while busy
if (itmp != NULL && buf_write(curbuf, itmp, NULL, line1, line2, eap,
false, false, false, true) == FAIL) {
msg_putchar('\n'); // Keep message from buf_write().
@@ -1308,18 +1340,20 @@ static void do_filter(
}
goto filterend;
}
- if (curbuf != old_curbuf)
+ if (curbuf != old_curbuf) {
goto filterend;
+ }
- if (!do_out)
+ if (!do_out) {
msg_putchar('\n');
+ }
- /* Create the shell command in allocated memory. */
+ // Create the shell command in allocated memory.
cmd_buf = make_filter_cmd(cmd, itmp, otmp);
ui_cursor_goto(Rows - 1, 0);
if (do_out) {
- if (u_save((linenr_T)(line2), (linenr_T)(line2 + 1)) == FAIL) {
+ if (u_save((line2), (linenr_T)(line2 + 1)) == FAIL) {
xfree(cmd_buf);
goto error;
}
@@ -1350,8 +1384,9 @@ static void do_filter(
}
goto error;
}
- if (curbuf != old_curbuf)
+ if (curbuf != old_curbuf) {
goto filterend;
+ }
}
read_linecount = curbuf->b_ml.ml_line_count - read_linecount;
@@ -1385,11 +1420,11 @@ static void do_filter(
* Adjust '[ and '] (set by buf_write()).
*/
curwin->w_cursor.lnum = line1;
- del_lines(linecount, TRUE);
- curbuf->b_op_start.lnum -= linecount; /* adjust '[ */
- curbuf->b_op_end.lnum -= linecount; /* adjust '] */
- write_lnum_adjust(-linecount); /* adjust last line
- for next write */
+ del_lines(linecount, true);
+ curbuf->b_op_start.lnum -= linecount; // adjust '[
+ curbuf->b_op_end.lnum -= linecount; // adjust ']
+ write_lnum_adjust(-linecount); // adjust last line
+ // for next write
foldUpdate(curwin, curbuf->b_op_start.lnum, curbuf->b_op_end.lnum);
} else {
/*
@@ -1399,22 +1434,24 @@ static void do_filter(
curwin->w_cursor.lnum = curbuf->b_op_end.lnum;
}
- beginline(BL_WHITE | BL_FIX); /* cursor on first non-blank */
+ beginline(BL_WHITE | BL_FIX); // cursor on first non-blank
--no_wait_return;
if (linecount > p_report) {
if (do_in) {
vim_snprintf((char *)msg_buf, sizeof(msg_buf),
- _("%" PRId64 " lines filtered"), (int64_t)linecount);
- if (msg(msg_buf) && !msg_scroll)
- /* save message to display it after redraw */
+ _("%" PRId64 " lines filtered"), (int64_t)linecount);
+ if (msg(msg_buf) && !msg_scroll) {
+ // save message to display it after redraw
set_keep_msg(msg_buf, 0);
- } else
+ }
+ } else {
msgmore((long)linecount);
+ }
}
} else {
error:
- /* put cursor back in same position for ":w !cmd" */
+ // put cursor back in same position for ":w !cmd"
curwin->w_cursor = cursor_save;
--no_wait_return;
wait_return(FALSE);
@@ -1426,21 +1463,21 @@ filterend:
--no_wait_return;
EMSG(_("E135: *Filter* Autocommands must not change current buffer"));
}
- if (itmp != NULL)
+ if (itmp != NULL) {
os_remove((char *)itmp);
- if (otmp != NULL)
+ }
+ if (otmp != NULL) {
os_remove((char *)otmp);
+ }
xfree(itmp);
xfree(otmp);
}
-// Call a shell to execute a command.
-// When "cmd" is NULL start an interactive shell.
-void
-do_shell(
- char_u *cmd,
- int flags // may be SHELL_DOOUT when output is redirected
-)
+/// Call a shell to execute a command.
+/// When "cmd" is NULL start an interactive shell.
+///
+/// @param flags may be SHELL_DOOUT when output is redirected
+void do_shell(char_u *cmd, int flags)
{
// Disallow shell commands from .exrc and .vimrc in current directory for
// security reasons.
@@ -1482,7 +1519,7 @@ do_shell(
msg_row = Rows - 1;
msg_col = 0;
- apply_autocmds(EVENT_SHELLCMDPOST, NULL, NULL, FALSE, curbuf);
+ apply_autocmds(EVENT_SHELLCMDPOST, NULL, NULL, false, curbuf);
}
#if !defined(UNIX)
@@ -1522,11 +1559,11 @@ char_u *make_filter_cmd(char_u *cmd, char_u *itmp, char_u *otmp)
size_t len = STRLEN(cmd) + 1; // At least enough space for cmd + NULL.
- len += is_fish_shell ? sizeof("begin; ""; end") - 1
- : sizeof("("")") - 1;
+ len += is_fish_shell ? sizeof("begin; " "; end") - 1
+ : sizeof("(" ")") - 1;
if (itmp != NULL) {
- len += STRLEN(itmp) + sizeof(" { "" < "" } ") - 1;
+ len += STRLEN(itmp) + sizeof(" { " " < " " } ") - 1;
}
if (otmp != NULL) {
len += STRLEN(otmp) + STRLEN(p_srr) + 2; // two extra spaces (" "),
@@ -1574,9 +1611,9 @@ char_u *make_filter_cmd(char_u *cmd, char_u *itmp, char_u *otmp)
}
#endif
if (otmp != NULL) {
- append_redir(buf, len, (char *) p_srr, (char *) otmp);
+ append_redir(buf, len, (char *)p_srr, (char *)otmp);
}
- return (char_u *) buf;
+ return (char_u *)buf;
}
/// Append output redirection for the given file to the end of the buffer
@@ -1588,8 +1625,8 @@ char_u *make_filter_cmd(char_u *cmd, char_u *itmp, char_u *otmp)
/// a space, opt, a space and then fname if `%s` is not found
/// there.
/// @param[in] fname File name to append.
-void append_redir(char *const buf, const size_t buflen,
- const char *const opt, const char *const fname)
+void append_redir(char *const buf, const size_t buflen, const char *const opt,
+ const char *const fname)
{
char *const end = buf + strlen(buf);
// find "%s"
@@ -1603,9 +1640,9 @@ void append_redir(char *const buf, const size_t buflen,
}
if (p != NULL) {
*end = ' '; // not really needed? Not with sh, ksh or bash
- vim_snprintf(end + 1, (size_t) (buflen - (end + 1 - buf)), opt, fname);
+ vim_snprintf(end + 1, (size_t)(buflen - (end + 1 - buf)), opt, fname);
} else {
- vim_snprintf(end, (size_t) (buflen - (end - buf)), " %s %s", opt, fname);
+ vim_snprintf(end, (size_t)(buflen - (end - buf)), " %s %s", opt, fname);
}
}
@@ -1635,28 +1672,30 @@ void print_line(linenr_T lnum, int use_number, int list)
msg_start();
silent_mode = FALSE;
- info_message = TRUE; /* use mch_msg(), not mch_errmsg() */
+ info_message = true; // use mch_msg(), not mch_errmsg()
print_line_no_prefix(lnum, use_number, list);
if (save_silent) {
msg_putchar('\n');
ui_flush();
silent_mode = save_silent;
}
- info_message = FALSE;
+ info_message = false;
}
int rename_buffer(char_u *new_fname)
{
- char_u *fname, *sfname, *xfname;
- buf_T *buf;
+ char_u *fname, *sfname, *xfname;
+ buf_T *buf;
buf = curbuf;
- apply_autocmds(EVENT_BUFFILEPRE, NULL, NULL, FALSE, curbuf);
- /* buffer changed, don't change name now */
- if (buf != curbuf)
+ apply_autocmds(EVENT_BUFFILEPRE, NULL, NULL, false, curbuf);
+ // buffer changed, don't change name now
+ if (buf != curbuf) {
return FAIL;
- if (aborting()) /* autocmds may abort script processing */
+ }
+ if (aborting()) { // autocmds may abort script processing
return FAIL;
+ }
/*
* The name of the current buffer will be changed.
* A new (unlisted) buffer entry needs to be made to hold the old file
@@ -1683,8 +1722,8 @@ int rename_buffer(char_u *new_fname)
}
xfree(fname);
xfree(sfname);
- apply_autocmds(EVENT_BUFFILEPOST, NULL, NULL, FALSE, curbuf);
- /* Change directories when the 'acd' option is set. */
+ apply_autocmds(EVENT_BUFFILEPOST, NULL, NULL, false, curbuf);
+ // Change directories when the 'acd' option is set.
do_autochdir();
return OK;
}
@@ -1722,8 +1761,9 @@ void ex_file(exarg_T *eap)
*/
void ex_update(exarg_T *eap)
{
- if (curbufIsChanged())
+ if (curbufIsChanged()) {
(void)do_write(eap);
+ }
}
/*
@@ -1755,15 +1795,16 @@ void ex_write(exarg_T *eap)
int do_write(exarg_T *eap)
{
int other;
- char_u *fname = NULL; /* init to shut up gcc */
- char_u *ffname;
+ char_u *fname = NULL; // init to shut up gcc
+ char_u *ffname;
int retval = FAIL;
- char_u *free_fname = NULL;
- buf_T *alt_buf = NULL;
- int name_was_missing;
+ char_u *free_fname = NULL;
+ buf_T *alt_buf = NULL;
+ int name_was_missing;
- if (not_writing()) /* check 'write' option */
+ if (not_writing()) { // check 'write' option
return FAIL;
+ }
ffname = eap->arg;
if (*ffname == NUL) {
@@ -1779,8 +1820,9 @@ int do_write(exarg_T *eap)
* When out-of-memory, keep unexpanded file name, because we MUST be
* able to write the file in this situation.
*/
- if (free_fname != NULL)
+ if (free_fname != NULL) {
ffname = free_fname;
+ }
other = otherfile(ffname);
}
@@ -1789,10 +1831,11 @@ int do_write(exarg_T *eap)
*/
if (other) {
if (vim_strchr(p_cpo, CPO_ALTWRITE) != NULL
- || eap->cmdidx == CMD_saveas)
+ || eap->cmdidx == CMD_saveas) {
alt_buf = setaltfname(ffname, fname, (linenr_T)1);
- else
+ } else {
alt_buf = buflist_findname(ffname);
+ }
if (alt_buf != NULL && alt_buf->b_ml.ml_mfp != NULL) {
/* Overwriting a file that is loaded in another buffer is not a
* good idea. */
@@ -1823,8 +1866,9 @@ int do_write(exarg_T *eap)
&& !p_wa) {
if (p_confirm || cmdmod.confirm) {
if (vim_dialog_yesno(VIM_QUESTION, NULL,
- (char_u *)_("Write partial file?"), 2) != VIM_YES)
+ (char_u *)_("Write partial file?"), 2) != VIM_YES) {
goto theend;
+ }
eap->forceit = TRUE;
} else {
EMSG(_("E140: Use ! to write partial buffer"));
@@ -1835,12 +1879,12 @@ int do_write(exarg_T *eap)
if (check_overwrite(eap, curbuf, fname, ffname, other) == OK) {
if (eap->cmdidx == CMD_saveas && alt_buf != NULL) {
- buf_T *was_curbuf = curbuf;
+ buf_T *was_curbuf = curbuf;
- apply_autocmds(EVENT_BUFFILEPRE, NULL, NULL, FALSE, curbuf);
- apply_autocmds(EVENT_BUFFILEPRE, NULL, NULL, FALSE, alt_buf);
+ apply_autocmds(EVENT_BUFFILEPRE, NULL, NULL, false, curbuf);
+ apply_autocmds(EVENT_BUFFILEPRE, NULL, NULL, false, alt_buf);
if (curbuf != was_curbuf || aborting()) {
- /* buffer changed, don't change name now */
+ // buffer changed, don't change name now
retval = FAIL;
goto theend;
}
@@ -1859,14 +1903,14 @@ int do_write(exarg_T *eap)
alt_buf->b_sfname = curbuf->b_sfname;
curbuf->b_sfname = fname;
buf_name_changed(curbuf);
- apply_autocmds(EVENT_BUFFILEPOST, NULL, NULL, FALSE, curbuf);
- apply_autocmds(EVENT_BUFFILEPOST, NULL, NULL, FALSE, alt_buf);
+ apply_autocmds(EVENT_BUFFILEPOST, NULL, NULL, false, curbuf);
+ apply_autocmds(EVENT_BUFFILEPOST, NULL, NULL, false, alt_buf);
if (!alt_buf->b_p_bl) {
alt_buf->b_p_bl = TRUE;
apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, alt_buf);
}
if (curbuf != was_curbuf || aborting()) {
- /* buffer changed, don't write the file */
+ // buffer changed, don't write the file
retval = FAIL;
goto theend;
}
@@ -1886,13 +1930,13 @@ int do_write(exarg_T *eap)
name_was_missing = curbuf->b_ffname == NULL;
retval = buf_write(curbuf, ffname, fname, eap->line1, eap->line2,
- eap, eap->append, eap->forceit, TRUE, FALSE);
+ eap, eap->append, eap->forceit, TRUE, FALSE);
- /* After ":saveas fname" reset 'readonly'. */
+ // After ":saveas fname" reset 'readonly'.
if (eap->cmdidx == CMD_saveas) {
if (retval == OK) {
curbuf->b_p_ro = FALSE;
- redraw_tabline = TRUE;
+ redraw_tabline = true;
}
}
@@ -1908,21 +1952,16 @@ theend:
return retval;
}
-/*
- * Check if it is allowed to overwrite a file. If b_flags has BF_NOTEDITED,
- * BF_NEW or BF_READERR, check for overwriting current file.
- * May set eap->forceit if a dialog says it's OK to overwrite.
- * Return OK if it's OK, FAIL if it is not.
- */
-int
-check_overwrite(
- exarg_T *eap,
- buf_T *buf,
- char_u *fname, // file name to be used (can differ from
- // buf->ffname)
- char_u *ffname, // full path version of fname
- int other // writing under other name
-)
+/// Check if it is allowed to overwrite a file. If b_flags has BF_NOTEDITED,
+/// BF_NEW or BF_READERR, check for overwriting current file.
+/// May set eap->forceit if a dialog says it's OK to overwrite.
+///
+/// @param fname file name to be used (can differ from buf->ffname)
+/// @param ffname full path version of fname
+/// @param other writing under other name
+///
+/// @return OK if it's OK, FAIL if it is not.
+int check_overwrite(exarg_T *eap, buf_T *buf, char_u *fname, char_u *ffname, int other)
{
/*
* write to other file or b_flags set or not writing the whole file:
@@ -1948,8 +1987,9 @@ check_overwrite(
char_u buff[DIALOG_MSG_SIZE];
dialog_msg(buff, _("Overwrite existing file \"%s\"?"), fname);
- if (vim_dialog_yesno(VIM_QUESTION, NULL, buff, 2) != VIM_YES)
+ if (vim_dialog_yesno(VIM_QUESTION, NULL, buff, 2) != VIM_YES) {
return FAIL;
+ }
eap->forceit = TRUE;
} else {
EMSG(_(e_exists));
@@ -1957,11 +1997,11 @@ check_overwrite(
}
}
- /* For ":w! filename" check that no swap file exists for "filename". */
+ // For ":w! filename" check that no swap file exists for "filename".
if (other && !emsg_silent) {
- char_u *dir;
- char_u *p;
- char_u *swapname;
+ char_u *dir;
+ char_u *p;
+ char_u *swapname;
/* We only try the first entry in 'directory', without checking if
* it's writable. If the "." directory is not writable the write
@@ -1983,8 +2023,8 @@ check_overwrite(
char_u buff[DIALOG_MSG_SIZE];
dialog_msg(buff,
- _("Swap file \"%s\" exists, overwrite anyway?"),
- swapname);
+ _("Swap file \"%s\" exists, overwrite anyway?"),
+ swapname);
if (vim_dialog_yesno(VIM_QUESTION, NULL, buff, 2)
!= VIM_YES) {
xfree(swapname);
@@ -1993,7 +2033,7 @@ check_overwrite(
eap->forceit = TRUE;
} else {
EMSG2(_("E768: Swap file exists: %s (:silent! overrides)"),
- swapname);
+ swapname);
xfree(swapname);
return FAIL;
}
@@ -2011,14 +2051,16 @@ void ex_wnext(exarg_T *eap)
{
int i;
- if (eap->cmd[1] == 'n')
+ if (eap->cmd[1] == 'n') {
i = curwin->w_arg_idx + (int)eap->line2;
- else
+ } else {
i = curwin->w_arg_idx - (int)eap->line2;
+ }
eap->line1 = 1;
eap->line2 = curbuf->b_ml.ml_line_count;
- if (do_write(eap) != FAIL)
+ if (do_write(eap) != FAIL) {
do_argfile(eap, i);
+ }
}
/*
@@ -2058,7 +2100,7 @@ void do_wqall(exarg_T *eap)
++error;
} else if (check_readonly(&eap->forceit, buf)
|| check_overwrite(eap, buf, buf->b_fname, buf->b_ffname,
- FALSE) == FAIL) {
+ FALSE) == FAIL) {
++error;
} else {
bufref_T bufref;
@@ -2071,11 +2113,12 @@ void do_wqall(exarg_T *eap)
buf = firstbuf;
}
}
- eap->forceit = save_forceit; /* check_overwrite() may set it */
+ eap->forceit = save_forceit; // check_overwrite() may set it
}
if (exiting) {
- if (!error)
- getout(0); /* exit Vim */
+ if (!error) {
+ getout(0); // exit Vim
+ }
not_exiting();
}
}
@@ -2086,8 +2129,9 @@ void do_wqall(exarg_T *eap)
*/
int not_writing(void)
{
- if (p_write)
+ if (p_write) {
return FALSE;
+ }
EMSG(_("E142: File not written: Writing is disabled by 'write' option"));
return TRUE;
}
@@ -2107,28 +2151,30 @@ static int check_readonly(int *forceit, buf_T *buf)
if ((p_confirm || cmdmod.confirm) && buf->b_fname != NULL) {
char_u buff[DIALOG_MSG_SIZE];
- if (buf->b_p_ro)
+ if (buf->b_p_ro) {
dialog_msg(buff,
- _(
- "'readonly' option is set for \"%s\".\nDo you wish to write anyway?"),
- buf->b_fname);
- else
+ _( "'readonly' option is set for \"%s\".\nDo you wish to write anyway?"),
+ buf->b_fname);
+ } else {
dialog_msg(buff,
- _(
- "File permissions of \"%s\" are read-only.\nIt may still be possible to write it.\nDo you wish to try?"),
- buf->b_fname);
+ _(
+ "File permissions of \"%s\" are read-only.\nIt may still be possible to write it.\nDo you wish to try?"),
+ buf->b_fname);
+ }
if (vim_dialog_yesno(VIM_QUESTION, NULL, buff, 2) == VIM_YES) {
- /* Set forceit, to force the writing of a readonly file */
+ // Set forceit, to force the writing of a readonly file
*forceit = TRUE;
return FALSE;
- } else
+ } else {
return TRUE;
- } else if (buf->b_p_ro)
+ }
+ } else if (buf->b_p_ro) {
EMSG(_(e_readonly));
- else
+ } else {
EMSG2(_("E505: \"%s\" is read-only (add ! to override)"),
- buf->b_fname);
+ buf->b_fname);
+ }
return TRUE;
}
@@ -2144,14 +2190,13 @@ static int check_readonly(int *forceit, buf_T *buf)
// GETFILE_NOT_WRITTEN for "not written" error,
// GETFILE_SAME_FILE for success
// GETFILE_OPEN_OTHER for successfully opening another file.
-int getfile(int fnum, char_u *ffname_arg, char_u *sfname_arg, int setpm,
- linenr_T lnum, int forceit)
+int getfile(int fnum, char_u *ffname_arg, char_u *sfname_arg, int setpm, linenr_T lnum, int forceit)
{
char_u *ffname = ffname_arg;
char_u *sfname = sfname_arg;
int other;
int retval;
- char_u *free_me = NULL;
+ char_u *free_me = NULL;
if (text_locked()) {
return GETFILE_ERROR;
@@ -2161,12 +2206,13 @@ int getfile(int fnum, char_u *ffname_arg, char_u *sfname_arg, int setpm,
}
if (fnum == 0) {
- /* make ffname full path, set sfname */
+ // make ffname full path, set sfname
fname_expand(curbuf, &ffname, &sfname);
other = otherfile(ffname);
- free_me = ffname; /* has been allocated, free() later */
- } else
+ free_me = ffname; // has been allocated, free() later
+ } else {
other = (fnum != curbuf->b_fnum);
+ }
if (other) {
no_wait_return++; // don't wait for autowrite message
@@ -2183,10 +2229,12 @@ int getfile(int fnum, char_u *ffname_arg, char_u *sfname_arg, int setpm,
goto theend;
}
}
- if (other)
+ if (other) {
--no_wait_return;
- if (setpm)
+ }
+ if (setpm) {
setpcmark();
+ }
if (!other) {
if (lnum != 0) {
curwin->w_cursor.lnum = lnum;
@@ -2218,7 +2266,7 @@ theend:
/// - NULL to start an empty buffer
/// @param sfname the short file name (or NULL)
/// @param eap contains the command to be executed after loading the file
-/// and forced 'ff' and 'fenc'
+/// and forced 'ff' and 'fenc'. Can be NULL!
/// @param newlnum if > 0: put cursor on this line number (if possible)
/// ECMD_LASTL: use last position in loaded file
/// ECMD_LAST: use last position in all files
@@ -2236,55 +2284,52 @@ theend:
/// info of the previous buffer for "oldwin" is stored.
///
/// @return FAIL for failure, OK otherwise
-int do_ecmd(
- int fnum,
- char_u *ffname,
- char_u *sfname,
- exarg_T *eap, /* can be NULL! */
- linenr_T newlnum,
- int flags,
- win_T *oldwin
-)
+int do_ecmd(int fnum, char_u *ffname, char_u *sfname, exarg_T *eap, linenr_T newlnum, int flags,
+ win_T *oldwin)
{
- int other_file; /* TRUE if editing another file */
- int oldbuf; /* TRUE if using existing buffer */
- int auto_buf = FALSE; /* TRUE if autocommands brought us
- into the buffer unexpectedly */
- char_u *new_name = NULL;
- int did_set_swapcommand = FALSE;
- buf_T *buf;
- bufref_T bufref;
- bufref_T old_curbuf;
- char_u *free_fname = NULL;
+ bool other_file; // true if editing another file
+ int oldbuf; // TRUE if using existing buffer
+ bool auto_buf = false; // true if autocommands brought us
+ // into the buffer unexpectedly
+ char_u *new_name = NULL;
+ bool did_set_swapcommand = false;
+ buf_T *buf;
+ bufref_T bufref;
+ bufref_T old_curbuf;
+ char_u *free_fname = NULL;
int retval = FAIL;
long n;
pos_T orig_pos;
linenr_T topline = 0;
int newcol = -1;
int solcol = -1;
- pos_T *pos;
- char_u *command = NULL;
- int did_get_winopts = FALSE;
+ pos_T *pos;
+ char_u *command = NULL;
+ bool did_get_winopts = false;
int readfile_flags = 0;
bool did_inc_redrawing_disabled = false;
long *so_ptr = curwin->w_p_so >= 0 ? &curwin->w_p_so : &p_so;
- if (eap != NULL)
+ if (eap != NULL) {
command = eap->do_ecmd_cmd;
+ }
set_bufref(&old_curbuf, curbuf);
if (fnum != 0) {
- if (fnum == curbuf->b_fnum) /* file is already being edited */
- return OK; /* nothing to do */
- other_file = TRUE;
+ if (fnum == curbuf->b_fnum) { // file is already being edited
+ return OK; // nothing to do
+ }
+ other_file = true;
} else {
- /* if no short name given, use ffname for short name */
- if (sfname == NULL)
+ // if no short name given, use ffname for short name
+ if (sfname == NULL) {
sfname = ffname;
+ }
#ifdef USE_FNAME_CASE
- if (sfname != NULL)
+ if (sfname != NULL) {
path_fix_case(sfname); // set correct case for sfname
+ }
#endif
if ((flags & (ECMD_ADDBUF | ECMD_ALTBUF))
@@ -2292,19 +2337,19 @@ int do_ecmd(
goto theend;
}
- if (ffname == NULL)
- other_file = TRUE;
- /* there is no file name */
- else if (*ffname == NUL && curbuf->b_ffname == NULL)
- other_file = FALSE;
- else {
- if (*ffname == NUL) { /* re-edit with same file name */
+ if (ffname == NULL) {
+ other_file = true;
+ } else if (*ffname == NUL && curbuf->b_ffname == NULL) { // there is no file name
+ other_file = false;
+ } else {
+ if (*ffname == NUL) { // re-edit with same file name
ffname = curbuf->b_ffname;
sfname = curbuf->b_fname;
}
- free_fname = (char_u *)fix_fname((char *)ffname); /* may expand to full path name */
- if (free_fname != NULL)
+ free_fname = (char_u *)fix_fname((char *)ffname); // may expand to full path name
+ if (free_fname != NULL) {
ffname = free_fname;
+ }
other_file = otherfile(ffname);
}
}
@@ -2350,7 +2395,7 @@ int do_ecmd(
vim_snprintf(p, len, "%" PRId64 "G", (int64_t)newlnum);
}
set_vim_var_string(VV_SWAPCOMMAND, p, -1);
- did_set_swapcommand = TRUE;
+ did_set_swapcommand = true;
xfree(p);
}
@@ -2378,13 +2423,14 @@ int do_ecmd(
if (command != NULL) {
tlnum = atol((char *)command);
- if (tlnum <= 0)
+ if (tlnum <= 0) {
tlnum = 1L;
+ }
}
// Add BLN_NOCURWIN to avoid a new wininfo items are associated
// with the current window.
const buf_T *const newbuf
- = buflist_new(ffname, sfname, tlnum, BLN_LISTED | BLN_NOCURWIN);
+ = buflist_new(ffname, sfname, tlnum, BLN_LISTED | BLN_NOCURWIN);
if (newbuf != NULL && (flags & ECMD_ALTBUF)) {
curwin->w_alt_fnum = newbuf->b_fnum;
}
@@ -2398,8 +2444,9 @@ int do_ecmd(
}
set_bufref(&old_curbuf, curbuf);
}
- if (buf == NULL)
+ if (buf == NULL) {
goto theend;
+ }
if (buf->b_ml.ml_mfp == NULL) {
// No memfile yet.
oldbuf = false;
@@ -2458,7 +2505,7 @@ int do_ecmd(
delbuf_msg(new_name); // Frees new_name.
goto theend;
}
- if (aborting()) { /* autocmds may abort script processing */
+ if (aborting()) { // autocmds may abort script processing
xfree(new_name);
goto theend;
}
@@ -2480,10 +2527,9 @@ int do_ecmd(
// Close the link to the current buffer. This will set
// oldwin->w_buffer to NULL.
u_sync(false);
- const bool did_decrement = close_buffer(
- oldwin, curbuf,
- (flags & ECMD_HIDE) || curbuf->terminal ? 0 : DOBUF_UNLOAD,
- false);
+ const bool did_decrement = close_buffer(oldwin, curbuf,
+ (flags & ECMD_HIDE) || curbuf->terminal ? 0 : DOBUF_UNLOAD,
+ false);
// Autocommands may have closed the window.
if (win_valid(the_curwin)) {
@@ -2524,7 +2570,7 @@ int do_ecmd(
curbuf = buf;
++curbuf->b_nwindows;
- /* Set 'fileformat', 'binary' and 'fenc' when forced. */
+ // Set 'fileformat', 'binary' and 'fenc' when forced.
if (!oldbuf && eap != NULL) {
set_file_options(TRUE, eap);
set_forced_fenc(eap);
@@ -2536,8 +2582,7 @@ int do_ecmd(
* before, reset the local window options to the global
* values. Also restores old folding stuff. */
get_winopts(curbuf);
- did_get_winopts = TRUE;
-
+ did_get_winopts = true;
}
xfree(new_name);
au_new_curbuf.br_buf = NULL;
@@ -2569,10 +2614,12 @@ int do_ecmd(
/* If autocommands change buffers under our fingers, forget about
* editing the file. */
- if (buf != curbuf)
+ if (buf != curbuf) {
goto theend;
- if (aborting()) /* autocmds may abort script processing */
+ }
+ if (aborting()) { // autocmds may abort script processing
goto theend;
+ }
/* Since we are starting to edit a file, consider the filetype to be
* unset. Helps for when an autocommand changes files and expects syntax
@@ -2580,14 +2627,14 @@ int do_ecmd(
did_filetype = FALSE;
/*
- * other_file oldbuf
- * FALSE FALSE re-edit same file, buffer is re-used
- * FALSE TRUE re-edit same file, nothing changes
- * TRUE FALSE start editing new file, new buffer
- * TRUE TRUE start editing in existing buffer (nothing to do)
+ * other_file oldbuf
+ * FALSE FALSE re-edit same file, buffer is re-used
+ * FALSE TRUE re-edit same file, nothing changes
+ * TRUE FALSE start editing new file, new buffer
+ * TRUE TRUE start editing in existing buffer (nothing to do)
*/
- if (!other_file && !oldbuf) { /* re-use the buffer */
- set_last_cursor(curwin); /* may set b_last_cursor */
+ if (!other_file && !oldbuf) { // re-use the buffer
+ set_last_cursor(curwin); // may set b_last_cursor
if (newlnum == ECMD_LAST || newlnum == ECMD_LASTL) {
newlnum = curwin->w_cursor.lnum;
solcol = curwin->w_cursor.col;
@@ -2607,7 +2654,7 @@ int do_ecmd(
&& (p_ur < 0 || curbuf->b_ml.ml_line_count <= p_ur)) {
// Sync first so that this is a separate undo-able action.
u_sync(false);
- if (u_savecommon(0, curbuf->b_ml.ml_line_count + 1, 0, true)
+ if (u_savecommon(curbuf, 0, curbuf->b_ml.ml_line_count + 1, 0, true)
== FAIL) {
xfree(new_name);
goto theend;
@@ -2633,12 +2680,14 @@ int do_ecmd(
/* If autocommands change buffers under our fingers, forget about
* re-editing the file. Should do the buf_clear_file(), but perhaps
* the autocommands changed the buffer... */
- if (buf != curbuf)
+ if (buf != curbuf) {
goto theend;
- if (aborting()) /* autocmds may abort script processing */
+ }
+ if (aborting()) { // autocmds may abort script processing
goto theend;
+ }
buf_clear_file(curbuf);
- curbuf->b_op_start.lnum = 0; /* clear '[ and '] marks */
+ curbuf->b_op_start.lnum = 0; // clear '[ and '] marks
curbuf->b_op_end.lnum = 0;
}
@@ -2646,7 +2695,7 @@ int do_ecmd(
* If we get here we are sure to start editing
*/
- /* Assume success now */
+ // Assume success now
retval = OK;
/*
@@ -2670,7 +2719,7 @@ int do_ecmd(
}
}
- /* Change directories when the 'acd' option is set. */
+ // Change directories when the 'acd' option is set.
do_autochdir();
/*
@@ -2679,18 +2728,20 @@ int do_ecmd(
*/
orig_pos = curwin->w_cursor;
topline = curwin->w_topline;
- if (!oldbuf) { /* need to read the file */
+ if (!oldbuf) { // need to read the file
swap_exists_action = SEA_DIALOG;
- curbuf->b_flags |= BF_CHECK_RO; /* set/reset 'ro' flag */
+ curbuf->b_flags |= BF_CHECK_RO; // set/reset 'ro' flag
/*
* Open the buffer and read the file.
*/
- if (should_abort(open_buffer(FALSE, eap, readfile_flags)))
+ if (should_abort(open_buffer(FALSE, eap, readfile_flags))) {
retval = FAIL;
+ }
- if (swap_exists_action == SEA_QUIT)
+ if (swap_exists_action == SEA_QUIT) {
retval = FAIL;
+ }
handle_swap_exists(&old_curbuf);
} else {
/* Read the modelines, but only to set window-local options. Any
@@ -2699,9 +2750,9 @@ int do_ecmd(
do_modelines(OPT_WINONLY);
apply_autocmds_retval(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf,
- &retval);
+ &retval);
apply_autocmds_retval(EVENT_BUFWINENTER, NULL, NULL, FALSE, curbuf,
- &retval);
+ &retval);
}
check_arg_idx(curwin);
@@ -2717,10 +2768,11 @@ int do_ecmd(
newcol = curwin->w_cursor.col;
}
}
- if (curwin->w_topline == topline)
+ if (curwin->w_topline == topline) {
topline = 0;
+ }
- /* Even when cursor didn't move we need to recompute topline. */
+ // Even when cursor didn't move we need to recompute topline.
changed_line_abv_curs();
maketitle();
@@ -2736,68 +2788,74 @@ int do_ecmd(
/* If the window options were changed may need to set the spell language.
* Can only do this after the buffer has been properly setup. */
- if (did_get_winopts && curwin->w_p_spell && *curwin->w_s->b_p_spl != NUL)
+ if (did_get_winopts && curwin->w_p_spell && *curwin->w_s->b_p_spl != NUL) {
(void)did_set_spelllang(curwin);
+ }
if (command == NULL) {
- if (newcol >= 0) { /* position set by autocommands */
+ if (newcol >= 0) { // position set by autocommands
curwin->w_cursor.lnum = newlnum;
curwin->w_cursor.col = newcol;
check_cursor();
- } else if (newlnum > 0) { /* line number from caller or old position */
+ } else if (newlnum > 0) { // line number from caller or old position
curwin->w_cursor.lnum = newlnum;
check_cursor_lnum();
if (solcol >= 0 && !p_sol) {
- /* 'sol' is off: Use last known column. */
+ // 'sol' is off: Use last known column.
curwin->w_cursor.col = solcol;
check_cursor_col();
curwin->w_cursor.coladd = 0;
curwin->w_set_curswant = TRUE;
- } else
+ } else {
beginline(BL_SOL | BL_FIX);
- } else { /* no line number, go to last line in Ex mode */
- if (exmode_active)
+ }
+ } else { // no line number, go to last line in Ex mode
+ if (exmode_active) {
curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+ }
beginline(BL_WHITE | BL_FIX);
}
}
- /* Check if cursors in other windows on the same buffer are still valid */
- check_lnums(FALSE);
+ // Check if cursors in other windows on the same buffer are still valid
+ check_lnums(false);
/*
* Did not read the file, need to show some info about the file.
* Do this after setting the cursor.
*/
if (oldbuf
- && !auto_buf
- ) {
+ && !auto_buf) {
int msg_scroll_save = msg_scroll;
/* Obey the 'O' flag in 'cpoptions': overwrite any previous file
* message. */
- if (shortmess(SHM_OVERALL) && !exiting && p_verbose == 0)
+ if (shortmess(SHM_OVERALL) && !exiting && p_verbose == 0) {
msg_scroll = FALSE;
- if (!msg_scroll) /* wait a bit when overwriting an error msg */
- check_for_delay(FALSE);
+ }
+ if (!msg_scroll) { // wait a bit when overwriting an error msg
+ check_for_delay(false);
+ }
msg_start();
msg_scroll = msg_scroll_save;
- msg_scrolled_ign = TRUE;
+ msg_scrolled_ign = true;
if (!shortmess(SHM_FILEINFO)) {
fileinfo(false, true, false);
}
- msg_scrolled_ign = FALSE;
+ msg_scrolled_ign = false;
}
curbuf->b_last_used = time(NULL);
- if (command != NULL)
+ if (command != NULL) {
do_cmdline(command, NULL, NULL, DOCMD_VERBOSE);
+ }
- if (curbuf->b_kmap_state & KEYMAP_INIT)
+ if (curbuf->b_kmap_state & KEYMAP_INIT) {
(void)keymap_init();
+ }
RedrawingDisabled--;
did_inc_redrawing_disabled = false;
@@ -2812,10 +2870,11 @@ int do_ecmd(
redraw_curbuf_later(NOT_VALID); // redraw this buffer later
}
- if (p_im)
- need_start_insertmode = TRUE;
+ if (p_im) {
+ need_start_insertmode = true;
+ }
- /* Change directories when the 'acd' option is set. */
+ // Change directories when the 'acd' option is set.
do_autochdir();
@@ -2837,65 +2896,72 @@ theend:
static void delbuf_msg(char_u *name)
{
EMSG2(_("E143: Autocommands unexpectedly deleted new buffer %s"),
- name == NULL ? (char_u *)"" : name);
+ name == NULL ? (char_u *)"" : name);
xfree(name);
au_new_curbuf.br_buf = NULL;
au_new_curbuf.br_buf_free_count = 0;
}
-static int append_indent = 0; /* autoindent for first line */
+static int append_indent = 0; // autoindent for first line
/*
* ":insert" and ":append", also used by ":change"
*/
void ex_append(exarg_T *eap)
{
- char_u *theline;
+ char_u *theline;
bool did_undo = false;
linenr_T lnum = eap->line2;
int indent = 0;
- char_u *p;
+ char_u *p;
int vcol;
int empty = (curbuf->b_ml.ml_flags & ML_EMPTY);
- /* the ! flag toggles autoindent */
- if (eap->forceit)
+ // the ! flag toggles autoindent
+ if (eap->forceit) {
curbuf->b_p_ai = !curbuf->b_p_ai;
+ }
- /* First autoindent comes from the line we start on */
- if (eap->cmdidx != CMD_change && curbuf->b_p_ai && lnum > 0)
+ // First autoindent comes from the line we start on
+ if (eap->cmdidx != CMD_change && curbuf->b_p_ai && lnum > 0) {
append_indent = get_indent_lnum(lnum);
+ }
- if (eap->cmdidx != CMD_append)
+ if (eap->cmdidx != CMD_append) {
--lnum;
+ }
// when the buffer is empty need to delete the dummy line
- if (empty && lnum == 1)
+ if (empty && lnum == 1) {
lnum = 0;
+ }
- State = INSERT; /* behave like in Insert mode */
- if (curbuf->b_p_iminsert == B_IMODE_LMAP)
+ State = INSERT; // behave like in Insert mode
+ if (curbuf->b_p_iminsert == B_IMODE_LMAP) {
State |= LANGMAP;
+ }
for (;; ) {
msg_scroll = TRUE;
- need_wait_return = FALSE;
+ need_wait_return = false;
if (curbuf->b_p_ai) {
if (append_indent >= 0) {
indent = append_indent;
append_indent = -1;
- } else if (lnum > 0)
+ } else if (lnum > 0) {
indent = get_indent_lnum(lnum);
+ }
}
- ex_keep_indent = FALSE;
if (eap->getline == NULL) {
/* No getline() function, use the lines that follow. This ends
* when there is no more. */
- if (eap->nextcmd == NULL || *eap->nextcmd == NUL)
+ if (eap->nextcmd == NULL || *eap->nextcmd == NUL) {
break;
+ }
p = vim_strchr(eap->nextcmd, NL);
- if (p == NULL)
+ if (p == NULL) {
p = eap->nextcmd + STRLEN(eap->nextcmd);
+ }
theline = vim_strnsave(eap->nextcmd, p - eap->nextcmd);
if (*p != NUL) {
p++;
@@ -2906,28 +2972,25 @@ void ex_append(exarg_T *eap)
// when getline() returns.
int save_State = State;
State = CMDLINE;
- theline = eap->getline(
- eap->cstack->cs_looplevel > 0 ? -1 :
- NUL, eap->cookie, indent, true);
+ theline = eap->getline(eap->cstack->cs_looplevel > 0 ? -1 :
+ NUL, eap->cookie, indent, true);
State = save_State;
}
lines_left = Rows - 1;
- if (theline == NULL)
+ if (theline == NULL) {
break;
+ }
- /* Using ^ CTRL-D in getexmodeline() makes us repeat the indent. */
- if (ex_keep_indent)
- append_indent = indent;
-
- /* Look for the "." after automatic indent. */
+ // Look for the "." after automatic indent.
vcol = 0;
for (p = theline; indent > vcol; ++p) {
- if (*p == ' ')
+ if (*p == ' ') {
++vcol;
- else if (*p == TAB)
+ } else if (*p == TAB) {
vcol += 8 - vcol % 8;
- else
+ } else {
break;
+ }
}
if ((p[0] == '.' && p[1] == NUL)
|| (!did_undo && u_save(lnum, lnum + 1 + (empty ? 1 : 0))
@@ -2936,9 +2999,10 @@ void ex_append(exarg_T *eap)
break;
}
- /* don't use autoindent if nothing was typed. */
- if (p[0] == NUL)
+ // don't use autoindent if nothing was typed.
+ if (p[0] == NUL) {
theline[0] = NUL;
+ }
did_undo = true;
ml_append(lnum, theline, (colnr_T)0, false);
@@ -2954,8 +3018,9 @@ void ex_append(exarg_T *eap)
}
State = NORMAL;
- if (eap->forceit)
+ if (eap->forceit) {
curbuf->b_p_ai = !curbuf->b_p_ai;
+ }
/* "start" is set to eap->line2+1 unless that position is invalid (when
* eap->line2 pointed to the end of the buffer and nothing was appended)
@@ -2963,8 +3028,9 @@ void ex_append(exarg_T *eap)
* it is the same than "start" -- Acevedo */
curbuf->b_op_start.lnum = (eap->line2 < curbuf->b_ml.ml_line_count) ?
eap->line2 + 1 : curbuf->b_ml.ml_line_count;
- if (eap->cmdidx != CMD_append)
+ if (eap->cmdidx != CMD_append) {
--curbuf->b_op_start.lnum;
+ }
curbuf->b_op_end.lnum = (eap->line2 < lnum)
? lnum : curbuf->b_op_start.lnum;
curbuf->b_op_start.col = curbuf->b_op_end.col = 0;
@@ -2972,8 +3038,8 @@ void ex_append(exarg_T *eap)
check_cursor_lnum();
beginline(BL_SOL | BL_FIX);
- need_wait_return = FALSE; /* don't use wait_return() now */
- ex_no_reprint = TRUE;
+ need_wait_return = false; // don't use wait_return() now
+ ex_no_reprint = true;
}
/*
@@ -2984,33 +3050,36 @@ void ex_change(exarg_T *eap)
linenr_T lnum;
if (eap->line2 >= eap->line1
- && u_save(eap->line1 - 1, eap->line2 + 1) == FAIL)
+ && u_save(eap->line1 - 1, eap->line2 + 1) == FAIL) {
return;
+ }
- /* the ! flag toggles autoindent */
- if (eap->forceit ? !curbuf->b_p_ai : curbuf->b_p_ai)
+ // the ! flag toggles autoindent
+ if (eap->forceit ? !curbuf->b_p_ai : curbuf->b_p_ai) {
append_indent = get_indent_lnum(eap->line1);
+ }
for (lnum = eap->line2; lnum >= eap->line1; --lnum) {
- if (curbuf->b_ml.ml_flags & ML_EMPTY) /* nothing to delete */
+ if (curbuf->b_ml.ml_flags & ML_EMPTY) { // nothing to delete
break;
+ }
ml_delete(eap->line1, false);
}
- /* make sure the cursor is not beyond the end of the file now */
+ // make sure the cursor is not beyond the end of the file now
check_cursor_lnum();
- deleted_lines_mark(eap->line1, (long)(eap->line2 - lnum));
+ deleted_lines_mark(eap->line1, (eap->line2 - lnum));
- /* ":append" on the line above the deleted lines. */
+ // ":append" on the line above the deleted lines.
eap->line2 = eap->line1;
ex_append(eap);
}
void ex_z(exarg_T *eap)
{
- char_u *x;
- int64_t bigness;
- char_u *kind;
+ char_u *x;
+ int64_t bigness;
+ char_u *kind;
int minus = 0;
linenr_T start, end, curs, i;
int j;
@@ -3019,7 +3088,7 @@ void ex_z(exarg_T *eap)
// Vi compatible: ":z!" uses display height, without a count uses
// 'scroll'
if (eap->forceit) {
- bigness = curwin->w_height_inner;
+ bigness = Rows - 1;
} else if (ONE_WINDOW) {
bigness = curwin->w_p_scr * 2;
} else {
@@ -3032,10 +3101,12 @@ void ex_z(exarg_T *eap)
x = eap->arg;
kind = x;
if (*kind == '-' || *kind == '+' || *kind == '='
- || *kind == '^' || *kind == '.')
+ || *kind == '^' || *kind == '.') {
++x;
- while (*x == '-' || *x == '+')
+ }
+ while (*x == '-' || *x == '+') {
++x;
+ }
if (*x != 0) {
if (!ascii_isdigit(*x)) {
@@ -3055,10 +3126,12 @@ void ex_z(exarg_T *eap)
}
}
- /* the number of '-' and '+' multiplies the distance */
- if (*kind == '-' || *kind == '+')
- for (x = kind + 1; *x == *kind; ++x)
+ // the number of '-' and '+' multiplies the distance
+ if (*kind == '-' || *kind == '+') {
+ for (x = kind + 1; *x == *kind; ++x) {
;
+ }
+ }
switch (*kind) {
case '-':
@@ -3086,22 +3159,25 @@ void ex_z(exarg_T *eap)
curs = end;
break;
- default: /* '+' */
+ default: // '+'
start = lnum;
- if (*kind == '+')
+ if (*kind == '+') {
start += bigness * (linenr_T)(x - kind - 1) + 1;
- else if (eap->addr_count == 0)
+ } else if (eap->addr_count == 0) {
++start;
+ }
end = start + bigness - 1;
curs = end;
break;
}
- if (start < 1)
+ if (start < 1) {
start = 1;
+ }
- if (end > curbuf->b_ml.ml_line_count)
+ if (end > curbuf->b_ml.ml_line_count) {
end = curbuf->b_ml.ml_line_count;
+ }
if (curs > curbuf->b_ml.ml_line_count) {
curs = curbuf->b_ml.ml_line_count;
@@ -3113,8 +3189,9 @@ void ex_z(exarg_T *eap)
if (minus && i == lnum) {
msg_putchar('\n');
- for (j = 1; j < Columns; j++)
+ for (j = 1; j < Columns; j++) {
msg_putchar('-');
+ }
}
print_line(i, eap->flags & EXFLAG_NR, eap->flags & EXFLAG_LIST);
@@ -3122,8 +3199,9 @@ void ex_z(exarg_T *eap)
if (minus && i == lnum) {
msg_putchar('\n');
- for (j = 1; j < Columns; j++)
+ for (j = 1; j < Columns; j++) {
msg_putchar('-');
+ }
}
}
@@ -3157,7 +3235,7 @@ int check_secure(void)
}
/// Previous substitute replacement string
-static SubReplacementString old_sub = {NULL, 0, NULL};
+static SubReplacementString old_sub = { NULL, 0, NULL };
static int global_need_beginline; // call beginline() after ":g"
@@ -3194,8 +3272,7 @@ void sub_set_replacement(SubReplacementString sub)
/// @param[in] save Save pattern to options, history
///
/// @returns true if :substitute can be replaced with a join command
-static bool sub_joining_lines(exarg_T *eap, char_u *pat, char_u *sub,
- char_u *cmd, bool save)
+static bool sub_joining_lines(exarg_T *eap, char_u *pat, char_u *sub, char_u *cmd, bool save)
FUNC_ATTR_NONNULL_ARG(1, 3, 4)
{
// TODO(vim): find a generic solution to make line-joining operations more
@@ -3222,8 +3299,8 @@ static bool sub_joining_lines(exarg_T *eap, char_u *pat, char_u *sub,
// The number of lines joined is the number of lines in the range
linenr_T joined_lines_count = eap->line2 - eap->line1 + 1
- // plus one extra line if not at the end of file.
- + (eap->line2 < curbuf->b_ml.ml_line_count ? 1 : 0);
+ // plus one extra line if not at the end of file.
+ + (eap->line2 < curbuf->b_ml.ml_line_count ? 1 : 0);
if (joined_lines_count > 1) {
do_join(joined_lines_count, FALSE, TRUE, FALSE, true);
sub_nsubs = joined_lines_count - 1;
@@ -3290,8 +3367,7 @@ static char_u *sub_grow_buf(char_u **new_start, int needed_len)
/// @param[in,out] which_pat pattern type from which to get default search
///
/// @returns pointer to the end of the flags, which may be the end of the string
-static char_u *sub_parse_flags(char_u *cmd, subflags_T *subflags,
- int *which_pat)
+static char_u *sub_parse_flags(char_u *cmd, subflags_T *subflags, int *which_pat)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET
{
// Find trailing options. When '&' is used, keep old options.
@@ -3363,8 +3439,7 @@ static int check_regexp_delim(int c)
///
/// @param do_buf_event If `true`, send buffer updates.
/// @return buffer used for 'inccommand' preview
-static buf_T *do_sub(exarg_T *eap, proftime_T timeout,
- bool do_buf_event, handle_T bufnr)
+static buf_T *do_sub(exarg_T *eap, proftime_T timeout, bool do_buf_event, handle_T bufnr)
{
long i = 0;
regmmatch_T regmatch;
@@ -3382,8 +3457,8 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout,
int delimiter;
bool has_second_delim = false;
int sublen;
- int got_quit = false;
- int got_match = false;
+ bool got_quit = false;
+ bool got_match = false;
int which_pat;
char_u *cmd = eap->arg;
linenr_T first_line = 0; // first changed line
@@ -3409,12 +3484,12 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout,
}
start_nsubs = sub_nsubs;
- if (eap->cmdidx == CMD_tilde)
- which_pat = RE_LAST; /* use last used regexp */
- else
- which_pat = RE_SUBST; /* use last substitute regexp */
-
- /* new pattern and substitution */
+ if (eap->cmdidx == CMD_tilde) {
+ which_pat = RE_LAST; // use last used regexp
+ } else {
+ which_pat = RE_SUBST; // use last substitute regexp
+ }
+ // new pattern and substitution
if (eap->cmd[0] == 's' && *cmd != NUL && !ascii_iswhite(*cmd)
&& vim_strchr((char_u *)"0123456789cegriIp|\"", *cmd) == NULL) {
// don't accept alphanumeric for separator
@@ -3452,11 +3527,11 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout,
* Small incompatibility: vi sees '\n' as end of the command, but in
* Vim we want to use '\n' to find/substitute a NUL.
*/
- sub = cmd; /* remember the start of the substitution */
+ sub = cmd; // remember the start of the substitution
while (cmd[0]) {
- if (cmd[0] == delimiter) { /* end delimiter found */
- *cmd++ = NUL; /* replace it with a NUL */
+ if (cmd[0] == delimiter) { // end delimiter found
+ *cmd++ = NUL; // replace it with a NUL
break;
}
if (cmd[0] == '\\' && cmd[1] != 0) { // skip escaped characters
@@ -3467,18 +3542,18 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout,
if (!eap->skip && !preview) {
sub_set_replacement((SubReplacementString) {
- .sub = xstrdup((char *) sub),
+ .sub = xstrdup((char *)sub),
.timestamp = os_time(),
.additional_elements = NULL,
});
}
- } else if (!eap->skip) { /* use previous pattern and substitution */
- if (old_sub.sub == NULL) { /* there is no previous command */
+ } else if (!eap->skip) { // use previous pattern and substitution
+ if (old_sub.sub == NULL) { // there is no previous command
EMSG(_(e_nopresub));
return NULL;
}
- pat = NULL; /* search_regcomp() will use previous pattern */
- sub = (char_u *) old_sub.sub;
+ pat = NULL; // search_regcomp() will use previous pattern
+ sub = (char_u *)old_sub.sub;
/* Vi compatibility quirk: repeating with ":s" keeps the cursor in the
* last column after using "$". */
@@ -3504,15 +3579,16 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout,
}
eap->line1 = eap->line2;
eap->line2 += i - 1;
- if (eap->line2 > curbuf->b_ml.ml_line_count)
+ if (eap->line2 > curbuf->b_ml.ml_line_count) {
eap->line2 = curbuf->b_ml.ml_line_count;
+ }
}
/*
* check for trailing command or garbage
*/
cmd = skipwhite(cmd);
- if (*cmd && *cmd != '"') { /* if not end-of-line or comment */
+ if (*cmd && *cmd != '"') { // if not end-of-line or comment
eap->nextcmd = check_nextcmd(cmd);
if (eap->nextcmd == NULL) {
EMSG(_(e_trailing));
@@ -3570,9 +3646,9 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout,
colnr_T copycol;
colnr_T matchcol;
colnr_T prev_matchcol = MAXCOL;
- char_u *new_end, *new_start = NULL;
- char_u *p1;
- int did_sub = FALSE;
+ char_u *new_end, *new_start = NULL;
+ char_u *p1;
+ bool did_sub = false;
int lastone;
long nmatch_tl = 0; // nr of lines matched below lnum
int do_again; // do it again after joining lines
@@ -3582,29 +3658,29 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout,
/*
* The new text is build up step by step, to avoid too much
* copying. There are these pieces:
- * sub_firstline The old text, unmodified.
- * copycol Column in the old text where we started
- * looking for a match; from here old text still
- * needs to be copied to the new text.
- * matchcol Column number of the old text where to look
- * for the next match. It's just after the
- * previous match or one further.
- * prev_matchcol Column just after the previous match (if any).
- * Mostly equal to matchcol, except for the first
- * match and after skipping an empty match.
- * regmatch.*pos Where the pattern matched in the old text.
- * new_start The new text, all that has been produced so
- * far.
- * new_end The new text, where to append new text.
+ * sub_firstline The old text, unmodified.
+ * copycol Column in the old text where we started
+ * looking for a match; from here old text still
+ * needs to be copied to the new text.
+ * matchcol Column number of the old text where to look
+ * for the next match. It's just after the
+ * previous match or one further.
+ * prev_matchcol Column just after the previous match (if any).
+ * Mostly equal to matchcol, except for the first
+ * match and after skipping an empty match.
+ * regmatch.*pos Where the pattern matched in the old text.
+ * new_start The new text, all that has been produced so
+ * far.
+ * new_end The new text, where to append new text.
*
- * lnum The line number where we found the start of
- * the match. Can be below the line we searched
- * when there is a \n before a \zs in the
- * pattern.
- * sub_firstlnum The line number in the buffer where to look
- * for a match. Can be different from "lnum"
- * when the pattern or substitute string contains
- * line breaks.
+ * lnum The line number where we found the start of
+ * the match. Can be below the line we searched
+ * when there is a \n before a \zs in the
+ * pattern.
+ * sub_firstlnum The line number in the buffer where to look
+ * for a match. Can be different from "lnum"
+ * when the pattern or substitute string contains
+ * line breaks.
*
* Special situations:
* - When the substitute string contains a line break, the part up
@@ -3627,10 +3703,10 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout,
copycol = 0;
matchcol = 0;
- /* At first match, remember current cursor position. */
+ // At first match, remember current cursor position.
if (!got_match) {
setpcmark();
- got_match = TRUE;
+ got_match = true;
}
/*
@@ -3720,11 +3796,12 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout,
skip_match = true;
}
sub_nsubs++;
- did_sub = TRUE;
- /* Skip the substitution, unless an expression is used,
- * then it is evaluated in the sandbox. */
- if (!(sub[0] == '\\' && sub[1] == '='))
+ did_sub = true;
+ // Skip the substitution, unless an expression is used,
+ // then it is evaluated in the sandbox.
+ if (!(sub[0] == '\\' && sub[1] == '=')) {
goto skip;
+ }
}
if (subflags.do_ask && !preview) {
@@ -3734,7 +3811,7 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout,
* properly */
int save_State = State;
State = CONFIRM;
- setmouse(); /* disable mouse in xterm */
+ setmouse(); // disable mouse in xterm
curwin->w_cursor.col = regmatch.startpos[0].col;
if (curwin->w_p_crb) {
@@ -3743,15 +3820,17 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout,
/* When 'cpoptions' contains "u" don't sync undo when
* asking for confirmation. */
- if (vim_strchr(p_cpo, CPO_UNDO) != NULL)
+ if (vim_strchr(p_cpo, CPO_UNDO) != NULL) {
++no_u_sync;
+ }
/*
* Loop until 'y', 'n', 'q', CTRL-E or CTRL-Y typed.
*/
while (subflags.do_ask) {
if (exmode_active) {
- char_u *resp;
+ char *prompt;
+ char_u *resp;
colnr_T sc, ec;
print_line_no_prefix(lnum, subflags.do_number, subflags.do_list);
@@ -3767,13 +3846,14 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout,
sc += numw;
ec += numw;
}
- msg_start();
- for (i = 0; i < (long)sc; ++i)
- msg_putchar(' ');
- for (; i <= (long)ec; ++i)
- msg_putchar('^');
- resp = getexmodeline('?', NULL, 0, true);
+ prompt = xmallocz(ec + 1);
+ memset(prompt, ' ', sc);
+ memset(prompt + sc, '^', ec - sc + 1);
+ resp = (char_u *)getcmdline_prompt(NUL, prompt, 0, EXPAND_NOTHING,
+ NULL, CALLBACK_NONE);
+ msg_putchar('\n');
+ xfree(prompt);
if (resp != NULL) {
typed = *resp;
xfree(resp);
@@ -3823,8 +3903,9 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout,
redraw_later(curwin, SOME_VALID);
curwin->w_p_fen = save_p_fen;
- if (msg_row == Rows - 1)
- msg_didout = FALSE; /* avoid a scroll-up */
+ if (msg_row == Rows - 1) {
+ msg_didout = false; // avoid a scroll-up
+ }
msg_starthere();
i = msg_scroll;
msg_scroll = 0; /* truncate msg when
@@ -3835,7 +3916,7 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout,
_("replace with %s (y/n/a/q/l/^E/^Y)?"), sub);
msg_no_more = FALSE;
msg_scroll = i;
- showruler(TRUE);
+ showruler(true);
ui_cursor_goto(msg_row, msg_col);
RedrawingDisabled = temp;
@@ -3843,8 +3924,8 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout,
typed = plain_vgetc();
no_mapping--;
- /* clear the question */
- msg_didout = FALSE; /* don't scroll up */
+ // clear the question
+ msg_didout = false; // don't scroll up
msg_col = 0;
gotocmdline(true);
p_lz = save_p_lz;
@@ -3860,10 +3941,12 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout,
got_quit = true;
break;
}
- if (typed == 'n')
+ if (typed == 'n') {
break;
- if (typed == 'y')
+ }
+ if (typed == 'y') {
break;
+ }
if (typed == 'l') {
// last: replace and then stop
subflags.do_all = false;
@@ -3874,15 +3957,17 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout,
subflags.do_ask = false;
break;
}
- if (typed == Ctrl_E)
+ if (typed == Ctrl_E) {
scrollup_clamp();
- else if (typed == Ctrl_Y)
+ } else if (typed == Ctrl_Y) {
scrolldown_clamp();
+ }
}
State = save_State;
setmouse();
- if (vim_strchr(p_cpo, CPO_UNDO) != NULL)
+ if (vim_strchr(p_cpo, CPO_UNDO) != NULL) {
--no_u_sync;
+ }
if (typed == 'n') {
/* For a multi-line match, put matchcol at the NUL at
@@ -3896,8 +3981,9 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout,
}
goto skip;
}
- if (got_quit)
+ if (got_quit) {
goto skip;
+ }
}
/* Move the cursor to the start of the match, so that we can
@@ -3913,28 +3999,28 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout,
}
#define ADJUST_SUB_FIRSTLNUM() \
- do { \
- /* For a multi-line match, make a copy of the last matched */ \
- /* line and continue in that one. */ \
- if (nmatch > 1) { \
- sub_firstlnum += nmatch - 1; \
- xfree(sub_firstline); \
- sub_firstline = vim_strsave(ml_get(sub_firstlnum)); \
- /* When going beyond the last line, stop substituting. */ \
- if (sub_firstlnum <= line2) { \
- do_again = true; \
- } else { \
- subflags.do_all = false; \
- } \
- } \
- if (skip_match) { \
- /* Already hit end of the buffer, sub_firstlnum is one */ \
- /* less than what it ought to be. */ \
- xfree(sub_firstline); \
- sub_firstline = vim_strsave((char_u *)""); \
- copycol = 0; \
- } \
- } while (0)
+ do { \
+ /* For a multi-line match, make a copy of the last matched */ \
+ /* line and continue in that one. */ \
+ if (nmatch > 1) { \
+ sub_firstlnum += nmatch - 1; \
+ xfree(sub_firstline); \
+ sub_firstline = vim_strsave(ml_get(sub_firstlnum)); \
+ /* When going beyond the last line, stop substituting. */ \
+ if (sub_firstlnum <= line2) { \
+ do_again = true; \
+ } else { \
+ subflags.do_all = false; \
+ } \
+ } \
+ if (skip_match) { \
+ /* Already hit end of the buffer, sub_firstlnum is one */ \
+ /* less than what it ought to be. */ \
+ xfree(sub_firstline); \
+ sub_firstline = vim_strsave((char_u *)""); \
+ copycol = 0; \
+ } \
+ } while (0)
// Save the line numbers for the preview buffer
// NOTE: If the pattern matches a final newline, the next line will
@@ -3999,7 +4085,7 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout,
+ copy_len + sublen + 1);
// copy the text up to the part that matched
- memmove(new_end, sub_firstline + copycol, (size_t)copy_len);
+ memmove(new_end, sub_firstline + copycol, copy_len);
new_end += copy_len;
// Finally, at this point we can know where the match actually will
@@ -4147,8 +4233,9 @@ skip:
* it in the buffer.
*/
++lnum;
- if (u_savedel(lnum, nmatch_tl) != OK)
+ if (u_savedel(lnum, nmatch_tl) != OK) {
break;
+ }
for (i = 0; i < nmatch_tl; i++) {
ml_delete(lnum, false);
}
@@ -4174,7 +4261,7 @@ skip:
}
sub_firstlnum = lnum;
- xfree(sub_firstline); /* free the temp buffer */
+ xfree(sub_firstline); // free the temp buffer
sub_firstline = new_start;
new_start = NULL;
matchcol = (colnr_T)STRLEN(sub_firstline) - matchcol;
@@ -4182,9 +4269,10 @@ skip:
- prev_matchcol;
copycol = 0;
}
- if (nmatch == -1 && !lastone)
+ if (nmatch == -1 && !lastone) {
nmatch = vim_regexec_multi(&regmatch, curwin, curbuf,
sub_firstlnum, matchcol, NULL, NULL);
+ }
/*
* 5. break if there isn't another match in this line
@@ -4193,23 +4281,24 @@ skip:
/* If the match found didn't start where we were
* searching, do the next search in the line where we
* found the match. */
- if (nmatch == -1)
+ if (nmatch == -1) {
lnum -= regmatch.startpos[0].lnum;
+ }
#define PUSH_PREVIEW_LINES() \
- do { \
- linenr_T match_lines = current_match.end.lnum \
- - current_match.start.lnum +1; \
- if (preview_lines.subresults.size > 0) { \
- linenr_T last = kv_last(preview_lines.subresults).end.lnum; \
- if (last == current_match.start.lnum) { \
- preview_lines.lines_needed += match_lines - 1; \
- } \
- } else { \
- preview_lines.lines_needed += match_lines; \
- } \
- kv_push(preview_lines.subresults, current_match); \
- } while (0)
+ do { \
+ linenr_T match_lines = current_match.end.lnum \
+ - current_match.start.lnum +1; \
+ if (preview_lines.subresults.size > 0) { \
+ linenr_T last = kv_last(preview_lines.subresults).end.lnum; \
+ if (last == current_match.start.lnum) { \
+ preview_lines.lines_needed += match_lines - 1; \
+ } \
+ } else { \
+ preview_lines.lines_needed += match_lines; \
+ } \
+ kv_push(preview_lines.subresults, current_match); \
+ } while (0)
// Push the match to preview_lines.
PUSH_PREVIEW_LINES();
@@ -4252,7 +4341,7 @@ skip:
do_buf_event);
}
- xfree(sub_firstline); /* may have to free allocated copy of the line */
+ xfree(sub_firstline); // may have to free allocated copy of the line
// ":s/pat//n" doesn't move the cursor
if (subflags.do_count) {
@@ -4260,7 +4349,7 @@ skip:
}
if (sub_nsubs > start_nsubs) {
- /* Set the '[ and '] marks. */
+ // Set the '[ and '] marks.
curbuf->b_op_start.lnum = eap->line1;
curbuf->b_op_end.lnum = line2;
curbuf->b_op_start.col = curbuf->b_op_end.col = 0;
@@ -4339,15 +4428,13 @@ skip:
#undef PUSH_PREVIEW_LINES
} // NOLINT(readability/fn_size)
-/*
- * Give message for number of substitutions.
- * Can also be used after a ":global" command.
- * Return TRUE if a message was given.
- */
-bool
-do_sub_msg (
- bool count_only /* used 'n' flag for ":s" */
-)
+/// Give message for number of substitutions.
+/// Can also be used after a ":global" command.
+///
+/// @param count_only used 'n' flag for ":s"
+///
+/// @return true if a message was given.
+bool do_sub_msg(bool count_only)
{
/*
* Only report substitutions when:
@@ -4358,27 +4445,31 @@ do_sub_msg (
if (((sub_nsubs > p_report && (KeyTyped || sub_nlines > 1 || p_report < 1))
|| count_only)
&& messaging()) {
- if (got_int)
+ if (got_int) {
STRCPY(msg_buf, _("(Interrupted) "));
- else
+ } else {
*msg_buf = NUL;
- if (sub_nsubs == 1)
+ }
+ if (sub_nsubs == 1) {
vim_snprintf_add((char *)msg_buf, sizeof(msg_buf),
- "%s", count_only ? _("1 match") : _("1 substitution"));
- else
+ "%s", count_only ? _("1 match") : _("1 substitution"));
+ } else {
vim_snprintf_add((char *)msg_buf, sizeof(msg_buf),
- count_only ? _("%" PRId64 " matches")
- : _("%" PRId64 " substitutions"),
- (int64_t)sub_nsubs);
- if (sub_nlines == 1)
+ count_only ? _("%" PRId64 " matches")
+ : _("%" PRId64 " substitutions"),
+ (int64_t)sub_nsubs);
+ }
+ if (sub_nlines == 1) {
vim_snprintf_add((char *)msg_buf, sizeof(msg_buf),
- "%s", _(" on 1 line"));
- else
+ "%s", _(" on 1 line"));
+ } else {
vim_snprintf_add((char *)msg_buf, sizeof(msg_buf),
- _(" on %" PRId64 " lines"), (int64_t)sub_nlines);
- if (msg(msg_buf))
- /* save message to display it after redraw */
+ _(" on %" PRId64 " lines"), (int64_t)sub_nlines);
+ }
+ if (msg(msg_buf)) {
+ // save message to display it after redraw
set_keep_msg(msg_buf, 0);
+ }
return true;
}
if (got_int) {
@@ -4417,13 +4508,13 @@ static void global_exe_one(char_u *const cmd, const linenr_T lnum)
*/
void ex_global(exarg_T *eap)
{
- linenr_T lnum; /* line number according to old situation */
+ linenr_T lnum; // line number according to old situation
int ndone = 0;
- int type; /* first char of cmd: 'v' or 'g' */
- char_u *cmd; /* command argument */
+ int type; // first char of cmd: 'v' or 'g'
+ char_u *cmd; // command argument
- char_u delim; /* delimiter, normally '/' */
- char_u *pat;
+ char_u delim; // delimiter, normally '/'
+ char_u *pat;
regmmatch_T regmatch;
int match;
int which_pat;
@@ -4437,17 +4528,18 @@ void ex_global(exarg_T *eap)
return;
}
- if (eap->forceit) /* ":global!" is like ":vglobal" */
+ if (eap->forceit) { // ":global!" is like ":vglobal"
type = 'v';
- else
+ } else {
type = *eap->cmd;
+ }
cmd = eap->arg;
- which_pat = RE_LAST; /* default: use last used regexp */
+ which_pat = RE_LAST; // default: use last used regexp
/*
* undocumented vi feature:
- * "\/" and "\?": use previous search pattern.
- * "\&": use previous substitute pattern.
+ * "\/" and "\?": use previous search pattern.
+ * "\&": use previous substitute pattern.
*/
if (*cmd == '\\') {
++cmd;
@@ -4455,10 +4547,11 @@ void ex_global(exarg_T *eap)
EMSG(_(e_backslash));
return;
}
- if (*cmd == '&')
- which_pat = RE_SUBST; /* use previous substitute pattern */
- else
- which_pat = RE_SEARCH; /* use previous search pattern */
+ if (*cmd == '&') {
+ which_pat = RE_SUBST; // use previous substitute pattern
+ } else {
+ which_pat = RE_SEARCH; // use previous search pattern
+ }
++cmd;
pat = (char_u *)"";
} else if (*cmd == NUL) {
@@ -4467,13 +4560,15 @@ void ex_global(exarg_T *eap)
} else if (check_regexp_delim(*cmd) == FAIL) {
return;
} else {
- delim = *cmd; /* get the delimiter */
- if (delim)
- ++cmd; /* skip delimiter if there is one */
- pat = cmd; /* remember start of pattern */
+ delim = *cmd; // get the delimiter
+ if (delim) {
+ ++cmd; // skip delimiter if there is one
+ }
+ pat = cmd; // remember start of pattern
cmd = skip_regexp(cmd, delim, p_magic, &eap->arg);
- if (cmd[0] == delim) /* end delimiter found */
- *cmd++ = NUL; /* replace it with a NUL */
+ if (cmd[0] == delim) { // end delimiter found
+ *cmd++ = NUL; // replace it with a NUL
+ }
}
if (search_regcomp(pat, RE_BOTH, which_pat, SEARCH_HIS, &regmatch) == FAIL) {
@@ -4577,19 +4672,17 @@ void global_exe(char_u *cmd)
#if defined(EXITFREE)
void free_old_sub(void)
{
- sub_set_replacement((SubReplacementString) {NULL, 0, NULL});
+ sub_set_replacement((SubReplacementString) { NULL, 0, NULL });
}
#endif
-/*
- * Set up for a tagpreview.
- * Return TRUE when it was created.
- */
-bool
-prepare_tagpreview (
- bool undo_sync /* sync undo when leaving the window */
-)
+/// Set up for a tagpreview.
+///
+/// @param undo_sync sync undo when leaving the window
+///
+/// @return true when it was created.
+bool prepare_tagpreview(bool undo_sync)
{
/*
* If there is already a preview window open, use that one.
@@ -4608,8 +4701,9 @@ prepare_tagpreview (
* There is no preview window open yet. Create one.
*/
if (win_split(g_do_tagpreview > 0 ? g_do_tagpreview : 0, 0)
- == FAIL)
+ == FAIL) {
return false;
+ }
curwin->w_p_pvw = TRUE;
curwin->w_p_wfh = TRUE;
RESET_BINDING(curwin); /* don't take over 'scrollbind'
@@ -4630,20 +4724,20 @@ prepare_tagpreview (
*/
void ex_help(exarg_T *eap)
{
- char_u *arg;
- char_u *tag;
- FILE *helpfd; /* file descriptor of help file */
+ char_u *arg;
+ char_u *tag;
+ FILE *helpfd; // file descriptor of help file
int n;
int i;
- win_T *wp;
+ win_T *wp;
int num_matches;
- char_u **matches;
- char_u *p;
+ char_u **matches;
+ char_u *p;
int empty_fnum = 0;
int alt_fnum = 0;
- buf_T *buf;
+ buf_T *buf;
int len;
- char_u *lang;
+ char_u *lang;
const bool old_KeyTyped = KeyTyped;
if (eap != NULL) {
@@ -4666,49 +4760,57 @@ void ex_help(exarg_T *eap)
return;
}
- if (eap->skip) /* not executing commands */
+ if (eap->skip) { // not executing commands
return;
- } else
+ }
+ } else {
arg = (char_u *)"";
+ }
- /* remove trailing blanks */
+ // remove trailing blanks
p = arg + STRLEN(arg) - 1;
- while (p > arg && ascii_iswhite(*p) && p[-1] != '\\')
+ while (p > arg && ascii_iswhite(*p) && p[-1] != '\\') {
*p-- = NUL;
+ }
- /* Check for a specified language */
+ // Check for a specified language
lang = check_help_lang(arg);
- /* When no argument given go to the index. */
- if (*arg == NUL)
+ // When no argument given go to the index.
+ if (*arg == NUL) {
arg = (char_u *)"help.txt";
+ }
/*
* Check if there is a match for the argument.
*/
n = find_help_tags(arg, &num_matches, &matches,
- eap != NULL && eap->forceit);
+ eap != NULL && eap->forceit);
i = 0;
- if (n != FAIL && lang != NULL)
- /* Find first item with the requested language. */
+ if (n != FAIL && lang != NULL) {
+ // Find first item with the requested language.
for (i = 0; i < num_matches; ++i) {
len = (int)STRLEN(matches[i]);
if (len > 3 && matches[i][len - 3] == '@'
- && STRICMP(matches[i] + len - 2, lang) == 0)
+ && STRICMP(matches[i] + len - 2, lang) == 0) {
break;
+ }
}
+ }
if (i >= num_matches || n == FAIL) {
- if (lang != NULL)
+ if (lang != NULL) {
EMSG3(_("E661: Sorry, no '%s' help for %s"), lang, arg);
- else
+ } else {
EMSG2(_("E149: Sorry, no help for %s"), arg);
- if (n != FAIL)
+ }
+ if (n != FAIL) {
FreeWild(num_matches, matches);
+ }
return;
}
- /* The first match (in the requested language) is the best match. */
+ // The first match (in the requested language) is the best match.
tag = vim_strsave(matches[i]);
FreeWild(num_matches, matches);
@@ -4717,8 +4819,7 @@ void ex_help(exarg_T *eap)
* Always open a new one for ":tab help".
*/
if (!bt_help(curwin->w_buffer)
- || cmdmod.tab != 0
- ) {
+ || cmdmod.tab != 0) {
if (cmdmod.tab != 0) {
wp = NULL;
} else {
@@ -4746,13 +4847,16 @@ void ex_help(exarg_T *eap)
* narrow. */
n = WSP_HELP;
if (cmdmod.split == 0 && curwin->w_width != Columns
- && curwin->w_width < 80)
+ && curwin->w_width < 80) {
n |= WSP_TOP;
- if (win_split(0, n) == FAIL)
+ }
+ if (win_split(0, n) == FAIL) {
goto erret;
+ }
- if (curwin->w_height < p_hh)
+ if (curwin->w_height < p_hh) {
win_setheight((int)p_hh);
+ }
/*
* Open help file (do_ecmd() will set b_help flag, readfile() will
@@ -4761,18 +4865,19 @@ void ex_help(exarg_T *eap)
*/
alt_fnum = curbuf->b_fnum;
(void)do_ecmd(0, NULL, NULL, NULL, ECMD_LASTL,
- ECMD_HIDE + ECMD_SET_HELP,
- NULL /* buffer is still open, don't store info */
- );
- if (!cmdmod.keepalt)
+ ECMD_HIDE + ECMD_SET_HELP,
+ NULL // buffer is still open, don't store info
+ );
+ if (!cmdmod.keepalt) {
curwin->w_alt_fnum = alt_fnum;
+ }
empty_fnum = curbuf->b_fnum;
}
}
- if (!p_im)
- restart_edit = 0; /* don't want insert mode in help file */
-
+ if (!p_im) {
+ restart_edit = 0; // don't want insert mode in help file
+ }
/* Restore KeyTyped, setting 'filetype=help' may reset it.
* It is needed for do_tag top open folds under the cursor. */
KeyTyped = old_KeyTyped;
@@ -4789,9 +4894,10 @@ void ex_help(exarg_T *eap)
}
}
- /* keep the previous alternate file */
- if (alt_fnum != 0 && curwin->w_alt_fnum == empty_fnum && !cmdmod.keepalt)
+ // keep the previous alternate file
+ if (alt_fnum != 0 && curwin->w_alt_fnum == empty_fnum && !cmdmod.keepalt) {
curwin->w_alt_fnum = alt_fnum;
+ }
erret:
xfree(tag);
@@ -4809,37 +4915,37 @@ char_u *check_help_lang(char_u *arg)
if (len >= 3 && arg[len - 3] == '@' && ASCII_ISALPHA(arg[len - 2])
&& ASCII_ISALPHA(arg[len - 1])) {
- arg[len - 3] = NUL; /* remove the '@' */
+ arg[len - 3] = NUL; // remove the '@'
return arg + len - 2;
}
return NULL;
}
-/*
- * Return a heuristic indicating how well the given string matches. The
- * smaller the number, the better the match. This is the order of priorities,
- * from best match to worst match:
- * - Match with least alpha-numeric characters is better.
- * - Match with least total characters is better.
- * - Match towards the start is better.
- * - Match starting with "+" is worse (feature instead of command)
- * Assumption is made that the matched_string passed has already been found to
- * match some string for which help is requested. webb.
- */
-int
-help_heuristic(
- char_u *matched_string,
- int offset, // offset for match
- int wrong_case // no matching case
-)
+/// Return a heuristic indicating how well the given string matches. The
+/// smaller the number, the better the match. This is the order of priorities,
+/// from best match to worst match:
+/// - Match with least alphanumeric characters is better.
+/// - Match with least total characters is better.
+/// - Match towards the start is better.
+/// - Match starting with "+" is worse (feature instead of command)
+/// Assumption is made that the matched_string passed has already been found to
+/// match some string for which help is requested. webb.
+///
+/// @param offset offset for match
+/// @param wrong_case no matching case
+///
+/// @return a heuristic indicating how well the given string matches.
+int help_heuristic(char_u *matched_string, int offset, int wrong_case)
{
int num_letters;
- char_u *p;
+ char_u *p;
num_letters = 0;
- for (p = matched_string; *p; p++)
- if (ASCII_ISALNUM(*p))
+ for (p = matched_string; *p; p++) {
+ if (ASCII_ISALNUM(*p)) {
num_letters++;
+ }
+ }
/*
* Multiply the number of letters by 100 to give it a much bigger
@@ -4874,8 +4980,8 @@ help_heuristic(
*/
static int help_compare(const void *s1, const void *s2)
{
- char *p1;
- char *p2;
+ char *p1;
+ char *p2;
p1 = *(char **)s1 + strlen(*(char **)s1) + 1;
p2 = *(char **)s2 + strlen(*(char **)s2) + 1;
@@ -4886,39 +4992,38 @@ static int help_compare(const void *s1, const void *s2)
// the number of matches in num_matches.
// The matches will be sorted with a "best" match algorithm.
// When "keep_lang" is true try keeping the language of the current buffer.
-int find_help_tags(const char_u *arg, int *num_matches, char_u ***matches,
- bool keep_lang)
+int find_help_tags(const char_u *arg, int *num_matches, char_u ***matches, bool keep_lang)
{
int i;
static const char *(mtable[]) = {
- "*", "g*", "[*", "]*",
- "/*", "/\\*", "\"*", "**",
- "/\\(\\)", "/\\%(\\)",
- "?", ":?", "?<CR>", "g?", "g?g?", "g??",
- "-?", "q?", "v_g?",
- "/\\?", "/\\z(\\)", "\\=", ":s\\=",
- "[count]", "[quotex]",
- "[range]", ":[range]",
- "[pattern]", "\\|", "\\%$",
- "s/\\~", "s/\\U", "s/\\L",
- "s/\\1", "s/\\2", "s/\\3", "s/\\9"
+ "*", "g*", "[*", "]*",
+ "/*", "/\\*", "\"*", "**",
+ "/\\(\\)", "/\\%(\\)",
+ "?", ":?", "?<CR>", "g?", "g?g?", "g??",
+ "-?", "q?", "v_g?",
+ "/\\?", "/\\z(\\)", "\\=", ":s\\=",
+ "[count]", "[quotex]",
+ "[range]", ":[range]",
+ "[pattern]", "\\|", "\\%$",
+ "s/\\~", "s/\\U", "s/\\L",
+ "s/\\1", "s/\\2", "s/\\3", "s/\\9"
};
static const char *(rtable[]) = {
- "star", "gstar", "[star", "]star",
- "/star", "/\\\\star", "quotestar", "starstar",
- "/\\\\(\\\\)", "/\\\\%(\\\\)",
- "?", ":?", "?<CR>", "g?", "g?g?", "g??",
- "-?", "q?", "v_g?",
- "/\\\\?", "/\\\\z(\\\\)", "\\\\=", ":s\\\\=",
- "\\[count]", "\\[quotex]",
- "\\[range]", ":\\[range]",
- "\\[pattern]", "\\\\bar", "/\\\\%\\$",
- "s/\\\\\\~", "s/\\\\U", "s/\\\\L",
- "s/\\\\1", "s/\\\\2", "s/\\\\3", "s/\\\\9"
+ "star", "gstar", "[star", "]star",
+ "/star", "/\\\\star", "quotestar", "starstar",
+ "/\\\\(\\\\)", "/\\\\%(\\\\)",
+ "?", ":?", "?<CR>", "g?", "g?g?", "g??",
+ "-?", "q?", "v_g?",
+ "/\\\\?", "/\\\\z(\\\\)", "\\\\=", ":s\\\\=",
+ "\\[count]", "\\[quotex]",
+ "\\[range]", ":\\[range]",
+ "\\[pattern]", "\\\\bar", "/\\\\%\\$",
+ "s/\\\\\\~", "s/\\\\U", "s/\\\\L",
+ "s/\\\\1", "s/\\\\2", "s/\\\\3", "s/\\\\9"
};
static const char *(expr_table[]) = {
- "!=?", "!~?", "<=?", "<?", "==?", "=~?",
- ">=?", ">?", "is?", "isnot?"
+ "!=?", "!~?", "<=?", "<?", "==?", "=~?",
+ ">=?", ">?", "is?", "isnot?"
};
char_u *d = IObuff; // assume IObuff is long enough!
@@ -4951,7 +5056,7 @@ int find_help_tags(const char_u *arg, int *num_matches, char_u ***matches,
}
}
- if (i < 0) { /* no match in table */
+ if (i < 0) { // no match in table
/* Replace "\S" with "/\\S", etc. Otherwise every tag is matched.
* Also replace "\%^" and "\%(", they match every tag too.
* Also "\zs", "\z1", etc.
@@ -4963,9 +5068,10 @@ int find_help_tags(const char_u *arg, int *num_matches, char_u ***matches,
&& arg[2] != NUL))) {
STRCPY(d, "/\\\\");
STRCPY(d + 3, arg + 1);
- /* Check for "/\\_$", should be "/\\_\$" */
- if (d[3] == '_' && d[4] == '$')
+ // Check for "/\\_$", should be "/\\_\$"
+ if (d[3] == '_' && d[4] == '$') {
STRCPY(d + 4, "\\$");
+ }
} else {
/* Replace:
* "[:...:]" with "\[:...:]"
@@ -4974,12 +5080,13 @@ int find_help_tags(const char_u *arg, int *num_matches, char_u ***matches,
*/
if ((arg[0] == '[' && (arg[1] == ':'
|| (arg[1] == '+' && arg[2] == '+')))
- || (arg[0] == '\\' && arg[1] == '{'))
+ || (arg[0] == '\\' && arg[1] == '{')) {
*d++ = '\\';
+ }
// If tag starts with "('", skip the "(". Fixes CTRL-] on ('option'.
if (*arg == '(' && arg[1] == '\'') {
- arg++;
+ arg++;
}
for (const char_u *s = arg; *s; s++) {
// Replace "|" with "bar" and '"' with "quote" to match the name of
@@ -4992,19 +5099,24 @@ int find_help_tags(const char_u *arg, int *num_matches, char_u ***matches,
break;
}
switch (*s) {
- case '|': STRCPY(d, "bar");
+ case '|':
+ STRCPY(d, "bar");
d += 3;
continue;
- case '"': STRCPY(d, "quote");
+ case '"':
+ STRCPY(d, "quote");
d += 5;
continue;
- case '*': *d++ = '.';
+ case '*':
+ *d++ = '.';
break;
- case '?': *d++ = '.';
+ case '?':
+ *d++ = '.';
continue;
case '$':
case '.':
- case '~': *d++ = '\\';
+ case '~':
+ *d++ = '\\';
break;
}
@@ -5015,31 +5127,36 @@ int find_help_tags(const char_u *arg, int *num_matches, char_u ***matches,
*/
if (*s < ' ' || (*s == '^' && s[1] && (ASCII_ISALPHA(s[1])
|| vim_strchr((char_u *)
- "?@[\\]^",
- s[1]) != NULL))) {
- if (d > IObuff && d[-1] != '_' && d[-1] != '\\')
- *d++ = '_'; /* prepend a '_' to make x_CTRL-x */
+ "?@[\\]^",
+ s[1]) != NULL))) {
+ if (d > IObuff && d[-1] != '_' && d[-1] != '\\') {
+ *d++ = '_'; // prepend a '_' to make x_CTRL-x
+ }
STRCPY(d, "CTRL-");
d += 5;
if (*s < ' ') {
*d++ = *s + '@';
- if (d[-1] == '\\')
- *d++ = '\\'; /* double a backslash */
- } else
+ if (d[-1] == '\\') {
+ *d++ = '\\'; // double a backslash
+ }
+ } else {
*d++ = *++s;
- if (s[1] != NUL && s[1] != '_')
- *d++ = '_'; /* append a '_' */
+ }
+ if (s[1] != NUL && s[1] != '_') {
+ *d++ = '_'; // append a '_'
+ }
continue;
- } else if (*s == '^') /* "^" or "CTRL-^" or "^_" */
+ } else if (*s == '^') { // "^" or "CTRL-^" or "^_"
*d++ = '\\';
-
+ }
/*
* Insert a backslash before a backslash after a slash, for search
* pattern tags: "/\|" --> "/\\|".
*/
else if (s[0] == '\\' && s[1] != '\\'
- && *arg == '/' && s == arg + 1)
+ && *arg == '/' && s == arg + 1) {
*d++ = '\\';
+ }
/* "CTRL-\_" -> "CTRL-\\_" to avoid the special meaning of "\_" in
* "CTRL-\_CTRL-N" */
@@ -5071,16 +5188,16 @@ int find_help_tags(const char_u *arg, int *num_matches, char_u ***matches,
if (*IObuff == '`') {
if (d > IObuff + 2 && d[-1] == '`') {
- /* remove the backticks from `command` */
+ // remove the backticks from `command`
memmove(IObuff, IObuff + 1, STRLEN(IObuff));
d[-2] = NUL;
} else if (d > IObuff + 3 && d[-2] == '`' && d[-1] == ',') {
- /* remove the backticks and comma from `command`, */
+ // remove the backticks and comma from `command`,
memmove(IObuff, IObuff + 1, STRLEN(IObuff));
d[-3] = NUL;
} else if (d > IObuff + 4 && d[-3] == '`'
&& d[-2] == '\\' && d[-1] == '.') {
- /* remove the backticks and dot from `command`\. */
+ // remove the backticks and dot from `command`\.
memmove(IObuff, IObuff + 1, STRLEN(IObuff));
d[-4] = NUL;
}
@@ -5099,10 +5216,11 @@ int find_help_tags(const char_u *arg, int *num_matches, char_u ***matches,
/* Sort the matches found on the heuristic number that is after the
* tag name. */
qsort((void *)*matches, (size_t)*num_matches,
- sizeof(char_u *), help_compare);
- /* Delete more than TAG_MANY to reduce the size of the listing. */
- while (*num_matches > TAG_MANY)
+ sizeof(char_u *), help_compare);
+ // Delete more than TAG_MANY to reduce the size of the listing.
+ while (*num_matches > TAG_MANY) {
xfree((*matches)[--*num_matches]);
+ }
}
return OK;
}
@@ -5154,14 +5272,14 @@ static void prepare_help_buffer(void)
void fix_help_buffer(void)
{
linenr_T lnum;
- char_u *line;
+ char_u *line;
bool in_example = false;
// Set filetype to "help".
if (STRCMP(curbuf->b_p_ft, "help") != 0) {
- curbuf_lock++;
+ curbuf->b_ro_locked++;
set_option_value("ft", 0L, "help", OPT_LOCAL);
- curbuf_lock--;
+ curbuf->b_ro_locked--;
}
if (!syntax_present(curwin)) {
@@ -5169,23 +5287,23 @@ void fix_help_buffer(void)
line = ml_get_buf(curbuf, lnum, false);
const size_t len = STRLEN(line);
if (in_example && len > 0 && !ascii_iswhite(line[0])) {
- /* End of example: non-white or '<' in first column. */
+ // End of example: non-white or '<' in first column.
if (line[0] == '<') {
- /* blank-out a '<' in the first column */
- line = ml_get_buf(curbuf, lnum, TRUE);
+ // blank-out a '<' in the first column
+ line = ml_get_buf(curbuf, lnum, true);
line[0] = ' ';
}
in_example = false;
}
if (!in_example && len > 0) {
if (line[len - 1] == '>' && (len == 1 || line[len - 2] == ' ')) {
- /* blank-out a '>' in the last column (start of example) */
- line = ml_get_buf(curbuf, lnum, TRUE);
+ // blank-out a '>' in the last column (start of example)
+ line = ml_get_buf(curbuf, lnum, true);
line[len - 1] = ' ';
in_example = true;
} else if (line[len - 1] == '~') {
- /* blank-out a '~' at the end of line (header marker) */
- line = ml_get_buf(curbuf, lnum, TRUE);
+ // blank-out a '~' at the end of line (header marker)
+ line = ml_get_buf(curbuf, lnum, true);
line[len - 1] = ' ';
}
}
@@ -5202,12 +5320,12 @@ void fix_help_buffer(void)
&& ASCII_ISALPHA(fname[5])
&& ASCII_ISALPHA(fname[6])
&& TOLOWER_ASC(fname[7]) == 'x'
- && fname[8] == NUL)
- ) {
- for (lnum = 1; lnum < curbuf->b_ml.ml_line_count; ++lnum) {
- line = ml_get_buf(curbuf, lnum, FALSE);
- if (strstr((char *)line, "*local-additions*") == NULL)
+ && fname[8] == NUL)) {
+ for (lnum = 1; lnum < curbuf->b_ml.ml_line_count; lnum++) {
+ line = ml_get_buf(curbuf, lnum, false);
+ if (strstr((char *)line, "*local-additions*") == NULL) {
continue;
+ }
/* Go through all directories in 'runtimepath', skipping
* $VIMRUNTIME. */
@@ -5218,10 +5336,10 @@ void fix_help_buffer(void)
if (rt != NULL
&& path_full_compare(rt, NameBuff, false, true) != kEqualFiles) {
int fcount;
- char_u **fnames;
- char_u *s;
+ char_u **fnames;
+ char_u *s;
vimconv_T vc;
- char_u *cp;
+ char_u *cp;
// Find all "doc/ *.txt" files in this directory.
if (!add_pathsep((char *)NameBuff)
@@ -5233,9 +5351,9 @@ void fix_help_buffer(void)
// Note: We cannot just do `&NameBuff` because it is a statically sized array
// so `NameBuff == &NameBuff` according to C semantics.
- char_u *buff_list[1] = {NameBuff};
+ char_u *buff_list[1] = { NameBuff };
if (gen_expand_wildcards(1, buff_list, &fcount,
- &fnames, EW_FILE|EW_SILENT) == OK
+ &fnames, EW_FILE|EW_SILENT) == OK
&& fcount > 0) {
// If foo.abx is found use it instead of foo.txt in
// the same directory.
@@ -5292,8 +5410,9 @@ void fix_help_buffer(void)
IObuff[0] = '|';
*s = '|';
while (*s != NUL) {
- if (*s == '\r' || *s == '\n')
+ if (*s == '\r' || *s == '\n') {
*s = NUL;
+ }
/* The text is utf-8 when a byte
* above 127 is found and no
* illegal byte sequence is found.
@@ -5312,10 +5431,9 @@ void fix_help_buffer(void)
* conversion to the current
* 'encoding' may be required. */
vc.vc_type = CONV_NONE;
- convert_setup(
- &vc,
- (char_u *)(this_utf == kTrue ? "utf-8" : "latin1"),
- p_enc);
+ convert_setup(&vc,
+ (char_u *)(this_utf == kTrue ? "utf-8" : "latin1"),
+ p_enc);
if (vc.vc_type == CONV_NONE) {
// No conversion needed.
cp = IObuff;
@@ -5372,15 +5490,15 @@ void ex_viusage(exarg_T *eap)
/// French)
/// @param add_help_tags Whether to add the "help-tags" tag
/// @param ignore_writeerr ignore write error
-static void helptags_one(char_u *dir, const char_u *ext, const char_u *tagfname,
- bool add_help_tags, bool ignore_writeerr)
+static void helptags_one(char_u *dir, const char_u *ext, const char_u *tagfname, bool add_help_tags,
+ bool ignore_writeerr)
FUNC_ATTR_NONNULL_ALL
{
garray_T ga;
int filecount;
- char_u **files;
- char_u *p1, *p2;
- char_u *s;
+ char_u **files;
+ char_u *p1, *p2;
+ char_u *s;
TriState utf8 = kNone;
bool mix = false; // detected mixed encodings
@@ -5395,9 +5513,9 @@ static void helptags_one(char_u *dir, const char_u *ext, const char_u *tagfname,
// Note: We cannot just do `&NameBuff` because it is a statically sized array
// so `NameBuff == &NameBuff` according to C semantics.
- char_u *buff_list[1] = {NameBuff};
+ char_u *buff_list[1] = { NameBuff };
if (gen_expand_wildcards(1, buff_list, &filecount, &files,
- EW_FILE|EW_SILENT) == FAIL
+ EW_FILE|EW_SILENT) == FAIL
|| filecount == 0) {
if (!got_int) {
EMSG2(_("E151: No match: %s"), NameBuff);
@@ -5431,8 +5549,9 @@ static void helptags_one(char_u *dir, const char_u *ext, const char_u *tagfname,
if (add_help_tags
|| path_full_compare((char_u *)"$VIMRUNTIME/doc",
dir, false, true) == kEqualFiles) {
- s = xmalloc(18 + STRLEN(tagfname));
- sprintf((char *)s, "help-tags\t%s\t1\n", tagfname);
+ size_t s_len = 18 + STRLEN(tagfname);
+ s = xmalloc(s_len);
+ snprintf((char *)s, s_len, "help-tags\t%s\t1\n", tagfname);
GA_APPEND(char_u *, &ga, s);
}
@@ -5468,9 +5587,8 @@ static void helptags_one(char_u *dir, const char_u *ext, const char_u *tagfname,
if (utf8 == kNone) { // first file
utf8 = this_utf8;
} else if (utf8 != this_utf8) {
- EMSG2(_(
- "E670: Mix of help file encodings within a language: %s"),
- files[fi]);
+ EMSG2(_("E670: Mix of help file encodings within a language: %s"),
+ files[fi]);
mix = !got_int;
got_int = TRUE;
}
@@ -5494,10 +5612,11 @@ static void helptags_one(char_u *dir, const char_u *ext, const char_u *tagfname,
&& (vim_strchr((char_u *)" \t\n\r", s[1]) != NULL
|| s[1] == '\0')) {
*p2 = '\0';
- ++p1;
- s = xmalloc((p2 - p1) + STRLEN(fname) + 2);
+ p1++;
+ size_t s_len= (p2 - p1) + STRLEN(fname) + 2;
+ s = xmalloc(s_len);
GA_APPEND(char_u *, &ga, s);
- sprintf((char *)s, "%s\t%s", p1, fname);
+ snprintf((char *)s, s_len, "%s\t%s", p1, fname);
// find next '*'
p2 = vim_strchr(p2 + 1, '*');
@@ -5525,8 +5644,8 @@ static void helptags_one(char_u *dir, const char_u *ext, const char_u *tagfname,
if (*p2 == '\t') {
*p2 = NUL;
vim_snprintf((char *)NameBuff, MAXPATHL,
- _("E154: Duplicate tag \"%s\" in file %s/%s"),
- ((char_u **)ga.ga_data)[i], dir, p2 + 1);
+ _("E154: Duplicate tag \"%s\" in file %s/%s"),
+ ((char_u **)ga.ga_data)[i], dir, p2 + 1);
EMSG(NameBuff);
*p2 = '\t';
break;
@@ -5568,8 +5687,7 @@ static void helptags_one(char_u *dir, const char_u *ext, const char_u *tagfname,
}
/// Generate tags in one help directory, taking care of translations.
-static void do_helptags(char_u *dirname, bool add_help_tags,
- bool ignore_writeerr)
+static void do_helptags(char_u *dirname, bool add_help_tags, bool ignore_writeerr)
FUNC_ATTR_NONNULL_ALL
{
int len;
@@ -5590,7 +5708,7 @@ static void do_helptags(char_u *dirname, bool add_help_tags,
// Note: We cannot just do `&NameBuff` because it is a statically sized array
// so `NameBuff == &NameBuff` according to C semantics.
- char_u *buff_list[1] = {NameBuff};
+ char_u *buff_list[1] = { NameBuff };
if (gen_expand_wildcards(1, buff_list, &filecount, &files,
EW_FILE|EW_SILENT) == FAIL
|| filecount == 0) {
@@ -5608,18 +5726,19 @@ static void do_helptags(char_u *dirname, bool add_help_tags,
continue;
}
if (STRICMP(files[i] + len - 4, ".txt") == 0) {
- /* ".txt" -> language "en" */
+ // ".txt" -> language "en"
lang[0] = 'e';
lang[1] = 'n';
} else if (files[i][len - 4] == '.'
&& ASCII_ISALPHA(files[i][len - 3])
&& ASCII_ISALPHA(files[i][len - 2])
&& TOLOWER_ASC(files[i][len - 1]) == 'x') {
- /* ".abx" -> language "ab" */
+ // ".abx" -> language "ab"
lang[0] = TOLOWER_ASC(files[i][len - 3]);
lang[1] = TOLOWER_ASC(files[i][len - 2]);
- } else
+ } else {
continue;
+ }
// Did we find this language already?
for (j = 0; j < ga.ga_len; j += 2) {
@@ -5643,11 +5762,11 @@ static void do_helptags(char_u *dirname, bool add_help_tags,
fname[5] = ((char_u *)ga.ga_data)[j];
fname[6] = ((char_u *)ga.ga_data)[j + 1];
if (fname[5] == 'e' && fname[6] == 'n') {
- /* English is an exception: use ".txt" and "tags". */
+ // English is an exception: use ".txt" and "tags".
fname[4] = NUL;
STRCPY(ext, ".txt");
} else {
- /* Language "ab" uses ".abx" and "tags-ab". */
+ // Language "ab" uses ".abx" and "tags-ab".
STRCPY(ext, ".xxx");
ext[1] = fname[5];
ext[2] = fname[6];
@@ -5662,7 +5781,7 @@ static void do_helptags(char_u *dirname, bool add_help_tags,
static void helptags_cb(char_u *fname, void *cookie)
FUNC_ATTR_NONNULL_ALL
{
- do_helptags(fname, *(bool *)cookie, true);
+ do_helptags(fname, *(bool *)cookie, true);
}
/*
@@ -5674,7 +5793,7 @@ void ex_helptags(exarg_T *eap)
char_u *dirname;
bool add_help_tags = false;
- /* Check for ":helptags ++t {dir}". */
+ // Check for ":helptags ++t {dir}".
if (STRNCMP(eap->arg, "++t", 3) == 0 && ascii_iswhite(eap->arg[3])) {
add_help_tags = true;
eap->arg = skipwhite(eap->arg + 3);
@@ -5730,9 +5849,8 @@ int sub_preview_win(buf_T *preview_buf)
/// Shows the effects of the :substitute command being typed ('inccommand').
/// If inccommand=split, shows a preview window and later restores the layout.
-static buf_T *show_sub(exarg_T *eap, pos_T old_cusr,
- PreviewLines *preview_lines, int hl_id, int src_id,
- handle_T bufnr)
+static buf_T *show_sub(exarg_T *eap, pos_T old_cusr, PreviewLines *preview_lines, int hl_id,
+ int src_id, handle_T bufnr)
FUNC_ATTR_NONNULL_ALL
{
win_T *save_curwin = curwin;
@@ -5881,12 +5999,12 @@ static buf_T *show_sub(exarg_T *eap, pos_T old_cusr,
/// Closes any open windows for inccommand preview buffer.
void close_preview_windows(void)
{
- block_autocmds();
- buf_T *buf = preview_bufnr ? buflist_findnr(preview_bufnr) : NULL;
- if (buf != NULL) {
- close_windows(buf, false);
- }
- unblock_autocmds();
+ block_autocmds();
+ buf_T *buf = preview_bufnr ? buflist_findnr(preview_bufnr) : NULL;
+ if (buf != NULL) {
+ close_windows(buf, false);
+ }
+ unblock_autocmds();
}
/// :substitute command
@@ -5934,7 +6052,9 @@ void ex_substitute(exarg_T *eap)
if (save_changedtick != buf_get_changedtick(curbuf)) {
// Undo invisibly. This also moves the cursor!
- if (!u_undo_and_forget(1)) { abort(); }
+ if (!u_undo_and_forget(1)) {
+ abort();
+ }
// Restore newhead. It is meaningless when curhead is valid, but we must
// restore it so that undotree() is identical before/after the preview.
curbuf->b_u_newhead = save_b_u_newhead;
@@ -6005,7 +6125,7 @@ char_u *skip_vimgrep_pat(char_u *p, char_u **s, int *flags)
/// List v:oldfiles in a nice way.
void ex_oldfiles(exarg_T *eap)
{
- list_T *l = get_vim_var_list(VV_OLDFILES);
+ list_T *l = get_vim_var_list(VV_OLDFILES);
long nr = 0;
if (l == NULL) {
diff --git a/src/nvim/ex_cmds.lua b/src/nvim/ex_cmds.lua
index 7b971f464f..c388373ac1 100644
--- a/src/nvim/ex_cmds.lua
+++ b/src/nvim/ex_cmds.lua
@@ -3271,7 +3271,7 @@ module.cmds = {
},
{
command='z',
- flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, FLAGS, TRLBAR, CMDWIN),
+ flags=bit.bor(RANGE, WHOLEFOLD, BANG, EXTRA, FLAGS, TRLBAR, CMDWIN),
addr_type='ADDR_LINES',
func='ex_z',
},
diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c
index 9d500a8ddb..46b86fbc84 100644
--- a/src/nvim/ex_cmds2.c
+++ b/src/nvim/ex_cmds2.c
@@ -6,62 +6,58 @@
/// Some more functions for command line commands
#include <assert.h>
+#include <fcntl.h>
#include <inttypes.h>
#include <stdbool.h>
#include <string.h>
-#include <fcntl.h>
-#include "nvim/vim.h"
#include "nvim/ascii.h"
+#include "nvim/vim.h"
#ifdef HAVE_LOCALE_H
# include <locale.h>
#endif
-#include "nvim/ex_cmds2.h"
+#include "nvim/api/private/defs.h"
+#include "nvim/api/private/helpers.h"
#include "nvim/buffer.h"
#include "nvim/change.h"
#include "nvim/charset.h"
+#include "nvim/debugger.h"
#include "nvim/eval/userfunc.h"
#include "nvim/ex_cmds.h"
-#include "nvim/ex_docmd.h"
+#include "nvim/ex_cmds2.h"
#include "nvim/ex_eval.h"
#include "nvim/ex_getln.h"
#include "nvim/fileio.h"
-#include "nvim/getchar.h"
-#include "nvim/globals.h"
+#include "nvim/garray.h"
+#include "nvim/lua/executor.h"
#include "nvim/mark.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
+#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/garray.h"
-#include "nvim/memory.h"
#include "nvim/move.h"
#include "nvim/normal.h"
#include "nvim/ops.h"
#include "nvim/option.h"
+#include "nvim/os/fs_defs.h"
+#include "nvim/os/shell.h"
#include "nvim/os_unix.h"
#include "nvim/path.h"
+#include "nvim/profile.h"
#include "nvim/quickfix.h"
#include "nvim/regexp.h"
-#include "nvim/screen.h"
#include "nvim/strings.h"
#include "nvim/undo.h"
#include "nvim/version.h"
#include "nvim/window.h"
-#include "nvim/profile.h"
-#include "nvim/os/os.h"
-#include "nvim/os/shell.h"
-#include "nvim/os/fs_defs.h"
-#include "nvim/api/private/helpers.h"
-#include "nvim/api/private/defs.h"
-#include "nvim/lua/executor.h"
/// Growarray to store info about already sourced scripts.
/// Also store the dev/ino, so that we don't have to stat() each
/// script when going through the list.
typedef struct scriptitem_S {
- char_u *sn_name;
+ char_u *sn_name;
bool file_id_valid;
FileID file_id;
bool sn_prof_on; ///< true when script is/was profiled
@@ -113,822 +109,20 @@ struct source_cookie {
vimconv_T conv; ///< type of conversion
};
-# define PRL_ITEM(si, idx) (((sn_prl_T *)(si)->sn_prl_ga.ga_data)[(idx)])
+#define PRL_ITEM(si, idx) (((sn_prl_T *)(si)->sn_prl_ga.ga_data)[(idx)])
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "ex_cmds2.c.generated.h"
#endif
-/// batch mode debugging: don't save and restore typeahead.
-static bool debug_greedy = false;
-
-static char *debug_oldval = NULL; // old and newval for debug expressions
-static char *debug_newval = NULL;
-
-/// Debug mode. Repeatedly get Ex commands, until told to continue normal
-/// execution.
-void do_debug(char_u *cmd)
-{
- int save_msg_scroll = msg_scroll;
- int save_State = State;
- int save_did_emsg = did_emsg;
- const bool save_cmd_silent = cmd_silent;
- int save_msg_silent = msg_silent;
- int save_emsg_silent = emsg_silent;
- int save_redir_off = redir_off;
- tasave_T typeaheadbuf;
- bool typeahead_saved = false;
- int save_ignore_script = 0;
- int save_ex_normal_busy;
- int n;
- char_u *cmdline = NULL;
- char_u *p;
- char *tail = NULL;
- static int last_cmd = 0;
-#define CMD_CONT 1
-#define CMD_NEXT 2
-#define CMD_STEP 3
-#define CMD_FINISH 4
-#define CMD_QUIT 5
-#define CMD_INTERRUPT 6
-#define CMD_BACKTRACE 7
-#define CMD_FRAME 8
-#define CMD_UP 9
-#define CMD_DOWN 10
-
-
- RedrawingDisabled++; // don't redisplay the window
- no_wait_return++; // don't wait for return
- did_emsg = false; // don't use error from debugged stuff
- cmd_silent = false; // display commands
- msg_silent = false; // display messages
- emsg_silent = false; // display error messages
- redir_off = true; // don't redirect debug commands
-
- State = NORMAL;
- debug_mode = true;
-
- if (!debug_did_msg) {
- MSG(_("Entering Debug mode. Type \"cont\" to continue."));
- }
- if (debug_oldval != NULL) {
- smsg(_("Oldval = \"%s\""), debug_oldval);
- xfree(debug_oldval);
- debug_oldval = NULL;
- }
- if (debug_newval != NULL) {
- smsg(_("Newval = \"%s\""), debug_newval);
- xfree(debug_newval);
- debug_newval = NULL;
- }
- if (sourcing_name != NULL) {
- msg(sourcing_name);
- }
- if (sourcing_lnum != 0) {
- smsg(_("line %" PRId64 ": %s"), (int64_t)sourcing_lnum, cmd);
- } else {
- smsg(_("cmd: %s"), cmd);
- }
- // Repeat getting a command and executing it.
- for (;; ) {
- msg_scroll = true;
- need_wait_return = false;
- // Save the current typeahead buffer and replace it with an empty one.
- // This makes sure we get input from the user here and don't interfere
- // with the commands being executed. Reset "ex_normal_busy" to avoid
- // the side effects of using ":normal". Save the stuff buffer and make
- // it empty. Set ignore_script to avoid reading from script input.
- save_ex_normal_busy = ex_normal_busy;
- ex_normal_busy = 0;
- if (!debug_greedy) {
- save_typeahead(&typeaheadbuf);
- typeahead_saved = true;
- save_ignore_script = ignore_script;
- ignore_script = true;
- }
-
- xfree(cmdline);
- cmdline = (char_u *)getcmdline_prompt('>', NULL, 0, EXPAND_NOTHING, NULL,
- CALLBACK_NONE);
-
- if (typeahead_saved) {
- restore_typeahead(&typeaheadbuf);
- ignore_script = save_ignore_script;
- }
- ex_normal_busy = save_ex_normal_busy;
-
- cmdline_row = msg_row;
- msg_starthere();
- if (cmdline != NULL) {
- // If this is a debug command, set "last_cmd".
- // If not, reset "last_cmd".
- // For a blank line use previous command.
- p = skipwhite(cmdline);
- if (*p != NUL) {
- switch (*p) {
- case 'c': last_cmd = CMD_CONT;
- tail = "ont";
- break;
- case 'n': last_cmd = CMD_NEXT;
- tail = "ext";
- break;
- case 's': last_cmd = CMD_STEP;
- tail = "tep";
- break;
- case 'f':
- last_cmd = 0;
- if (p[1] == 'r') {
- last_cmd = CMD_FRAME;
- tail = "rame";
- } else {
- last_cmd = CMD_FINISH;
- tail = "inish";
- }
- break;
- case 'q': last_cmd = CMD_QUIT;
- tail = "uit";
- break;
- case 'i': last_cmd = CMD_INTERRUPT;
- tail = "nterrupt";
- break;
- case 'b':
- last_cmd = CMD_BACKTRACE;
- if (p[1] == 't') {
- tail = "t";
- } else {
- tail = "acktrace";
- }
- break;
- case 'w':
- last_cmd = CMD_BACKTRACE;
- tail = "here";
- break;
- case 'u':
- last_cmd = CMD_UP;
- tail = "p";
- break;
- case 'd':
- last_cmd = CMD_DOWN;
- tail = "own";
- break;
- default: last_cmd = 0;
- }
- if (last_cmd != 0) {
- // Check that the tail matches.
- p++;
- while (*p != NUL && *p == *tail) {
- p++;
- tail++;
- }
- if (ASCII_ISALPHA(*p) && last_cmd != CMD_FRAME) {
- last_cmd = 0;
- }
- }
- }
-
- if (last_cmd != 0) {
- // Execute debug command: decided where to break next and return.
- switch (last_cmd) {
- case CMD_CONT:
- debug_break_level = -1;
- break;
- case CMD_NEXT:
- debug_break_level = ex_nesting_level;
- break;
- case CMD_STEP:
- debug_break_level = 9999;
- break;
- case CMD_FINISH:
- debug_break_level = ex_nesting_level - 1;
- break;
- case CMD_QUIT:
- got_int = true;
- debug_break_level = -1;
- break;
- case CMD_INTERRUPT:
- got_int = true;
- debug_break_level = 9999;
- // Do not repeat ">interrupt" cmd, continue stepping.
- last_cmd = CMD_STEP;
- break;
- case CMD_BACKTRACE:
- do_showbacktrace(cmd);
- continue;
- case CMD_FRAME:
- if (*p == NUL) {
- do_showbacktrace(cmd);
- } else {
- p = skipwhite(p);
- do_setdebugtracelevel(p);
- }
- continue;
- case CMD_UP:
- debug_backtrace_level++;
- do_checkbacktracelevel();
- continue;
- case CMD_DOWN:
- debug_backtrace_level--;
- do_checkbacktracelevel();
- continue;
- }
- // Going out reset backtrace_level
- debug_backtrace_level = 0;
- break;
- }
-
- // don't debug this command
- n = debug_break_level;
- debug_break_level = -1;
- (void)do_cmdline(cmdline, getexline, NULL,
- DOCMD_VERBOSE|DOCMD_EXCRESET);
- debug_break_level = n;
- }
- lines_left = (int)(Rows - 1);
- }
- xfree(cmdline);
-
- RedrawingDisabled--;
- no_wait_return--;
- redraw_all_later(NOT_VALID);
- need_wait_return = false;
- msg_scroll = save_msg_scroll;
- lines_left = (int)(Rows - 1);
- State = save_State;
- debug_mode = false;
- did_emsg = save_did_emsg;
- cmd_silent = save_cmd_silent;
- msg_silent = save_msg_silent;
- emsg_silent = save_emsg_silent;
- redir_off = save_redir_off;
-
- // Only print the message again when typing a command before coming back here.
- debug_did_msg = true;
-}
-
-static int get_maxbacktrace_level(void)
-{
- int maxbacktrace = 0;
-
- if (sourcing_name != NULL) {
- char *p = (char *)sourcing_name;
- char *q;
- while ((q = strstr(p, "..")) != NULL) {
- p = q + 2;
- maxbacktrace++;
- }
- }
- return maxbacktrace;
-}
-
-static void do_setdebugtracelevel(char_u *arg)
-{
- int level = atoi((char *)arg);
- if (*arg == '+' || level < 0) {
- debug_backtrace_level += level;
- } else {
- debug_backtrace_level = level;
- }
-
- do_checkbacktracelevel();
-}
-
-static void do_checkbacktracelevel(void)
-{
- if (debug_backtrace_level < 0) {
- debug_backtrace_level = 0;
- MSG(_("frame is zero"));
- } else {
- int max = get_maxbacktrace_level();
- if (debug_backtrace_level > max) {
- debug_backtrace_level = max;
- smsg(_("frame at highest level: %d"), max);
- }
- }
-}
-
-static void do_showbacktrace(char_u *cmd)
-{
- if (sourcing_name != NULL) {
- int i = 0;
- int max = get_maxbacktrace_level();
- char *cur = (char *)sourcing_name;
- while (!got_int) {
- char *next = strstr(cur, "..");
- if (next != NULL) {
- *next = NUL;
- }
- if (i == max - debug_backtrace_level) {
- smsg("->%d %s", max - i, cur);
- } else {
- smsg(" %d %s", max - i, cur);
- }
- i++;
- if (next == NULL) {
- break;
- }
- *next = '.';
- cur = next + 2;
- }
- }
- if (sourcing_lnum != 0) {
- smsg(_("line %" PRId64 ": %s"), (int64_t)sourcing_lnum, cmd);
- } else {
- smsg(_("cmd: %s"), cmd);
- }
-}
-
-
-/// ":debug".
-void ex_debug(exarg_T *eap)
-{
- int debug_break_level_save = debug_break_level;
-
- debug_break_level = 9999;
- do_cmdline_cmd((char *)eap->arg);
- debug_break_level = debug_break_level_save;
-}
-
-static char_u *debug_breakpoint_name = NULL;
-static linenr_T debug_breakpoint_lnum;
-
-/// When debugging or a breakpoint is set on a skipped command, no debug prompt
-/// is shown by do_one_cmd(). This situation is indicated by debug_skipped, and
-/// debug_skipped_name is then set to the source name in the breakpoint case. If
-/// a skipped command decides itself that a debug prompt should be displayed, it
-/// can do so by calling dbg_check_skipped().
-static int debug_skipped;
-static char_u *debug_skipped_name;
-
-/// Go to debug mode when a breakpoint was encountered or "ex_nesting_level" is
-/// at or below the break level. But only when the line is actually
-/// executed. Return true and set breakpoint_name for skipped commands that
-/// decide to execute something themselves.
-/// Called from do_one_cmd() before executing a command.
-void dbg_check_breakpoint(exarg_T *eap)
-{
- char_u *p;
-
- debug_skipped = false;
- if (debug_breakpoint_name != NULL) {
- if (!eap->skip) {
- // replace K_SNR with "<SNR>"
- if (debug_breakpoint_name[0] == K_SPECIAL
- && debug_breakpoint_name[1] == KS_EXTRA
- && debug_breakpoint_name[2] == (int)KE_SNR) {
- p = (char_u *)"<SNR>";
- } else {
- p = (char_u *)"";
- }
- smsg(_("Breakpoint in \"%s%s\" line %" PRId64),
- p,
- debug_breakpoint_name + (*p == NUL ? 0 : 3),
- (int64_t)debug_breakpoint_lnum);
- debug_breakpoint_name = NULL;
- do_debug(eap->cmd);
- } else {
- debug_skipped = true;
- debug_skipped_name = debug_breakpoint_name;
- debug_breakpoint_name = NULL;
- }
- } else if (ex_nesting_level <= debug_break_level) {
- if (!eap->skip) {
- do_debug(eap->cmd);
- } else {
- debug_skipped = true;
- debug_skipped_name = NULL;
- }
- }
-}
-
-/// Go to debug mode if skipped by dbg_check_breakpoint() because eap->skip was
-/// set.
-///
-/// @return true when the debug mode is entered this time.
-bool dbg_check_skipped(exarg_T *eap)
-{
- int prev_got_int;
-
- if (debug_skipped) {
- // Save the value of got_int and reset it. We don't want a previous
- // interruption cause flushing the input buffer.
- prev_got_int = got_int;
- got_int = false;
- debug_breakpoint_name = debug_skipped_name;
- // eap->skip is true
- eap->skip = false;
- dbg_check_breakpoint(eap);
- eap->skip = true;
- got_int |= prev_got_int;
- return true;
- }
- return false;
-}
-
-/// The list of breakpoints: dbg_breakp.
-/// This is a grow-array of structs.
-struct debuggy {
- int dbg_nr; ///< breakpoint number
- int dbg_type; ///< DBG_FUNC or DBG_FILE or DBG_EXPR
- char_u *dbg_name; ///< function, expression or file name
- regprog_T *dbg_prog; ///< regexp program
- linenr_T dbg_lnum; ///< line number in function or file
- int dbg_forceit; ///< ! used
- typval_T *dbg_val; ///< last result of watchexpression
- int dbg_level; ///< stored nested level for expr
-};
-
-static garray_T dbg_breakp = { 0, 0, sizeof(struct debuggy), 4, NULL };
-#define BREAKP(idx) (((struct debuggy *)dbg_breakp.ga_data)[idx])
-#define DEBUGGY(gap, idx) (((struct debuggy *)gap->ga_data)[idx])
-static int last_breakp = 0; // nr of last defined breakpoint
-
-// Profiling uses file and func names similar to breakpoints.
-static garray_T prof_ga = { 0, 0, sizeof(struct debuggy), 4, NULL };
-#define DBG_FUNC 1
-#define DBG_FILE 2
-#define DBG_EXPR 3
-
-
-/// Parse the arguments of ":profile", ":breakadd" or ":breakdel" and put them
-/// in the entry just after the last one in dbg_breakp. Note that "dbg_name"
-/// is allocated.
-/// Returns FAIL for failure.
-///
-/// @param arg
-/// @param gap either &dbg_breakp or &prof_ga
-static int dbg_parsearg(char_u *arg, garray_T *gap)
-{
- char_u *p = arg;
- char_u *q;
- struct debuggy *bp;
- bool here = false;
-
- ga_grow(gap, 1);
-
- bp = &DEBUGGY(gap, gap->ga_len);
-
- // Find "func" or "file".
- if (STRNCMP(p, "func", 4) == 0) {
- bp->dbg_type = DBG_FUNC;
- } else if (STRNCMP(p, "file", 4) == 0) {
- bp->dbg_type = DBG_FILE;
- } else if (gap != &prof_ga && STRNCMP(p, "here", 4) == 0) {
- if (curbuf->b_ffname == NULL) {
- EMSG(_(e_noname));
- return FAIL;
- }
- bp->dbg_type = DBG_FILE;
- here = true;
- } else if (gap != &prof_ga && STRNCMP(p, "expr", 4) == 0) {
- bp->dbg_type = DBG_EXPR;
- } else {
- EMSG2(_(e_invarg2), p);
- return FAIL;
- }
- p = skipwhite(p + 4);
-
- // Find optional line number.
- if (here) {
- bp->dbg_lnum = curwin->w_cursor.lnum;
- } else if (gap != &prof_ga && ascii_isdigit(*p)) {
- bp->dbg_lnum = getdigits_long(&p, true, 0);
- p = skipwhite(p);
- } else {
- bp->dbg_lnum = 0;
- }
-
- // Find the function or file name. Don't accept a function name with ().
- if ((!here && *p == NUL)
- || (here && *p != NUL)
- || (bp->dbg_type == DBG_FUNC && strstr((char *)p, "()") != NULL)) {
- EMSG2(_(e_invarg2), arg);
- return FAIL;
- }
-
- if (bp->dbg_type == DBG_FUNC) {
- bp->dbg_name = vim_strsave(p);
- } else if (here) {
- bp->dbg_name = vim_strsave(curbuf->b_ffname);
- } else if (bp->dbg_type == DBG_EXPR) {
- bp->dbg_name = vim_strsave(p);
- bp->dbg_val = eval_expr(bp->dbg_name);
- } else {
- // Expand the file name in the same way as do_source(). This means
- // doing it twice, so that $DIR/file gets expanded when $DIR is
- // "~/dir".
- q = expand_env_save(p);
- if (q == NULL) {
- return FAIL;
- }
- p = expand_env_save(q);
- xfree(q);
- if (p == NULL) {
- return FAIL;
- }
- if (*p != '*') {
- bp->dbg_name = (char_u *)fix_fname((char *)p);
- xfree(p);
- } else {
- bp->dbg_name = p;
- }
- }
-
- if (bp->dbg_name == NULL) {
- return FAIL;
- }
- return OK;
-}
-
-/// ":breakadd". Also used for ":profile".
-void ex_breakadd(exarg_T *eap)
-{
- struct debuggy *bp;
- garray_T *gap;
-
- gap = &dbg_breakp;
- if (eap->cmdidx == CMD_profile) {
- gap = &prof_ga;
- }
-
- if (dbg_parsearg(eap->arg, gap) == OK) {
- bp = &DEBUGGY(gap, gap->ga_len);
- bp->dbg_forceit = eap->forceit;
-
- if (bp->dbg_type != DBG_EXPR) {
- char_u *pat = file_pat_to_reg_pat(bp->dbg_name, NULL, NULL, false);
- if (pat != NULL) {
- bp->dbg_prog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
- xfree(pat);
- }
- if (pat == NULL || bp->dbg_prog == NULL) {
- xfree(bp->dbg_name);
- } else {
- if (bp->dbg_lnum == 0) { // default line number is 1
- bp->dbg_lnum = 1;
- }
- if (eap->cmdidx != CMD_profile) {
- DEBUGGY(gap, gap->ga_len).dbg_nr = ++last_breakp;
- debug_tick++;
- }
- gap->ga_len++;
- }
- } else {
- // DBG_EXPR
- DEBUGGY(gap, gap->ga_len++).dbg_nr = ++last_breakp;
- debug_tick++;
- }
- }
-}
-
-/// ":debuggreedy".
-void ex_debuggreedy(exarg_T *eap)
-{
- if (eap->addr_count == 0 || eap->line2 != 0) {
- debug_greedy = true;
- } else {
- debug_greedy = false;
- }
-}
-
-/// ":breakdel" and ":profdel".
-void ex_breakdel(exarg_T *eap)
-{
- struct debuggy *bp, *bpi;
- int nr;
- int todel = -1;
- bool del_all = false;
- linenr_T best_lnum = 0;
- garray_T *gap;
-
- gap = &dbg_breakp;
- if (eap->cmdidx == CMD_profdel) {
- gap = &prof_ga;
- }
-
- if (ascii_isdigit(*eap->arg)) {
- // ":breakdel {nr}"
- nr = atoi((char *)eap->arg);
- for (int i = 0; i < gap->ga_len; i++) {
- if (DEBUGGY(gap, i).dbg_nr == nr) {
- todel = i;
- break;
- }
- }
- } else if (*eap->arg == '*') {
- todel = 0;
- del_all = true;
- } else {
- // ":breakdel {func|file|expr} [lnum] {name}"
- if (dbg_parsearg(eap->arg, gap) == FAIL) {
- return;
- }
- bp = &DEBUGGY(gap, gap->ga_len);
- for (int i = 0; i < gap->ga_len; i++) {
- bpi = &DEBUGGY(gap, i);
- if (bp->dbg_type == bpi->dbg_type
- && STRCMP(bp->dbg_name, bpi->dbg_name) == 0
- && (bp->dbg_lnum == bpi->dbg_lnum
- || (bp->dbg_lnum == 0
- && (best_lnum == 0
- || bpi->dbg_lnum < best_lnum)))) {
- todel = i;
- best_lnum = bpi->dbg_lnum;
- }
- }
- xfree(bp->dbg_name);
- }
-
- if (todel < 0) {
- EMSG2(_("E161: Breakpoint not found: %s"), eap->arg);
- } else {
- while (!GA_EMPTY(gap)) {
- xfree(DEBUGGY(gap, todel).dbg_name);
- if (DEBUGGY(gap, todel).dbg_type == DBG_EXPR
- && DEBUGGY(gap, todel).dbg_val != NULL) {
- tv_free(DEBUGGY(gap, todel).dbg_val);
- }
- vim_regfree(DEBUGGY(gap, todel).dbg_prog);
- gap->ga_len--;
- if (todel < gap->ga_len) {
- memmove(&DEBUGGY(gap, todel), &DEBUGGY(gap, todel + 1),
- (size_t)(gap->ga_len - todel) * sizeof(struct debuggy));
- }
- if (eap->cmdidx == CMD_breakdel) {
- debug_tick++;
- }
- if (!del_all) {
- break;
- }
- }
-
- // If all breakpoints were removed clear the array.
- if (GA_EMPTY(gap)) {
- ga_clear(gap);
- }
- }
-}
-
-/// ":breaklist".
-void ex_breaklist(exarg_T *eap)
-{
- struct debuggy *bp;
-
- if (GA_EMPTY(&dbg_breakp)) {
- MSG(_("No breakpoints defined"));
- } else {
- for (int i = 0; i < dbg_breakp.ga_len; i++) {
- bp = &BREAKP(i);
- if (bp->dbg_type == DBG_FILE) {
- home_replace(NULL, bp->dbg_name, NameBuff, MAXPATHL, true);
- }
- if (bp->dbg_type != DBG_EXPR) {
- smsg(_("%3d %s %s line %" PRId64),
- bp->dbg_nr,
- bp->dbg_type == DBG_FUNC ? "func" : "file",
- bp->dbg_type == DBG_FUNC ? bp->dbg_name : NameBuff,
- (int64_t)bp->dbg_lnum);
- } else {
- smsg(_("%3d expr %s"), bp->dbg_nr, bp->dbg_name);
- }
- }
- }
-}
-
-/// Find a breakpoint for a function or sourced file.
-/// Returns line number at which to break; zero when no matching breakpoint.
-linenr_T
-dbg_find_breakpoint(
- bool file, // true for a file, false for a function
- char_u *fname, // file or function name
- linenr_T after // after this line number
-)
-{
- return debuggy_find(file, fname, after, &dbg_breakp, NULL);
-}
-
-/// @param file true for a file, false for a function
-/// @param fname file or function name
-/// @param fp[out] forceit
-///
-/// @returns true if profiling is on for a function or sourced file.
-bool has_profiling(bool file, char_u *fname, bool *fp)
-{
- return debuggy_find(file, fname, (linenr_T)0, &prof_ga, fp)
- != (linenr_T)0;
-}
-
-/// Common code for dbg_find_breakpoint() and has_profiling().
-static linenr_T
-debuggy_find(
- bool file, // true for a file, false for a function
- char_u *fname, // file or function name
- linenr_T after, // after this line number
- garray_T *gap, // either &dbg_breakp or &prof_ga
- bool *fp // if not NULL: return forceit
-)
-{
- struct debuggy *bp;
- linenr_T lnum = 0;
- char_u *name = fname;
- int prev_got_int;
-
- // Return quickly when there are no breakpoints.
- if (GA_EMPTY(gap)) {
- return (linenr_T)0;
- }
-
- // Replace K_SNR in function name with "<SNR>".
- if (!file && fname[0] == K_SPECIAL) {
- name = xmalloc(STRLEN(fname) + 3);
- STRCPY(name, "<SNR>");
- STRCPY(name + 5, fname + 3);
- }
-
- for (int i = 0; i < gap->ga_len; i++) {
- // Skip entries that are not useful or are for a line that is beyond
- // an already found breakpoint.
- bp = &DEBUGGY(gap, i);
- if ((bp->dbg_type == DBG_FILE) == file
- && bp->dbg_type != DBG_EXPR
- && (gap == &prof_ga
- || (bp->dbg_lnum > after && (lnum == 0 || bp->dbg_lnum < lnum)))) {
- // Save the value of got_int and reset it. We don't want a
- // previous interruption cancel matching, only hitting CTRL-C
- // while matching should abort it.
- prev_got_int = got_int;
- got_int = false;
- if (vim_regexec_prog(&bp->dbg_prog, false, name, (colnr_T)0)) {
- lnum = bp->dbg_lnum;
- if (fp != NULL) {
- *fp = bp->dbg_forceit;
- }
- }
- got_int |= prev_got_int;
- } else if (bp->dbg_type == DBG_EXPR) {
- bool line = false;
-
- prev_got_int = got_int;
- got_int = false;
-
- typval_T *tv = eval_expr(bp->dbg_name);
- if (tv != NULL) {
- if (bp->dbg_val == NULL) {
- debug_oldval = typval_tostring(NULL);
- bp->dbg_val = tv;
- debug_newval = typval_tostring(bp->dbg_val);
- line = true;
- } else {
- if (typval_compare(tv, bp->dbg_val, EXPR_IS, false) == OK
- && tv->vval.v_number == false) {
- line = true;
- debug_oldval = typval_tostring(bp->dbg_val);
- // Need to evaluate again, typval_compare() overwrites "tv".
- typval_T *v = eval_expr(bp->dbg_name);
- debug_newval = typval_tostring(v);
- tv_free(bp->dbg_val);
- bp->dbg_val = v;
- }
- tv_free(tv);
- }
- } else if (bp->dbg_val != NULL) {
- debug_oldval = typval_tostring(bp->dbg_val);
- debug_newval = typval_tostring(NULL);
- tv_free(bp->dbg_val);
- bp->dbg_val = NULL;
- line = true;
- }
-
- if (line) {
- lnum = after > 0 ? after : 1;
- break;
- }
-
- got_int |= prev_got_int;
- }
- }
- if (name != fname) {
- xfree(name);
- }
-
- return lnum;
-}
-
-/// Called when a breakpoint was encountered.
-void dbg_breakpoint(char_u *name, linenr_T lnum)
-{
- // We need to check if this line is actually executed in do_one_cmd()
- debug_breakpoint_name = name;
- debug_breakpoint_lnum = lnum;
-}
-
-static char_u *profile_fname = NULL;
+static char_u *profile_fname = NULL;
/// ":profile cmd args"
void ex_profile(exarg_T *eap)
{
static proftime_T pause_time;
- char_u *e;
+ char_u *e;
int len;
e = skiptowhite(eap->arg);
@@ -1083,7 +277,7 @@ void set_context_in_profile_cmd(expand_T *xp, const char *arg)
/// Dump the profiling info.
void profile_dump(void)
{
- FILE *fd;
+ FILE *fd;
if (profile_fname != NULL) {
fd = os_fopen((char *)profile_fname, "w");
@@ -1123,7 +317,7 @@ static void profile_reset(void)
}
// Reset functions.
- size_t n = func_hashtab.ht_used;
+ size_t n = func_hashtab.ht_used;
hashitem_T *hi = func_hashtab.ht_array;
for (; n > (size_t)0; hi++) {
@@ -1168,11 +362,11 @@ static void profile_init(scriptitem_T *si)
}
/// Save time when starting to invoke another script or function.
-void script_prof_save(
- proftime_T *tm // place to store wait time
-)
+///
+/// @param tm place to store wait time
+void script_prof_save(proftime_T *tm)
{
- scriptitem_T *si;
+ scriptitem_T *si;
if (current_sctx.sc_sid > 0 && current_sctx.sc_sid <= script_items.ga_len) {
si = &SCRIPT_ITEM(current_sctx.sc_sid);
@@ -1186,7 +380,7 @@ void script_prof_save(
/// Count time spent in children after invoking another script or function.
void script_prof_restore(proftime_T *tm)
{
- scriptitem_T *si;
+ scriptitem_T *si;
if (current_sctx.sc_sid > 0 && current_sctx.sc_sid <= script_items.ga_len) {
si = &SCRIPT_ITEM(current_sctx.sc_sid);
@@ -1218,9 +412,9 @@ void prof_inchar_exit(void)
/// Dump the profiling results for all scripts in file "fd".
static void script_dump_profile(FILE *fd)
{
- scriptitem_T *si;
- FILE *sfd;
- sn_prl_T *pp;
+ scriptitem_T *si;
+ FILE *sfd;
+ sn_prl_T *pp;
for (int id = 1; id <= script_items.ga_len; id++) {
si = &SCRIPT_ITEM(id);
@@ -1460,7 +654,7 @@ bool dialog_close_terminal(buf_T *buf)
int ret = vim_dialog_yesnocancel(VIM_QUESTION, NULL, buff, 1);
- return (ret == VIM_YES) ? true : false;
+ return ret == VIM_YES;
}
/// Return true if the buffer "buf" can be abandoned, either by making it
@@ -1505,7 +699,7 @@ bool check_changed_any(bool hidden, bool unload)
int i;
int bufnum = 0;
size_t bufcount = 0;
- int *bufnrs;
+ int *bufnrs;
// Make a list of all buffers, with the most important ones first.
FOR_ALL_BUFFERS(buf) {
@@ -1635,7 +829,7 @@ int check_fname(void)
int buf_write_all(buf_T *buf, int forceit)
{
int retval;
- buf_T *old_curbuf = curbuf;
+ buf_T *old_curbuf = curbuf;
retval = (buf_write(buf, buf->b_ffname, buf->b_fname,
(linenr_T)1, buf->b_ml.ml_line_count, NULL,
@@ -1658,7 +852,7 @@ int buf_write_all(buf_T *buf, int forceit)
/// Return a pointer to the start of the next argument.
static char_u *do_one_arg(char_u *str)
{
- char_u *p;
+ char_u *p;
bool inbacktick;
inbacktick = false;
@@ -1742,8 +936,8 @@ static int do_arglist(char_u *str, int what, int after, bool will_edit)
{
garray_T new_ga;
int exp_count;
- char_u **exp_files;
- char_u *p;
+ char_u **exp_files;
+ char_u *p;
int match;
int arg_escaped = true;
@@ -1843,9 +1037,8 @@ static bool editing_arg_idx(win_T *win)
|| (win->w_buffer->b_fnum
!= WARGLIST(win)[win->w_arg_idx].ae_fnum
&& (win->w_buffer->b_ffname == NULL
- || !(path_full_compare(
- alist_name(&WARGLIST(win)[win->w_arg_idx]),
- win->w_buffer->b_ffname, true, true) & kEqualFiles))));
+ || !(path_full_compare(alist_name(&WARGLIST(win)[win->w_arg_idx]),
+ win->w_buffer->b_ffname, true, true) & kEqualFiles))));
}
/// Check if window "win" is editing the w_arg_idx file in its argument list.
@@ -1908,7 +1101,7 @@ void ex_args(exarg_T *eap)
xfree(items);
}
} else if (eap->cmdidx == CMD_arglocal) {
- garray_T *gap = &curwin->w_alist->al_ga;
+ garray_T *gap = &curwin->w_alist->al_ga;
// ":argslocal": make a local copy of the global argument list.
ga_grow(gap, GARGCOUNT);
@@ -1964,7 +1157,7 @@ void ex_argument(exarg_T *eap)
void do_argfile(exarg_T *eap, int argn)
{
int other;
- char_u *p;
+ char_u *p;
int old_arg_idx = curwin->w_arg_idx;
if (argn < 0 || argn >= ARGCOUNT) {
@@ -2116,9 +1309,9 @@ void ex_argdelete(exarg_T *eap)
curwin->w_arg_idx = (int)eap->line1;
}
if (ARGCOUNT == 0) {
- curwin->w_arg_idx = 0;
+ curwin->w_arg_idx = 0;
} else if (curwin->w_arg_idx >= ARGCOUNT) {
- curwin->w_arg_idx = ARGCOUNT - 1;
+ curwin->w_arg_idx = ARGCOUNT - 1;
}
}
} else {
@@ -2131,11 +1324,11 @@ void ex_argdelete(exarg_T *eap)
void ex_listdo(exarg_T *eap)
{
int i;
- win_T *wp;
- tabpage_T *tp;
+ win_T *wp;
+ tabpage_T *tp;
int next_fnum = 0;
- char_u *save_ei = NULL;
- char_u *p_shm_save;
+ char_u *save_ei = NULL;
+ char_u *p_shm_save;
if (eap->cmdidx != CMD_windo && eap->cmdidx != CMD_tabdo) {
// Don't do syntax HL autocommands. Skipping the syntax file is a
@@ -2416,9 +1609,9 @@ char_u *get_arglist_name(expand_T *xp FUNC_ATTR_UNUSED, int idx)
/// ":compiler[!] {name}"
void ex_compiler(exarg_T *eap)
{
- char_u *buf;
- char_u *old_cur_comp = NULL;
- char_u *p;
+ char_u *buf;
+ char_u *old_cur_comp = NULL;
+ char_u *p;
if (*eap->arg == NUL) {
// List all compiler scripts.
@@ -2447,10 +1640,10 @@ void ex_compiler(exarg_T *eap)
do_unlet(S_LEN("b:current_compiler"), true);
snprintf((char *)buf, bufsize, "compiler/%s.vim", eap->arg);
- if (source_in_path(p_rtp, buf, DIP_ALL) == FAIL) {
+ if (source_runtime(buf, DIP_ALL) == FAIL) {
// Try lua compiler
snprintf((char *)buf, bufsize, "compiler/%s.lua", eap->arg);
- if (source_in_path(p_rtp, buf, DIP_ALL) == FAIL) {
+ if (source_runtime(buf, DIP_ALL) == FAIL) {
EMSG2(_("E666: compiler not supported: %s"), eap->arg);
}
}
@@ -2509,9 +1702,9 @@ void init_pyxversion(void)
// otherwise return 0.
static int requires_py_version(char_u *filename)
{
- FILE *file;
- int requires_py_version = 0;
- int i, lines;
+ FILE *file;
+ int requires_py_version = 0;
+ int i, lines;
lines = (int)p_mls;
if (lines < 0) {
@@ -2635,44 +1828,42 @@ static void cmd_source(char_u *fname, exarg_T *eap)
}
}
-typedef struct {
- linenr_T curr_lnum;
- const linenr_T final_lnum;
-} GetBufferLineCookie;
-
-/// Get one line from the current selection in the buffer.
-/// Called by do_cmdline() when it's called from cmd_source_buffer().
+/// Concatenate VimL line if it starts with a line continuation into a growarray
+/// (excluding the continuation chars and leading whitespace)
///
-/// @return pointer to allocated line, or NULL for end-of-file or
-/// some error.
-static char_u *get_buffer_line(int c, void *cookie, int indent, bool do_concat)
-{
- GetBufferLineCookie *p = cookie;
- if (p->curr_lnum > p->final_lnum) {
- return NULL;
- }
- char_u *curr_line = ml_get(p->curr_lnum);
- p->curr_lnum++;
- return (char_u *)xstrdup((const char *)curr_line);
-}
-
-static void cmd_source_buffer(const exarg_T *eap)
+/// @note Growsize of the growarray may be changed to speed up concatenations!
+///
+/// @param ga the growarray to append to
+/// @param init_growsize the starting growsize value of the growarray
+/// @param p pointer to the beginning of the line to consider
+/// @param len the length of this line
+///
+/// @return true if this line did begin with a continuation (the next line
+/// should also be considered, if it exists); false otherwise
+static bool concat_continued_line(garray_T *const ga, const int init_growsize,
+ const char_u *const p, size_t len)
FUNC_ATTR_NONNULL_ALL
{
- GetBufferLineCookie cookie = {
- .curr_lnum = eap->line1,
- .final_lnum = eap->line2,
- };
- if (curbuf != NULL && curbuf->b_fname
- && path_with_extension((const char *)curbuf->b_fname, "lua")) {
- nlua_source_using_linegetter(get_buffer_line, (void *)&cookie,
- ":source (no file)");
- } else {
- source_using_linegetter((void *)&cookie, get_buffer_line,
- ":source (no file)");
+ const char_u *const line = skipwhite_len(p, len);
+ len -= (size_t)(line - p);
+ // Skip lines starting with '\" ', concat lines starting with '\'
+ if (len >= 3 && STRNCMP(line, "\"\\ ", 3) == 0) {
+ return true;
+ } else if (len == 0 || line[0] != '\\') {
+ return false;
+ }
+ if (ga->ga_len > init_growsize) {
+ ga_set_growsize(ga, MAX(ga->ga_len, 8000));
}
+ ga_concat_len(ga, (const char *)line + 1, len - 1);
+ return true;
}
+typedef struct {
+ linenr_T curr_lnum;
+ const linenr_T final_lnum;
+} GetBufferLineCookie;
+
/// ":source" and associated commands.
///
/// @return address holding the next breakpoint line for a source cookie
@@ -2725,22 +1916,30 @@ typedef struct {
static char_u *get_str_line(int c, void *cookie, int indent, bool do_concat)
{
GetStrLineCookie *p = cookie;
- size_t i = p->offset;
- if (strlen((char *)p->buf) <= p->offset) {
+ if (STRLEN(p->buf) <= p->offset) {
return NULL;
}
- while (!(p->buf[i] == '\n' || p->buf[i] == '\0')) {
- i++;
+ const char_u *line = p->buf + p->offset;
+ const char_u *eol = skip_to_newline(line);
+ garray_T ga;
+ ga_init(&ga, sizeof(char_u), 400);
+ ga_concat_len(&ga, (const char *)line, (size_t)(eol - line));
+ if (do_concat && vim_strchr(p_cpo, CPO_CONCAT) == NULL) {
+ while (eol[0] != NUL) {
+ line = eol + 1;
+ const char_u *const next_eol = skip_to_newline(line);
+ if (!concat_continued_line(&ga, 400, line, (size_t)(next_eol - line))) {
+ break;
+ }
+ eol = next_eol;
+ }
}
- size_t line_length = i - p->offset;
- char_u *buf = xmemdupz(p->buf + p->offset, line_length);
- p->offset = i + 1;
- return buf;
+ ga_append(&ga, NUL);
+ p->offset = (size_t)(eol - p->buf) + 1;
+ return ga.ga_data;
}
-static int source_using_linegetter(void *cookie,
- LineGetter fgetline,
- const char *traceback_name)
+static int source_using_linegetter(void *cookie, LineGetter fgetline, const char *traceback_name)
{
char_u *save_sourcing_name = sourcing_name;
linenr_T save_sourcing_lnum = sourcing_lnum;
@@ -2749,9 +1948,9 @@ static int source_using_linegetter(void *cookie,
sourcing_name = (char_u *)traceback_name;
} else {
snprintf((char *)sourcing_name_buf, sizeof(sourcing_name_buf),
- "%s called at %s:%"PRIdLINENR, traceback_name, save_sourcing_name,
+ "%s called at %s:%" PRIdLINENR, traceback_name, save_sourcing_name,
save_sourcing_lnum);
- sourcing_name = sourcing_name_buf;
+ sourcing_name = sourcing_name_buf; // -V507 reassigned below, before return.
}
sourcing_lnum = 0;
@@ -2770,14 +1969,48 @@ static int source_using_linegetter(void *cookie,
return retval;
}
+static void cmd_source_buffer(const exarg_T *const eap)
+ FUNC_ATTR_NONNULL_ALL
+{
+ if (curbuf == NULL) {
+ return;
+ }
+ garray_T ga;
+ ga_init(&ga, sizeof(char_u), 400);
+ const linenr_T final_lnum = eap->line2;
+ // Copy the contents to be executed.
+ for (linenr_T curr_lnum = eap->line1; curr_lnum <= final_lnum; curr_lnum++) {
+ // Adjust growsize to current length to speed up concatenating many lines.
+ if (ga.ga_len > 400) {
+ ga_set_growsize(&ga, MAX(ga.ga_len, 8000));
+ }
+ ga_concat(&ga, ml_get(curr_lnum));
+ ga_append(&ga, NL);
+ }
+ ((char_u *)ga.ga_data)[ga.ga_len - 1] = NUL;
+ const GetStrLineCookie cookie = {
+ .buf = ga.ga_data,
+ .offset = 0,
+ };
+ if (curbuf->b_fname
+ && path_with_extension((const char *)curbuf->b_fname, "lua")) {
+ nlua_source_using_linegetter(get_str_line, (void *)&cookie,
+ ":source (no file)");
+ } else {
+ source_using_linegetter((void *)&cookie, get_str_line,
+ ":source (no file)");
+ }
+ ga_clear(&ga);
+}
+
/// Executes lines in `src` as Ex commands.
///
/// @see do_source()
int do_source_str(const char *cmd, const char *traceback_name)
{
GetStrLineCookie cookie = {
- .buf = (char_u *)cmd,
- .offset = 0,
+ .buf = (char_u *)cmd,
+ .offset = 0,
};
return source_using_linegetter((void *)&cookie, get_str_line, traceback_name);
}
@@ -2797,16 +2030,16 @@ int do_source_str(const char *cmd, const char *traceback_name)
int do_source(char_u *fname, int check_other, int is_vimrc)
{
struct source_cookie cookie;
- char_u *save_sourcing_name;
+ char_u *save_sourcing_name;
linenr_T save_sourcing_lnum;
- char_u *p;
- char_u *fname_exp;
- char_u *firstline = NULL;
+ char_u *p;
+ char_u *fname_exp;
+ char_u *firstline = NULL;
int retval = FAIL;
static scid_T last_current_SID = 0;
static int last_current_SID_seq = 0;
int save_debug_break_level = debug_break_level;
- scriptitem_T *si = NULL;
+ scriptitem_T *si = NULL;
proftime_T wait_start;
bool trigger_source_post = false;
@@ -2879,7 +2112,7 @@ int do_source(char_u *fname, int check_other, int is_vimrc)
verbose_leave();
}
if (is_vimrc == DOSO_VIMRC) {
- vimrc_found(fname_exp, (char_u *)"MYVIMRC");
+ vimrc_found((char *)fname_exp, "MYVIMRC");
}
#ifdef USE_CRNL
@@ -3107,7 +2340,7 @@ void ex_scriptnames(exarg_T *eap)
}
}
-# if defined(BACKSLASH_IN_FILENAME)
+#if defined(BACKSLASH_IN_FILENAME)
/// Fix slashes in the list of script names for 'shellslash'.
void scriptnames_slash_adjust(void)
{
@@ -3118,7 +2351,7 @@ void scriptnames_slash_adjust(void)
}
}
-# endif
+#endif
/// Get a pointer to a script name. Used for ":verbose set".
/// Message appended to "Last set from "
@@ -3127,35 +2360,35 @@ char_u *get_scriptname(LastSet last_set, bool *should_free)
*should_free = false;
switch (last_set.script_ctx.sc_sid) {
- case SID_MODELINE:
- return (char_u *)_("modeline");
- case SID_CMDARG:
- return (char_u *)_("--cmd argument");
- case SID_CARG:
- return (char_u *)_("-c argument");
- case SID_ENV:
- return (char_u *)_("environment variable");
- case SID_ERROR:
- return (char_u *)_("error handler");
- case SID_WINLAYOUT:
- return (char_u *)_("changed window size");
- case SID_LUA:
- return (char_u *)_("Lua");
- case SID_API_CLIENT:
- vim_snprintf((char *)IObuff, IOSIZE,
- _("API client (channel id %" PRIu64 ")"),
- last_set.channel_id);
- return IObuff;
- case SID_STR:
- return (char_u *)_("anonymous :source");
- default:
- *should_free = true;
- return home_replace_save(NULL,
- SCRIPT_ITEM(last_set.script_ctx.sc_sid).sn_name);
+ case SID_MODELINE:
+ return (char_u *)_("modeline");
+ case SID_CMDARG:
+ return (char_u *)_("--cmd argument");
+ case SID_CARG:
+ return (char_u *)_("-c argument");
+ case SID_ENV:
+ return (char_u *)_("environment variable");
+ case SID_ERROR:
+ return (char_u *)_("error handler");
+ case SID_WINLAYOUT:
+ return (char_u *)_("changed window size");
+ case SID_LUA:
+ return (char_u *)_("Lua");
+ case SID_API_CLIENT:
+ vim_snprintf((char *)IObuff, IOSIZE,
+ _("API client (channel id %" PRIu64 ")"),
+ last_set.channel_id);
+ return IObuff;
+ case SID_STR:
+ return (char_u *)_("anonymous :source");
+ default:
+ *should_free = true;
+ return home_replace_save(NULL,
+ SCRIPT_ITEM(last_set.script_ctx.sc_sid).sn_name);
}
}
-# if defined(EXITFREE)
+#if defined(EXITFREE)
void free_scriptnames(void)
{
profile_reset();
@@ -3163,11 +2396,11 @@ void free_scriptnames(void)
# define FREE_SCRIPTNAME(item) xfree((item)->sn_name)
GA_DEEP_CLEAR(&script_items, scriptitem_T, FREE_SCRIPTNAME);
}
-# endif
+#endif
linenr_T get_sourced_lnum(LineGetter fgetline, void *cookie)
{
- return fgetline == getsourceline
+ return fgetline == getsourceline
? ((struct source_cookie *)cookie)->sourcing_lnum
: sourcing_lnum;
}
@@ -3227,26 +2460,11 @@ char_u *getsourceline(int c, void *cookie, int indent, bool do_concat)
ga_init(&ga, (int)sizeof(char_u), 400);
ga_concat(&ga, line);
- if (*p == '\\') {
- ga_concat(&ga, p + 1);
- }
- for (;; ) {
+ while (sp->nextline != NULL
+ && concat_continued_line(&ga, 400, sp->nextline,
+ STRLEN(sp->nextline))) {
xfree(sp->nextline);
sp->nextline = get_one_sourceline(sp);
- if (sp->nextline == NULL) {
- break;
- }
- p = skipwhite(sp->nextline);
- if (*p == '\\') {
- // Adjust the growsize to the current length to speed up
- // concatenating many lines.
- if (ga.ga_len > 400) {
- ga_set_growsize(&ga, (ga.ga_len > 8000) ? 8000 : ga.ga_len);
- }
- ga_concat(&ga, p + 1);
- } else if (p[0] != '"' || p[1] != '\\' || p[2] != ' ') {
- break;
- }
}
ga_append(&ga, NUL);
xfree(line);
@@ -3255,7 +2473,7 @@ char_u *getsourceline(int c, void *cookie, int indent, bool do_concat)
}
if (line != NULL && sp->conv.vc_type != CONV_NONE) {
- char_u *s;
+ char_u *s;
// Convert the encoding of the script line.
s = string_convert(&sp->conv, line, NULL);
@@ -3281,7 +2499,7 @@ static char_u *get_one_sourceline(struct source_cookie *sp)
garray_T ga;
int len;
int c;
- char_u *buf;
+ char_u *buf;
#ifdef USE_CRNL
int has_cr; // CR-LF found
#endif
@@ -3384,8 +2602,8 @@ retry:
/// until later and we need to store the time now.
void script_line_start(void)
{
- scriptitem_T *si;
- sn_prl_T *pp;
+ scriptitem_T *si;
+ sn_prl_T *pp;
if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len) {
return;
@@ -3416,7 +2634,7 @@ void script_line_start(void)
/// Called when actually executing a function line.
void script_line_exec(void)
{
- scriptitem_T *si;
+ scriptitem_T *si;
if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len) {
return;
@@ -3430,8 +2648,8 @@ void script_line_exec(void)
/// Called when done with a function line.
void script_line_end(void)
{
- scriptitem_T *si;
- sn_prl_T *pp;
+ scriptitem_T *si;
+ sn_prl_T *pp;
if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len) {
return;
@@ -3456,8 +2674,8 @@ void script_line_end(void)
/// Without the multi-byte feature it's simply ignored.
void ex_scriptencoding(exarg_T *eap)
{
- struct source_cookie *sp;
- char_u *name;
+ struct source_cookie *sp;
+ char_u *name;
if (!getline_equal(eap->getline, eap->cookie, getsourceline)) {
EMSG(_("E167: :scriptencoding used outside of a sourced file"));
@@ -3501,7 +2719,7 @@ void do_finish(exarg_T *eap, int reanimate)
eap->cookie))->finished = false;
}
- // Cleanup (and inactivate) conditionals, but stop when a try conditional
+ // Cleanup (and deactivate) conditionals, but stop when a try conditional
// not in its finally clause (which then is to be executed next) is found.
// In this case, make the ":finish" pending for execution at the ":endtry".
// Otherwise, finish normally.
@@ -3522,14 +2740,13 @@ void do_finish(exarg_T *eap, int reanimate)
bool source_finished(LineGetter fgetline, void *cookie)
{
return getline_equal(fgetline, cookie, getsourceline)
- && ((struct source_cookie *)getline_cookie(
- fgetline, cookie))->finished;
+ && ((struct source_cookie *)getline_cookie(fgetline, cookie))->finished;
}
/// ":checktime [buffer]"
void ex_checktime(exarg_T *eap)
{
- buf_T *buf;
+ buf_T *buf;
int save_no_check_timestamps = no_check_timestamps;
no_check_timestamps = 0;
@@ -3569,17 +2786,17 @@ char *get_mess_lang(void)
{
char *p;
-# ifdef HAVE_GET_LOCALE_VAL
-# if defined(LC_MESSAGES)
+#ifdef HAVE_GET_LOCALE_VAL
+# if defined(LC_MESSAGES)
p = get_locale_val(LC_MESSAGES);
-# else
+# else
// This is necessary for Win32, where LC_MESSAGES is not defined and $LANG
// may be set to the LCID number. LC_COLLATE is the best guess, LC_TIME
// and LC_MONETARY may be set differently for a Japanese working in the
// US.
p = get_locale_val(LC_COLLATE);
-# endif
-# else
+# endif
+#else
p = os_getenv("LC_ALL");
if (!is_valid_mess_lang(p)) {
p = os_getenv("LC_MESSAGES");
@@ -3587,7 +2804,7 @@ char *get_mess_lang(void)
p = os_getenv("LANG");
}
}
-# endif
+#endif
return is_valid_mess_lang(p) ? p : NULL;
}
@@ -3596,7 +2813,7 @@ char *get_mess_lang(void)
/// Get the language used for messages from the environment.
static char_u *get_mess_env(void)
{
- char_u *p;
+ char_u *p;
p = (char_u *)os_getenv("LC_ALL");
if (p == NULL) {
@@ -3625,37 +2842,37 @@ void set_lang_var(void)
{
const char *loc;
-# ifdef HAVE_GET_LOCALE_VAL
+#ifdef HAVE_GET_LOCALE_VAL
loc = get_locale_val(LC_CTYPE);
-# else
+#else
// setlocale() not supported: use the default value
loc = "C";
-# endif
+#endif
set_vim_var_string(VV_CTYPE, loc, -1);
// When LC_MESSAGES isn't defined use the value from $LC_MESSAGES, fall
// back to LC_CTYPE if it's empty.
-# ifdef HAVE_WORKING_LIBINTL
+#ifdef HAVE_WORKING_LIBINTL
loc = (char *)get_mess_env();
-# elif defined(LC_MESSAGES)
+#elif defined(LC_MESSAGES)
loc = get_locale_val(LC_MESSAGES);
-# else
+#else
// In Windows LC_MESSAGES is not defined fallback to LC_CTYPE
loc = get_locale_val(LC_CTYPE);
-# endif
+#endif
set_vim_var_string(VV_LANG, loc, -1);
-# ifdef HAVE_GET_LOCALE_VAL
+#ifdef HAVE_GET_LOCALE_VAL
loc = get_locale_val(LC_TIME);
-# endif
+#endif
set_vim_var_string(VV_LC_TIME, loc, -1);
-# ifdef HAVE_GET_LOCALE_VAL
+#ifdef HAVE_GET_LOCALE_VAL
loc = get_locale_val(LC_COLLATE);
-# else
+#else
// setlocale() not supported: use the default value
loc = "C";
-# endif
+#endif
set_vim_var_string(VV_COLLATE, loc, -1);
}
@@ -3667,16 +2884,16 @@ void set_lang_var(void)
///
void ex_language(exarg_T *eap)
{
- char *loc;
- char_u *p;
- char_u *name;
+ char *loc;
+ char_u *p;
+ char_u *name;
int what = LC_ALL;
- char *whatstr = "";
-#ifdef LC_MESSAGES
-# define VIM_LC_MESSAGES LC_MESSAGES
-#else
-# define VIM_LC_MESSAGES 6789
-#endif
+ char *whatstr = "";
+# ifdef LC_MESSAGES
+# define VIM_LC_MESSAGES LC_MESSAGES
+# else
+# define VIM_LC_MESSAGES 6789
+# endif
name = eap->arg;
@@ -3705,43 +2922,43 @@ void ex_language(exarg_T *eap)
}
if (*name == NUL) {
-#ifdef HAVE_WORKING_LIBINTL
+# ifdef HAVE_WORKING_LIBINTL
if (what == VIM_LC_MESSAGES) {
p = get_mess_env();
} else {
-#endif
- p = (char_u *)setlocale(what, NULL);
-#ifdef HAVE_WORKING_LIBINTL
- }
-#endif
+# endif
+ p = (char_u *)setlocale(what, NULL);
+# ifdef HAVE_WORKING_LIBINTL
+ }
+# endif
if (p == NULL || *p == NUL) {
p = (char_u *)"Unknown";
}
smsg(_("Current %slanguage: \"%s\""), whatstr, p);
} else {
-#ifndef LC_MESSAGES
+# ifndef LC_MESSAGES
if (what == VIM_LC_MESSAGES) {
loc = "";
} else {
-#endif
- loc = setlocale(what, (char *)name);
-#ifdef LC_NUMERIC
- // Make sure strtod() uses a decimal point, not a comma.
- setlocale(LC_NUMERIC, "C");
-#endif
-#ifndef LC_MESSAGES
- }
-#endif
+# endif
+ loc = setlocale(what, (char *)name);
+# ifdef LC_NUMERIC
+ // Make sure strtod() uses a decimal point, not a comma.
+ setlocale(LC_NUMERIC, "C");
+# endif
+# ifndef LC_MESSAGES
+ }
+# endif
if (loc == NULL) {
EMSG2(_("E197: Cannot set language to \"%s\""), name);
} else {
-#ifdef HAVE_NL_MSG_CAT_CNTR
+# ifdef HAVE_NL_MSG_CAT_CNTR
// Need to do this for GNU gettext, otherwise cached translations
// will be used again.
extern int _nl_msg_cat_cntr;
_nl_msg_cat_cntr++;
-#endif
+# endif
// Reset $LC_ALL, otherwise it would overrule everything.
os_setenv("LC_ALL", "", 1);
@@ -3770,7 +2987,7 @@ void ex_language(exarg_T *eap)
static char_u **locales = NULL; // Array of all available locales
-#ifndef WIN32
+# ifndef WIN32
static bool did_init_locales = false;
/// Return an array of strings for all available locales + NULL for the
@@ -3778,7 +2995,7 @@ static bool did_init_locales = false;
static char_u **find_locales(void)
{
garray_T locales_ga;
- char_u *loc;
+ char_u *loc;
char *saveptr = NULL;
// Find all available locales by running command "locale -a". If this
@@ -3805,20 +3022,20 @@ static char_u **find_locales(void)
((char_u **)locales_ga.ga_data)[locales_ga.ga_len] = NULL;
return (char_u **)locales_ga.ga_data;
}
-#endif
+# endif
/// Lazy initialization of all available locales.
static void init_locales(void)
{
-#ifndef WIN32
+# ifndef WIN32
if (!did_init_locales) {
did_init_locales = true;
locales = find_locales();
}
-#endif
+# endif
}
-# if defined(EXITFREE)
+# if defined(EXITFREE)
void free_locales(void)
{
int i;
@@ -3830,7 +3047,7 @@ void free_locales(void)
}
}
-# endif
+# endif
/// Function given to ExpandGeneric() to obtain the possible arguments of the
/// ":language" command.
@@ -3916,7 +3133,7 @@ static void script_host_do_range(char *name, exarg_T *eap)
/// ":drop"
/// Opens the first argument in a window. When there are two or more arguments
/// the argument list is redefined.
-void ex_drop(exarg_T *eap)
+void ex_drop(exarg_T *eap)
{
bool split = false;
buf_T *buf;
diff --git a/src/nvim/ex_cmds_defs.h b/src/nvim/ex_cmds_defs.h
index f928c61ea4..d64b14c9c5 100644
--- a/src/nvim/ex_cmds_defs.h
+++ b/src/nvim/ex_cmds_defs.h
@@ -58,7 +58,7 @@
#define EX_SBOXOK 0x40000 // allowed in the sandbox
#define EX_CMDWIN 0x80000 // allowed in cmdline window; when missing
// disallows editing another buffer when
- // curbuf_lock is set
+ // current buffer is locked
#define EX_MODIFY 0x100000 // forbidden in non-'modifiable' buffer
#define EX_FLAGS 0x200000 // allow flags after count in argument
#define EX_FILES (EX_XFILE | EX_EXTRA) // multiple extra files allowed
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 27c98a13a6..dff3b4223b 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -4,33 +4,43 @@
// ex_docmd.c: functions for executing an Ex command line.
#include <assert.h>
-#include <string.h>
+#include <inttypes.h>
#include <stdbool.h>
#include <stdlib.h>
-#include <inttypes.h>
+#include <string.h>
-#include "nvim/vim.h"
+#include "nvim/api/private/helpers.h"
#include "nvim/ascii.h"
-#include "nvim/ex_docmd.h"
#include "nvim/buffer.h"
#include "nvim/change.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
+#include "nvim/debugger.h"
#include "nvim/diff.h"
#include "nvim/digraph.h"
#include "nvim/edit.h"
#include "nvim/eval.h"
#include "nvim/eval/userfunc.h"
+#include "nvim/event/rstream.h"
+#include "nvim/event/wstream.h"
#include "nvim/ex_cmds.h"
#include "nvim/ex_cmds2.h"
+#include "nvim/ex_cmds_defs.h"
+#include "nvim/ex_docmd.h"
#include "nvim/ex_eval.h"
#include "nvim/ex_getln.h"
+#include "nvim/ex_session.h"
+#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/globals.h"
#include "nvim/hardcopy.h"
#include "nvim/if_cscope.h"
+#include "nvim/keymap.h"
+#include "nvim/lua/executor.h"
#include "nvim/main.h"
#include "nvim/mark.h"
#include "nvim/mbyte.h"
@@ -39,20 +49,21 @@
#include "nvim/menu.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/ex_session.h"
-#include "nvim/keymap.h"
-#include "nvim/file_search.h"
-#include "nvim/garray.h"
+#include "nvim/mouse.h"
#include "nvim/move.h"
#include "nvim/normal.h"
#include "nvim/ops.h"
#include "nvim/option.h"
+#include "nvim/os/input.h"
+#include "nvim/os/os.h"
+#include "nvim/os/time.h"
#include "nvim/os_unix.h"
#include "nvim/path.h"
#include "nvim/quickfix.h"
#include "nvim/regexp.h"
#include "nvim/screen.h"
#include "nvim/search.h"
+#include "nvim/shada.h"
#include "nvim/sign.h"
#include "nvim/spell.h"
#include "nvim/spellfile.h"
@@ -63,47 +74,37 @@
#include "nvim/ui.h"
#include "nvim/undo.h"
#include "nvim/version.h"
+#include "nvim/vim.h"
#include "nvim/window.h"
-#include "nvim/os/os.h"
-#include "nvim/os/input.h"
-#include "nvim/os/time.h"
-#include "nvim/ex_cmds_defs.h"
-#include "nvim/mouse.h"
-#include "nvim/event/rstream.h"
-#include "nvim/event/wstream.h"
-#include "nvim/shada.h"
-#include "nvim/lua/executor.h"
-#include "nvim/globals.h"
-#include "nvim/api/private/helpers.h"
static int quitmore = 0;
static bool ex_pressedreturn = false;
typedef struct ucmd {
- char_u *uc_name; // The command name
+ char_u *uc_name; // The command name
uint32_t uc_argt; // The argument type
- char_u *uc_rep; // The command's replacement string
+ char_u *uc_rep; // The command's replacement string
long uc_def; // The default value for a range/count
int uc_compl; // completion type
cmd_addr_T uc_addr_type; // The command's address type
sctx_T uc_script_ctx; // SCTX where the command was defined
- char_u *uc_compl_arg; // completion argument if any
+ char_u *uc_compl_arg; // completion argument if any
} ucmd_T;
-#define UC_BUFFER 1 /* -buffer: local to current buffer */
+#define UC_BUFFER 1 // -buffer: local to current buffer
-static garray_T ucmds = {0, 0, sizeof(ucmd_T), 4, NULL};
+static garray_T ucmds = { 0, 0, sizeof(ucmd_T), 4, NULL };
#define USER_CMD(i) (&((ucmd_T *)(ucmds.ga_data))[i])
#define USER_CMD_GA(gap, i) (&((ucmd_T *)((gap)->ga_data))[i])
-/* Wether a command index indicates a user command. */
-# define IS_USER_CMDIDX(idx) ((int)(idx) < 0)
+// Whether a command index indicates a user command.
+#define IS_USER_CMDIDX(idx) ((int)(idx) < 0)
-/* Struct for storing a line inside a while/for loop */
+// Struct for storing a line inside a while/for loop
typedef struct {
- char_u *line; /* command line */
- linenr_T lnum; /* sourcing_lnum of the line */
+ char_u *line; // command line
+ linenr_T lnum; // sourcing_lnum of the line
} wcmd_T;
#define FREE_WCMD(wcmd) xfree((wcmd)->line)
@@ -114,27 +115,27 @@ typedef struct {
* reads more lines that may come from the while/for loop.
*/
struct loop_cookie {
- garray_T *lines_gap; // growarray with line info
+ garray_T *lines_gap; // growarray with line info
int current_line; // last read line from growarray
int repeating; // TRUE when looping a second time
// When "repeating" is FALSE use "getline" and "cookie" to get lines
- char_u *(*getline)(int, void *, int, bool);
- void *cookie;
+ char_u *(*getline)(int, void *, int, bool);
+ void *cookie;
};
-/* Struct to save a few things while debugging. Used in do_cmdline() only. */
+// Struct to save a few things while debugging. Used in do_cmdline() only.
struct dbg_stuff {
int trylevel;
int force_abort;
- except_T *caught_stack;
- char_u *vv_exception;
- char_u *vv_throwpoint;
+ except_T *caught_stack;
+ char_u *vv_exception;
+ char_u *vv_throwpoint;
int did_emsg;
int got_int;
int need_rethrow;
int check_cstack;
- except_T *current_exception;
+ except_T *current_exception;
};
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -152,7 +153,7 @@ struct dbg_stuff {
# include "ex_cmds_defs.generated.h"
#endif
-static char_u dollar_command[2] = {'$', 0};
+static char_u dollar_command[2] = { '$', 0 };
static void save_dbg_stuff(struct dbg_stuff *dsp)
{
@@ -186,23 +187,21 @@ static void restore_dbg_stuff(struct dbg_stuff *dsp)
}
/// Repeatedly get commands for Ex mode, until the ":vi" command is given.
-void do_exmode(int improved)
+void do_exmode(void)
{
int save_msg_scroll;
int prev_msg_row;
linenr_T prev_line;
int changedtick;
- if (improved)
- exmode_active = EXMODE_VIM;
- else
- exmode_active = EXMODE_NORMAL;
+ exmode_active = true;
State = NORMAL;
/* When using ":global /pat/ visual" and then "Q" we return to continue
* the :global command. */
- if (global_busy)
+ if (global_busy) {
return;
+ }
save_msg_scroll = msg_scroll;
RedrawingDisabled++; // don't redisplay the window
@@ -210,9 +209,9 @@ void do_exmode(int improved)
MSG(_("Entering Ex mode. Type \"visual\" to go to Normal mode."));
while (exmode_active) {
- /* Check for a ":normal" command and no more characters left. */
+ // Check for a ":normal" command and no more characters left.
if (ex_normal_busy > 0 && typebuf.tb_len == 0) {
- exmode_active = 0;
+ exmode_active = false;
break;
}
msg_scroll = true;
@@ -235,18 +234,20 @@ void do_exmode(int improved)
/* go up one line, to overwrite the ":<CR>" line, so the
* output doesn't contain empty lines. */
msg_row = prev_msg_row;
- if (prev_msg_row == Rows - 1)
+ if (prev_msg_row == Rows - 1) {
msg_row--;
+ }
}
msg_col = 0;
print_line_no_prefix(curwin->w_cursor.lnum, FALSE, FALSE);
msg_clr_eos();
}
- } else if (ex_pressedreturn && !ex_no_reprint) { /* must be at EOF */
- if (curbuf->b_ml.ml_flags & ML_EMPTY)
+ } else if (ex_pressedreturn && !ex_no_reprint) { // must be at EOF
+ if (curbuf->b_ml.ml_flags & ML_EMPTY) {
EMSG(_(e_emptybuf));
- else
+ } else {
EMSG(_("E501: At end-of-file"));
+ }
}
}
@@ -303,40 +304,41 @@ int do_cmdline_cmd(const char *cmd)
/// DOCMD_KEYTYPED - Don't reset KeyTyped.
/// DOCMD_EXCRESET - Reset the exception environment (used for debugging).
/// DOCMD_KEEPLINE - Store first typed line (for repeating with ".").
+/// DOCMD_PREVIEW - During 'inccommand' preview.
+///
+/// @param cookie argument for fgetline()
///
/// @return FAIL if cmdline could not be executed, OK otherwise
-int do_cmdline(char_u *cmdline, LineGetter fgetline,
- void *cookie, /* argument for fgetline() */
- int flags)
-{
- char_u *next_cmdline; /* next cmd to execute */
- char_u *cmdline_copy = NULL; /* copy of cmd line */
- int used_getline = FALSE; /* used "fgetline" to obtain command */
- static int recursive = 0; /* recursive depth */
- int msg_didout_before_start = 0;
- int count = 0; /* line number count */
- int did_inc = FALSE; /* incremented RedrawingDisabled */
+int do_cmdline(char_u *cmdline, LineGetter fgetline, void *cookie, int flags)
+{
+ char_u *next_cmdline; // next cmd to execute
+ char_u *cmdline_copy = NULL; // copy of cmd line
+ bool used_getline = false; // used "fgetline" to obtain command
+ static int recursive = 0; // recursive depth
+ bool msg_didout_before_start = false;
+ int count = 0; // line number count
+ int did_inc = FALSE; // incremented RedrawingDisabled
int retval = OK;
cstack_T cstack = { // conditional stack
.cs_idx = -1,
};
garray_T lines_ga; // keep lines for ":while"/":for"
int current_line = 0; // active line in lines_ga
- char_u *fname = NULL; // function or script name
+ char_u *fname = NULL; // function or script name
linenr_T *breakpoint = NULL; // ptr to breakpoint field in cookie
- int *dbg_tick = NULL; // ptr to dbg_tick field in cookie
+ int *dbg_tick = NULL; // ptr to dbg_tick field in cookie
struct dbg_stuff debug_saved; // saved things for debug mode
int initial_trylevel;
- struct msglist **saved_msg_list = NULL;
- struct msglist *private_msg_list;
+ struct msglist **saved_msg_list = NULL;
+ struct msglist *private_msg_list;
// "fgetline" and "cookie" passed to do_one_cmd()
- char_u *(*cmd_getline)(int, void *, int, bool);
- void *cmd_cookie;
+ char_u *(*cmd_getline)(int, void *, int, bool);
+ void *cmd_cookie;
struct loop_cookie cmd_loop_cookie;
- void *real_cookie;
+ void *real_cookie;
int getline_is_func;
- static int call_depth = 0; /* recursiveness */
+ static int call_depth = 0; // recursiveness
/* For every pair of do_cmdline()/do_one_cmd() calls, use an extra memory
* location for storing error messages to be converted to an exception.
@@ -366,10 +368,11 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
real_cookie = getline_cookie(fgetline, cookie);
- /* Inside a function use a higher nesting level. */
+ // Inside a function use a higher nesting level.
getline_is_func = getline_equal(fgetline, cookie, get_func_line);
- if (getline_is_func && ex_nesting_level == func_level(real_cookie))
+ if (getline_is_func && ex_nesting_level == func_level(real_cookie)) {
++ex_nesting_level;
+ }
/* Get the function or script name and the address where the next breakpoint
* line and the debug tick for a function or script are stored. */
@@ -425,13 +428,14 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
do {
getline_is_func = getline_equal(fgetline, cookie, get_func_line);
- /* stop skipping cmds for an error msg after all endif/while/for */
+ // stop skipping cmds for an error msg after all endif/while/for
if (next_cmdline == NULL
&& !force_abort
&& cstack.cs_idx < 0
- && !(getline_is_func && func_has_abort(real_cookie))
- )
+ && !(getline_is_func &&
+ func_has_abort(real_cookie))) {
did_emsg = FALSE;
+ }
/*
* 1. If repeating a line in a loop, get a line from lines_ga.
@@ -439,7 +443,7 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
* 3. If a line is given: Make a copy, so we can mess with it.
*/
- /* 1. If repeating, get a previous line from lines_ga. */
+ // 1. If repeating, get a previous line from lines_ga.
if (cstack.cs_looplevel > 0 && current_line < lines_ga.ga_len) {
/* Each '|' separated command is stored separately in lines_ga, to
* be able to jump to it. Don't use next_cmdline now. */
@@ -448,49 +452,50 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
/* Check if a function has returned or, unless it has an unclosed
* try conditional, aborted. */
if (getline_is_func) {
- if (do_profiling == PROF_YES)
+ if (do_profiling == PROF_YES) {
func_line_end(real_cookie);
+ }
if (func_has_ended(real_cookie)) {
retval = FAIL;
break;
}
} else if (do_profiling == PROF_YES
- && getline_equal(fgetline, cookie, getsourceline))
+ && getline_equal(fgetline, cookie, getsourceline)) {
script_line_end();
+ }
- /* Check if a sourced file hit a ":finish" command. */
+ // Check if a sourced file hit a ":finish" command.
if (source_finished(fgetline, cookie)) {
retval = FAIL;
break;
}
- /* If breakpoints have been added/deleted need to check for it. */
+ // If breakpoints have been added/deleted need to check for it.
if (breakpoint != NULL && dbg_tick != NULL
&& *dbg_tick != debug_tick) {
- *breakpoint = dbg_find_breakpoint(
- getline_equal(fgetline, cookie, getsourceline),
- fname, sourcing_lnum);
+ *breakpoint = dbg_find_breakpoint(getline_equal(fgetline, cookie, getsourceline),
+ fname, sourcing_lnum);
*dbg_tick = debug_tick;
}
next_cmdline = ((wcmd_T *)(lines_ga.ga_data))[current_line].line;
sourcing_lnum = ((wcmd_T *)(lines_ga.ga_data))[current_line].lnum;
- /* Did we encounter a breakpoint? */
+ // Did we encounter a breakpoint?
if (breakpoint != NULL && *breakpoint != 0
&& *breakpoint <= sourcing_lnum) {
dbg_breakpoint(fname, sourcing_lnum);
- /* Find next breakpoint. */
- *breakpoint = dbg_find_breakpoint(
- getline_equal(fgetline, cookie, getsourceline),
- fname, sourcing_lnum);
+ // Find next breakpoint.
+ *breakpoint = dbg_find_breakpoint(getline_equal(fgetline, cookie, getsourceline),
+ fname, sourcing_lnum);
*dbg_tick = debug_tick;
}
if (do_profiling == PROF_YES) {
- if (getline_is_func)
+ if (getline_is_func) {
func_line_start(real_cookie);
- else if (getline_equal(fgetline, cookie, getsourceline))
+ } else if (getline_equal(fgetline, cookie, getsourceline)) {
script_line_start();
+ }
}
}
@@ -512,7 +517,7 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
cmd_cookie = cookie;
}
- /* 2. If no line given, get an allocated line with fgetline(). */
+ // 2. If no line given, get an allocated line with fgetline().
if (next_cmdline == NULL) {
/*
* Need to set msg_didout for the first line after an ":if",
@@ -535,20 +540,21 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
retval = FAIL;
break;
}
- used_getline = TRUE;
+ used_getline = true;
/*
* Keep the first typed line. Clear it when more lines are typed.
*/
if (flags & DOCMD_KEEPLINE) {
xfree(repeat_cmdline);
- if (count == 0)
+ if (count == 0) {
repeat_cmdline = vim_strsave(next_cmdline);
- else
+ } else {
repeat_cmdline = NULL;
+ }
}
}
- /* 3. Make a copy of the command so we can mess with it. */
+ // 3. Make a copy of the command so we can mess with it.
else if (cmdline_copy == NULL) {
next_cmdline = vim_strsave(next_cmdline);
}
@@ -565,7 +571,7 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
&& (cstack.cs_looplevel || has_loop_cmd(next_cmdline))) {
store_loop_line(&lines_ga, next_cmdline);
}
- did_endif = FALSE;
+ did_endif = false;
if (count++ == 0) {
/*
@@ -576,10 +582,10 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
*/
if (!(flags & DOCMD_NOWAIT) && !recursive) {
msg_didout_before_start = msg_didout;
- msg_didany = FALSE; /* no output yet */
+ msg_didany = false; // no output yet
msg_start();
- msg_scroll = TRUE; /* put messages below each other */
- ++no_wait_return; /* don't wait for return until finished */
+ msg_scroll = TRUE; // put messages below each other
+ ++no_wait_return; // don't wait for return until finished
++RedrawingDisabled;
did_inc = TRUE;
}
@@ -601,14 +607,15 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
recursive--;
// Ignore trailing '|'-separated commands in preview-mode ('inccommand').
- if (State & CMDPREVIEW) {
+ if ((State & CMDPREVIEW) && (flags & DOCMD_PREVIEW)) {
next_cmdline = NULL;
}
- if (cmd_cookie == (void *)&cmd_loop_cookie)
+ if (cmd_cookie == (void *)&cmd_loop_cookie) {
/* Use "current_line" from "cmd_loop_cookie", it may have been
* incremented when defining a function. */
current_line = cmd_loop_cookie.current_line;
+ }
if (next_cmdline == NULL) {
XFREE_CLEAR(cmdline_copy);
@@ -630,11 +637,12 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
}
- /* reset did_emsg for a function that is not aborted by an error */
+ // reset did_emsg for a function that is not aborted by an error
if (did_emsg && !force_abort
&& getline_equal(fgetline, cookie, get_func_line)
- && !func_has_abort(real_cookie))
+ && !func_has_abort(real_cookie)) {
did_emsg = FALSE;
+ }
if (cstack.cs_looplevel > 0) {
++current_line;
@@ -659,24 +667,24 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
&& cstack.cs_line[cstack.cs_idx] >= 0
&& (cstack.cs_flags[cstack.cs_idx] & CSF_ACTIVE)) {
current_line = cstack.cs_line[cstack.cs_idx];
- /* remember we jumped there */
+ // remember we jumped there
cstack.cs_lflags |= CSL_HAD_LOOP;
- line_breakcheck(); /* check if CTRL-C typed */
+ line_breakcheck(); // check if CTRL-C typed
/* Check for the next breakpoint at or after the ":while"
* or ":for". */
if (breakpoint != NULL) {
- *breakpoint = dbg_find_breakpoint(
- getline_equal(fgetline, cookie, getsourceline),
- fname,
- ((wcmd_T *)lines_ga.ga_data)[current_line].lnum-1);
+ *breakpoint = dbg_find_breakpoint(getline_equal(fgetline, cookie, getsourceline),
+ fname,
+ ((wcmd_T *)lines_ga.ga_data)[current_line].lnum-1);
*dbg_tick = debug_tick;
}
} else {
- /* can only get here with ":endwhile" or ":endfor" */
- if (cstack.cs_idx >= 0)
+ // can only get here with ":endwhile" or ":endfor"
+ if (cstack.cs_idx >= 0) {
rewind_conditionals(&cstack, cstack.cs_idx - 1,
- CSF_WHILE | CSF_FOR, &cstack.cs_looplevel);
+ CSF_WHILE | CSF_FOR, &cstack.cs_looplevel);
+ }
}
}
/*
@@ -729,9 +737,8 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
force_abort = false;
}
- /* Convert an interrupt to an exception if appropriate. */
+ // Convert an interrupt to an exception if appropriate.
(void)do_intthrow(&cstack);
-
}
/*
* Continue executing command lines when:
@@ -750,14 +757,13 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
* the :endtry to be missed. */
&& (cstack.cs_trylevel == 0 || did_emsg_syntax)
&& used_getline
- && (getline_equal(fgetline, cookie, getexmodeline)
- || getline_equal(fgetline, cookie, getexline)))
+ && getline_equal(fgetline, cookie, getexline))
&& (next_cmdline != NULL
|| cstack.cs_idx >= 0
|| (flags & DOCMD_REPEAT)));
xfree(cmdline_copy);
- did_emsg_syntax = FALSE;
+ did_emsg_syntax = false;
GA_DEEP_CLEAR(&lines_ga, wcmd_T, FREE_WCMD);
if (cstack.cs_idx >= 0) {
@@ -770,14 +776,15 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
&& !source_finished(fgetline, cookie))
|| (getline_equal(fgetline, cookie, get_func_line)
&& !func_has_ended(real_cookie)))) {
- if (cstack.cs_flags[cstack.cs_idx] & CSF_TRY)
+ if (cstack.cs_flags[cstack.cs_idx] & CSF_TRY) {
EMSG(_(e_endtry));
- else if (cstack.cs_flags[cstack.cs_idx] & CSF_WHILE)
+ } else if (cstack.cs_flags[cstack.cs_idx] & CSF_WHILE) {
EMSG(_(e_endwhile));
- else if (cstack.cs_flags[cstack.cs_idx] & CSF_FOR)
+ } else if (cstack.cs_flags[cstack.cs_idx] & CSF_FOR) {
EMSG(_(e_endfor));
- else
+ } else {
EMSG(_(e_endif));
+ }
}
/*
@@ -790,10 +797,11 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
do {
int idx = cleanup_conditionals(&cstack, 0, TRUE);
- if (idx >= 0)
- --idx; /* remove try block not in its finally clause */
+ if (idx >= 0) {
+ --idx; // remove try block not in its finally clause
+ }
rewind_conditionals(&cstack, idx, CSF_WHILE | CSF_FOR,
- &cstack.cs_looplevel);
+ &cstack.cs_looplevel);
} while (cstack.cs_idx >= 0);
trylevel = initial_trylevel;
}
@@ -825,8 +833,8 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
switch (current_exception->type) {
case ET_USER:
vim_snprintf((char *)IObuff, IOSIZE,
- _("E605: Exception not caught: %s"),
- current_exception->value);
+ _("E605: Exception not caught: %s"),
+ current_exception->value);
p = vim_strsave(IObuff);
break;
case ET_ERROR:
@@ -890,27 +898,30 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
check_cstack = true;
}
} else {
- /* When leaving a function, reduce nesting level. */
- if (getline_equal(fgetline, cookie, get_func_line))
+ // When leaving a function, reduce nesting level.
+ if (getline_equal(fgetline, cookie, get_func_line)) {
--ex_nesting_level;
+ }
/*
* Go to debug mode when returning from a function in which we are
* single-stepping.
*/
if ((getline_equal(fgetline, cookie, getsourceline)
|| getline_equal(fgetline, cookie, get_func_line))
- && ex_nesting_level + 1 <= debug_break_level)
+ && ex_nesting_level + 1 <= debug_break_level) {
do_debug(getline_equal(fgetline, cookie, getsourceline)
? (char_u *)_("End of sourced file")
: (char_u *)_("End of function"));
+ }
}
/*
* Restore the exception environment (done after returning from the
* debugger).
*/
- if (flags & DOCMD_EXCRESET)
+ if (flags & DOCMD_EXCRESET) {
restore_dbg_stuff(&debug_saved);
+ }
msg_list = saved_msg_list;
@@ -929,10 +940,9 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
* wait for hit-return. Also for an error situation.
*/
if (retval == FAIL
- || (did_endif && KeyTyped && !did_emsg)
- ) {
- need_wait_return = FALSE;
- msg_didany = FALSE; /* don't wait when restarting edit */
+ || (did_endif && KeyTyped && !did_emsg)) {
+ need_wait_return = false;
+ msg_didany = false; // don't wait when restarting edit
} else if (need_wait_return) {
/*
* The msg_start() above clears msg_didout. The wait_return we do
@@ -944,7 +954,7 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
}
}
- did_endif = FALSE; /* in case do_cmdline used recursively */
+ did_endif = false; // in case do_cmdline used recursively
call_depth--;
end_batch_changes();
@@ -956,14 +966,14 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
*/
static char_u *get_loop_line(int c, void *cookie, int indent, bool do_concat)
{
- struct loop_cookie *cp = (struct loop_cookie *)cookie;
- wcmd_T *wp;
- char_u *line;
+ struct loop_cookie *cp = (struct loop_cookie *)cookie;
+ wcmd_T *wp;
+ char_u *line;
if (cp->current_line + 1 >= cp->lines_gap->ga_len) {
- if (cp->repeating)
- return NULL; /* trying to read past ":endwhile"/":endfor" */
-
+ if (cp->repeating) {
+ return NULL; // trying to read past ":endwhile"/":endfor"
+ }
// First time inside the ":while"/":for": get line normally.
if (cp->getline == NULL) {
line = getcmdline(c, 0L, indent, do_concat);
@@ -995,13 +1005,11 @@ static void store_loop_line(garray_T *gap, char_u *line)
p->lnum = sourcing_lnum;
}
-/*
- * If "fgetline" is get_loop_line(), return TRUE if the getline it uses equals
- * "func". * Otherwise return TRUE when "fgetline" equals "func".
- */
-int getline_equal(LineGetter fgetline,
- void *cookie, /* argument for fgetline() */
- LineGetter func)
+/// If "fgetline" is get_loop_line(), return TRUE if the getline it uses equals
+/// "func". * Otherwise return TRUE when "fgetline" equals "func".
+///
+/// @param cookie argument for fgetline()
+int getline_equal(LineGetter fgetline, void *cookie, LineGetter func)
{
LineGetter gp;
struct loop_cookie *cp;
@@ -1018,13 +1026,11 @@ int getline_equal(LineGetter fgetline,
return gp == func;
}
-/*
- * If "fgetline" is get_loop_line(), return the cookie used by the original
- * getline function. Otherwise return "cookie".
- */
-void * getline_cookie(LineGetter fgetline,
- void *cookie /* argument for fgetline() */
- )
+/// If "fgetline" is get_loop_line(), return the cookie used by the original
+/// getline function. Otherwise return "cookie".
+///
+/// @param cookie argument for fgetline()
+void *getline_cookie(LineGetter fgetline, void *cookie)
{
LineGetter gp;
struct loop_cookie *cp;
@@ -1053,16 +1059,18 @@ static int compute_buffer_local_count(int addr_type, int lnum, int offset)
int count = offset;
buf = firstbuf;
- while (buf->b_next != NULL && buf->b_fnum < lnum)
+ while (buf->b_next != NULL && buf->b_fnum < lnum) {
buf = buf->b_next;
+ }
while (count != 0) {
count += (count < 0) ? 1 : -1;
nextbuf = (offset < 0) ? buf->b_prev : buf->b_next;
- if (nextbuf == NULL)
+ if (nextbuf == NULL) {
break;
+ }
buf = nextbuf;
- if (addr_type == ADDR_LOADED_BUFFERS)
- /* skip over unloaded buffers */
+ if (addr_type == ADDR_LOADED_BUFFERS) {
+ // skip over unloaded buffers
while (buf->b_ml.ml_mfp == NULL) {
nextbuf = (offset < 0) ? buf->b_prev : buf->b_next;
if (nextbuf == NULL) {
@@ -1070,13 +1078,15 @@ static int compute_buffer_local_count(int addr_type, int lnum, int offset)
}
buf = nextbuf;
}
+ }
}
// we might have gone too far, last buffer is not loaded
if (addr_type == ADDR_LOADED_BUFFERS) {
while (buf->b_ml.ml_mfp == NULL) {
nextbuf = (offset >= 0) ? buf->b_prev : buf->b_next;
- if (nextbuf == NULL)
+ if (nextbuf == NULL) {
break;
+ }
buf = nextbuf;
}
}
@@ -1092,8 +1102,9 @@ static int current_win_nr(const win_T *win)
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
++nr;
- if (wp == win)
+ if (wp == win) {
break;
+ }
}
return nr;
}
@@ -1104,8 +1115,9 @@ static int current_tab_nr(tabpage_T *tab)
FOR_ALL_TABS(tp) {
++nr;
- if (tp == tab)
+ if (tp == tab) {
break;
+ }
}
return nr;
}
@@ -1120,87 +1132,87 @@ static int current_tab_nr(tabpage_T *tab)
static void get_wincmd_addr_type(char_u *arg, exarg_T *eap)
{
switch (*arg) {
- case 'S':
- case Ctrl_S:
- case 's':
- case Ctrl_N:
- case 'n':
- case 'j':
- case Ctrl_J:
- case 'k':
- case Ctrl_K:
- case 'T':
- case Ctrl_R:
- case 'r':
- case 'R':
- case 'K':
- case 'J':
- case '+':
- case '-':
- case Ctrl__:
- case '_':
- case '|':
- case ']':
- case Ctrl_RSB:
- case 'g':
- case Ctrl_G:
- case Ctrl_V:
- case 'v':
- case 'h':
- case Ctrl_H:
- case 'l':
- case Ctrl_L:
- case 'H':
- case 'L':
- case '>':
- case '<':
- case '}':
- case 'f':
- case 'F':
- case Ctrl_F:
- case 'i':
- case Ctrl_I:
- case 'd':
- case Ctrl_D:
- // window size or any count
- eap->addr_type = ADDR_OTHER; // -V1037
- break;
+ case 'S':
+ case Ctrl_S:
+ case 's':
+ case Ctrl_N:
+ case 'n':
+ case 'j':
+ case Ctrl_J:
+ case 'k':
+ case Ctrl_K:
+ case 'T':
+ case Ctrl_R:
+ case 'r':
+ case 'R':
+ case 'K':
+ case 'J':
+ case '+':
+ case '-':
+ case Ctrl__:
+ case '_':
+ case '|':
+ case ']':
+ case Ctrl_RSB:
+ case 'g':
+ case Ctrl_G:
+ case Ctrl_V:
+ case 'v':
+ case 'h':
+ case Ctrl_H:
+ case 'l':
+ case Ctrl_L:
+ case 'H':
+ case 'L':
+ case '>':
+ case '<':
+ case '}':
+ case 'f':
+ case 'F':
+ case Ctrl_F:
+ case 'i':
+ case Ctrl_I:
+ case 'd':
+ case Ctrl_D:
+ // window size or any count
+ eap->addr_type = ADDR_OTHER; // -V1037
+ break;
- case Ctrl_HAT:
- case '^':
- // buffer number
- eap->addr_type = ADDR_BUFFERS;
- break;
+ case Ctrl_HAT:
+ case '^':
+ // buffer number
+ eap->addr_type = ADDR_BUFFERS;
+ break;
- case Ctrl_Q:
- case 'q':
- case Ctrl_C:
- case 'c':
- case Ctrl_O:
- case 'o':
- case Ctrl_W:
- case 'w':
- case 'W':
- case 'x':
- case Ctrl_X:
- // window number
- eap->addr_type = ADDR_WINDOWS;
- break;
+ case Ctrl_Q:
+ case 'q':
+ case Ctrl_C:
+ case 'c':
+ case Ctrl_O:
+ case 'o':
+ case Ctrl_W:
+ case 'w':
+ case 'W':
+ case 'x':
+ case Ctrl_X:
+ // window number
+ eap->addr_type = ADDR_WINDOWS;
+ break;
- case Ctrl_Z:
- case 'z':
- case 'P':
- case 't':
- case Ctrl_T:
- case 'b':
- case Ctrl_B:
- case 'p':
- case Ctrl_P:
- case '=':
- case CAR:
- // no count
- eap->addr_type = ADDR_NONE;
- break;
+ case Ctrl_Z:
+ case 'z':
+ case 'P':
+ case 't':
+ case Ctrl_T:
+ case 'b':
+ case Ctrl_B:
+ case 'p':
+ case Ctrl_P:
+ case '=':
+ case CAR:
+ // no count
+ eap->addr_type = ADDR_NONE;
+ break;
}
}
@@ -1221,54 +1233,51 @@ static char_u *skip_colon_white(const char_u *p, bool skipleadingwhite)
return (char_u *)p;
}
-/*
- * Execute one Ex command.
- *
- * If 'sourcing' is TRUE, the command will be included in the error message.
- *
- * 1. skip comment lines and leading space
- * 2. handle command modifiers
- * 3. skip over the range to find the command
- * 4. parse the range
- * 5. parse the command
- * 6. parse arguments
- * 7. switch on command name
- *
- * Note: "fgetline" can be NULL.
- *
- * This function may be called recursively!
- */
-static char_u * do_one_cmd(char_u **cmdlinep,
- int flags,
- cstack_T *cstack,
- LineGetter fgetline,
- void *cookie /* argument for fgetline() */
- )
-{
- char_u *p;
+/// Execute one Ex command.
+///
+/// If 'sourcing' is TRUE, the command will be included in the error message.
+///
+/// 1. skip comment lines and leading space
+/// 2. handle command modifiers
+/// 3. skip over the range to find the command
+/// 4. parse the range
+/// 5. parse the command
+/// 6. parse arguments
+/// 7. switch on command name
+///
+/// Note: "fgetline" can be NULL.
+///
+/// This function may be called recursively!
+///
+/// @param cookie argument for fgetline()
+static char_u *do_one_cmd(char_u **cmdlinep, int flags, cstack_T *cstack, LineGetter fgetline,
+ void *cookie)
+{
+ char_u *p;
linenr_T lnum;
long n;
- char_u *errormsg = NULL; // error message
- char_u *after_modifier = NULL;
+ char_u *errormsg = NULL; // error message
+ char_u *after_modifier = NULL;
exarg_T ea;
const int save_msg_scroll = msg_scroll;
cmdmod_T save_cmdmod;
const int save_reg_executing = reg_executing;
- char_u *cmd;
+ char_u *cmd;
memset(&ea, 0, sizeof(ea));
ea.line1 = 1;
ea.line2 = 1;
ex_nesting_level++;
- /* When the last file has not been edited :q has to be typed twice. */
+ // When the last file has not been edited :q has to be typed twice.
if (quitmore
- /* avoid that a function call in 'statusline' does this */
+ // avoid that a function call in 'statusline' does this
&& !getline_equal(fgetline, cookie, get_func_line)
- /* avoid that an autocommand, e.g. QuitPre, does this */
- && !getline_equal(fgetline, cookie, getnextac)
- )
+ // avoid that an autocommand, e.g. QuitPre, does this
+ && !getline_equal(fgetline, cookie,
+ getnextac)) {
--quitmore;
+ }
/*
* Reset browse, confirm, etc.. They are restored when returning, for
@@ -1425,13 +1434,14 @@ static char_u * do_one_cmd(char_u **cmdlinep,
ea.line2 = curbuf->b_ml.ml_line_count;
}
- if (ea.line2 < 0)
+ if (ea.line2 < 0) {
errormsg = (char_u *)_(e_invrange);
- else {
- if (ea.line2 == 0)
+ } else {
+ if (ea.line2 == 0) {
curwin->w_cursor.lnum = 1;
- else
+ } else {
curwin->w_cursor.lnum = ea.line2;
+ }
beginline(BL_SOL | BL_FIX);
}
}
@@ -1448,7 +1458,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,
++p;
}
p = vim_strnsave(ea.cmd, p - ea.cmd);
- int ret = apply_autocmds(EVENT_CMDUNDEFINED, p, p, TRUE, NULL);
+ int ret = apply_autocmds(EVENT_CMDUNDEFINED, p, p, true, NULL);
xfree(p);
// If the autocommands did something and didn't cause an error, try
// finding the command again.
@@ -1456,8 +1466,9 @@ static char_u * do_one_cmd(char_u **cmdlinep,
}
if (p == NULL) {
- if (!ea.skip)
+ if (!ea.skip) {
errormsg = (char_u *)_("E464: Ambiguous use of user-defined command");
+ }
goto doend;
}
// Check for wrong commands.
@@ -1479,8 +1490,8 @@ static char_u * do_one_cmd(char_u **cmdlinep,
// set when Not Implemented
const int ni = !IS_USER_CMDIDX(ea.cmdidx)
- && (cmdnames[ea.cmdidx].cmd_func == ex_ni
- || cmdnames[ea.cmdidx].cmd_func == ex_script_ni);
+ && (cmdnames[ea.cmdidx].cmd_func == ex_ni
+ || cmdnames[ea.cmdidx].cmd_func == ex_script_ni);
// Forced commands.
@@ -1506,7 +1517,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,
if (!MODIFIABLE(curbuf) && (ea.argt & EX_MODIFY)
// allow :put in terminals
&& (!curbuf->terminal || ea.cmdidx != CMD_put)) {
- /* Command not allowed in non-'modifiable' buffer */
+ // Command not allowed in non-'modifiable' buffer
errormsg = (char_u *)_(e_modifiable);
goto doend;
}
@@ -1518,7 +1529,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,
goto doend;
}
- // Disallow editing another buffer when "curbuf_lock" is set.
+ // Disallow editing another buffer when "curbuf->b_ro_locked" is set.
// Do allow ":checktime" (it is postponed).
// Do allow ":edit" (check for an argument later).
// Do allow ":file" with no arguments (check for an argument later).
@@ -1565,8 +1576,9 @@ static char_u * do_one_cmd(char_u **cmdlinep,
ea.line1 = ea.line2;
ea.line2 = lnum;
}
- if ((errormsg = invalid_range(&ea)) != NULL)
+ if ((errormsg = invalid_range(&ea)) != NULL) {
goto doend;
+ }
}
if ((ea.addr_type == ADDR_OTHER) && ea.addr_count == 0) {
@@ -1589,19 +1601,21 @@ static char_u * do_one_cmd(char_u **cmdlinep,
* option here, so things like % get expanded.
*/
p = replace_makeprg(&ea, p, cmdlinep);
- if (p == NULL)
+ if (p == NULL) {
goto doend;
+ }
/*
* Skip to start of argument.
* Don't do this for the ":!" command, because ":!! -l" needs the space.
*/
- if (ea.cmdidx == CMD_bang)
+ if (ea.cmdidx == CMD_bang) {
ea.arg = p;
- else
+ } else {
ea.arg = skipwhite(p);
+ }
- // ":file" cannot be run with an argument when "curbuf_lock" is set
+ // ":file" cannot be run with an argument when "curbuf->b_ro_locked" is set
if (ea.cmdidx == CMD_file && *ea.arg != NUL && curbuf_locked()) {
goto doend;
}
@@ -1620,14 +1634,14 @@ static char_u * do_one_cmd(char_u **cmdlinep,
}
if (ea.cmdidx == CMD_write || ea.cmdidx == CMD_update) {
- if (*ea.arg == '>') { /* append */
- if (*++ea.arg != '>') { /* typed wrong */
+ if (*ea.arg == '>') { // append
+ if (*++ea.arg != '>') { // typed wrong
errormsg = (char_u *)_("E494: Use w or w>>");
goto doend;
}
ea.arg = skipwhite(ea.arg + 1);
ea.append = TRUE;
- } else if (*ea.arg == '!' && ea.cmdidx == CMD_write) { /* :w !filter */
+ } else if (*ea.arg == '!' && ea.cmdidx == CMD_write) { // :w !filter
++ea.arg;
ea.usefilter = TRUE;
}
@@ -1635,9 +1649,9 @@ static char_u * do_one_cmd(char_u **cmdlinep,
if (ea.cmdidx == CMD_read) {
if (ea.forceit) {
- ea.usefilter = TRUE; /* :r! filter if ea.forceit */
+ ea.usefilter = TRUE; // :r! filter if ea.forceit
ea.forceit = FALSE;
- } else if (*ea.arg == '!') { /* :r !filter */
+ } else if (*ea.arg == '!') { // :r !filter
++ea.arg;
ea.usefilter = TRUE;
}
@@ -1645,7 +1659,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,
if (ea.cmdidx == CMD_lshift || ea.cmdidx == CMD_rshift) {
ea.amount = 1;
- while (*ea.arg == *ea.cmd) { /* count number of '>' or '<' */
+ while (*ea.arg == *ea.cmd) { // count number of '>' or '<'
++ea.arg;
++ea.amount;
}
@@ -1696,67 +1710,67 @@ static char_u * do_one_cmd(char_u **cmdlinep,
ea.line1 = 1;
switch (ea.addr_type) {
- case ADDR_LINES:
- case ADDR_OTHER:
- ea.line2 = curbuf->b_ml.ml_line_count;
- break;
- case ADDR_LOADED_BUFFERS:
- buf = firstbuf;
- while (buf->b_next != NULL && buf->b_ml.ml_mfp == NULL) {
- buf = buf->b_next;
- }
- ea.line1 = buf->b_fnum;
- buf = lastbuf;
- while (buf->b_prev != NULL && buf->b_ml.ml_mfp == NULL) {
- buf = buf->b_prev;
- }
- ea.line2 = buf->b_fnum;
- break;
- case ADDR_BUFFERS:
- ea.line1 = firstbuf->b_fnum;
- ea.line2 = lastbuf->b_fnum;
- break;
- case ADDR_WINDOWS:
- ea.line2 = LAST_WIN_NR;
- break;
- case ADDR_TABS:
- ea.line2 = LAST_TAB_NR;
- break;
- case ADDR_TABS_RELATIVE:
+ case ADDR_LINES:
+ case ADDR_OTHER:
+ ea.line2 = curbuf->b_ml.ml_line_count;
+ break;
+ case ADDR_LOADED_BUFFERS:
+ buf = firstbuf;
+ while (buf->b_next != NULL && buf->b_ml.ml_mfp == NULL) {
+ buf = buf->b_next;
+ }
+ ea.line1 = buf->b_fnum;
+ buf = lastbuf;
+ while (buf->b_prev != NULL && buf->b_ml.ml_mfp == NULL) {
+ buf = buf->b_prev;
+ }
+ ea.line2 = buf->b_fnum;
+ break;
+ case ADDR_BUFFERS:
+ ea.line1 = firstbuf->b_fnum;
+ ea.line2 = lastbuf->b_fnum;
+ break;
+ case ADDR_WINDOWS:
+ ea.line2 = LAST_WIN_NR;
+ break;
+ case ADDR_TABS:
+ ea.line2 = LAST_TAB_NR;
+ break;
+ case ADDR_TABS_RELATIVE:
+ ea.line2 = 1;
+ break;
+ case ADDR_ARGUMENTS:
+ if (ARGCOUNT == 0) {
+ ea.line1 = ea.line2 = 0;
+ } else {
+ ea.line2 = ARGCOUNT;
+ }
+ break;
+ case ADDR_QUICKFIX_VALID:
+ ea.line2 = qf_get_valid_size(&ea);
+ if (ea.line2 == 0) {
ea.line2 = 1;
- break;
- case ADDR_ARGUMENTS:
- if (ARGCOUNT == 0) {
- ea.line1 = ea.line2 = 0;
- } else {
- ea.line2 = ARGCOUNT;
- }
- break;
- case ADDR_QUICKFIX_VALID:
- ea.line2 = qf_get_valid_size(&ea);
- if (ea.line2 == 0) {
- ea.line2 = 1;
- }
- break;
- case ADDR_NONE:
- case ADDR_UNSIGNED:
- case ADDR_QUICKFIX:
- IEMSG(_("INTERNAL: Cannot use EX_DFLALL "
- "with ADDR_NONE, ADDR_UNSIGNED or ADDR_QUICKFIX"));
- break;
+ }
+ break;
+ case ADDR_NONE:
+ case ADDR_UNSIGNED:
+ case ADDR_QUICKFIX:
+ IEMSG(_("INTERNAL: Cannot use EX_DFLALL "
+ "with ADDR_NONE, ADDR_UNSIGNED or ADDR_QUICKFIX"));
+ break;
}
}
// accept numbered register only when no count allowed (:put)
if ((ea.argt & EX_REGSTR)
&& *ea.arg != NUL
- /* Do not allow register = for user commands */
+ // Do not allow register = for user commands
&& (!IS_USER_CMDIDX(ea.cmdidx) || *ea.arg != '=')
&& !((ea.argt & EX_COUNT) && ascii_isdigit(*ea.arg))) {
if (valid_yank_reg(*ea.arg, (ea.cmdidx != CMD_put
&& !IS_USER_CMDIDX(ea.cmdidx)))) {
ea.regname = *ea.arg++;
- /* for '=' register: accept the rest of the line as an expression */
+ // for '=' register: accept the rest of the line as an expression
if (ea.arg[-1] == '=' && ea.arg[0] != NUL) {
set_expr_line(vim_strsave(ea.arg));
ea.arg += STRLEN(ea.arg);
@@ -1780,8 +1794,9 @@ static char_u * do_one_cmd(char_u **cmdlinep,
}
if (ea.addr_type != ADDR_LINES) { // e.g. :buffer 2, :sleep 3
ea.line2 = n;
- if (ea.addr_count == 0)
+ if (ea.addr_count == 0) {
ea.addr_count = 1;
+ }
} else {
ea.line1 = ea.line2;
ea.line2 += n - 1;
@@ -1819,7 +1834,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,
*/
if (ea.skip) {
switch (ea.cmdidx) {
- /* commands that need evaluation */
+ // commands that need evaluation
case CMD_while:
case CMD_endwhile:
case CMD_for:
@@ -1920,20 +1935,20 @@ static char_u * do_one_cmd(char_u **cmdlinep,
* number. Don't do this for a user command.
*/
if ((ea.argt & EX_BUFNAME) && *ea.arg != NUL && ea.addr_count == 0
- && !IS_USER_CMDIDX(ea.cmdidx)
- ) {
+ && !IS_USER_CMDIDX(ea.cmdidx)) {
/*
* :bdelete, :bwipeout and :bunload take several arguments, separated
* by spaces: find next space (skipping over escaped characters).
* The others take one argument: ignore trailing spaces.
*/
if (ea.cmdidx == CMD_bdelete || ea.cmdidx == CMD_bwipeout
- || ea.cmdidx == CMD_bunload)
+ || ea.cmdidx == CMD_bunload) {
p = skiptowhite_esc(ea.arg);
- else {
+ } else {
p = ea.arg + STRLEN(ea.arg);
- while (p > ea.arg && ascii_iswhite(p[-1]))
+ while (p > ea.arg && ascii_iswhite(p[-1])) {
--p;
+ }
}
ea.line2 = buflist_findpat(ea.arg, p, (ea.argt & EX_BUFUNL) != 0,
false, false);
@@ -1966,8 +1981,9 @@ static char_u * do_one_cmd(char_u **cmdlinep,
*/
ea.errmsg = NULL;
(cmdnames[ea.cmdidx].cmd_func)(&ea);
- if (ea.errmsg != NULL)
+ if (ea.errmsg != NULL) {
errormsg = (char_u *)_(ea.errmsg);
+ }
}
/*
@@ -1977,14 +1993,15 @@ static char_u * do_one_cmd(char_u **cmdlinep,
* exception, or reanimate a returned function or finished script file and
* return or finish it again.
*/
- if (need_rethrow)
+ if (need_rethrow) {
do_throw(cstack);
- else if (check_cstack) {
- if (source_finished(fgetline, cookie))
+ } else if (check_cstack) {
+ if (source_finished(fgetline, cookie)) {
do_finish(&ea, TRUE);
- else if (getline_equal(fgetline, cookie, get_func_line)
- && current_func_returned())
+ } else if (getline_equal(fgetline, cookie, get_func_line)
+ && current_func_returned()) {
do_return(&ea, TRUE, FALSE, NULL);
+ }
}
need_rethrow = check_cstack = FALSE;
@@ -2006,7 +2023,7 @@ doend:
emsg(errormsg);
}
do_errthrow(cstack,
- (ea.cmdidx != CMD_SIZE && !IS_USER_CMDIDX(ea.cmdidx))
+ (ea.cmdidx != CMD_SIZE && !IS_USER_CMDIDX(ea.cmdidx))
? cmdnames[(int)ea.cmdidx].cmd_name
: (char_u *)NULL);
@@ -2018,8 +2035,9 @@ doend:
sandbox--;
}
- if (ea.nextcmd && *ea.nextcmd == NUL) /* not really a next command */
+ if (ea.nextcmd && *ea.nextcmd == NUL) { // not really a next command
ea.nextcmd = NULL;
+ }
--ex_nesting_level;
@@ -2056,8 +2074,7 @@ int parse_command_modifiers(exarg_T *eap, char_u **errormsg, bool skip_only)
// in ex mode, an empty line works like :+
if (*eap->cmd == NUL && exmode_active
- && (getline_equal(eap->getline, eap->cookie, getexmodeline)
- || getline_equal(eap->getline, eap->cookie, getexline))
+ && getline_equal(eap->getline, eap->cookie, getexline)
&& curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) {
eap->cmd = (char_u *)"+";
if (!skip_only) {
@@ -2079,12 +2096,15 @@ int parse_command_modifiers(exarg_T *eap, char_u **errormsg, bool skip_only)
p = skip_range(eap->cmd, NULL);
switch (*p) {
// When adding an entry, also modify cmd_exists().
- case 'a': if (!checkforcmd(&eap->cmd, "aboveleft", 3))
+ case 'a':
+ if (!checkforcmd(&eap->cmd, "aboveleft", 3)) {
break;
+ }
cmdmod.split |= WSP_ABOVE;
continue;
- case 'b': if (checkforcmd(&eap->cmd, "belowright", 3)) {
+ case 'b':
+ if (checkforcmd(&eap->cmd, "belowright", 3)) {
cmdmod.split |= WSP_BELOW;
continue;
}
@@ -2098,15 +2118,18 @@ int parse_command_modifiers(exarg_T *eap, char_u **errormsg, bool skip_only)
cmdmod.split |= WSP_BOT;
continue;
- case 'c': if (!checkforcmd(&eap->cmd, "confirm", 4))
+ case 'c':
+ if (!checkforcmd(&eap->cmd, "confirm", 4)) {
break;
+ }
cmdmod.confirm = true;
continue;
- case 'k': if (checkforcmd(&eap->cmd, "keepmarks", 3)) {
+ case 'k':
+ if (checkforcmd(&eap->cmd, "keepmarks", 3)) {
cmdmod.keepmarks = true;
continue;
- }
+ }
if (checkforcmd(&eap->cmd, "keepalt", 5)) {
cmdmod.keepalt = true;
continue;
@@ -2154,17 +2177,20 @@ int parse_command_modifiers(exarg_T *eap, char_u **errormsg, bool skip_only)
}
// ":hide" and ":hide | cmd" are not modifiers
- case 'h': if (p != eap->cmd || !checkforcmd(&p, "hide", 3)
- || *p == NUL || ends_excmd(*p))
+ case 'h':
+ if (p != eap->cmd || !checkforcmd(&p, "hide", 3)
+ || *p == NUL || ends_excmd(*p)) {
break;
+ }
eap->cmd = p;
cmdmod.hide = true;
continue;
- case 'l': if (checkforcmd(&eap->cmd, "lockmarks", 3)) {
+ case 'l':
+ if (checkforcmd(&eap->cmd, "lockmarks", 3)) {
cmdmod.lockmarks = true;
continue;
- }
+ }
if (!checkforcmd(&eap->cmd, "leftabove", 5)) {
break;
@@ -2189,12 +2215,15 @@ int parse_command_modifiers(exarg_T *eap, char_u **errormsg, bool skip_only)
cmdmod.noswapfile = true;
continue;
- case 'r': if (!checkforcmd(&eap->cmd, "rightbelow", 6))
+ case 'r':
+ if (!checkforcmd(&eap->cmd, "rightbelow", 6)) {
break;
+ }
cmdmod.split |= WSP_BELOW;
continue;
- case 's': if (checkforcmd(&eap->cmd, "sandbox", 3)) {
+ case 's':
+ if (checkforcmd(&eap->cmd, "sandbox", 3)) {
if (!skip_only) {
if (!eap->did_sandbox) {
sandbox++;
@@ -2202,7 +2231,7 @@ int parse_command_modifiers(exarg_T *eap, char_u **errormsg, bool skip_only)
eap->did_sandbox = true;
}
continue;
- }
+ }
if (!checkforcmd(&eap->cmd, "silent", 3)) {
break;
}
@@ -2222,32 +2251,34 @@ int parse_command_modifiers(exarg_T *eap, char_u **errormsg, bool skip_only)
}
continue;
- case 't': if (checkforcmd(&p, "tab", 3)) {
- if (!skip_only) {
- long tabnr = get_address(
- eap, &eap->cmd, ADDR_TABS, eap->skip, skip_only, false, 1);
+ case 't':
+ if (checkforcmd(&p, "tab", 3)) {
+ if (!skip_only) {
+ long tabnr = get_address(eap, &eap->cmd, ADDR_TABS, eap->skip, skip_only, false, 1);
- if (tabnr == MAXLNUM) {
- cmdmod.tab = tabpage_index(curtab) + 1;
- } else {
- if (tabnr < 0 || tabnr > LAST_TAB_NR) {
- *errormsg = (char_u *)_(e_invrange);
- return false;
+ if (tabnr == MAXLNUM) {
+ cmdmod.tab = tabpage_index(curtab) + 1;
+ } else {
+ if (tabnr < 0 || tabnr > LAST_TAB_NR) {
+ *errormsg = (char_u *)_(e_invrange);
+ return false;
+ }
+ cmdmod.tab = tabnr + 1;
}
- cmdmod.tab = tabnr + 1;
}
+ eap->cmd = p;
+ continue;
}
- eap->cmd = p;
- continue;
- }
if (!checkforcmd(&eap->cmd, "topleft", 2)) {
break;
}
cmdmod.split |= WSP_TOP;
continue;
- case 'u': if (!checkforcmd(&eap->cmd, "unsilent", 3))
+ case 'u':
+ if (!checkforcmd(&eap->cmd, "unsilent", 3)) {
break;
+ }
if (!skip_only) {
if (eap->save_msg_silent == -1) {
eap->save_msg_silent = msg_silent;
@@ -2256,12 +2287,14 @@ int parse_command_modifiers(exarg_T *eap, char_u **errormsg, bool skip_only)
}
continue;
- case 'v': if (checkforcmd(&eap->cmd, "vertical", 4)) {
+ case 'v':
+ if (checkforcmd(&eap->cmd, "vertical", 4)) {
cmdmod.split |= WSP_VERT;
continue;
- }
- if (!checkforcmd(&p, "verbose", 4))
+ }
+ if (!checkforcmd(&p, "verbose", 4)) {
break;
+ }
if (!skip_only) {
if (eap->verbose_save < 0) {
eap->verbose_save = p_verbose;
@@ -2333,40 +2366,40 @@ int parse_cmd_address(exarg_T *eap, char_u **errormsg, bool silent)
for (;;) {
eap->line1 = eap->line2;
switch (eap->addr_type) {
- case ADDR_LINES:
- case ADDR_OTHER:
- // default is current line number
- eap->line2 = curwin->w_cursor.lnum;
- break;
- case ADDR_WINDOWS:
- eap->line2 = CURRENT_WIN_NR;
- break;
- case ADDR_ARGUMENTS:
- eap->line2 = curwin->w_arg_idx + 1;
- if (eap->line2 > ARGCOUNT) {
- eap->line2 = ARGCOUNT;
- }
- break;
- case ADDR_LOADED_BUFFERS:
- case ADDR_BUFFERS:
- eap->line2 = curbuf->b_fnum;
- break;
- case ADDR_TABS:
- eap->line2 = CURRENT_TAB_NR;
- break;
- case ADDR_TABS_RELATIVE:
- case ADDR_UNSIGNED:
- eap->line2 = 1;
- break;
- case ADDR_QUICKFIX:
- eap->line2 = qf_get_cur_idx(eap);
- break;
- case ADDR_QUICKFIX_VALID:
- eap->line2 = qf_get_cur_valid_idx(eap);
- break;
- case ADDR_NONE:
- // Will give an error later if a range is found.
- break;
+ case ADDR_LINES:
+ case ADDR_OTHER:
+ // default is current line number
+ eap->line2 = curwin->w_cursor.lnum;
+ break;
+ case ADDR_WINDOWS:
+ eap->line2 = CURRENT_WIN_NR;
+ break;
+ case ADDR_ARGUMENTS:
+ eap->line2 = curwin->w_arg_idx + 1;
+ if (eap->line2 > ARGCOUNT) {
+ eap->line2 = ARGCOUNT;
+ }
+ break;
+ case ADDR_LOADED_BUFFERS:
+ case ADDR_BUFFERS:
+ eap->line2 = curbuf->b_fnum;
+ break;
+ case ADDR_TABS:
+ eap->line2 = CURRENT_TAB_NR;
+ break;
+ case ADDR_TABS_RELATIVE:
+ case ADDR_UNSIGNED:
+ eap->line2 = 1;
+ break;
+ case ADDR_QUICKFIX:
+ eap->line2 = qf_get_cur_idx(eap);
+ break;
+ case ADDR_QUICKFIX_VALID:
+ eap->line2 = qf_get_cur_valid_idx(eap);
+ break;
+ case ADDR_NONE:
+ // Will give an error later if a range is found.
+ break;
}
eap->cmd = skipwhite(eap->cmd);
lnum = get_address(eap, &eap->cmd, eap->addr_type, eap->skip, silent,
@@ -2378,65 +2411,65 @@ int parse_cmd_address(exarg_T *eap, char_u **errormsg, bool silent)
if (*eap->cmd == '%') { // '%' - all lines
eap->cmd++;
switch (eap->addr_type) {
- case ADDR_LINES:
- case ADDR_OTHER:
- eap->line1 = 1;
- eap->line2 = curbuf->b_ml.ml_line_count;
- break;
- case ADDR_LOADED_BUFFERS: {
- buf_T *buf = firstbuf;
+ case ADDR_LINES:
+ case ADDR_OTHER:
+ eap->line1 = 1;
+ eap->line2 = curbuf->b_ml.ml_line_count;
+ break;
+ case ADDR_LOADED_BUFFERS: {
+ buf_T *buf = firstbuf;
- while (buf->b_next != NULL && buf->b_ml.ml_mfp == NULL) {
- buf = buf->b_next;
- }
- eap->line1 = buf->b_fnum;
- buf = lastbuf;
- while (buf->b_prev != NULL && buf->b_ml.ml_mfp == NULL) {
- buf = buf->b_prev;
- }
- eap->line2 = buf->b_fnum;
- break;
+ while (buf->b_next != NULL && buf->b_ml.ml_mfp == NULL) {
+ buf = buf->b_next;
}
- case ADDR_BUFFERS:
- eap->line1 = firstbuf->b_fnum;
- eap->line2 = lastbuf->b_fnum;
- break;
- case ADDR_WINDOWS:
- case ADDR_TABS:
- if (IS_USER_CMDIDX(eap->cmdidx)) {
- eap->line1 = 1;
- eap->line2 = eap->addr_type == ADDR_WINDOWS
+ eap->line1 = buf->b_fnum;
+ buf = lastbuf;
+ while (buf->b_prev != NULL && buf->b_ml.ml_mfp == NULL) {
+ buf = buf->b_prev;
+ }
+ eap->line2 = buf->b_fnum;
+ break;
+ }
+ case ADDR_BUFFERS:
+ eap->line1 = firstbuf->b_fnum;
+ eap->line2 = lastbuf->b_fnum;
+ break;
+ case ADDR_WINDOWS:
+ case ADDR_TABS:
+ if (IS_USER_CMDIDX(eap->cmdidx)) {
+ eap->line1 = 1;
+ eap->line2 = eap->addr_type == ADDR_WINDOWS
? LAST_WIN_NR : LAST_TAB_NR;
- } else {
- // there is no Vim command which uses '%' and
- // ADDR_WINDOWS or ADDR_TABS
- *errormsg = (char_u *)_(e_invrange);
- return FAIL;
- }
- break;
- case ADDR_TABS_RELATIVE:
- case ADDR_UNSIGNED:
- case ADDR_QUICKFIX:
+ } else {
+ // there is no Vim command which uses '%' and
+ // ADDR_WINDOWS or ADDR_TABS
*errormsg = (char_u *)_(e_invrange);
return FAIL;
- case ADDR_ARGUMENTS:
- if (ARGCOUNT == 0) {
- eap->line1 = eap->line2 = 0;
- } else {
- eap->line1 = 1;
- eap->line2 = ARGCOUNT;
- }
- break;
- case ADDR_QUICKFIX_VALID:
+ }
+ break;
+ case ADDR_TABS_RELATIVE:
+ case ADDR_UNSIGNED:
+ case ADDR_QUICKFIX:
+ *errormsg = (char_u *)_(e_invrange);
+ return FAIL;
+ case ADDR_ARGUMENTS:
+ if (ARGCOUNT == 0) {
+ eap->line1 = eap->line2 = 0;
+ } else {
eap->line1 = 1;
- eap->line2 = qf_get_valid_size(eap);
- if (eap->line2 == 0) {
- eap->line2 = 1;
- }
- break;
- case ADDR_NONE:
- // Will give an error later if a range is found.
- break;
+ eap->line2 = ARGCOUNT;
+ }
+ break;
+ case ADDR_QUICKFIX_VALID:
+ eap->line1 = 1;
+ eap->line2 = qf_get_valid_size(eap);
+ if (eap->line2 == 0) {
+ eap->line2 = 1;
+ }
+ break;
+ case ADDR_NONE:
+ // Will give an error later if a range is found.
+ break;
}
eap->addr_count++;
} else if (*eap->cmd == '*') {
@@ -2492,22 +2525,21 @@ int parse_cmd_address(exarg_T *eap, char_u **errormsg, bool silent)
return OK;
}
-/*
- * Check for an Ex command with optional tail.
- * If there is a match advance "pp" to the argument and return TRUE.
- */
-int
-checkforcmd(
- char_u **pp, // start of command
- char *cmd, // name of command
- int len // required length
-)
+/// Check for an Ex command with optional tail.
+/// If there is a match advance "pp" to the argument and return TRUE.
+///
+/// @param pp start of command
+/// @param cmd name of command
+/// @param len required length
+int checkforcmd(char_u **pp, char *cmd, int len)
{
int i;
- for (i = 0; cmd[i] != NUL; ++i)
- if (((char_u *)cmd)[i] != (*pp)[i])
+ for (i = 0; cmd[i] != NUL; ++i) {
+ if (((char_u *)cmd)[i] != (*pp)[i]) {
break;
+ }
+ }
if (i >= len && !isalpha((*pp)[i])) {
*pp = skipwhite(*pp + i);
return TRUE;
@@ -2532,8 +2564,9 @@ static void append_command(char_u *cmd)
s += 2;
STRCPY(d, "<a0>");
d += 4;
- } else
+ } else {
MB_COPY_CHAR(s, d);
+ }
}
*d = NUL;
}
@@ -2547,7 +2580,7 @@ static char_u *find_command(exarg_T *eap, int *full)
FUNC_ATTR_NONNULL_ARG(1)
{
int len;
- char_u *p;
+ char_u *p;
int i;
/*
@@ -2555,8 +2588,8 @@ static char_u *find_command(exarg_T *eap, int *full)
* Exceptions:
* - the 'k' command can directly be followed by any character.
* - the 's' command can be followed directly by 'c', 'g', 'i', 'I' or 'r'
- * but :sre[wind] is another command, as are :scr[iptnames],
- * :scs[cope], :sim[alt], :sig[ns] and :sil[ent].
+ * but :sre[wind] is another command, as are :scr[iptnames],
+ * :scs[cope], :sim[alt], :sig[ns] and :sil[ent].
* - the "d" command can directly be followed by 'l' or 'p' flag.
*/
p = eap->cmd;
@@ -2576,29 +2609,36 @@ static char_u *find_command(exarg_T *eap, int *full)
eap->cmdidx = CMD_substitute;
++p;
} else {
- while (ASCII_ISALPHA(*p))
+ while (ASCII_ISALPHA(*p)) {
++p;
- /* for python 3.x support ":py3", ":python3", ":py3file", etc. */
- if (eap->cmd[0] == 'p' && eap->cmd[1] == 'y')
- while (ASCII_ISALNUM(*p))
+ }
+ // for python 3.x support ":py3", ":python3", ":py3file", etc.
+ if (eap->cmd[0] == 'p' && eap->cmd[1] == 'y') {
+ while (ASCII_ISALNUM(*p)) {
++p;
+ }
+ }
- /* check for non-alpha command */
- if (p == eap->cmd && vim_strchr((char_u *)"@!=><&~#", *p) != NULL)
+ // check for non-alpha command
+ if (p == eap->cmd && vim_strchr((char_u *)"@!=><&~#", *p) != NULL) {
++p;
+ }
len = (int)(p - eap->cmd);
if (*eap->cmd == 'd' && (p[-1] == 'l' || p[-1] == 'p')) {
/* Check for ":dl", ":dell", etc. to ":deletel": that's
* :delete with the 'l' flag. Same for 'p'. */
- for (i = 0; i < len; ++i)
- if (eap->cmd[i] != ((char_u *)"delete")[i])
+ for (i = 0; i < len; ++i) {
+ if (eap->cmd[i] != ((char_u *)"delete")[i]) {
break;
+ }
+ }
if (i == len - 1) {
--len;
- if (p[-1] == 'l')
+ if (p[-1] == 'l') {
eap->flags |= EXFLAG_LIST;
- else
+ } else {
eap->flags |= EXFLAG_PRINT;
+ }
}
}
@@ -2606,7 +2646,7 @@ static char_u *find_command(exarg_T *eap, int *full)
const int c1 = eap->cmd[0];
const int c2 = len == 1 ? NUL : eap->cmd[1];
- if (command_count != (int)CMD_SIZE) {
+ if (command_count != CMD_SIZE) {
iemsg((char *)_("E943: Command table needs to be updated, run 'make'"));
getout(1);
}
@@ -2621,55 +2661,55 @@ static char_u *find_command(exarg_T *eap, int *full)
eap->cmdidx = CMD_bang;
}
- for (; (int)eap->cmdidx < (int)CMD_SIZE;
- eap->cmdidx = (cmdidx_T)((int)eap->cmdidx + 1))
+ for (; (int)eap->cmdidx < CMD_SIZE;
+ eap->cmdidx = (cmdidx_T)((int)eap->cmdidx + 1)) {
if (STRNCMP(cmdnames[(int)eap->cmdidx].cmd_name, (char *)eap->cmd,
- (size_t)len) == 0) {
+ (size_t)len) == 0) {
if (full != NULL
- && cmdnames[(int)eap->cmdidx].cmd_name[len] == NUL)
+ && cmdnames[(int)eap->cmdidx].cmd_name[len] == NUL) {
*full = TRUE;
+ }
break;
}
+ }
// Look for a user defined command as a last resort.
if ((eap->cmdidx == CMD_SIZE)
&& *eap->cmd >= 'A' && *eap->cmd <= 'Z') {
- /* User defined commands may contain digits. */
- while (ASCII_ISALNUM(*p))
+ // User defined commands may contain digits.
+ while (ASCII_ISALNUM(*p)) {
++p;
+ }
p = find_ucmd(eap, p, full, NULL, NULL);
}
- if (p == eap->cmd)
+ if (p == eap->cmd) {
eap->cmdidx = CMD_SIZE;
+ }
}
return p;
}
-/*
- * Search for a user command that matches "eap->cmd".
- * Return cmdidx in "eap->cmdidx", flags in "eap->argt", idx in "eap->useridx".
- * Return a pointer to just after the command.
- * Return NULL if there is no matching command.
- */
-static char_u *
-find_ucmd (
- exarg_T *eap,
- char_u *p, // end of the command (possibly including count)
- int *full, // set to TRUE for a full match
- expand_T *xp, // used for completion, NULL otherwise
- int *complp // completion flags or NULL
-)
+/// Search for a user command that matches "eap->cmd".
+/// Return cmdidx in "eap->cmdidx", flags in "eap->argt", idx in "eap->useridx".
+/// Return a pointer to just after the command.
+/// Return NULL if there is no matching command.
+///
+/// @param *p end of the command (possibly including count)
+/// @param full set to TRUE for a full match
+/// @param xp used for completion, NULL otherwise
+/// @param complp completion flags or NULL
+static char_u *find_ucmd(exarg_T *eap, char_u *p, int *full, expand_T *xp, int *complp)
{
int len = (int)(p - eap->cmd);
int j, k, matchlen = 0;
- ucmd_T *uc;
- int found = FALSE;
- int possible = FALSE;
- char_u *cp, *np; /* Point into typed cmd and test name */
- garray_T *gap;
- int amb_local = FALSE; /* Found ambiguous buffer-local command,
- only full match global is accepted. */
+ ucmd_T *uc;
+ bool found = false;
+ bool possible = false;
+ char_u *cp, *np; // Point into typed cmd and test name
+ garray_T *gap;
+ bool amb_local = false; // Found ambiguous buffer-local command,
+ // only full match global is accepted.
/*
* Look for buffer-local user commands first, then global ones.
@@ -2681,16 +2721,18 @@ find_ucmd (
cp = eap->cmd;
np = uc->uc_name;
k = 0;
- while (k < len && *np != NUL && *cp++ == *np++)
+ while (k < len && *np != NUL && *cp++ == *np++) {
k++;
+ }
if (k == len || (*np == NUL && ascii_isdigit(eap->cmd[k]))) {
/* If finding a second match, the command is ambiguous. But
* not if a buffer-local command wasn't a full match and a
* global command is a full match. */
if (k == len && found && *np != NUL) {
- if (gap == &ucmds)
+ if (gap == &ucmds) {
return NULL;
- amb_local = TRUE;
+ }
+ amb_local = true;
}
if (!found || (k == len && *np == NUL)) {
@@ -2698,15 +2740,17 @@ find_ucmd (
* be another command including the digit that we
* should use instead.
*/
- if (k == len)
- found = TRUE;
- else
- possible = TRUE;
+ if (k == len) {
+ found = true;
+ } else {
+ possible = true;
+ }
- if (gap == &ucmds)
+ if (gap == &ucmds) {
eap->cmdidx = CMD_USER;
- else
+ } else {
eap->cmdidx = CMD_USER_BUF;
+ }
eap->argt = uc->uc_argt;
eap->useridx = j;
eap->addr_type = uc->uc_addr_type;
@@ -2723,39 +2767,43 @@ find_ucmd (
* if this is an exact match. */
matchlen = k;
if (k == len && *np == NUL) {
- if (full != NULL)
+ if (full != NULL) {
*full = TRUE;
- amb_local = FALSE;
+ }
+ amb_local = false;
break;
}
}
}
}
- /* Stop if we found a full match or searched all. */
- if (j < gap->ga_len || gap == &ucmds)
+ // Stop if we found a full match or searched all.
+ if (j < gap->ga_len || gap == &ucmds) {
break;
+ }
gap = &ucmds;
}
- /* Only found ambiguous matches. */
+ // Only found ambiguous matches.
if (amb_local) {
- if (xp != NULL)
+ if (xp != NULL) {
xp->xp_context = EXPAND_UNSUCCESSFUL;
+ }
return NULL;
}
/* The match we found may be followed immediately by a number. Move "p"
* back to point to it. */
- if (found || possible)
+ if (found || possible) {
return p + (matchlen - len);
+ }
return p;
}
static struct cmdmod {
- char *name;
+ char *name;
int minlen;
- int has_count; /* :123verbose :3tab */
+ int has_count; // :123verbose :3tab
} cmdmods[] = {
{ "aboveleft", 3, false },
{ "belowright", 3, false },
@@ -2788,7 +2836,7 @@ static struct cmdmod {
*/
int modifier_len(char_u *cmd)
{
- char_u *p = cmd;
+ char_u *p = cmd;
if (ascii_isdigit(*cmd)) {
p = skipwhite(skipdigits(cmd + 1));
@@ -2817,13 +2865,13 @@ int modifier_len(char_u *cmd)
int cmd_exists(const char *const name)
{
exarg_T ea;
- char_u *p;
+ char_u *p;
// Check command modifiers.
for (int i = 0; i < (int)ARRAY_SIZE(cmdmods); i++) {
int j;
for (j = 0; name[j] != NUL; j++) {
- if (name[j] != (char)cmdmods[i].name[j]) {
+ if (name[j] != cmdmods[i].name[j]) {
break;
}
}
@@ -2838,26 +2886,26 @@ int cmd_exists(const char *const name)
ea.cmdidx = (cmdidx_T)0;
int full = false;
p = find_command(&ea, &full);
- if (p == NULL)
+ if (p == NULL) {
return 3;
- if (ascii_isdigit(*name) && ea.cmdidx != CMD_match)
+ }
+ if (ascii_isdigit(*name) && ea.cmdidx != CMD_match) {
return 0;
- if (*skipwhite(p) != NUL)
- return 0; /* trailing garbage */
+ }
+ if (*skipwhite(p) != NUL) {
+ return 0; // trailing garbage
+ }
return ea.cmdidx == CMD_SIZE ? 0 : (full ? 2 : 1);
}
-/*
- * This is all pretty much copied from do_one_cmd(), with all the extra stuff
- * we don't need/want deleted. Maybe this could be done better if we didn't
- * repeat all this stuff. The only problem is that they may not stay
- * perfectly compatible with each other, but then the command line syntax
- * probably won't change that much -- webb.
- */
-const char * set_one_cmd_context(
- expand_T *xp,
- const char *buff // buffer for command string
-)
+/// This is all pretty much copied from do_one_cmd(), with all the extra stuff
+/// we don't need/want deleted. Maybe this could be done better if we didn't
+/// repeat all this stuff. The only problem is that they may not stay
+/// perfectly compatible with each other, but then the command line syntax
+/// probably won't change that much -- webb.
+///
+/// @param buff buffer for command string
+const char *set_one_cmd_context(expand_T *xp, const char *buff)
{
size_t len = 0;
exarg_T ea;
@@ -2876,9 +2924,10 @@ const char * set_one_cmd_context(
}
xp->xp_pattern = (char_u *)cmd;
- if (*cmd == NUL)
+ if (*cmd == NUL) {
return NULL;
- if (*cmd == '"') { /* ignore comment lines */
+ }
+ if (*cmd == '"') { // ignore comment lines
xp->xp_context = EXPAND_NOTHING;
return NULL;
}
@@ -2900,9 +2949,9 @@ const char * set_one_cmd_context(
return NULL;
}
- if (*cmd == '|' || *cmd == '\n')
- return cmd + 1; /* There's another command */
-
+ if (*cmd == '|' || *cmd == '\n') {
+ return cmd + 1; // There's another command
+ }
/*
* Isolate the command and search for it in the command table.
* Exceptions:
@@ -2942,7 +2991,7 @@ const char * set_one_cmd_context(
xp->xp_context = EXPAND_UNSUCCESSFUL;
return NULL;
}
- for (ea.cmdidx = (cmdidx_T)0; (int)ea.cmdidx < (int)CMD_SIZE;
+ for (ea.cmdidx = (cmdidx_T)0; (int)ea.cmdidx < CMD_SIZE;
ea.cmdidx = (cmdidx_T)((int)ea.cmdidx + 1)) {
if (STRNCMP(cmdnames[(int)ea.cmdidx].cmd_name, cmd, len) == 0) {
break;
@@ -2956,12 +3005,13 @@ const char * set_one_cmd_context(
}
}
- /*
- * If the cursor is touching the command, and it ends in an alpha-numeric
- * character, complete the command name.
- */
- if (*p == NUL && ASCII_ISALNUM(p[-1]))
+ //
+ // If the cursor is touching the command, and it ends in an alphanumeric
+ // character, complete the command name.
+ //
+ if (*p == NUL && ASCII_ISALNUM(p[-1])) {
return NULL;
+ }
if (ea.cmdidx == CMD_SIZE) {
if (*cmd == 's' && vim_strchr((const char_u *)"cgriI", cmd[1]) != NULL) {
@@ -2976,12 +3026,12 @@ const char * set_one_cmd_context(
}
}
if (ea.cmdidx == CMD_SIZE) {
- /* Not still touching the command and it was an illegal one */
+ // Not still touching the command and it was an illegal one
xp->xp_context = EXPAND_UNSUCCESSFUL;
return NULL;
}
- xp->xp_context = EXPAND_NOTHING; /* Default now that we're past command */
+ xp->xp_context = EXPAND_NOTHING; // Default now that we're past command
if (*p == '!') { // forced commands
forceit = true;
@@ -3054,9 +3104,10 @@ const char * set_one_cmd_context(
*/
if ((ea.argt & EX_TRLBAR) && !usefilter) {
p = arg;
- /* ":redir @" is not the start of a comment */
- if (ea.cmdidx == CMD_redir && p[0] == '@' && p[1] == '"')
+ // ":redir @" is not the start of a comment
+ if (ea.cmdidx == CMD_redir && p[0] == '@' && p[1] == '"') {
p += 2;
+ }
while (*p) {
if (*p == Ctrl_V) {
if (p[1] != NUL) {
@@ -3066,9 +3117,10 @@ const char * set_one_cmd_context(
|| *p == '|'
|| *p == '\n') {
if (*(p - 1) != '\\') {
- if (*p == '|' || *p == '\n')
+ if (*p == '|' || *p == '\n') {
return p + 1;
- return NULL; /* It's a comment */
+ }
+ return NULL; // It's a comment
}
}
MB_PTR_ADV(p);
@@ -3080,7 +3132,7 @@ const char * set_one_cmd_context(
return NULL;
}
- /* Find start of last argument (argument just before cursor): */
+ // Find start of last argument (argument just before cursor):
p = buff;
xp->xp_pattern = (char_u *)p;
len = strlen(buff);
@@ -3121,10 +3173,10 @@ const char * set_one_cmd_context(
/* An argument can contain just about everything, except
* characters that end the command and white space. */
else if (c == '|'
- || c == '\n'
- || c == '"'
- || ascii_iswhite(c)) {
- len = 0; /* avoid getting stuck when space is in 'isfname' */
+ || c == '\n'
+ || c == '"'
+ || ascii_iswhite(c)) {
+ len = 0; // avoid getting stuck when space is in 'isfname'
while (*p != NUL) {
c = utf_ptr2char((const char_u *)p);
if (c == '`' || vim_isfilec_or_wc(c)) {
@@ -3152,7 +3204,7 @@ const char * set_one_cmd_context(
}
xp->xp_context = EXPAND_FILES;
- /* For a shell command more chars need to be escaped. */
+ // For a shell command more chars need to be escaped.
if (usefilter || ea.cmdidx == CMD_bang || ea.cmdidx == CMD_terminal) {
#ifndef BACKSLASH_IN_FILENAME
xp->xp_shell = TRUE;
@@ -3179,7 +3231,7 @@ const char * set_one_cmd_context(
}
}
}
- /* Check for user names */
+ // Check for user names.
if (*xp->xp_pattern == '~') {
for (p = (const char *)xp->xp_pattern + 1; *p != NUL && *p != '/'; p++) {
}
@@ -3201,8 +3253,9 @@ const char * set_one_cmd_context(
case CMD_find:
case CMD_sfind:
case CMD_tabfind:
- if (xp->xp_context == EXPAND_FILES)
+ if (xp->xp_context == EXPAND_FILES) {
xp->xp_context = EXPAND_FILES_IN_PATH;
+ }
break;
case CMD_cd:
case CMD_chdir:
@@ -3267,7 +3320,7 @@ const char * set_one_cmd_context(
case CMD_match:
if (*arg == NUL || !ends_excmd(*arg)) {
- /* also complete "None" */
+ // also complete "None"
set_context_in_echohl_cmd(xp, arg);
arg = (const char *)skipwhite(skiptowhite((const char_u *)arg));
if (*arg != NUL) {
@@ -3283,7 +3336,7 @@ const char * set_one_cmd_context(
*/
case CMD_command:
- /* Check for attributes */
+ // Check for attributes
while (*arg == '-') {
arg++; // Skip "-".
p = (const char *)skiptowhite((const char_u *)arg);
@@ -3346,8 +3399,9 @@ const char * set_one_cmd_context(
}
arg++;
}
- if (arg[0] != NUL)
+ if (arg[0] != NUL) {
return arg + 1;
+ }
break;
}
case CMD_and:
@@ -3532,9 +3586,9 @@ const char * set_one_cmd_context(
} else if (context == EXPAND_COMMANDS) {
return arg;
} else if (context == EXPAND_MAPPINGS) {
- return (const char *)set_context_in_map_cmd(
- xp, (char_u *)"map", (char_u *)arg, forceit, false, false,
- CMD_map);
+ return (const char *)set_context_in_map_cmd(xp, (char_u *)"map", (char_u *)arg, forceit,
+ false, false,
+ CMD_map);
}
// Find start of last argument.
p = arg;
@@ -3552,17 +3606,26 @@ const char * set_one_cmd_context(
xp->xp_context = context;
}
break;
- case CMD_map: case CMD_noremap:
- case CMD_nmap: case CMD_nnoremap:
- case CMD_vmap: case CMD_vnoremap:
- case CMD_omap: case CMD_onoremap:
- case CMD_imap: case CMD_inoremap:
- case CMD_cmap: case CMD_cnoremap:
- case CMD_lmap: case CMD_lnoremap:
- case CMD_smap: case CMD_snoremap:
- case CMD_xmap: case CMD_xnoremap:
- return (const char *)set_context_in_map_cmd(
- xp, (char_u *)cmd, (char_u *)arg, forceit, false, false, ea.cmdidx);
+ case CMD_map:
+ case CMD_noremap:
+ case CMD_nmap:
+ case CMD_nnoremap:
+ case CMD_vmap:
+ case CMD_vnoremap:
+ case CMD_omap:
+ case CMD_onoremap:
+ case CMD_imap:
+ case CMD_inoremap:
+ case CMD_cmap:
+ case CMD_cnoremap:
+ case CMD_lmap:
+ case CMD_lnoremap:
+ case CMD_smap:
+ case CMD_snoremap:
+ case CMD_xmap:
+ case CMD_xnoremap:
+ return (const char *)set_context_in_map_cmd(xp, (char_u *)cmd, (char_u *)arg, forceit, false,
+ false, ea.cmdidx);
case CMD_unmap:
case CMD_nunmap:
case CMD_vunmap:
@@ -3572,8 +3635,8 @@ const char * set_one_cmd_context(
case CMD_lunmap:
case CMD_sunmap:
case CMD_xunmap:
- return (const char *)set_context_in_map_cmd(
- xp, (char_u *)cmd, (char_u *)arg, forceit, false, true, ea.cmdidx);
+ return (const char *)set_context_in_map_cmd(xp, (char_u *)cmd, (char_u *)arg, forceit, false,
+ true, ea.cmdidx);
case CMD_mapclear:
case CMD_nmapclear:
case CMD_vmapclear:
@@ -3587,27 +3650,45 @@ const char * set_one_cmd_context(
xp->xp_pattern = (char_u *)arg;
break;
- case CMD_abbreviate: case CMD_noreabbrev:
- case CMD_cabbrev: case CMD_cnoreabbrev:
- case CMD_iabbrev: case CMD_inoreabbrev:
- return (const char *)set_context_in_map_cmd(
- xp, (char_u *)cmd, (char_u *)arg, forceit, true, false, ea.cmdidx);
+ case CMD_abbreviate:
+ case CMD_noreabbrev:
+ case CMD_cabbrev:
+ case CMD_cnoreabbrev:
+ case CMD_iabbrev:
+ case CMD_inoreabbrev:
+ return (const char *)set_context_in_map_cmd(xp, (char_u *)cmd, (char_u *)arg, forceit, true,
+ false, ea.cmdidx);
case CMD_unabbreviate:
case CMD_cunabbrev:
case CMD_iunabbrev:
- return (const char *)set_context_in_map_cmd(
- xp, (char_u *)cmd, (char_u *)arg, forceit, true, true, ea.cmdidx);
- case CMD_menu: case CMD_noremenu: case CMD_unmenu:
- case CMD_amenu: case CMD_anoremenu: case CMD_aunmenu:
- case CMD_nmenu: case CMD_nnoremenu: case CMD_nunmenu:
- case CMD_vmenu: case CMD_vnoremenu: case CMD_vunmenu:
- case CMD_omenu: case CMD_onoremenu: case CMD_ounmenu:
- case CMD_imenu: case CMD_inoremenu: case CMD_iunmenu:
- case CMD_cmenu: case CMD_cnoremenu: case CMD_cunmenu:
- case CMD_tmenu: case CMD_tunmenu:
- case CMD_popup: case CMD_emenu:
- return (const char *)set_context_in_menu_cmd(
- xp, cmd, (char_u *)arg, forceit);
+ return (const char *)set_context_in_map_cmd(xp, (char_u *)cmd, (char_u *)arg, forceit, true,
+ true, ea.cmdidx);
+ case CMD_menu:
+ case CMD_noremenu:
+ case CMD_unmenu:
+ case CMD_amenu:
+ case CMD_anoremenu:
+ case CMD_aunmenu:
+ case CMD_nmenu:
+ case CMD_nnoremenu:
+ case CMD_nunmenu:
+ case CMD_vmenu:
+ case CMD_vnoremenu:
+ case CMD_vunmenu:
+ case CMD_omenu:
+ case CMD_onoremenu:
+ case CMD_ounmenu:
+ case CMD_imenu:
+ case CMD_inoremenu:
+ case CMD_iunmenu:
+ case CMD_cmenu:
+ case CMD_cnoremenu:
+ case CMD_cunmenu:
+ case CMD_tmenu:
+ case CMD_tunmenu:
+ case CMD_popup:
+ case CMD_emenu:
+ return (const char *)set_context_in_menu_cmd(xp, cmd, (char_u *)arg, forceit);
case CMD_colorscheme:
xp->xp_context = EXPAND_COLORS;
@@ -3697,17 +3778,17 @@ const char * set_one_cmd_context(
return NULL;
}
-// Skip a range specifier of the form: addr [,addr] [;addr] ..
-//
-// Backslashed delimiters after / or ? will be skipped, and commands will
-// not be expanded between /'s and ?'s or after "'".
-//
-// Also skip white space and ":" characters.
-// Returns the "cmd" pointer advanced to beyond the range.
-char_u *skip_range(
- const char_u *cmd,
- int *ctx // pointer to xp_context or NULL
-)
+/// Skip a range specifier of the form: addr [,addr] [;addr] ..
+///
+/// Backslashed delimiters after / or ? will be skipped, and commands will
+/// not be expanded between /'s and ?'s or after "'".
+///
+/// Also skip white space and ":" characters.
+///
+/// @param ctx pointer to xp_context or NULL
+///
+/// @return the "cmd" pointer advanced to beyond the range.
+char_u *skip_range(const char_u *cmd, int *ctx)
{
unsigned delim;
@@ -3724,14 +3805,18 @@ char_u *skip_range(
}
} else if (*cmd == '/' || *cmd == '?') {
delim = *cmd++;
- while (*cmd != NUL && *cmd != delim)
- if (*cmd++ == '\\' && *cmd != NUL)
+ while (*cmd != NUL && *cmd != delim) {
+ if (*cmd++ == '\\' && *cmd != NUL) {
++cmd;
- if (*cmd == NUL && ctx != NULL)
+ }
+ }
+ if (*cmd == NUL && ctx != NULL) {
*ctx = EXPAND_NOTHING;
+ }
}
- if (*cmd != NUL)
+ if (*cmd != NUL) {
++cmd;
+ }
}
// Skip ":" and white space.
@@ -3749,28 +3834,28 @@ static void addr_error(cmd_addr_T addr_type)
}
}
-// Get a single EX address
-//
-// Set ptr to the next character after the part that was interpreted.
-// Set ptr to NULL when an error is encountered.
-// This may set the last used search pattern.
-//
-// Return MAXLNUM when no Ex address was found.
-static linenr_T get_address(exarg_T *eap,
- char_u **ptr,
- cmd_addr_T addr_type,
- int skip, // only skip the address, don't use it
- bool silent, // no errors or side effects
- int to_other_file, // flag: may jump to other file
- int address_count) // 1 for first, >1 after comma
+/// Get a single EX address
+///
+/// Set ptr to the next character after the part that was interpreted.
+/// Set ptr to NULL when an error is encountered.
+/// This may set the last used search pattern.
+///
+/// @param skip only skip the address, don't use it
+/// @param silent no errors or side effects
+/// @param to_other_file flag: may jump to other file
+/// @param address_count 1 for first, >1 after comma
+///
+/// @return MAXLNUM when no Ex address was found.
+static linenr_T get_address(exarg_T *eap, char_u **ptr, cmd_addr_T addr_type, int skip, bool silent,
+ int to_other_file, int address_count)
FUNC_ATTR_NONNULL_ALL
{
int c;
int i;
long n;
- char_u *cmd;
+ char_u *cmd;
pos_T pos;
- pos_T *fp;
+ pos_T *fp;
linenr_T lnum;
buf_T *buf;
@@ -3778,94 +3863,94 @@ static linenr_T get_address(exarg_T *eap,
lnum = MAXLNUM;
do {
switch (*cmd) {
- case '.': /* '.' - Cursor position */
+ case '.': // '.' - Cursor position
++cmd;
switch (addr_type) {
- case ADDR_LINES:
- case ADDR_OTHER:
- lnum = curwin->w_cursor.lnum;
- break;
- case ADDR_WINDOWS:
- lnum = CURRENT_WIN_NR;
- break;
- case ADDR_ARGUMENTS:
- lnum = curwin->w_arg_idx + 1;
- break;
- case ADDR_LOADED_BUFFERS:
- case ADDR_BUFFERS:
- lnum = curbuf->b_fnum;
- break;
- case ADDR_TABS:
- lnum = CURRENT_TAB_NR;
- break;
- case ADDR_NONE:
- case ADDR_TABS_RELATIVE:
- case ADDR_UNSIGNED:
- addr_error(addr_type);
- cmd = NULL;
- goto error;
- break;
- case ADDR_QUICKFIX:
- lnum = qf_get_cur_idx(eap);
- break;
- case ADDR_QUICKFIX_VALID:
- lnum = qf_get_cur_valid_idx(eap);
- break;
+ case ADDR_LINES:
+ case ADDR_OTHER:
+ lnum = curwin->w_cursor.lnum;
+ break;
+ case ADDR_WINDOWS:
+ lnum = CURRENT_WIN_NR;
+ break;
+ case ADDR_ARGUMENTS:
+ lnum = curwin->w_arg_idx + 1;
+ break;
+ case ADDR_LOADED_BUFFERS:
+ case ADDR_BUFFERS:
+ lnum = curbuf->b_fnum;
+ break;
+ case ADDR_TABS:
+ lnum = CURRENT_TAB_NR;
+ break;
+ case ADDR_NONE:
+ case ADDR_TABS_RELATIVE:
+ case ADDR_UNSIGNED:
+ addr_error(addr_type);
+ cmd = NULL;
+ goto error;
+ break;
+ case ADDR_QUICKFIX:
+ lnum = qf_get_cur_idx(eap);
+ break;
+ case ADDR_QUICKFIX_VALID:
+ lnum = qf_get_cur_valid_idx(eap);
+ break;
}
break;
- case '$': /* '$' - last line */
+ case '$': // '$' - last line
++cmd;
switch (addr_type) {
- case ADDR_LINES:
- case ADDR_OTHER:
- lnum = curbuf->b_ml.ml_line_count;
- break;
- case ADDR_WINDOWS:
- lnum = LAST_WIN_NR;
- break;
- case ADDR_ARGUMENTS:
- lnum = ARGCOUNT;
- break;
- case ADDR_LOADED_BUFFERS:
- buf = lastbuf;
- while (buf->b_ml.ml_mfp == NULL) {
- if (buf->b_prev == NULL) {
- break;
- }
- buf = buf->b_prev;
- }
- lnum = buf->b_fnum;
- break;
- case ADDR_BUFFERS:
- lnum = lastbuf->b_fnum;
- break;
- case ADDR_TABS:
- lnum = LAST_TAB_NR;
- break;
- case ADDR_NONE:
- case ADDR_TABS_RELATIVE:
- case ADDR_UNSIGNED:
- addr_error(addr_type);
- cmd = NULL;
- goto error;
- break;
- case ADDR_QUICKFIX:
- lnum = qf_get_size(eap);
- if (lnum == 0) {
- lnum = 1;
- }
- break;
- case ADDR_QUICKFIX_VALID:
- lnum = qf_get_valid_size(eap);
- if (lnum == 0) {
- lnum = 1;
+ case ADDR_LINES:
+ case ADDR_OTHER:
+ lnum = curbuf->b_ml.ml_line_count;
+ break;
+ case ADDR_WINDOWS:
+ lnum = LAST_WIN_NR;
+ break;
+ case ADDR_ARGUMENTS:
+ lnum = ARGCOUNT;
+ break;
+ case ADDR_LOADED_BUFFERS:
+ buf = lastbuf;
+ while (buf->b_ml.ml_mfp == NULL) {
+ if (buf->b_prev == NULL) {
+ break;
}
- break;
+ buf = buf->b_prev;
+ }
+ lnum = buf->b_fnum;
+ break;
+ case ADDR_BUFFERS:
+ lnum = lastbuf->b_fnum;
+ break;
+ case ADDR_TABS:
+ lnum = LAST_TAB_NR;
+ break;
+ case ADDR_NONE:
+ case ADDR_TABS_RELATIVE:
+ case ADDR_UNSIGNED:
+ addr_error(addr_type);
+ cmd = NULL;
+ goto error;
+ break;
+ case ADDR_QUICKFIX:
+ lnum = qf_get_size(eap);
+ if (lnum == 0) {
+ lnum = 1;
+ }
+ break;
+ case ADDR_QUICKFIX_VALID:
+ lnum = qf_get_valid_size(eap);
+ if (lnum == 0) {
+ lnum = 1;
+ }
+ break;
}
break;
- case '\'': /* ''' - mark */
+ case '\'': // ''' - mark
if (*++cmd == NUL) {
cmd = NULL;
goto error;
@@ -3875,17 +3960,17 @@ static linenr_T get_address(exarg_T *eap,
cmd = NULL;
goto error;
}
- if (skip)
+ if (skip) {
++cmd;
- else {
+ } else {
/* Only accept a mark in another file when it is
* used by itself: ":'M". */
fp = getmark(*cmd, to_other_file && cmd[1] == NUL);
++cmd;
- if (fp == (pos_T *)-1)
- /* Jumped to another file. */
+ if (fp == (pos_T *)-1) {
+ // Jumped to another file.
lnum = curwin->w_cursor.lnum;
- else {
+ } else {
if (check_mark(fp) == FAIL) {
cmd = NULL;
goto error;
@@ -3896,17 +3981,18 @@ static linenr_T get_address(exarg_T *eap,
break;
case '/':
- case '?': /* '/' or '?' - search */
+ case '?': // '/' or '?' - search
c = *cmd++;
if (addr_type != ADDR_LINES) {
addr_error(addr_type);
cmd = NULL;
goto error;
}
- if (skip) { /* skip "/pat/" */
+ if (skip) { // skip "/pat/"
cmd = skip_regexp(cmd, c, p_magic, NULL);
- if (*cmd == c)
+ if (*cmd == c) {
++cmd;
+ }
} else {
int flags;
@@ -3938,23 +4024,23 @@ static linenr_T get_address(exarg_T *eap,
}
lnum = curwin->w_cursor.lnum;
curwin->w_cursor = pos;
- /* adjust command string pointer */
+ // adjust command string pointer
cmd += searchcmdlen;
}
break;
- case '\\': /* "\?", "\/" or "\&", repeat search */
+ case '\\': // "\?", "\/" or "\&", repeat search
++cmd;
if (addr_type != ADDR_LINES) {
addr_error(addr_type);
cmd = NULL;
goto error;
}
- if (*cmd == '&')
+ if (*cmd == '&') {
i = RE_SUBST;
- else if (*cmd == '?' || *cmd == '/')
+ } else if (*cmd == '?' || *cmd == '/') {
i = RE_SEARCH;
- else {
+ } else {
EMSG(_(e_backslash));
cmd = NULL;
goto error;
@@ -3992,37 +4078,37 @@ static linenr_T get_address(exarg_T *eap,
if (lnum == MAXLNUM) {
switch (addr_type) {
- case ADDR_LINES:
- case ADDR_OTHER:
- // "+1" is same as ".+1"
- lnum = curwin->w_cursor.lnum;
- break;
- case ADDR_WINDOWS:
- lnum = CURRENT_WIN_NR;
- break;
- case ADDR_ARGUMENTS:
- lnum = curwin->w_arg_idx + 1;
- break;
- case ADDR_LOADED_BUFFERS:
- case ADDR_BUFFERS:
- lnum = curbuf->b_fnum;
- break;
- case ADDR_TABS:
- lnum = CURRENT_TAB_NR;
- break;
- case ADDR_TABS_RELATIVE:
- lnum = 1;
- break;
- case ADDR_QUICKFIX:
- lnum = qf_get_cur_idx(eap);
- break;
- case ADDR_QUICKFIX_VALID:
- lnum = qf_get_cur_valid_idx(eap);
- break;
- case ADDR_NONE:
- case ADDR_UNSIGNED:
- lnum = 0;
- break;
+ case ADDR_LINES:
+ case ADDR_OTHER:
+ // "+1" is same as ".+1"
+ lnum = curwin->w_cursor.lnum;
+ break;
+ case ADDR_WINDOWS:
+ lnum = CURRENT_WIN_NR;
+ break;
+ case ADDR_ARGUMENTS:
+ lnum = curwin->w_arg_idx + 1;
+ break;
+ case ADDR_LOADED_BUFFERS:
+ case ADDR_BUFFERS:
+ lnum = curbuf->b_fnum;
+ break;
+ case ADDR_TABS:
+ lnum = CURRENT_TAB_NR;
+ break;
+ case ADDR_TABS_RELATIVE:
+ lnum = 1;
+ break;
+ case ADDR_QUICKFIX:
+ lnum = qf_get_cur_idx(eap);
+ break;
+ case ADDR_QUICKFIX_VALID:
+ lnum = qf_get_cur_valid_idx(eap);
+ break;
+ case ADDR_NONE:
+ case ADDR_UNSIGNED:
+ lnum = 0;
+ break;
}
}
@@ -4042,8 +4128,7 @@ static linenr_T get_address(exarg_T *eap,
cmd = NULL;
goto error;
} else if (addr_type == ADDR_LOADED_BUFFERS || addr_type == ADDR_BUFFERS) {
- lnum = compute_buffer_local_count(
- addr_type, lnum, (i == '-') ? -1 * n : n);
+ lnum = compute_buffer_local_count(addr_type, lnum, (i == '-') ? -1 * n : n);
} else {
// Relative line addressing, need to adjust for folded lines
// now, but only do it after the first address.
@@ -4071,12 +4156,13 @@ error:
static void get_flags(exarg_T *eap)
{
while (vim_strchr((char_u *)"lp#", *eap->arg) != NULL) {
- if (*eap->arg == 'l')
+ if (*eap->arg == 'l') {
eap->flags |= EXFLAG_LIST;
- else if (*eap->arg == 'p')
+ } else if (*eap->arg == 'p') {
eap->flags |= EXFLAG_PRINT;
- else
+ } else {
eap->flags |= EXFLAG_NR;
+ }
eap->arg = skipwhite(eap->arg + 1);
}
}
@@ -4084,9 +4170,9 @@ static void get_flags(exarg_T *eap)
/// Stub function for command which is Not Implemented. NI!
void ex_ni(exarg_T *eap)
{
- if (!eap->skip)
- eap->errmsg = (char_u *)N_(
- "E319: The command is not available in this version");
+ if (!eap->skip) {
+ eap->errmsg = (char_u *)N_("E319: The command is not available in this version");
+ }
}
/// Stub function for script command which is Not Implemented. NI!
@@ -4114,77 +4200,77 @@ static char_u *invalid_range(exarg_T *eap)
if (eap->argt & EX_RANGE) {
switch (eap->addr_type) {
- case ADDR_LINES:
- if (eap->line2 > (curbuf->b_ml.ml_line_count
- + (eap->cmdidx == CMD_diffget))) {
- return (char_u *)_(e_invrange);
- }
- break;
- case ADDR_ARGUMENTS:
- // add 1 if ARGCOUNT is 0
- if (eap->line2 > ARGCOUNT + (!ARGCOUNT)) {
- return (char_u *)_(e_invrange);
- }
- break;
- case ADDR_BUFFERS:
- if (eap->line1 < firstbuf->b_fnum
- || eap->line2 > lastbuf->b_fnum) {
- return (char_u *)_(e_invrange);
- }
- break;
- case ADDR_LOADED_BUFFERS:
- buf = firstbuf;
- while (buf->b_ml.ml_mfp == NULL) {
- if (buf->b_next == NULL) {
- return (char_u *)_(e_invrange);
- }
- buf = buf->b_next;
- }
- if (eap->line1 < buf->b_fnum) {
- return (char_u *)_(e_invrange);
- }
- buf = lastbuf;
- while (buf->b_ml.ml_mfp == NULL) {
- if (buf->b_prev == NULL) {
- return (char_u *)_(e_invrange);
- }
- buf = buf->b_prev;
- }
- if (eap->line2 > buf->b_fnum) {
- return (char_u *)_(e_invrange);
- }
- break;
- case ADDR_WINDOWS:
- if (eap->line2 > LAST_WIN_NR) {
- return (char_u *)_(e_invrange);
- }
- break;
- case ADDR_TABS:
- if (eap->line2 > LAST_TAB_NR) {
- return (char_u *)_(e_invrange);
- }
- break;
- case ADDR_TABS_RELATIVE:
- case ADDR_OTHER:
- // Any range is OK.
- break;
- case ADDR_QUICKFIX:
- assert(eap->line2 >= 0);
- // No error for value that is too big, will use the last entry.
- if (eap->line2 <= 0) {
+ case ADDR_LINES:
+ if (eap->line2 > (curbuf->b_ml.ml_line_count
+ + (eap->cmdidx == CMD_diffget))) {
+ return (char_u *)_(e_invrange);
+ }
+ break;
+ case ADDR_ARGUMENTS:
+ // add 1 if ARGCOUNT is 0
+ if (eap->line2 > ARGCOUNT + (!ARGCOUNT)) {
+ return (char_u *)_(e_invrange);
+ }
+ break;
+ case ADDR_BUFFERS:
+ if (eap->line1 < firstbuf->b_fnum
+ || eap->line2 > lastbuf->b_fnum) {
+ return (char_u *)_(e_invrange);
+ }
+ break;
+ case ADDR_LOADED_BUFFERS:
+ buf = firstbuf;
+ while (buf->b_ml.ml_mfp == NULL) {
+ if (buf->b_next == NULL) {
return (char_u *)_(e_invrange);
}
- break;
- case ADDR_QUICKFIX_VALID:
- if ((eap->line2 != 1 && (size_t)eap->line2 > qf_get_valid_size(eap))
- || eap->line2 < 0) {
+ buf = buf->b_next;
+ }
+ if (eap->line1 < buf->b_fnum) {
+ return (char_u *)_(e_invrange);
+ }
+ buf = lastbuf;
+ while (buf->b_ml.ml_mfp == NULL) {
+ if (buf->b_prev == NULL) {
return (char_u *)_(e_invrange);
}
- break;
- case ADDR_UNSIGNED:
- case ADDR_NONE:
- // Will give an error elsewhere.
- break;
+ buf = buf->b_prev;
+ }
+ if (eap->line2 > buf->b_fnum) {
+ return (char_u *)_(e_invrange);
+ }
+ break;
+ case ADDR_WINDOWS:
+ if (eap->line2 > LAST_WIN_NR) {
+ return (char_u *)_(e_invrange);
+ }
+ break;
+ case ADDR_TABS:
+ if (eap->line2 > LAST_TAB_NR) {
+ return (char_u *)_(e_invrange);
+ }
+ break;
+ case ADDR_TABS_RELATIVE:
+ case ADDR_OTHER:
+ // Any range is OK.
+ break;
+ case ADDR_QUICKFIX:
+ assert(eap->line2 >= 0);
+ // No error for value that is too big, will use the last entry.
+ if (eap->line2 <= 0) {
+ return (char_u *)_(e_invrange);
+ }
+ break;
+ case ADDR_QUICKFIX_VALID:
+ if ((eap->line2 != 1 && (size_t)eap->line2 > qf_get_valid_size(eap))
+ || eap->line2 < 0) {
+ return (char_u *)_(e_invrange);
+ }
+ break;
+ case ADDR_UNSIGNED:
+ case ADDR_NONE:
+ // Will give an error elsewhere.
+ break;
}
}
return NULL;
@@ -4212,15 +4298,16 @@ static void correct_range(exarg_T *eap)
*/
static char_u *skip_grep_pat(exarg_T *eap)
{
- char_u *p = eap->arg;
+ char_u *p = eap->arg;
if (*p != NUL && (eap->cmdidx == CMD_vimgrep || eap->cmdidx == CMD_lvimgrep
|| eap->cmdidx == CMD_vimgrepadd
|| eap->cmdidx == CMD_lvimgrepadd
|| grep_internal(eap->cmdidx))) {
p = skip_vimgrep_pat(p, NULL, NULL);
- if (p == NULL)
+ if (p == NULL) {
p = eap->arg;
+ }
}
return p;
}
@@ -4231,10 +4318,10 @@ static char_u *skip_grep_pat(exarg_T *eap)
*/
static char_u *replace_makeprg(exarg_T *eap, char_u *p, char_u **cmdlinep)
{
- char_u *new_cmdline;
- char_u *program;
- char_u *pos;
- char_u *ptr;
+ char_u *new_cmdline;
+ char_u *program;
+ char_u *pos;
+ char_u *ptr;
int len;
int i;
@@ -4248,24 +4335,27 @@ static char_u *replace_makeprg(exarg_T *eap, char_u *p, char_u **cmdlinep)
&& !grep_internal(eap->cmdidx)) {
if (eap->cmdidx == CMD_grep || eap->cmdidx == CMD_lgrep
|| eap->cmdidx == CMD_grepadd || eap->cmdidx == CMD_lgrepadd) {
- if (*curbuf->b_p_gp == NUL)
+ if (*curbuf->b_p_gp == NUL) {
program = p_gp;
- else
+ } else {
program = curbuf->b_p_gp;
+ }
} else {
- if (*curbuf->b_p_mp == NUL)
+ if (*curbuf->b_p_mp == NUL) {
program = p_mp;
- else
+ } else {
program = curbuf->b_p_mp;
+ }
}
p = skipwhite(p);
if ((pos = (char_u *)strstr((char *)program, "$*")) != NULL) {
- /* replace $* by given arguments */
+ // replace $* by given arguments
i = 1;
- while ((pos = (char_u *)strstr((char *)pos + 2, "$*")) != NULL)
+ while ((pos = (char_u *)strstr((char *)pos + 2, "$*")) != NULL) {
++i;
+ }
len = (int)STRLEN(p);
new_cmdline = xmalloc(STRLEN(program) + i * (len - 2) + 1);
ptr = new_cmdline;
@@ -4285,7 +4375,7 @@ static char_u *replace_makeprg(exarg_T *eap, char_u *p, char_u **cmdlinep)
}
msg_make(p);
- /* 'eap->cmd' is not set here, because it is not used at CMD_make */
+ // 'eap->cmd' is not set here, because it is not used at CMD_make
xfree(*cmdlinep);
*cmdlinep = new_cmdline;
p = new_cmdline;
@@ -4298,13 +4388,13 @@ static char_u *replace_makeprg(exarg_T *eap, char_u *p, char_u **cmdlinep)
// Return FAIL for failure, OK otherwise.
int expand_filename(exarg_T *eap, char_u **cmdlinep, char_u **errormsgp)
{
- int has_wildcards; /* need to expand wildcards */
- char_u *repl;
+ int has_wildcards; // need to expand wildcards
+ char_u *repl;
size_t srclen;
- char_u *p;
+ char_u *p;
int escaped;
- /* Skip a regexp pattern for ":vimgrep[add] pat file..." */
+ // Skip a regexp pattern for ":vimgrep[add] pat file..."
p = skip_grep_pat(eap);
/*
@@ -4314,12 +4404,13 @@ int expand_filename(exarg_T *eap, char_u **cmdlinep, char_u **errormsgp)
*/
has_wildcards = path_has_wildcard(p);
while (*p != NUL) {
- /* Skip over `=expr`, wildcards in it are not expanded. */
+ // Skip over `=expr`, wildcards in it are not expanded.
if (p[0] == '`' && p[1] == '=') {
p += 2;
(void)skip_expr(&p);
- if (*p == '`')
+ if (*p == '`') {
++p;
+ }
continue;
}
/*
@@ -4335,10 +4426,11 @@ int expand_filename(exarg_T *eap, char_u **cmdlinep, char_u **errormsgp)
* Try to find a match at this position.
*/
repl = eval_vars(p, eap->arg, &srclen, &(eap->do_ecmd_lnum),
- errormsgp, &escaped);
- if (*errormsgp != NULL) /* error detected */
+ errormsgp, &escaped);
+ if (*errormsgp != NULL) { // error detected
return FAIL;
- if (repl == NULL) { /* no match found */
+ }
+ if (repl == NULL) { // no match found
p += srclen;
continue;
}
@@ -4368,9 +4460,8 @@ int expand_filename(exarg_T *eap, char_u **cmdlinep, char_u **errormsgp)
&& eap->cmdidx != CMD_lmake
&& eap->cmdidx != CMD_make
&& eap->cmdidx != CMD_terminal
- && !(eap->argt & EX_NOSPC)
- ) {
- char_u *l;
+ && !(eap->argt & EX_NOSPC)) {
+ char_u *l;
#ifdef BACKSLASH_IN_FILENAME
/* Don't escape a backslash here, because rem_backslash() doesn't
* remove it later. */
@@ -4380,13 +4471,14 @@ int expand_filename(exarg_T *eap, char_u **cmdlinep, char_u **errormsgp)
# define ESCAPE_CHARS escape_chars
#endif
- for (l = repl; *l; ++l)
+ for (l = repl; *l; ++l) {
if (vim_strchr(ESCAPE_CHARS, *l) != NULL) {
l = vim_strsave_escaped(repl, ESCAPE_CHARS);
xfree(repl);
repl = l;
break;
}
+ }
}
// For a shell command a '!' must be escaped.
@@ -4394,7 +4486,7 @@ int expand_filename(exarg_T *eap, char_u **cmdlinep, char_u **errormsgp)
|| eap->cmdidx == CMD_bang
|| eap->cmdidx == CMD_terminal)
&& vim_strpbrk(repl, (char_u *)"!") != NULL) {
- char_u *l;
+ char_u *l;
l = vim_strsave_escaped(repl, (char_u *)"!");
xfree(repl);
@@ -4421,12 +4513,12 @@ int expand_filename(exarg_T *eap, char_u **cmdlinep, char_u **errormsgp)
*/
if (vim_strchr(eap->arg, '$') != NULL
|| vim_strchr(eap->arg, '~') != NULL) {
- expand_env_esc(eap->arg, NameBuff, MAXPATHL,
- TRUE, TRUE, NULL);
+ expand_env_esc(eap->arg, NameBuff, MAXPATHL, true, true, NULL);
has_wildcards = path_has_wildcard(NameBuff);
p = NameBuff;
- } else
+ } else {
p = NULL;
+ }
if (p != NULL) {
(void)repl_cmdline(eap, eap->arg, STRLEN(eap->arg), p, cmdlinep);
}
@@ -4448,8 +4540,9 @@ int expand_filename(exarg_T *eap, char_u **cmdlinep, char_u **errormsgp)
ExpandInit(&xpc);
xpc.xp_context = EXPAND_FILES;
- if (p_wic)
+ if (p_wic) {
options += WILD_ICASE;
+ }
p = ExpandOne(&xpc, eap->arg, NULL, options, WILD_EXPAND_FREE);
if (p == NULL) {
return FAIL;
@@ -4468,8 +4561,8 @@ int expand_filename(exarg_T *eap, char_u **cmdlinep, char_u **errormsgp)
* "repl" is the replacement string.
* Returns a pointer to the character after the replaced string.
*/
-static char_u *repl_cmdline(exarg_T *eap, char_u *src, size_t srclen,
- char_u *repl, char_u **cmdlinep)
+static char_u *repl_cmdline(exarg_T *eap, char_u *src, size_t srclen, char_u *repl,
+ char_u **cmdlinep)
{
/*
* The new command line is build in new_cmdline[].
@@ -4478,8 +4571,9 @@ static char_u *repl_cmdline(exarg_T *eap, char_u *src, size_t srclen,
*/
size_t len = STRLEN(repl);
size_t i = (size_t)(src - *cmdlinep) + STRLEN(src + srclen) + len + 3;
- if (eap->nextcmd != NULL)
- i += STRLEN(eap->nextcmd); /* add space for next command */
+ if (eap->nextcmd != NULL) {
+ i += STRLEN(eap->nextcmd); // add space for next command
+ }
char_u *new_cmdline = xmalloc(i);
/*
@@ -4488,23 +4582,24 @@ static char_u *repl_cmdline(exarg_T *eap, char_u *src, size_t srclen,
* Copy what came after the expanded part.
* Copy the next commands, if there are any.
*/
- i = (size_t)(src - *cmdlinep); /* length of part before match */
+ i = (size_t)(src - *cmdlinep); // length of part before match
memmove(new_cmdline, *cmdlinep, i);
memmove(new_cmdline + i, repl, len);
- i += len; /* remember the end of the string */
+ i += len; // remember the end of the string
STRCPY(new_cmdline + i, src + srclen);
- src = new_cmdline + i; /* remember where to continue */
+ src = new_cmdline + i; // remember where to continue
- if (eap->nextcmd != NULL) { /* append next command */
+ if (eap->nextcmd != NULL) { // append next command
i = STRLEN(new_cmdline) + 1;
STRCPY(new_cmdline + i, eap->nextcmd);
eap->nextcmd = new_cmdline + i;
}
eap->cmd = new_cmdline + (eap->cmd - *cmdlinep);
eap->arg = new_cmdline + (eap->arg - *cmdlinep);
- if (eap->do_ecmd_cmd != NULL && eap->do_ecmd_cmd != dollar_command)
+ if (eap->do_ecmd_cmd != NULL && eap->do_ecmd_cmd != dollar_command) {
eap->do_ecmd_cmd = new_cmdline + (eap->do_ecmd_cmd - *cmdlinep);
+ }
xfree(*cmdlinep);
*cmdlinep = new_cmdline;
@@ -4516,7 +4611,7 @@ static char_u *repl_cmdline(exarg_T *eap, char_u *src, size_t srclen,
*/
void separate_nextcmd(exarg_T *eap)
{
- char_u *p;
+ char_u *p;
p = skip_grep_pat(eap);
@@ -4539,16 +4634,16 @@ void separate_nextcmd(exarg_T *eap)
break;
}
} else if (
- // Check for '"': start of comment or '|': next command */
- // :@" does not start a comment!
- // :redir @" doesn't either.
- (*p == '"'
- && !(eap->argt & EX_NOTRLCOM)
- && (eap->cmdidx != CMD_at || p != eap->arg)
- && (eap->cmdidx != CMD_redir
- || p != eap->arg + 1 || p[-1] != '@'))
- || *p == '|'
- || *p == '\n') {
+ // Check for '"': start of comment or '|': next command */
+ // :@" does not start a comment!
+ // :redir @" doesn't either.
+ (*p == '"'
+ && !(eap->argt & EX_NOTRLCOM)
+ && (eap->cmdidx != CMD_at || p != eap->arg)
+ && (eap->cmdidx != CMD_redir
+ || p != eap->arg + 1 || p[-1] != '@'))
+ || *p == '|'
+ || *p == '\n') {
// We remove the '\' before the '|', unless EX_CTRLV is used
// AND 'b' is present in 'cpoptions'.
if ((vim_strchr(p_cpo, CPO_BAR) == NULL
@@ -4576,38 +4671,36 @@ static char_u *getargcmd(char_u **argp)
char_u *arg = *argp;
char_u *command = NULL;
- if (*arg == '+') { /* +[command] */
+ if (*arg == '+') { // +[command]
++arg;
- if (ascii_isspace(*arg) || *arg == '\0')
+ if (ascii_isspace(*arg) || *arg == '\0') {
command = dollar_command;
- else {
+ } else {
command = arg;
arg = skip_cmd_arg(command, TRUE);
- if (*arg != NUL)
- *arg++ = NUL; /* terminate command with NUL */
+ if (*arg != NUL) {
+ *arg++ = NUL; // terminate command with NUL
+ }
}
- arg = skipwhite(arg); /* skip over spaces */
+ arg = skipwhite(arg); // skip over spaces
*argp = arg;
}
return command;
}
-/*
- * Find end of "+command" argument. Skip over "\ " and "\\".
- */
-static char_u *
-skip_cmd_arg (
- char_u *p,
- int rembs /* TRUE to halve the number of backslashes */
-)
+/// Find end of "+command" argument. Skip over "\ " and "\\".
+///
+/// @param rembs TRUE to halve the number of backslashes
+static char_u *skip_cmd_arg(char_u *p, int rembs)
{
while (*p && !ascii_isspace(*p)) {
if (*p == '\\' && p[1] != NUL) {
- if (rembs)
+ if (rembs) {
STRMOVE(p, p + 1);
- else
+ } else {
++p;
+ }
}
MB_PTR_ADV(p);
}
@@ -4635,25 +4728,27 @@ int get_bad_opt(const char_u *p, exarg_T *eap)
*/
static int getargopt(exarg_T *eap)
{
- char_u *arg = eap->arg + 2;
- int *pp = NULL;
+ char_u *arg = eap->arg + 2;
+ int *pp = NULL;
int bad_char_idx;
- char_u *p;
+ char_u *p;
- /* ":edit ++[no]bin[ary] file" */
+ // ":edit ++[no]bin[ary] file"
if (STRNCMP(arg, "bin", 3) == 0 || STRNCMP(arg, "nobin", 5) == 0) {
if (*arg == 'n') {
arg += 2;
eap->force_bin = FORCE_NOBIN;
- } else
+ } else {
eap->force_bin = FORCE_BIN;
- if (!checkforcmd(&arg, "binary", 3))
+ }
+ if (!checkforcmd(&arg, "binary", 3)) {
return FAIL;
+ }
eap->arg = skipwhite(arg);
return OK;
}
- /* ":read ++edit file" */
+ // ":read ++edit file"
if (STRNCMP(arg, "edit", 4) == 0) {
eap->read_edit = TRUE;
eap->arg = skipwhite(arg + 4);
@@ -4667,18 +4762,20 @@ static int getargopt(exarg_T *eap)
arg += 10;
pp = &eap->force_ff;
} else if (STRNCMP(arg, "enc", 3) == 0) {
- if (STRNCMP(arg, "encoding", 8) == 0)
+ if (STRNCMP(arg, "encoding", 8) == 0) {
arg += 8;
- else
+ } else {
arg += 3;
+ }
pp = &eap->force_enc;
} else if (STRNCMP(arg, "bad", 3) == 0) {
arg += 3;
pp = &bad_char_idx;
}
- if (pp == NULL || *arg != '=')
+ if (pp == NULL || *arg != '=') {
return FAIL;
+ }
++arg;
*pp = (int)(arg - eap->cmd);
@@ -4692,9 +4789,10 @@ static int getargopt(exarg_T *eap)
}
eap->force_ff = eap->cmd[eap->force_ff];
} else if (pp == &eap->force_enc) {
- /* Make 'fileencoding' lower case. */
- for (p = eap->cmd + eap->force_enc; *p != NUL; ++p)
+ // Make 'fileencoding' lower case.
+ for (p = eap->cmd + eap->force_enc; *p != NUL; ++p) {
*p = TOLOWER_ASC(*p);
+ }
} else {
/* Check ++bad= argument. Must be a single-byte character, "keep" or
* "drop". */
@@ -4717,8 +4815,8 @@ static int get_tabpage_arg(exarg_T *eap)
if (eap->arg && *eap->arg != NUL) {
char_u *p = eap->arg;
char_u *p_save;
- int relative = 0; // argument +N/-N means: go to N places to the
- // right/left relative to the current position.
+ int relative = 0; // argument +N/-N means: go to N places to the
+ // right/left relative to the current position.
if (*p == '-') {
relative = -1;
@@ -4745,8 +4843,7 @@ static int get_tabpage_arg(exarg_T *eap)
} else {
if (*p_save == NUL) {
tab_number = 1;
- }
- else if (p == p_save || *p_save == '-' || *p != NUL || tab_number == 0) {
+ } else if (p == p_save || *p_save == '-' || *p != NUL || tab_number == 0) {
// No numbers as argument.
eap->errmsg = e_invarg;
goto theend;
@@ -4776,8 +4873,9 @@ static int get_tabpage_arg(exarg_T *eap)
switch (eap->cmdidx) {
case CMD_tabnext:
tab_number = tabpage_index(curtab) + 1;
- if (tab_number > LAST_TAB_NR)
+ if (tab_number > LAST_TAB_NR) {
tab_number = 1;
+ }
break;
case CMD_tabmove:
tab_number = LAST_TAB_NR;
@@ -4796,7 +4894,7 @@ theend:
*/
static void ex_abbreviate(exarg_T *eap)
{
- do_exmap(eap, TRUE); /* almost the same as mapping */
+ do_exmap(eap, TRUE); // almost the same as mapping
}
/*
@@ -4847,10 +4945,11 @@ static void ex_autocmd(exarg_T *eap)
if (secure) {
secure = 2;
eap->errmsg = e_curdir;
- } else if (eap->cmdidx == CMD_autocmd)
+ } else if (eap->cmdidx == CMD_autocmd) {
do_autocmd(eap->arg, eap->forceit);
- else
+ } else {
do_augroup(eap->arg, eap->forceit);
+ }
}
/*
@@ -4876,16 +4975,16 @@ static void ex_doautocmd(exarg_T *eap)
*/
static void ex_bunload(exarg_T *eap)
{
- eap->errmsg = do_bufdel(
- eap->cmdidx == CMD_bdelete ? DOBUF_DEL
- : eap->cmdidx == CMD_bwipeout ? DOBUF_WIPE
- : DOBUF_UNLOAD, eap->arg,
- eap->addr_count, (int)eap->line1, (int)eap->line2, eap->forceit);
+ eap->errmsg = do_bufdel(eap->cmdidx == CMD_bdelete ? DOBUF_DEL
+ : eap->cmdidx == CMD_bwipeout ? DOBUF_WIPE
+ : DOBUF_UNLOAD,
+ eap->arg,
+ eap->addr_count, (int)eap->line1, (int)eap->line2, eap->forceit);
}
/*
- * :[N]buffer [N] to buffer N
- * :[N]sbuffer [N] to buffer N
+ * :[N]buffer [N] to buffer N
+ * :[N]sbuffer [N] to buffer N
*/
static void ex_buffer(exarg_T *eap)
{
@@ -4904,8 +5003,8 @@ static void ex_buffer(exarg_T *eap)
}
/*
- * :[N]bmodified [N] to next mod. buffer
- * :[N]sbmodified [N] to next mod. buffer
+ * :[N]bmodified [N] to next mod. buffer
+ * :[N]sbmodified [N] to next mod. buffer
*/
static void ex_bmodified(exarg_T *eap)
{
@@ -4916,8 +5015,8 @@ static void ex_bmodified(exarg_T *eap)
}
/*
- * :[N]bnext [N] to next buffer
- * :[N]sbnext [N] split and to next buffer
+ * :[N]bnext [N] to next buffer
+ * :[N]sbnext [N] split and to next buffer
*/
static void ex_bnext(exarg_T *eap)
{
@@ -4928,10 +5027,10 @@ static void ex_bnext(exarg_T *eap)
}
/*
- * :[N]bNext [N] to previous buffer
- * :[N]bprevious [N] to previous buffer
- * :[N]sbNext [N] split and to previous buffer
- * :[N]sbprevious [N] split and to previous buffer
+ * :[N]bNext [N] to previous buffer
+ * :[N]bprevious [N] to previous buffer
+ * :[N]sbNext [N] split and to previous buffer
+ * :[N]sbprevious [N] split and to previous buffer
*/
static void ex_bprevious(exarg_T *eap)
{
@@ -4942,10 +5041,10 @@ static void ex_bprevious(exarg_T *eap)
}
/*
- * :brewind to first buffer
- * :bfirst to first buffer
- * :sbrewind split and to first buffer
- * :sbfirst split and to first buffer
+ * :brewind to first buffer
+ * :bfirst to first buffer
+ * :sbrewind split and to first buffer
+ * :sbfirst split and to first buffer
*/
static void ex_brewind(exarg_T *eap)
{
@@ -4956,8 +5055,8 @@ static void ex_brewind(exarg_T *eap)
}
/*
- * :blast to last buffer
- * :sblast split and to last buffer
+ * :blast to last buffer
+ * :sblast split and to last buffer
*/
static void ex_blast(exarg_T *eap)
{
@@ -4991,28 +5090,23 @@ char_u *find_nextcmd(const char_u *p)
/// Return NULL if it isn't, the following character if it is.
char_u *check_nextcmd(char_u *p)
{
- char_u *s = skipwhite(p);
+ char_u *s = skipwhite(p);
- if (*s == '|' || *s == '\n') {
- return (s + 1);
- } else {
- return NULL;
- }
+ if (*s == '|' || *s == '\n') {
+ return (s + 1);
+ } else {
+ return NULL;
+ }
}
-/*
- * - if there are more files to edit
- * - and this is the last window
- * - and forceit not used
- * - and not repeated twice on a row
- * return FAIL and give error message if 'message' TRUE
- * return OK otherwise
- */
-static int
-check_more(
- int message, // when FALSE check only, no messages
- bool forceit
-)
+/// - if there are more files to edit
+/// - and this is the last window
+/// - and forceit not used
+/// - and not repeated twice on a row
+/// @return FAIL and give error message if 'message' TRUE, return OK otherwise
+///
+/// @param message when FALSE check only, no messages
+static int check_more(int message, bool forceit)
{
int n = ARGCOUNT - curwin->w_arg_idx - 1;
@@ -5022,21 +5116,24 @@ check_more(
if ((p_confirm || cmdmod.confirm) && curbuf->b_fname != NULL) {
char_u buff[DIALOG_MSG_SIZE];
- if (n == 1)
+ if (n == 1) {
STRLCPY(buff, _("1 more file to edit. Quit anyway?"),
- DIALOG_MSG_SIZE);
- else
+ DIALOG_MSG_SIZE);
+ } else {
vim_snprintf((char *)buff, DIALOG_MSG_SIZE,
- _("%d more files to edit. Quit anyway?"), n);
- if (vim_dialog_yesno(VIM_QUESTION, NULL, buff, 1) == VIM_YES)
+ _("%d more files to edit. Quit anyway?"), n);
+ }
+ if (vim_dialog_yesno(VIM_QUESTION, NULL, buff, 1) == VIM_YES) {
return OK;
+ }
return FAIL;
}
- if (n == 1)
+ if (n == 1) {
EMSG(_("E173: 1 more file to edit"));
- else
+ } else {
EMSGN(_("E173: %" PRId64 " more files to edit"), n);
- quitmore = 2; /* next try to quit is allowed */
+ }
+ quitmore = 2; // next try to quit is allowed
}
return FAIL;
}
@@ -5048,38 +5145,40 @@ check_more(
*/
char_u *get_command_name(expand_T *xp, int idx)
{
- if (idx >= (int)CMD_SIZE)
+ if (idx >= CMD_SIZE) {
return get_user_command_name(idx);
+ }
return cmdnames[idx].cmd_name;
}
-static int uc_add_command(char_u *name, size_t name_len, char_u *rep,
- uint32_t argt, long def, int flags, int compl,
- char_u *compl_arg, cmd_addr_T addr_type, bool force)
+static int uc_add_command(char_u *name, size_t name_len, char_u *rep, uint32_t argt, long def,
+ int flags, int compl, char_u *compl_arg, cmd_addr_T addr_type, bool force)
FUNC_ATTR_NONNULL_ARG(1, 3)
{
- ucmd_T *cmd = NULL;
+ ucmd_T *cmd = NULL;
int i;
int cmp = 1;
- char_u *rep_buf = NULL;
- garray_T *gap;
+ char_u *rep_buf = NULL;
+ garray_T *gap;
replace_termcodes(rep, STRLEN(rep), &rep_buf, false, false, true,
CPO_TO_CPO_FLAGS);
if (rep_buf == NULL) {
- /* Can't replace termcodes - try using the string as is */
+ // Can't replace termcodes - try using the string as is
rep_buf = vim_strsave(rep);
}
- /* get address of growarray: global or in curbuf */
+ // get address of growarray: global or in curbuf
if (flags & UC_BUFFER) {
gap = &curbuf->b_ucmds;
- if (gap->ga_itemsize == 0)
+ if (gap->ga_itemsize == 0) {
ga_init(gap, (int)sizeof(ucmd_T), 4);
- } else
+ }
+ } else {
gap = &ucmds;
+ }
- /* Search for the command in the already defined commands. */
+ // Search for the command in the already defined commands.
for (i = 0; i < gap->ga_len; ++i) {
size_t len;
@@ -5087,10 +5186,11 @@ static int uc_add_command(char_u *name, size_t name_len, char_u *rep,
len = STRLEN(cmd->uc_name);
cmp = STRNCMP(name, cmd->uc_name, name_len);
if (cmp == 0) {
- if (name_len < len)
+ if (name_len < len) {
cmp = -1;
- else if (name_len > len)
+ } else if (name_len > len) {
cmp = 1;
+ }
}
if (cmp == 0) {
@@ -5109,12 +5209,13 @@ static int uc_add_command(char_u *name, size_t name_len, char_u *rep,
break;
}
- /* Stop as soon as we pass the name to add */
- if (cmp < 0)
+ // Stop as soon as we pass the name to add
+ if (cmp < 0) {
break;
+ }
}
- /* Extend the array unless we're replacing an existing command */
+ // Extend the array unless we're replacing an existing command
if (cmp != 0) {
ga_grow(gap, 1);
@@ -5225,7 +5326,7 @@ static void uc_list(char_u *name, size_t name_len)
{
int i, j;
bool found = false;
- ucmd_T *cmd;
+ ucmd_T *cmd;
uint32_t a;
// In cmdwin, the alternative buffer should be used.
@@ -5251,8 +5352,9 @@ static void uc_list(char_u *name, size_t name_len)
}
found = true;
msg_putchar('\n');
- if (got_int)
+ if (got_int) {
break;
+ }
// Special cases
int len = 4;
@@ -5291,21 +5393,21 @@ static void uc_list(char_u *name, size_t name_len)
// Arguments
switch (a & (EX_EXTRA | EX_NOSPC | EX_NEEDARG)) {
- case 0:
- IObuff[len++] = '0';
- break;
- case (EX_EXTRA):
- IObuff[len++] = '*';
- break;
- case (EX_EXTRA | EX_NOSPC):
- IObuff[len++] = '?';
- break;
- case (EX_EXTRA | EX_NEEDARG):
- IObuff[len++] = '+';
- break;
- case (EX_EXTRA | EX_NOSPC | EX_NEEDARG):
- IObuff[len++] = '1';
- break;
+ case 0:
+ IObuff[len++] = '0';
+ break;
+ case (EX_EXTRA):
+ IObuff[len++] = '*';
+ break;
+ case (EX_EXTRA | EX_NOSPC):
+ IObuff[len++] = '?';
+ break;
+ case (EX_EXTRA | EX_NEEDARG):
+ IObuff[len++] = '+';
+ break;
+ case (EX_EXTRA | EX_NOSPC | EX_NEEDARG):
+ IObuff[len++] = '1';
+ break;
}
do {
@@ -5373,21 +5475,22 @@ static void uc_list(char_u *name, size_t name_len)
break;
}
}
- if (gap == &ucmds || i < gap->ga_len)
+ if (gap == &ucmds || i < gap->ga_len) {
break;
+ }
gap = &ucmds;
}
- if (!found)
+ if (!found) {
MSG(_("No user-defined commands found"));
+ }
}
-static int uc_scan_attr(char_u *attr, size_t len, uint32_t *argt, long *def,
- int *flags, int *complp, char_u **compl_arg,
- cmd_addr_T *addr_type_arg)
+static int uc_scan_attr(char_u *attr, size_t len, uint32_t *argt, long *def, int *flags,
+ int *complp, char_u **compl_arg, cmd_addr_T *addr_type_arg)
FUNC_ATTR_NONNULL_ALL
{
- char_u *p;
+ char_u *p;
if (len == 0) {
EMSG(_("E175: No attribute specified"));
@@ -5405,7 +5508,7 @@ static int uc_scan_attr(char_u *attr, size_t len, uint32_t *argt, long *def,
*argt |= EX_TRLBAR;
} else {
int i;
- char_u *val = NULL;
+ char_u *val = NULL;
size_t vallen = 0;
size_t attrlen = len;
@@ -5473,17 +5576,20 @@ invalid_count:
if (val != NULL) {
p = val;
- if (*def >= 0)
+ if (*def >= 0) {
goto two_count;
+ }
*def = getdigits_long(&p, true, 0);
- if (p != val + vallen)
+ if (p != val + vallen) {
goto invalid_count;
+ }
}
- if (*def < 0)
+ if (*def < 0) {
*def = 0;
+ }
} else if (STRNICMP(attr, "complete", attrlen) == 0) {
if (val == NULL) {
EMSG(_("E179: argument required for -complete"));
@@ -5518,26 +5624,28 @@ invalid_count:
return OK;
}
+static char e_complete_used_without_nargs[] = N_("E1208: -complete used without -nargs");
+
/*
* ":command ..."
*/
static void ex_command(exarg_T *eap)
{
- char_u *name;
- char_u *end;
- char_u *p;
+ char_u *name;
+ char_u *end;
+ char_u *p;
uint32_t argt = 0;
long def = -1;
int flags = 0;
- int compl = EXPAND_NOTHING;
- char_u *compl_arg = NULL;
+ int compl = EXPAND_NOTHING;
+ char_u *compl_arg = NULL;
cmd_addr_T addr_type_arg = ADDR_NONE;
int has_attr = (eap->arg[0] == '-');
int name_len;
p = eap->arg;
- /* Check for attributes */
+ // Check for attributes
while (*p == '-') {
++p;
end = skiptowhite(p);
@@ -5569,10 +5677,10 @@ static void ex_command(exarg_T *eap)
uc_list(name, end - name);
} else if (!ASCII_ISUPPER(*name)) {
EMSG(_("E183: User defined commands must start with an uppercase letter"));
- return;
} else if (name_len <= 4 && STRNCMP(name, "Next", name_len) == 0) {
EMSG(_("E841: Reserved name, cannot be used for user defined command"));
- return;
+ } else if (compl > 0 && (argt & EX_EXTRA) == 0) {
+ EMSG(_(e_complete_used_without_nargs));
} else {
uc_add_command(name, end - name, p, argt, def, flags, compl, compl_arg,
addr_type_arg, eap->forceit);
@@ -5589,7 +5697,7 @@ void ex_comclear(exarg_T *eap)
uc_clear(&curbuf->b_ucmds);
}
-static void free_ucmd(ucmd_T* cmd) {
+static void free_ucmd(ucmd_T * cmd) {
xfree(cmd->uc_name);
xfree(cmd->uc_rep);
xfree(cmd->uc_compl_arg);
@@ -5606,20 +5714,22 @@ void uc_clear(garray_T *gap)
static void ex_delcommand(exarg_T *eap)
{
int i = 0;
- ucmd_T *cmd = NULL;
+ ucmd_T *cmd = NULL;
int cmp = -1;
- garray_T *gap;
+ garray_T *gap;
gap = &curbuf->b_ucmds;
for (;; ) {
for (i = 0; i < gap->ga_len; ++i) {
cmd = USER_CMD_GA(gap, i);
cmp = STRCMP(eap->arg, cmd->uc_name);
- if (cmp <= 0)
+ if (cmp <= 0) {
break;
+ }
}
- if (gap == &ucmds || cmp == 0)
+ if (gap == &ucmds || cmp == 0) {
break;
+ }
gap = &ucmds;
}
@@ -5634,8 +5744,9 @@ static void ex_delcommand(exarg_T *eap)
--gap->ga_len;
- if (i < gap->ga_len)
+ if (i < gap->ga_len) {
memmove(cmd, cmd + 1, (gap->ga_len - i) * sizeof(ucmd_T));
+ }
}
/*
@@ -5648,9 +5759,9 @@ static char_u *uc_split_args(char_u *arg, size_t *lenp)
char_u *q;
int len;
- /* Precalculate length */
+ // Precalculate length
p = arg;
- len = 2; /* Initial and final quotes */
+ len = 2; // Initial and final quotes
while (*p) {
if (p[0] == '\\' && p[1] == '\\') {
@@ -5664,9 +5775,10 @@ static char_u *uc_split_args(char_u *arg, size_t *lenp)
p += 1;
} else if (ascii_iswhite(*p)) {
p = skipwhite(p);
- if (*p == NUL)
+ if (*p == NUL) {
break;
- len += 3; /* "," */
+ }
+ len += 3; // ","
} else {
const int charlen = utfc_ptr2len(p);
@@ -5693,8 +5805,9 @@ static char_u *uc_split_args(char_u *arg, size_t *lenp)
*q++ = *p++;
} else if (ascii_iswhite(*p)) {
p = skipwhite(p);
- if (*p == NUL)
+ if (*p == NUL) {
break;
+ }
*q++ = '"';
*q++ = ',';
*q++ = '"';
@@ -5727,28 +5840,22 @@ static size_t add_cmd_modifier(char_u *buf, char *mod_str, bool *multi_mods)
return result;
}
-/*
- * Check for a <> code in a user command.
- * "code" points to the '<'. "len" the length of the <> (inclusive).
- * "buf" is where the result is to be added.
- * "split_buf" points to a buffer used for splitting, caller should free it.
- * "split_len" is the length of what "split_buf" contains.
- * Returns the length of the replacement, which has been added to "buf".
- * Returns -1 if there was no match, and only the "<" has been copied.
- */
-static size_t
-uc_check_code(
- char_u *code,
- size_t len,
- char_u *buf,
- ucmd_T *cmd, /* the user command we're expanding */
- exarg_T *eap, /* ex arguments */
- char_u **split_buf,
- size_t *split_len
-)
+/// Check for a <> code in a user command.
+///
+/// @param code points to the '<'. "len" the length of the <> (inclusive).
+/// @param buf is where the result is to be added.
+/// @param cmd the user command we're expanding
+/// @param eap ex arguments
+/// @param split_buf points to a buffer used for splitting, caller should free it.
+/// @param split_len is the length of what "split_buf" contains.
+///
+/// @return the length of the replacement, which has been added to "buf".
+/// Return -1 if there was no match, and only the "<" has been copied.
+static size_t uc_check_code(char_u *code, size_t len, char_u *buf, ucmd_T *cmd, exarg_T *eap,
+ char_u **split_buf, size_t *split_len)
{
size_t result = 0;
- char_u *p = code + 1;
+ char_u *p = code + 1;
size_t l = len - 2;
int quote = 0;
enum {
@@ -5795,14 +5902,16 @@ uc_check_code(
switch (type) {
case ct_ARGS:
- /* Simple case first */
+ // Simple case first
if (*eap->arg == NUL) {
if (quote == 1) {
result = 2;
- if (buf != NULL)
+ if (buf != NULL) {
STRCPY(buf, "''");
- } else
+ }
+ } else {
result = 0;
+ }
break;
}
@@ -5813,12 +5922,13 @@ uc_check_code(
}
switch (quote) {
- case 0: /* No quoting, no splitting */
+ case 0: // No quoting, no splitting
result = STRLEN(eap->arg);
- if (buf != NULL)
+ if (buf != NULL) {
STRCPY(buf, eap->arg);
+ }
break;
- case 1: /* Quote, but don't split */
+ case 1: // Quote, but don't split
result = STRLEN(eap->arg) + 2;
for (p = eap->arg; *p; p++) {
if (*p == '\\' || *p == '"') {
@@ -5838,14 +5948,16 @@ uc_check_code(
}
break;
- case 2: /* Quote and split (<f-args>) */
- /* This is hard, so only do it once, and cache the result */
- if (*split_buf == NULL)
+ case 2: // Quote and split (<f-args>)
+ // This is hard, so only do it once, and cache the result
+ if (*split_buf == NULL) {
*split_buf = uc_split_args(eap->arg, split_len);
+ }
result = *split_len;
- if (buf != NULL && result != 0)
+ if (buf != NULL && result != 0) {
STRCPY(buf, *split_buf);
+ }
break;
}
@@ -5853,23 +5965,26 @@ uc_check_code(
case ct_BANG:
result = eap->forceit ? 1 : 0;
- if (quote)
+ if (quote) {
result += 2;
+ }
if (buf != NULL) {
- if (quote)
+ if (quote) {
*buf++ = '"';
- if (eap->forceit)
+ }
+ if (eap->forceit) {
*buf++ = '!';
- if (quote)
+ }
+ if (quote) {
*buf = '"';
+ }
}
break;
case ct_LINE1:
case ct_LINE2:
case ct_RANGE:
- case ct_COUNT:
- {
+ case ct_COUNT: {
char num_buf[20];
long num = (type == ct_LINE1) ? eap->line1 :
(type == ct_LINE2) ? eap->line2 :
@@ -5881,23 +5996,25 @@ uc_check_code(
num_len = STRLEN(num_buf);
result = num_len;
- if (quote)
+ if (quote) {
result += 2;
+ }
if (buf != NULL) {
- if (quote)
+ if (quote) {
*buf++ = '"';
+ }
STRCPY(buf, num_buf);
buf += num_len;
- if (quote)
+ if (quote) {
*buf = '"';
+ }
}
break;
}
- case ct_MODS:
- {
+ case ct_MODS: {
result = quote ? 2 : 0;
if (buf != NULL) {
if (quote) {
@@ -5979,29 +6096,35 @@ uc_check_code(
case ct_REGISTER:
result = eap->regname ? 1 : 0;
- if (quote)
+ if (quote) {
result += 2;
+ }
if (buf != NULL) {
- if (quote)
+ if (quote) {
*buf++ = '\'';
- if (eap->regname)
+ }
+ if (eap->regname) {
*buf++ = eap->regname;
- if (quote)
+ }
+ if (quote) {
*buf = '\'';
+ }
}
break;
case ct_LT:
result = 1;
- if (buf != NULL)
+ if (buf != NULL) {
*buf = '<';
+ }
break;
default:
- /* Not recognized: just copy the '<' and return -1. */
+ // Not recognized: just copy the '<' and return -1.
result = (size_t)-1;
- if (buf != NULL)
+ if (buf != NULL) {
*buf = '<';
+ }
break;
}
@@ -6010,24 +6133,25 @@ uc_check_code(
static void do_ucmd(exarg_T *eap)
{
- char_u *buf;
- char_u *p;
- char_u *q;
+ char_u *buf;
+ char_u *p;
+ char_u *q;
- char_u *start;
- char_u *end = NULL;
- char_u *ksp;
+ char_u *start;
+ char_u *end = NULL;
+ char_u *ksp;
size_t len, totlen;
size_t split_len = 0;
- char_u *split_buf = NULL;
- ucmd_T *cmd;
+ char_u *split_buf = NULL;
+ ucmd_T *cmd;
const sctx_T save_current_sctx = current_sctx;
- if (eap->cmdidx == CMD_USER)
+ if (eap->cmdidx == CMD_USER) {
cmd = USER_CMD(eap->useridx);
- else
+ } else {
cmd = USER_CMD_GA(&curbuf->b_ucmds, eap->useridx);
+ }
/*
* Replace <> in the command by the arguments.
@@ -6036,14 +6160,15 @@ static void do_ucmd(exarg_T *eap)
*/
buf = NULL;
for (;; ) {
- p = cmd->uc_rep; /* source */
- q = buf; /* destination */
+ p = cmd->uc_rep; // source
+ q = buf; // destination
totlen = 0;
for (;; ) {
start = vim_strchr(p, '<');
- if (start != NULL)
+ if (start != NULL) {
end = vim_strchr(start + 1, '>');
+ }
if (buf != NULL) {
for (ksp = p; *ksp != NUL && *ksp != K_SPECIAL; ksp++) {
}
@@ -6065,41 +6190,44 @@ static void do_ucmd(exarg_T *eap)
}
}
- /* break if there no <item> is found */
- if (start == NULL || end == NULL)
+ // break if there no <item> is found
+ if (start == NULL || end == NULL) {
break;
+ }
- /* Include the '>' */
+ // Include the '>'
++end;
- /* Take everything up to the '<' */
+ // Take everything up to the '<'
len = start - p;
- if (buf == NULL)
+ if (buf == NULL) {
totlen += len;
- else {
+ } else {
memmove(q, p, len);
q += len;
}
len = uc_check_code(start, end - start, q, cmd, eap,
- &split_buf, &split_len);
+ &split_buf, &split_len);
if (len == (size_t)-1) {
- /* no match, continue after '<' */
+ // no match, continue after '<'
p = start + 1;
len = 1;
- } else
+ } else {
p = end;
- if (buf == NULL)
+ }
+ if (buf == NULL) {
totlen += len;
- else
+ } else {
q += len;
+ }
}
- if (buf != NULL) { /* second time here, finished */
+ if (buf != NULL) { // second time here, finished
STRCPY(q, p);
break;
}
- totlen += STRLEN(p); /* Add on the trailing characters */
+ totlen += STRLEN(p); // Add on the trailing characters
buf = xmalloc(totlen + 1);
}
@@ -6113,7 +6241,7 @@ static void do_ucmd(exarg_T *eap)
static char_u *get_user_command_name(int idx)
{
- return get_user_commands(NULL, idx - (int)CMD_SIZE);
+ return get_user_commands(NULL, idx - CMD_SIZE);
}
/*
* Function given to ExpandGeneric() to obtain the list of user address type names.
@@ -6150,12 +6278,13 @@ char_u *get_user_commands(expand_T *xp FUNC_ATTR_UNUSED, int idx)
*/
char_u *get_user_cmd_flags(expand_T *xp, int idx)
{
- static char *user_cmd_flags[] = {"addr", "bang", "bar",
- "buffer", "complete", "count",
- "nargs", "range", "register"};
+ static char *user_cmd_flags[] = { "addr", "bang", "bar",
+ "buffer", "complete", "count",
+ "nargs", "range", "register" };
- if (idx >= (int)ARRAY_SIZE(user_cmd_flags))
+ if (idx >= (int)ARRAY_SIZE(user_cmd_flags)) {
return NULL;
+ }
return (char_u *)user_cmd_flags[idx];
}
@@ -6164,10 +6293,11 @@ char_u *get_user_cmd_flags(expand_T *xp, int idx)
*/
char_u *get_user_cmd_nargs(expand_T *xp, int idx)
{
- static char *user_cmd_nargs[] = {"0", "1", "*", "?", "+"};
+ static char *user_cmd_nargs[] = { "0", "1", "*", "?", "+" };
- if (idx >= (int)ARRAY_SIZE(user_cmd_nargs))
+ if (idx >= (int)ARRAY_SIZE(user_cmd_nargs)) {
return NULL;
+ }
return (char_u *)user_cmd_nargs[idx];
}
@@ -6223,8 +6353,8 @@ int parse_addr_type_arg(char_u *value, int vallen, cmd_addr_T *addr_type_arg)
* copied to allocated memory and stored in "*compl_arg".
* Returns FAIL if something is wrong.
*/
-int parse_compl_arg(const char_u *value, int vallen, int *complp,
- uint32_t *argt, char_u **compl_arg)
+int parse_compl_arg(const char_u *value, int vallen, int *complp, uint32_t *argt,
+ char_u **compl_arg)
FUNC_ATTR_NONNULL_ALL
{
const char_u *arg = NULL;
@@ -6232,7 +6362,7 @@ int parse_compl_arg(const char_u *value, int vallen, int *complp,
int i;
int valend = vallen;
- /* Look for any argument part - which is the part after any ',' */
+ // Look for any argument part - which is the part after any ','
for (i = 0; i < vallen; ++i) {
if (value[i] == ',') {
arg = &value[i + 1];
@@ -6283,17 +6413,17 @@ int parse_compl_arg(const char_u *value, int vallen, int *complp,
int cmdcomplete_str_to_type(const char *complete_str)
{
- for (int i = 0; i < (int)(ARRAY_SIZE(command_complete)); i++) {
- char *cmd_compl = get_command_complete(i);
- if (cmd_compl == NULL) {
- continue;
- }
- if (strcmp(complete_str, command_complete[i]) == 0) {
- return i;
- }
+ for (int i = 0; i < (int)(ARRAY_SIZE(command_complete)); i++) {
+ char *cmd_compl = get_command_complete(i);
+ if (cmd_compl == NULL) {
+ continue;
+ }
+ if (strcmp(complete_str, command_complete[i]) == 0) {
+ return i;
}
+ }
- return EXPAND_NOTHING;
+ return EXPAND_NOTHING;
}
static void ex_colorscheme(exarg_T *eap)
@@ -6302,18 +6432,20 @@ static void ex_colorscheme(exarg_T *eap)
char_u *expr = vim_strsave((char_u *)"g:colors_name");
char_u *p = NULL;
- ++emsg_off;
- p = eval_to_string(expr, NULL, FALSE);
- --emsg_off;
+ emsg_off++;
+ p = eval_to_string(expr, NULL, false);
+ emsg_off--;
xfree(expr);
if (p != NULL) {
MSG(p);
xfree(p);
- } else
+ } else {
MSG("default");
- } else if (load_colors(eap->arg) == FAIL)
+ }
+ } else if (load_colors(eap->arg) == FAIL) {
EMSG2(_("E185: Cannot find color scheme '%s'"), eap->arg);
+ }
}
static void ex_highlight(exarg_T *eap)
@@ -6371,7 +6503,7 @@ static void ex_quit(exarg_T *eap)
cmdwin_result = Ctrl_C;
return;
}
- /* Don't quit while editing the command line. */
+ // Don't quit while editing the command line.
if (text_locked()) {
text_locked_msg();
return;
@@ -6383,8 +6515,9 @@ static void ex_quit(exarg_T *eap)
int wnr = eap->line2;
for (wp = firstwin; wp->w_next != NULL; wp = wp->w_next) {
- if (--wnr <= 0)
+ if (--wnr <= 0) {
break;
+ }
}
} else {
wp = curwin;
@@ -6446,7 +6579,7 @@ static void ex_quit_all(exarg_T *eap)
return;
}
- /* Don't quit while editing the command line. */
+ // Don't quit while editing the command line.
if (text_locked()) {
text_locked_msg();
return;
@@ -6483,8 +6616,9 @@ static void ex_close(exarg_T *eap)
break;
}
}
- if (win == NULL)
+ if (win == NULL) {
win = lastwin;
+ }
ex_win_close(eap->forceit, win, NULL);
}
}
@@ -6503,19 +6637,14 @@ static void ex_pclose(exarg_T *eap)
}
}
-/*
- * Close window "win" and take care of handling closing the last window for a
- * modified buffer.
- */
-void
-ex_win_close(
- int forceit,
- win_T *win,
- tabpage_T *tp /* NULL or the tab page "win" is in */
-)
+/// Close window "win" and take care of handling closing the last window for a
+/// modified buffer.
+///
+/// @param tp NULL or the tab page "win" is in
+void ex_win_close(int forceit, win_T *win, tabpage_T *tp)
{
int need_hide;
- buf_T *buf = win->w_buffer;
+ buf_T *buf = win->w_buffer;
// Never close the autocommand window.
if (win == aucmd_win) {
@@ -6554,13 +6683,13 @@ ex_win_close(
*/
static void ex_tabclose(exarg_T *eap)
{
- tabpage_T *tp;
+ tabpage_T *tp;
- if (cmdwin_type != 0)
+ if (cmdwin_type != 0) {
cmdwin_result = K_IGNORE;
- else if (first_tabpage->tp_next == NULL)
+ } else if (first_tabpage->tp_next == NULL) {
EMSG(_("E784: Cannot close last tab page"));
- else {
+ } else {
int tab_number = get_tabpage_arg(eap);
if (eap->errmsg == NULL) {
tp = find_tabpage(tab_number);
@@ -6584,7 +6713,7 @@ static void ex_tabonly(exarg_T *eap)
if (cmdwin_type != 0) {
cmdwin_result = K_IGNORE;
} else if (first_tabpage->tp_next == NULL) {
- MSG(_("Already only one tab page"));
+ MSG(_("Already only one tab page"));
} else {
int tab_number = get_tabpage_arg(eap);
if (eap->errmsg == NULL) {
@@ -6639,7 +6768,7 @@ void tabpage_close(int forceit)
void tabpage_close_other(tabpage_T *tp, int forceit)
{
int done = 0;
- win_T *wp;
+ win_T *wp;
int h = tabline_height();
char_u prev_idx[NUMBUFLEN];
@@ -6652,13 +6781,15 @@ void tabpage_close_other(tabpage_T *tp, int forceit)
/* Autocommands may delete the tab page under our fingers and we may
* fail to close a window with a modified buffer. */
- if (!valid_tabpage(tp) || tp->tp_firstwin == wp)
+ if (!valid_tabpage(tp) || tp->tp_firstwin == wp) {
break;
+ }
}
- redraw_tabline = TRUE;
- if (h != tabline_height())
+ redraw_tabline = true;
+ if (h != tabline_height()) {
shell_new_rows();
+ }
}
/*
@@ -6672,10 +6803,11 @@ static void ex_only(exarg_T *eap)
if (eap->addr_count > 0) {
wnr = eap->line2;
for (wp = firstwin; --wnr > 0;) {
- if (wp->w_next == NULL)
+ if (wp->w_next == NULL) {
break;
- else
+ } else {
wp = wp->w_next;
+ }
}
} else {
wp = curwin;
@@ -6692,34 +6824,35 @@ static void ex_only(exarg_T *eap)
*/
void ex_all(exarg_T *eap)
{
- if (eap->addr_count == 0)
+ if (eap->addr_count == 0) {
eap->line2 = 9999;
+ }
do_arg_all((int)eap->line2, eap->forceit, eap->cmdidx == CMD_drop);
}
static void ex_hide(exarg_T *eap)
{
- // ":hide" or ":hide | cmd": hide current window
- if (!eap->skip) {
- if (eap->addr_count == 0) {
- win_close(curwin, false); // don't free buffer
- } else {
- int winnr = 0;
- win_T *win = NULL;
-
- FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
- winnr++;
- if (winnr == eap->line2) {
- win = wp;
- break;
- }
- }
- if (win == NULL) {
- win = lastwin;
- }
- win_close(win, false);
+ // ":hide" or ":hide | cmd": hide current window
+ if (!eap->skip) {
+ if (eap->addr_count == 0) {
+ win_close(curwin, false); // don't free buffer
+ } else {
+ int winnr = 0;
+ win_T *win = NULL;
+
+ FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
+ winnr++;
+ if (winnr == eap->line2) {
+ win = wp;
+ break;
}
+ }
+ if (win == NULL) {
+ win = lastwin;
+ }
+ win_close(win, false);
}
+ }
}
/// ":stop" and ":suspend": Suspend Vim.
@@ -6750,7 +6883,7 @@ static void ex_exit(exarg_T *eap)
cmdwin_result = Ctrl_C;
return;
}
- /* Don't quit while editing the command line. */
+ // Don't quit while editing the command line.
if (text_locked()) {
text_locked_msg();
return;
@@ -6784,25 +6917,26 @@ static void ex_exit(exarg_T *eap)
*/
static void ex_print(exarg_T *eap)
{
- if (curbuf->b_ml.ml_flags & ML_EMPTY)
+ if (curbuf->b_ml.ml_flags & ML_EMPTY) {
EMSG(_(e_emptybuf));
- else {
+ } else {
for (; !got_int; os_breakcheck()) {
print_line(eap->line1,
- (eap->cmdidx == CMD_number || eap->cmdidx == CMD_pound
- || (eap->flags & EXFLAG_NR)),
- eap->cmdidx == CMD_list || (eap->flags & EXFLAG_LIST));
- if (++eap->line1 > eap->line2)
+ (eap->cmdidx == CMD_number || eap->cmdidx == CMD_pound
+ || (eap->flags & EXFLAG_NR)),
+ eap->cmdidx == CMD_list || (eap->flags & EXFLAG_LIST));
+ if (++eap->line1 > eap->line2) {
break;
- ui_flush(); /* show one line at a time */
+ }
+ ui_flush(); // show one line at a time
}
setpcmark();
- /* put cursor at last line */
+ // put cursor at last line
curwin->w_cursor.lnum = eap->line2;
beginline(BL_SOL | BL_FIX);
}
- ex_no_reprint = TRUE;
+ ex_no_reprint = true;
}
static void ex_goto(exarg_T *eap)
@@ -6815,7 +6949,7 @@ static void ex_goto(exarg_T *eap)
*/
void alist_clear(alist_T *al)
{
-# define FREE_AENTRY_FNAME(arg) xfree(arg->ae_fname)
+#define FREE_AENTRY_FNAME(arg) xfree(arg->ae_fname)
GA_DEEP_CLEAR(&al->al_ga, aentry_T, FREE_AENTRY_FNAME);
}
@@ -6860,11 +6994,11 @@ void alist_new(void)
*/
void alist_expand(int *fnum_list, int fnum_len)
{
- char_u **old_arg_files;
+ char_u **old_arg_files;
int old_arg_count;
- char_u **new_arg_files;
+ char_u **new_arg_files;
int new_arg_file_count;
- char_u *save_p_su = p_su;
+ char_u *save_p_su = p_su;
int i;
/* Don't use 'suffixes' here. This should work like the shell did the
@@ -6872,15 +7006,16 @@ void alist_expand(int *fnum_list, int fnum_len)
* can't set the options. */
p_su = empty_option;
old_arg_files = xmalloc(sizeof(*old_arg_files) * GARGCOUNT);
- for (i = 0; i < GARGCOUNT; ++i)
+ for (i = 0; i < GARGCOUNT; ++i) {
old_arg_files[i] = vim_strsave(GARGLIST[i].ae_fname);
+ }
old_arg_count = GARGCOUNT;
if (expand_wildcards(old_arg_count, old_arg_files,
- &new_arg_file_count, &new_arg_files,
- EW_FILE|EW_NOTFOUND|EW_ADDSLASH|EW_NOERROR) == OK
+ &new_arg_file_count, &new_arg_files,
+ EW_FILE|EW_NOTFOUND|EW_ADDSLASH|EW_NOERROR) == OK
&& new_arg_file_count > 0) {
alist_set(&global_alist, new_arg_file_count, new_arg_files,
- TRUE, fnum_list, fnum_len);
+ TRUE, fnum_list, fnum_len);
FreeWild(old_arg_count, old_arg_files);
}
p_su = save_p_su;
@@ -6909,15 +7044,17 @@ void alist_set(alist_T *al, int count, char_u **files, int use_curbuf, int *fnum
if (got_int) {
/* When adding many buffers this can take a long time. Allow
* interrupting here. */
- while (i < count)
+ while (i < count) {
xfree(files[i++]);
+ }
break;
}
/* May set buffer name of a buffer previously used for the
* argument list, so that it's re-used by alist_add. */
- if (fnum_list != NULL && i < fnum_len)
+ if (fnum_list != NULL && i < fnum_len) {
buf_set_name(fnum_list[i], files[i]);
+ }
alist_add(al, files[i], use_curbuf ? 2 : 1);
os_breakcheck();
@@ -6931,26 +7068,23 @@ void alist_set(alist_T *al, int count, char_u **files, int use_curbuf, int *fnum
recursive--;
}
-/*
- * Add file "fname" to argument list "al".
- * "fname" must have been allocated and "al" must have been checked for room.
- */
-void
-alist_add(
- alist_T *al,
- char_u *fname,
- int set_fnum /* 1: set buffer number; 2: re-use curbuf */
-)
-{
- if (fname == NULL) /* don't add NULL file names */
+/// Add file "fname" to argument list "al".
+/// "fname" must have been allocated and "al" must have been checked for room.
+///
+/// @param set_fnum 1: set buffer number; 2: re-use curbuf
+void alist_add(alist_T *al, char_u *fname, int set_fnum)
+{
+ if (fname == NULL) { // don't add NULL file names
return;
+ }
#ifdef BACKSLASH_IN_FILENAME
slash_adjust(fname);
#endif
AARGLIST(al)[al->al_ga.ga_len].ae_fname = fname;
- if (set_fnum > 0)
+ if (set_fnum > 0) {
AARGLIST(al)[al->al_ga.ga_len].ae_fnum =
buflist_add(fname, BLN_LISTED | (set_fnum == 2 ? BLN_CURBUF : 0));
+ }
++al->al_ga.ga_len;
}
@@ -6992,9 +7126,9 @@ static void ex_recover(exarg_T *eap)
// Set recoverymode right away to avoid the ATTENTION prompt.
recoverymode = true;
if (!check_changed(curbuf, (p_awa ? CCGD_AW : 0)
- | CCGD_MULTWIN
- | (eap->forceit ? CCGD_FORCEIT : 0)
- | CCGD_EXCMD)
+ | CCGD_MULTWIN
+ | (eap->forceit ? CCGD_FORCEIT : 0)
+ | CCGD_EXCMD)
&& (*eap->arg == NUL
|| setfname(curbuf, eap->arg, NULL, true) == OK)) {
@@ -7012,40 +7146,43 @@ static void ex_wrongmodifier(exarg_T *eap)
}
/*
- * :sview [+command] file split window with new file, read-only
- * :split [[+command] file] split window with current or new file
- * :vsplit [[+command] file] split window vertically with current or new file
- * :new [[+command] file] split window with no or new file
- * :vnew [[+command] file] split vertically window with no or new file
- * :sfind [+command] file split window with file in 'path'
+ * :sview [+command] file split window with new file, read-only
+ * :split [[+command] file] split window with current or new file
+ * :vsplit [[+command] file] split window vertically with current or new file
+ * :new [[+command] file] split window with no or new file
+ * :vnew [[+command] file] split vertically window with no or new file
+ * :sfind [+command] file split window with file in 'path'
*
- * :tabedit open new Tab page with empty window
- * :tabedit [+command] file open new Tab page and edit "file"
- * :tabnew [[+command] file] just like :tabedit
- * :tabfind [+command] file open new Tab page and find "file"
+ * :tabedit open new Tab page with empty window
+ * :tabedit [+command] file open new Tab page and edit "file"
+ * :tabnew [[+command] file] just like :tabedit
+ * :tabfind [+command] file open new Tab page and find "file"
*/
void ex_splitview(exarg_T *eap)
{
- win_T *old_curwin = curwin;
- char_u *fname = NULL;
+ win_T *old_curwin = curwin;
+ char_u *fname = NULL;
const bool use_tab = eap->cmdidx == CMD_tabedit
- || eap->cmdidx == CMD_tabfind
- || eap->cmdidx == CMD_tabnew;
+ || eap->cmdidx == CMD_tabfind
+ || eap->cmdidx == CMD_tabnew;
/* A ":split" in the quickfix window works like ":new". Don't want two
* quickfix windows. But it's OK when doing ":tab split". */
if (bt_quickfix(curbuf) && cmdmod.tab == 0) {
- if (eap->cmdidx == CMD_split)
+ if (eap->cmdidx == CMD_split) {
eap->cmdidx = CMD_new;
- if (eap->cmdidx == CMD_vsplit)
+ }
+ if (eap->cmdidx == CMD_vsplit) {
eap->cmdidx = CMD_vnew;
+ }
}
if (eap->cmdidx == CMD_sfind || eap->cmdidx == CMD_tabfind) {
fname = find_file_in_path(eap->arg, STRLEN(eap->arg),
FNAME_MESS, TRUE, curbuf->b_ffname);
- if (fname == NULL)
+ if (fname == NULL) {
goto theend;
+ }
eap->arg = fname;
}
@@ -7056,17 +7193,18 @@ void ex_splitview(exarg_T *eap)
if (win_new_tabpage(cmdmod.tab != 0 ? cmdmod.tab : eap->addr_count == 0
? 0 : (int)eap->line2 + 1, eap->arg) != FAIL) {
do_exedit(eap, old_curwin);
- apply_autocmds(EVENT_TABNEWENTERED, NULL, NULL, FALSE, curbuf);
+ apply_autocmds(EVENT_TABNEWENTERED, NULL, NULL, false, curbuf);
- /* set the alternate buffer for the window we came from */
+ // set the alternate buffer for the window we came from
if (curwin != old_curwin
&& win_valid(old_curwin)
&& old_curwin->w_buffer != curbuf
- && !cmdmod.keepalt)
+ && !cmdmod.keepalt) {
old_curwin->w_alt_fnum = curbuf->b_fnum;
+ }
}
} else if (win_split(eap->addr_count > 0 ? (int)eap->line2 : 0,
- *eap->cmd == 'v' ? WSP_VERT : 0) != FAIL) {
+ *eap->cmd == 'v' ? WSP_VERT : 0) != FAIL) {
/* Reset 'scrollbind' when editing another file, but keep it when
* doing ":split" without arguments. */
if (*eap->arg != NUL
@@ -7173,7 +7311,7 @@ static void ex_tabs(exarg_T *eap)
FOR_ALL_TABS(tp) {
if (got_int) {
- break;
+ break;
}
msg_putchar('\n');
@@ -7192,13 +7330,13 @@ static void ex_tabs(exarg_T *eap)
msg_putchar(' ');
msg_putchar(bufIsChanged(wp->w_buffer) ? '+' : ' ');
msg_putchar(' ');
- if (buf_spname(wp->w_buffer) != NULL)
+ if (buf_spname(wp->w_buffer) != NULL) {
STRLCPY(IObuff, buf_spname(wp->w_buffer), IOSIZE);
- else
- home_replace(wp->w_buffer, wp->w_buffer->b_fname,
- IObuff, IOSIZE, TRUE);
+ } else {
+ home_replace(wp->w_buffer, wp->w_buffer->b_fname, IObuff, IOSIZE, true);
+ }
msg_outtrans(IObuff);
- ui_flush(); /* output one line at a time */
+ ui_flush(); // output one line at a time
os_breakcheck();
}
}
@@ -7226,12 +7364,13 @@ static void ex_mode(exarg_T *eap)
static void ex_resize(exarg_T *eap)
{
int n;
- win_T *wp = curwin;
+ win_T *wp = curwin;
if (eap->addr_count > 0) {
n = eap->line2;
- for (wp = firstwin; wp->w_next != NULL && --n > 0; wp = wp->w_next)
+ for (wp = firstwin; wp->w_next != NULL && --n > 0; wp = wp->w_next) {
;
+ }
}
n = atol((char *)eap->arg);
@@ -7257,7 +7396,7 @@ static void ex_resize(exarg_T *eap)
*/
static void ex_find(exarg_T *eap)
{
- char_u *fname;
+ char_u *fname;
int count;
fname = find_file_in_path(eap->arg, STRLEN(eap->arg),
@@ -7285,14 +7424,10 @@ static void ex_edit(exarg_T *eap)
do_exedit(eap, NULL);
}
-/*
- * ":edit <file>" command and alikes.
- */
-void
-do_exedit(
- exarg_T *eap,
- win_T *old_curwin /* curwin before doing a split or NULL */
-)
+/// ":edit <file>" command and alikes.
+///
+/// @param old_curwin curwin before doing a split or NULL
+void do_exedit(exarg_T *eap, win_T *old_curwin)
{
int n;
int need_hide;
@@ -7302,10 +7437,10 @@ do_exedit(
*/
if (exmode_active && (eap->cmdidx == CMD_visual
|| eap->cmdidx == CMD_view)) {
- exmode_active = 0;
+ exmode_active = false;
ex_pressedreturn = false;
if (*eap->arg == NUL) {
- /* Special case: ":global/pat/visual\NLvi-commands" */
+ // Special case: ":global/pat/visual\NLvi-commands"
if (global_busy) {
int rd = RedrawingDisabled;
int nwr = no_wait_return;
@@ -7318,7 +7453,7 @@ do_exedit(
RedrawingDisabled = 0;
no_wait_return = 0;
- need_wait_return = FALSE;
+ need_wait_return = false;
msg_scroll = 0;
redraw_all_later(NOT_VALID);
@@ -7337,23 +7472,25 @@ do_exedit(
|| eap->cmdidx == CMD_tabedit
|| eap->cmdidx == CMD_vnew
) && *eap->arg == NUL) {
- /* ":new" or ":tabnew" without argument: edit an new empty buffer */
+ // ":new" or ":tabnew" without argument: edit an new empty buffer
setpcmark();
(void)do_ecmd(0, NULL, NULL, eap, ECMD_ONE,
- ECMD_HIDE + (eap->forceit ? ECMD_FORCEIT : 0),
- old_curwin == NULL ? curwin : NULL);
+ ECMD_HIDE + (eap->forceit ? ECMD_FORCEIT : 0),
+ old_curwin == NULL ? curwin : NULL);
} else if ((eap->cmdidx != CMD_split && eap->cmdidx != CMD_vsplit)
|| *eap->arg != NUL) {
- /* Can't edit another file when "curbuf_lock" is set. Only ":edit"
- * can bring us here, others are stopped earlier. */
- if (*eap->arg != NUL && curbuf_locked())
+ // Can't edit another file when "curbuf->b_ro_lockec" is set. Only ":edit"
+ // can bring us here, others are stopped earlier.
+ if (*eap->arg != NUL && curbuf_locked()) {
return;
+ }
n = readonlymode;
- if (eap->cmdidx == CMD_view || eap->cmdidx == CMD_sview)
- readonlymode = TRUE;
- else if (eap->cmdidx == CMD_enew)
- readonlymode = FALSE; /* 'readonly' doesn't make sense in an
- empty buffer */
+ if (eap->cmdidx == CMD_view || eap->cmdidx == CMD_sview) {
+ readonlymode = true;
+ } else if (eap->cmdidx == CMD_enew) {
+ readonlymode = false; // 'readonly' doesn't make sense
+ // in an empty buffer
+ }
if (eap->cmdidx != CMD_balt && eap->cmdidx != CMD_badd) {
setpcmark();
}
@@ -7392,12 +7529,14 @@ do_exedit(
}
readonlymode = n;
} else {
- if (eap->do_ecmd_cmd != NULL)
+ if (eap->do_ecmd_cmd != NULL) {
do_cmdline_cmd((char *)eap->do_ecmd_cmd);
+ }
n = curwin->w_arg_idx_invalid;
check_arg_idx(curwin);
- if (n != curwin->w_arg_idx_invalid)
+ if (n != curwin->w_arg_idx_invalid) {
maketitle();
+ }
}
/*
@@ -7409,10 +7548,11 @@ do_exedit(
&& curwin != old_curwin
&& win_valid(old_curwin)
&& old_curwin->w_buffer != curbuf
- && !cmdmod.keepalt)
+ && !cmdmod.keepalt) {
old_curwin->w_alt_fnum = curbuf->b_fnum;
+ }
- ex_no_reprint = TRUE;
+ ex_no_reprint = true;
}
/// ":gui" and ":gvim" when there is no GUI.
@@ -7425,10 +7565,11 @@ static void ex_nogui(exarg_T *eap)
static void ex_swapname(exarg_T *eap)
{
- if (curbuf->b_ml.ml_mfp == NULL || curbuf->b_ml.ml_mfp->mf_fname == NULL)
+ if (curbuf->b_ml.ml_mfp == NULL || curbuf->b_ml.ml_mfp->mf_fname == NULL) {
MSG(_("No swap file"));
- else
+ } else {
msg(curbuf->b_ml.ml_mfp->mf_fname);
+ }
}
/*
@@ -7438,8 +7579,8 @@ static void ex_swapname(exarg_T *eap)
*/
static void ex_syncbind(exarg_T *eap)
{
- win_T *save_curwin = curwin;
- buf_T *save_curbuf = curbuf;
+ win_T *save_curwin = curwin;
+ buf_T *save_curbuf = curbuf;
long topline;
long y;
linenr_T old_linenr = curwin->w_cursor.lnum;
@@ -7475,10 +7616,11 @@ static void ex_syncbind(exarg_T *eap)
if (curwin->w_p_scb) {
curbuf = curwin->w_buffer;
y = topline - curwin->w_topline;
- if (y > 0)
+ if (y > 0) {
scrollup(y, TRUE);
- else
+ } else {
scrolldown(-y, TRUE);
+ }
curwin->w_scbind_pos = topline;
redraw_later(curwin, VALID);
cursor_correct();
@@ -7488,7 +7630,7 @@ static void ex_syncbind(exarg_T *eap)
curwin = save_curwin;
curbuf = save_curbuf;
if (curwin->w_p_scb) {
- did_syncbind = TRUE;
+ did_syncbind = true;
checkpcmark();
if (old_linenr != curwin->w_cursor.lnum) {
char_u ctrl_o[2];
@@ -7519,13 +7661,13 @@ static void ex_read(exarg_T *eap)
return;
}
i = readfile(curbuf->b_ffname, curbuf->b_fname,
- eap->line2, (linenr_T)0, (linenr_T)MAXLNUM, eap, 0);
+ eap->line2, (linenr_T)0, (linenr_T)MAXLNUM, eap, 0);
} else {
- if (vim_strchr(p_cpo, CPO_ALTREAD) != NULL)
+ if (vim_strchr(p_cpo, CPO_ALTREAD) != NULL) {
(void)setaltfname(eap->arg, eap->arg, (linenr_T)1);
+ }
i = readfile(eap->arg, NULL,
- eap->line2, (linenr_T)0, (linenr_T)MAXLNUM, eap, 0);
-
+ eap->line2, (linenr_T)0, (linenr_T)MAXLNUM, eap, 0);
}
if (i != OK) {
if (!aborting()) {
@@ -7535,10 +7677,11 @@ static void ex_read(exarg_T *eap)
if (empty && exmode_active) {
/* Delete the empty line that remains. Historically ex does
* this but vi doesn't. */
- if (eap->line2 == 0)
+ if (eap->line2 == 0) {
lnum = curbuf->b_ml.ml_line_count;
- else
+ } else {
lnum = 1;
+ }
if (*ml_get(lnum) == NUL && u_savedel(lnum, 1L) == OK) {
ml_delete(lnum, false);
if (curwin->w_cursor.lnum > 1
@@ -7553,7 +7696,7 @@ static void ex_read(exarg_T *eap)
}
}
-static char_u *prev_dir = NULL;
+static char_u *prev_dir = NULL;
#if defined(EXITFREE)
void free_cd_dir(void)
@@ -7613,21 +7756,22 @@ void post_chdir(CdScope scope, bool trigger_dirchanged)
/// `:cd`, `:tcd`, `:lcd`, `:chdir`, `:tchdir` and `:lchdir`.
void ex_cd(exarg_T *eap)
{
- char_u *new_dir;
- char_u *tofree;
+ char_u *new_dir;
+ char_u *tofree;
new_dir = eap->arg;
#if !defined(UNIX)
- /* for non-UNIX ":cd" means: print current directory */
- if (*new_dir == NUL)
+ // for non-UNIX ":cd" means: print current directory
+ if (*new_dir == NUL) {
ex_pwd(NULL);
- else
+ } else
#endif
{
- if (allbuf_locked())
+ if (allbuf_locked()) {
return;
+ }
- /* ":cd -": Change to previous directory */
+ // ":cd -": Change to previous directory
if (STRCMP(new_dir, "-") == 0) {
if (prev_dir == NULL) {
EMSG(_("E186: No previous directory"));
@@ -7636,12 +7780,13 @@ void ex_cd(exarg_T *eap)
new_dir = prev_dir;
}
- /* Save current directory for next ":cd -" */
+ // Save current directory for next ":cd -"
tofree = prev_dir;
- if (os_dirname(NameBuff, MAXPATHL) == OK)
+ if (os_dirname(NameBuff, MAXPATHL) == OK) {
prev_dir = vim_strsave(NameBuff);
- else
+ } else {
prev_dir = NULL;
+ }
#if defined(UNIX)
// On Unix ":cd" means: go to home directory.
@@ -7690,8 +7835,9 @@ static void ex_pwd(exarg_T *eap)
slash_adjust(NameBuff);
#endif
msg(NameBuff);
- } else
+ } else {
EMSG(_("E187: Unknown"));
+ }
}
/*
@@ -7710,15 +7856,19 @@ static void ex_sleep(exarg_T *eap)
if (cursor_valid()) {
n = curwin->w_winrow + curwin->w_wrow - msg_scrolled;
- if (n >= 0)
+ if (n >= 0) {
ui_cursor_goto(n, curwin->w_wincol + curwin->w_wcol);
+ }
}
len = eap->line2;
switch (*eap->arg) {
- case 'm': break;
- case NUL: len *= 1000L; break;
- default: EMSG2(_(e_invarg2), eap->arg); return;
+ case 'm':
+ break;
+ case NUL:
+ len *= 1000L; break;
+ default:
+ EMSG2(_(e_invarg2), eap->arg); return;
}
do_sleep(len);
}
@@ -7745,16 +7895,18 @@ void do_sleep(long msec)
static void do_exmap(exarg_T *eap, int isabbrev)
{
int mode;
- char_u *cmdp;
+ char_u *cmdp;
cmdp = eap->cmd;
mode = get_map_mode(&cmdp, eap->forceit || isabbrev);
switch (do_map((*cmdp == 'n') ? 2 : (*cmdp == 'u'),
- eap->arg, mode, isabbrev)) {
- case 1: EMSG(_(e_invarg));
+ eap->arg, mode, isabbrev)) {
+ case 1:
+ EMSG(_(e_invarg));
break;
- case 2: EMSG(isabbrev ? _(e_noabbr) : _(e_nomap));
+ case 2:
+ EMSG(isabbrev ? _(e_noabbr) : _(e_nomap));
break;
}
}
@@ -7784,25 +7936,26 @@ static void ex_winsize(exarg_T *eap)
static void ex_wincmd(exarg_T *eap)
{
int xchar = NUL;
- char_u *p;
+ char_u *p;
if (*eap->arg == 'g' || *eap->arg == Ctrl_G) {
- /* CTRL-W g and CTRL-W CTRL-G have an extra command character */
+ // CTRL-W g and CTRL-W CTRL-G have an extra command character
if (eap->arg[1] == NUL) {
EMSG(_(e_invarg));
return;
}
xchar = eap->arg[1];
p = eap->arg + 2;
- } else
+ } else {
p = eap->arg + 1;
+ }
eap->nextcmd = check_nextcmd(p);
p = skipwhite(p);
- if (*p != NUL && *p != '"' && eap->nextcmd == NULL)
+ if (*p != NUL && *p != '"' && eap->nextcmd == NULL) {
EMSG(_(e_invarg));
- else if (!eap->skip) {
- /* Pass flags on for ":vertical wincmd ]". */
+ } else if (!eap->skip) {
+ // Pass flags on for ":vertical wincmd ]".
postponed_split_flags = cmdmod.split;
postponed_split_tab = cmdmod.tab;
do_window(*eap->arg, eap->addr_count > 0 ? eap->line2 : 0L, xchar);
@@ -7831,8 +7984,9 @@ static void ex_operators(exarg_T *eap)
beginline(BL_SOL | BL_FIX);
}
- if (VIsual_active)
+ if (VIsual_active) {
end_visual_mode();
+ }
switch (eap->cmdidx) {
case CMD_delete:
@@ -7845,13 +7999,14 @@ static void ex_operators(exarg_T *eap)
(void)op_yank(&oa, true, false);
break;
- default: /* CMD_rshift or CMD_lshift */
+ default: // CMD_rshift or CMD_lshift
if (
- (eap->cmdidx == CMD_rshift) ^ curwin->w_p_rl
- )
+ (eap->cmdidx == CMD_rshift) ^ curwin->w_p_rl
+ ) {
oa.op_type = OP_RSHIFT;
- else
+ } else {
oa.op_type = OP_LSHIFT;
+ }
op_shift(&oa, FALSE, eap->amount);
break;
}
@@ -7864,7 +8019,7 @@ static void ex_operators(exarg_T *eap)
*/
static void ex_put(exarg_T *eap)
{
- /* ":0put" works like ":1put!". */
+ // ":0put" works like ":1put!".
if (eap->line2 == 0) {
eap->line2 = 1;
eap->forceit = TRUE;
@@ -7895,10 +8050,12 @@ static void ex_copymove(exarg_T *eap)
}
if (eap->cmdidx == CMD_move) {
- if (do_move(eap->line1, eap->line2, n) == FAIL)
+ if (do_move(eap->line1, eap->line2, n) == FAIL) {
return;
- } else
+ }
+ } else {
ex_copy(eap->line1, eap->line2, n);
+ }
u_clearline();
beginline(BL_SOL | BL_FIX);
ex_may_print(eap);
@@ -7911,8 +8068,8 @@ void ex_may_print(exarg_T *eap)
{
if (eap->flags != 0) {
print_line(curwin->w_cursor.lnum, (eap->flags & EXFLAG_NR),
- (eap->flags & EXFLAG_LIST));
- ex_no_reprint = TRUE;
+ (eap->flags & EXFLAG_LIST));
+ ex_no_reprint = true;
}
}
@@ -7933,8 +8090,9 @@ static void ex_join(exarg_T *eap)
{
curwin->w_cursor.lnum = eap->line1;
if (eap->line1 == eap->line2) {
- if (eap->addr_count >= 2) /* :2,2join does nothing */
+ if (eap->addr_count >= 2) { // :2,2join does nothing
return;
+ }
if (eap->line2 == curbuf->b_ml.ml_line_count) {
beep_flush();
return;
@@ -7962,22 +8120,23 @@ static void ex_at(exarg_T *eap)
c = '@';
}
- /* Put the register in the typeahead buffer with the "silent" flag. */
+ // Put the register in the typeahead buffer with the "silent" flag.
if (do_execreg(c, TRUE, vim_strchr(p_cpo, CPO_EXECBUF) != NULL, TRUE)
== FAIL) {
beep_flush();
} else {
- int save_efr = exec_from_reg;
+ bool save_efr = exec_from_reg;
- exec_from_reg = TRUE;
+ exec_from_reg = true;
/*
* Execute from the typeahead buffer.
* Continue until the stuff buffer is empty and all added characters
* have been consumed.
*/
- while (!stuff_empty() || typebuf.tb_len > prev_len)
+ while (!stuff_empty() || typebuf.tb_len > prev_len) {
(void)do_cmdline(NULL, getexline, NULL, DOCMD_NOWAIT|DOCMD_VERBOSE);
+ }
exec_from_reg = save_efr;
}
@@ -8007,16 +8166,16 @@ static void ex_wundo(exarg_T *eap)
{
char_u hash[UNDO_HASH_SIZE];
- u_compute_hash(hash);
- u_write_undo((char *) eap->arg, eap->forceit, curbuf, hash);
+ u_compute_hash(curbuf, hash);
+ u_write_undo((char *)eap->arg, eap->forceit, curbuf, hash);
}
static void ex_rundo(exarg_T *eap)
{
char_u hash[UNDO_HASH_SIZE];
- u_compute_hash(hash);
- u_read_undo((char *) eap->arg, hash, NULL);
+ u_compute_hash(curbuf, hash);
+ u_read_undo((char *)eap->arg, hash, NULL);
}
/// ":redo".
@@ -8031,18 +8190,23 @@ static void ex_later(exarg_T *eap)
long count = 0;
bool sec = false;
bool file = false;
- char_u *p = eap->arg;
+ char_u *p = eap->arg;
if (*p == NUL) {
count = 1;
} else if (isdigit(*p)) {
count = getdigits_long(&p, false, 0);
switch (*p) {
- case 's': ++p; sec = true; break;
- case 'm': ++p; sec = true; count *= 60; break;
- case 'h': ++p; sec = true; count *= 60 * 60; break;
- case 'd': ++p; sec = true; count *= 24 * 60 * 60; break;
- case 'f': ++p; file = true; break;
+ case 's':
+ ++p; sec = true; break;
+ case 'm':
+ ++p; sec = true; count *= 60; break;
+ case 'h':
+ ++p; sec = true; count *= 60 * 60; break;
+ case 'd':
+ ++p; sec = true; count *= 24 * 60 * 60; break;
+ case 'f':
+ ++p; file = true; break;
}
}
@@ -8059,43 +8223,46 @@ static void ex_later(exarg_T *eap)
*/
static void ex_redir(exarg_T *eap)
{
- char *mode;
- char_u *fname;
- char_u *arg = eap->arg;
+ char *mode;
+ char_u *fname;
+ char_u *arg = eap->arg;
- if (STRICMP(eap->arg, "END") == 0)
+ if (STRICMP(eap->arg, "END") == 0) {
close_redir();
- else {
+ } else {
if (*arg == '>') {
++arg;
if (*arg == '>') {
++arg;
mode = "a";
- } else
+ } else {
mode = "w";
+ }
arg = skipwhite(arg);
close_redir();
- /* Expand environment variables and "~/". */
+ // Expand environment variables and "~/".
fname = expand_env_save(arg);
- if (fname == NULL)
+ if (fname == NULL) {
return;
+ }
redir_fd = open_exfile(fname, eap->forceit, mode);
xfree(fname);
} else if (*arg == '@') {
- /* redirect to a register a-z (resp. A-Z for appending) */
+ // redirect to a register a-z (resp. A-Z for appending)
close_redir();
++arg;
if (valid_yank_reg(*arg, true) && *arg != '_') {
redir_reg = *arg++;
- if (*arg == '>' && arg[1] == '>') /* append */
+ if (*arg == '>' && arg[1] == '>') { // append
arg += 2;
- else {
- /* Can use both "@a" and "@a>". */
- if (*arg == '>')
+ } else {
+ // Can use both "@a" and "@a>".
+ if (*arg == '>') {
arg++;
+ }
// Make register empty when not using @A-@Z and the
// command is valid.
if (*arg == NUL && !isupper(redir_reg)) {
@@ -8110,30 +8277,33 @@ static void ex_redir(exarg_T *eap)
} else if (*arg == '=' && arg[1] == '>') {
int append;
- /* redirect to a variable */
+ // redirect to a variable
close_redir();
arg += 2;
if (*arg == '>') {
++arg;
append = TRUE;
- } else
+ } else {
append = FALSE;
+ }
- if (var_redir_start(skipwhite(arg), append) == OK)
+ if (var_redir_start(skipwhite(arg), append) == OK) {
redir_vname = 1;
+ }
}
- /* TODO: redirect to a buffer */
- else
+ // TODO: redirect to a buffer
+ else {
EMSG2(_(e_invarg2), eap->arg);
+ }
}
/* Make sure redirection is not off. Can happen for cmdline completion
* that indirectly invokes a command to catch its output. */
if (redir_fd != NULL
- || redir_reg || redir_vname
- )
- redir_off = FALSE;
+ || redir_reg || redir_vname) {
+ redir_off = false;
+ }
}
/// ":redraw": force redraw
@@ -8153,19 +8323,19 @@ static void ex_redraw(exarg_T *eap)
redraw_all_later(NOT_VALID);
}
update_screen(eap->forceit ? NOT_VALID
- : VIsual_active ? INVERTED : 0);
+ : VIsual_active ? INVERTED : 0);
if (need_maketitle) {
maketitle();
}
RedrawingDisabled = r;
p_lz = p;
- /* Reset msg_didout, so that a message that's there is overwritten. */
- msg_didout = FALSE;
+ // Reset msg_didout, so that a message that's there is overwritten.
+ msg_didout = false;
msg_col = 0;
- /* No need to wait after an intentional redraw. */
- need_wait_return = FALSE;
+ // No need to wait after an intentional redraw.
+ need_wait_return = false;
ui_flush();
}
@@ -8181,13 +8351,13 @@ static void ex_redrawstatus(exarg_T *eap)
RedrawingDisabled = 0;
p_lz = FALSE;
- if (eap->forceit)
+ if (eap->forceit) {
status_redraw_all();
- else
+ } else {
status_redraw_curbuf();
- update_screen(
- VIsual_active ? INVERTED :
- 0);
+ }
+ update_screen(VIsual_active ? INVERTED :
+ 0);
RedrawingDisabled = r;
p_lz = p;
ui_flush();
@@ -8239,21 +8409,17 @@ int vim_mkdir_emsg(const char *const name, const int prot)
return OK;
}
-/*
- * Open a file for writing for an Ex command, with some checks.
- * Return file descriptor, or NULL on failure.
- */
-FILE *
-open_exfile (
- char_u *fname,
- int forceit,
- char *mode /* "w" for create new file or "a" for append */
-)
+/// Open a file for writing for an Ex command, with some checks.
+///
+/// @param mode "w" for create new file or "a" for append
+///
+/// @return file descriptor, or NULL on failure.
+FILE *open_exfile(char_u *fname, int forceit, char *mode)
{
- FILE *fd;
+ FILE *fd;
#ifdef UNIX
- /* with Unix it is possible to open a directory */
+ // with Unix it is possible to open a directory
if (os_isdir(fname)) {
EMSG2(_(e_isadir2), fname);
return NULL;
@@ -8278,17 +8444,18 @@ static void ex_mark(exarg_T *eap)
{
pos_T pos;
- if (*eap->arg == NUL) /* No argument? */
+ if (*eap->arg == NUL) { // No argument?
EMSG(_(e_argreq));
- else if (eap->arg[1] != NUL) /* more than one character? */
+ } else if (eap->arg[1] != NUL) { // more than one character?
EMSG(_(e_trailing));
- else {
- pos = curwin->w_cursor; /* save curwin->w_cursor */
+ } else {
+ pos = curwin->w_cursor; // save curwin->w_cursor
curwin->w_cursor.lnum = eap->line2;
beginline(BL_WHITE | BL_FIX);
- if (setmark(*eap->arg) == FAIL) /* set mark */
+ if (setmark(*eap->arg) == FAIL) { // set mark
EMSG(_("E191: Argument must be a letter or forward/backward quote"));
- curwin->w_cursor = pos; /* restore curwin->w_cursor */
+ }
+ curwin->w_cursor = pos; // restore curwin->w_cursor
}
}
@@ -8348,7 +8515,9 @@ void restore_current_state(save_state_T *sst)
finish_op = sst->save_finish_op;
opcount = sst->save_opcount;
reg_executing = sst->save_reg_executing;
- msg_didout |= sst->save_msg_didout; // don't reset msg_didout now
+
+ // don't reset msg_didout now
+ msg_didout |= sst->save_msg_didout;
// Restore the state (needed when called from a function executed for
// 'indentexpr'). Update the mouse and cursor, they may have changed.
@@ -8366,9 +8535,9 @@ static void ex_normal(exarg_T *eap)
return;
}
save_state_T save_state;
- char_u *arg = NULL;
+ char_u *arg = NULL;
int l;
- char_u *p;
+ char_u *p;
if (ex_normal_lock > 0) {
EMSG(_(e_secure));
@@ -8385,12 +8554,14 @@ static void ex_normal(exarg_T *eap)
{
int len = 0;
- /* Count the number of characters to be escaped. */
+ // Count the number of characters to be escaped.
for (p = eap->arg; *p != NUL; ++p) {
- for (l = (*mb_ptr2len)(p) - 1; l > 0; --l)
- if (*++p == K_SPECIAL /* trailbyte K_SPECIAL or CSI */
- )
+ for (l = (*mb_ptr2len)(p) - 1; l > 0; --l) {
+ if (*++p == K_SPECIAL // trailbyte K_SPECIAL or CSI
+ ) {
len += 2;
+ }
+ }
}
if (len > 0) {
arg = xmalloc(STRLEN(eap->arg) + len + 1);
@@ -8426,7 +8597,7 @@ static void ex_normal(exarg_T *eap)
} while (eap->addr_count > 0 && eap->line1 <= eap->line2 && !got_int);
}
- /* Might not return to the main loop when in an event handler. */
+ // Might not return to the main loop when in an event handler.
update_topline_cursor();
restore_current_state(&save_state);
@@ -8457,16 +8628,18 @@ static void ex_startinsert(exarg_T *eap)
return;
}
- if (eap->cmdidx == CMD_startinsert)
+ if (eap->cmdidx == CMD_startinsert) {
restart_edit = 'a';
- else if (eap->cmdidx == CMD_startreplace)
+ } else if (eap->cmdidx == CMD_startreplace) {
restart_edit = 'R';
- else
+ } else {
restart_edit = 'V';
+ }
if (!eap->forceit) {
- if (eap->cmdidx == CMD_startinsert)
+ if (eap->cmdidx == CMD_startinsert) {
restart_edit = 'i';
+ }
curwin->w_curswant = 0; // avoid MAXCOL
}
@@ -8516,7 +8689,7 @@ void exec_normal(bool was_typed)
static void ex_checkpath(exarg_T *eap)
{
- find_pattern_in_path(NULL, 0, 0, FALSE, FALSE, CHECK_PATH, 1L,
+ find_pattern_in_path(NULL, 0, 0, false, false, CHECK_PATH, 1L,
eap->forceit ? ACTION_SHOW_ALL : ACTION_SHOW,
(linenr_T)1, (linenr_T)MAXLNUM);
}
@@ -8533,25 +8706,26 @@ static void ex_psearch(exarg_T *eap)
static void ex_findpat(exarg_T *eap)
{
- int whole = TRUE;
+ bool whole = true;
long n;
- char_u *p;
+ char_u *p;
int action;
switch (cmdnames[eap->cmdidx].cmd_name[2]) {
- case 'e': /* ":psearch", ":isearch" and ":dsearch" */
- if (cmdnames[eap->cmdidx].cmd_name[0] == 'p')
+ case 'e': // ":psearch", ":isearch" and ":dsearch"
+ if (cmdnames[eap->cmdidx].cmd_name[0] == 'p') {
action = ACTION_GOTO;
- else
+ } else {
action = ACTION_SHOW;
+ }
break;
- case 'i': /* ":ilist" and ":dlist" */
+ case 'i': // ":ilist" and ":dlist"
action = ACTION_SHOW_ALL;
break;
- case 'u': /* ":ijump" and ":djump" */
+ case 'u': // ":ijump" and ":djump"
action = ACTION_GOTO;
break;
- default: /* ":isplit" and ":dsplit" */
+ default: // ":isplit" and ":dsplit"
action = ACTION_SPLIT;
break;
}
@@ -8577,10 +8751,11 @@ static void ex_findpat(exarg_T *eap)
}
}
}
- if (!eap->skip)
+ if (!eap->skip) {
find_pattern_in_path(eap->arg, 0, STRLEN(eap->arg), whole, !eap->forceit,
*eap->cmd == 'd' ? FIND_DEFINE : FIND_ANY,
n, action, eap->line1, eap->line2);
+ }
}
@@ -8589,7 +8764,7 @@ static void ex_findpat(exarg_T *eap)
*/
static void ex_ptag(exarg_T *eap)
{
- g_do_tagpreview = p_pvh; /* will be reset to 0 in ex_tag_cmd() */
+ g_do_tagpreview = p_pvh; // will be reset to 0 in ex_tag_cmd()
ex_tag_cmd(eap, cmdnames[eap->cmdidx].cmd_name + 1);
}
@@ -8598,7 +8773,7 @@ static void ex_ptag(exarg_T *eap)
*/
static void ex_pedit(exarg_T *eap)
{
- win_T *curwin_save = curwin;
+ win_T *curwin_save = curwin;
// Open the preview window or popup and make it the current window.
g_do_tagpreview = p_pvh;
@@ -8642,21 +8817,28 @@ static void ex_tag_cmd(exarg_T *eap, char_u *name)
int cmd;
switch (name[1]) {
- case 'j': cmd = DT_JUMP; // ":tjump"
+ case 'j':
+ cmd = DT_JUMP; // ":tjump"
break;
- case 's': cmd = DT_SELECT; // ":tselect"
+ case 's':
+ cmd = DT_SELECT; // ":tselect"
break;
case 'p': // ":tprevious"
- case 'N': cmd = DT_PREV; // ":tNext"
+ case 'N':
+ cmd = DT_PREV; // ":tNext"
break;
- case 'n': cmd = DT_NEXT; // ":tnext"
+ case 'n':
+ cmd = DT_NEXT; // ":tnext"
break;
- case 'o': cmd = DT_POP; // ":pop"
+ case 'o':
+ cmd = DT_POP; // ":pop"
break;
case 'f': // ":tfirst"
- case 'r': cmd = DT_FIRST; // ":trewind"
+ case 'r':
+ cmd = DT_FIRST; // ":trewind"
break;
- case 'l': cmd = DT_LAST; // ":tlast"
+ case 'l':
+ cmd = DT_LAST; // ":tlast"
break;
default: // ":tag"
if (p_cst && *eap->arg != NUL) {
@@ -8672,7 +8854,7 @@ static void ex_tag_cmd(exarg_T *eap, char_u *name)
}
do_tag(eap->arg, cmd, eap->addr_count > 0 ? (int)eap->line2 : 1,
- eap->forceit, TRUE);
+ eap->forceit, TRUE);
}
enum {
@@ -8731,58 +8913,57 @@ ssize_t find_cmdline_var(const char_u *src, size_t *usedlen)
return -1;
}
-/*
- * Evaluate cmdline variables.
- *
- * change '%' to curbuf->b_ffname
- * '#' to curwin->w_alt_fnum
- * '<cword>' to word under the cursor
- * '<cWORD>' to WORD under the cursor
- * '<cexpr>' to C-expression under the cursor
- * '<cfile>' to path name under the cursor
- * '<sfile>' to sourced file name
- * '<slnum>' to sourced file line number
- * '<afile>' to file name for autocommand
- * '<abuf>' to buffer number for autocommand
- * '<amatch>' to matching name for autocommand
- *
- * When an error is detected, "errormsg" is set to a non-NULL pointer (may be
- * "" for error without a message) and NULL is returned.
- * Returns an allocated string if a valid match was found.
- * Returns NULL if no match was found. "usedlen" then still contains the
- * number of characters to skip.
- */
-char_u *
-eval_vars (
- char_u *src, /* pointer into commandline */
- char_u *srcstart, /* beginning of valid memory for src */
- size_t *usedlen, /* characters after src that are used */
- linenr_T *lnump, /* line number for :e command, or NULL */
- char_u **errormsg, /* pointer to error message */
- int *escaped /* return value has escaped white space (can
- * be NULL) */
-)
+/// Evaluate cmdline variables.
+///
+/// change '%' to curbuf->b_ffname
+/// '#' to curwin->w_alt_fnum
+/// '<cword>' to word under the cursor
+/// '<cWORD>' to WORD under the cursor
+/// '<cexpr>' to C-expression under the cursor
+/// '<cfile>' to path name under the cursor
+/// '<sfile>' to sourced file name
+/// '<slnum>' to sourced file line number
+/// '<afile>' to file name for autocommand
+/// '<abuf>' to buffer number for autocommand
+/// '<amatch>' to matching name for autocommand
+///
+/// When an error is detected, "errormsg" is set to a non-NULL pointer (may be
+/// "" for error without a message) and NULL is returned.
+///
+/// @param src pointer into commandline
+/// @param srcstart beginning of valid memory for src
+/// @param usedlen characters after src that are used
+/// @param lnump line number for :e command, or NULL
+/// @param errormsg pointer to error message
+/// @param escaped return value has escaped white space (can be NULL)
+///
+/// @return an allocated string if a valid match was found.
+/// Returns NULL if no match was found. "usedlen" then still contains the
+/// number of characters to skip.
+char_u *eval_vars(char_u *src, char_u *srcstart, size_t *usedlen, linenr_T *lnump,
+ char_u **errormsg, int *escaped)
{
int i;
- char_u *s;
- char_u *result;
- char_u *resultbuf = NULL;
+ char_u *s;
+ char_u *result;
+ char_u *resultbuf = NULL;
size_t resultlen;
- buf_T *buf;
+ buf_T *buf;
int valid = VALID_HEAD | VALID_PATH; // Assume valid result.
bool tilde_file = false;
- int skip_mod = false;
+ bool skip_mod = false;
char strbuf[30];
*errormsg = NULL;
- if (escaped != NULL)
+ if (escaped != NULL) {
*escaped = FALSE;
+ }
/*
* Check if there is something to do.
*/
ssize_t spec_idx = find_cmdline_var(src, usedlen);
- if (spec_idx < 0) { /* no match */
+ if (spec_idx < 0) { // no match
*usedlen = 1;
return NULL;
}
@@ -8793,7 +8974,7 @@ eval_vars (
*/
if (src > srcstart && src[-1] == '\\') {
*usedlen = 0;
- STRMOVE(src - 1, src); /* remove backslash */
+ STRMOVE(src - 1, src); // remove backslash
return NULL;
}
@@ -8803,9 +8984,8 @@ eval_vars (
if (spec_idx == SPEC_CWORD
|| spec_idx == SPEC_CCWORD
|| spec_idx == SPEC_CEXPR) {
- resultlen = find_ident_under_cursor(
- &result,
- spec_idx == SPEC_CWORD
+ resultlen = find_ident_under_cursor(&result,
+ spec_idx == SPEC_CWORD
? (FIND_IDENT | FIND_STRING)
: (spec_idx == SPEC_CEXPR
? (FIND_IDENT | FIND_STRING | FIND_EVAL)
@@ -8814,13 +8994,13 @@ eval_vars (
*errormsg = (char_u *)"";
return NULL;
}
- //
- // '#': Alternate file name
- // '%': Current file name
- // File name under the cursor
- // File name for autocommand
- // and following modifiers
- //
+ //
+ // '#': Alternate file name
+ // '%': Current file name
+ // File name under the cursor
+ // File name for autocommand
+ // and following modifiers
+ //
} else {
switch (spec_idx) {
case SPEC_PERC: // '%': current file
@@ -8833,14 +9013,15 @@ eval_vars (
}
break;
- case SPEC_HASH: /* '#' or "#99": alternate file */
- if (src[1] == '#') { /* "##": the argument list */
+ case SPEC_HASH: // '#' or "#99": alternate file
+ if (src[1] == '#') { // "##": the argument list
result = arg_all();
resultbuf = result;
*usedlen = 2;
- if (escaped != NULL)
+ if (escaped != NULL) {
*escaped = TRUE;
- skip_mod = TRUE;
+ }
+ skip_mod = true;
break;
}
s = src + 1;
@@ -8856,7 +9037,7 @@ eval_vars (
if (src[1] == '<' && i != 0) {
if (*usedlen < 2) {
- /* Should we give an error message for #<text? */
+ // Should we give an error message for #<text?
*usedlen = 1;
return NULL;
}
@@ -8872,12 +9053,12 @@ eval_vars (
}
buf = buflist_findnr(i);
if (buf == NULL) {
- *errormsg = (char_u *)_(
- "E194: No alternate file name to substitute for '#'");
+ *errormsg = (char_u *)_("E194: No alternate file name to substitute for '#'");
return NULL;
}
- if (lnump != NULL)
+ if (lnump != NULL) {
*lnump = ECMD_LAST;
+ }
if (buf->b_fname == NULL) {
result = (char_u *)"";
valid = 0; // Must have ":p:h" to be valid
@@ -8888,13 +9069,13 @@ eval_vars (
}
break;
- case SPEC_CFILE: /* file name under cursor */
+ case SPEC_CFILE: // file name under cursor
result = file_name_at_cursor(FNAME_MESS|FNAME_HYP, 1L, NULL);
if (result == NULL) {
*errormsg = (char_u *)"";
return NULL;
}
- resultbuf = result; /* remember allocated string */
+ resultbuf = result; // remember allocated string
break;
case SPEC_AFILE: // file name for autocommand
@@ -8911,37 +9092,33 @@ eval_vars (
}
result = autocmd_fname;
if (result == NULL) {
- *errormsg = (char_u *)_(
- "E495: no autocommand file name to substitute for \"<afile>\"");
+ *errormsg = (char_u *)_("E495: no autocommand file name to substitute for \"<afile>\"");
return NULL;
}
result = path_try_shorten_fname(result);
break;
- case SPEC_ABUF: /* buffer number for autocommand */
+ case SPEC_ABUF: // buffer number for autocommand
if (autocmd_bufnr <= 0) {
- *errormsg = (char_u *)_(
- "E496: no autocommand buffer number to substitute for \"<abuf>\"");
+ *errormsg = (char_u *)_("E496: no autocommand buffer number to substitute for \"<abuf>\"");
return NULL;
}
snprintf(strbuf, sizeof(strbuf), "%d", autocmd_bufnr);
result = (char_u *)strbuf;
break;
- case SPEC_AMATCH: /* match name for autocommand */
+ case SPEC_AMATCH: // match name for autocommand
result = autocmd_match;
if (result == NULL) {
- *errormsg = (char_u *)_(
- "E497: no autocommand match name to substitute for \"<amatch>\"");
+ *errormsg = (char_u *)_("E497: no autocommand match name to substitute for \"<amatch>\"");
return NULL;
}
break;
- case SPEC_SFILE: /* file name for ":so" command */
+ case SPEC_SFILE: // file name for ":so" command
result = sourcing_name;
if (result == NULL) {
- *errormsg = (char_u *)_(
- "E498: no :source file name to substitute for \"<sfile>\"");
+ *errormsg = (char_u *)_("E498: no :source file name to substitute for \"<sfile>\"");
return NULL;
}
break;
@@ -9001,15 +9178,16 @@ eval_vars (
}
if (resultlen == 0 || valid != VALID_HEAD + VALID_PATH) {
- if (valid != VALID_HEAD + VALID_PATH)
- /* xgettext:no-c-format */
- *errormsg = (char_u *)_(
- "E499: Empty file name for '%' or '#', only works with \":p:h\"");
- else
+ if (valid != VALID_HEAD + VALID_PATH) {
+ // xgettext:no-c-format
+ *errormsg = (char_u *)_("E499: Empty file name for '%' or '#', only works with \":p:h\"");
+ } else {
*errormsg = (char_u *)_("E500: Evaluates to an empty string");
+ }
result = NULL;
- } else
+ } else {
result = vim_strnsave(result, resultlen);
+ }
xfree(resultbuf);
return result;
}
@@ -9023,8 +9201,8 @@ static char_u *arg_all(void)
{
int len;
int idx;
- char_u *retval = NULL;
- char_u *p;
+ char_u *retval = NULL;
+ char_u *p;
/*
* Do this loop two times:
@@ -9039,9 +9217,10 @@ static char_u *arg_all(void)
continue;
}
if (len > 0) {
- /* insert a space in between names */
- if (retval != NULL)
+ // insert a space in between names
+ if (retval != NULL) {
retval[len] = ' ';
+ }
++len;
}
for (; *p != NUL; p++) {
@@ -9063,13 +9242,13 @@ static char_u *arg_all(void)
}
}
- /* second time: break here */
+ // second time: break here
if (retval != NULL) {
retval[len] = NUL;
break;
}
- /* allocate memory */
+ // allocate memory
retval = xmalloc(len + 1);
}
@@ -9083,29 +9262,30 @@ static char_u *arg_all(void)
*/
char_u *expand_sfile(char_u *arg)
{
- char_u *errormsg;
+ char_u *errormsg;
size_t len;
- char_u *result;
- char_u *newres;
- char_u *repl;
+ char_u *result;
+ char_u *newres;
+ char_u *repl;
size_t srclen;
- char_u *p;
+ char_u *p;
result = vim_strsave(arg);
for (p = result; *p; ) {
- if (STRNCMP(p, "<sfile>", 7) != 0)
+ if (STRNCMP(p, "<sfile>", 7) != 0) {
++p;
- else {
- /* replace "<sfile>" with the sourced file name, and do ":" stuff */
+ } else {
+ // replace "<sfile>" with the sourced file name, and do ":" stuff
repl = eval_vars(p, result, &srclen, NULL, &errormsg, NULL);
if (errormsg != NULL) {
- if (*errormsg)
+ if (*errormsg) {
emsg(errormsg);
+ }
xfree(result);
return NULL;
}
- if (repl == NULL) { /* no match (cannot happen) */
+ if (repl == NULL) { // no match (cannot happen)
p += srclen;
continue;
}
@@ -9118,7 +9298,7 @@ char_u *expand_sfile(char_u *arg)
xfree(repl);
xfree(result);
result = newres;
- p = newres + len; /* continue after the match */
+ p = newres + len; // continue after the match
}
}
@@ -9130,15 +9310,16 @@ char_u *expand_sfile(char_u *arg)
*/
static void ex_shada(exarg_T *eap)
{
- char_u *save_shada;
+ char_u *save_shada;
save_shada = p_shada;
- if (*p_shada == NUL)
+ if (*p_shada == NUL) {
p_shada = (char_u *)"'100";
+ }
if (eap->cmdidx == CMD_rviminfo || eap->cmdidx == CMD_rshada) {
- (void) shada_read_everything((char *) eap->arg, eap->forceit, false);
+ (void)shada_read_everything((char *)eap->arg, eap->forceit, false);
} else {
- shada_write_file((char *) eap->arg, eap->forceit);
+ shada_write_file((char *)eap->arg, eap->forceit);
}
p_shada = save_shada;
}
@@ -9149,8 +9330,9 @@ static void ex_shada(exarg_T *eap)
*/
void dialog_msg(char_u *buff, char *format, char_u *fname)
{
- if (fname == NULL)
+ if (fname == NULL) {
fname = (char_u *)_("Untitled");
+ }
vim_snprintf((char *)buff, DIALOG_MSG_SIZE, format, fname);
}
@@ -9180,10 +9362,12 @@ static void ex_behave(exarg_T *eap)
*/
char_u *get_behave_arg(expand_T *xp, int idx)
{
- if (idx == 0)
+ if (idx == 0) {
return (char_u *)"mswin";
- if (idx == 1)
+ }
+ if (idx == 1) {
return (char_u *)"xterm";
+ }
return NULL;
}
@@ -9220,12 +9404,12 @@ static TriState filetype_indent = kNone;
*/
static void ex_filetype(exarg_T *eap)
{
- char_u *arg = eap->arg;
+ char_u *arg = eap->arg;
bool plugin = false;
bool indent = false;
if (*eap->arg == NUL) {
- /* Print current status. */
+ // Print current status.
smsg("filetype detection:%s plugin:%s indent:%s",
filetype_detect == kTrue ? "ON" : "OFF",
filetype_plugin == kTrue ? (filetype_detect == kTrue ? "ON" : "(on)") : "OFF", // NOLINT(whitespace/line_length)
@@ -9233,7 +9417,7 @@ static void ex_filetype(exarg_T *eap)
return;
}
- /* Accept "plugin" and "indent" in any order. */
+ // Accept "plugin" and "indent" in any order.
for (;; ) {
if (STRNCMP(arg, "plugin", 6) == 0) {
plugin = true;
@@ -9278,8 +9462,9 @@ static void ex_filetype(exarg_T *eap)
source_runtime((char_u *)FTOFF_FILE, DIP_ALL);
filetype_detect = kFalse;
}
- } else
+ } else {
EMSG2(_(e_invarg2), arg);
+ }
}
/// Set all :filetype options ON if user did not explicitly set any to OFF.
@@ -9329,10 +9514,11 @@ static void ex_set(exarg_T *eap)
{
int flags = 0;
- if (eap->cmdidx == CMD_setlocal)
+ if (eap->cmdidx == CMD_setlocal) {
flags = OPT_LOCAL;
- else if (eap->cmdidx == CMD_setglobal)
+ } else if (eap->cmdidx == CMD_setglobal) {
flags = OPT_GLOBAL;
+ }
(void)do_set(eap->arg, flags);
}
@@ -9532,16 +9718,16 @@ bool cmd_can_preview(char_u *cmd)
char_u *end = find_command(&ea, NULL);
switch (ea.cmdidx) {
- case CMD_substitute:
- case CMD_smagic:
- case CMD_snomagic:
- // Only preview once the pattern delimiter has been typed
- if (*end && !ASCII_ISALNUM(*end)) {
- return true;
- }
- break;
- default:
- break;
+ case CMD_substitute:
+ case CMD_smagic:
+ case CMD_snomagic:
+ // Only preview once the pattern delimiter has been typed
+ if (*end && !ASCII_ISALNUM(*end)) {
+ return true;
+ }
+ break;
+ default:
+ break;
}
return false;
@@ -9572,11 +9758,16 @@ Dictionary commands_array(buf_T *buf)
PUT(d, "register", BOOLEAN_OBJ(!!(cmd->uc_argt & EX_REGSTR)));
switch (cmd->uc_argt & (EX_EXTRA | EX_NOSPC | EX_NEEDARG)) {
- case 0: arg[0] = '0'; break;
- case(EX_EXTRA): arg[0] = '*'; break;
- case(EX_EXTRA | EX_NOSPC): arg[0] = '?'; break;
- case(EX_EXTRA | EX_NEEDARG): arg[0] = '+'; break;
- case(EX_EXTRA | EX_NOSPC | EX_NEEDARG): arg[0] = '1'; break;
+ case 0:
+ arg[0] = '0'; break;
+ case (EX_EXTRA):
+ arg[0] = '*'; break;
+ case (EX_EXTRA | EX_NOSPC):
+ arg[0] = '?'; break;
+ case (EX_EXTRA | EX_NEEDARG):
+ arg[0] = '+'; break;
+ case (EX_EXTRA | EX_NOSPC | EX_NEEDARG):
+ arg[0] = '1'; break;
}
PUT(d, "nargs", STRING_OBJ(cstr_to_string(arg)));
diff --git a/src/nvim/ex_docmd.h b/src/nvim/ex_docmd.h
index f6bd2adcd5..8a78ca0337 100644
--- a/src/nvim/ex_docmd.h
+++ b/src/nvim/ex_docmd.h
@@ -11,21 +11,18 @@
#define DOCMD_KEYTYPED 0x08 // don't reset KeyTyped
#define DOCMD_EXCRESET 0x10 // reset exception environment (for debugging
#define DOCMD_KEEPLINE 0x20 // keep typed line for repeating with "."
+#define DOCMD_PREVIEW 0x40 // during 'inccommand' preview
/* defines for eval_vars() */
#define VALID_PATH 1
#define VALID_HEAD 2
-/* Values for exmode_active (0 is no exmode) */
-#define EXMODE_NORMAL 1
-#define EXMODE_VIM 2
-
// Structure used to save the current state. Used when executing Normal mode
// commands while in any other mode.
typedef struct {
int save_msg_scroll;
int save_restart_edit;
- int save_msg_didout;
+ bool save_msg_didout;
int save_State;
int save_insertmode;
bool save_finish_op;
diff --git a/src/nvim/ex_eval.c b/src/nvim/ex_eval.c
index 5ca88002f1..21ddf7399b 100644
--- a/src/nvim/ex_eval.c
+++ b/src/nvim/ex_eval.c
@@ -7,22 +7,23 @@
///
/// Functions for Ex command line for the +eval feature.
#include <assert.h>
-#include <stdbool.h>
#include <inttypes.h>
#include <limits.h>
+#include <stdbool.h>
-#include "nvim/vim.h"
#include "nvim/ascii.h"
-#include "nvim/ex_eval.h"
#include "nvim/charset.h"
+#include "nvim/debugger.h"
#include "nvim/eval.h"
#include "nvim/eval/userfunc.h"
#include "nvim/ex_cmds2.h"
#include "nvim/ex_docmd.h"
-#include "nvim/message.h"
+#include "nvim/ex_eval.h"
#include "nvim/memory.h"
+#include "nvim/message.h"
#include "nvim/regexp.h"
#include "nvim/strings.h"
+#include "nvim/vim.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "ex_eval.c.generated.h"
@@ -110,8 +111,9 @@ int aborting(void)
*/
void update_force_abort(void)
{
- if (cause_abort)
+ if (cause_abort) {
force_abort = TRUE;
+ }
}
/*
@@ -210,7 +212,7 @@ bool cause_errthrow(const char_u *mesg, bool severe, bool *ignore)
* not skipped. Errors in those commands may affect what of the subsequent
* commands are regarded part of catch and finally clauses. Catching the
* exception would then cause execution of commands not intended by the
- * user, who wouldn't even get aware of the problem. Therefor, discard the
+ * user, who wouldn't even get aware of the problem. Therefore, discard the
* exception currently being thrown to prevent it from being caught. Just
* execute finally clauses and terminate.
*/
@@ -247,8 +249,9 @@ bool cause_errthrow(const char_u *mesg, bool severe, bool *ignore)
*/
if (msg_list != NULL) {
plist = msg_list;
- while (*plist != NULL)
+ while (*plist != NULL) {
plist = &(*plist)->next;
+ }
elem = xmalloc(sizeof(struct msglist));
elem->msg = vim_strsave(mesg);
@@ -256,19 +259,20 @@ bool cause_errthrow(const char_u *mesg, bool severe, bool *ignore)
elem->throw_msg = NULL;
*plist = elem;
if (plist == msg_list || severe) {
- char_u *tmsg;
+ char_u *tmsg;
- /* Skip the extra "Vim " prefix for message "E458". */
+ // Skip the extra "Vim " prefix for message "E458".
tmsg = elem->msg;
if (STRNCMP(tmsg, "Vim E", 5) == 0
&& ascii_isdigit(tmsg[5])
&& ascii_isdigit(tmsg[6])
&& ascii_isdigit(tmsg[7])
&& tmsg[8] == ':'
- && tmsg[9] == ' ')
+ && tmsg[9] == ' ') {
(*msg_list)->throw_msg = &tmsg[4];
- else
+ } else {
(*msg_list)->throw_msg = tmsg;
+ }
}
}
return true;
@@ -280,7 +284,7 @@ bool cause_errthrow(const char_u *mesg, bool severe, bool *ignore)
*/
static void free_msglist(struct msglist *l)
{
- struct msglist *messages, *next;
+ struct msglist *messages, *next;
messages = l;
while (messages != NULL) {
@@ -319,16 +323,18 @@ void do_errthrow(cstack_T *cstack, char_u *cmdname)
/* If no exception is to be thrown or the conversion should be done after
* returning to a previous invocation of do_one_cmd(), do nothing. */
- if (msg_list == NULL || *msg_list == NULL)
+ if (msg_list == NULL || *msg_list == NULL) {
return;
+ }
- if (throw_exception(*msg_list, ET_ERROR, cmdname) == FAIL)
+ if (throw_exception(*msg_list, ET_ERROR, cmdname) == FAIL) {
free_msglist(*msg_list);
- else {
- if (cstack != NULL)
+ } else {
+ if (cstack != NULL) {
do_throw(cstack);
- else
+ } else {
need_rethrow = TRUE;
+ }
}
*msg_list = NULL;
}
@@ -356,36 +362,35 @@ int do_intthrow(cstack_T *cstack)
}
} else {
#endif
- // Throw an interrupt exception, so that everything will be aborted
- // (except for executing finally clauses), until the interrupt exception
- // is caught; if still uncaught at the top level, the script processing
- // will be terminated then. - If an interrupt exception is already
- // being thrown, do nothing.
-
- if (current_exception) {
- if (current_exception->type == ET_INTERRUPT) {
- return false;
- }
+ // Throw an interrupt exception, so that everything will be aborted
+ // (except for executing finally clauses), until the interrupt exception
+ // is caught; if still uncaught at the top level, the script processing
+ // will be terminated then. - If an interrupt exception is already
+ // being thrown, do nothing.
- // An interrupt exception replaces any user or error exception.
- discard_current_exception();
- }
- if (throw_exception("Vim:Interrupt", ET_INTERRUPT, NULL) != FAIL) {
- do_throw(cstack);
+ if (current_exception) {
+ if (current_exception->type == ET_INTERRUPT) {
+ return false;
}
-#ifdef THROW_TEST
+
+ // An interrupt exception replaces any user or error exception.
+ discard_current_exception();
}
+ if (throw_exception("Vim:Interrupt", ET_INTERRUPT, NULL) != FAIL) {
+ do_throw(cstack);
+ }
+#ifdef THROW_TEST
+}
#endif
return true;
}
// Get an exception message that is to be stored in current_exception->value.
-char_u *get_exception_string(void *value, except_type_T type, char_u *cmdname,
- int *should_free)
+char_u *get_exception_string(void *value, except_type_T type, char_u *cmdname, int *should_free)
{
- char_u *ret, *mesg;
- char_u *p, *val;
+ char_u *ret, *mesg;
+ char_u *p, *val;
if (type == ET_ERROR) {
*should_free = true;
@@ -433,7 +438,7 @@ char_u *get_exception_string(void *value, except_type_T type, char_u *cmdname,
}
} else {
*should_free = FALSE;
- ret = (char_u *) value;
+ ret = (char_u *)value;
}
return ret;
@@ -446,7 +451,7 @@ char_u *get_exception_string(void *value, except_type_T type, char_u *cmdname,
// error exception.
static int throw_exception(void *value, except_type_T type, char_u *cmdname)
{
- except_T *excp;
+ except_T *excp;
int should_free;
/*
@@ -465,14 +470,16 @@ static int throw_exception(void *value, except_type_T type, char_u *cmdname)
excp = xmalloc(sizeof(except_T));
- if (type == ET_ERROR)
+ if (type == ET_ERROR) {
/* Store the original message and prefix the exception value with
* "Vim:" or, if a command name is given, "Vim(cmdname):". */
excp->messages = (struct msglist *)value;
+ }
excp->value = get_exception_string(value, type, cmdname, &should_free);
- if (excp->value == NULL && should_free)
+ if (excp->value == NULL && should_free) {
goto nomem;
+ }
excp->type = type;
excp->throw_name = vim_strsave(sourcing_name == NULL
@@ -482,24 +489,27 @@ static int throw_exception(void *value, except_type_T type, char_u *cmdname)
if (p_verbose >= 13 || debug_break_level > 0) {
int save_msg_silent = msg_silent;
- if (debug_break_level > 0)
- msg_silent = FALSE; /* display messages */
- else
+ if (debug_break_level > 0) {
+ msg_silent = FALSE; // display messages
+ } else {
verbose_enter();
+ }
++no_wait_return;
- if (debug_break_level > 0 || *p_vfile == NUL)
- msg_scroll = TRUE; /* always scroll up, don't overwrite */
-
+ if (debug_break_level > 0 || *p_vfile == NUL) {
+ msg_scroll = TRUE; // always scroll up, don't overwrite
+ }
smsg(_("Exception thrown: %s"), excp->value);
msg_puts("\n"); // don't overwrite this either
- if (debug_break_level > 0 || *p_vfile == NUL)
+ if (debug_break_level > 0 || *p_vfile == NUL) {
cmdline_row = msg_row;
+ }
--no_wait_return;
- if (debug_break_level > 0)
+ if (debug_break_level > 0) {
msg_silent = save_msg_silent;
- else
+ } else {
verbose_leave();
+ }
}
current_exception = excp;
@@ -520,7 +530,7 @@ fail:
*/
static void discard_exception(except_T *excp, bool was_finished)
{
- char_u *saved_IObuff;
+ char_u *saved_IObuff;
if (current_exception == excp) {
current_exception = NULL;
@@ -534,13 +544,15 @@ static void discard_exception(except_T *excp, bool was_finished)
int save_msg_silent = msg_silent;
saved_IObuff = vim_strsave(IObuff);
- if (debug_break_level > 0)
- msg_silent = FALSE; /* display messages */
- else
+ if (debug_break_level > 0) {
+ msg_silent = FALSE; // display messages
+ } else {
verbose_enter();
+ }
++no_wait_return;
- if (debug_break_level > 0 || *p_vfile == NUL)
- msg_scroll = TRUE; /* always scroll up, don't overwrite */
+ if (debug_break_level > 0 || *p_vfile == NUL) {
+ msg_scroll = TRUE; // always scroll up, don't overwrite
+ }
smsg(was_finished ? _("Exception finished: %s")
: _("Exception discarded: %s"),
excp->value);
@@ -557,10 +569,12 @@ static void discard_exception(except_T *excp, bool was_finished)
xstrlcpy((char *)IObuff, (const char *)saved_IObuff, IOSIZE);
xfree(saved_IObuff);
}
- if (excp->type != ET_INTERRUPT)
+ if (excp->type != ET_INTERRUPT) {
xfree(excp->value);
- if (excp->type == ET_ERROR)
+ }
+ if (excp->type == ET_ERROR) {
free_msglist(excp->messages);
+ }
xfree(excp->throw_name);
xfree(excp);
}
@@ -585,7 +599,7 @@ static void catch_exception(except_T *excp)
{
excp->caught = caught_stack;
caught_stack = excp;
- set_vim_var_string(VV_EXCEPTION, (char *) excp->value, -1);
+ set_vim_var_string(VV_EXCEPTION, (char *)excp->value, -1);
if (*excp->throw_name != NUL) {
if (excp->throw_lnum != 0) {
vim_snprintf((char *)IObuff, IOSIZE, _("%s, line %" PRId64),
@@ -593,7 +607,7 @@ static void catch_exception(except_T *excp)
} else {
vim_snprintf((char *)IObuff, IOSIZE, "%s", excp->throw_name);
}
- set_vim_var_string(VV_THROWPOINT, (char *) IObuff, -1);
+ set_vim_var_string(VV_THROWPOINT, (char *)IObuff, -1);
} else {
// throw_name not set on an exception from a command that was typed.
set_vim_var_string(VV_THROWPOINT, NULL, -1);
@@ -602,24 +616,27 @@ static void catch_exception(except_T *excp)
if (p_verbose >= 13 || debug_break_level > 0) {
int save_msg_silent = msg_silent;
- if (debug_break_level > 0)
- msg_silent = FALSE; /* display messages */
- else
+ if (debug_break_level > 0) {
+ msg_silent = FALSE; // display messages
+ } else {
verbose_enter();
+ }
++no_wait_return;
- if (debug_break_level > 0 || *p_vfile == NUL)
- msg_scroll = TRUE; /* always scroll up, don't overwrite */
-
+ if (debug_break_level > 0 || *p_vfile == NUL) {
+ msg_scroll = TRUE; // always scroll up, don't overwrite
+ }
smsg(_("Exception caught: %s"), excp->value);
msg_puts("\n"); // don't overwrite this either
- if (debug_break_level > 0 || *p_vfile == NUL)
+ if (debug_break_level > 0 || *p_vfile == NUL) {
cmdline_row = msg_row;
+ }
--no_wait_return;
- if (debug_break_level > 0)
+ if (debug_break_level > 0) {
msg_silent = save_msg_silent;
- else
+ } else {
verbose_leave();
+ }
}
}
@@ -633,7 +650,7 @@ static void finish_exception(except_T *excp)
}
caught_stack = caught_stack->caught;
if (caught_stack != NULL) {
- set_vim_var_string(VV_EXCEPTION, (char *) caught_stack->value, -1);
+ set_vim_var_string(VV_EXCEPTION, (char *)caught_stack->value, -1);
if (*caught_stack->throw_name != NUL) {
if (caught_stack->throw_lnum != 0) {
vim_snprintf((char *)IObuff, IOSIZE,
@@ -643,7 +660,7 @@ static void finish_exception(except_T *excp)
vim_snprintf((char *)IObuff, IOSIZE, "%s",
caught_stack->throw_name);
}
- set_vim_var_string(VV_THROWPOINT, (char *) IObuff, -1);
+ set_vim_var_string(VV_THROWPOINT, (char *)IObuff, -1);
} else {
// throw_name not set on an exception from a command that was
// typed.
@@ -687,7 +704,7 @@ static void report_pending(int action, int pending, void *value)
case RP_RESUME:
mesg = _("%s resumed");
break;
- /* case RP_DISCARD: */
+ // case RP_DISCARD:
default:
mesg = _("%s discarded");
break;
@@ -707,7 +724,7 @@ static void report_pending(int action, int pending, void *value)
s = ":finish";
break;
case CSTP_RETURN:
- /* ":return" command producing value, allocated */
+ // ":return" command producing value, allocated
s = (char *)get_return_cmd(value);
break;
@@ -717,30 +734,34 @@ static void report_pending(int action, int pending, void *value)
mesg, _("Exception"));
mesg = (char *)concat_str(IObuff, (char_u *)": %s");
s = (char *)((except_T *)value)->value;
- } else if ((pending & CSTP_ERROR) && (pending & CSTP_INTERRUPT))
+ } else if ((pending & CSTP_ERROR) && (pending & CSTP_INTERRUPT)) {
s = _("Error and interrupt");
- else if (pending & CSTP_ERROR)
+ } else if (pending & CSTP_ERROR) {
s = _("Error");
- else /* if (pending & CSTP_INTERRUPT) */
+ } else { // if (pending & CSTP_INTERRUPT)
s = _("Interrupt");
+ }
}
save_msg_silent = msg_silent;
- if (debug_break_level > 0)
- msg_silent = FALSE; /* display messages */
+ if (debug_break_level > 0) {
+ msg_silent = FALSE; // display messages
+ }
++no_wait_return;
- msg_scroll = TRUE; /* always scroll up, don't overwrite */
+ msg_scroll = TRUE; // always scroll up, don't overwrite
smsg(mesg, s);
msg_puts("\n"); // don't overwrite this either
cmdline_row = msg_row;
--no_wait_return;
- if (debug_break_level > 0)
+ if (debug_break_level > 0) {
msg_silent = save_msg_silent;
+ }
- if (pending == CSTP_RETURN)
+ if (pending == CSTP_RETURN) {
xfree(s);
- else if (pending & CSTP_THROW)
+ } else if (pending & CSTP_THROW) {
xfree(mesg);
+ }
}
/*
@@ -750,11 +771,13 @@ static void report_pending(int action, int pending, void *value)
void report_make_pending(int pending, void *value)
{
if (p_verbose >= 14 || debug_break_level > 0) {
- if (debug_break_level <= 0)
+ if (debug_break_level <= 0) {
verbose_enter();
+ }
report_pending(RP_MAKE, pending, value);
- if (debug_break_level <= 0)
+ if (debug_break_level <= 0) {
verbose_leave();
+ }
}
}
@@ -765,11 +788,13 @@ void report_make_pending(int pending, void *value)
void report_resume_pending(int pending, void *value)
{
if (p_verbose >= 14 || debug_break_level > 0) {
- if (debug_break_level <= 0)
+ if (debug_break_level <= 0) {
verbose_enter();
+ }
report_pending(RP_RESUME, pending, value);
- if (debug_break_level <= 0)
+ if (debug_break_level <= 0) {
verbose_leave();
+ }
}
}
@@ -780,11 +805,13 @@ void report_resume_pending(int pending, void *value)
void report_discard_pending(int pending, void *value)
{
if (p_verbose >= 14 || debug_break_level > 0) {
- if (debug_break_level <= 0)
+ if (debug_break_level <= 0) {
verbose_enter();
+ }
report_pending(RP_DISCARD, pending, value);
- if (debug_break_level <= 0)
+ if (debug_break_level <= 0) {
verbose_leave();
+ }
}
}
@@ -807,9 +834,9 @@ void ex_if(exarg_T *eap)
int result;
cstack_T *const cstack = eap->cstack;
- if (cstack->cs_idx == CSTACK_LEN - 1)
+ if (cstack->cs_idx == CSTACK_LEN - 1) {
eap->errmsg = (char_u *)N_("E579: :if nesting too deep");
- else {
+ } else {
++cstack->cs_idx;
cstack->cs_flags[cstack->cs_idx] = 0;
@@ -819,11 +846,13 @@ void ex_if(exarg_T *eap)
result = eval_to_bool(eap->arg, &error, &eap->nextcmd, skip);
if (!skip && !error) {
- if (result)
+ if (result) {
cstack->cs_flags[cstack->cs_idx] = CSF_ACTIVE | CSF_TRUE;
- } else
- /* set TRUE, so this conditional will never get active */
+ }
+ } else {
+ // set TRUE, so this conditional will never get active
cstack->cs_flags[cstack->cs_idx] = CSF_TRUE;
+ }
}
}
@@ -832,24 +861,23 @@ void ex_if(exarg_T *eap)
*/
void ex_endif(exarg_T *eap)
{
- did_endif = TRUE;
+ did_endif = true;
if (eap->cstack->cs_idx < 0
|| (eap->cstack->cs_flags[eap->cstack->cs_idx]
- & (CSF_WHILE | CSF_FOR | CSF_TRY)))
+ & (CSF_WHILE | CSF_FOR | CSF_TRY))) {
eap->errmsg = (char_u *)N_("E580: :endif without :if");
- else {
- /*
- * When debugging or a breakpoint was encountered, display the debug
- * prompt (if not already done). This shows the user that an ":endif"
- * is executed when the ":if" or a previous ":elseif" was not TRUE.
- * Handle a ">quit" debug command as if an interrupt had occurred before
- * the ":endif". That is, throw an interrupt exception if appropriate.
- * Doing this here prevents an exception for a parsing error being
- * discarded by throwing the interrupt exception later on.
- */
+ } else {
+ // When debugging or a breakpoint was encountered, display the debug
+ // prompt (if not already done). This shows the user that an ":endif"
+ // is executed when the ":if" or a previous ":elseif" was not TRUE.
+ // Handle a ">quit" debug command as if an interrupt had occurred before
+ // the ":endif". That is, throw an interrupt exception if appropriate.
+ // Doing this here prevents an exception for a parsing error being
+ // discarded by throwing the interrupt exception later on.
if (!(eap->cstack->cs_flags[eap->cstack->cs_idx] & CSF_TRUE)
- && dbg_check_skipped(eap))
+ && dbg_check_skipped(eap)) {
(void)do_intthrow(eap->cstack);
+ }
--eap->cstack->cs_idx;
}
@@ -884,13 +912,15 @@ void ex_else(exarg_T *eap)
skip = TRUE;
}
- /* if skipping or the ":if" was TRUE, reset ACTIVE, otherwise set it */
+ // if skipping or the ":if" was TRUE, reset ACTIVE, otherwise set it
if (skip || cstack->cs_flags[cstack->cs_idx] & CSF_TRUE) {
- if (eap->errmsg == NULL)
+ if (eap->errmsg == NULL) {
cstack->cs_flags[cstack->cs_idx] = CSF_TRUE;
- skip = TRUE; /* don't evaluate an ":elseif" */
- } else
+ }
+ skip = TRUE; // don't evaluate an ":elseif"
+ } else {
cstack->cs_flags[cstack->cs_idx] = CSF_ACTIVE;
+ }
/*
* When debugging or a breakpoint was encountered, display the debug prompt
@@ -917,15 +947,18 @@ void ex_else(exarg_T *eap)
* case, the parsing error will be ignored by emsg(). */
if (!skip && !error) {
- if (result)
+ if (result) {
cstack->cs_flags[cstack->cs_idx] = CSF_ACTIVE | CSF_TRUE;
- else
+ } else {
cstack->cs_flags[cstack->cs_idx] = 0;
- } else if (eap->errmsg == NULL)
- /* set TRUE, so this conditional will never get active */
+ }
+ } else if (eap->errmsg == NULL) {
+ // set TRUE, so this conditional will never get active
cstack->cs_flags[cstack->cs_idx] = CSF_TRUE;
- } else
+ }
+ } else {
cstack->cs_flags[cstack->cs_idx] |= CSF_ELSE;
+ }
}
/*
@@ -938,9 +971,9 @@ void ex_while(exarg_T *eap)
int result;
cstack_T *const cstack = eap->cstack;
- if (cstack->cs_idx == CSTACK_LEN - 1)
+ if (cstack->cs_idx == CSTACK_LEN - 1) {
eap->errmsg = (char_u *)N_("E585: :while/:for nesting too deep");
- else {
+ } else {
/*
* The loop flag is set when we have jumped back from the matching
* ":endwhile" or ":endfor". When not set, need to initialise this
@@ -972,16 +1005,17 @@ void ex_while(exarg_T *eap)
fi = cstack->cs_forinfo[cstack->cs_idx];
error = FALSE;
} else {
- /* Evaluate the argument and get the info in a structure. */
+ // Evaluate the argument and get the info in a structure.
fi = eval_for_line(eap->arg, &error, &eap->nextcmd, skip);
cstack->cs_forinfo[cstack->cs_idx] = fi;
}
- /* use the element at the start of the list and advance */
- if (!error && fi != NULL && !skip)
+ // use the element at the start of the list and advance
+ if (!error && fi != NULL && !skip) {
result = next_for_item(fi, eap->arg);
- else
+ } else {
result = FALSE;
+ }
if (!result) {
free_for_info(fi);
@@ -1003,8 +1037,9 @@ void ex_while(exarg_T *eap)
* the list, show the debug prompt at the ":endwhile"/":endfor" as
* if there was a ":break" in a ":while"/":for" evaluating to
* TRUE. */
- if (!skip && !error)
+ if (!skip && !error) {
cstack->cs_flags[cstack->cs_idx] |= CSF_TRUE;
+ }
}
}
}
@@ -1017,12 +1052,12 @@ void ex_continue(exarg_T *eap)
int idx;
cstack_T *const cstack = eap->cstack;
- if (cstack->cs_looplevel <= 0 || cstack->cs_idx < 0)
+ if (cstack->cs_looplevel <= 0 || cstack->cs_idx < 0) {
eap->errmsg = (char_u *)N_("E586: :continue without :while or :for");
- else {
+ } else {
/* Try to find the matching ":while". This might stop at a try
* conditional not in its finally clause (which is then to be executed
- * next). Therefor, inactivate all conditionals except the ":while"
+ * next). Therefore, deactivate all conditionals except the ":while"
* itself (if reached). */
idx = cleanup_conditionals(cstack, CSF_WHILE | CSF_FOR, FALSE);
assert(idx >= 0);
@@ -1033,7 +1068,7 @@ void ex_continue(exarg_T *eap)
* Set CSL_HAD_CONT, so do_cmdline() will jump back to the
* matching ":while".
*/
- cstack->cs_lflags |= CSL_HAD_CONT; /* let do_cmdline() handle it */
+ cstack->cs_lflags |= CSL_HAD_CONT; // let do_cmdline() handle it
} else {
/* If a try conditional not in its finally clause is reached first,
* make the ":continue" pending for execution at the ":endtry". */
@@ -1051,14 +1086,14 @@ void ex_break(exarg_T *eap)
int idx;
cstack_T *const cstack = eap->cstack;
- if (cstack->cs_looplevel <= 0 || cstack->cs_idx < 0)
+ if (cstack->cs_looplevel <= 0 || cstack->cs_idx < 0) {
eap->errmsg = (char_u *)N_("E587: :break without :while or :for");
- else {
- /* Inactivate conditionals until the matching ":while" or a try
- * conditional not in its finally clause (which is then to be
- * executed next) is found. In the latter case, make the ":break"
- * pending for execution at the ":endtry". */
- idx = cleanup_conditionals(cstack, CSF_WHILE | CSF_FOR, TRUE);
+ } else {
+ // Deactivate conditionals until the matching ":while" or a try
+ // conditional not in its finally clause (which is then to be
+ // executed next) is found. In the latter case, make the ":break"
+ // pending for execution at the ":endtry". */
+ idx = cleanup_conditionals(cstack, CSF_WHILE | CSF_FOR, true);
if (idx >= 0 && !(cstack->cs_flags[idx] & (CSF_WHILE | CSF_FOR))) {
cstack->cs_pending[idx] = CSTP_BREAK;
report_make_pending(CSTP_BREAK, NULL);
@@ -1073,7 +1108,7 @@ void ex_endwhile(exarg_T *eap)
{
cstack_T *const cstack = eap->cstack;
int idx;
- char_u *err;
+ char_u *err;
int csf;
int fl;
@@ -1085,24 +1120,26 @@ void ex_endwhile(exarg_T *eap)
csf = CSF_FOR;
}
- if (cstack->cs_looplevel <= 0 || cstack->cs_idx < 0)
+ if (cstack->cs_looplevel <= 0 || cstack->cs_idx < 0) {
eap->errmsg = err;
- else {
+ } else {
fl = cstack->cs_flags[cstack->cs_idx];
if (!(fl & csf)) {
/* If we are in a ":while" or ":for" but used the wrong endloop
* command, do not rewind to the next enclosing ":for"/":while". */
- if (fl & CSF_WHILE)
+ if (fl & CSF_WHILE) {
eap->errmsg = (char_u *)_("E732: Using :endfor with :while");
- else if (fl & CSF_FOR)
+ } else if (fl & CSF_FOR) {
eap->errmsg = (char_u *)_("E733: Using :endwhile with :for");
+ }
}
if (!(fl & (CSF_WHILE | CSF_FOR))) {
- if (!(fl & CSF_TRY))
+ if (!(fl & CSF_TRY)) {
eap->errmsg = e_endif;
- else if (fl & CSF_FINALLY)
+ } else if (fl & CSF_FINALLY) {
eap->errmsg = e_endtry;
- /* Try to find the matching ":while" and report what's missing. */
+ }
+ // Try to find the matching ":while" and report what's missing.
for (idx = cstack->cs_idx; idx > 0; --idx) {
fl = cstack->cs_flags[idx];
if ((fl & CSF_TRY) && !(fl & CSF_FINALLY)) {
@@ -1111,10 +1148,11 @@ void ex_endwhile(exarg_T *eap)
eap->errmsg = err;
return;
}
- if (fl & csf)
+ if (fl & csf) {
break;
+ }
}
- /* Cleanup and rewind all contained (and unclosed) conditionals. */
+ // Cleanup and rewind all contained (and unclosed) conditionals.
(void)cleanup_conditionals(cstack, CSF_WHILE | CSF_FOR, FALSE);
rewind_conditionals(cstack, idx, CSF_TRY, &cstack->cs_trylevel);
}
@@ -1130,8 +1168,9 @@ void ex_endwhile(exarg_T *eap)
*/
else if (cstack->cs_flags[cstack->cs_idx] & CSF_TRUE
&& !(cstack->cs_flags[cstack->cs_idx] & CSF_ACTIVE)
- && dbg_check_skipped(eap))
+ && dbg_check_skipped(eap)) {
(void)do_intthrow(cstack);
+ }
/*
* Set loop flag, so do_cmdline() will jump back to the matching
@@ -1179,15 +1218,15 @@ void do_throw(cstack_T *cstack)
int idx;
int inactivate_try = FALSE;
- /*
- * Cleanup and inactivate up to the next surrounding try conditional that
- * is not in its finally clause. Normally, do not inactivate the try
- * conditional itself, so that its ACTIVE flag can be tested below. But
- * if a previous error or interrupt has not been converted to an exception,
- * inactivate the try conditional, too, as if the conversion had been done,
- * and reset the did_emsg or got_int flag, so this won't happen again at
- * the next surrounding try conditional.
- */
+ //
+ // Cleanup and deactivate up to the next surrounding try conditional that
+ // is not in its finally clause. Normally, do not deactivate the try
+ // conditional itself, so that its ACTIVE flag can be tested below. But
+ // if a previous error or interrupt has not been converted to an exception,
+ // deactivate the try conditional, too, as if the conversion had been done,
+ // and reset the did_emsg or got_int flag, so this won't happen again at
+ // the next surrounding try conditional.
+ //
#ifndef THROW_ON_ERROR_TRUE
if (did_emsg && !THROW_ON_ERROR) {
inactivate_try = TRUE;
@@ -1216,13 +1255,14 @@ void do_throw(cstack_T *cstack)
* the matching catch clause or the finally clause.
*/
if (!(cstack->cs_flags[idx] & CSF_CAUGHT)) {
- if (cstack->cs_flags[idx] & CSF_ACTIVE)
+ if (cstack->cs_flags[idx] & CSF_ACTIVE) {
cstack->cs_flags[idx] |= CSF_THROWN;
- else
+ } else {
/* THROWN may have already been set for a catchable exception
* that has been discarded. Ensure it is reset for the new
* exception. */
cstack->cs_flags[idx] &= ~CSF_THROWN;
+ }
}
cstack->cs_flags[idx] &= ~CSF_ACTIVE;
cstack->cs_exception[idx] = current_exception;
@@ -1237,9 +1277,9 @@ void ex_try(exarg_T *eap)
int skip;
cstack_T *const cstack = eap->cstack;
- if (cstack->cs_idx == CSTACK_LEN - 1)
+ if (cstack->cs_idx == CSTACK_LEN - 1) {
eap->errmsg = (char_u *)N_("E601: :try nesting too deep");
- else {
+ } else {
++cstack->cs_idx;
++cstack->cs_trylevel;
cstack->cs_flags[cstack->cs_idx] = CSF_TRY;
@@ -1278,7 +1318,6 @@ void ex_try(exarg_T *eap)
emsg_silent = 0;
}
}
-
}
}
@@ -1291,13 +1330,13 @@ void ex_catch(exarg_T *eap)
int give_up = FALSE;
int skip = FALSE;
int caught = FALSE;
- char_u *end;
+ char_u *end;
char_u save_char = 0;
- char_u *save_cpo;
+ char_u *save_cpo;
regmatch_T regmatch;
int prev_got_int;
cstack_T *const cstack = eap->cstack;
- char_u *pat;
+ char_u *pat;
if (cstack->cs_trylevel <= 0 || cstack->cs_idx < 0) {
eap->errmsg = (char_u *)N_("E603: :catch without :try");
@@ -1309,20 +1348,23 @@ void ex_catch(exarg_T *eap)
eap->errmsg = get_end_emsg(cstack);
skip = TRUE;
}
- for (idx = cstack->cs_idx; idx > 0; --idx)
- if (cstack->cs_flags[idx] & CSF_TRY)
+ for (idx = cstack->cs_idx; idx > 0; --idx) {
+ if (cstack->cs_flags[idx] & CSF_TRY) {
break;
+ }
+ }
if (cstack->cs_flags[idx] & CSF_FINALLY) {
/* Give up for a ":catch" after ":finally" and ignore it.
* Just parse. */
eap->errmsg = (char_u *)N_("E604: :catch after :finally");
give_up = TRUE;
- } else
+ } else {
rewind_conditionals(cstack, idx, CSF_WHILE | CSF_FOR,
- &cstack->cs_looplevel);
+ &cstack->cs_looplevel);
+ }
}
- if (ends_excmd(*eap->arg)) { /* no argument, catch all errors */
+ if (ends_excmd(*eap->arg)) { // no argument, catch all errors
pat = (char_u *)".*";
end = NULL;
eap->nextcmd = find_nextcmd(eap->arg);
@@ -1390,7 +1432,7 @@ void ex_catch(exarg_T *eap)
prev_got_int = got_int;
got_int = FALSE;
caught = vim_regexec_nl(&regmatch, current_exception->value,
- (colnr_T)0);
+ (colnr_T)0);
got_int |= prev_got_int;
vim_regfree(regmatch.regprog);
}
@@ -1430,8 +1472,9 @@ void ex_catch(exarg_T *eap)
}
}
- if (end != NULL)
+ if (end != NULL) {
eap->nextcmd = find_nextcmd(end);
+ }
}
/*
@@ -1444,28 +1487,31 @@ void ex_finally(exarg_T *eap)
int pending = CSTP_NONE;
cstack_T *const cstack = eap->cstack;
- if (cstack->cs_trylevel <= 0 || cstack->cs_idx < 0)
+ if (cstack->cs_trylevel <= 0 || cstack->cs_idx < 0) {
eap->errmsg = (char_u *)N_("E606: :finally without :try");
- else {
+ } else {
if (!(cstack->cs_flags[cstack->cs_idx] & CSF_TRY)) {
eap->errmsg = get_end_emsg(cstack);
- for (idx = cstack->cs_idx - 1; idx > 0; --idx)
- if (cstack->cs_flags[idx] & CSF_TRY)
+ for (idx = cstack->cs_idx - 1; idx > 0; --idx) {
+ if (cstack->cs_flags[idx] & CSF_TRY) {
break;
+ }
+ }
/* Make this error pending, so that the commands in the following
* finally clause can be executed. This overrules also a pending
* ":continue", ":break", ":return", or ":finish". */
pending = CSTP_ERROR;
- } else
+ } else {
idx = cstack->cs_idx;
+ }
if (cstack->cs_flags[idx] & CSF_FINALLY) {
- /* Give up for a multiple ":finally" and ignore it. */
+ // Give up for a multiple ":finally" and ignore it.
eap->errmsg = (char_u *)N_("E607: multiple :finally");
return;
}
rewind_conditionals(cstack, idx, CSF_WHILE | CSF_FOR,
- &cstack->cs_looplevel);
+ &cstack->cs_looplevel);
/*
* Don't do something when the corresponding try block never got active
@@ -1517,7 +1563,7 @@ void ex_finally(exarg_T *eap)
if (pending == CSTP_ERROR || did_emsg || got_int || current_exception) {
if (cstack->cs_pending[cstack->cs_idx] == CSTP_RETURN) {
report_discard_pending(CSTP_RETURN,
- cstack->cs_rettv[cstack->cs_idx]);
+ cstack->cs_rettv[cstack->cs_idx]);
discard_pending_return(cstack->cs_rettv[cstack->cs_idx]);
}
if (pending == CSTP_ERROR && !did_emsg) {
@@ -1564,7 +1610,7 @@ void ex_endtry(exarg_T *eap)
int skip;
int rethrow = FALSE;
int pending = CSTP_NONE;
- void *rettv = NULL;
+ void *rettv = NULL;
cstack_T *const cstack = eap->cstack;
if (cstack->cs_trylevel <= 0 || cstack->cs_idx < 0) {
@@ -1585,13 +1631,13 @@ void ex_endtry(exarg_T *eap)
if (!(cstack->cs_flags[cstack->cs_idx] & CSF_TRY)) {
eap->errmsg = get_end_emsg(cstack);
- /* Find the matching ":try" and report what's missing. */
+ // Find the matching ":try" and report what's missing.
idx = cstack->cs_idx;
do
--idx;
while (idx > 0 && !(cstack->cs_flags[idx] & CSF_TRY));
rewind_conditionals(cstack, idx, CSF_WHILE | CSF_FOR,
- &cstack->cs_looplevel);
+ &cstack->cs_looplevel);
skip = TRUE;
/*
@@ -1656,10 +1702,11 @@ void ex_endtry(exarg_T *eap)
if (!skip) {
pending = cstack->cs_pending[idx];
cstack->cs_pending[idx] = CSTP_NONE;
- if (pending == CSTP_RETURN)
+ if (pending == CSTP_RETURN) {
rettv = cstack->cs_rettv[idx];
- else if (pending & CSTP_THROW)
+ } else if (pending & CSTP_THROW) {
current_exception = cstack->cs_exception[idx];
+ }
}
/*
@@ -1679,8 +1726,8 @@ void ex_endtry(exarg_T *eap)
if (!skip) {
report_resume_pending(pending,
- (pending == CSTP_RETURN) ? rettv :
- (pending & CSTP_THROW) ? (void *)current_exception : NULL);
+ (pending == CSTP_RETURN) ? rettv :
+ (pending & CSTP_THROW) ? (void *)current_exception : NULL);
switch (pending) {
case CSTP_NONE:
break;
@@ -1788,7 +1835,7 @@ void enter_cleanup(cleanup_T *csp)
did_emsg = got_int = need_rethrow = false;
current_exception = NULL;
- /* Report if required by the 'verbose' option or when debugging. */
+ // Report if required by the 'verbose' option or when debugging.
report_make_pending(pending, csp->exception);
} else {
csp->pending = CSTP_NONE;
@@ -1815,8 +1862,9 @@ void leave_cleanup(cleanup_T *csp)
{
int pending = csp->pending;
- if (pending == CSTP_NONE) /* nothing to do */
+ if (pending == CSTP_NONE) { // nothing to do
return;
+ }
/* If there was an aborting error, an interrupt, or an uncaught exception
* after the corresponding call to enter_cleanup(), discard what has been
@@ -1832,8 +1880,9 @@ void leave_cleanup(cleanup_T *csp)
/* If an error was about to be converted to an exception when
* enter_cleanup() was called, free the message list. */
- if (msg_list != NULL)
+ if (msg_list != NULL) {
free_global_msglist();
+ }
}
/*
* If there was no new error, interrupt, or throw between the calls
@@ -1846,9 +1895,9 @@ void leave_cleanup(cleanup_T *csp)
* called, we need to rethrow it. Make it the exception currently
* being thrown.
*/
- if (pending & CSTP_THROW)
+ if (pending & CSTP_THROW) {
current_exception = csp->exception;
-
+ }
/*
* If an error was about to be converted to an exception when
* enter_cleanup() was called, let "cause_abort" take the part of
@@ -1871,8 +1920,7 @@ void leave_cleanup(cleanup_T *csp)
}
// Report if required by the 'verbose' option or when debugging.
- report_resume_pending(
- pending, ((pending & CSTP_THROW) ? (void *)current_exception : NULL));
+ report_resume_pending(pending, ((pending & CSTP_THROW) ? (void *)current_exception : NULL));
}
}
@@ -1920,7 +1968,7 @@ int cleanup_conditionals(cstack_T *cstack, int searched_cond, int inclusive)
case CSTP_RETURN:
report_discard_pending(CSTP_RETURN,
- cstack->cs_rettv[idx]);
+ cstack->cs_rettv[idx]);
discard_pending_return(cstack->cs_rettv[idx]);
cstack->cs_pending[idx] = CSTP_NONE;
break;
@@ -1948,15 +1996,17 @@ int cleanup_conditionals(cstack_T *cstack, int searched_cond, int inclusive)
*/
if (!(cstack->cs_flags[idx] & CSF_FINALLY)) {
if ((cstack->cs_flags[idx] & CSF_ACTIVE)
- && (cstack->cs_flags[idx] & CSF_CAUGHT))
+ && (cstack->cs_flags[idx] & CSF_CAUGHT)) {
finish_exception((except_T *)cstack->cs_exception[idx]);
+ }
/* Stop at this try conditional - except the try block never
* got active (because of an inactive surrounding conditional
* or when the ":try" appeared after an error or interrupt or
* throw). */
if (cstack->cs_flags[idx] & CSF_TRUE) {
- if (searched_cond == 0 && !inclusive)
+ if (searched_cond == 0 && !inclusive) {
break;
+ }
stop = TRUE;
}
}
@@ -1967,13 +2017,15 @@ int cleanup_conditionals(cstack_T *cstack, int searched_cond, int inclusive)
* If "inclusive" is TRUE and "searched_cond" is CSF_TRY|CSF_SILENT,
* check first whether "emsg_silent" needs to be restored. */
if (cstack->cs_flags[idx] & searched_cond) {
- if (!inclusive)
+ if (!inclusive) {
break;
+ }
stop = TRUE;
}
cstack->cs_flags[idx] &= ~CSF_ACTIVE;
- if (stop && searched_cond != (CSF_TRY | CSF_SILENT))
+ if (stop && searched_cond != (CSF_TRY | CSF_SILENT)) {
break;
+ }
/*
* When leaving a try conditional that reset "emsg_silent" on its
@@ -1982,7 +2034,7 @@ int cleanup_conditionals(cstack_T *cstack, int searched_cond, int inclusive)
*/
if ((cstack->cs_flags[idx] & CSF_TRY)
&& (cstack->cs_flags[idx] & CSF_SILENT)) {
- eslist_T *elem;
+ eslist_T *elem;
elem = cstack->cs_emsg_silent_list;
cstack->cs_emsg_silent_list = elem->next;
@@ -1990,8 +2042,9 @@ int cleanup_conditionals(cstack_T *cstack, int searched_cond, int inclusive)
xfree(elem);
cstack->cs_flags[idx] &= ~CSF_SILENT;
}
- if (stop)
+ if (stop) {
break;
+ }
}
return idx;
}
@@ -2001,10 +2054,12 @@ int cleanup_conditionals(cstack_T *cstack, int searched_cond, int inclusive)
*/
static char_u *get_end_emsg(cstack_T *cstack)
{
- if (cstack->cs_flags[cstack->cs_idx] & CSF_WHILE)
+ if (cstack->cs_flags[cstack->cs_idx] & CSF_WHILE) {
return e_endwhile;
- if (cstack->cs_flags[cstack->cs_idx] & CSF_FOR)
+ }
+ if (cstack->cs_flags[cstack->cs_idx] & CSF_FOR) {
return e_endfor;
+ }
return e_endif;
}
@@ -2016,14 +2071,15 @@ static char_u *get_end_emsg(cstack_T *cstack)
* type.
* Also free "for info" structures where needed.
*/
-void rewind_conditionals(cstack_T *cstack, int idx, int cond_type,
- int *cond_level)
+void rewind_conditionals(cstack_T *cstack, int idx, int cond_type, int *cond_level)
{
while (cstack->cs_idx > idx) {
- if (cstack->cs_flags[cstack->cs_idx] & cond_type)
+ if (cstack->cs_flags[cstack->cs_idx] & cond_type) {
--*cond_level;
- if (cstack->cs_flags[cstack->cs_idx] & CSF_FOR)
+ }
+ if (cstack->cs_flags[cstack->cs_idx] & CSF_FOR) {
free_for_info(cstack->cs_forinfo[cstack->cs_idx]);
+ }
--cstack->cs_idx;
}
}
@@ -2043,18 +2099,21 @@ int has_loop_cmd(char_u *p)
{
int len;
- /* skip modifiers, white space and ':' */
+ // skip modifiers, white space and ':'
for (;; ) {
- while (*p == ' ' || *p == '\t' || *p == ':')
+ while (*p == ' ' || *p == '\t' || *p == ':') {
++p;
+ }
len = modifier_len(p);
- if (len == 0)
+ if (len == 0) {
break;
+ }
p += len;
}
if ((p[0] == 'w' && p[1] == 'h')
- || (p[0] == 'f' && p[1] == 'o' && p[2] == 'r'))
+ || (p[0] == 'f' && p[1] == 'o' && p[2] == 'r')) {
return TRUE;
+ }
return FALSE;
}
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index f63987136f..a9990df58f 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -6,49 +6,56 @@
*/
#include <assert.h>
+#include <inttypes.h>
#include <stdbool.h>
-#include <string.h>
#include <stdlib.h>
-#include <inttypes.h>
+#include <string.h>
-#include "nvim/assert.h"
-#include "nvim/log.h"
-#include "nvim/vim.h"
-#include "nvim/ascii.h"
+#include "nvim/api/private/helpers.h"
#include "nvim/arabic.h"
-#include "nvim/ex_getln.h"
+#include "nvim/ascii.h"
+#include "nvim/assert.h"
#include "nvim/buffer.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
+#include "nvim/cursor_shape.h"
#include "nvim/digraph.h"
#include "nvim/edit.h"
#include "nvim/eval.h"
#include "nvim/eval/userfunc.h"
+#include "nvim/event/loop.h"
#include "nvim/ex_cmds.h"
#include "nvim/ex_cmds2.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_eval.h"
+#include "nvim/ex_getln.h"
#include "nvim/fileio.h"
#include "nvim/func_attr.h"
+#include "nvim/garray.h"
#include "nvim/getchar.h"
#include "nvim/highlight.h"
+#include "nvim/highlight_defs.h"
#include "nvim/if_cscope.h"
#include "nvim/indent.h"
+#include "nvim/keymap.h"
+#include "nvim/lib/kvec.h"
+#include "nvim/log.h"
+#include "nvim/lua/executor.h"
#include "nvim/main.h"
#include "nvim/mark.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
+#include "nvim/memory.h"
#include "nvim/menu.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/memory.h"
-#include "nvim/cursor_shape.h"
-#include "nvim/keymap.h"
-#include "nvim/garray.h"
-#include "nvim/move.h"
#include "nvim/mouse.h"
+#include "nvim/move.h"
#include "nvim/ops.h"
#include "nvim/option.h"
+#include "nvim/os/input.h"
+#include "nvim/os/os.h"
+#include "nvim/os/time.h"
#include "nvim/os_unix.h"
#include "nvim/path.h"
#include "nvim/popupmnu.h"
@@ -56,22 +63,15 @@
#include "nvim/screen.h"
#include "nvim/search.h"
#include "nvim/sign.h"
-#include "nvim/strings.h"
#include "nvim/state.h"
+#include "nvim/strings.h"
#include "nvim/syntax.h"
#include "nvim/tag.h"
-#include "nvim/window.h"
#include "nvim/ui.h"
-#include "nvim/os/input.h"
-#include "nvim/os/os.h"
-#include "nvim/event/loop.h"
-#include "nvim/os/time.h"
-#include "nvim/lib/kvec.h"
-#include "nvim/api/private/helpers.h"
-#include "nvim/highlight_defs.h"
-#include "nvim/lua/executor.h"
-#include "nvim/viml/parser/parser.h"
+#include "nvim/vim.h"
#include "nvim/viml/parser/expressions.h"
+#include "nvim/viml/parser/parser.h"
+#include "nvim/window.h"
/// Command-line colors: one chunk
///
@@ -110,21 +110,21 @@ typedef enum {
* structure.
*/
struct cmdline_info {
- char_u *cmdbuff; // pointer to command line buffer
+ char_u *cmdbuff; // pointer to command line buffer
int cmdbufflen; // length of cmdbuff
int cmdlen; // number of chars in command line
int cmdpos; // current cursor position
int cmdspos; // cursor column on screen
int cmdfirstc; // ':', '/', '?', '=', '>' or NUL
int cmdindent; // number of spaces before cmdline
- char_u *cmdprompt; // message in front of cmdline
+ char_u *cmdprompt; // message in front of cmdline
int cmdattr; // attributes for prompt
int overstrike; // Typing mode on the command line. Shared by
// getcmdline() and put_on_cmdline().
- expand_T *xpc; // struct being used for expansion, xp_pattern
- // may point into cmdbuff
+ expand_T *xpc; // struct being used for expansion, xp_pattern
+ // may point into cmdbuff
int xp_context; // type of expansion
- char_u *xp_arg; // user-defined expansion arg
+ char_u *xp_arg; // user-defined expansion arg
int input_fn; // when TRUE Invoked for input() function
unsigned prompt_id; ///< Prompt number, used to disable coloring on errors.
Callback highlight_callback; ///< Callback used for coloring user input.
@@ -140,25 +140,25 @@ static unsigned last_prompt_id = 0;
// Struct to store the viewstate during 'incsearch' highlighting.
typedef struct {
- colnr_T vs_curswant;
- colnr_T vs_leftcol;
- linenr_T vs_topline;
- int vs_topfill;
- linenr_T vs_botline;
- int vs_empty_rows;
+ colnr_T vs_curswant;
+ colnr_T vs_leftcol;
+ linenr_T vs_topline;
+ int vs_topfill;
+ linenr_T vs_botline;
+ int vs_empty_rows;
} viewstate_T;
// Struct to store the state of 'incsearch' highlighting.
typedef struct {
- pos_T search_start; // where 'incsearch' starts searching
- pos_T save_cursor;
+ pos_T search_start; // where 'incsearch' starts searching
+ pos_T save_cursor;
viewstate_T init_viewstate;
viewstate_T old_viewstate;
- pos_T match_start;
- pos_T match_end;
- bool did_incsearch;
- bool incsearch_postponed;
- int magic_save;
+ pos_T match_start;
+ pos_T match_end;
+ bool did_incsearch;
+ bool incsearch_postponed;
+ int magic_save;
} incsearch_state_T;
typedef struct command_line_state {
@@ -178,9 +178,9 @@ typedef struct command_line_state {
int did_wild_list; // did wild_list() recently
int wim_index; // index in wim_flags[]
int res;
- int save_msg_scroll;
- int save_State; // remember State when called
- char_u *save_p_icm;
+ int save_msg_scroll;
+ int save_State; // remember State when called
+ char_u *save_p_icm;
int some_key_typed; // one of the keys was typed
// mouse drag and release events are ignored, unless they are
// preceded with a mouse down event
@@ -198,9 +198,9 @@ typedef struct cmdline_info CmdlineInfo;
* TODO: make it local to getcmdline() and pass it around. */
static struct cmdline_info ccline;
-static int cmd_showtail; /* Only show path tail in lists ? */
+static int cmd_showtail; // Only show path tail in lists ?
-static int new_cmdpos; /* position set by set_cmdline_pos() */
+static int new_cmdpos; // position set by set_cmdline_pos()
/// currently displayed block of context
static Array cmdline_block = ARRAY_DICT_INIT;
@@ -210,11 +210,11 @@ static Array cmdline_block = ARRAY_DICT_INIT;
*/
typedef void *(*user_expand_func_T)(const char_u *, int, typval_T *);
-static histentry_T *(history[HIST_COUNT]) = {NULL, NULL, NULL, NULL, NULL};
-static int hisidx[HIST_COUNT] = {-1, -1, -1, -1, -1}; /* lastused entry */
-static int hisnum[HIST_COUNT] = {0, 0, 0, 0, 0};
-/* identifying (unique) number of newest history entry */
-static int hislen = 0; /* actual length of history tables */
+static histentry_T *(history[HIST_COUNT]) = { NULL, NULL, NULL, NULL, NULL };
+static int hisidx[HIST_COUNT] = { -1, -1, -1, -1, -1 }; // lastused entry
+static int hisnum[HIST_COUNT] = { 0, 0, 0, 0, 0 };
+// identifying (unique) number of newest history entry
+static int hislen = 0; // actual length of history tables
/// Flag for command_line_handle_key to ignore <C-c>
///
@@ -275,9 +275,8 @@ static void init_incsearch_state(incsearch_state_T *s)
// Return true when 'incsearch' highlighting is to be done.
// Sets search_first_line and search_last_line to the address range.
-static bool do_incsearch_highlighting(int firstc, int *search_delim,
- incsearch_state_T *s, int *skiplen,
- int *patlen)
+static bool do_incsearch_highlighting(int firstc, int *search_delim, incsearch_state_T *s,
+ int *skiplen, int *patlen)
FUNC_ATTR_NONNULL_ALL
{
char_u *cmd;
@@ -384,7 +383,7 @@ static bool do_incsearch_highlighting(int firstc, int *search_delim,
// Don't do 'hlsearch' highlighting if the pattern matches everything.
if (!use_last_pat) {
char_u c = *end;
- int empty;
+ int empty;
*end = NUL;
empty = empty_pattern(p);
@@ -425,8 +424,7 @@ theend:
}
// May do 'incsearch' highlighting if desired.
-static void may_do_incsearch_highlighting(int firstc, long count,
- incsearch_state_T *s)
+static void may_do_incsearch_highlighting(int firstc, long count, incsearch_state_T *s)
{
pos_T end_pos;
proftime_T tm;
@@ -472,7 +470,7 @@ static void may_do_incsearch_highlighting(int firstc, long count,
// Use the previous pattern for ":s//".
next_char = ccline.cmdbuff[skiplen + patlen];
use_last_pat = patlen == 0 && skiplen > 0
- && ccline.cmdbuff[skiplen - 1] == next_char;
+ && ccline.cmdbuff[skiplen - 1] == next_char;
// If there is no pattern, don't do anything.
if (patlen == 0 && !use_last_pat) {
@@ -624,8 +622,7 @@ static int may_add_char_to_search(int firstc, int *c, incsearch_state_T *s)
return OK;
}
-static void finish_incsearch_highlighting(int gotesc, incsearch_state_T *s,
- bool call_update_screen)
+static void finish_incsearch_highlighting(int gotesc, incsearch_state_T *s, bool call_update_screen)
{
if (s->did_incsearch) {
s->did_incsearch = false;
@@ -872,7 +869,7 @@ static uint8_t *command_line_enter(int firstc, long count, int indent)
&& s->firstc != NUL
&& (s->some_key_typed || s->histype == HIST_SEARCH)) {
add_to_history(s->histype, ccline.cmdbuff, true,
- s->histype == HIST_SEARCH ? s->firstc : NUL);
+ s->histype == HIST_SEARCH ? s->firstc : NUL);
if (s->firstc == ':') {
xfree(new_last_cmdline);
new_last_cmdline = vim_strsave(ccline.cmdbuff);
@@ -973,12 +970,18 @@ static int command_line_execute(VimState *state, int key)
// typed by the user directly, not when the result of a
// mapping.
switch (s->c) {
- case K_RIGHT: s->c = K_LEFT; break;
- case K_S_RIGHT: s->c = K_S_LEFT; break;
- case K_C_RIGHT: s->c = K_C_LEFT; break;
- case K_LEFT: s->c = K_RIGHT; break;
- case K_S_LEFT: s->c = K_S_RIGHT; break;
- case K_C_LEFT: s->c = K_C_RIGHT; break;
+ case K_RIGHT:
+ s->c = K_LEFT; break;
+ case K_S_RIGHT:
+ s->c = K_S_LEFT; break;
+ case K_C_RIGHT:
+ s->c = K_C_LEFT; break;
+ case K_LEFT:
+ s->c = K_RIGHT; break;
+ case K_S_LEFT:
+ s->c = K_S_RIGHT; break;
+ case K_C_LEFT:
+ s->c = K_C_RIGHT; break;
}
}
}
@@ -1078,7 +1081,7 @@ static int command_line_execute(VimState *state, int key)
redrawcmd();
save_p_ls = -1;
wild_menu_showing = 0;
- // don't redraw statusline if WM_LIST is showing
+ // don't redraw statusline if WM_LIST is showing
} else if (wild_menu_showing != WM_LIST) {
win_redraw_last_status(topframe);
wild_menu_showing = 0; // must be before redraw_statuslines #8385
@@ -1155,7 +1158,7 @@ static int command_line_execute(VimState *state, int key)
s->c = (int)p_wc;
KeyTyped = true; // in case the key was mapped
} else if (STRNCMP(s->xpc.xp_pattern, upseg + 1, 3) == 0
- && s->c == K_DOWN) {
+ && s->c == K_DOWN) {
// If in a direct ancestor, strip off one ../ to go down
int found = false;
@@ -1242,7 +1245,7 @@ static int command_line_execute(VimState *state, int key)
vungetc(s->c);
s->c = Ctrl_BSL;
} else if (s->c == 'e') {
- char_u *p = NULL;
+ char_u *p = NULL;
int len;
// Replace the command line with the result of an expression.
@@ -1318,7 +1321,7 @@ static int command_line_execute(VimState *state, int key)
|| s->c == '\r'
|| s->c == K_KENTER
|| (s->c == ESC
- && (!KeyTyped || vim_strchr(p_cpo, CPO_ESC) != NULL))) {
+ && (!KeyTyped || vim_strchr(p_cpo, CPO_ESC) != NULL))) {
// In Ex mode a backslash escapes a newline.
if (exmode_active
&& s->c != ESC
@@ -1419,7 +1422,7 @@ static int command_line_execute(VimState *state, int key)
}
(void)showmatches(&s->xpc, p_wmnu
- && ((wim_flags[s->wim_index] & WIM_LIST) == 0));
+ && ((wim_flags[s->wim_index] & WIM_LIST) == 0));
redrawcmd();
s->did_wild_list = true;
@@ -1464,7 +1467,7 @@ static int command_line_execute(VimState *state, int key)
}
}
- if (s->c == NUL || s->c == K_ZERO) {
+ if (s->c == NUL || s->c == K_ZERO) {
// NUL is stored as NL
s->c = NL;
}
@@ -1476,8 +1479,7 @@ static int command_line_execute(VimState *state, int key)
// May adjust 'incsearch' highlighting for typing CTRL-G and CTRL-T, go to next
// or previous match.
// Returns FAIL when calling command_line_not_changed.
-static int may_do_command_line_next_incsearch(int firstc, long count,
- incsearch_state_T *s,
+static int may_do_command_line_next_incsearch(int firstc, long count, incsearch_state_T *s,
bool next_match)
FUNC_ATTR_NONNULL_ALL
{
@@ -1500,7 +1502,7 @@ static int may_do_command_line_next_incsearch(int firstc, long count,
ui_busy_start();
ui_flush();
- pos_T t;
+ pos_T t;
char_u *pat;
int search_flags = SEARCH_NOOF;
char_u save;
@@ -1656,7 +1658,7 @@ static int command_line_handle_key(CommandLineState *s)
if (s->c == K_DEL) {
ccline.cmdpos += mb_off_next(ccline.cmdbuff,
- ccline.cmdbuff + ccline.cmdpos);
+ ccline.cmdbuff + ccline.cmdpos);
}
if (ccline.cmdpos > 0) {
@@ -1980,8 +1982,9 @@ static int command_line_handle_key(CommandLineState *s)
return command_line_not_changed(s);
case Ctrl_A: // all matches
- if (nextwild(&s->xpc, WILD_ALL, 0, s->firstc != '@') == FAIL)
+ if (nextwild(&s->xpc, WILD_ALL, 0, s->firstc != '@') == FAIL) {
break;
+ }
return command_line_changed(s);
case Ctrl_L:
@@ -1999,7 +2002,7 @@ static int command_line_handle_key(CommandLineState *s)
case Ctrl_P: // previous match
if (s->xpc.xp_numfiles > 0) {
if (nextwild(&s->xpc, (s->c == Ctrl_P) ? WILD_PREV : WILD_NEXT,
- 0, s->firstc != '@') == FAIL) {
+ 0, s->firstc != '@') == FAIL) {
break;
}
return command_line_not_changed(s);
@@ -2033,7 +2036,7 @@ static int command_line_handle_key(CommandLineState *s)
if (s->hiscnt != s->save_hiscnt) {
// jumped to other entry
- char_u *p;
+ char_u *p;
int len = 0;
int old_firstc;
@@ -2251,7 +2254,7 @@ static int command_line_changed(CommandLineState *s)
State |= CMDPREVIEW;
emsg_silent++; // Block error reporting as the command may be incomplete
msg_silent++; // Block messages, namely ones that prompt
- do_cmdline(ccline.cmdbuff, NULL, NULL, DOCMD_KEEPLINE|DOCMD_NOWAIT);
+ do_cmdline(ccline.cmdbuff, NULL, NULL, DOCMD_KEEPLINE|DOCMD_NOWAIT|DOCMD_PREVIEW);
msg_silent--; // Unblock messages
emsg_silent--; // Unblock error reporting
@@ -2261,13 +2264,12 @@ static int command_line_changed(CommandLineState *s)
update_topline(curwin);
redrawcmdline();
-
} else if (State & CMDPREVIEW) {
State = (State & ~CMDPREVIEW);
close_preview_windows();
update_screen(SOME_VALID); // Clear 'inccommand' preview.
} else {
- if (s->xpc.xp_context == EXPAND_NOTHING) {
+ if (s->xpc.xp_context == EXPAND_NOTHING && (KeyTyped || vpeekc() == NUL)) {
may_do_incsearch_highlighting(s->firstc, s->count, &s->is_state);
}
}
@@ -2298,32 +2300,27 @@ static void abandon_cmdline(void)
redraw_cmdline = true;
}
-/*
- * getcmdline() - accept a command line starting with firstc.
- *
- * firstc == ':' get ":" command line.
- * firstc == '/' or '?' get search pattern
- * firstc == '=' get expression
- * firstc == '@' get text for input() function
- * firstc == '>' get text for debug mode
- * firstc == NUL get text for :insert command
- * firstc == -1 like NUL, and break on CTRL-C
- *
- * The line is collected in ccline.cmdbuff, which is reallocated to fit the
- * command line.
- *
- * Careful: getcmdline() can be called recursively!
- *
- * Return pointer to allocated string if there is a commandline, NULL
- * otherwise.
- */
-char_u *
-getcmdline (
- int firstc,
- long count, // only used for incremental search
- int indent, // indent for inside conditionals
- bool do_concat FUNC_ATTR_UNUSED
-)
+/// getcmdline() - accept a command line starting with firstc.
+///
+/// firstc == ':' get ":" command line.
+/// firstc == '/' or '?' get search pattern
+/// firstc == '=' get expression
+/// firstc == '@' get text for input() function
+/// firstc == '>' get text for debug mode
+/// firstc == NUL get text for :insert command
+/// firstc == -1 like NUL, and break on CTRL-C
+///
+/// The line is collected in ccline.cmdbuff, which is reallocated to fit the
+/// command line.
+///
+/// Careful: getcmdline() can be called recursively!
+///
+/// Return pointer to allocated string if there is a commandline, NULL
+/// otherwise.
+///
+/// @param count only used for incremental search
+/// @param indent indent for inside conditionals
+char_u *getcmdline(int firstc, long count, int indent, bool do_concat FUNC_ATTR_UNUSED)
{
// Be prepared for situations where cmdline can be invoked recursively.
// That includes cmd mappings, event handlers, as well as update_screen()
@@ -2348,9 +2345,8 @@ getcmdline (
/// @param[in] highlight_callback Callback used for highlighting user input.
///
/// @return [allocated] Command line or NULL.
-char *getcmdline_prompt(const char firstc, const char *const prompt,
- const int attr, const int xp_context,
- const char *const xp_arg,
+char *getcmdline_prompt(const char firstc, const char *const prompt, const int attr,
+ const int xp_context, const char *const xp_arg,
const Callback highlight_callback)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_MALLOC
{
@@ -2390,8 +2386,9 @@ char *getcmdline_prompt(const char firstc, const char *const prompt,
* another window or buffer. Used when editing the command line etc.
*/
int text_locked(void) {
- if (cmdwin_type != 0)
+ if (cmdwin_type != 0) {
return TRUE;
+ }
return textlock != 0;
}
@@ -2404,7 +2401,7 @@ void text_locked_msg(void)
EMSG(_(get_text_locked_msg()));
}
-char_u * get_text_locked_msg(void) {
+char_u *get_text_locked_msg(void) {
if (cmdwin_type != 0) {
return e_cmdwin;
} else {
@@ -2412,13 +2409,11 @@ char_u * get_text_locked_msg(void) {
}
}
-/*
- * Check if "curbuf_lock" or "allbuf_lock" is set and return TRUE when it is
- * and give an error message.
- */
+/// Check if "curbuf->b_ro_locked" or "allbuf_lock" is set and
+/// return TRUE when it is and give an error message.
int curbuf_locked(void)
{
- if (curbuf_lock > 0) {
+ if (curbuf->b_ro_locked > 0) {
EMSG(_("E788: Not allowed to edit another buffer now"));
return TRUE;
}
@@ -2440,8 +2435,9 @@ int allbuf_locked(void)
static int cmdline_charsize(int idx)
{
- if (cmdline_star > 0) /* showing '*', always 1 position */
+ if (cmdline_star > 0) { // showing '*', always 1 position
return 1;
+ }
return ptr2cells(ccline.cmdbuff + idx);
}
@@ -2461,8 +2457,9 @@ static int cmd_screencol(int bytepos)
int col = cmd_startcol();
if (KeyTyped) {
m = Columns * Rows;
- if (m < 0) /* overflow, Columns or Rows at weird value */
+ if (m < 0) { // overflow, Columns or Rows at weird value
m = MAXCOL;
+ }
} else {
m = MAXCOL;
}
@@ -2494,282 +2491,18 @@ static void correct_screencol(int idx, int cells, int *col)
}
}
-/*
- * Get an Ex command line for the ":" command.
- */
-char_u *
-getexline(
- int c, // normally ':', NUL for ":append"
- void *cookie,
- int indent, // indent for inside conditionals
- bool do_concat
-)
+/// Get an Ex command line for the ":" command.
+///
+/// @param c normally ':', NUL for ":append"
+/// @param indent indent for inside conditionals
+char_u *getexline(int c, void *cookie, int indent, bool do_concat)
{
- /* When executing a register, remove ':' that's in front of each line. */
- if (exec_from_reg && vpeekc() == ':')
+ // When executing a register, remove ':' that's in front of each line.
+ if (exec_from_reg && vpeekc() == ':') {
(void)vgetc();
-
- return getcmdline(c, 1L, indent, do_concat);
-}
-
-/*
- * Get an Ex command line for Ex mode.
- * In Ex mode we only use the OS supplied line editing features and no
- * mappings or abbreviations.
- * Returns a string in allocated memory or NULL.
- */
-char_u *
-getexmodeline(
- int promptc, // normally ':', NUL for ":append" and '?'
- // for :s prompt
- void *cookie,
- int indent, // indent for inside conditionals
- bool do_concat
-)
-{
- garray_T line_ga;
- char_u *pend;
- int startcol = 0;
- int c1 = 0;
- int escaped = FALSE; /* CTRL-V typed */
- int vcol = 0;
- char_u *p;
- int prev_char;
- int len;
-
- /* always start in column 0; write a newline if necessary */
- compute_cmdrow();
- if ((msg_col || msg_didout) && promptc != '?')
- msg_putchar('\n');
- if (promptc == ':') {
- /* indent that is only displayed, not in the line itself */
- if (p_prompt)
- msg_putchar(':');
- while (indent-- > 0)
- msg_putchar(' ');
- startcol = msg_col;
}
- ga_init(&line_ga, 1, 30);
-
- /* autoindent for :insert and :append is in the line itself */
- if (promptc <= 0) {
- vcol = indent;
- while (indent >= 8) {
- ga_append(&line_ga, TAB);
- msg_puts(" ");
- indent -= 8;
- }
- while (indent-- > 0) {
- ga_append(&line_ga, ' ');
- msg_putchar(' ');
- }
- }
- no_mapping++;
-
- /*
- * Get the line, one character at a time.
- */
- got_int = FALSE;
- while (!got_int) {
- ga_grow(&line_ga, 40);
-
- /* Get one character at a time. Don't use inchar(), it can't handle
- * special characters. */
- prev_char = c1;
-
- // Check for a ":normal" command and no more characters left.
- if (ex_normal_busy > 0 && typebuf.tb_len == 0) {
- c1 = '\n';
- } else {
- c1 = vgetc();
- }
-
- /*
- * Handle line editing.
- * Previously this was left to the system, putting the terminal in
- * cooked mode, but then CTRL-D and CTRL-T can't be used properly.
- */
- if (got_int) {
- msg_putchar('\n');
- break;
- }
-
- if (!escaped) {
- /* CR typed means "enter", which is NL */
- if (c1 == '\r')
- c1 = '\n';
-
- if (c1 == BS || c1 == K_BS || c1 == DEL || c1 == K_DEL || c1 == K_KDEL) {
- if (!GA_EMPTY(&line_ga)) {
- p = (char_u *)line_ga.ga_data;
- p[line_ga.ga_len] = NUL;
- len = utf_head_off(p, p + line_ga.ga_len - 1) + 1;
- line_ga.ga_len -= len;
- goto redraw;
- }
- continue;
- }
-
- if (c1 == Ctrl_U) {
- msg_col = startcol;
- msg_clr_eos();
- line_ga.ga_len = 0;
- goto redraw;
- }
-
- int num_spaces;
- if (c1 == Ctrl_T) {
- int sw = get_sw_value(curbuf);
-
- p = (char_u *)line_ga.ga_data;
- p[line_ga.ga_len] = NUL;
- indent = get_indent_str(p, 8, FALSE);
- num_spaces = sw - indent % sw;
-add_indent:
- if (num_spaces > 0) {
- ga_grow(&line_ga, num_spaces + 1);
- p = (char_u *)line_ga.ga_data;
- char_u *s = skipwhite(p);
-
- // Insert spaces after leading whitespaces.
- long move_len = line_ga.ga_len - (s - p) + 1;
- assert(move_len >= 0);
- memmove(s + num_spaces, s, (size_t)move_len);
- memset(s, ' ', (size_t)num_spaces);
-
- line_ga.ga_len += num_spaces;
- }
-redraw:
- /* redraw the line */
- msg_col = startcol;
- vcol = 0;
- p = (char_u *)line_ga.ga_data;
- p[line_ga.ga_len] = NUL;
- while (p < (char_u *)line_ga.ga_data + line_ga.ga_len) {
- if (*p == TAB) {
- do {
- msg_putchar(' ');
- } while (++vcol % 8);
- p++;
- } else {
- len = utfc_ptr2len(p);
- msg_outtrans_len(p, len);
- vcol += ptr2cells(p);
- p += len;
- }
- }
- msg_clr_eos();
- cmd_cursor_goto(msg_row, msg_col);
- continue;
- }
-
- if (c1 == Ctrl_D) {
- /* Delete one shiftwidth. */
- p = (char_u *)line_ga.ga_data;
- if (prev_char == '0' || prev_char == '^') {
- if (prev_char == '^')
- ex_keep_indent = TRUE;
- indent = 0;
- p[--line_ga.ga_len] = NUL;
- } else {
- p[line_ga.ga_len] = NUL;
- indent = get_indent_str(p, 8, FALSE);
- if (indent == 0) {
- continue;
- }
- --indent;
- indent -= indent % get_sw_value(curbuf);
- }
-
- // reduce the line's indentation
- char_u *from = skipwhite(p);
- char_u *to = from;
- int old_indent;
- while ((old_indent = get_indent_str(p, 8, FALSE)) > indent) {
- *--to = NUL;
- }
- long move_len = line_ga.ga_len - (from - p) + 1;
- assert(move_len > 0);
- memmove(to, from, (size_t)move_len);
- line_ga.ga_len -= (int)(from - to);
-
- // Removed to much indentation, fix it before redrawing.
- num_spaces = indent - old_indent;
- goto add_indent;
- }
-
- if (c1 == Ctrl_V || c1 == Ctrl_Q) {
- escaped = TRUE;
- continue;
- }
-
- if (IS_SPECIAL(c1)) {
- // Ignore other special key codes
- continue;
- }
- }
-
- if (IS_SPECIAL(c1)) {
- c1 = '?';
- }
- len = utf_char2bytes(c1, (char_u *)line_ga.ga_data + line_ga.ga_len);
- if (c1 == '\n') {
- msg_putchar('\n');
- } else if (c1 == TAB) {
- // Don't use chartabsize(), 'ts' can be different.
- do {
- msg_putchar(' ');
- } while (++vcol % 8);
- } else {
- msg_outtrans_len(((char_u *)line_ga.ga_data) + line_ga.ga_len, len);
- vcol += char2cells(c1);
- }
- line_ga.ga_len += len;
- escaped = FALSE;
-
- cmd_cursor_goto(msg_row, msg_col);
- pend = (char_u *)(line_ga.ga_data) + line_ga.ga_len;
-
- /* We are done when a NL is entered, but not when it comes after an
- * odd number of backslashes, that results in a NUL. */
- if (!GA_EMPTY(&line_ga) && pend[-1] == '\n') {
- int bcount = 0;
-
- while (line_ga.ga_len - 2 >= bcount && pend[-2 - bcount] == '\\')
- ++bcount;
-
- if (bcount > 0) {
- /* Halve the number of backslashes: "\NL" -> "NUL", "\\NL" ->
- * "\NL", etc. */
- line_ga.ga_len -= (bcount + 1) / 2;
- pend -= (bcount + 1) / 2;
- pend[-1] = '\n';
- }
-
- if ((bcount & 1) == 0) {
- --line_ga.ga_len;
- --pend;
- *pend = NUL;
- break;
- }
- }
- }
-
- no_mapping--;
-
- /* make following messages go to the next line */
- msg_didout = FALSE;
- msg_col = 0;
- if (msg_row < Rows - 1) {
- msg_row++;
- }
- emsg_on_display = false; // don't want os_delay()
-
- if (got_int)
- ga_clear(&line_ga);
-
- return (char_u *)line_ga.ga_data;
+ return getcmdline(c, 1L, indent, do_concat);
}
bool cmdline_overstrike(void)
@@ -2794,10 +2527,11 @@ static void alloc_cmdbuff(int len)
/*
* give some extra space to avoid having to allocate all the time
*/
- if (len < 80)
+ if (len < 80) {
len = 100;
- else
+ } else {
len += 20;
+ }
ccline.cmdbuff = xmalloc((size_t)len);
ccline.cmdbufflen = len;
@@ -2813,7 +2547,7 @@ static void realloc_cmdbuff(int len)
}
char_u *p = ccline.cmdbuff;
- alloc_cmdbuff(len); /* will get some more */
+ alloc_cmdbuff(len); // will get some more
/* There isn't always a NUL after the command, but it may need to be
* there, thus copy up to the NUL and add a NUL. */
memmove(ccline.cmdbuff, p, (size_t)ccline.cmdlen);
@@ -2828,20 +2562,21 @@ static void realloc_cmdbuff(int len)
/* If xp_pattern points inside the old cmdbuff it needs to be adjusted
* to point into the newly allocated memory. */
- if (i >= 0 && i <= ccline.cmdlen)
+ if (i >= 0 && i <= ccline.cmdlen) {
ccline.xpc->xp_pattern = ccline.cmdbuff + i;
+ }
}
}
-static char_u *arshape_buf = NULL;
+static char_u *arshape_buf = NULL;
-# if defined(EXITFREE)
+#if defined(EXITFREE)
void free_arshape_buf(void)
{
xfree(arshape_buf);
}
-# endif
+#endif
enum { MAX_CB_ERRORS = 1 };
@@ -2855,7 +2590,7 @@ static void color_expr_cmdline(const CmdlineInfo *const colored_ccline,
ColoredCmdline *const ret_ccline_colors)
FUNC_ATTR_NONNULL_ALL
{
- ParserLine plines[] = {
+ ParserLine parser_lines[] = {
{
.data = (const char *)colored_ccline->cmdbuff,
.size = STRLEN(colored_ccline->cmdbuff),
@@ -2863,12 +2598,11 @@ static void color_expr_cmdline(const CmdlineInfo *const colored_ccline,
},
{ NULL, 0, false },
};
- ParserLine *plines_p = plines;
+ ParserLine *plines_p = parser_lines;
ParserHighlight colors;
kvi_init(colors);
ParserState pstate;
- viml_parser_init(
- &pstate, parser_simple_get_line, &plines_p, &colors);
+ viml_parser_init(&pstate, parser_simple_get_line, &plines_p, &colors);
ExprAST east = viml_pexpr_parse(&pstate, kExprFlagsDisallowEOC);
viml_pexpr_free_ast(east);
viml_parser_destroy(&pstate);
@@ -2888,9 +2622,9 @@ static void color_expr_cmdline(const CmdlineInfo *const colored_ccline,
const int id = syn_name2id((const char_u *)chunk.group);
const int attr = (id == 0 ? 0 : syn_id2attr(id));
kv_push(ret_ccline_colors->colors, ((CmdlineColorChunk) {
- .start = (int)chunk.start.col,
- .end = (int)chunk.end_col,
- .attr = attr,
+ .start = (int)chunk.start.col,
+ .end = (int)chunk.end_col,
+ .attr = attr,
}));
prev_end = chunk.end_col;
}
@@ -2978,8 +2712,7 @@ static bool color_cmdline(CmdlineInfo *colored_ccline)
color_cb = colored_ccline->highlight_callback;
} else if (colored_ccline->cmdfirstc == ':') {
try_enter(&tstate);
- err_errmsg = N_(
- "E5408: Unable to get g:Nvim_color_cmdline callback: %s");
+ err_errmsg = N_("E5408: Unable to get g:Nvim_color_cmdline callback: %s");
dgc_ret = tv_dict_get_callback(&globvardict, S_LEN("Nvim_color_cmdline"),
&color_cb);
tl_ret = try_leave(&tstate, &err);
@@ -3047,7 +2780,7 @@ static bool color_cmdline(CmdlineInfo *colored_ccline)
}
bool error = false;
const varnumber_T start = (
- tv_get_number_chk(TV_LIST_ITEM_TV(tv_list_first(l)), &error));
+ tv_get_number_chk(TV_LIST_ITEM_TV(tv_list_first(l)), &error));
if (error) {
goto color_cmdline_error;
} else if (!(prev_end <= start && start < colored_ccline->cmdlen)) {
@@ -3067,8 +2800,8 @@ static bool color_cmdline(CmdlineInfo *colored_ccline)
.attr = 0,
}));
}
- const varnumber_T end = tv_get_number_chk(
- TV_LIST_ITEM_TV(TV_LIST_ITEM_NEXT(l, tv_list_first(l))), &error);
+ const varnumber_T end =
+ tv_get_number_chk(TV_LIST_ITEM_TV(TV_LIST_ITEM_NEXT(l, tv_list_first(l))), &error);
if (error) {
goto color_cmdline_error;
} else if (!(start < end && end <= colored_ccline->cmdlen)) {
@@ -3084,8 +2817,7 @@ static bool color_cmdline(CmdlineInfo *colored_ccline)
goto color_cmdline_error;
}
prev_end = end;
- const char *const group = tv_get_string_chk(
- TV_LIST_ITEM_TV(tv_list_last(l)));
+ const char *const group = tv_get_string_chk(TV_LIST_ITEM_TV(tv_list_last(l)));
if (group == NULL) {
goto color_cmdline_error;
}
@@ -3403,8 +3135,8 @@ void putcmdline(char c, int shift)
}
msg_no_more = false;
} else if (ccline.redraw_state != kCmdRedrawAll) {
- ui_call_cmdline_special_char(cchar_to_string((char)(c)), shift,
- ccline.level);
+ ui_call_cmdline_special_char(cchar_to_string((char)(c)), shift,
+ ccline.level);
}
cursorcmd();
ccline.special_char = c;
@@ -3444,15 +3176,16 @@ void put_on_cmdline(char_u *str, int len, int redraw)
int m;
int c;
- if (len < 0)
+ if (len < 0) {
len = (int)STRLEN(str);
+ }
realloc_cmdbuff(ccline.cmdlen + len + 1);
if (!ccline.overstrike) {
memmove(ccline.cmdbuff + ccline.cmdpos + len,
- ccline.cmdbuff + ccline.cmdpos,
- (size_t)(ccline.cmdlen - ccline.cmdpos));
+ ccline.cmdbuff + ccline.cmdpos,
+ (size_t)(ccline.cmdlen - ccline.cmdpos));
ccline.cmdlen += len;
} else {
// Count nr of characters in the new string.
@@ -3494,11 +3227,12 @@ void put_on_cmdline(char_u *str, int len, int redraw)
if (arabic_combine(utf_ptr2char(ccline.cmdbuff + ccline.cmdpos - i), c)) {
ccline.cmdpos -= i;
len += i;
- } else
+ } else {
i = 0;
+ }
}
if (i != 0) {
- /* Also backup the cursor position. */
+ // Also backup the cursor position.
i = ptr2cells(ccline.cmdbuff + ccline.cmdpos);
ccline.cmdspos -= i;
msg_col -= i;
@@ -3514,9 +3248,10 @@ void put_on_cmdline(char_u *str, int len, int redraw)
i = cmdline_row;
cursorcmd();
draw_cmdline(ccline.cmdpos, ccline.cmdlen - ccline.cmdpos);
- /* Avoid clearing the rest of the line too often. */
- if (cmdline_row != i || ccline.overstrike)
+ // Avoid clearing the rest of the line too often.
+ if (cmdline_row != i || ccline.overstrike) {
msg_clr_eos();
+ }
msg_no_more = FALSE;
}
if (KeyTyped) {
@@ -3610,8 +3345,8 @@ void restore_cmdline_alloc(char_u *p)
/// @returns FAIL for failure, OK otherwise
static bool cmdline_paste(int regname, bool literally, bool remcr)
{
- char_u *arg;
- char_u *p;
+ char_u *arg;
+ char_u *p;
bool allocated;
struct cmdline_info save_ccline;
@@ -3626,8 +3361,9 @@ static bool cmdline_paste(int regname, bool literally, bool remcr)
/* A register containing CTRL-R can cause an endless loop. Allow using
* CTRL-C to break the loop. */
line_breakcheck();
- if (got_int)
+ if (got_int) {
return FAIL;
+ }
/* Need to save and restore ccline. And set "textlock" to avoid nasty
@@ -3639,18 +3375,19 @@ static bool cmdline_paste(int regname, bool literally, bool remcr)
restore_cmdline(&save_ccline);
if (i) {
- /* Got the value of a special register in "arg". */
- if (arg == NULL)
+ // Got the value of a special register in "arg".
+ if (arg == NULL) {
return FAIL;
+ }
/* When 'incsearch' is set and CTRL-R CTRL-W used: skip the duplicate
* part of the word. */
p = arg;
if (p_is && regname == Ctrl_W) {
- char_u *w;
+ char_u *w;
int len;
- /* Locate start of last word in the cmd buffer. */
+ // Locate start of last word in the cmd buffer.
for (w = ccline.cmdbuff + ccline.cmdpos; w > ccline.cmdbuff; ) {
len = utf_head_off(ccline.cmdbuff, w - 1) + 1;
if (!vim_iswordc(utf_ptr2char(w - len))) {
@@ -3659,13 +3396,15 @@ static bool cmdline_paste(int regname, bool literally, bool remcr)
w -= len;
}
len = (int)((ccline.cmdbuff + ccline.cmdpos) - w);
- if (p_ic ? STRNICMP(w, arg, len) == 0 : STRNCMP(w, arg, len) == 0)
+ if (p_ic ? STRNICMP(w, arg, len) == 0 : STRNCMP(w, arg, len) == 0) {
p += len;
+ }
}
cmdline_paste_str(p, literally);
- if (allocated)
+ if (allocated) {
xfree(arg);
+ }
return OK;
}
@@ -3682,9 +3421,9 @@ void cmdline_paste_str(char_u *s, int literally)
{
int c, cv;
- if (literally)
+ if (literally) {
put_on_cmdline(s, -1, TRUE);
- else
+ } else {
while (*s != NUL) {
cv = *s;
if (cv == Ctrl_V && s[1]) {
@@ -3698,6 +3437,7 @@ void cmdline_paste_str(char_u *s, int literally)
}
stuffcharReadbuff(c);
}
+ }
}
/// Delete characters on the command line, from "from" to the current position.
@@ -3715,9 +3455,10 @@ static void cmdline_del(int from)
// overwritten.
void redrawcmdline(void)
{
- if (cmd_silent)
+ if (cmd_silent) {
return;
- need_wait_return = FALSE;
+ }
+ need_wait_return = false;
compute_cmdrow();
redrawcmd();
cursorcmd();
@@ -3728,8 +3469,9 @@ static void redrawcmdprompt(void)
{
int i;
- if (cmd_silent)
+ if (cmd_silent) {
return;
+ }
if (ui_has(kUICmdline)) {
ccline.redraw_state = kCmdRedrawAll;
return;
@@ -3756,15 +3498,16 @@ static void redrawcmdprompt(void)
*/
void redrawcmd(void)
{
- if (cmd_silent)
+ if (cmd_silent) {
return;
+ }
if (ui_has(kUICmdline)) {
draw_cmdline(0, ccline.cmdlen);
return;
}
- /* when 'incsearch' is set there may be no command line while redrawing */
+ // when 'incsearch' is set there may be no command line while redrawing
if (ccline.cmdbuff == NULL) {
cmd_cursor_goto(cmdline_row, 0);
msg_clr_eos();
@@ -3776,7 +3519,7 @@ void redrawcmd(void)
msg_start();
redrawcmdprompt();
- /* Don't use more prompt, truncate the cmdline if it doesn't fit. */
+ // Don't use more prompt, truncate the cmdline if it doesn't fit.
msg_no_more = TRUE;
draw_cmdline(0, ccline.cmdlen);
msg_clr_eos();
@@ -3792,7 +3535,7 @@ void redrawcmd(void)
* An emsg() before may have set msg_scroll. This is used in normal mode,
* in cmdline mode we can reset them now.
*/
- msg_scroll = FALSE; /* next message overwrites cmdline */
+ msg_scroll = FALSE; // next message overwrites cmdline
// Typing ':' at the more prompt may set skip_redraw. We don't want this
// in cmdline mode.
@@ -3815,8 +3558,9 @@ void compute_cmdrow(void)
static void cursorcmd(void)
{
- if (cmd_silent)
+ if (cmd_silent) {
return;
+ }
if (ui_has(kUICmdline)) {
if (ccline.redraw_state < kCmdRedrawPos) {
@@ -3904,28 +3648,27 @@ static int sort_func_compare(const void *s1, const void *s2)
char_u *p1 = *(char_u **)s1;
char_u *p2 = *(char_u **)s2;
- if (*p1 != '<' && *p2 == '<') return -1;
- if (*p1 == '<' && *p2 != '<') return 1;
+ if (*p1 != '<' && *p2 == '<') {
+ return -1;
+ }
+ if (*p1 == '<' && *p2 != '<') {
+ return 1;
+ }
return STRCMP(p1, p2);
}
-/*
- * Return FAIL if this is not an appropriate context in which to do
- * completion of anything, return OK if it is (even if there are no matches).
- * For the caller, this means that the character is just passed through like a
- * normal character (instead of being expanded). This allows :s/^I^D etc.
- */
-static int
-nextwild (
- expand_T *xp,
- int type,
- int options, /* extra options for ExpandOne() */
- int escape /* if TRUE, escape the returned matches */
-)
+/// Return FAIL if this is not an appropriate context in which to do
+/// completion of anything, return OK if it is (even if there are no matches).
+/// For the caller, this means that the character is just passed through like a
+/// normal character (instead of being expanded). This allows :s/^I^D etc.
+///
+/// @param options extra options for ExpandOne()
+/// @param escape if TRUE, escape the returned matches
+static int nextwild(expand_T *xp, int type, int options, int escape)
{
int i, j;
- char_u *p1;
- char_u *p2;
+ char_u *p1;
+ char_u *p2;
int difflen;
if (xp->xp_numfiles == -1) {
@@ -3935,10 +3678,10 @@ nextwild (
if (xp->xp_context == EXPAND_UNSUCCESSFUL) {
beep_flush();
- return OK; /* Something illegal on command line */
+ return OK; // Something illegal on command line
}
if (xp->xp_context == EXPAND_NOTHING) {
- /* Caller can use the character as a normal char instead */
+ // Caller can use the character as a normal char instead
return FAIL;
}
@@ -3958,12 +3701,12 @@ nextwild (
// Translate string into pattern and expand it.
p1 = addstar(xp->xp_pattern, xp->xp_pattern_len, xp->xp_context);
const int use_options = (
- options
- | WILD_HOME_REPLACE
- | WILD_ADD_SLASH
- | WILD_SILENT
- | (escape ? WILD_ESCAPE : 0)
- | (p_wic ? WILD_ICASE : 0));
+ options
+ | WILD_HOME_REPLACE
+ | WILD_ADD_SLASH
+ | WILD_SILENT
+ | (escape ? WILD_ESCAPE : 0)
+ | (p_wic ? WILD_ICASE : 0));
p2 = ExpandOne(xp, p1, vim_strnsave(&ccline.cmdbuff[i], xp->xp_pattern_len),
use_options, type);
xfree(p1);
@@ -4008,67 +3751,62 @@ nextwild (
/* When expanding a ":map" command and no matches are found, assume that
* the key is supposed to be inserted literally */
- if (xp->xp_context == EXPAND_MAPPINGS && p2 == NULL)
+ if (xp->xp_context == EXPAND_MAPPINGS && p2 == NULL) {
return FAIL;
+ }
- if (xp->xp_numfiles <= 0 && p2 == NULL)
+ if (xp->xp_numfiles <= 0 && p2 == NULL) {
beep_flush();
- else if (xp->xp_numfiles == 1)
- /* free expanded pattern */
+ } else if (xp->xp_numfiles == 1) {
+ // free expanded pattern
(void)ExpandOne(xp, NULL, NULL, 0, WILD_FREE);
+ }
return OK;
}
-/*
- * Do wildcard expansion on the string 'str'.
- * Chars that should not be expanded must be preceded with a backslash.
- * Return a pointer to allocated memory containing the new string.
- * Return NULL for failure.
- *
- * "orig" is the originally expanded string, copied to allocated memory. It
- * should either be kept in orig_save or freed. When "mode" is WILD_NEXT or
- * WILD_PREV "orig" should be NULL.
- *
- * Results are cached in xp->xp_files and xp->xp_numfiles, except when "mode"
- * is WILD_EXPAND_FREE or WILD_ALL.
- *
- * mode = WILD_FREE: just free previously expanded matches
- * mode = WILD_EXPAND_FREE: normal expansion, do not keep matches
- * mode = WILD_EXPAND_KEEP: normal expansion, keep matches
- * mode = WILD_NEXT: use next match in multiple match, wrap to first
- * mode = WILD_PREV: use previous match in multiple match, wrap to first
- * mode = WILD_ALL: return all matches concatenated
- * mode = WILD_LONGEST: return longest matched part
- * mode = WILD_ALL_KEEP: get all matches, keep matches
- *
- * options = WILD_LIST_NOTFOUND: list entries without a match
- * options = WILD_HOME_REPLACE: do home_replace() for buffer names
- * options = WILD_USE_NL: Use '\n' for WILD_ALL
- * options = WILD_NO_BEEP: Don't beep for multiple matches
- * options = WILD_ADD_SLASH: add a slash after directory names
- * options = WILD_KEEP_ALL: don't remove 'wildignore' entries
- * options = WILD_SILENT: don't print warning messages
- * options = WILD_ESCAPE: put backslash before special chars
- * options = WILD_ICASE: ignore case for files
- *
- * The variables xp->xp_context and xp->xp_backslash must have been set!
- */
-char_u *
-ExpandOne (
- expand_T *xp,
- char_u *str,
- char_u *orig, /* allocated copy of original of expanded string */
- int options,
- int mode
-)
+/// Do wildcard expansion on the string 'str'.
+/// Chars that should not be expanded must be preceded with a backslash.
+/// Return a pointer to allocated memory containing the new string.
+/// Return NULL for failure.
+///
+/// "orig" is the originally expanded string, copied to allocated memory. It
+/// should either be kept in orig_save or freed. When "mode" is WILD_NEXT or
+/// WILD_PREV "orig" should be NULL.
+///
+/// Results are cached in xp->xp_files and xp->xp_numfiles, except when "mode"
+/// is WILD_EXPAND_FREE or WILD_ALL.
+///
+/// mode = WILD_FREE: just free previously expanded matches
+/// mode = WILD_EXPAND_FREE: normal expansion, do not keep matches
+/// mode = WILD_EXPAND_KEEP: normal expansion, keep matches
+/// mode = WILD_NEXT: use next match in multiple match, wrap to first
+/// mode = WILD_PREV: use previous match in multiple match, wrap to first
+/// mode = WILD_ALL: return all matches concatenated
+/// mode = WILD_LONGEST: return longest matched part
+/// mode = WILD_ALL_KEEP: get all matches, keep matches
+///
+/// options = WILD_LIST_NOTFOUND: list entries without a match
+/// options = WILD_HOME_REPLACE: do home_replace() for buffer names
+/// options = WILD_USE_NL: Use '\n' for WILD_ALL
+/// options = WILD_NO_BEEP: Don't beep for multiple matches
+/// options = WILD_ADD_SLASH: add a slash after directory names
+/// options = WILD_KEEP_ALL: don't remove 'wildignore' entries
+/// options = WILD_SILENT: don't print warning messages
+/// options = WILD_ESCAPE: put backslash before special chars
+/// options = WILD_ICASE: ignore case for files
+///
+/// The variables xp->xp_context and xp->xp_backslash must have been set!
+///
+/// @param orig allocated copy of original of expanded string
+char_u *ExpandOne(expand_T *xp, char_u *str, char_u *orig, int options, int mode)
{
- char_u *ss = NULL;
+ char_u *ss = NULL;
static int findex;
- static char_u *orig_save = NULL; /* kept value of orig */
+ static char_u *orig_save = NULL; // kept value of orig
int orig_saved = FALSE;
int i;
- int non_suf_match; /* number without matching suffix */
+ int non_suf_match; // number without matching suffix
/*
* first handle the case of using an old match
@@ -4076,27 +3814,31 @@ ExpandOne (
if (mode == WILD_NEXT || mode == WILD_PREV) {
if (xp->xp_numfiles > 0) {
if (mode == WILD_PREV) {
- if (findex == -1)
+ if (findex == -1) {
findex = xp->xp_numfiles;
+ }
--findex;
- } else /* mode == WILD_NEXT */
+ } else { // mode == WILD_NEXT
++findex;
+ }
/*
* When wrapping around, return the original string, set findex to
* -1.
*/
if (findex < 0) {
- if (orig_save == NULL)
+ if (orig_save == NULL) {
findex = xp->xp_numfiles - 1;
- else
+ } else {
findex = -1;
+ }
}
if (findex >= xp->xp_numfiles) {
- if (orig_save == NULL)
+ if (orig_save == NULL) {
findex = 0;
- else
+ } else {
findex = -1;
+ }
}
if (compl_match_array) {
compl_selected = findex;
@@ -4109,8 +3851,9 @@ ExpandOne (
return vim_strsave(orig_save);
}
return vim_strsave(xp->xp_files[findex]);
- } else
+ } else {
return NULL;
+ }
}
if (mode == WILD_CANCEL) {
@@ -4120,7 +3863,7 @@ ExpandOne (
xp->xp_files[findex]);
}
- /* free old names */
+ // free old names
if (xp->xp_numfiles != -1 && mode != WILD_ALL && mode != WILD_LONGEST) {
FreeWild(xp->xp_numfiles, xp->xp_files);
xp->xp_numfiles = -1;
@@ -4128,8 +3871,9 @@ ExpandOne (
}
findex = 0;
- if (mode == WILD_FREE) /* only release file name */
+ if (mode == WILD_FREE) { // only release file name
return NULL;
+ }
if (xp->xp_numfiles == -1 && mode != WILD_APPLY && mode != WILD_CANCEL) {
xfree(orig_save);
@@ -4140,20 +3884,22 @@ ExpandOne (
* Do the expansion.
*/
if (ExpandFromContext(xp, str, &xp->xp_numfiles, &xp->xp_files,
- options) == FAIL) {
+ options) == FAIL) {
#ifdef FNAME_ILLEGAL
/* Illegal file name has been silently skipped. But when there
* are wildcards, the real problem is that there was no match,
* causing the pattern to be added, which has illegal characters.
*/
- if (!(options & WILD_SILENT) && (options & WILD_LIST_NOTFOUND))
+ if (!(options & WILD_SILENT) && (options & WILD_LIST_NOTFOUND)) {
EMSG2(_(e_nomatch2), str);
+ }
#endif
} else if (xp->xp_numfiles == 0) {
- if (!(options & WILD_SILENT))
+ if (!(options & WILD_SILENT)) {
EMSG2(_(e_nomatch2), str);
+ }
} else {
- /* Escape the matches for use on the command line. */
+ // Escape the matches for use on the command line.
ExpandEscape(xp, str, xp->xp_numfiles, xp->xp_files, options);
/*
@@ -4161,10 +3907,11 @@ ExpandOne (
*/
if (mode != WILD_ALL && mode != WILD_ALL_KEEP
&& mode != WILD_LONGEST) {
- if (xp->xp_numfiles)
+ if (xp->xp_numfiles) {
non_suf_match = xp->xp_numfiles;
- else
+ } else {
non_suf_match = 1;
+ }
if ((xp->xp_context == EXPAND_FILES
|| xp->xp_context == EXPAND_DIRECTORIES)
&& xp->xp_numfiles > 1) {
@@ -4174,9 +3921,11 @@ ExpandOne (
* expand_wildcards, only need to check the first two.
*/
non_suf_match = 0;
- for (i = 0; i < 2; ++i)
- if (match_suffix(xp->xp_files[i]))
+ for (i = 0; i < 2; ++i) {
+ if (match_suffix(xp->xp_files[i])) {
++non_suf_match;
+ }
+ }
}
if (non_suf_match != 1) {
/* Can we ever get here unless it's while expanding
@@ -4184,13 +3933,15 @@ ExpandOne (
* together. Don't really want to wait for this message
* (and possibly have to hit return to continue!).
*/
- if (!(options & WILD_SILENT))
+ if (!(options & WILD_SILENT)) {
EMSG(_(e_toomany));
- else if (!(options & WILD_NO_BEEP))
+ } else if (!(options & WILD_NO_BEEP)) {
beep_flush();
+ }
}
- if (!(non_suf_match != 1 && mode == WILD_EXPAND_FREE))
+ if (!(non_suf_match != 1 && mode == WILD_EXPAND_FREE)) {
ss = vim_strsave(xp->xp_files[0]);
+ }
}
}
}
@@ -4232,23 +3983,27 @@ ExpandOne (
// TODO(philix): use xstpcpy instead of strcat in a loop (ExpandOne)
if (mode == WILD_ALL && xp->xp_numfiles > 0) {
size_t len = 0;
- for (i = 0; i < xp->xp_numfiles; ++i)
+ for (i = 0; i < xp->xp_numfiles; ++i) {
len += STRLEN(xp->xp_files[i]) + 1;
+ }
ss = xmalloc(len);
*ss = NUL;
for (i = 0; i < xp->xp_numfiles; ++i) {
STRCAT(ss, xp->xp_files[i]);
- if (i != xp->xp_numfiles - 1)
+ if (i != xp->xp_numfiles - 1) {
STRCAT(ss, (options & WILD_USE_NL) ? "\n" : " ");
+ }
}
}
- if (mode == WILD_EXPAND_FREE || mode == WILD_ALL)
+ if (mode == WILD_EXPAND_FREE || mode == WILD_ALL) {
ExpandCleanup(xp);
+ }
- /* Free "orig" if it wasn't stored in "orig_save". */
- if (!orig_saved)
+ // Free "orig" if it wasn't stored in "orig_save".
+ if (!orig_saved) {
xfree(orig);
+ }
return ss;
}
@@ -4278,13 +4033,14 @@ void ExpandCleanup(expand_T *xp)
void ExpandEscape(expand_T *xp, char_u *str, int numfiles, char_u **files, int options)
{
int i;
- char_u *p;
+ char_u *p;
/*
* May change home directory back to "~"
*/
- if (options & WILD_HOME_REPLACE)
+ if (options & WILD_HOME_REPLACE) {
tilde_replace(str, numfiles, files);
+ }
if (options & WILD_ESCAPE) {
if (xp->xp_context == EXPAND_FILES
@@ -4297,7 +4053,7 @@ void ExpandEscape(expand_T *xp, char_u *str, int numfiles, char_u **files, int o
* and wildmatch characters, except '~'.
*/
for (i = 0; i < numfiles; ++i) {
- /* for ":set path=" we need to escape spaces twice */
+ // for ":set path=" we need to escape spaces twice
if (xp->xp_backslash == XP_BS_THREE) {
p = vim_strsave_escaped(files[i], (char_u *)" ");
xfree(files[i]);
@@ -4319,15 +4075,17 @@ void ExpandEscape(expand_T *xp, char_u *str, int numfiles, char_u **files, int o
/* If 'str' starts with "\~", replace "~" at start of
* files[i] with "\~". */
- if (str[0] == '\\' && str[1] == '~' && files[i][0] == '~')
+ if (str[0] == '\\' && str[1] == '~' && files[i][0] == '~') {
escape_fname(&files[i]);
+ }
}
xp->xp_backslash = XP_BS_NONE;
/* If the first file starts with a '+' escape it. Otherwise it
* could be seen as "+cmd". */
- if (*files[0] == '+')
+ if (*files[0] == '+') {
escape_fname(&files[0]);
+ }
} else if (xp->xp_context == EXPAND_TAGS) {
/*
* Insert a backslash before characters in a tag name that
@@ -4349,12 +4107,11 @@ void ExpandEscape(expand_T *xp, char_u *str, int numfiles, char_u **files, int o
/// if true then it escapes for a shell command.
///
/// @return [allocated] escaped file name.
-char *vim_strsave_fnameescape(const char *const fname,
- const bool shell FUNC_ATTR_UNUSED)
+char *vim_strsave_fnameescape(const char *const fname, const bool shell FUNC_ATTR_UNUSED)
FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ALL
{
#ifdef BACKSLASH_IN_FILENAME
-#define PATH_ESC_CHARS " \t\n*?[{`%#'\"|!<"
+# define PATH_ESC_CHARS " \t\n*?[{`%#'\"|!<"
char_u buf[sizeof(PATH_ESC_CHARS)];
int j = 0;
@@ -4368,10 +4125,10 @@ char *vim_strsave_fnameescape(const char *const fname,
char *p = (char *)vim_strsave_escaped((const char_u *)fname,
(const char_u *)buf);
#else
-#define PATH_ESC_CHARS ((char_u *)" \t\n*?[{`$\\%#'\"|!<")
-#define SHELL_ESC_CHARS ((char_u *)" \t\n*?[{`$\\%#'\"|!<>();&")
- char *p = (char *)vim_strsave_escaped(
- (const char_u *)fname, (shell ? SHELL_ESC_CHARS : PATH_ESC_CHARS));
+# define PATH_ESC_CHARS ((char_u *)" \t\n*?[{`$\\%#'\"|!<")
+# define SHELL_ESC_CHARS ((char_u *)" \t\n*?[{`$\\%#'\"|!<>();&")
+ char *p =
+ (char *)vim_strsave_escaped((const char_u *)fname, (shell ? SHELL_ESC_CHARS : PATH_ESC_CHARS));
if (shell && csh_like_shell()) {
// For csh and similar shells need to put two backslashes before '!'.
// One is taken by Vim, one by the shell.
@@ -4410,7 +4167,7 @@ static void escape_fname(char_u **pp)
void tilde_replace(char_u *orig_pat, int num_files, char_u **files)
{
int i;
- char_u *p;
+ char_u *p;
if (orig_pat[0] == '~' && vim_ispathsep(orig_pat[1])) {
for (i = 0; i < num_files; ++i) {
@@ -4437,12 +4194,12 @@ static int showmatches(expand_T *xp, int wildmenu)
#define L_SHOWFILE(m) (showtail \
? sm_gettail(files_found[m], false) : files_found[m])
int num_files;
- char_u **files_found;
+ char_u **files_found;
int i, j, k;
int maxlen;
int lines;
int columns;
- char_u *p;
+ char_u *p;
int lastlen;
int attr;
int showtail;
@@ -4450,11 +4207,11 @@ static int showmatches(expand_T *xp, int wildmenu)
if (xp->xp_numfiles == -1) {
set_expand_context(xp);
i = expand_cmdline(xp, ccline.cmdbuff, ccline.cmdpos,
- &num_files, &files_found);
+ &num_files, &files_found);
showtail = expand_showtail(xp);
- if (i != EXPAND_OK)
+ if (i != EXPAND_OK) {
return i;
-
+ }
} else {
num_files = xp->xp_numfiles;
files_found = xp->xp_files;
@@ -4487,13 +4244,13 @@ static int showmatches(expand_T *xp, int wildmenu)
}
if (!wildmenu) {
- msg_didany = FALSE; /* lines_left will be set */
- msg_start(); /* prepare for paging */
+ msg_didany = false; // lines_left will be set
+ msg_start(); // prepare for paging
msg_putchar('\n');
ui_flush();
cmdline_row = msg_row;
- msg_didany = FALSE; /* lines_left will be set again */
- msg_start(); /* prepare for paging */
+ msg_didany = false; // lines_left will be set again
+ msg_start(); // prepare for paging
}
if (got_int) {
@@ -4509,10 +4266,12 @@ static int showmatches(expand_T *xp, int wildmenu)
|| xp->xp_context == EXPAND_BUFFERS)) {
home_replace(NULL, files_found[i], NameBuff, MAXPATHL, TRUE);
j = vim_strsize(NameBuff);
- } else
+ } else {
j = vim_strsize(L_SHOWFILE(i));
- if (j > maxlen)
+ }
+ if (j > maxlen) {
maxlen = j;
+ }
}
if (xp->xp_context == EXPAND_TAGS_LISTFILES) {
@@ -4536,7 +4295,7 @@ static int showmatches(expand_T *xp, int wildmenu)
MSG_PUTS_ATTR(_(" kind file\n"), HL_ATTR(HLF_T));
}
- /* list the files line by line */
+ // list the files line by line
for (i = 0; i < lines; ++i) {
lastlen = 999;
for (k = i; k < num_files; k += lines) {
@@ -4549,12 +4308,13 @@ static int showmatches(expand_T *xp, int wildmenu)
msg_puts_long_attr(p + 2, HL_ATTR(HLF_D));
break;
}
- for (j = maxlen - lastlen; --j >= 0; )
+ for (j = maxlen - lastlen; --j >= 0; ) {
msg_putchar(' ');
+ }
if (xp->xp_context == EXPAND_FILES
|| xp->xp_context == EXPAND_SHELLCMD
|| xp->xp_context == EXPAND_BUFFERS) {
- /* highlight directories */
+ // highlight directories
if (xp->xp_numfiles != -1) {
// Expansion was done before and special characters
// were escaped, need to halve backslashes. Also
@@ -4575,7 +4335,7 @@ static int showmatches(expand_T *xp, int wildmenu)
p = L_SHOWFILE(k);
} else {
home_replace(NULL, files_found[k], NameBuff, MAXPATHL,
- TRUE);
+ TRUE);
p = NameBuff;
}
} else {
@@ -4584,11 +4344,11 @@ static int showmatches(expand_T *xp, int wildmenu)
}
lastlen = msg_outtrans_attr(p, j ? attr : 0);
}
- if (msg_col > 0) { /* when not wrapped around */
+ if (msg_col > 0) { // when not wrapped around
msg_clr_eos();
msg_putchar('\n');
}
- ui_flush(); /* show one line at a time */
+ ui_flush(); // show one line at a time
if (got_int) {
got_int = FALSE;
break;
@@ -4599,11 +4359,12 @@ static int showmatches(expand_T *xp, int wildmenu)
* we redraw the command below the lines that we have just listed
* This is a bit tricky, but it saves a lot of screen updating.
*/
- cmdline_row = msg_row; /* will put it back later */
+ cmdline_row = msg_row; // will put it back later
}
- if (xp->xp_numfiles == -1)
+ if (xp->xp_numfiles == -1) {
FreeWild(num_files, files_found);
+ }
return EXPAND_OK;
}
@@ -4614,8 +4375,8 @@ static int showmatches(expand_T *xp, int wildmenu)
*/
char_u *sm_gettail(char_u *s, bool eager)
{
- char_u *p;
- char_u *t = s;
+ char_u *p;
+ char_u *t = s;
int had_sep = FALSE;
for (p = s; *p != NUL; ) {
@@ -4645,26 +4406,29 @@ char_u *sm_gettail(char_u *s, bool eager)
*/
static int expand_showtail(expand_T *xp)
{
- char_u *s;
- char_u *end;
+ char_u *s;
+ char_u *end;
- /* When not completing file names a "/" may mean something different. */
+ // When not completing file names a "/" may mean something different.
if (xp->xp_context != EXPAND_FILES
&& xp->xp_context != EXPAND_SHELLCMD
- && xp->xp_context != EXPAND_DIRECTORIES)
+ && xp->xp_context != EXPAND_DIRECTORIES) {
return FALSE;
+ }
end = path_tail(xp->xp_pattern);
- if (end == xp->xp_pattern) /* there is no path separator */
+ if (end == xp->xp_pattern) { // there is no path separator
return FALSE;
+ }
for (s = xp->xp_pattern; s < end; s++) {
/* Skip escaped wildcards. Only when the backslash is not a path
* separator, on DOS the '*' "path\*\file" must not be skipped. */
- if (rem_backslash(s))
+ if (rem_backslash(s)) {
++s;
- else if (vim_strchr((char_u *)"*?[", *s) != NULL)
+ } else if (vim_strchr((char_u *)"*?[", *s) != NULL) {
return FALSE;
+ }
}
return TRUE;
}
@@ -4680,10 +4444,10 @@ static int expand_showtail(expand_T *xp)
char_u *addstar(char_u *fname, size_t len, int context)
FUNC_ATTR_NONNULL_RET
{
- char_u *retval;
+ char_u *retval;
size_t i, j;
size_t new_len;
- char_u *tail;
+ char_u *tail;
int ends_in_star;
if (context != EXPAND_FILES
@@ -4711,19 +4475,20 @@ char_u *addstar(char_u *fname, size_t len, int context)
} else {
new_len = len + 2; // +2 for '^' at start, NUL at end
for (i = 0; i < len; i++) {
- if (fname[i] == '*' || fname[i] == '~')
+ if (fname[i] == '*' || fname[i] == '~') {
new_len++; /* '*' needs to be replaced by ".*"
'~' needs to be replaced by "\~" */
-
- /* Buffer names are like file names. "." should be literal */
- if (context == EXPAND_BUFFERS && fname[i] == '.')
- new_len++; /* "." becomes "\." */
-
+ }
+ // Buffer names are like file names. "." should be literal
+ if (context == EXPAND_BUFFERS && fname[i] == '.') {
+ new_len++; // "." becomes "\."
+ }
/* Custom expansion takes care of special things, match
* backslashes literally (perhaps also for other types?) */
if ((context == EXPAND_USER_DEFINED
- || context == EXPAND_USER_LIST) && fname[i] == '\\')
- new_len++; /* '\' becomes "\\" */
+ || context == EXPAND_USER_LIST) && fname[i] == '\\') {
+ new_len++; // '\' becomes "\\"
+ }
}
retval = xmalloc(new_len);
{
@@ -4735,22 +4500,30 @@ char_u *addstar(char_u *fname, size_t len, int context)
if (context != EXPAND_USER_DEFINED
&& context != EXPAND_USER_LIST
&& fname[i] == '\\'
- && ++i == len)
+ && ++i == len) {
break;
+ }
switch (fname[i]) {
- case '*': retval[j++] = '.';
+ case '*':
+ retval[j++] = '.';
break;
- case '~': retval[j++] = '\\';
+ case '~':
+ retval[j++] = '\\';
break;
- case '?': retval[j] = '.';
+ case '?':
+ retval[j] = '.';
continue;
- case '.': if (context == EXPAND_BUFFERS)
+ case '.':
+ if (context == EXPAND_BUFFERS) {
retval[j++] = '\\';
+ }
break;
- case '\\': if (context == EXPAND_USER_DEFINED
- || context == EXPAND_USER_LIST)
+ case '\\':
+ if (context == EXPAND_USER_DEFINED
+ || context == EXPAND_USER_LIST) {
retval[j++] = '\\';
+ }
break;
}
retval[j] = fname[i];
@@ -4783,10 +4556,11 @@ char_u *addstar(char_u *fname, size_t len, int context)
if ((*retval != '~' || tail != retval)
&& !ends_in_star
&& vim_strchr(tail, '$') == NULL
- && vim_strchr(retval, '`') == NULL)
+ && vim_strchr(retval, '`') == NULL) {
retval[len++] = '*';
- else if (len > 0 && retval[len - 1] == '$')
+ } else if (len > 0 && retval[len - 1] == '$') {
--len;
+ }
retval[len] = NUL;
}
return retval;
@@ -4796,66 +4570,62 @@ char_u *addstar(char_u *fname, size_t len, int context)
* Must parse the command line so far to work out what context we are in.
* Completion can then be done based on that context.
* This routine sets the variables:
- * xp->xp_pattern The start of the pattern to be expanded within
- * the command line (ends at the cursor).
- * xp->xp_context The type of thing to expand. Will be one of:
+ * xp->xp_pattern The start of the pattern to be expanded within
+ * the command line (ends at the cursor).
+ * xp->xp_context The type of thing to expand. Will be one of:
*
- * EXPAND_UNSUCCESSFUL Used sometimes when there is something illegal on
- * the command line, like an unknown command. Caller
- * should beep.
- * EXPAND_NOTHING Unrecognised context for completion, use char like
- * a normal char, rather than for completion. eg
- * :s/^I/
- * EXPAND_COMMANDS Cursor is still touching the command, so complete
- * it.
- * EXPAND_BUFFERS Complete file names for :buf and :sbuf commands.
- * EXPAND_FILES After command with EX_XFILE set, or after setting
- * with P_EXPAND set. eg :e ^I, :w>>^I
- * EXPAND_DIRECTORIES In some cases this is used instead of the latter
- * when we know only directories are of interest. eg
- * :set dir=^I
- * EXPAND_SHELLCMD After ":!cmd", ":r !cmd" or ":w !cmd".
- * EXPAND_SETTINGS Complete variable names. eg :set d^I
+ * EXPAND_UNSUCCESSFUL Used sometimes when there is something illegal on
+ * the command line, like an unknown command. Caller
+ * should beep.
+ * EXPAND_NOTHING Unrecognised context for completion, use char like
+ * a normal char, rather than for completion. eg
+ * :s/^I/
+ * EXPAND_COMMANDS Cursor is still touching the command, so complete
+ * it.
+ * EXPAND_BUFFERS Complete file names for :buf and :sbuf commands.
+ * EXPAND_FILES After command with EX_XFILE set, or after setting
+ * with P_EXPAND set. eg :e ^I, :w>>^I
+ * EXPAND_DIRECTORIES In some cases this is used instead of the latter
+ * when we know only directories are of interest. eg
+ * :set dir=^I
+ * EXPAND_SHELLCMD After ":!cmd", ":r !cmd" or ":w !cmd".
+ * EXPAND_SETTINGS Complete variable names. eg :set d^I
* EXPAND_BOOL_SETTINGS Complete boolean variables only, eg :set no^I
- * EXPAND_TAGS Complete tags from the files in p_tags. eg :ta a^I
+ * EXPAND_TAGS Complete tags from the files in p_tags. eg :ta a^I
* EXPAND_TAGS_LISTFILES As above, but list filenames on ^D, after :tselect
- * EXPAND_HELP Complete tags from the file 'helpfile'/tags
- * EXPAND_EVENTS Complete event names
- * EXPAND_SYNTAX Complete :syntax command arguments
- * EXPAND_HIGHLIGHT Complete highlight (syntax) group names
- * EXPAND_AUGROUP Complete autocommand group names
- * EXPAND_USER_VARS Complete user defined variable names, eg :unlet a^I
- * EXPAND_MAPPINGS Complete mapping and abbreviation names,
- * eg :unmap a^I , :cunab x^I
- * EXPAND_FUNCTIONS Complete internal or user defined function names,
- * eg :call sub^I
- * EXPAND_USER_FUNC Complete user defined function names, eg :delf F^I
- * EXPAND_EXPRESSION Complete internal or user defined function/variable
- * names in expressions, eg :while s^I
- * EXPAND_ENV_VARS Complete environment variable names
- * EXPAND_USER Complete user names
+ * EXPAND_HELP Complete tags from the file 'helpfile'/tags
+ * EXPAND_EVENTS Complete event names
+ * EXPAND_SYNTAX Complete :syntax command arguments
+ * EXPAND_HIGHLIGHT Complete highlight (syntax) group names
+ * EXPAND_AUGROUP Complete autocommand group names
+ * EXPAND_USER_VARS Complete user defined variable names, eg :unlet a^I
+ * EXPAND_MAPPINGS Complete mapping and abbreviation names,
+ * eg :unmap a^I , :cunab x^I
+ * EXPAND_FUNCTIONS Complete internal or user defined function names,
+ * eg :call sub^I
+ * EXPAND_USER_FUNC Complete user defined function names, eg :delf F^I
+ * EXPAND_EXPRESSION Complete internal or user defined function/variable
+ * names in expressions, eg :while s^I
+ * EXPAND_ENV_VARS Complete environment variable names
+ * EXPAND_USER Complete user names
*/
static void set_expand_context(expand_T *xp)
{
- /* only expansion for ':', '>' and '=' command-lines */
+ // only expansion for ':', '>' and '=' command-lines
if (ccline.cmdfirstc != ':'
&& ccline.cmdfirstc != '>' && ccline.cmdfirstc != '='
- && !ccline.input_fn
- ) {
+ && !ccline.input_fn) {
xp->xp_context = EXPAND_NOTHING;
return;
}
set_cmd_context(xp, ccline.cmdbuff, ccline.cmdlen, ccline.cmdpos, true);
}
-void
-set_cmd_context (
- expand_T *xp,
- char_u *str, // start of command line
- int len, // length of command line (excl. NUL)
- int col, // position of cursor
- int use_ccline // use ccline for info
-)
+/// @param str start of command line
+/// @param len length of command line (excl. NUL)
+/// @param col position of cursor
+/// @param use_ccline use ccline for info
+void set_cmd_context(expand_T *xp, char_u *str, int len, int col, int use_ccline)
{
char_u old_char = NUL;
@@ -4863,8 +4633,9 @@ set_cmd_context (
* Avoid a UMR warning from Purify, only save the character if it has been
* written before.
*/
- if (col < len)
+ if (col < len) {
old_char = str[col];
+ }
str[col] = NUL;
const char *nextcomm = (const char *)str;
@@ -4889,35 +4660,31 @@ set_cmd_context (
str[col] = old_char;
}
-/*
- * Expand the command line "str" from context "xp".
- * "xp" must have been set by set_cmd_context().
- * xp->xp_pattern points into "str", to where the text that is to be expanded
- * starts.
- * Returns EXPAND_UNSUCCESSFUL when there is something illegal before the
- * cursor.
- * Returns EXPAND_NOTHING when there is nothing to expand, might insert the
- * key that triggered expansion literally.
- * Returns EXPAND_OK otherwise.
- */
-int
-expand_cmdline (
- expand_T *xp,
- char_u *str, /* start of command line */
- int col, /* position of cursor */
- int *matchcount, /* return: nr of matches */
- char_u ***matches /* return: array of pointers to matches */
-)
+/// Expand the command line "str" from context "xp".
+/// "xp" must have been set by set_cmd_context().
+/// xp->xp_pattern points into "str", to where the text that is to be expanded
+/// starts.
+/// Returns EXPAND_UNSUCCESSFUL when there is something illegal before the
+/// cursor.
+/// Returns EXPAND_NOTHING when there is nothing to expand, might insert the
+/// key that triggered expansion literally.
+/// Returns EXPAND_OK otherwise.
+///
+/// @param str start of command line
+/// @param col position of cursor
+/// @param matchcount return: nr of matches
+/// @param matches return: array of pointers to matches
+int expand_cmdline(expand_T *xp, char_u *str, int col, int *matchcount, char_u ***matches)
{
- char_u *file_str = NULL;
+ char_u *file_str = NULL;
int options = WILD_ADD_SLASH|WILD_SILENT;
if (xp->xp_context == EXPAND_UNSUCCESSFUL) {
beep_flush();
- return EXPAND_UNSUCCESSFUL; /* Something illegal on command line */
+ return EXPAND_UNSUCCESSFUL; // Something illegal on command line
}
if (xp->xp_context == EXPAND_NOTHING) {
- /* Caller can use the character as a normal char instead */
+ // Caller can use the character as a normal char instead
return EXPAND_NOTHING;
}
@@ -4926,10 +4693,11 @@ expand_cmdline (
xp->xp_pattern_len = (size_t)((str + col) - xp->xp_pattern);
file_str = addstar(xp->xp_pattern, xp->xp_pattern_len, xp->xp_context);
- if (p_wic)
+ if (p_wic) {
options += WILD_ICASE;
+ }
- /* find all files that match the description */
+ // find all files that match the description
if (ExpandFromContext(xp, file_str, matchcount, matches, options) == FAIL) {
*matchcount = 0;
*matches = NULL;
@@ -4993,31 +4761,28 @@ static void cleanup_help_tags(int num_file, char_u **file)
typedef char_u *(*ExpandFunc)(expand_T *, int);
-/*
- * Do the expansion based on xp->xp_context and "pat".
- */
-static int
-ExpandFromContext (
- expand_T *xp,
- char_u *pat,
- int *num_file,
- char_u ***file,
- int options // WILD_ flags
-)
+/// Do the expansion based on xp->xp_context and "pat".
+///
+/// @param options WILD_ flags
+static int ExpandFromContext(expand_T *xp, char_u *pat, int *num_file, char_u ***file, int options)
{
regmatch_T regmatch;
int ret;
int flags;
- flags = EW_DIR; /* include directories */
- if (options & WILD_LIST_NOTFOUND)
+ flags = EW_DIR; // include directories
+ if (options & WILD_LIST_NOTFOUND) {
flags |= EW_NOTFOUND;
- if (options & WILD_ADD_SLASH)
+ }
+ if (options & WILD_ADD_SLASH) {
flags |= EW_ADDSLASH;
- if (options & WILD_KEEP_ALL)
+ }
+ if (options & WILD_KEEP_ALL) {
flags |= EW_KEEPALL;
- if (options & WILD_SILENT)
+ }
+ if (options & WILD_SILENT) {
flags |= EW_SILENT;
+ }
if (options & WILD_NOERROR) {
flags |= EW_NOERROR;
}
@@ -5038,32 +4803,38 @@ ExpandFromContext (
if (xp->xp_backslash != XP_BS_NONE) {
free_pat = TRUE;
pat = vim_strsave(pat);
- for (i = 0; pat[i]; ++i)
+ for (i = 0; pat[i]; ++i) {
if (pat[i] == '\\') {
if (xp->xp_backslash == XP_BS_THREE
&& pat[i + 1] == '\\'
&& pat[i + 2] == '\\'
- && pat[i + 3] == ' ')
+ && pat[i + 3] == ' ') {
STRMOVE(pat + i, pat + i + 3);
+ }
if (xp->xp_backslash == XP_BS_ONE
- && pat[i + 1] == ' ')
+ && pat[i + 1] == ' ') {
STRMOVE(pat + i, pat + i + 1);
+ }
}
+ }
}
- if (xp->xp_context == EXPAND_FILES)
+ if (xp->xp_context == EXPAND_FILES) {
flags |= EW_FILE;
- else if (xp->xp_context == EXPAND_FILES_IN_PATH)
+ } else if (xp->xp_context == EXPAND_FILES_IN_PATH) {
flags |= (EW_FILE | EW_PATH);
- else
+ } else {
flags = (flags | EW_DIR) & ~EW_FILE;
- if (options & WILD_ICASE)
+ }
+ if (options & WILD_ICASE) {
flags |= EW_ICASE;
+ }
- /* Expand wildcards, supporting %:h and the like. */
+ // Expand wildcards, supporting %:h and the like.
ret = expand_wildcards_eval(&pat, num_file, file, flags);
- if (free_pat)
+ if (free_pat) {
xfree(pat);
+ }
#ifdef BACKSLASH_IN_FILENAME
if (p_csl[0] != NUL && (options & WILD_IGNORE_COMPLETESLASH) == 0) {
for (int i = 0; i < *num_file; i++) {
@@ -5104,8 +4875,9 @@ ExpandFromContext (
ExpandOldSetting(num_file, file);
return OK;
}
- if (xp->xp_context == EXPAND_BUFFERS)
+ if (xp->xp_context == EXPAND_BUFFERS) {
return ExpandBufnames(pat, num_file, file, options);
+ }
if (xp->xp_context == EXPAND_DIFF_BUFFERS) {
return ExpandBufnames(pat, num_file, file, options | BUF_DIFF_FILTER);
}
@@ -5158,20 +4930,21 @@ ExpandFromContext (
}
regmatch.regprog = vim_regcomp(pat, p_magic ? RE_MAGIC : 0);
- if (regmatch.regprog == NULL)
+ if (regmatch.regprog == NULL) {
return FAIL;
+ }
- /* set ignore-case according to p_ic, p_scs and pat */
+ // set ignore-case according to p_ic, p_scs and pat
regmatch.rm_ic = ignorecase(pat);
if (xp->xp_context == EXPAND_SETTINGS
- || xp->xp_context == EXPAND_BOOL_SETTINGS)
+ || xp->xp_context == EXPAND_BOOL_SETTINGS) {
ret = ExpandSettings(xp, &regmatch, num_file, file);
- else if (xp->xp_context == EXPAND_MAPPINGS)
+ } else if (xp->xp_context == EXPAND_MAPPINGS) {
ret = ExpandMappings(&regmatch, num_file, file);
- else if (xp->xp_context == EXPAND_USER_DEFINED)
+ } else if (xp->xp_context == EXPAND_USER_DEFINED) {
ret = ExpandUserDefined(xp, &regmatch, num_file, file);
- else {
+ } else {
static struct expgen {
int context;
ExpandFunc func;
@@ -5217,7 +4990,7 @@ ExpandFromContext (
* right function to do the expansion.
*/
ret = FAIL;
- for (i = 0; i < (int)ARRAY_SIZE(tab); ++i)
+ for (i = 0; i < (int)ARRAY_SIZE(tab); ++i) {
if (xp->xp_context == tab[i].context) {
if (tab[i].ic) {
regmatch.rm_ic = TRUE;
@@ -5227,6 +5000,7 @@ ExpandFromContext (
ret = OK;
break;
}
+ }
}
vim_regfree(regmatch.regprog);
@@ -5235,39 +5009,36 @@ ExpandFromContext (
return ret;
}
-/*
- * Expand a list of names.
- *
- * Generic function for command line completion. It calls a function to
- * obtain strings, one by one. The strings are matched against a regexp
- * program. Matching strings are copied into an array, which is returned.
- */
-static void ExpandGeneric(
- expand_T *xp,
- regmatch_T *regmatch,
- int *num_file,
- char_u ***file,
- CompleteListItemGetter func, /* returns a string from the list */
- int escaped
- )
+/// Expand a list of names.
+///
+/// Generic function for command line completion. It calls a function to
+/// obtain strings, one by one. The strings are matched against a regexp
+/// program. Matching strings are copied into an array, which is returned.
+///
+/// @param func returns a string from the list
+static void ExpandGeneric(expand_T *xp, regmatch_T *regmatch, int *num_file, char_u ***file,
+ CompleteListItemGetter func, int escaped)
{
int i;
size_t count = 0;
- char_u *str;
+ char_u *str;
// count the number of matching names
for (i = 0;; ++i) {
str = (*func)(xp, i);
- if (str == NULL) // end of list
+ if (str == NULL) { // end of list
break;
- if (*str == NUL) // skip empty strings
+ }
+ if (*str == NUL) { // skip empty strings
continue;
+ }
if (vim_regexec(regmatch, str, (colnr_T)0)) {
++count;
}
}
- if (count == 0)
+ if (count == 0) {
return;
+ }
assert(count < INT_MAX);
*num_file = (int)count;
*file = (char_u **)xmalloc(count * sizeof(char_u *));
@@ -5299,16 +5070,17 @@ static void ExpandGeneric(
}
}
- /* Sort the results. Keep menu's in the specified order. */
+ // Sort the results. Keep menu's in the specified order.
if (xp->xp_context != EXPAND_MENUNAMES && xp->xp_context != EXPAND_MENUS) {
if (xp->xp_context == EXPAND_EXPRESSION
|| xp->xp_context == EXPAND_FUNCTIONS
- || xp->xp_context == EXPAND_USER_FUNC)
- /* <SNR> functions should be sorted to the end. */
+ || xp->xp_context == EXPAND_USER_FUNC) {
+ // <SNR> functions should be sorted to the end.
qsort((void *)*file, (size_t)*num_file, sizeof(char_u *),
- sort_func_compare);
- else
+ sort_func_compare);
+ } else {
sort_strings(*file, *num_file);
+ }
}
/* Reset the variables used for special highlight names expansion, so that
@@ -5324,26 +5096,27 @@ static void ExpandGeneric(
/// *file will either be set to NULL or point to
/// allocated memory.
/// @param flagsarg is a combination of EW_* flags.
-static void expand_shellcmd(char_u *filepat, int *num_file, char_u ***file,
- int flagsarg)
+static void expand_shellcmd(char_u *filepat, int *num_file, char_u ***file, int flagsarg)
FUNC_ATTR_NONNULL_ALL
{
- char_u *pat;
+ char_u *pat;
int i;
- char_u *path = NULL;
+ char_u *path = NULL;
garray_T ga;
char_u *buf = xmalloc(MAXPATHL);
size_t l;
- char_u *s, *e;
+ char_u *s, *e;
int flags = flagsarg;
int ret;
bool did_curdir = false;
// for ":set path=" and ":set tags=" halve backslashes for escaped space
pat = vim_strsave(filepat);
- for (i = 0; pat[i]; ++i)
- if (pat[i] == '\\' && pat[i + 1] == ' ')
+ for (i = 0; pat[i]; ++i) {
+ if (pat[i] == '\\' && pat[i + 1] == ' ') {
STRMOVE(pat + i, pat + i + 1);
+ }
+ }
flags |= EW_FILE | EW_EXEC | EW_SHELLCMD;
@@ -5401,7 +5174,7 @@ static void expand_shellcmd(char_u *filepat, int *num_file, char_u ***file,
l = STRLEN(buf);
STRLCPY(buf + l, pat, MAXPATHL - l);
- /* Expand matches in one directory of $PATH. */
+ // Expand matches in one directory of $PATH.
ret = expand_wildcards(1, &buf, num_file, file, flags);
if (ret == OK) {
ga_grow(&ga, *num_file);
@@ -5428,8 +5201,9 @@ static void expand_shellcmd(char_u *filepat, int *num_file, char_u ***file,
xfree(*file);
}
}
- if (*e != NUL)
+ if (*e != NUL) {
++e;
+ }
}
*file = ga.ga_data;
*num_file = ga.ga_len;
@@ -5444,8 +5218,8 @@ static void expand_shellcmd(char_u *filepat, int *num_file, char_u ***file,
/// Call "user_expand_func()" to invoke a user defined Vim script function and
/// return the result (either a string, a List or NULL).
-static void * call_user_expand_func(user_expand_func_T user_expand_func,
- expand_T *xp, int *num_file, char_u ***file)
+static void *call_user_expand_func(user_expand_func_T user_expand_func, expand_T *xp, int *num_file,
+ char_u ***file)
FUNC_ATTR_NONNULL_ALL
{
char_u keep = 0;
@@ -5454,8 +5228,9 @@ static void * call_user_expand_func(user_expand_func_T user_expand_func,
const sctx_T save_current_sctx = current_sctx;
struct cmdline_info save_ccline;
- if (xp->xp_arg == NULL || xp->xp_arg[0] == '\0' || xp->xp_line == NULL)
+ if (xp->xp_arg == NULL || xp->xp_arg[0] == '\0' || xp->xp_line == NULL) {
return NULL;
+ }
*num_file = 0;
*file = NULL;
@@ -5473,7 +5248,7 @@ static void * call_user_expand_func(user_expand_func_T user_expand_func,
args[1].vval.v_string = xp->xp_line;
args[2].vval.v_number = xp->xp_col;
- /* Save the cmdline, we don't know what the function may do. */
+ // Save the cmdline, we don't know what the function may do.
save_ccline = ccline;
ccline.cmdbuff = NULL;
ccline.cmdprompt = NULL;
@@ -5496,11 +5271,11 @@ static void * call_user_expand_func(user_expand_func_T user_expand_func,
*/
static int ExpandUserDefined(expand_T *xp, regmatch_T *regmatch, int *num_file, char_u ***file)
{
- char_u *e;
- garray_T ga;
+ char_u *e;
+ garray_T ga;
- char_u *const retstr = call_user_expand_func(
- (user_expand_func_T)call_func_retstr, xp, num_file, file);
+ char_u *const retstr = call_user_expand_func((user_expand_func_T)call_func_retstr, xp, num_file,
+ file);
if (retstr == NULL) {
return FAIL;
@@ -5509,13 +5284,14 @@ static int ExpandUserDefined(expand_T *xp, regmatch_T *regmatch, int *num_file,
ga_init(&ga, (int)sizeof(char *), 3);
for (char_u *s = retstr; *s != NUL; s = e) {
e = vim_strchr(s, '\n');
- if (e == NULL)
+ if (e == NULL) {
e = s + STRLEN(s);
+ }
const char_u keep = *e;
*e = NUL;
const bool skip = xp->xp_pattern[0]
- && vim_regexec(regmatch, s, (colnr_T)0) == 0;
+ && vim_regexec(regmatch, s, (colnr_T)0) == 0;
*e = keep;
if (!skip) {
GA_APPEND(char_u *, &ga, vim_strnsave(s, (size_t)(e - s)));
@@ -5536,8 +5312,8 @@ static int ExpandUserDefined(expand_T *xp, regmatch_T *regmatch, int *num_file,
*/
static int ExpandUserList(expand_T *xp, int *num_file, char_u ***file)
{
- list_T *const retlist = call_user_expand_func(
- (user_expand_func_T)call_func_retlist, xp, num_file, file);
+ list_T *const retlist = call_user_expand_func((user_expand_func_T)call_func_retlist, xp, num_file,
+ file);
if (retlist == NULL) {
return FAIL;
}
@@ -5551,8 +5327,7 @@ static int ExpandUserList(expand_T *xp, int *num_file, char_u ***file)
continue; // Skip non-string items and empty strings.
}
- GA_APPEND(char *, &ga, xstrdup(
- (const char *)TV_LIST_ITEM_TV(li)->vval.v_string));
+ GA_APPEND(char *, &ga, xstrdup((const char *)TV_LIST_ITEM_TV(li)->vval.v_string));
});
tv_list_unref(retlist);
@@ -5570,8 +5345,7 @@ static int ExpandUserList(expand_T *xp, int *num_file, char_u ***file)
/// 'packpath'/pack/ * /opt/ * /{dirnames}/{pat}.vim
/// When "flags" has DIP_LUA: search also performed for .lua files
/// "dirnames" is an array with one or more directory names.
-static int ExpandRTDir(char_u *pat, int flags, int *num_file, char_u ***file,
- char *dirnames[])
+static int ExpandRTDir(char_u *pat, int flags, int *num_file, char_u ***file, char *dirnames[])
{
*num_file = 0;
*file = NULL;
@@ -5665,8 +5439,9 @@ static int ExpandRTDir(char_u *pat, int flags, int *num_file, char_u ***file,
}
}
- if (GA_EMPTY(&ga))
+ if (GA_EMPTY(&ga)) {
return FAIL;
+ }
/* Sort and remove duplicates which can happen when specifying multiple
* directories in dirnames. */
@@ -5759,7 +5534,7 @@ void globpath(char_u *path, char_u *file, garray_T *ga, int expand_options)
/*********************************
-* Command line history stuff *
+* Command line history stuff *
*********************************/
/// Translate a history character to the associated type number
@@ -5767,26 +5542,20 @@ static HistoryType hist_char2type(const int c)
FUNC_ATTR_CONST FUNC_ATTR_WARN_UNUSED_RESULT
{
switch (c) {
- case ':': {
- return HIST_CMD;
- }
- case '=': {
- return HIST_EXPR;
- }
- case '@': {
- return HIST_INPUT;
- }
- case '>': {
- return HIST_DEBUG;
- }
- case NUL:
- case '/':
- case '?': {
- return HIST_SEARCH;
- }
- default: {
- return HIST_INVALID;
- }
+ case ':':
+ return HIST_CMD;
+ case '=':
+ return HIST_EXPR;
+ case '@':
+ return HIST_INPUT;
+ case '>':
+ return HIST_DEBUG;
+ case NUL:
+ case '/':
+ case '?':
+ return HIST_SEARCH;
+ default:
+ return HIST_INVALID;
}
// Silence -Wreturn-type
return 0;
@@ -5823,10 +5592,12 @@ static char_u *get_history_arg(expand_T *xp, int idx)
compl[0] = (char_u)short_names[idx];
return compl;
}
- if (idx < short_names_count + history_name_count)
+ if (idx < short_names_count + history_name_count) {
return (char_u *)history_names[idx - short_names_count];
- if (idx == short_names_count + history_name_count)
+ }
+ if (idx == short_names_count + history_name_count) {
return (char_u *)"all";
+ }
return NULL;
}
@@ -5904,49 +5675,48 @@ static inline void clear_hist_entry(histentry_T *hisptr)
memset(hisptr, 0, sizeof(*hisptr));
}
-/*
- * Check if command line 'str' is already in history.
- * If 'move_to_front' is TRUE, matching entry is moved to end of history.
- */
-static int
-in_history (
- int type,
- char_u *str,
- int move_to_front, // Move the entry to the front if it exists
- int sep
-)
+/// Check if command line 'str' is already in history.
+/// If 'move_to_front' is TRUE, matching entry is moved to end of history.
+///
+/// @param move_to_front Move the entry to the front if it exists
+static int in_history(int type, char_u *str, int move_to_front, int sep)
{
int i;
int last_i = -1;
- char_u *p;
+ char_u *p;
- if (hisidx[type] < 0)
+ if (hisidx[type] < 0) {
return FALSE;
+ }
i = hisidx[type];
do {
- if (history[type][i].hisstr == NULL)
+ if (history[type][i].hisstr == NULL) {
return FALSE;
+ }
/* For search history, check that the separator character matches as
* well. */
p = history[type][i].hisstr;
if (STRCMP(str, p) == 0
&& (type != HIST_SEARCH || sep == p[STRLEN(p) + 1])) {
- if (!move_to_front)
+ if (!move_to_front) {
return TRUE;
+ }
last_i = i;
break;
}
- if (--i < 0)
+ if (--i < 0) {
i = hislen - 1;
+ }
} while (i != hisidx[type]);
if (last_i >= 0) {
list_T *const list = history[type][i].additional_elements;
str = history[type][i].hisstr;
while (i != hisidx[type]) {
- if (++i >= hislen)
+ if (++i >= hislen) {
i = 0;
+ }
history[type][last_i] = history[type][i];
last_i = i;
}
@@ -5972,8 +5742,7 @@ in_history (
///
/// @return Any value from HistoryType enum, including HIST_INVALID. May not
/// return HIST_DEFAULT unless return_default is true.
-HistoryType get_histtype(const char *const name, const size_t len,
- const bool return_default)
+HistoryType get_histtype(const char *const name, const size_t len, const bool return_default)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
// No argument: use current history.
@@ -5994,20 +5763,15 @@ HistoryType get_histtype(const char *const name, const size_t len,
return HIST_INVALID;
}
-static int last_maptick = -1; /* last seen maptick */
+static int last_maptick = -1; // last seen maptick
-/*
- * Add the given string to the given history. If the string is already in the
- * history then it is moved to the front. "histype" may be one of he HIST_
- * values.
- */
-void
-add_to_history (
- int histype,
- char_u *new_entry,
- int in_map, /* consider maptick when inside a mapping */
- int sep /* separator character used (search hist) */
-)
+/// Add the given string to the given history. If the string is already in the
+/// history then it is moved to the front. "histype" may be one of he HIST_
+/// values.
+///
+/// @parma in_map consider maptick when inside a mapping
+/// @param sep separator character used (search hist)
+void add_to_history(int histype, char_u *new_entry, int in_map, int sep)
{
histentry_T *hisptr;
@@ -6016,8 +5780,9 @@ add_to_history (
}
assert(histype != HIST_DEFAULT);
- if (cmdmod.keeppatterns && histype == HIST_SEARCH)
+ if (cmdmod.keeppatterns && histype == HIST_SEARCH) {
return;
+ }
/*
* Searches inside the same mapping overwrite each other, so that only
@@ -6030,14 +5795,16 @@ add_to_history (
hisptr = &history[HIST_SEARCH][hisidx[HIST_SEARCH]];
hist_free_entry(hisptr);
--hisnum[histype];
- if (--hisidx[HIST_SEARCH] < 0)
+ if (--hisidx[HIST_SEARCH] < 0) {
hisidx[HIST_SEARCH] = hislen - 1;
+ }
}
last_maptick = -1;
}
if (!in_history(histype, new_entry, true, sep)) {
- if (++hisidx[histype] == hislen)
+ if (++hisidx[histype] == hislen) {
hisidx[histype] = 0;
+ }
hisptr = &history[histype][hisidx[histype]];
hist_free_entry(hisptr);
@@ -6049,8 +5816,9 @@ add_to_history (
hisptr->hisstr[len + 1] = (char_u)sep;
hisptr->hisnum = ++hisnum[histype];
- if (histype == HIST_SEARCH && in_map)
+ if (histype == HIST_SEARCH && in_map) {
last_maptick = maptick;
+ }
}
}
@@ -6062,8 +5830,9 @@ add_to_history (
int get_history_idx(int histype)
{
if (hislen == 0 || histype < 0 || histype >= HIST_COUNT
- || hisidx[histype] < 0)
+ || hisidx[histype] < 0) {
return -1;
+ }
return history[histype][hisidx[histype]].hisnum;
}
@@ -6098,8 +5867,9 @@ char_u *get_cmdline_str(void)
}
struct cmdline_info *p = get_ccline_ptr();
- if (p == NULL)
+ if (p == NULL) {
return NULL;
+ }
return vim_strnsave(p->cmdbuff, (size_t)p->cmdlen);
}
@@ -6113,8 +5883,9 @@ int get_cmdline_pos(void)
{
struct cmdline_info *p = get_ccline_ptr();
- if (p == NULL)
+ if (p == NULL) {
return -1;
+ }
return p->cmdpos;
}
@@ -6127,15 +5898,17 @@ int set_cmdline_pos(int pos)
{
struct cmdline_info *p = get_ccline_ptr();
- if (p == NULL)
+ if (p == NULL) {
return 1;
+ }
/* The position is not set directly but after CTRL-\ e or CTRL-R = has
* changed the command line. */
- if (pos < 0)
+ if (pos < 0) {
new_cmdpos = 0;
- else
+ } else {
new_cmdpos = pos;
+ }
return 0;
}
@@ -6149,10 +5922,12 @@ int get_cmdline_type(void)
{
struct cmdline_info *p = get_ccline_ptr();
- if (p == NULL)
+ if (p == NULL) {
return NUL;
- if (p->cmdfirstc == NUL)
+ }
+ if (p->cmdfirstc == NUL) {
return (p->input_fn) ? '@' : '-';
+ }
return p->cmdfirstc;
}
@@ -6169,26 +5944,32 @@ static int calc_hist_idx(int histype, int num)
int wrapped = FALSE;
if (hislen == 0 || histype < 0 || histype >= HIST_COUNT
- || (i = hisidx[histype]) < 0 || num == 0)
+ || (i = hisidx[histype]) < 0 || num == 0) {
return -1;
+ }
hist = history[histype];
if (num > 0) {
- while (hist[i].hisnum > num)
+ while (hist[i].hisnum > num) {
if (--i < 0) {
- if (wrapped)
+ if (wrapped) {
break;
+ }
i += hislen;
wrapped = TRUE;
}
- if (hist[i].hisnum == num && hist[i].hisstr != NULL)
+ }
+ if (hist[i].hisnum == num && hist[i].hisstr != NULL) {
return i;
- } else if (-num <= hislen) {
+ }
+ } else if (-num <= hislen) {
i += num + 1;
- if (i < 0)
+ if (i < 0) {
i += hislen;
- if (hist[i].hisstr != NULL)
+ }
+ if (hist[i].hisstr != NULL) {
return i;
+ }
}
return -1;
}
@@ -6200,10 +5981,11 @@ static int calc_hist_idx(int histype, int num)
char_u *get_history_entry(int histype, int idx)
{
idx = calc_hist_idx(histype, idx);
- if (idx >= 0)
+ if (idx >= 0) {
return history[histype][idx].hisstr;
- else
+ } else {
return (char_u *)"";
+ }
}
/// Clear all entries in a history
@@ -6240,7 +6022,7 @@ int del_history_entry(int histype, char_u *str)
bool found = false;
regmatch.regprog = NULL;
- regmatch.rm_ic = FALSE; /* always match case */
+ regmatch.rm_ic = FALSE; // always match case
if (hislen != 0
&& histype >= 0
&& histype < HIST_COUNT
@@ -6251,8 +6033,9 @@ int del_history_entry(int histype, char_u *str)
i = last = idx;
do {
hisptr = &history[histype][i];
- if (hisptr->hisstr == NULL)
+ if (hisptr->hisstr == NULL) {
break;
+ }
if (vim_regexec(&regmatch, hisptr->hisstr, (colnr_T)0)) {
found = true;
hist_free_entry(hisptr);
@@ -6261,14 +6044,17 @@ int del_history_entry(int histype, char_u *str)
history[histype][last] = *hisptr;
clear_hist_entry(hisptr);
}
- if (--last < 0)
+ if (--last < 0) {
last += hislen;
+ }
}
- if (--i < 0)
+ if (--i < 0) {
i += hislen;
+ }
} while (i != idx);
- if (history[histype][idx].hisstr == NULL)
+ if (history[histype][idx].hisstr == NULL) {
hisidx[histype] = -1;
+ }
}
vim_regfree(regmatch.regprog);
return found;
@@ -6283,16 +6069,18 @@ int del_history_idx(int histype, int idx)
int i, j;
i = calc_hist_idx(histype, idx);
- if (i < 0)
+ if (i < 0) {
return FALSE;
+ }
idx = hisidx[histype];
hist_free_entry(&history[histype][i]);
/* When deleting the last added search string in a mapping, reset
* last_maptick, so that the last added search string isn't deleted again.
*/
- if (histype == HIST_SEARCH && maptick == last_maptick && i == idx)
+ if (histype == HIST_SEARCH && maptick == last_maptick && i == idx) {
last_maptick = -1;
+ }
while (i != idx) {
j = (i + 1) % hislen;
@@ -6323,7 +6111,7 @@ int get_list_range(char_u **str, int *num1, int *num2)
*str = skipwhite(*str);
if (**str == '-' || ascii_isdigit(**str)) { // parse "from" part of range
- vim_str2nr(*str, NULL, &len, 0, &num, NULL, 0);
+ vim_str2nr(*str, NULL, &len, 0, &num, NULL, 0, false);
*str += len;
*num1 = (int)num;
first = true;
@@ -6331,7 +6119,7 @@ int get_list_range(char_u **str, int *num1, int *num2)
*str = skipwhite(*str);
if (**str == ',') { // parse "to" part of range
*str = skipwhite(*str + 1);
- vim_str2nr(*str, NULL, &len, 0, &num, NULL, 0);
+ vim_str2nr(*str, NULL, &len, 0, &num, NULL, 0, false);
if (len > 0) {
*num2 = (int)num;
*str = skipwhite(*str + len);
@@ -6356,8 +6144,8 @@ void ex_history(exarg_T *eap)
int hisidx2 = -1;
int idx;
int i, j, k;
- char_u *end;
- char_u *arg = eap->arg;
+ char_u *end;
+ char_u *arg = eap->arg;
if (hislen == 0) {
MSG(_("'history' option is zero"));
@@ -6367,8 +6155,9 @@ void ex_history(exarg_T *eap)
if (!(ascii_isdigit(*arg) || *arg == '-' || *arg == ',')) {
end = arg;
while (ASCII_ISALPHA(*end)
- || vim_strchr((char_u *)":=@>/?", *end) != NULL)
+ || vim_strchr((char_u *)":=@>/?", *end) != NULL) {
end++;
+ }
histype1 = get_histtype((const char *)arg, (size_t)(end - arg), false);
if (histype1 == HIST_INVALID) {
if (STRNICMP(arg, "all", end - arg) == 0) {
@@ -6378,8 +6167,9 @@ void ex_history(exarg_T *eap)
EMSG(_(e_trailing));
return;
}
- } else
+ } else {
histype2 = histype1;
+ }
} else {
end = arg;
}
@@ -6397,14 +6187,17 @@ void ex_history(exarg_T *eap)
hist = history[histype1];
j = hisidx1;
k = hisidx2;
- if (j < 0)
+ if (j < 0) {
j = (-j > hislen) ? 0 : hist[(hislen+j+idx+1) % hislen].hisnum;
- if (k < 0)
+ }
+ if (k < 0) {
k = (-k > hislen) ? 0 : hist[(hislen+k+idx+1) % hislen].hisnum;
- if (idx >= 0 && j <= k)
+ }
+ if (idx >= 0 && j <= k) {
for (i = idx + 1; !got_int; ++i) {
- if (i == hislen)
+ if (i == hislen) {
i = 0;
+ }
if (hist[i].hisstr != NULL
&& hist[i].hisnum >= j && hist[i].hisnum <= k) {
msg_putchar('\n');
@@ -6419,9 +6212,11 @@ void ex_history(exarg_T *eap)
msg_outtrans(IObuff);
ui_flush();
}
- if (i == idx)
+ if (i == idx) {
break;
+ }
}
+ }
}
}
@@ -6430,24 +6225,18 @@ int hist_type2char(int type)
FUNC_ATTR_CONST
{
switch (type) {
- case HIST_CMD: {
- return ':';
- }
- case HIST_SEARCH: {
- return '/';
- }
- case HIST_EXPR: {
- return '=';
- }
- case HIST_INPUT: {
- return '@';
- }
- case HIST_DEBUG: {
- return '>';
- }
- default: {
- abort();
- }
+ case HIST_CMD:
+ return ':';
+ case HIST_SEARCH:
+ return '/';
+ case HIST_EXPR:
+ return '=';
+ case HIST_INPUT:
+ return '@';
+ case HIST_DEBUG:
+ return '>';
+ default:
+ abort();
}
return NUL;
}
@@ -6461,23 +6250,22 @@ int hist_type2char(int type)
static int open_cmdwin(void)
{
struct cmdline_info save_ccline;
- bufref_T old_curbuf;
- bufref_T bufref;
- win_T *old_curwin = curwin;
- win_T *wp;
+ bufref_T old_curbuf;
+ bufref_T bufref;
+ win_T *old_curwin = curwin;
+ win_T *wp;
int i;
linenr_T lnum;
garray_T winsizes;
char_u typestr[2];
int save_restart_edit = restart_edit;
int save_State = State;
- int save_exmode = exmode_active;
+ bool save_exmode = exmode_active;
int save_cmdmsg_rl = cmdmsg_rl;
- /* Can't do this recursively. Can't do it when typing a password. */
+ // Can't do this recursively. Can't do it when typing a password.
if (cmdwin_type != 0
- || cmdline_star > 0
- ) {
+ || cmdline_star > 0) {
beep_flush();
return K_IGNORE;
}
@@ -6513,7 +6301,7 @@ static int open_cmdwin(void)
curwin->w_p_fen = false;
// Don't allow switching to another buffer.
- curbuf_lock++;
+ curbuf->b_ro_locked++;
// Showing the prompt may have set need_wait_return, reset it.
need_wait_return = false;
@@ -6521,12 +6309,12 @@ static int open_cmdwin(void)
const int histtype = hist_char2type(cmdwin_type);
if (histtype == HIST_CMD || histtype == HIST_DEBUG) {
if (p_wc == TAB) {
- add_map((char_u *)"<buffer> <Tab> <C-X><C-V>", INSERT);
- add_map((char_u *)"<buffer> <Tab> a<C-X><C-V>", NORMAL);
+ add_map((char_u *)"<buffer> <Tab> <C-X><C-V>", INSERT, false);
+ add_map((char_u *)"<buffer> <Tab> a<C-X><C-V>", NORMAL, false);
}
set_option_value("ft", 0L, "vim", OPT_LOCAL);
}
- curbuf_lock--;
+ curbuf->b_ro_locked--;
// Reset 'textwidth' after setting 'filetype' (the Vim filetype plugin
// sets 'textwidth' to 78).
@@ -6539,8 +6327,9 @@ static int open_cmdwin(void)
if (i >= 0) {
lnum = 0;
do {
- if (++i == hislen)
+ if (++i == hislen) {
i = 0;
+ }
if (history[histtype][i].hisstr != NULL) {
ml_append(lnum++, history[histtype][i].hisstr, (colnr_T)0, false);
}
@@ -6565,7 +6354,7 @@ static int open_cmdwin(void)
save_cmdline(&save_ccline);
// No Ex mode here!
- exmode_active = 0;
+ exmode_active = false;
State = NORMAL;
setmouse();
@@ -6614,10 +6403,11 @@ static int open_cmdwin(void)
cmdwin_result = Ctrl_C;
EMSG(_("E199: Active window or buffer deleted"));
} else {
- /* autocmds may abort script processing */
- if (aborting() && cmdwin_result != K_IGNORE)
+ // autocmds may abort script processing
+ if (aborting() && cmdwin_result != K_IGNORE) {
cmdwin_result = Ctrl_C;
- /* Set the new command line from the cmdline buffer. */
+ }
+ // Set the new command line from the cmdline buffer.
xfree(ccline.cmdbuff);
if (cmdwin_result == K_XF1 || cmdwin_result == K_XF2) { // :qa[!] typed
const char *p = (cmdwin_result == K_XF2) ? "qa" : "qa!";
@@ -6637,8 +6427,9 @@ static int open_cmdwin(void)
/* :q or :close, don't execute any command
* and don't modify the cmd window. */
ccline.cmdbuff = NULL;
- } else
+ } else {
ccline.cmdbuff = vim_strsave(get_cursor_line_ptr());
+ }
if (ccline.cmdbuff == NULL) {
ccline.cmdbuff = vim_strsave((char_u *)"");
ccline.cmdlen = 0;
@@ -6649,8 +6440,9 @@ static int open_cmdwin(void)
ccline.cmdlen = (int)STRLEN(ccline.cmdbuff);
ccline.cmdbufflen = ccline.cmdlen + 1;
ccline.cmdpos = curwin->w_cursor.col;
- if (ccline.cmdpos > ccline.cmdlen)
+ if (ccline.cmdpos > ccline.cmdlen) {
ccline.cmdpos = ccline.cmdlen;
+ }
if (cmdwin_result == K_IGNORE) {
ccline.cmdspos = cmd_screencol(ccline.cmdpos);
redrawcmd();
@@ -6716,13 +6508,12 @@ char *script_get(exarg_T *const eap, size_t *const lenp)
}
const char *const end_pattern = (
- cmd[2] != NUL
+ cmd[2] != NUL
? (const char *)skipwhite((const char_u *)cmd + 2)
: ".");
for (;;) {
- char *const theline = (char *)eap->getline(
- eap->cstack->cs_looplevel > 0 ? -1 :
- NUL, eap->cookie, 0, true);
+ char *const theline = (char *)eap->getline(eap->cstack->cs_looplevel > 0 ? -1 :
+ NUL, eap->cookie, 0, true);
if (theline == NULL || strcmp(end_pattern, theline) == 0) {
xfree(theline);
@@ -6764,8 +6555,8 @@ char *script_get(exarg_T *const eap, size_t *const lenp)
///
/// @return Pointer used in next iteration or NULL to indicate that iteration
/// was finished.
-const void *hist_iter(const void *const iter, const uint8_t history_type,
- const bool zero, histentry_T *const hist)
+const void *hist_iter(const void *const iter, const uint8_t history_type, const bool zero,
+ histentry_T *const hist)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ARG(4)
{
*hist = (histentry_T) {
@@ -6776,7 +6567,7 @@ const void *hist_iter(const void *const iter, const uint8_t history_type,
}
histentry_T *const hstart = &(history[history_type][0]);
histentry_T *const hlast = (
- &(history[history_type][hisidx[history_type]]));
+ &(history[history_type][hisidx[history_type]]));
const histentry_T *const hend = &(history[history_type][hislen - 1]);
histentry_T *hiter;
if (iter == NULL) {
@@ -6792,7 +6583,7 @@ const void *hist_iter(const void *const iter, const uint8_t history_type,
} while (hfirst != hlast);
hiter = hfirst;
} else {
- hiter = (histentry_T *) iter;
+ hiter = (histentry_T *)iter;
}
if (hiter == NULL) {
return NULL;
@@ -6805,7 +6596,7 @@ const void *hist_iter(const void *const iter, const uint8_t history_type,
return NULL;
}
hiter++;
- return (const void *) ((hiter > hend) ? hstart : hiter);
+ return (const void *)((hiter > hend) ? hstart : hiter);
}
/// Get array of history items
diff --git a/src/nvim/ex_session.c b/src/nvim/ex_session.c
index 67b8e7e92f..4aadd77d45 100644
--- a/src/nvim/ex_session.c
+++ b/src/nvim/ex_session.c
@@ -8,13 +8,11 @@
// :mksession
#include <assert.h>
-#include <string.h>
+#include <inttypes.h>
#include <stdbool.h>
#include <stdlib.h>
-#include <inttypes.h>
+#include <string.h>
-#include "nvim/vim.h"
-#include "nvim/globals.h"
#include "nvim/ascii.h"
#include "nvim/buffer.h"
#include "nvim/cursor.h"
@@ -28,6 +26,7 @@
#include "nvim/fileio.h"
#include "nvim/fold.h"
#include "nvim/getchar.h"
+#include "nvim/globals.h"
#include "nvim/keymap.h"
#include "nvim/misc1.h"
#include "nvim/move.h"
@@ -36,6 +35,7 @@
#include "nvim/os/os.h"
#include "nvim/os/time.h"
#include "nvim/path.h"
+#include "nvim/vim.h"
#include "nvim/window.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -63,7 +63,7 @@ static int put_view_curpos(FILE *fd, const win_T *wp, char *spaces)
static int ses_winsizes(FILE *fd, int restore_size, win_T *tab_firstwin)
{
int n = 0;
- win_T *wp;
+ win_T *wp;
if (restore_size && (ssop_flags & SSOP_WINSIZE)) {
for (wp = tab_firstwin; wp != NULL; wp = wp->w_next) {
@@ -105,7 +105,7 @@ static int ses_winsizes(FILE *fd, int restore_size, win_T *tab_firstwin)
// Returns FAIL when writing the commands to "fd" fails.
static int ses_win_rec(FILE *fd, frame_T *fr)
{
- frame_T *frc;
+ frame_T *frc;
int count = 0;
if (fr->fr_layout != FR_LEAF) {
@@ -149,7 +149,7 @@ static int ses_win_rec(FILE *fd, frame_T *fr)
// Returns NULL when there none.
static frame_T *ses_skipframe(frame_T *fr)
{
- frame_T *frc;
+ frame_T *frc;
FOR_ALL_FRAMES(frc, fr) {
if (ses_do_frame(frc)) {
@@ -200,11 +200,10 @@ static int ses_do_win(win_T *wp)
/// @param flagp
///
/// @returns FAIL if writing fails.
-static int ses_arglist(FILE *fd, char *cmd, garray_T *gap, int fullname,
- unsigned *flagp)
+static int ses_arglist(FILE *fd, char *cmd, garray_T *gap, int fullname, unsigned *flagp)
{
- char_u *buf = NULL;
- char_u *s;
+ char_u *buf = NULL;
+ char_u *s;
if (fprintf(fd, "%s\n%s\n", cmd, "%argdel") < 0) {
return FAIL;
@@ -297,17 +296,15 @@ static int ses_put_fname(FILE *fd, char_u *name, unsigned *flagp)
return retval;
}
-// Write commands to "fd" to restore the view of a window.
-// Caller must make sure 'scrolloff' is zero.
-static int put_view(
- FILE *fd,
- win_T *wp,
- int add_edit, // add ":edit" command to view
- unsigned *flagp, // vop_flags or ssop_flags
- int current_arg_idx // current argument index of the window, use
-) // -1 if unknown
+/// Write commands to "fd" to restore the view of a window.
+/// Caller must make sure 'scrolloff' is zero.
+///
+/// @param add_edit add ":edit" command to view
+/// @param flagp vop_flags or ssop_flags
+/// @param current_arg_idx current argument index of the window, use -1 if unknown
+static int put_view(FILE *fd, win_T *wp, int add_edit, unsigned *flagp, int current_arg_idx)
{
- win_T *save_curwin;
+ win_T *save_curwin;
int f;
int do_cursor;
int did_next = false;
@@ -348,8 +345,8 @@ static int put_view(
// Load the file.
//
if (wp->w_buffer->b_ffname != NULL
- && (!bt_nofile(wp->w_buffer) || wp->w_buffer->terminal)
- ) {
+ && (!bt_nofile(wp->w_buffer) ||
+ wp->w_buffer->terminal)) {
// Editing a file in this buffer: use ":edit file".
// This may have side effects! (e.g., compressed or network file).
//
@@ -434,8 +431,8 @@ static int put_view(
//
if ((*flagp & SSOP_FOLDS)
&& wp->w_buffer->b_ffname != NULL
- && (bt_normal(wp->w_buffer) || bt_help(wp->w_buffer))
- ) {
+ && (bt_normal(wp->w_buffer) ||
+ bt_help(wp->w_buffer))) {
if (put_folds(fd, wp) == FAIL) {
return FAIL;
}
@@ -453,11 +450,11 @@ static int put_view(
}
} else if (fprintf(fd,
"let s:l = %" PRIdLINENR " - ((%" PRIdLINENR
- " * winheight(0) + %" PRId64 ") / %" PRId64 ")\n",
+ " * winheight(0) + %d) / %d)\n",
wp->w_cursor.lnum,
wp->w_cursor.lnum - wp->w_topline,
- (int64_t)(wp->w_height_inner / 2),
- (int64_t)wp->w_height_inner) < 0) {
+ (wp->w_height_inner / 2),
+ wp->w_height_inner) < 0) {
return FAIL;
}
if (fprintf(fd,
@@ -525,12 +522,12 @@ static int makeopens(FILE *fd, char_u *dirnow)
int only_save_windows = true;
int nr;
int restore_size = true;
- win_T *wp;
- char_u *sname;
- win_T *edited_win = NULL;
+ win_T *wp;
+ char_u *sname;
+ win_T *edited_win = NULL;
int tabnr;
- win_T *tab_firstwin;
- frame_T *tab_topframe;
+ win_T *tab_firstwin;
+ frame_T *tab_topframe;
int cur_arg_idx = 0;
int next_arg_idx = 0;
@@ -583,22 +580,6 @@ static int makeopens(FILE *fd, char_u *dirnow)
return FAIL;
}
- // Now put the other buffers into the buffer list.
- FOR_ALL_BUFFERS(buf) {
- if (!(only_save_windows && buf->b_nwindows == 0)
- && !(buf->b_help && !(ssop_flags & SSOP_HELP))
- && buf->b_fname != NULL
- && buf->b_p_bl) {
- if (fprintf(fd, "badd +%" PRId64 " ",
- buf->b_wininfo == NULL
- ? (int64_t)1L
- : (int64_t)buf->b_wininfo->wi_fpos.lnum) < 0
- || ses_fname(fd, buf, &ssop_flags, true) == FAIL) {
- return FAIL;
- }
- }
- }
-
// the global argument list
if (ses_arglist(fd, "argglobal", &global_alist.al_ga,
!(ssop_flags & SSOP_CURDIR), &ssop_flags) == FAIL) {
@@ -674,8 +655,7 @@ static int makeopens(FILE *fd, char_u *dirnow)
if (ses_do_win(wp)
&& wp->w_buffer->b_ffname != NULL
&& !bt_help(wp->w_buffer)
- && !bt_nofile(wp->w_buffer)
- ) {
+ && !bt_nofile(wp->w_buffer)) {
if (need_tabnext && put_line(fd, "tabnext") == FAIL) {
return FAIL;
}
@@ -813,12 +793,31 @@ static int makeopens(FILE *fd, char_u *dirnow)
return FAIL;
}
+ // Now put the remaining buffers into the buffer list.
+ // This is near the end, so that when 'hidden' is set we don't create extra
+ // buffers. If the buffer was already created with another command the
+ // ":badd" will have no effect.
+ FOR_ALL_BUFFERS(buf) {
+ if (!(only_save_windows && buf->b_nwindows == 0)
+ && !(buf->b_help && !(ssop_flags & SSOP_HELP))
+ && buf->b_fname != NULL
+ && buf->b_p_bl) {
+ if (fprintf(fd, "badd +%" PRId64 " ",
+ buf->b_wininfo == NULL
+ ? (int64_t)1L
+ : (int64_t)buf->b_wininfo->wi_fpos.lnum) < 0
+ || ses_fname(fd, buf, &ssop_flags, true) == FAIL) {
+ return FAIL;
+ }
+ }
+ }
+
//
// Wipe out an empty unnamed buffer we started in.
//
if (fprintf(fd, "%s",
"if exists('s:wipebuf') "
- "&& len(win_findbuf(s:wipebuf)) == 0"
+ "&& len(win_findbuf(s:wipebuf)) == 0 "
"&& getbufvar(s:wipebuf, '&buftype') isnot# 'terminal'\n"
" silent exe 'bwipe ' . s:wipebuf\n"
"endif\n"
@@ -874,12 +873,12 @@ void ex_loadview(exarg_T *eap)
/// - SSOP_SLASH: filenames are written with "/" slash
void ex_mkrc(exarg_T *eap)
{
- FILE *fd;
+ FILE *fd;
int failed = false;
int view_session = false; // :mkview, :mksession
int using_vdir = false; // using 'viewdir'?
char *viewFile = NULL;
- unsigned *flagp;
+ unsigned *flagp;
if (eap->cmdidx == CMD_mksession || eap->cmdidx == CMD_mkview) {
view_session = true;
diff --git a/src/nvim/extmark.c b/src/nvim/extmark.c
index 2906a2196b..cf01c305d7 100644
--- a/src/nvim/extmark.c
+++ b/src/nvim/extmark.c
@@ -19,7 +19,7 @@
// Marks live in namespaces that allow plugins/users to segregate marks
// from other users.
//
-// Deleting marks only happens when explicitly calling extmark_del, deleteing
+// Deleting marks only happens when explicitly calling extmark_del, deleting
// over a range of marks will only move the marks. Deleting on a mark will
// leave it in same position unless it is on the EOL of a line.
//
@@ -29,55 +29,43 @@
// code for redrawing the line with the deleted decoration.
#include <assert.h>
+
#include "nvim/api/vim.h"
-#include "nvim/vim.h"
+#include "nvim/buffer.h"
+#include "nvim/buffer_updates.h"
#include "nvim/charset.h"
-#include "nvim/extmark.h"
#include "nvim/decoration.h"
-#include "nvim/buffer_updates.h"
-#include "nvim/memline.h"
-#include "nvim/pos.h"
+#include "nvim/extmark.h"
#include "nvim/globals.h"
-#include "nvim/map.h"
#include "nvim/lib/kbtree.h"
+#include "nvim/map.h"
+#include "nvim/memline.h"
+#include "nvim/pos.h"
#include "nvim/undo.h"
-#include "nvim/buffer.h"
+#include "nvim/vim.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "extmark.c.generated.h"
#endif
static ExtmarkNs *buf_ns_ref(buf_T *buf, uint64_t ns_id, bool put) {
- if (!buf->b_extmark_ns) {
- if (!put) {
- return NULL;
- }
- buf->b_extmark_ns = map_new(uint64_t, ExtmarkNs)();
- buf->b_extmark_index = map_new(uint64_t, ExtmarkItem)();
- }
-
- ExtmarkNs *ns = map_ref(uint64_t, ExtmarkNs)(buf->b_extmark_ns, ns_id, put);
- if (put && ns->map == NULL) {
- ns->map = map_new(uint64_t, uint64_t)();
- ns->free_id = 1;
- }
- return ns;
+ return map_ref(uint64_t, ExtmarkNs)(buf->b_extmark_ns, ns_id, put);
}
/// Create or update an extmark
///
/// must not be used during iteration!
-/// @returns the mark id
-uint64_t extmark_set(buf_T *buf, uint64_t ns_id, uint64_t id,
- int row, colnr_T col, int end_row, colnr_T end_col,
- Decoration *decor, bool right_gravity,
- bool end_right_gravity, ExtmarkOp op)
+/// @returns the internal mark id
+uint64_t extmark_set(buf_T *buf, uint64_t ns_id, uint64_t *idp, int row, colnr_T col, int end_row,
+ colnr_T end_col, Decoration *decor, bool right_gravity, bool end_right_gravity,
+ ExtmarkOp op)
{
ExtmarkNs *ns = buf_ns_ref(buf, ns_id, true);
assert(ns != NULL);
mtpos_t old_pos;
uint64_t mark = 0;
+ uint64_t id = idp ? *idp : 0;
if (id == 0) {
id = ns->free_id++;
@@ -131,7 +119,11 @@ revised:
if (decor) {
decor_redraw(buf, row, end_row > -1 ? end_row : row, decor);
}
- return id;
+
+ if (idp) {
+ *idp = id;
+ }
+ return mark;
}
static bool extmark_setraw(buf_T *buf, uint64_t mark, int row, colnr_T col)
@@ -182,6 +174,10 @@ bool extmark_del(buf_T *buf, uint64_t ns_id, uint64_t id)
decor_free(item.decor);
}
+ if (mark == buf->b_virt_line_mark) {
+ clear_virt_lines(buf, pos.row);
+ }
+
map_del(uint64_t, uint64_t)(ns->map, id);
map_del(uint64_t, ExtmarkItem)(buf->b_extmark_index, mark);
@@ -191,11 +187,9 @@ bool extmark_del(buf_T *buf, uint64_t ns_id, uint64_t id)
// Free extmarks in a ns between lines
// if ns = 0, it means clear all namespaces
-bool extmark_clear(buf_T *buf, uint64_t ns_id,
- int l_row, colnr_T l_col,
- int u_row, colnr_T u_col)
+bool extmark_clear(buf_T *buf, uint64_t ns_id, int l_row, colnr_T l_col, int u_row, colnr_T u_col)
{
- if (!buf->b_extmark_ns) {
+ if (!map_size(buf->b_extmark_ns)) {
return false;
}
@@ -215,12 +209,9 @@ bool extmark_clear(buf_T *buf, uint64_t ns_id,
}
// the value is either zero or the lnum (row+1) if highlight was present.
- static Map(uint64_t, ssize_t) *delete_set = NULL;
+ static Map(uint64_t, ssize_t) delete_set = MAP_INIT;
typedef struct { Decoration *decor; int row1; } DecorItem;
static kvec_t(DecorItem) decors;
- if (delete_set == NULL) {
- delete_set = map_new(uint64_t, ssize_t)();
- }
MarkTreeIter itr[1] = { 0 };
marktree_itr_get(buf->b_marktree, l_row, l_col, itr);
@@ -231,7 +222,7 @@ bool extmark_clear(buf_T *buf, uint64_t ns_id,
|| (mark.row == u_row && mark.col > u_col)) {
break;
}
- ssize_t *del_status = map_ref(uint64_t, ssize_t)(delete_set, mark.id,
+ ssize_t *del_status = map_ref(uint64_t, ssize_t)(&delete_set, mark.id,
false);
if (del_status) {
marktree_del_itr(buf->b_marktree, itr, false);
@@ -240,11 +231,14 @@ bool extmark_clear(buf_T *buf, uint64_t ns_id,
decor_redraw(buf, it.row1, mark.row, it.decor);
decor_free(it.decor);
}
- map_del(uint64_t, ssize_t)(delete_set, mark.id);
+ map_del(uint64_t, ssize_t)(&delete_set, mark.id);
continue;
}
uint64_t start_id = mark.id & ~MARKTREE_END_FLAG;
+ if (start_id == buf->b_virt_line_mark) {
+ clear_virt_lines(buf, mark.row);
+ }
ExtmarkItem item = map_get(uint64_t, ExtmarkItem)(buf->b_extmark_index,
start_id);
@@ -261,14 +255,14 @@ bool extmark_clear(buf_T *buf, uint64_t ns_id,
kv_push(decors,
((DecorItem) { .decor = item.decor, .row1 = mark.row }));
}
- map_put(uint64_t, ssize_t)(delete_set, other, decor_id);
+ map_put(uint64_t, ssize_t)(&delete_set, other, decor_id);
} else if (item.decor) {
decor_redraw(buf, mark.row, mark.row, item.decor);
decor_free(item.decor);
}
ExtmarkNs *my_ns = all_ns ? buf_ns_ref(buf, item.ns_id, false) : ns;
map_del(uint64_t, uint64_t)(my_ns->map, item.mark_id);
- map_del(uint64_t, ExtmarkItem)(buf->b_extmark_index, mark.id);
+ map_del(uint64_t, ExtmarkItem)(buf->b_extmark_index, start_id);
marktree_del_itr(buf->b_marktree, itr, false);
} else {
marktree_itr_next(buf->b_marktree, itr);
@@ -276,7 +270,7 @@ bool extmark_clear(buf_T *buf, uint64_t ns_id,
}
uint64_t id;
ssize_t decor_id;
- map_foreach(delete_set, id, decor_id, {
+ map_foreach(&delete_set, id, decor_id, {
mtpos_t pos = marktree_lookup(buf->b_marktree, id, itr);
assert(itr->node);
marktree_del_itr(buf->b_marktree, itr, false);
@@ -286,7 +280,7 @@ bool extmark_clear(buf_T *buf, uint64_t ns_id,
decor_free(it.decor);
}
});
- map_clear(uint64_t, ssize_t)(delete_set);
+ map_clear(uint64_t, ssize_t)(&delete_set);
kv_size(decors) = 0;
return marks_cleared;
}
@@ -297,10 +291,8 @@ bool extmark_clear(buf_T *buf, uint64_t ns_id,
// will be searched to the start, or end
// dir can be set to control the order of the array
// amount = amount of marks to find or -1 for all
-ExtmarkInfoArray extmark_get(buf_T *buf, uint64_t ns_id,
- int l_row, colnr_T l_col,
- int u_row, colnr_T u_col,
- int64_t amount, bool reverse)
+ExtmarkInfoArray extmark_get(buf_T *buf, uint64_t ns_id, int l_row, colnr_T l_col, int u_row,
+ colnr_T u_col, int64_t amount, bool reverse)
{
ExtmarkInfoArray array = KV_INITIAL_VALUE;
MarkTreeIter itr[1];
@@ -383,7 +375,7 @@ ExtmarkInfo extmark_from_id(buf_T *buf, uint64_t ns_id, uint64_t id)
// free extmarks from the buffer
void extmark_free_all(buf_T *buf)
{
- if (!buf->b_extmark_ns) {
+ if (!map_size(buf->b_extmark_ns)) {
return;
}
@@ -395,25 +387,24 @@ void extmark_free_all(buf_T *buf)
map_foreach(buf->b_extmark_ns, id, ns, {
(void)id;
- map_free(uint64_t, uint64_t)(ns.map);
+ map_destroy(uint64_t, uint64_t)(ns.map);
});
- map_free(uint64_t, ExtmarkNs)(buf->b_extmark_ns);
- buf->b_extmark_ns = NULL;
+ map_destroy(uint64_t, ExtmarkNs)(buf->b_extmark_ns);
+ map_init(uint64_t, ExtmarkNs, buf->b_extmark_ns);
map_foreach(buf->b_extmark_index, id, item, {
(void)id;
decor_free(item.decor);
});
- map_free(uint64_t, ExtmarkItem)(buf->b_extmark_index);
- buf->b_extmark_index = NULL;
+ map_destroy(uint64_t, ExtmarkItem)(buf->b_extmark_index);
+ map_init(uint64_t, ExtmarkItem, buf->b_extmark_index);
}
// Save info for undo/redo of set marks
-static void u_extmark_set(buf_T *buf, uint64_t mark,
- int row, colnr_T col)
+static void u_extmark_set(buf_T *buf, uint64_t mark, int row, colnr_T col)
{
- u_header_T *uhp = u_force_get_undo_header(buf);
+ u_header_T *uhp = u_force_get_undo_header(buf);
if (!uhp) {
return;
}
@@ -435,11 +426,9 @@ static void u_extmark_set(buf_T *buf, uint64_t mark,
///
/// useful when we cannot simply reverse the operation. This will do nothing on
/// redo, enforces correct position when undo.
-void u_extmark_copy(buf_T *buf,
- int l_row, colnr_T l_col,
- int u_row, colnr_T u_col)
+void u_extmark_copy(buf_T *buf, int l_row, colnr_T l_col, int u_row, colnr_T u_col)
{
- u_header_T *uhp = u_force_get_undo_header(buf);
+ u_header_T *uhp = u_force_get_undo_header(buf);
if (!uhp) {
return;
}
@@ -483,7 +472,6 @@ void extmark_apply_undo(ExtmarkUndoObject undo_info, bool undo)
splice.new_row, splice.new_col, splice.new_byte,
splice.old_row, splice.old_col, splice.old_byte,
kExtmarkNoUndo);
-
} else {
extmark_splice_impl(curbuf,
splice.start_row, splice.start_col, splice.start_byte,
@@ -491,14 +479,14 @@ void extmark_apply_undo(ExtmarkUndoObject undo_info, bool undo)
splice.new_row, splice.new_col, splice.new_byte,
kExtmarkNoUndo);
}
- // kExtmarkSavePos
+ // kExtmarkSavePos
} else if (undo_info.type == kExtmarkSavePos) {
ExtmarkSavePos pos = undo_info.data.savepos;
if (undo) {
if (pos.old_row >= 0) {
extmark_setraw(curbuf, pos.mark, pos.old_row, pos.old_col);
}
- // Redo
+ // Redo
} else {
if (pos.row >= 0) {
extmark_setraw(curbuf, pos.mark, pos.row, pos.col);
@@ -520,15 +508,12 @@ void extmark_apply_undo(ExtmarkUndoObject undo_info, bool undo)
kExtmarkNoUndo);
}
}
+ curbuf->b_virt_line_pos = -1;
}
// Adjust extmark row for inserted/deleted rows (columns stay fixed).
-void extmark_adjust(buf_T *buf,
- linenr_T line1,
- linenr_T line2,
- long amount,
- long amount_after,
+void extmark_adjust(buf_T *buf, linenr_T line1, linenr_T line2, long amount, long amount_after,
ExtmarkOp undo)
{
if (curbuf_splice_pending) {
@@ -553,7 +538,7 @@ void extmark_adjust(buf_T *buf,
}
if (new_row > 0) {
new_byte = ml_find_line_or_offset(buf, line1+new_row, NULL, true)
- - start_byte;
+ - start_byte;
}
extmark_splice_impl(buf,
(int)line1-1, 0, start_byte,
@@ -578,10 +563,8 @@ void extmark_adjust(buf_T *buf,
// the end column of the new region.
// @param new_byte Byte extent of the new region.
// @param undo
-void extmark_splice(buf_T *buf,
- int start_row, colnr_T start_col,
- int old_row, colnr_T old_col, bcount_t old_byte,
- int new_row, colnr_T new_col, bcount_t new_byte,
+void extmark_splice(buf_T *buf, int start_row, colnr_T start_col, int old_row, colnr_T old_col,
+ bcount_t old_byte, int new_row, colnr_T new_col, bcount_t new_byte,
ExtmarkOp undo)
{
long offset = ml_find_line_or_offset(buf, start_row + 1, NULL, true);
@@ -600,13 +583,12 @@ void extmark_splice(buf_T *buf,
undo);
}
-void extmark_splice_impl(buf_T *buf,
- int start_row, colnr_T start_col, bcount_t start_byte,
- int old_row, colnr_T old_col, bcount_t old_byte,
- int new_row, colnr_T new_col, bcount_t new_byte,
- ExtmarkOp undo)
+void extmark_splice_impl(buf_T *buf, int start_row, colnr_T start_col, bcount_t start_byte,
+ int old_row, colnr_T old_col, bcount_t old_byte, int new_row,
+ colnr_T new_col, bcount_t new_byte, ExtmarkOp undo)
{
- curbuf->deleted_bytes2 = 0;
+ buf->deleted_bytes2 = 0;
+ buf->b_virt_line_pos = -1;
buf_updates_send_splice(buf, start_row, start_col, start_byte,
old_row, old_col, old_byte,
new_row, new_col, new_byte);
@@ -628,7 +610,7 @@ void extmark_splice_impl(buf_T *buf,
new_row, new_col);
if (undo == kExtmarkUndo) {
- u_header_T *uhp = u_force_get_undo_header(buf);
+ u_header_T *uhp = u_force_get_undo_header(buf);
if (!uhp) {
return;
}
@@ -637,7 +619,7 @@ void extmark_splice_impl(buf_T *buf,
// TODO(bfredl): this is quite rudimentary. We merge small (within line)
// inserts with each other and small deletes with each other. Add full
// merge algorithm later.
- if (old_row == 0 && new_row == 0 && kv_size(uhp->uh_extmark)) {
+ if (old_row == 0 && new_row == 0 && kv_size(uhp->uh_extmark)) {
ExtmarkUndoObject *item = &kv_A(uhp->uh_extmark,
kv_size(uhp->uh_extmark)-1);
if (item->type == kExtmarkSplice) {
@@ -685,24 +667,20 @@ void extmark_splice_impl(buf_T *buf,
}
}
-void extmark_splice_cols(buf_T *buf,
- int start_row, colnr_T start_col,
- colnr_T old_col, colnr_T new_col,
- ExtmarkOp undo)
+void extmark_splice_cols(buf_T *buf, int start_row, colnr_T start_col, colnr_T old_col,
+ colnr_T new_col, ExtmarkOp undo)
{
extmark_splice(buf, start_row, start_col,
0, old_col, old_col,
0, new_col, new_col, undo);
}
-void extmark_move_region(
- buf_T *buf,
- int start_row, colnr_T start_col, bcount_t start_byte,
- int extent_row, colnr_T extent_col, bcount_t extent_byte,
- int new_row, colnr_T new_col, bcount_t new_byte,
- ExtmarkOp undo)
+void extmark_move_region(buf_T *buf, int start_row, colnr_T start_col, bcount_t start_byte,
+ int extent_row, colnr_T extent_col, bcount_t extent_byte, int new_row,
+ colnr_T new_col, bcount_t new_byte, ExtmarkOp undo)
{
- curbuf->deleted_bytes2 = 0;
+ buf->deleted_bytes2 = 0;
+ buf->b_virt_line_pos = -1;
// TODO(bfredl): this is not synced to the buffer state inside the callback.
// But unless we make the undo implementation smarter, this is not ensured
// anyway.
@@ -720,7 +698,7 @@ void extmark_move_region(
if (undo == kExtmarkUndo) {
- u_header_T *uhp = u_force_get_undo_header(buf);
+ u_header_T *uhp = u_force_get_undo_header(buf);
if (!uhp) {
return;
}
diff --git a/src/nvim/extmark_defs.h b/src/nvim/extmark_defs.h
index 784280dace..2da4f3dc00 100644
--- a/src/nvim/extmark_defs.h
+++ b/src/nvim/extmark_defs.h
@@ -6,6 +6,16 @@
typedef struct Decoration Decoration;
+typedef struct {
+ char *text;
+ int hl_id;
+} VirtTextChunk;
+
+typedef kvec_t(VirtTextChunk) VirtText;
+#define VIRTTEXT_EMPTY ((VirtText)KV_INITIAL_VALUE)
+typedef kvec_t(VirtText) VirtLines;
+
+
typedef struct
{
uint64_t ns_id;
@@ -23,8 +33,8 @@ typedef kvec_t(ExtmarkUndoObject) extmark_undo_vec_t;
typedef enum {
kExtmarkNOOP, // Extmarks shouldn't be moved
- kExtmarkUndo, // Operation should be reversable/undoable
- kExtmarkNoUndo, // Operation should not be reversable
+ kExtmarkUndo, // Operation should be reversible/undoable
+ kExtmarkNoUndo, // Operation should not be reversible
kExtmarkUndoNoRedo, // Operation should be undoable, but not redoable
} ExtmarkOp;
diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c
index 8beba38509..d364895ea4 100644
--- a/src/nvim/file_search.c
+++ b/src/nvim/file_search.c
@@ -44,50 +44,50 @@
// functions.
#include <assert.h>
-#include <string.h>
-#include <stdbool.h>
#include <inttypes.h>
#include <limits.h>
+#include <stdbool.h>
+#include <string.h>
-#include "nvim/vim.h"
-#include "nvim/eval.h"
#include "nvim/ascii.h"
-#include "nvim/file_search.h"
#include "nvim/charset.h"
+#include "nvim/eval.h"
+#include "nvim/file_search.h"
#include "nvim/fileio.h"
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
#include "nvim/option.h"
+#include "nvim/os/fs_defs.h"
+#include "nvim/os/input.h"
+#include "nvim/os/os.h"
#include "nvim/os_unix.h"
#include "nvim/path.h"
#include "nvim/strings.h"
#include "nvim/tag.h"
+#include "nvim/vim.h"
#include "nvim/window.h"
-#include "nvim/os/os.h"
-#include "nvim/os/input.h"
-#include "nvim/os/fs_defs.h"
-static char_u *ff_expand_buffer = NULL; /* used for expanding filenames */
+static char_u *ff_expand_buffer = NULL; // used for expanding filenames
/*
* type for the directory search stack
*/
typedef struct ff_stack {
- struct ff_stack *ffs_prev;
+ struct ff_stack *ffs_prev;
/* the fix part (no wildcards) and the part containing the wildcards
* of the search path
*/
- char_u *ffs_fix_path;
- char_u *ffs_wc_path;
+ char_u *ffs_fix_path;
+ char_u *ffs_wc_path;
/* files/dirs found in the above directory, matched by the first wildcard
* of wc_part
*/
- char_u **ffs_filearray;
+ char_u **ffs_filearray;
int ffs_filearray_size;
- char_u ffs_filearray_cur; /* needed for partly handled dirs */
+ char_u ffs_filearray_cur; // needed for partly handled dirs
/* to store status of partly handled directories
* 0: we work on this directory for the first time
@@ -100,7 +100,7 @@ typedef struct ff_stack {
*/
int ffs_level;
- /* Did we already expand '**' to an empty string? */
+ // Did we already expand '**' to an empty string?
int ffs_star_star_empty;
} ff_stack_T;
@@ -108,19 +108,19 @@ typedef struct ff_stack {
* type for already visited directories or files.
*/
typedef struct ff_visited {
- struct ff_visited *ffv_next;
+ struct ff_visited *ffv_next;
/* Visited directories are different if the wildcard string are
* different. So we have to save it.
*/
- char_u *ffv_wc_path;
+ char_u *ffv_wc_path;
// use FileID for comparison (needed because of links), else use filename.
bool file_id_valid;
FileID file_id;
/* The memory for this struct is allocated according to the length of
* ffv_fname.
*/
- char_u ffv_fname[1]; /* actually longer */
+ char_u ffv_fname[1]; // actually longer
} ff_visited_T;
/*
@@ -138,13 +138,12 @@ typedef struct ff_visited {
* visited lists.
*/
typedef struct ff_visited_list_hdr {
- struct ff_visited_list_hdr *ffvl_next;
+ struct ff_visited_list_hdr *ffvl_next;
- /* the filename the attached visited list is for */
- char_u *ffvl_filename;
-
- ff_visited_T *ffvl_visited_list;
+ // the filename the attached visited list is for
+ char_u *ffvl_filename;
+ ff_visited_T *ffvl_visited_list;
} ff_visited_list_hdr_T;
@@ -156,38 +155,38 @@ typedef struct ff_visited_list_hdr {
/*
* The search context:
- * ffsc_stack_ptr: the stack for the dirs to search
+ * ffsc_stack_ptr: the stack for the dirs to search
* ffsc_visited_list: the currently active visited list
* ffsc_dir_visited_list: the currently active visited list for search dirs
* ffsc_visited_lists_list: the list of all visited lists
* ffsc_dir_visited_lists_list: the list of all visited lists for search dirs
* ffsc_file_to_search: the file to search for
- * ffsc_start_dir: the starting directory, if search path was relative
- * ffsc_fix_path: the fix part of the given path (without wildcards)
- * Needed for upward search.
- * ffsc_wc_path: the part of the given path containing wildcards
- * ffsc_level: how many levels of dirs to search downwards
- * ffsc_stopdirs_v: array of stop directories for upward search
- * ffsc_find_what: FINDFILE_BOTH, FINDFILE_DIR or FINDFILE_FILE
- * ffsc_tagfile: searching for tags file, don't use 'suffixesadd'
+ * ffsc_start_dir: the starting directory, if search path was relative
+ * ffsc_fix_path: the fix part of the given path (without wildcards)
+ * Needed for upward search.
+ * ffsc_wc_path: the part of the given path containing wildcards
+ * ffsc_level: how many levels of dirs to search downwards
+ * ffsc_stopdirs_v: array of stop directories for upward search
+ * ffsc_find_what: FINDFILE_BOTH, FINDFILE_DIR or FINDFILE_FILE
+ * ffsc_tagfile: searching for tags file, don't use 'suffixesadd'
*/
typedef struct ff_search_ctx_T {
- ff_stack_T *ffsc_stack_ptr;
- ff_visited_list_hdr_T *ffsc_visited_list;
- ff_visited_list_hdr_T *ffsc_dir_visited_list;
- ff_visited_list_hdr_T *ffsc_visited_lists_list;
- ff_visited_list_hdr_T *ffsc_dir_visited_lists_list;
- char_u *ffsc_file_to_search;
- char_u *ffsc_start_dir;
- char_u *ffsc_fix_path;
- char_u *ffsc_wc_path;
+ ff_stack_T *ffsc_stack_ptr;
+ ff_visited_list_hdr_T *ffsc_visited_list;
+ ff_visited_list_hdr_T *ffsc_dir_visited_list;
+ ff_visited_list_hdr_T *ffsc_visited_lists_list;
+ ff_visited_list_hdr_T *ffsc_dir_visited_lists_list;
+ char_u *ffsc_file_to_search;
+ char_u *ffsc_start_dir;
+ char_u *ffsc_fix_path;
+ char_u *ffsc_wc_path;
int ffsc_level;
- char_u **ffsc_stopdirs_v;
+ char_u **ffsc_stopdirs_v;
int ffsc_find_what;
int ffsc_tagfile;
} ff_search_ctx_T;
-/* locally needed functions */
+// locally needed functions
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "file_search.c.generated.h"
@@ -195,104 +194,98 @@ typedef struct ff_search_ctx_T {
static char_u e_pathtoolong[] = N_("E854: path too long for completion");
-/*
- * Initialization routine for vim_findfile().
- *
- * Returns the newly allocated search context or NULL if an error occurred.
- *
- * Don't forget to clean up by calling vim_findfile_cleanup() if you are done
- * with the search context.
- *
- * Find the file 'filename' in the directory 'path'.
- * The parameter 'path' may contain wildcards. If so only search 'level'
- * directories deep. The parameter 'level' is the absolute maximum and is
- * not related to restricts given to the '**' wildcard. If 'level' is 100
- * and you use '**200' vim_findfile() will stop after 100 levels.
- *
- * 'filename' cannot contain wildcards! It is used as-is, no backslashes to
- * escape special characters.
- *
- * If 'stopdirs' is not NULL and nothing is found downward, the search is
- * restarted on the next higher directory level. This is repeated until the
- * start-directory of a search is contained in 'stopdirs'. 'stopdirs' has the
- * format ";*<dirname>*\(;<dirname>\)*;\=$".
- *
- * If the 'path' is relative, the starting dir for the search is either VIM's
- * current dir or if the path starts with "./" the current files dir.
- * If the 'path' is absolute, the starting dir is that part of the path before
- * the first wildcard.
- *
- * Upward search is only done on the starting dir.
- *
- * If 'free_visited' is TRUE the list of already visited files/directories is
- * cleared. Set this to FALSE if you just want to search from another
- * directory, but want to be sure that no directory from a previous search is
- * searched again. This is useful if you search for a file at different places.
- * The list of visited files/dirs can also be cleared with the function
- * vim_findfile_free_visited().
- *
- * Set the parameter 'find_what' to FINDFILE_DIR if you want to search for
- * directories only, FINDFILE_FILE for files only, FINDFILE_BOTH for both.
- *
- * A search context returned by a previous call to vim_findfile_init() can be
- * passed in the parameter "search_ctx_arg". This context is reused and
- * reinitialized with the new parameters. The list of already visited
- * directories from this context is only deleted if the parameter
- * "free_visited" is true. Be aware that the passed "search_ctx_arg" is freed
- * if the reinitialization fails.
- *
- * If you don't have a search context from a previous call "search_ctx_arg"
- * must be NULL.
- *
- * This function silently ignores a few errors, vim_findfile() will have
- * limited functionality then.
- */
-void *
-vim_findfile_init (
- char_u *path,
- char_u *filename,
- char_u *stopdirs,
- int level,
- int free_visited,
- int find_what,
- void *search_ctx_arg,
- int tagfile, /* expanding names of tags files */
- char_u *rel_fname /* file name to use for "." */
-)
+/// Initialization routine for vim_findfile().
+///
+/// Returns the newly allocated search context or NULL if an error occurred.
+///
+/// Don't forget to clean up by calling vim_findfile_cleanup() if you are done
+/// with the search context.
+///
+/// Find the file 'filename' in the directory 'path'.
+/// The parameter 'path' may contain wildcards. If so only search 'level'
+/// directories deep. The parameter 'level' is the absolute maximum and is
+/// not related to restricts given to the '**' wildcard. If 'level' is 100
+/// and you use '**200' vim_findfile() will stop after 100 levels.
+///
+/// 'filename' cannot contain wildcards! It is used as-is, no backslashes to
+/// escape special characters.
+///
+/// If 'stopdirs' is not NULL and nothing is found downward, the search is
+/// restarted on the next higher directory level. This is repeated until the
+/// start-directory of a search is contained in 'stopdirs'. 'stopdirs' has the
+/// format ";*<dirname>*\(;<dirname>\)*;\=$".
+///
+/// If the 'path' is relative, the starting dir for the search is either VIM's
+/// current dir or if the path starts with "./" the current files dir.
+/// If the 'path' is absolute, the starting dir is that part of the path before
+/// the first wildcard.
+///
+/// Upward search is only done on the starting dir.
+///
+/// If 'free_visited' is TRUE the list of already visited files/directories is
+/// cleared. Set this to FALSE if you just want to search from another
+/// directory, but want to be sure that no directory from a previous search is
+/// searched again. This is useful if you search for a file at different places.
+/// The list of visited files/dirs can also be cleared with the function
+/// vim_findfile_free_visited().
+///
+/// Set the parameter 'find_what' to FINDFILE_DIR if you want to search for
+/// directories only, FINDFILE_FILE for files only, FINDFILE_BOTH for both.
+///
+/// A search context returned by a previous call to vim_findfile_init() can be
+/// passed in the parameter "search_ctx_arg". This context is reused and
+/// reinitialized with the new parameters. The list of already visited
+/// directories from this context is only deleted if the parameter
+/// "free_visited" is true. Be aware that the passed "search_ctx_arg" is freed
+/// if the reinitialization fails.
+///
+/// If you don't have a search context from a previous call "search_ctx_arg"
+/// must be NULL.
+///
+/// This function silently ignores a few errors, vim_findfile() will have
+/// limited functionality then.
+///
+/// @param tagfile expanding names of tags files
+/// @param rel_fname file name to use for "."
+void *vim_findfile_init(char_u *path, char_u *filename, char_u *stopdirs, int level,
+ int free_visited, int find_what, void *search_ctx_arg, int tagfile,
+ char_u *rel_fname)
{
- char_u *wc_part;
- ff_stack_T *sptr;
- ff_search_ctx_T *search_ctx;
+ char_u *wc_part;
+ ff_stack_T *sptr;
+ ff_search_ctx_T *search_ctx;
/* If a search context is given by the caller, reuse it, else allocate a
* new one.
*/
- if (search_ctx_arg != NULL)
+ if (search_ctx_arg != NULL) {
search_ctx = search_ctx_arg;
- else {
+ } else {
search_ctx = xcalloc(1, sizeof(ff_search_ctx_T));
}
search_ctx->ffsc_find_what = find_what;
search_ctx->ffsc_tagfile = tagfile;
- /* clear the search context, but NOT the visited lists */
+ // clear the search context, but NOT the visited lists
ff_clear(search_ctx);
- /* clear visited list if wanted */
- if (free_visited == TRUE)
+ // clear visited list if wanted
+ if (free_visited == TRUE) {
vim_findfile_free_visited(search_ctx);
- else {
+ } else {
/* Reuse old visited lists. Get the visited list for the given
* filename. If no list for the current filename exists, creates a new
* one. */
search_ctx->ffsc_visited_list = ff_get_visited_list(filename,
- &search_ctx->ffsc_visited_lists_list);
- if (search_ctx->ffsc_visited_list == NULL)
+ &search_ctx->ffsc_visited_lists_list);
+ if (search_ctx->ffsc_visited_list == NULL) {
goto error_return;
+ }
search_ctx->ffsc_dir_visited_list = ff_get_visited_list(filename,
- &search_ctx->ffsc_dir_visited_lists_list);
- if (search_ctx->ffsc_dir_visited_list == NULL)
+ &search_ctx->ffsc_dir_visited_lists_list);
+ if (search_ctx->ffsc_dir_visited_list == NULL) {
goto error_return;
+ }
}
if (ff_expand_buffer == NULL) {
@@ -308,16 +301,18 @@ vim_findfile_init (
size_t len = (size_t)(path_tail(rel_fname) - rel_fname);
if (!vim_isAbsName(rel_fname) && len + 1 < MAXPATHL) {
- /* Make the start dir an absolute path name. */
+ // Make the start dir an absolute path name.
STRLCPY(ff_expand_buffer, rel_fname, len + 1);
search_ctx->ffsc_start_dir = (char_u *)FullName_save((char *)ff_expand_buffer, FALSE);
- } else
+ } else {
search_ctx->ffsc_start_dir = vim_strnsave(rel_fname, len);
- if (*++path != NUL)
+ }
+ if (*++path != NUL) {
++path;
+ }
} else if (*path == NUL || !vim_isAbsName(path)) {
#ifdef BACKSLASH_IN_FILENAME
- /* "c:dir" needs "c:" to be expanded, otherwise use current dir */
+ // "c:dir" needs "c:" to be expanded, otherwise use current dir
if (*path != NUL && path[1] == ':') {
char_u drive[3];
@@ -332,8 +327,9 @@ vim_findfile_init (
path += 2;
} else
#endif
- if (os_dirname(ff_expand_buffer, MAXPATHL) == FAIL)
+ if (os_dirname(ff_expand_buffer, MAXPATHL) == FAIL) {
goto error_return;
+ }
search_ctx->ffsc_start_dir = vim_strsave(ff_expand_buffer);
@@ -342,8 +338,9 @@ vim_findfile_init (
* directory (but not for "//machine/dir"). Only use the drive name. */
if ((*path == '/' || *path == '\\')
&& path[1] != path[0]
- && search_ctx->ffsc_start_dir[1] == ':')
+ && search_ctx->ffsc_start_dir[1] == ':') {
search_ctx->ffsc_start_dir[2] = NUL;
+ }
#endif
}
@@ -357,21 +354,22 @@ vim_findfile_init (
* ff_path_in_stoplist() for details.
*/
if (stopdirs != NULL) {
- char_u *walker = stopdirs;
+ char_u *walker = stopdirs;
- while (*walker == ';')
+ while (*walker == ';') {
walker++;
+ }
size_t dircount = 1;
search_ctx->ffsc_stopdirs_v = xmalloc(sizeof(char_u *));
do {
- char_u *helper;
- void *ptr;
+ char_u *helper;
+ void *ptr;
helper = walker;
ptr = xrealloc(search_ctx->ffsc_stopdirs_v,
- (dircount + 1) * sizeof(char_u *));
+ (dircount + 1) * sizeof(char_u *));
search_ctx->ffsc_stopdirs_v = ptr;
walker = vim_strchr(walker, ';');
if (walker) {
@@ -379,15 +377,15 @@ vim_findfile_init (
search_ctx->ffsc_stopdirs_v[dircount-1] =
vim_strnsave(helper, (size_t)(walker - helper));
walker++;
- } else
+ } else {
/* this might be "", which means ascent till top
* of directory tree.
*/
search_ctx->ffsc_stopdirs_v[dircount-1] =
vim_strsave(helper);
+ }
dircount++;
-
} while (walker != NULL);
search_ctx->ffsc_stopdirs_v[dircount-1] = NULL;
}
@@ -402,9 +400,9 @@ vim_findfile_init (
if (wc_part != NULL) {
int64_t llevel;
int len;
- char *errpt;
+ char *errpt;
- /* save the fix part of the path */
+ // save the fix part of the path
assert(wc_part - path >= 0);
search_ctx->ffsc_fix_path = vim_strnsave(path, (size_t)(wc_part - path));
@@ -428,27 +426,30 @@ vim_findfile_init (
ff_expand_buffer[len++] = *wc_part++;
llevel = strtol((char *)wc_part, &errpt, 10);
- if ((char_u *)errpt != wc_part && llevel > 0 && llevel < 255)
+ if ((char_u *)errpt != wc_part && llevel > 0 && llevel < 255) {
ff_expand_buffer[len++] = (char_u)llevel;
- else if ((char_u *)errpt != wc_part && llevel == 0)
- /* restrict is 0 -> remove already added '**' */
+ } else if ((char_u *)errpt != wc_part && llevel == 0) {
+ // restrict is 0 -> remove already added '**'
len -= 2;
- else
+ } else {
ff_expand_buffer[len++] = FF_MAX_STAR_STAR_EXPAND;
+ }
wc_part = (char_u *)errpt;
if (*wc_part != NUL && !vim_ispathsep(*wc_part)) {
EMSG2(_(
- "E343: Invalid path: '**[number]' must be at the end of the path or be followed by '%s'."),
- PATHSEPSTR);
+ "E343: Invalid path: '**[number]' must be at the end of the path or be followed by '%s'."),
+ PATHSEPSTR);
goto error_return;
}
- } else
+ } else {
ff_expand_buffer[len++] = *wc_part++;
+ }
}
ff_expand_buffer[len] = NUL;
search_ctx->ffsc_wc_path = vim_strsave(ff_expand_buffer);
- } else
+ } else {
search_ctx->ffsc_fix_path = vim_strsave(path);
+ }
if (search_ctx->ffsc_start_dir == NULL) {
/* store the fix part as startdir.
@@ -458,7 +459,7 @@ vim_findfile_init (
search_ctx->ffsc_fix_path[0] = NUL;
}
- /* create an absolute path */
+ // create an absolute path
if (STRLEN(search_ctx->ffsc_start_dir)
+ STRLEN(search_ctx->ffsc_fix_path) + 3 >= MAXPATHL) {
EMSG(_(e_pathtoolong));
@@ -505,8 +506,8 @@ vim_findfile_init (
}
sptr = ff_create_stack_element(ff_expand_buffer,
- search_ctx->ffsc_wc_path,
- level, 0);
+ search_ctx->ffsc_wc_path,
+ level, 0);
ff_push(search_ctx, sptr);
search_ctx->ffsc_file_to_search = vim_strsave(filename);
@@ -527,7 +528,7 @@ error_return:
*/
char_u *vim_findfile_stopdir(char_u *buf)
{
- char_u *r_ptr = buf;
+ char_u *r_ptr = buf;
while (*r_ptr != NUL && *r_ptr != ';') {
if (r_ptr[0] == '\\' && r_ptr[1] == ';') {
@@ -541,8 +542,9 @@ char_u *vim_findfile_stopdir(char_u *buf)
if (*r_ptr == ';') {
*r_ptr = 0;
r_ptr++;
- } else if (*r_ptr == NUL)
+ } else if (*r_ptr == NUL) {
r_ptr = NULL;
+ }
return r_ptr;
}
@@ -551,8 +553,9 @@ char_u *vim_findfile_stopdir(char_u *buf)
*/
void vim_findfile_cleanup(void *ctx)
{
- if (ctx == NULL)
+ if (ctx == NULL) {
return;
+ }
vim_findfile_free_visited(ctx);
ff_clear(ctx);
@@ -573,17 +576,18 @@ void vim_findfile_cleanup(void *ctx)
*/
char_u *vim_findfile(void *search_ctx_arg)
{
- char_u *file_path;
- char_u *rest_of_wildcards;
- char_u *path_end = NULL;
- ff_stack_T *stackp = NULL;
+ char_u *file_path;
+ char_u *rest_of_wildcards;
+ char_u *path_end = NULL;
+ ff_stack_T *stackp = NULL;
size_t len;
- char_u *p;
- char_u *suf;
+ char_u *p;
+ char_u *suf;
ff_search_ctx_T *search_ctx;
- if (search_ctx_arg == NULL)
+ if (search_ctx_arg == NULL) {
return NULL;
+ }
search_ctx = (ff_search_ctx_T *)search_ctx_arg;
@@ -593,24 +597,27 @@ char_u *vim_findfile(void *search_ctx_arg)
*/
file_path = xmalloc(MAXPATHL);
- /* store the end of the start dir -- needed for upward search */
- if (search_ctx->ffsc_start_dir != NULL)
+ // store the end of the start dir -- needed for upward search
+ if (search_ctx->ffsc_start_dir != NULL) {
path_end = &search_ctx->ffsc_start_dir[
- STRLEN(search_ctx->ffsc_start_dir)];
+ STRLEN(search_ctx->ffsc_start_dir)];
+ }
- /* upward search loop */
+ // upward search loop
for (;; ) {
- /* downward search loop */
+ // downward search loop
for (;; ) {
- /* check if user user wants to stop the search*/
+ // check if user user wants to stop the search
os_breakcheck();
- if (got_int)
+ if (got_int) {
break;
+ }
- /* get directory to work on from stack */
+ // get directory to work on from stack
stackp = ff_pop(search_ctx);
- if (stackp == NULL)
+ if (stackp == NULL) {
break;
+ }
/*
* TODO: decide if we leave this test in
@@ -633,10 +640,10 @@ char_u *vim_findfile(void *search_ctx_arg)
*/
if (stackp->ffs_filearray == NULL
&& ff_check_visited(&search_ctx->ffsc_dir_visited_list
- ->ffvl_visited_list,
- stackp->ffs_fix_path
- , stackp->ffs_wc_path
- ) == FAIL) {
+ ->ffvl_visited_list,
+ stackp->ffs_fix_path
+ , stackp->ffs_wc_path
+ ) == FAIL) {
#ifdef FF_VERBOSE
if (p_verbose >= 5) {
verbose_enter_scroll();
@@ -659,7 +666,7 @@ char_u *vim_findfile(void *search_ctx_arg)
}
#endif
- /* check depth */
+ // check depth
if (stackp->ffs_level <= 0) {
ff_free_stack_element(stackp);
continue;
@@ -725,13 +732,14 @@ char_u *vim_findfile(void *search_ctx_arg)
}
if (*p == 0) {
- /* remove '**<numb> from wildcards */
+ // remove '**<numb> from wildcards
STRMOVE(rest_of_wildcards, rest_of_wildcards + 3);
- } else
+ } else {
rest_of_wildcards += 3;
+ }
if (stackp->ffs_star_star_empty == 0) {
- /* if not done before, expand '**' to empty */
+ // if not done before, expand '**' to empty
stackp->ffs_star_star_empty = 1;
dirptrs[1] = stackp->ffs_fix_path;
}
@@ -754,8 +762,9 @@ char_u *vim_findfile(void *search_ctx_arg)
}
file_path[len] = NUL;
- if (vim_ispathsep(*rest_of_wildcards))
+ if (vim_ispathsep(*rest_of_wildcards)) {
rest_of_wildcards++;
+ }
}
/*
@@ -766,23 +775,25 @@ char_u *vim_findfile(void *search_ctx_arg)
stackp->ffs_filearray = xmalloc(sizeof(char *));
stackp->ffs_filearray[0] = vim_strsave(dirptrs[0]);
stackp->ffs_filearray_size = 1;
- } else
+ } else {
/* Add EW_NOTWILD because the expanded path may contain
* wildcard characters that are to be taken literally.
* This is a bit of a hack. */
expand_wildcards((dirptrs[1] == NULL) ? 1 : 2, dirptrs,
- &stackp->ffs_filearray_size,
- &stackp->ffs_filearray,
- EW_DIR|EW_ADDSLASH|EW_SILENT|EW_NOTWILD);
+ &stackp->ffs_filearray_size,
+ &stackp->ffs_filearray,
+ EW_DIR|EW_ADDSLASH|EW_SILENT|EW_NOTWILD);
+ }
stackp->ffs_filearray_cur = 0;
stackp->ffs_stage = 0;
- } else
+ } else {
rest_of_wildcards = &stackp->ffs_wc_path[
- STRLEN(stackp->ffs_wc_path)];
+ STRLEN(stackp->ffs_wc_path)];
+ }
if (stackp->ffs_stage == 0) {
- /* this is the first time we work on this directory */
+ // this is the first time we work on this directory
if (*rest_of_wildcards == NUL) {
/*
* We don't have further wildcards to expand, so we have to
@@ -791,9 +802,9 @@ char_u *vim_findfile(void *search_ctx_arg)
for (int i = stackp->ffs_filearray_cur;
i < stackp->ffs_filearray_size; ++i) {
if (!path_with_url((char *)stackp->ffs_filearray[i])
- && !os_isdir(stackp->ffs_filearray[i]))
- continue; /* not a directory */
-
+ && !os_isdir(stackp->ffs_filearray[i])) {
+ continue; // not a directory
+ }
// prepare the filename to be checked for existence below
if (STRLEN(stackp->ffs_filearray[i]) + 1
+ STRLEN(search_ctx->ffsc_file_to_search) >= MAXPATHL) {
@@ -812,12 +823,13 @@ char_u *vim_findfile(void *search_ctx_arg)
* from 'suffixesadd'.
*/
len = STRLEN(file_path);
- if (search_ctx->ffsc_tagfile)
+ if (search_ctx->ffsc_tagfile) {
suf = (char_u *)"";
- else
+ } else {
suf = curbuf->b_p_sua;
+ }
for (;; ) {
- /* if file exists and we didn't already find it */
+ // if file exists and we didn't already find it
if ((path_with_url((char *)file_path)
|| (os_path_exists(file_path)
&& (search_ctx->ffsc_find_what
@@ -826,19 +838,17 @@ char_u *vim_findfile(void *search_ctx_arg)
== FINDFILE_DIR)
== os_isdir(file_path)))))
#ifndef FF_VERBOSE
- && (ff_check_visited(
- &search_ctx->ffsc_visited_list->ffvl_visited_list,
- file_path
- , (char_u *)""
- ) == OK)
+ && (ff_check_visited(&search_ctx->ffsc_visited_list->ffvl_visited_list,
+ file_path
+ , (char_u *)""
+ ) == OK)
#endif
) {
#ifdef FF_VERBOSE
- if (ff_check_visited(
- &search_ctx->ffsc_visited_list->ffvl_visited_list,
- file_path
- , (char_u *)""
- ) == FAIL) {
+ if (ff_check_visited(&search_ctx->ffsc_visited_list->ffvl_visited_list,
+ file_path
+ , (char_u *)""
+ ) == FAIL) {
if (p_verbose >= 5) {
verbose_enter_scroll();
smsg("Already: %s", file_path);
@@ -849,19 +859,21 @@ char_u *vim_findfile(void *search_ctx_arg)
}
#endif
- /* push dir to examine rest of subdirs later */
+ // push dir to examine rest of subdirs later
assert(i < UCHAR_MAX - 1);
stackp->ffs_filearray_cur = (char_u)(i + 1);
ff_push(search_ctx, stackp);
- if (!path_with_url((char *)file_path))
+ if (!path_with_url((char *)file_path)) {
simplify_filename(file_path);
+ }
if (os_dirname(ff_expand_buffer, MAXPATHL)
== OK) {
p = path_shorten_fname(file_path,
- ff_expand_buffer);
- if (p != NULL)
+ ff_expand_buffer);
+ if (p != NULL) {
STRMOVE(file_path, p);
+ }
}
#ifdef FF_VERBOSE
if (p_verbose >= 5) {
@@ -874,12 +886,13 @@ char_u *vim_findfile(void *search_ctx_arg)
return file_path;
}
- /* Not found or found already, try next suffix. */
- if (*suf == NUL)
+ // Not found or found already, try next suffix.
+ if (*suf == NUL) {
break;
+ }
assert(MAXPATHL >= len);
copy_option_part(&suf, file_path + len,
- MAXPATHL - len, ",");
+ MAXPATHL - len, ",");
}
}
} else {
@@ -889,14 +902,13 @@ char_u *vim_findfile(void *search_ctx_arg)
*/
for (int i = stackp->ffs_filearray_cur;
i < stackp->ffs_filearray_size; ++i) {
- if (!os_isdir(stackp->ffs_filearray[i]))
- continue; /* not a directory */
-
+ if (!os_isdir(stackp->ffs_filearray[i])) {
+ continue; // not a directory
+ }
ff_push(search_ctx,
- ff_create_stack_element(
- stackp->ffs_filearray[i],
- rest_of_wildcards,
- stackp->ffs_level - 1, 0));
+ ff_create_stack_element(stackp->ffs_filearray[i],
+ rest_of_wildcards,
+ stackp->ffs_level - 1, 0));
}
}
stackp->ffs_filearray_cur = 0;
@@ -911,19 +923,20 @@ char_u *vim_findfile(void *search_ctx_arg)
for (int i = stackp->ffs_filearray_cur;
i < stackp->ffs_filearray_size; ++i) {
if (fnamecmp(stackp->ffs_filearray[i],
- stackp->ffs_fix_path) == 0)
- continue; /* don't repush same directory */
- if (!os_isdir(stackp->ffs_filearray[i]))
- continue; /* not a directory */
+ stackp->ffs_fix_path) == 0) {
+ continue; // don't repush same directory
+ }
+ if (!os_isdir(stackp->ffs_filearray[i])) {
+ continue; // not a directory
+ }
ff_push(search_ctx,
- ff_create_stack_element(stackp->ffs_filearray[i],
- stackp->ffs_wc_path, stackp->ffs_level - 1, 1));
+ ff_create_stack_element(stackp->ffs_filearray[i],
+ stackp->ffs_wc_path, stackp->ffs_level - 1, 1));
}
}
- /* we are done with the current directory */
+ // we are done with the current directory
ff_free_stack_element(stackp);
-
}
/* If we reached this, we didn't find anything downwards.
@@ -931,26 +944,30 @@ char_u *vim_findfile(void *search_ctx_arg)
*/
if (search_ctx->ffsc_start_dir
&& search_ctx->ffsc_stopdirs_v != NULL && !got_int) {
- ff_stack_T *sptr;
+ ff_stack_T *sptr;
- /* is the last starting directory in the stop list? */
+ // is the last starting directory in the stop list?
if (ff_path_in_stoplist(search_ctx->ffsc_start_dir,
- (int)(path_end - search_ctx->ffsc_start_dir),
- search_ctx->ffsc_stopdirs_v) == TRUE)
+ (int)(path_end - search_ctx->ffsc_start_dir),
+ search_ctx->ffsc_stopdirs_v) == TRUE) {
break;
+ }
- /* cut of last dir */
+ // cut of last dir
while (path_end > search_ctx->ffsc_start_dir
- && vim_ispathsep(*path_end))
+ && vim_ispathsep(*path_end)) {
path_end--;
+ }
while (path_end > search_ctx->ffsc_start_dir
- && !vim_ispathsep(path_end[-1]))
+ && !vim_ispathsep(path_end[-1])) {
path_end--;
+ }
*path_end = 0;
path_end--;
- if (*search_ctx->ffsc_start_dir == 0)
+ if (*search_ctx->ffsc_start_dir == 0) {
break;
+ }
if (STRLEN(search_ctx->ffsc_start_dir) + 1
+ STRLEN(search_ctx->ffsc_fix_path) >= MAXPATHL) {
@@ -962,12 +979,13 @@ char_u *vim_findfile(void *search_ctx_arg)
}
STRCAT(file_path, search_ctx->ffsc_fix_path);
- /* create a new stack entry */
+ // create a new stack entry
sptr = ff_create_stack_element(file_path,
- search_ctx->ffsc_wc_path, search_ctx->ffsc_level, 0);
+ search_ctx->ffsc_wc_path, search_ctx->ffsc_level, 0);
ff_push(search_ctx, sptr);
- } else
+ } else {
break;
+ }
}
fail:
@@ -983,8 +1001,9 @@ void vim_findfile_free_visited(void *search_ctx_arg)
{
ff_search_ctx_T *search_ctx;
- if (search_ctx_arg == NULL)
+ if (search_ctx_arg == NULL) {
return;
+ }
search_ctx = (ff_search_ctx_T *)search_ctx_arg;
vim_findfile_free_visited_list(&search_ctx->ffsc_visited_lists_list);
@@ -1023,11 +1042,12 @@ static void ff_free_visited_list(ff_visited_T *vl)
* Returns the already visited list for the given filename. If none is found it
* allocates a new one.
*/
-static ff_visited_list_hdr_T *ff_get_visited_list(char_u *filename, ff_visited_list_hdr_T **list_headp)
+static ff_visited_list_hdr_T *ff_get_visited_list(char_u *filename,
+ ff_visited_list_hdr_T **list_headp)
{
- ff_visited_list_hdr_T *retptr = NULL;
+ ff_visited_list_hdr_T *retptr = NULL;
- /* check if a visited list for the given filename exists */
+ // check if a visited list for the given filename exists
if (*list_headp != NULL) {
retptr = *list_headp;
while (retptr != NULL) {
@@ -1115,7 +1135,7 @@ static bool ff_wc_equal(char_u *s1, char_u *s2)
*/
static int ff_check_visited(ff_visited_T **visited_list, char_u *fname, char_u *wc_path)
{
- ff_visited_T *vp;
+ ff_visited_T *vp;
bool url = false;
FileID file_id;
@@ -1131,7 +1151,7 @@ static int ff_check_visited(ff_visited_T **visited_list, char_u *fname, char_u *
}
}
- /* check against list of already visited files */
+ // check against list of already visited files
for (vp = *visited_list; vp != NULL; vp = vp->ffv_next) {
if ((url && fnamecmp(vp->ffv_fname, ff_expand_buffer) == 0)
|| (!url && vp->file_id_valid
@@ -1158,10 +1178,11 @@ static int ff_check_visited(ff_visited_T **visited_list, char_u *fname, char_u *
STRCPY(vp->ffv_fname, ff_expand_buffer);
}
- if (wc_path != NULL)
+ if (wc_path != NULL) {
vp->ffv_wc_path = vim_strsave(wc_path);
- else
+ } else {
vp->ffv_wc_path = NULL;
+ }
vp->ffv_next = *visited_list;
*visited_list = vp;
@@ -1172,7 +1193,8 @@ static int ff_check_visited(ff_visited_T **visited_list, char_u *fname, char_u *
/*
* create stack element from given path pieces
*/
-static ff_stack_T *ff_create_stack_element(char_u *fix_part, char_u *wc_part, int level, int star_star_empty)
+static ff_stack_T *ff_create_stack_element(char_u *fix_part, char_u *wc_part, int level,
+ int star_star_empty)
{
ff_stack_T *new = xmalloc(sizeof(ff_stack_T));
@@ -1184,13 +1206,15 @@ static ff_stack_T *ff_create_stack_element(char_u *fix_part, char_u *wc_part, in
new->ffs_level = level;
new->ffs_star_star_empty = star_star_empty;
- /* the following saves NULL pointer checks in vim_findfile */
- if (fix_part == NULL)
+ // the following saves NULL pointer checks in vim_findfile
+ if (fix_part == NULL) {
fix_part = (char_u *)"";
+ }
new->ffs_fix_path = vim_strsave(fix_part);
- if (wc_part == NULL)
+ if (wc_part == NULL) {
wc_part = (char_u *)"";
+ }
new->ffs_wc_path = vim_strsave(wc_part);
return new;
@@ -1215,11 +1239,12 @@ static void ff_push(ff_search_ctx_T *search_ctx, ff_stack_T *stack_ptr)
*/
static ff_stack_T *ff_pop(ff_search_ctx_T *search_ctx)
{
- ff_stack_T *sptr;
+ ff_stack_T *sptr;
sptr = search_ctx->ffsc_stack_ptr;
- if (search_ctx->ffsc_stack_ptr != NULL)
+ if (search_ctx->ffsc_stack_ptr != NULL) {
search_ctx->ffsc_stack_ptr = search_ctx->ffsc_stack_ptr->ffs_prev;
+ }
return sptr;
}
@@ -1249,11 +1274,12 @@ static void ff_free_stack_element(ff_stack_T *const stack_ptr)
*/
static void ff_clear(ff_search_ctx_T *search_ctx)
{
- ff_stack_T *sptr;
+ ff_stack_T *sptr;
- /* clear up stack */
- while ((sptr = ff_pop(search_ctx)) != NULL)
+ // clear up stack
+ while ((sptr = ff_pop(search_ctx)) != NULL) {
ff_free_stack_element(sptr);
+ }
xfree(search_ctx->ffsc_file_to_search);
xfree(search_ctx->ffsc_start_dir);
@@ -1271,7 +1297,7 @@ static void ff_clear(ff_search_ctx_T *search_ctx)
}
search_ctx->ffsc_stopdirs_v = NULL;
- /* reset everything */
+ // reset everything
search_ctx->ffsc_file_to_search = NULL;
search_ctx->ffsc_start_dir = NULL;
search_ctx->ffsc_fix_path = NULL;
@@ -1287,13 +1313,15 @@ static int ff_path_in_stoplist(char_u *path, int path_len, char_u **stopdirs_v)
{
int i = 0;
- /* eat up trailing path separators, except the first */
- while (path_len > 1 && vim_ispathsep(path[path_len - 1]))
+ // eat up trailing path separators, except the first
+ while (path_len > 1 && vim_ispathsep(path[path_len - 1])) {
path_len--;
+ }
- /* if no path consider it as match */
- if (path_len == 0)
+ // if no path consider it as match
+ if (path_len == 0) {
return TRUE;
+ }
for (i = 0; stopdirs_v[i] != NULL; i++) {
if ((int)STRLEN(stopdirs_v[i]) > path_len) {
@@ -1302,49 +1330,46 @@ static int ff_path_in_stoplist(char_u *path, int path_len, char_u **stopdirs_v)
* '/home/r' would also match '/home/rks'
*/
if (fnamencmp(stopdirs_v[i], path, path_len) == 0
- && vim_ispathsep(stopdirs_v[i][path_len]))
+ && vim_ispathsep(stopdirs_v[i][path_len])) {
return TRUE;
+ }
} else {
- if (fnamecmp(stopdirs_v[i], path) == 0)
+ if (fnamecmp(stopdirs_v[i], path) == 0) {
return TRUE;
+ }
}
}
return FALSE;
}
-/*
- * Find the file name "ptr[len]" in the path. Also finds directory names.
- *
- * On the first call set the parameter 'first' to TRUE to initialize
- * the search. For repeating calls to FALSE.
- *
- * Repeating calls will return other files called 'ptr[len]' from the path.
- *
- * Only on the first call 'ptr' and 'len' are used. For repeating calls they
- * don't need valid values.
- *
- * If nothing found on the first call the option FNAME_MESS will issue the
- * message:
- * 'Can't find file "<file>" in path'
- * On repeating calls:
- * 'No more file "<file>" found in path'
- *
- * options:
- * FNAME_MESS give error message when not found
- *
- * Uses NameBuff[]!
- *
- * Returns an allocated string for the file name. NULL for error.
- *
- */
-char_u *
-find_file_in_path (
- char_u *ptr, /* file name */
- size_t len, /* length of file name */
- int options,
- int first, /* use count'th matching file name */
- char_u *rel_fname /* file name searching relative to */
-)
+/// Find the file name "ptr[len]" in the path. Also finds directory names.
+///
+/// On the first call set the parameter 'first' to TRUE to initialize
+/// the search. For repeating calls to FALSE.
+///
+/// Repeating calls will return other files called 'ptr[len]' from the path.
+///
+/// Only on the first call 'ptr' and 'len' are used. For repeating calls they
+/// don't need valid values.
+///
+/// If nothing found on the first call the option FNAME_MESS will issue the
+/// message:
+/// 'Can't find file "<file>" in path'
+/// On repeating calls:
+/// 'No more file "<file>" found in path'
+///
+/// options:
+/// FNAME_MESS give error message when not found
+///
+/// Uses NameBuff[]!
+///
+/// @param ptr file name
+/// @param len length of file name
+/// @param first use count'th matching file name
+/// @param rel_fname file name searching relative to
+///
+/// @return an allocated string for the file name. NULL for error.
+char_u *find_file_in_path(char_u *ptr, size_t len, int options, int first, char_u *rel_fname)
{
return find_file_in_path_option(ptr, len, options, first,
(*curbuf->b_p_path == NUL
@@ -1353,8 +1378,8 @@ find_file_in_path (
FINDFILE_BOTH, rel_fname, curbuf->b_p_sua);
}
-static char_u *ff_file_to_find = NULL;
-static void *fdip_search_ctx = NULL;
+static char_u *ff_file_to_find = NULL;
+static void *fdip_search_ctx = NULL;
#if defined(EXITFREE)
void free_findfile(void)
@@ -1366,46 +1391,41 @@ void free_findfile(void)
#endif
-/*
- * Find the directory name "ptr[len]" in the path.
- *
- * options:
- * FNAME_MESS give error message when not found
- * FNAME_UNESC unescape backslashes
- *
- * Uses NameBuff[]!
- *
- * Returns an allocated string for the file name. NULL for error.
- */
-char_u *
-find_directory_in_path (
- char_u *ptr, /* file name */
- size_t len, /* length of file name */
- int options,
- char_u *rel_fname /* file name searching relative to */
-)
+/// Find the directory name "ptr[len]" in the path.
+///
+/// options:
+/// FNAME_MESS give error message when not found
+/// FNAME_UNESC unescape backslashes
+///
+/// Uses NameBuff[]!
+///
+/// @param ptr file name
+/// @param len length of file name
+/// @param rel_fname file name searching relative to
+///
+/// @return an allocated string for the file name. NULL for error.
+char_u *find_directory_in_path(char_u *ptr, size_t len, int options, char_u *rel_fname)
{
return find_file_in_path_option(ptr, len, options, TRUE, p_cdpath,
FINDFILE_DIR, rel_fname, (char_u *)"");
}
-char_u *
-find_file_in_path_option (
- char_u *ptr, /* file name */
- size_t len, /* length of file name */
- int options,
- int first, /* use count'th matching file name */
- char_u *path_option, /* p_path or p_cdpath */
- int find_what, /* FINDFILE_FILE, _DIR or _BOTH */
- char_u *rel_fname, /* file name we are looking relative to. */
- char_u *suffixes /* list of suffixes, 'suffixesadd' option */
-)
+/// @param ptr file name
+/// @param len length of file name
+/// @param first use count'th matching file name
+/// @param path_option p_path or p_cdpath
+/// @param find_what FINDFILE_FILE, _DIR or _BOTH
+/// @param rel_fname file name we are looking relative to.
+/// @param suffixes list of suffixes, 'suffixesadd' option
+char_u *find_file_in_path_option(char_u *ptr, size_t len, int options, int first,
+ char_u *path_option, int find_what, char_u *rel_fname,
+ char_u *suffixes)
{
- static char_u *dir;
+ static char_u *dir;
static int did_findfile_init = FALSE;
char_u save_char;
- char_u *file_name = NULL;
- char_u *buf = NULL;
+ char_u *file_name = NULL;
+ char_u *buf = NULL;
int rel_to_curdir;
if (rel_fname != NULL && path_with_url((const char *)rel_fname)) {
@@ -1414,7 +1434,7 @@ find_file_in_path_option (
}
if (first == TRUE) {
- /* copy file name into NameBuff, expanding environment variables */
+ // copy file name into NameBuff, expanding environment variables
save_char = ptr[len];
ptr[len] = NUL;
expand_env_esc(ptr, NameBuff, MAXPATHL, false, true, NULL);
@@ -1485,11 +1505,12 @@ find_file_in_path_option (
&& (find_what == FINDFILE_BOTH
|| ((find_what == FINDFILE_DIR)
== os_isdir(NameBuff))))) {
- file_name = vim_strsave(NameBuff);
- goto theend;
+ file_name = vim_strsave(NameBuff);
+ goto theend;
}
- if (*buf == NUL)
+ if (*buf == NUL) {
break;
+ }
assert(MAXPATHL >= l);
copy_option_part(&buf, NameBuff + l, MAXPATHL - l, ",");
}
@@ -1502,7 +1523,7 @@ find_file_in_path_option (
* Otherwise continue to find the next match.
*/
if (first == TRUE) {
- /* vim_findfile_free_visited can handle a possible NULL pointer */
+ // vim_findfile_free_visited can handle a possible NULL pointer
vim_findfile_free_visited(fdip_search_ctx);
dir = path_option;
did_findfile_init = FALSE;
@@ -1511,12 +1532,13 @@ find_file_in_path_option (
for (;; ) {
if (did_findfile_init) {
file_name = vim_findfile(fdip_search_ctx);
- if (file_name != NULL)
+ if (file_name != NULL) {
break;
+ }
did_findfile_init = FALSE;
} else {
- char_u *r_ptr;
+ char_u *r_ptr;
if (dir == NULL || *dir == NUL) {
/* We searched all paths of the option, now we can
@@ -1528,36 +1550,39 @@ find_file_in_path_option (
buf = xmalloc(MAXPATHL);
- /* copy next path */
+ // copy next path
buf[0] = 0;
copy_option_part(&dir, buf, MAXPATHL, " ,");
- /* get the stopdir string */
+ // get the stopdir string
r_ptr = vim_findfile_stopdir(buf);
fdip_search_ctx = vim_findfile_init(buf, ff_file_to_find,
- r_ptr, 100, FALSE, find_what,
- fdip_search_ctx, FALSE, rel_fname);
- if (fdip_search_ctx != NULL)
+ r_ptr, 100, FALSE, find_what,
+ fdip_search_ctx, FALSE, rel_fname);
+ if (fdip_search_ctx != NULL) {
did_findfile_init = TRUE;
+ }
xfree(buf);
}
}
}
if (file_name == NULL && (options & FNAME_MESS)) {
if (first == TRUE) {
- if (find_what == FINDFILE_DIR)
+ if (find_what == FINDFILE_DIR) {
EMSG2(_("E344: Can't find directory \"%s\" in cdpath"),
- ff_file_to_find);
- else
+ ff_file_to_find);
+ } else {
EMSG2(_("E345: Can't find file \"%s\" in path"),
- ff_file_to_find);
+ ff_file_to_find);
+ }
} else {
- if (find_what == FINDFILE_DIR)
+ if (find_what == FINDFILE_DIR) {
EMSG2(_("E346: No more directory \"%s\" found in cdpath"),
- ff_file_to_find);
- else
+ ff_file_to_find);
+ } else {
EMSG2(_("E347: No more file \"%s\" found in path"),
- ff_file_to_find);
+ ff_file_to_find);
+ }
}
}
@@ -1581,22 +1606,18 @@ void do_autocmd_dirchanged(char *new_dir, CdScope scope, bool changed_window)
char buf[8];
switch (scope) {
- case kCdScopeGlobal: {
- snprintf(buf, sizeof(buf), "global");
- break;
- }
- case kCdScopeTab: {
- snprintf(buf, sizeof(buf), "tab");
- break;
- }
- case kCdScopeWindow: {
- snprintf(buf, sizeof(buf), "window");
- break;
- }
- case kCdScopeInvalid: {
- // Should never happen.
- abort();
- }
+ case kCdScopeGlobal:
+ snprintf(buf, sizeof(buf), "global");
+ break;
+ case kCdScopeTab:
+ snprintf(buf, sizeof(buf), "tab");
+ break;
+ case kCdScopeWindow:
+ snprintf(buf, sizeof(buf), "window");
+ break;
+ case kCdScopeInvalid:
+ // Should never happen.
+ abort();
}
tv_dict_add_str(dict, S_LEN("scope"), buf); // -V614
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c
index 29c29a2884..f5a4efc371 100644
--- a/src/nvim/fileio.c
+++ b/src/nvim/fileio.c
@@ -5,15 +5,13 @@
#include <assert.h>
#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
#include <stdbool.h>
#include <string.h>
-#include <inttypes.h>
-#include <fcntl.h>
-#include "nvim/vim.h"
-#include "nvim/api/private/handle.h"
+#include "nvim/api/private/helpers.h"
#include "nvim/ascii.h"
-#include "nvim/fileio.h"
#include "nvim/buffer.h"
#include "nvim/buffer_updates.h"
#include "nvim/change.h"
@@ -25,8 +23,10 @@
#include "nvim/ex_cmds.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_eval.h"
+#include "nvim/fileio.h"
#include "nvim/fold.h"
#include "nvim/func_attr.h"
+#include "nvim/garray.h"
#include "nvim/getchar.h"
#include "nvim/hashtab.h"
#include "nvim/iconv.h"
@@ -36,10 +36,13 @@
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/garray.h"
#include "nvim/move.h"
#include "nvim/normal.h"
#include "nvim/option.h"
+#include "nvim/os/input.h"
+#include "nvim/os/os.h"
+#include "nvim/os/os_defs.h"
+#include "nvim/os/time.h"
#include "nvim/os_unix.h"
#include "nvim/path.h"
#include "nvim/quickfix.h"
@@ -47,37 +50,34 @@
#include "nvim/screen.h"
#include "nvim/search.h"
#include "nvim/sha256.h"
+#include "nvim/shada.h"
#include "nvim/state.h"
#include "nvim/strings.h"
+#include "nvim/types.h"
#include "nvim/ui.h"
#include "nvim/ui_compositor.h"
-#include "nvim/types.h"
#include "nvim/undo.h"
+#include "nvim/vim.h"
#include "nvim/window.h"
-#include "nvim/shada.h"
-#include "nvim/os/os.h"
-#include "nvim/os/os_defs.h"
-#include "nvim/os/time.h"
-#include "nvim/os/input.h"
-#define BUFSIZE 8192 /* size of normal write buffer */
-#define SMBUFSIZE 256 /* size of emergency write buffer */
+#define BUFSIZE 8192 // size of normal write buffer
+#define SMBUFSIZE 256 // size of emergency write buffer
// For compatibility with libuv < 1.20.0 (tested on 1.18.0)
#ifndef UV_FS_COPYFILE_FICLONE
-#define UV_FS_COPYFILE_FICLONE 0
+# define UV_FS_COPYFILE_FICLONE 0
#endif
#define HAS_BW_FLAGS
-#define FIO_LATIN1 0x01 /* convert Latin1 */
-#define FIO_UTF8 0x02 /* convert UTF-8 */
-#define FIO_UCS2 0x04 /* convert UCS-2 */
-#define FIO_UCS4 0x08 /* convert UCS-4 */
-#define FIO_UTF16 0x10 /* convert UTF-16 */
-#define FIO_ENDIAN_L 0x80 /* little endian */
-#define FIO_NOCONVERT 0x2000 /* skip encoding conversion */
-#define FIO_UCSBOM 0x4000 /* check for BOM at start of file */
-#define FIO_ALL -1 /* allow all formats */
+#define FIO_LATIN1 0x01 // convert Latin1
+#define FIO_UTF8 0x02 // convert UTF-8
+#define FIO_UCS2 0x04 // convert UCS-2
+#define FIO_UCS4 0x08 // convert UCS-4
+#define FIO_UTF16 0x10 // convert UTF-16
+#define FIO_ENDIAN_L 0x80 // little endian
+#define FIO_NOCONVERT 0x2000 // skip encoding conversion
+#define FIO_UCSBOM 0x4000 // check for BOM at start of file
+#define 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... */
@@ -92,7 +92,7 @@
*/
struct bw_info {
int bw_fd; // file descriptor
- char_u *bw_buf; // buffer with data to be written
+ char_u *bw_buf; // buffer with data to be written
int bw_len; // length of data
#ifdef HAS_BW_FLAGS
int bw_flags; // FIO_ flags
@@ -100,22 +100,21 @@ struct bw_info {
char_u bw_rest[CONV_RESTLEN]; // not converted bytes
int bw_restlen; // nr of bytes in bw_rest[]
int bw_first; // first write call
- char_u *bw_conv_buf; // buffer for writing converted chars
+ char_u *bw_conv_buf; // buffer for writing converted chars
int bw_conv_buflen; // size of bw_conv_buf
int bw_conv_error; // set for conversion error
linenr_T bw_conv_error_lnum; // first line with error or zero
linenr_T bw_start_lnum; // line number at start of buffer
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
iconv_t bw_iconv_fd; // descriptor for iconv() or -1
-# endif
+#endif
};
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "fileio.c.generated.h"
#endif
-static char *e_auchangedbuf = N_(
- "E812: Autocommands changed buffer or buffer name");
+static char *e_auchangedbuf = N_("E812: Autocommands changed buffer or buffer name");
void filemess(buf_T *buf, char_u *name, char_u *s, int attr)
{
@@ -131,56 +130,50 @@ void filemess(buf_T *buf, char_u *name, char_u *s, int attr)
// For further ones overwrite the previous one, reset msg_scroll before
// calling filemess().
msg_scroll_save = msg_scroll;
- if (shortmess(SHM_OVERALL) && !exiting && p_verbose == 0)
+ if (shortmess(SHM_OVERALL) && !exiting && p_verbose == 0) {
msg_scroll = FALSE;
- if (!msg_scroll) /* wait a bit when overwriting an error msg */
- check_for_delay(FALSE);
+ }
+ if (!msg_scroll) { // wait a bit when overwriting an error msg
+ check_for_delay(false);
+ }
msg_start();
msg_scroll = msg_scroll_save;
- msg_scrolled_ign = TRUE;
- /* may truncate the message to avoid a hit-return prompt */
+ msg_scrolled_ign = true;
+ // may truncate the message to avoid a hit-return prompt
msg_outtrans_attr(msg_may_trunc(FALSE, IObuff), attr);
msg_clr_eos();
ui_flush();
- msg_scrolled_ign = FALSE;
+ msg_scrolled_ign = false;
}
-/*
- * Read lines from file "fname" into the buffer after line "from".
- *
- * 1. We allocate blocks with try_malloc, as big as possible.
- * 2. Each block is filled with characters from the file with a single read().
- * 3. The lines are inserted in the buffer with ml_append().
- *
- * (caller must check that fname != NULL, unless READ_STDIN is used)
- *
- * "lines_to_skip" is the number of lines that must be skipped
- * "lines_to_read" is the number of lines that are appended
- * When not recovering lines_to_skip is 0 and lines_to_read MAXLNUM.
- *
- * flags:
- * READ_NEW starting to edit a new buffer
- * READ_FILTER reading filter output
- * READ_STDIN read from stdin instead of a file
- * READ_BUFFER read from curbuf instead of a file (converting after reading
- * stdin)
- * READ_DUMMY read into a dummy buffer (to check if file contents changed)
- * READ_KEEP_UNDO don't clear undo info or read it from a file
- * READ_FIFO read from fifo/socket instead of a file
- *
- * return FAIL for failure, NOTDONE for directory (failure), or OK
- */
-int
-readfile(
- char_u *fname,
- char_u *sfname,
- linenr_T from,
- linenr_T lines_to_skip,
- linenr_T lines_to_read,
- exarg_T *eap, // can be NULL!
- int flags
-)
+/// Read lines from file "fname" into the buffer after line "from".
+///
+/// 1. We allocate blocks with try_malloc, as big as possible.
+/// 2. Each block is filled with characters from the file with a single read().
+/// 3. The lines are inserted in the buffer with ml_append().
+///
+/// (caller must check that fname != NULL, unless READ_STDIN is used)
+///
+/// "lines_to_skip" is the number of lines that must be skipped
+/// "lines_to_read" is the number of lines that are appended
+/// When not recovering lines_to_skip is 0 and lines_to_read MAXLNUM.
+///
+/// flags:
+/// READ_NEW starting to edit a new buffer
+/// READ_FILTER reading filter output
+/// READ_STDIN read from stdin instead of a file
+/// READ_BUFFER read from curbuf instead of a file (converting after reading
+/// stdin)
+/// READ_DUMMY read into a dummy buffer (to check if file contents changed)
+/// READ_KEEP_UNDO don't clear undo info or read it from a file
+/// READ_FIFO read from fifo/socket instead of a file
+///
+/// @param eap can be NULL!
+///
+/// @return FAIL for failure, NOTDONE for directory (failure), or OK
+int readfile(char_u *fname, char_u *sfname, linenr_T from, linenr_T lines_to_skip,
+ linenr_T lines_to_read, exarg_T *eap, int flags)
{
int fd = 0;
int newfile = (flags & READ_NEW);
@@ -191,35 +184,34 @@ readfile(
int read_fifo = (flags & READ_FIFO);
int set_options = newfile || read_buffer
|| (eap != NULL && eap->read_edit);
- linenr_T read_buf_lnum = 1; /* next line to read from curbuf */
- colnr_T read_buf_col = 0; /* next char to read from this line */
+ linenr_T read_buf_lnum = 1; // next line to read from curbuf
+ colnr_T read_buf_col = 0; // next char to read from this line
char_u c;
linenr_T lnum = from;
- char_u *ptr = NULL; /* pointer into read buffer */
- char_u *buffer = NULL; /* read buffer */
- char_u *new_buffer = NULL; /* init to shut up gcc */
- char_u *line_start = NULL; /* init to shut up gcc */
- int wasempty; /* buffer was empty before reading */
+ char_u *ptr = NULL; // pointer into read buffer
+ char_u *buffer = NULL; // read buffer
+ char_u *new_buffer = NULL; // init to shut up gcc
+ char_u *line_start = NULL; // init to shut up gcc
+ int wasempty; // buffer was empty before reading
colnr_T len;
long size = 0;
uint8_t *p = NULL;
off_T filesize = 0;
- int skip_read = false;
+ bool skip_read = false;
context_sha256_T sha_ctx;
int read_undo_file = false;
int split = 0; // number of split lines
linenr_T linecnt;
- int error = FALSE; /* errors encountered */
- int ff_error = EOL_UNKNOWN; /* file format with errors */
- long linerest = 0; /* remaining chars in line */
+ bool error = false; // errors encountered
+ int ff_error = EOL_UNKNOWN; // file format with errors
+ long linerest = 0; // remaining chars in line
int perm = 0;
#ifdef UNIX
- int swap_mode = -1; /* protection bits for swap file */
+ int swap_mode = -1; // protection bits for swap file
#endif
int fileformat = 0; // end-of-line format
bool keep_fileformat = false;
FileInfo file_info;
- int file_readonly;
linenr_T skip_count = 0;
linenr_T read_count = 0;
int msg_save = msg_scroll;
@@ -234,33 +226,32 @@ readfile(
int bad_char_behavior = BAD_REPLACE;
/* BAD_KEEP, BAD_DROP or character to
* replace with */
- char_u *tmpname = NULL; /* name of 'charconvert' output file */
+ char_u *tmpname = NULL; // name of 'charconvert' output file
int fio_flags = 0;
- char_u *fenc; // fileencoding to use
+ char_u *fenc; // fileencoding to use
bool fenc_alloced; // fenc_next is in allocated memory
- char_u *fenc_next = NULL; // next item in 'fencs' or NULL
+ char_u *fenc_next = NULL; // next item in 'fencs' or NULL
bool advance_fenc = false;
long real_size = 0;
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
iconv_t iconv_fd = (iconv_t)-1; // descriptor for iconv() or -1
- int did_iconv = false; // TRUE when iconv() failed and trying
+ bool did_iconv = false; // true when iconv() failed and trying
// 'charconvert' next
-# endif
- int converted = FALSE; /* TRUE if conversion done */
- int notconverted = FALSE; /* TRUE if conversion wanted but it
- wasn't possible */
+#endif
+ bool converted = false; // true if conversion done
+ bool notconverted = false; // true if conversion wanted but it wasn't possible
char_u conv_rest[CONV_RESTLEN];
- int conv_restlen = 0; /* nr of bytes in conv_rest[] */
- buf_T *old_curbuf;
- char_u *old_b_ffname;
- char_u *old_b_fname;
+ int conv_restlen = 0; // nr of bytes in conv_rest[]
+ buf_T *old_curbuf;
+ char_u *old_b_ffname;
+ char_u *old_b_fname;
int using_b_ffname;
int using_b_fname;
static char *msg_is_a_directory = N_("is a directory");
au_did_filetype = false; // reset before triggering any autocommands
- curbuf->b_no_eol_lnum = 0; /* in case it was set by the previous read */
+ curbuf->b_no_eol_lnum = 0; // in case it was set by the previous read
/*
* If there is no file name yet, use the one for the read file.
@@ -273,8 +264,9 @@ readfile(
&& fname != NULL
&& vim_strchr(p_cpo, CPO_FNAMER) != NULL
&& !(flags & READ_DUMMY)) {
- if (set_rw_fname(fname, sfname) == FAIL)
+ if (set_rw_fname(fname, sfname) == FAIL) {
return FAIL;
+ }
}
/* Remember the initial values of curbuf, curbuf->b_ffname and
@@ -290,10 +282,10 @@ readfile(
/* After reading a file the cursor line changes but we don't want to
* display the line. */
- ex_no_reprint = TRUE;
+ ex_no_reprint = true;
- /* don't display the file info for another buffer now */
- need_fileinfo = FALSE;
+ // don't display the file info for another buffer now
+ need_fileinfo = false;
// For Unix: Use the short file name whenever possible.
// Avoids problems with networks and when directory names are changed.
@@ -315,7 +307,7 @@ readfile(
pos = curbuf->b_op_start;
- /* Set '[ mark to the line above where the lines go (line 1 if zero). */
+ // Set '[ mark to the line above where the lines go (line 1 if zero).
curbuf->b_op_start.lnum = ((from == 0) ? 1 : from);
curbuf->b_op_start.col = 0;
@@ -346,11 +338,11 @@ readfile(
curbuf->b_op_start = pos;
}
- if ((shortmess(SHM_OVER) || curbuf->b_help) && p_verbose == 0)
- msg_scroll = FALSE; /* overwrite previous file message */
- else
- msg_scroll = TRUE; /* don't overwrite previous file message */
-
+ if ((shortmess(SHM_OVER) || curbuf->b_help) && p_verbose == 0) {
+ msg_scroll = FALSE; // overwrite previous file message
+ } else {
+ msg_scroll = TRUE; // don't overwrite previous file message
+ }
// If the name is too long we might crash further on, quit here.
if (fname != NULL && *fname != NUL) {
size_t namelen = STRLEN(fname);
@@ -381,10 +373,10 @@ readfile(
if (perm >= 0 && !S_ISREG(perm) // not a regular file ...
&& !S_ISFIFO(perm) // ... or fifo
&& !S_ISSOCK(perm) // ... or socket
-# ifdef OPEN_CHR_FILES
+#ifdef OPEN_CHR_FILES
&& !(S_ISCHR(perm) && is_dev_fd_file(fname))
// ... or a character special file named /dev/fd/<n>
-# endif
+#endif
) {
if (S_ISDIR(perm)) {
filemess(curbuf, fname, (char_u *)_(msg_is_a_directory), 0);
@@ -397,7 +389,7 @@ readfile(
}
}
- /* Set default or forced 'fileformat' and 'binary'. */
+ // Set default or forced 'fileformat' and 'binary'.
set_file_options(set_options, eap);
/*
@@ -407,8 +399,9 @@ readfile(
* Only set/reset b_p_ro when BF_CHECK_RO is set.
*/
check_readonly = (newfile && (curbuf->b_flags & BF_CHECK_RO));
- if (check_readonly && !readonlymode)
+ if (check_readonly && !readonlymode) {
curbuf->b_p_ro = FALSE;
+ }
if (newfile && !read_stdin && !read_buffer && !read_fifo) {
// Remember time of file.
@@ -442,7 +435,7 @@ readfile(
}
// Check readonly.
- file_readonly = false;
+ bool file_readonly = false;
if (!read_buffer && !read_stdin) {
if (!newfile || readonlymode || !(perm & 0222)
|| !os_file_is_writable((char *)fname)) {
@@ -466,7 +459,7 @@ readfile(
* "nofile" or "nowrite" buffer type. */
if (!bt_dontwrite(curbuf)) {
check_need_swap(newfile);
- /* SwapExists autocommand may mess things up */
+ // SwapExists autocommand may mess things up
if (curbuf != old_curbuf
|| (using_b_ffname
&& (old_b_ffname != curbuf->b_ffname))
@@ -493,19 +486,20 @@ readfile(
// remember the current fileformat
save_file_ff(curbuf);
- if (aborting()) /* autocmds may abort script processing */
+ if (aborting()) { // autocmds may abort script processing
return FAIL;
- return OK; /* a new file is not an error */
+ }
+ return OK; // a new file is not an error
} else {
filemess(curbuf, sfname, (char_u *)(
- (fd == UV_EFBIG) ? _("[File too big]") :
-# if defined(UNIX) && defined(EOVERFLOW)
- // libuv only returns -errno in Unix and in Windows open() does not
- // set EOVERFLOW
- (fd == -EOVERFLOW) ? _("[File too big]") :
-# endif
- _("[Permission Denied]")), 0);
- curbuf->b_p_ro = TRUE; /* must use "w!" now */
+ (fd == UV_EFBIG) ? _("[File too big]") :
+#if defined(UNIX) && defined(EOVERFLOW)
+ // libuv only returns -errno in Unix and in Windows open() does not
+ // set EOVERFLOW
+ (fd == -EOVERFLOW) ? _("[File too big]") :
+#endif
+ _("[Permission Denied]")), 0);
+ curbuf->b_p_ro = TRUE; // must use "w!" now
}
return FAIL;
@@ -513,10 +507,11 @@ readfile(
/*
* Only set the 'ro' flag for readonly files the first time they are
- * loaded. Help files always get readonly mode
+ * loaded. Help files always get readonly mode
*/
- if ((check_readonly && file_readonly) || curbuf->b_help)
+ if ((check_readonly && file_readonly) || curbuf->b_help) {
curbuf->b_p_ro = TRUE;
+ }
if (set_options) {
/* Don't change 'eol' if reading from buffer as it will already be
@@ -573,12 +568,13 @@ readfile(
// If "Quit" selected at ATTENTION dialog, don't load the file.
if (swap_exists_action == SEA_QUIT) {
- if (!read_buffer && !read_stdin)
+ if (!read_buffer && !read_stdin) {
close(fd);
+ }
return FAIL;
}
- ++no_wait_return; /* don't wait for return yet */
+ ++no_wait_return; // don't wait for return yet
/*
* Set '[ mark to the line above where the lines go (line 1 if zero).
@@ -627,10 +623,10 @@ readfile(
msg_scroll = m;
}
- if (aborting()) { /* autocmds may abort script processing */
+ if (aborting()) { // autocmds may abort script processing
--no_wait_return;
msg_scroll = msg_save;
- curbuf->b_p_ro = TRUE; /* must use "w!" now */
+ curbuf->b_p_ro = TRUE; // must use "w!" now
return FAIL;
}
/*
@@ -646,16 +642,17 @@ readfile(
|| (fd = os_open((char *)fname, O_RDONLY, 0)) < 0)) {
--no_wait_return;
msg_scroll = msg_save;
- if (fd < 0)
+ if (fd < 0) {
EMSG(_("E200: *ReadPre autocommands made the file unreadable"));
- else
+ } else {
EMSG(_("E201: *ReadPre autocommands must not change current buffer"));
- curbuf->b_p_ro = TRUE; /* must use "w!" now */
+ }
+ curbuf->b_p_ro = TRUE; // must use "w!" now
return FAIL;
}
}
- /* Autocommands may add lines to the file, need to check if it is empty */
+ // Autocommands may add lines to the file, need to check if it is empty
wasempty = (curbuf->b_ml.ml_flags & ML_EMPTY);
if (!recoverymode && !filtering && !(flags & READ_DUMMY)) {
@@ -664,7 +661,7 @@ readfile(
}
}
- msg_scroll = FALSE; /* overwrite the file message */
+ msg_scroll = FALSE; // overwrite the file message
/*
* Set linecnt now, before the "retry" caused by a wrong guess for
@@ -672,13 +669,15 @@ readfile(
*/
linecnt = curbuf->b_ml.ml_line_count;
- /* "++bad=" argument. */
+ // "++bad=" argument.
if (eap != NULL && eap->bad_char != 0) {
bad_char_behavior = eap->bad_char;
- if (set_options)
+ if (set_options) {
curbuf->b_bad_char = eap->bad_char;
- } else
+ }
+ } else {
curbuf->b_bad_char = 0;
+ }
/*
* Decide which 'encoding' to use or use first.
@@ -715,16 +714,16 @@ readfile(
* - "fileformat" check failed: try another
*
* Variables set for special retry actions:
- * "file_rewind" Rewind the file to start reading it again.
- * "advance_fenc" Advance "fenc" using "fenc_next".
- * "skip_read" Re-use already read bytes (BOM detected).
- * "did_iconv" iconv() conversion failed, try 'charconvert'.
+ * "file_rewind" Rewind the file to start reading it again.
+ * "advance_fenc" Advance "fenc" using "fenc_next".
+ * "skip_read" Re-use already read bytes (BOM detected).
+ * "did_iconv" iconv() conversion failed, try 'charconvert'.
* "keep_fileformat" Don't reset "fileformat".
*
* Other status indicators:
- * "tmpname" When != NULL did conversion with 'charconvert'.
- * Output file has to be deleted afterwards.
- * "iconv_fd" When != -1 did conversion with iconv().
+ * "tmpname" When != NULL did conversion with 'charconvert'.
+ * Output file has to be deleted afterwards.
+ * "iconv_fd" When != -1 did conversion with iconv().
*/
retry:
@@ -759,21 +758,23 @@ retry:
if (eap != NULL && eap->force_ff != 0) {
fileformat = get_fileformat_force(curbuf, eap);
try_unix = try_dos = try_mac = FALSE;
- } else if (curbuf->b_p_bin)
- fileformat = EOL_UNIX; /* binary: use Unix format */
- else if (*p_ffs == NUL)
- fileformat = get_fileformat(curbuf); /* use format from buffer */
- else
- fileformat = EOL_UNKNOWN; /* detect from file */
+ } else if (curbuf->b_p_bin) {
+ fileformat = EOL_UNIX; // binary: use Unix format
+ } else if (*p_ffs ==
+ NUL) {
+ fileformat = get_fileformat(curbuf); // use format from buffer
+ } else {
+ fileformat = EOL_UNKNOWN; // detect from file
+ }
}
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
if (iconv_fd != (iconv_t)-1) {
- /* aborted conversion with iconv(), close the descriptor */
+ // aborted conversion with iconv(), close the descriptor
iconv_close(iconv_fd);
iconv_fd = (iconv_t)-1;
}
-# endif
+#endif
if (advance_fenc) {
/*
@@ -782,17 +783,19 @@ retry:
advance_fenc = false;
if (eap != NULL && eap->force_enc != 0) {
- /* Conversion given with "++cc=" wasn't possible, read
- * without conversion. */
- notconverted = TRUE;
+ // Conversion given with "++cc=" wasn't possible, read
+ // without conversion.
+ notconverted = true;
conv_error = 0;
- if (fenc_alloced)
+ if (fenc_alloced) {
xfree(fenc);
+ }
fenc = (char_u *)"";
fenc_alloced = false;
} else {
- if (fenc_alloced)
+ if (fenc_alloced) {
xfree(fenc);
+ }
if (fenc_next != NULL) {
fenc = next_fenc(&fenc_next, &fenc_alloced);
} else {
@@ -813,7 +816,6 @@ retry:
fio_flags = 0;
converted = need_conversion(fenc);
if (converted) {
-
/* "ucs-bom" means we need to check the first bytes of the file
* for a BOM. */
if (STRCMP(fenc, ENC_UCSBOM) == 0) {
@@ -831,14 +833,13 @@ retry:
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
// Try using iconv() if we can't convert internally.
if (fio_flags == 0
- && !did_iconv
- ) {
+ && !did_iconv) {
iconv_fd = (iconv_t)my_iconv_open((char_u *)"utf-8", fenc);
}
-# endif
+#endif
/*
* Use the 'charconvert' expression when conversion is required
@@ -846,13 +847,13 @@ retry:
*/
if (fio_flags == 0 && !read_stdin && !read_buffer && *p_ccv != NUL
&& !read_fifo
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
&& iconv_fd == (iconv_t)-1
-# endif
+#endif
) {
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
did_iconv = false;
-# endif
+#endif
/* Skip conversion when it's already done (retry for wrong
* "fileformat"). */
if (tmpname == NULL) {
@@ -861,9 +862,9 @@ retry:
// Conversion failed. Try another one.
advance_fenc = true;
if (fd < 0) {
- /* Re-opening the original file failed! */
+ // Re-opening the original file failed!
EMSG(_("E202: Conversion made file unreadable!"));
- error = TRUE;
+ error = true;
goto failed;
}
goto retry;
@@ -871,9 +872,9 @@ retry:
}
} else {
if (fio_flags == 0
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
&& iconv_fd == (iconv_t)-1
-# endif
+#endif
) {
/* Conversion wanted but we can't.
* Try the next conversion in 'fileencodings' */
@@ -901,8 +902,9 @@ retry:
&& !read_fifo
&& !read_stdin
&& !read_buffer);
- if (read_undo_file)
+ if (read_undo_file) {
sha256_start(&sha_ctx);
+ }
}
while (!error && !got_int) {
@@ -936,11 +938,12 @@ retry:
}
}
if (new_buffer == NULL) {
- error = TRUE;
+ error = true;
break;
}
- if (linerest) /* copy characters from the previous buffer */
+ if (linerest) { // copy characters from the previous buffer
memmove(new_buffer, ptr - linerest, (size_t)linerest);
+ }
xfree(buffer);
buffer = new_buffer;
ptr = buffer + linerest;
@@ -957,11 +960,11 @@ retry:
* ucs-4 to utf-8: 4 bytes become up to 6 bytes, size must be
* multiple of 4 */
real_size = (int)size;
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
if (iconv_fd != (iconv_t)-1) {
size = size / ICONV_MULT;
} else {
-# endif
+#endif
if (fio_flags & FIO_LATIN1) {
size = size / 2;
} else if (fio_flags & (FIO_UCS2 | FIO_UTF16)) {
@@ -971,9 +974,9 @@ retry:
} else if (fio_flags == FIO_UCSBOM) {
size = size / ICONV_MULT; // worst case
}
-# ifdef HAVE_ICONV
- }
-# endif
+#ifdef HAVE_ICONV
+ }
+#endif
if (conv_restlen > 0) {
// Insert unconverted bytes from previous line.
memmove(ptr, conv_rest, conv_restlen); // -V614
@@ -986,9 +989,9 @@ retry:
* Read bytes from curbuf. Used for converting text read
* from stdin.
*/
- if (read_buf_lnum > from)
+ if (read_buf_lnum > from) {
size = 0;
- else {
+ } else {
int n, ni;
long tlen;
@@ -1002,10 +1005,11 @@ retry:
* below. */
n = (int)(size - tlen);
for (ni = 0; ni < n; ++ni) {
- if (p[ni] == NL)
+ if (p[ni] == NL) {
ptr[tlen++] = NUL;
- else
+ } else {
ptr[tlen++] = p[ni];
+ }
}
read_buf_col += n;
break;
@@ -1013,18 +1017,20 @@ retry:
/* Append whole line and new-line. Change NL
* to NUL to reverse the effect done below. */
for (ni = 0; ni < n; ++ni) {
- if (p[ni] == NL)
+ if (p[ni] == NL) {
ptr[tlen++] = NUL;
- else
+ } else {
ptr[tlen++] = p[ni];
+ }
}
ptr[tlen++] = NL;
read_buf_col = 0;
if (++read_buf_lnum > from) {
/* When the last line didn't have an
* end-of-line don't add it now either. */
- if (!curbuf->b_p_eol)
+ if (!curbuf->b_p_eol) {
--tlen;
+ }
size = tlen;
break;
}
@@ -1039,30 +1045,33 @@ retry:
}
if (size <= 0) {
- if (size < 0) /* read error */
- error = TRUE;
- else if (conv_restlen > 0) {
+ if (size < 0) { // read error
+ error = true;
+ } else if (conv_restlen > 0) {
/*
* Reached end-of-file but some trailing bytes could
* not be converted. Truncated file?
*/
- /* When we did a conversion report an error. */
+ // When we did a conversion report an error.
if (fio_flags != 0
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
|| iconv_fd != (iconv_t)-1
-# endif
+#endif
) {
- if (can_retry)
+ if (can_retry) {
goto rewind_retry;
- if (conv_error == 0)
+ }
+ if (conv_error == 0) {
conv_error = curbuf->b_ml.ml_line_count
- linecnt + 1;
+ }
}
- /* Remember the first linenr with an illegal byte */
- else if (illegal_byte == 0)
+ // Remember the first linenr with an illegal byte
+ else if (illegal_byte == 0) {
illegal_byte = curbuf->b_ml.ml_line_count
- linecnt + 1;
+ }
if (bad_char_behavior == BAD_DROP) {
*(ptr - conv_restlen) = NUL;
conv_restlen = 0;
@@ -1072,9 +1081,9 @@ retry:
* leave the UTF8 checking code to do it, as it
* works slightly differently. */
if (bad_char_behavior != BAD_KEEP && (fio_flags != 0
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
|| iconv_fd != (iconv_t)-1
-# endif
+#endif
)) {
while (conv_restlen > 0) {
*(--ptr) = bad_char_behavior;
@@ -1082,18 +1091,18 @@ retry:
}
}
fio_flags = 0; // don't convert this
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
if (iconv_fd != (iconv_t)-1) {
iconv_close(iconv_fd);
iconv_fd = (iconv_t)-1;
}
-# endif
+#endif
}
}
}
}
- skip_read = FALSE;
+ skip_read = false;
/*
* At start of file: Check for BOM.
@@ -1106,17 +1115,18 @@ retry:
|| (!curbuf->b_p_bomb
&& tmpname == NULL
&& (*fenc == 'u' || *fenc == NUL)))) {
- char_u *ccname;
+ char_u *ccname;
int blen;
- /* no BOM detection in a short file or in binary mode */
- if (size < 2 || curbuf->b_p_bin)
+ // no BOM detection in a short file or in binary mode
+ if (size < 2 || curbuf->b_p_bin) {
ccname = NULL;
- else
+ } else {
ccname = check_for_bom(ptr, size, &blen,
- fio_flags == FIO_UCSBOM ? FIO_ALL : get_fio_flags(fenc));
+ fio_flags == FIO_UCSBOM ? FIO_ALL : get_fio_flags(fenc));
+ }
if (ccname != NULL) {
- /* Remove BOM from the text */
+ // Remove BOM from the text
filesize += blen;
size -= blen;
memmove(ptr, ptr + blen, (size_t)size);
@@ -1131,36 +1141,38 @@ retry:
// No BOM detected: retry with next encoding.
advance_fenc = true;
} else {
- /* BOM detected: set "fenc" and jump back */
- if (fenc_alloced)
+ // BOM detected: set "fenc" and jump back
+ if (fenc_alloced) {
xfree(fenc);
+ }
fenc = ccname;
fenc_alloced = false;
}
- /* retry reading without getting new bytes or rewinding */
- skip_read = TRUE;
+ // retry reading without getting new bytes or rewinding
+ skip_read = true;
goto retry;
}
}
- /* Include not converted bytes. */
+ // Include not converted bytes.
ptr -= conv_restlen;
size += conv_restlen;
conv_restlen = 0;
/*
* Break here for a read error or end-of-file.
*/
- if (size <= 0)
+ if (size <= 0) {
break;
+ }
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
if (iconv_fd != (iconv_t)-1) {
/*
* Attempt conversion of the read bytes to 'encoding' using
* iconv().
*/
- const char *fromp;
- char *top;
+ const char *fromp;
+ char *top;
size_t from_size;
size_t to_size;
@@ -1176,16 +1188,18 @@ retry:
* alternative (help files).
*/
while ((iconv(iconv_fd, (void *)&fromp, &from_size,
- &top, &to_size)
+ &top, &to_size)
== (size_t)-1 && ICONV_ERRNO != ICONV_EINVAL)
|| from_size > CONV_RESTLEN) {
- if (can_retry)
+ if (can_retry) {
goto rewind_retry;
- if (conv_error == 0)
+ }
+ if (conv_error == 0) {
conv_error = readfile_linenr(linecnt,
- ptr, (char_u *)top);
+ ptr, (char_u *)top);
+ }
- /* Deal with a bad byte and continue with the next. */
+ // Deal with a bad byte and continue with the next.
++fromp;
--from_size;
if (bad_char_behavior == BAD_KEEP) {
@@ -1204,17 +1218,17 @@ retry:
conv_restlen = (int)from_size;
}
- /* move the linerest to before the converted characters */
+ // move the linerest to before the converted characters
line_start = ptr - linerest;
memmove(line_start, buffer, (size_t)linerest);
- size = (long)((char_u *)top - ptr);
+ size = ((char_u *)top - ptr);
}
-# endif
+#endif
if (fio_flags != 0) {
unsigned int u8c;
- char_u *dest;
- char_u *tail = NULL;
+ char_u *dest;
+ char_u *tail = NULL;
// Convert Unicode or Latin1 to UTF-8.
// Go from end to start through the buffer, because the number
@@ -1225,22 +1239,25 @@ retry:
if (fio_flags == FIO_LATIN1 || fio_flags == FIO_UTF8) {
p = ptr + size;
if (fio_flags == FIO_UTF8) {
- /* Check for a trailing incomplete UTF-8 sequence */
+ // Check for a trailing incomplete UTF-8 sequence
tail = ptr + size - 1;
- while (tail > ptr && (*tail & 0xc0) == 0x80)
+ while (tail > ptr && (*tail & 0xc0) == 0x80) {
--tail;
- if (tail + utf_byte2len(*tail) <= ptr + size)
+ }
+ if (tail + utf_byte2len(*tail) <= ptr + size) {
tail = NULL;
- else
+ } else {
p = tail;
+ }
}
} else if (fio_flags & (FIO_UCS2 | FIO_UTF16)) {
- /* Check for a trailing byte */
+ // Check for a trailing byte
p = ptr + (size & ~1);
- if (size & 1)
+ if (size & 1) {
tail = p;
+ }
if ((fio_flags & FIO_UTF16) && p > ptr) {
- /* Check for a trailing leading word */
+ // Check for a trailing leading word
if (fio_flags & FIO_ENDIAN_L) {
u8c = (*--p << 8);
u8c += *--p;
@@ -1248,16 +1265,18 @@ retry:
u8c = *--p;
u8c += (*--p << 8);
}
- if (u8c >= 0xd800 && u8c <= 0xdbff)
+ if (u8c >= 0xd800 && u8c <= 0xdbff) {
tail = p;
- else
+ } else {
p += 2;
+ }
}
- } else { /* FIO_UCS4 */
- /* Check for trailing 1, 2 or 3 bytes */
+ } else { // FIO_UCS4
+ // Check for trailing 1, 2 or 3 bytes
p = ptr + (size & ~3);
- if (size & 3)
+ if (size & 3) {
tail = p;
+ }
}
/* If there is a trailing incomplete sequence move it to
@@ -1270,9 +1289,9 @@ retry:
while (p > ptr) {
- if (fio_flags & FIO_LATIN1)
+ if (fio_flags & FIO_LATIN1) {
u8c = *--p;
- else if (fio_flags & (FIO_UCS2 | FIO_UTF16)) {
+ } else if (fio_flags & (FIO_UCS2 | FIO_UTF16)) {
if (fio_flags & FIO_ENDIAN_L) {
u8c = (*--p << 8);
u8c += *--p;
@@ -1285,16 +1304,20 @@ retry:
int u16c;
if (p == ptr) {
- /* Missing leading word. */
- if (can_retry)
+ // Missing leading word.
+ if (can_retry) {
goto rewind_retry;
- if (conv_error == 0)
+ }
+ if (conv_error == 0) {
conv_error = readfile_linenr(linecnt,
- ptr, p);
- if (bad_char_behavior == BAD_DROP)
+ ptr, p);
+ }
+ if (bad_char_behavior == BAD_DROP) {
continue;
- if (bad_char_behavior != BAD_KEEP)
+ }
+ if (bad_char_behavior != BAD_KEEP) {
u8c = bad_char_behavior;
+ }
}
/* found second word of double-word, get the first
@@ -1309,17 +1332,21 @@ retry:
u8c = 0x10000 + ((u16c & 0x3ff) << 10)
+ (u8c & 0x3ff);
- /* Check if the word is indeed a leading word. */
+ // Check if the word is indeed a leading word.
if (u16c < 0xd800 || u16c > 0xdbff) {
- if (can_retry)
+ if (can_retry) {
goto rewind_retry;
- if (conv_error == 0)
+ }
+ if (conv_error == 0) {
conv_error = readfile_linenr(linecnt,
- ptr, p);
- if (bad_char_behavior == BAD_DROP)
+ ptr, p);
+ }
+ if (bad_char_behavior == BAD_DROP) {
continue;
- if (bad_char_behavior != BAD_KEEP)
+ }
+ if (bad_char_behavior != BAD_KEEP) {
u8c = bad_char_behavior;
+ }
}
}
} else if (fio_flags & FIO_UCS4) {
@@ -1328,16 +1355,16 @@ retry:
u8c += (unsigned)(*--p) << 16;
u8c += (unsigned)(*--p) << 8;
u8c += *--p;
- } else { /* big endian */
+ } else { // big endian
u8c = *--p;
u8c += (unsigned)(*--p) << 8;
u8c += (unsigned)(*--p) << 16;
u8c += (unsigned)(*--p) << 24;
}
- } else { /* UTF-8 */
- if (*--p < 0x80)
+ } else { // UTF-8
+ if (*--p < 0x80) {
u8c = *p;
- else {
+ } else {
len = utf_head_off(ptr, p);
p -= len;
u8c = utf_ptr2char(p);
@@ -1345,15 +1372,19 @@ retry:
/* Not a valid UTF-8 character, retry with
* another fenc when possible, otherwise just
* report the error. */
- if (can_retry)
+ if (can_retry) {
goto rewind_retry;
- if (conv_error == 0)
+ }
+ if (conv_error == 0) {
conv_error = readfile_linenr(linecnt,
- ptr, p);
- if (bad_char_behavior == BAD_DROP)
+ ptr, p);
+ }
+ if (bad_char_behavior == BAD_DROP) {
continue;
- if (bad_char_behavior != BAD_KEEP)
+ }
+ if (bad_char_behavior != BAD_KEEP) {
u8c = bad_char_behavior;
+ }
}
}
}
@@ -1366,7 +1397,7 @@ retry:
// move the linerest to before the converted characters
line_start = dest - linerest;
memmove(line_start, buffer, (size_t)linerest);
- size = (long)((ptr + real_size) - dest);
+ size = ((ptr + real_size) - dest);
ptr = dest;
} else if (!curbuf->b_p_bin) {
bool incomplete_tail = false;
@@ -1407,57 +1438,61 @@ retry:
/* Illegal byte. If we can try another encoding
* do that, unless at EOF where a truncated
* file is more likely than a conversion error. */
- if (can_retry && !incomplete_tail)
+ if (can_retry && !incomplete_tail) {
break;
-# ifdef HAVE_ICONV
+ }
+#ifdef HAVE_ICONV
// When we did a conversion report an error.
if (iconv_fd != (iconv_t)-1 && conv_error == 0) {
conv_error = readfile_linenr(linecnt, ptr, p);
}
-# endif
- /* Remember the first linenr with an illegal byte */
- if (conv_error == 0 && illegal_byte == 0)
+#endif
+ // Remember the first linenr with an illegal byte
+ if (conv_error == 0 && illegal_byte == 0) {
illegal_byte = readfile_linenr(linecnt, ptr, p);
+ }
- /* Drop, keep or replace the bad byte. */
+ // Drop, keep or replace the bad byte.
if (bad_char_behavior == BAD_DROP) {
memmove(p, p + 1, todo - 1);
--p;
--size;
- } else if (bad_char_behavior != BAD_KEEP)
+ } else if (bad_char_behavior != BAD_KEEP) {
*p = bad_char_behavior;
- } else
+ }
+ } else {
p += l - 1;
+ }
}
}
if (p < ptr + size && !incomplete_tail) {
- /* Detected a UTF-8 error. */
+ // Detected a UTF-8 error.
rewind_retry:
// Retry reading with another conversion.
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
if (*p_ccv != NUL && iconv_fd != (iconv_t)-1) {
// iconv() failed, try 'charconvert'
did_iconv = true;
} else {
-# endif
+#endif
// use next item from 'fileencodings'
advance_fenc = true;
-# ifdef HAVE_ICONV
- }
-# endif
+#ifdef HAVE_ICONV
+ }
+#endif
file_rewind = true;
goto retry;
}
}
- /* count the number of characters (after conversion!) */
+ // count the number of characters (after conversion!)
filesize += size;
/*
* when reading the first part of a file: guess EOL type
*/
if (fileformat == EOL_UNKNOWN) {
- /* First try finding a NL, for Dos and Unix */
+ // First try finding a NL, for Dos and Unix
if (try_dos || try_unix) {
// Reset the carriage return counter.
if (try_mac) {
@@ -1467,32 +1502,36 @@ rewind_retry:
for (p = ptr; p < ptr + size; ++p) {
if (*p == NL) {
if (!try_unix
- || (try_dos && p > ptr && p[-1] == CAR))
+ || (try_dos && p > ptr && p[-1] == CAR)) {
fileformat = EOL_DOS;
- else
+ } else {
fileformat = EOL_UNIX;
+ }
break;
} else if (*p == CAR && try_mac) {
try_mac++;
}
}
- /* Don't give in to EOL_UNIX if EOL_MAC is more likely */
+ // Don't give in to EOL_UNIX if EOL_MAC is more likely
if (fileformat == EOL_UNIX && try_mac) {
- /* Need to reset the counters when retrying fenc. */
+ // Need to reset the counters when retrying fenc.
try_mac = 1;
try_unix = 1;
- for (; p >= ptr && *p != CAR; p--)
+ for (; p >= ptr && *p != CAR; p--) {
;
+ }
if (p >= ptr) {
for (p = ptr; p < ptr + size; ++p) {
- if (*p == NL)
+ if (*p == NL) {
try_unix++;
- else if (*p == CAR)
+ } else if (*p == CAR) {
try_mac++;
+ }
}
- if (try_mac > try_unix)
+ if (try_mac > try_unix) {
fileformat = EOL_MAC;
+ }
}
} else if (fileformat == EOL_UNKNOWN && try_mac == 1) {
// Looking for CR but found no end-of-line markers at all:
@@ -1501,13 +1540,15 @@ rewind_retry:
}
}
- /* No NL found: may use Mac format */
- if (fileformat == EOL_UNKNOWN && try_mac)
+ // No NL found: may use Mac format
+ if (fileformat == EOL_UNKNOWN && try_mac) {
fileformat = EOL_MAC;
+ }
- /* Still nothing found? Use first format in 'ffs' */
- if (fileformat == EOL_UNKNOWN)
+ // Still nothing found? Use first format in 'ffs'
+ if (fileformat == EOL_UNKNOWN) {
fileformat = default_fileformat();
+ }
// May set 'p_ff' if editing a new file.
if (set_options) {
@@ -1523,44 +1564,48 @@ rewind_retry:
if (fileformat == EOL_MAC) {
--ptr;
while (++ptr, --size >= 0) {
- /* catch most common case first */
- if ((c = *ptr) != NUL && c != CAR && c != NL)
+ // catch most common case first
+ if ((c = *ptr) != NUL && c != CAR && c != NL) {
continue;
- if (c == NUL)
- *ptr = NL; /* NULs are replaced by newlines! */
- else if (c == NL)
- *ptr = CAR; /* NLs are replaced by CRs! */
- else {
+ }
+ if (c == NUL) {
+ *ptr = NL; // NULs are replaced by newlines!
+ } else if (c == NL) {
+ *ptr = CAR; // NLs are replaced by CRs!
+ } else {
if (skip_count == 0) {
- *ptr = NUL; /* end of line */
- len = (colnr_T) (ptr - line_start + 1);
+ *ptr = NUL; // end of line
+ len = (colnr_T)(ptr - line_start + 1);
if (ml_append(lnum, line_start, len, newfile) == FAIL) {
- error = TRUE;
+ error = true;
break;
}
- if (read_undo_file)
+ if (read_undo_file) {
sha256_update(&sha_ctx, line_start, len);
+ }
++lnum;
if (--read_count == 0) {
- error = TRUE; /* break loop */
- line_start = ptr; /* nothing left to write */
+ error = true; // break loop
+ line_start = ptr; // nothing left to write
break;
}
- } else
+ } else {
--skip_count;
+ }
line_start = ptr + 1;
}
}
} else {
--ptr;
while (++ptr, --size >= 0) {
- if ((c = *ptr) != NUL && c != NL) /* catch most common case */
+ if ((c = *ptr) != NUL && c != NL) { // catch most common case
continue;
- if (c == NUL)
- *ptr = NL; /* NULs are replaced by newlines! */
- else {
+ }
+ if (c == NUL) {
+ *ptr = NL; // NULs are replaced by newlines!
+ } else {
if (skip_count == 0) {
- *ptr = NUL; /* end of line */
+ *ptr = NUL; // end of line
len = (colnr_T)(ptr - line_start + 1);
if (fileformat == EOL_DOS) {
if (ptr > line_start && ptr[-1] == CAR) {
@@ -1577,8 +1622,9 @@ rewind_retry:
&& (read_buffer
|| vim_lseek(fd, (off_T)0L, SEEK_SET) == 0)) {
fileformat = EOL_UNIX;
- if (set_options)
+ if (set_options) {
set_fileformat(EOL_UNIX, OPT_LOCAL);
+ }
file_rewind = true;
keep_fileformat = true;
goto retry;
@@ -1587,31 +1633,34 @@ rewind_retry:
}
}
if (ml_append(lnum, line_start, len, newfile) == FAIL) {
- error = TRUE;
+ error = true;
break;
}
- if (read_undo_file)
+ if (read_undo_file) {
sha256_update(&sha_ctx, line_start, len);
+ }
++lnum;
if (--read_count == 0) {
- error = TRUE; /* break loop */
- line_start = ptr; /* nothing left to write */
+ error = true; // break loop
+ line_start = ptr; // nothing left to write
break;
}
- } else
+ } else {
--skip_count;
+ }
line_start = ptr + 1;
}
}
}
- linerest = (long)(ptr - line_start);
+ linerest = (ptr - line_start);
os_breakcheck();
}
failed:
- /* not an error, max. number of lines reached */
- if (error && read_count == 0)
- error = FALSE;
+ // not an error, max. number of lines reached
+ if (error && read_count == 0) {
+ error = false;
+ }
/*
* If we get EOF in the middle of a line, note the fact and
@@ -1625,16 +1674,18 @@ failed:
&& fileformat == EOL_DOS
&& *line_start == Ctrl_Z
&& ptr == line_start + 1)) {
- /* remember for when writing */
- if (set_options)
+ // remember for when writing
+ if (set_options) {
curbuf->b_p_eol = FALSE;
+ }
*ptr = NUL;
len = (colnr_T)(ptr - line_start + 1);
- if (ml_append(lnum, line_start, len, newfile) == FAIL)
- error = TRUE;
- else {
- if (read_undo_file)
+ if (ml_append(lnum, line_start, len, newfile) == FAIL) {
+ error = true;
+ } else {
+ if (read_undo_file) {
sha256_update(&sha_ctx, line_start, len);
+ }
read_no_eol_lnum = ++lnum;
}
}
@@ -1646,13 +1697,14 @@ failed:
// Also for ":read ++edit file".
set_string_option_direct("fenc", -1, fenc, OPT_FREE | OPT_LOCAL, 0);
}
- if (fenc_alloced)
+ if (fenc_alloced) {
xfree(fenc);
-# ifdef HAVE_ICONV
+ }
+#ifdef HAVE_ICONV
if (iconv_fd != (iconv_t)-1) {
iconv_close(iconv_fd);
}
-# endif
+#endif
if (!read_buffer && !read_stdin) {
close(fd); // errors are ignored
@@ -1679,13 +1731,13 @@ failed:
os_remove((char *)tmpname); // delete converted file
xfree(tmpname);
}
- --no_wait_return; /* may wait for return now */
+ --no_wait_return; // may wait for return now
/*
* In recovery mode everything but autocommands is skipped.
*/
if (!recoverymode) {
- /* need to delete the last line, which comes from the empty buffer */
+ // need to delete the last line, which comes from the empty buffer
if (newfile && wasempty && !(curbuf->b_ml.ml_flags & ML_EMPTY)) {
ml_delete(curbuf->b_ml.ml_line_count, false);
linecnt--;
@@ -1695,8 +1747,9 @@ failed:
curbuf->deleted_codepoints = 0;
curbuf->deleted_codeunits = 0;
linecnt = curbuf->b_ml.ml_line_count - linecnt;
- if (filesize == 0)
+ if (filesize == 0) {
linecnt = 0;
+ }
if (newfile || read_buffer) {
redraw_curbuf_later(NOT_VALID);
/* After reading the text into the buffer the diff info needs to
@@ -1705,8 +1758,9 @@ failed:
/* All folds in the window are invalid now. Mark them for update
* before triggering autocommands. */
foldUpdateAll(curwin);
- } else if (linecnt) /* appended at least one line */
+ } else if (linecnt) { // appended at least one line
appended_lines_mark(from, linecnt);
+ }
/*
* If we were reading from the same terminal as where messages go,
@@ -1720,12 +1774,13 @@ failed:
if (got_int) {
if (!(flags & READ_DUMMY)) {
filemess(curbuf, sfname, (char_u *)_(e_interr), 0);
- if (newfile)
- curbuf->b_p_ro = TRUE; /* must use "w!" now */
+ if (newfile) {
+ curbuf->b_p_ro = TRUE; // must use "w!" now
+ }
}
msg_scroll = msg_save;
check_marks_read();
- return OK; /* an interrupt isn't really an error */
+ return OK; // an interrupt isn't really an error
}
if (!filtering && !(flags & READ_DUMMY)) {
@@ -1742,7 +1797,7 @@ failed:
c = TRUE;
}
# ifdef OPEN_CHR_FILES
- if (S_ISCHR(perm)) { /* or character special */
+ if (S_ISCHR(perm)) { // or character special
STRCAT(IObuff, _("[character special]"));
c = TRUE;
}
@@ -1773,24 +1828,25 @@ failed:
}
if (conv_error != 0) {
sprintf((char *)IObuff + STRLEN(IObuff),
- _("[CONVERSION ERROR in line %" PRId64 "]"), (int64_t)conv_error);
+ _("[CONVERSION ERROR in line %" PRId64 "]"), (int64_t)conv_error);
c = TRUE;
} else if (illegal_byte > 0) {
sprintf((char *)IObuff + STRLEN(IObuff),
- _("[ILLEGAL BYTE in line %" PRId64 "]"), (int64_t)illegal_byte);
+ _("[ILLEGAL BYTE in line %" PRId64 "]"), (int64_t)illegal_byte);
c = TRUE;
- } else if (error) {
+ } else if (error) {
STRCAT(IObuff, _("[READ ERRORS]"));
c = TRUE;
}
- if (msg_add_fileformat(fileformat))
+ if (msg_add_fileformat(fileformat)) {
c = TRUE;
+ }
msg_add_lines(c, (long)linecnt, filesize);
XFREE_CLEAR(keep_msg);
p = NULL;
- msg_scrolled_ign = TRUE;
+ msg_scrolled_ign = true;
if (!read_stdin && !read_buffer) {
p = msg_trunc_attr(IObuff, FALSE, 0);
@@ -1805,28 +1861,30 @@ failed:
// - When the screen was scrolled but there is no wait-return prompt.
set_keep_msg(p, 0);
}
- msg_scrolled_ign = FALSE;
+ msg_scrolled_ign = false;
}
- /* with errors writing the file requires ":w!" */
+ // with errors writing the file requires ":w!"
if (newfile && (error
|| conv_error != 0
|| (illegal_byte > 0 && bad_char_behavior != BAD_KEEP)
- ))
+ )) {
curbuf->b_p_ro = TRUE;
+ }
- u_clearline(); /* cannot use "U" command after adding lines */
+ u_clearline(); // cannot use "U" command after adding lines
/*
* In Ex mode: cursor at last new line.
* Otherwise: cursor at first new line.
*/
- if (exmode_active)
+ if (exmode_active) {
curwin->w_cursor.lnum = from + linecnt;
- else
+ } else {
curwin->w_cursor.lnum = from + 1;
+ }
check_cursor_lnum();
- beginline(BL_WHITE | BL_FIX); /* on first non-blank */
+ beginline(BL_WHITE | BL_FIX); // on first non-blank
/*
* Set '[ and '] marks to the newly read lines.
@@ -1835,7 +1893,6 @@ failed:
curbuf->b_op_start.col = 0;
curbuf->b_op_end.lnum = from + linecnt;
curbuf->b_op_end.col = 0;
-
}
msg_scroll = msg_save;
@@ -1854,8 +1911,9 @@ failed:
/* When reloading a buffer put the cursor at the first line that is
* different. */
- if (flags & READ_KEEP_UNDO)
+ if (flags & READ_KEEP_UNDO) {
u_find_first_changed();
+ }
/*
* When opening a new file locate undo info and read it.
@@ -1873,8 +1931,9 @@ failed:
/* Save the fileformat now, otherwise the buffer will be considered
* modified if the format/encoding was automatically detected. */
- if (set_options)
+ if (set_options) {
save_file_ff(curbuf);
+ }
/*
* The output from the autocommands should not overwrite anything and
@@ -1906,8 +1965,9 @@ failed:
}
}
- if (recoverymode && error)
+ if (recoverymode && error) {
return FAIL;
+ }
return OK;
}
@@ -1930,25 +1990,24 @@ bool is_dev_fd_file(char_u *fname)
#endif
-/*
- * From the current line count and characters read after that, estimate the
- * line number where we are now.
- * Used for error messages that include a line number.
- */
-static linenr_T
-readfile_linenr(
- linenr_T linecnt, // line count before reading more bytes
- char_u *p, // start of more bytes read
- char_u *endp // end of more bytes read
-)
+/// From the current line count and characters read after that, estimate the
+/// line number where we are now.
+/// Used for error messages that include a line number.
+///
+/// @param linecnt line count before reading more bytes
+/// @param p start of more bytes read
+/// @param endp end of more bytes read
+static linenr_T readfile_linenr(linenr_T linecnt, char_u *p, char_u *endp)
{
- char_u *s;
+ char_u *s;
linenr_T lnum;
lnum = curbuf->b_ml.ml_line_count - linecnt + 1;
- for (s = p; s < endp; ++s)
- if (*s == '\n')
+ for (s = p; s < endp; ++s) {
+ if (*s == '\n') {
++lnum;
+ }
+ }
return lnum;
}
@@ -1977,15 +2036,16 @@ void prep_exarg(exarg_T *eap, const buf_T *buf)
*/
void set_file_options(int set_options, exarg_T *eap)
{
- /* set default 'fileformat' */
+ // set default 'fileformat'
if (set_options) {
- if (eap != NULL && eap->force_ff != 0)
+ if (eap != NULL && eap->force_ff != 0) {
set_fileformat(get_fileformat_force(curbuf, eap), OPT_LOCAL);
- else if (*p_ffs != NUL)
+ } else if (*p_ffs != NUL) {
set_fileformat(default_fileformat(), OPT_LOCAL);
+ }
}
- /* set or reset 'binary' */
+ // set or reset 'binary'
if (eap != NULL && eap->force_bin != 0) {
int oldval = curbuf->b_p_bin;
@@ -2015,8 +2075,8 @@ void set_forced_fenc(exarg_T *eap)
static char_u *next_fenc(char_u **pp, bool *alloced)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET
{
- char_u *p;
- char_u *r;
+ char_u *p;
+ char_u *r;
*alloced = false;
if (**pp == NUL) {
@@ -2038,29 +2098,26 @@ static char_u *next_fenc(char_u **pp, bool *alloced)
return r;
}
-/*
- * Convert a file with the 'charconvert' expression.
- * This closes the file which is to be read, converts it and opens the
- * resulting file for reading.
- * Returns name of the resulting converted file (the caller should delete it
- * after reading it).
- * Returns NULL if the conversion failed ("*fdp" is not set) .
- */
-static char_u *
-readfile_charconvert (
- char_u *fname, /* name of input file */
- char_u *fenc, /* converted from */
- int *fdp /* in/out: file descriptor of file */
-)
+/// Convert a file with the 'charconvert' expression.
+/// This closes the file which is to be read, converts it and opens the
+/// resulting file for reading.
+///
+/// @param fname name of input file
+/// @param fenc converted from
+/// @param fdp in/out: file descriptor of file
+///
+/// @return name of the resulting converted file (the caller should delete it after reading it).
+/// Returns NULL if the conversion failed ("*fdp" is not set) .
+static char_u *readfile_charconvert(char_u *fname, char_u *fenc, int *fdp)
{
- char_u *tmpname;
- char_u *errmsg = NULL;
+ char_u *tmpname;
+ char_u *errmsg = NULL;
tmpname = vim_tempname();
- if (tmpname == NULL)
+ if (tmpname == NULL) {
errmsg = (char_u *)_("Can't find temp file for conversion");
- else {
- close(*fdp); /* close the input file, ignore errors */
+ } else {
+ close(*fdp); // close the input file, ignore errors
*fdp = -1;
if (eval_charconvert((char *)fenc, "utf-8",
(char *)fname, (char *)tmpname) == FAIL) {
@@ -2081,7 +2138,7 @@ readfile_charconvert (
}
}
- /* If the input file is closed, open it (caller should check for error). */
+ // If the input file is closed, open it (caller should check for error).
if (*fdp < 0) {
*fdp = os_open((char *)fname, O_RDONLY, 0);
}
@@ -2111,45 +2168,35 @@ char *new_file_message(void)
return shortmess(SHM_NEW) ? _("[New]") : _("[New File]");
}
-/*
- * buf_write() - write to file "fname" lines "start" through "end"
- *
- * We do our own buffering here because fwrite() is so slow.
- *
- * If "forceit" is true, we don't care for errors when attempting backups.
- * In case of an error everything possible is done to restore the original
- * file. But when "forceit" is TRUE, we risk losing it.
- *
- * When "reset_changed" is TRUE and "append" == FALSE and "start" == 1 and
- * "end" == curbuf->b_ml.ml_line_count, reset curbuf->b_changed.
- *
- * This function must NOT use NameBuff (because it's called by autowrite()).
- *
- * return FAIL for failure, OK otherwise
- */
-int
-buf_write(
- buf_T *buf,
- char_u *fname,
- char_u *sfname,
- linenr_T start,
- linenr_T end,
- exarg_T *eap, /* for forced 'ff' and 'fenc', can be
- NULL! */
- int append, /* append to the file */
- int forceit,
- int reset_changed,
- int filtering
-)
+/// buf_write() - write to file "fname" lines "start" through "end"
+///
+/// We do our own buffering here because fwrite() is so slow.
+///
+/// If "forceit" is true, we don't care for errors when attempting backups.
+/// In case of an error everything possible is done to restore the original
+/// file. But when "forceit" is TRUE, we risk losing it.
+///
+/// When "reset_changed" is TRUE and "append" == FALSE and "start" == 1 and
+/// "end" == curbuf->b_ml.ml_line_count, reset curbuf->b_changed.
+///
+/// This function must NOT use NameBuff (because it's called by autowrite()).
+///
+///
+/// @param eap for forced 'ff' and 'fenc', can be NULL!
+/// @param append append to the file
+///
+/// @return FAIL for failure, OK otherwise
+int buf_write(buf_T *buf, char_u *fname, char_u *sfname, linenr_T start, linenr_T end, exarg_T *eap,
+ int append, int forceit, int reset_changed, int filtering)
{
int fd;
- char_u *backup = NULL;
- int backup_copy = FALSE; /* copy the original file? */
+ char_u *backup = NULL;
+ int backup_copy = FALSE; // copy the original file?
int dobackup;
- char_u *ffname;
- char_u *wfname = NULL; /* name of file to write to */
- char_u *s;
- char_u *ptr;
+ char_u *ffname;
+ char_u *wfname = NULL; // name of file to write to
+ char_u *s;
+ char_u *ptr;
char_u c;
int len;
linenr_T lnum;
@@ -2164,9 +2211,9 @@ buf_write(
char *errmsg = NULL;
int errmsgarg = 0;
bool errmsg_allocated = false;
- char_u *buffer;
+ char_u *buffer;
char_u smallbuf[SMBUFSIZE];
- char_u *backup_ext;
+ char_u *backup_ext;
int bufsize;
long perm; // file permissions
int retval = OK;
@@ -2178,21 +2225,21 @@ buf_write(
int prev_got_int = got_int;
int checking_conversion;
bool file_readonly = false; // overwritten file is read-only
- static char *err_readonly =
+ static char *err_readonly =
"is read-only (cannot override: \"W\" in 'cpoptions')";
#if defined(UNIX)
- int made_writable = FALSE; /* 'w' bit has been set */
+ int made_writable = FALSE; // 'w' bit has been set
#endif
- /* writing everything */
+ // writing everything
int whole = (start == 1 && end == buf->b_ml.ml_line_count);
linenr_T old_line_count = buf->b_ml.ml_line_count;
int fileformat;
int write_bin;
- struct bw_info write_info; /* info for buf_write_bytes() */
+ struct bw_info write_info; // info for buf_write_bytes()
int converted = FALSE;
int notconverted = FALSE;
- char_u *fenc; /* effective 'fileencoding' */
- char_u *fenc_tofree = NULL; /* allocated "fenc" */
+ char_u *fenc; // effective 'fileencoding'
+ char_u *fenc_tofree = NULL; // allocated "fenc"
#ifdef HAS_BW_FLAGS
int wb_flags = 0;
#endif
@@ -2204,8 +2251,9 @@ buf_write(
context_sha256_T sha_ctx;
unsigned int bkc = get_bkc_value(buf);
- if (fname == NULL || *fname == NUL) /* safety check */
+ if (fname == NULL || *fname == NUL) { // safety check
return FAIL;
+ }
if (buf->b_ml.ml_mfp == NULL) {
/* This can happen during startup when there is a stray "w" in the
* vimrc file. */
@@ -2217,27 +2265,28 @@ buf_write(
* Disallow writing from .exrc and .vimrc in current directory for
* security reasons.
*/
- if (check_secure())
+ if (check_secure()) {
return FAIL;
+ }
- /* Avoid a crash for a long name. */
+ // Avoid a crash for a long name.
if (STRLEN(fname) >= MAXPATHL) {
EMSG(_(e_longname));
return FAIL;
}
- /* must init bw_conv_buf and bw_iconv_fd before jumping to "fail" */
+ // must init bw_conv_buf and bw_iconv_fd before jumping to "fail"
write_info.bw_conv_buf = NULL;
write_info.bw_conv_error = FALSE;
write_info.bw_conv_error_lnum = 0;
write_info.bw_restlen = 0;
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
write_info.bw_iconv_fd = (iconv_t)-1;
-# endif
+#endif
/* After writing a file changedtick changes but we don't want to display
* the line. */
- ex_no_reprint = TRUE;
+ ex_no_reprint = true;
/*
* If there is no file name yet, use the one for the written file.
@@ -2254,13 +2303,15 @@ buf_write(
&& !filtering
&& (!append || vim_strchr(p_cpo, CPO_FNAMEAPP) != NULL)
&& vim_strchr(p_cpo, CPO_FNAMEW) != NULL) {
- if (set_rw_fname(fname, sfname) == FAIL)
+ if (set_rw_fname(fname, sfname) == FAIL) {
return FAIL;
- buf = curbuf; /* just in case autocmds made "buf" invalid */
+ }
+ buf = curbuf; // just in case autocmds made "buf" invalid
}
- if (sfname == NULL)
+ if (sfname == NULL) {
sfname = fname;
+ }
// For Unix: Use the short file name whenever possible.
// Avoids problems with networks and when directory names are changed.
@@ -2271,12 +2322,13 @@ buf_write(
fname = sfname;
#endif
- if (buf->b_ffname != NULL && fnamecmp(ffname, buf->b_ffname) == 0)
+ if (buf->b_ffname != NULL && fnamecmp(ffname, buf->b_ffname) == 0) {
overwriting = TRUE;
- else
+ } else {
overwriting = FALSE;
+ }
- ++no_wait_return; /* don't wait for return yet */
+ ++no_wait_return; // don't wait for return yet
/*
* Set '[ and '] marks to the lines to be written.
@@ -2302,14 +2354,18 @@ buf_write(
* Set curbuf to the buffer to be written.
* Careful: The autocommands may call buf_write() recursively!
*/
- if (ffname == buf->b_ffname)
+ if (ffname == buf->b_ffname) {
buf_ffname = TRUE;
- if (sfname == buf->b_sfname)
+ }
+ if (sfname == buf->b_sfname) {
buf_sfname = TRUE;
- if (fname == buf->b_ffname)
+ }
+ if (fname == buf->b_ffname) {
buf_fname_f = TRUE;
- if (fname == buf->b_sfname)
+ }
+ if (fname == buf->b_sfname) {
buf_fname_s = TRUE;
+ }
// Set curwin/curbuf to buf and save a few things.
aucmd_prepbuf(&aco, buf);
@@ -2317,21 +2373,22 @@ buf_write(
if (append) {
if (!(did_cmd = apply_autocmds_exarg(EVENT_FILEAPPENDCMD,
- sfname, sfname, FALSE, curbuf, eap))) {
- if (overwriting && bt_nofile(curbuf))
+ sfname, sfname, FALSE, curbuf, eap))) {
+ if (overwriting && bt_nofile(curbuf)) {
nofile_err = TRUE;
- else
+ } else {
apply_autocmds_exarg(EVENT_FILEAPPENDPRE,
- sfname, sfname, FALSE, curbuf, eap);
+ sfname, sfname, FALSE, curbuf, eap);
+ }
}
} else if (filtering) {
apply_autocmds_exarg(EVENT_FILTERWRITEPRE,
- NULL, sfname, FALSE, curbuf, eap);
- } else if (reset_changed && whole) {
+ NULL, sfname, FALSE, curbuf, eap);
+ } else if (reset_changed && whole) {
int was_changed = curbufIsChanged();
did_cmd = apply_autocmds_exarg(EVENT_BUFWRITECMD,
- sfname, sfname, FALSE, curbuf, eap);
+ sfname, sfname, FALSE, curbuf, eap);
if (did_cmd) {
if (was_changed && !curbufIsChanged()) {
/* Written everything correctly and BufWriteCmd has reset
@@ -2341,24 +2398,26 @@ buf_write(
u_update_save_nr(curbuf);
}
} else {
- if (overwriting && bt_nofile(curbuf))
+ if (overwriting && bt_nofile(curbuf)) {
nofile_err = TRUE;
- else
+ } else {
apply_autocmds_exarg(EVENT_BUFWRITEPRE,
- sfname, sfname, FALSE, curbuf, eap);
+ sfname, sfname, FALSE, curbuf, eap);
+ }
}
} else {
if (!(did_cmd = apply_autocmds_exarg(EVENT_FILEWRITECMD,
- sfname, sfname, FALSE, curbuf, eap))) {
- if (overwriting && bt_nofile(curbuf))
+ sfname, sfname, FALSE, curbuf, eap))) {
+ if (overwriting && bt_nofile(curbuf)) {
nofile_err = TRUE;
- else
+ } else {
apply_autocmds_exarg(EVENT_FILEWRITEPRE,
- sfname, sfname, FALSE, curbuf, eap);
+ sfname, sfname, FALSE, curbuf, eap);
+ }
}
}
- /* restore curwin/curbuf and a few other things */
+ // restore curwin/curbuf and a few other things
aucmd_restbuf(&aco);
// In three situations we return here and don't write the file:
@@ -2370,41 +2429,45 @@ buf_write(
}
if (buf == NULL || (buf->b_ml.ml_mfp == NULL && !empty_memline)
|| did_cmd || nofile_err
- || aborting()
- ) {
+ || aborting()) {
--no_wait_return;
msg_scroll = msg_save;
- if (nofile_err)
+ if (nofile_err) {
EMSG(_("E676: No matching autocommands for acwrite buffer"));
+ }
if (nofile_err
- || aborting()
- )
+ || aborting()) {
/* An aborting error, interrupt or exception in the
* autocommands. */
return FAIL;
+ }
if (did_cmd) {
- if (buf == NULL)
+ if (buf == NULL) {
/* The buffer was deleted. We assume it was written
* (can't retry anyway). */
return OK;
+ }
if (overwriting) {
- /* Assume the buffer was written, update the timestamp. */
+ // Assume the buffer was written, update the timestamp.
ml_timestamp(buf);
- if (append)
+ if (append) {
buf->b_flags &= ~BF_NEW;
- else
+ } else {
buf->b_flags &= ~BF_WRITE_MASK;
+ }
}
if (reset_changed && buf->b_changed && !append
- && (overwriting || vim_strchr(p_cpo, CPO_PLUS) != NULL))
+ && (overwriting || vim_strchr(p_cpo, CPO_PLUS) != NULL)) {
/* Buffer still changed, the autocommands didn't work
* properly. */
return FAIL;
+ }
return OK;
}
- if (!aborting())
+ if (!aborting()) {
EMSG(_("E203: Autocommands deleted or unloaded buffer to be written"));
+ }
return FAIL;
}
@@ -2415,11 +2478,11 @@ buf_write(
* changed the number of lines that are to be written (tricky!).
*/
if (buf->b_ml.ml_line_count != old_line_count) {
- if (whole) /* write all */
+ if (whole) { // write all
end = buf->b_ml.ml_line_count;
- else if (buf->b_ml.ml_line_count > old_line_count) /* more lines */
+ } else if (buf->b_ml.ml_line_count > old_line_count) { // more lines
end += buf->b_ml.ml_line_count - old_line_count;
- else { /* less lines */
+ } else { // less lines
end -= old_line_count - buf->b_ml.ml_line_count;
if (end < start) {
--no_wait_return;
@@ -2434,30 +2497,36 @@ buf_write(
* The autocommands may have changed the name of the buffer, which may
* be kept in fname, ffname and sfname.
*/
- if (buf_ffname)
+ if (buf_ffname) {
ffname = buf->b_ffname;
- if (buf_sfname)
+ }
+ if (buf_sfname) {
sfname = buf->b_sfname;
- if (buf_fname_f)
+ }
+ if (buf_fname_f) {
fname = buf->b_ffname;
- if (buf_fname_s)
+ }
+ if (buf_fname_s) {
fname = buf->b_sfname;
+ }
}
- if (shortmess(SHM_OVER) && !exiting)
- msg_scroll = FALSE; /* overwrite previous file message */
- else
- msg_scroll = TRUE; /* don't overwrite previous file message */
- if (!filtering)
+ if (shortmess(SHM_OVER) && !exiting) {
+ msg_scroll = FALSE; // overwrite previous file message
+ } else {
+ msg_scroll = TRUE; // don't overwrite previous file message
+ }
+ if (!filtering) {
filemess(buf,
#ifndef UNIX
- sfname,
+ sfname,
#else
- fname,
+ fname,
#endif
- (char_u *)"", 0); /* show that we are busy */
- msg_scroll = FALSE; /* always overwrite the file message now */
+ (char_u *)"", 0); // show that we are busy
+ }
+ msg_scroll = FALSE; // always overwrite the file message now
buffer = verbose_try_malloc(BUFSIZE);
// can't allocate big buffer, use small one (to be able to write when out of
@@ -2465,8 +2534,9 @@ buf_write(
if (buffer == NULL) {
buffer = smallbuf;
bufsize = SMBUFSIZE;
- } else
+ } else {
bufsize = BUFSIZE;
+ }
/*
* Get information about original file (if there is one).
@@ -2478,7 +2548,7 @@ buf_write(
newfile = TRUE;
} else {
perm = file_info_old.stat.st_mode;
- if (!S_ISREG(file_info_old.stat.st_mode)) { /* not a file */
+ if (!S_ISREG(file_info_old.stat.st_mode)) { // not a file
if (S_ISDIR(file_info_old.stat.st_mode)) {
SET_ERRMSG_NUM("E502", _("is a directory"));
goto fail;
@@ -2540,8 +2610,9 @@ buf_write(
*/
if (overwriting) {
retval = check_mtime(buf, &file_info_old);
- if (retval == FAIL)
+ if (retval == FAIL) {
goto fail;
+ }
}
}
@@ -2549,16 +2620,18 @@ buf_write(
/*
* For systems that support ACL: get the ACL from the original file.
*/
- if (!newfile)
+ if (!newfile) {
acl = mch_get_acl(fname);
+ }
#endif
/*
* If 'backupskip' is not empty, don't make a backup for some files.
*/
dobackup = (p_wb || p_bk || *p_pm != NUL);
- if (dobackup && *p_bsk != NUL && match_file_list(p_bsk, sfname, ffname))
+ if (dobackup && *p_bsk != NUL && match_file_list(p_bsk, sfname, ffname)) {
dobackup = FALSE;
+ }
/*
* Save the value of got_int and reset it. We don't want a previous
@@ -2568,7 +2641,7 @@ buf_write(
prev_got_int = got_int;
got_int = FALSE;
- /* Mark the buffer as 'being saved' to prevent changed buffer warnings */
+ // Mark the buffer as 'being saved' to prevent changed buffer warnings
buf->b_saving = true;
/*
@@ -2583,9 +2656,9 @@ buf_write(
FileInfo file_info;
const bool no_prepend_dot = false;
- if ((bkc & BKC_YES) || append) { /* "yes" */
+ if ((bkc & BKC_YES) || append) { // "yes"
backup_copy = TRUE;
- } else if ((bkc & BKC_AUTO)) { /* "auto" */
+ } else if ((bkc & BKC_AUTO)) { // "auto"
int i;
/*
@@ -2613,11 +2686,11 @@ buf_write(
}
}
fd = os_open((char *)IObuff,
- O_CREAT|O_WRONLY|O_EXCL|O_NOFOLLOW, perm);
- if (fd < 0) /* can't write in directory */
+ O_CREAT|O_WRONLY|O_EXCL|O_NOFOLLOW, perm);
+ if (fd < 0) { // can't write in directory
backup_copy = TRUE;
- else {
-# ifdef UNIX
+ } else {
+#ifdef UNIX
os_fchown(fd, file_info_old.stat.st_uid, file_info_old.stat.st_gid);
if (!os_fileinfo((char *)IObuff, &file_info)
|| file_info.stat.st_uid != file_info_old.stat.st_uid
@@ -2625,7 +2698,7 @@ buf_write(
|| (long)file_info.stat.st_mode != perm) {
backup_copy = TRUE;
}
-# endif
+#endif
/* Close the file before removing it, on MS-Windows we
* can't delete an open file. */
close(fd);
@@ -2638,38 +2711,39 @@ buf_write(
* Break symlinks and/or hardlinks if we've been asked to.
*/
if ((bkc & BKC_BREAKSYMLINK) || (bkc & BKC_BREAKHARDLINK)) {
-# ifdef UNIX
+#ifdef UNIX
bool file_info_link_ok = os_fileinfo_link((char *)fname, &file_info);
- /* Symlinks. */
+ // Symlinks.
if ((bkc & BKC_BREAKSYMLINK)
&& file_info_link_ok
&& !os_fileinfo_id_equal(&file_info, &file_info_old)) {
backup_copy = FALSE;
}
- /* Hardlinks. */
+ // Hardlinks.
if ((bkc & BKC_BREAKHARDLINK)
&& os_fileinfo_hardlinks(&file_info_old) > 1
&& (!file_info_link_ok
|| os_fileinfo_id_equal(&file_info, &file_info_old))) {
backup_copy = FALSE;
}
-# endif
+#endif
}
- /* make sure we have a valid backup extension to use */
- if (*p_bex == NUL)
+ // make sure we have a valid backup extension to use
+ if (*p_bex == NUL) {
backup_ext = (char_u *)".bak";
- else
+ } else {
backup_ext = p_bex;
+ }
if (backup_copy) {
char_u *wp;
int some_error = false;
- char_u *dirp;
- char_u *rootname;
- char_u *p;
+ char_u *dirp;
+ char_u *rootname;
+ char_u *p;
/*
* Try to make the backup in each directory in the 'bdir' option.
@@ -2688,9 +2762,22 @@ buf_write(
/*
* Isolate one directory name, using an entry in 'bdir'.
*/
- (void)copy_option_part(&dirp, IObuff, IOSIZE, ",");
- p = IObuff + STRLEN(IObuff);
- if (after_pathsep((char *)IObuff, (char *)p) && p[-1] == p[-2]) {
+ size_t dir_len = copy_option_part(&dirp, IObuff, IOSIZE, ",");
+ p = IObuff + dir_len;
+ bool trailing_pathseps = after_pathsep((char *)IObuff, (char *)p) && p[-1] == p[-2];
+ if (trailing_pathseps) {
+ IObuff[dir_len - 2] = NUL;
+ }
+ if (*dirp == NUL && !os_isdir(IObuff)) {
+ int ret;
+ char *failed_dir;
+ if ((ret = os_mkdir_recurse((char *)IObuff, 0755, &failed_dir)) != 0) {
+ EMSG3(_("E303: Unable to create directory \"%s\" for backup file: %s"),
+ failed_dir, os_strerror(ret));
+ xfree(failed_dir);
+ }
+ }
+ if (trailing_pathseps) {
// Ends with '//', Use Full path
if ((p = (char_u *)make_percent_swname((char *)IObuff, (char *)fname))
!= NULL) {
@@ -2702,7 +2789,7 @@ buf_write(
rootname = get_file_in_dir(fname, IObuff);
if (rootname == NULL) {
- some_error = TRUE; /* out of memory */
+ some_error = TRUE; // out of memory
goto nobackup;
}
@@ -2718,7 +2805,7 @@ buf_write(
if (backup == NULL) {
xfree(rootname);
- some_error = TRUE; /* out of memory */
+ some_error = TRUE; // out of memory
goto nobackup;
}
@@ -2761,7 +2848,7 @@ buf_write(
* Try to create the backup file
*/
if (backup != NULL) {
- /* remove old backup, if present */
+ // remove old backup, if present
os_remove((char *)backup);
// set file protection same as original file, but
@@ -2802,8 +2889,7 @@ buf_write(
nobackup:
if (backup == NULL && errmsg == NULL) {
- SET_ERRMSG(_(
- "E509: Cannot create backup file (add ! to override)"));
+ SET_ERRMSG(_("E509: Cannot create backup file (add ! to override)"));
}
// Ignore errors when forceit is TRUE.
if ((some_error || errmsg != NULL) && !forceit) {
@@ -2812,9 +2898,9 @@ nobackup:
}
SET_ERRMSG(NULL);
} else {
- char_u *dirp;
- char_u *p;
- char_u *rootname;
+ char_u *dirp;
+ char_u *p;
+ char_u *rootname;
/*
* Make a backup by renaming the original file.
@@ -2840,9 +2926,22 @@ nobackup:
/*
* Isolate one directory name and make the backup file name.
*/
- (void)copy_option_part(&dirp, IObuff, IOSIZE, ",");
- p = IObuff + STRLEN(IObuff);
- if (after_pathsep((char *)IObuff, (char *)p) && p[-1] == p[-2]) {
+ size_t dir_len = copy_option_part(&dirp, IObuff, IOSIZE, ",");
+ p = IObuff + dir_len;
+ bool trailing_pathseps = after_pathsep((char *)IObuff, (char *)p) && p[-1] == p[-2];
+ if (trailing_pathseps) {
+ IObuff[dir_len - 2] = NUL;
+ }
+ if (*dirp == NUL && !os_isdir(IObuff)) {
+ int ret;
+ char *failed_dir;
+ if ((ret = os_mkdir_recurse((char *)IObuff, 0755, &failed_dir)) != 0) {
+ EMSG3(_("E303: Unable to create directory \"%s\" for backup file: %s"),
+ failed_dir, os_strerror(ret));
+ xfree(failed_dir);
+ }
+ }
+ if (trailing_pathseps) {
// path ends with '//', use full path
if ((p = (char_u *)make_percent_swname((char *)IObuff, (char *)fname))
!= NULL) {
@@ -2871,8 +2970,9 @@ nobackup:
*/
if (!p_bk && os_path_exists(backup)) {
p = backup + STRLEN(backup) - 1 - STRLEN(backup_ext);
- if (p < backup) /* empty file name ??? */
+ if (p < backup) { // empty file name ???
p = backup;
+ }
*p = 'z';
while (*p > 'a' && os_path_exists(backup)) {
(*p)--;
@@ -2925,10 +3025,12 @@ nobackup:
status_redraw_all(); // redraw status lines later
}
- if (end > buf->b_ml.ml_line_count)
+ if (end > buf->b_ml.ml_line_count) {
end = buf->b_ml.ml_line_count;
- if (buf->b_ml.ml_flags & ML_EMPTY)
+ }
+ if (buf->b_ml.ml_flags & ML_EMPTY) {
start = end + 1;
+ }
// If the original file is being overwritten, there is a small chance that
// we crash in the middle of writing. Therefore the file is preserved now.
@@ -2983,12 +3085,12 @@ nobackup:
if (converted && wb_flags == 0) {
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
// Use iconv() conversion when conversion is needed and it's not done
// internally.
write_info.bw_iconv_fd = (iconv_t)my_iconv_open(fenc, (char_u *)"utf-8");
if (write_info.bw_iconv_fd != (iconv_t)-1) {
- /* We're going to use iconv(), allocate a buffer to convert in. */
+ // We're going to use iconv(), allocate a buffer to convert in.
write_info.bw_conv_buflen = bufsize * ICONV_MULT;
write_info.bw_conv_buf = verbose_try_malloc(write_info.bw_conv_buflen);
if (!write_info.bw_conv_buf) {
@@ -2996,7 +3098,7 @@ nobackup:
}
write_info.bw_first = TRUE;
} else
-# endif
+#endif
/*
* When the file needs to be converted with 'charconvert' after
@@ -3012,14 +3114,12 @@ nobackup:
}
}
if (converted && wb_flags == 0
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
&& write_info.bw_iconv_fd == (iconv_t)-1
-# endif
- && wfname == fname
- ) {
+#endif
+ && wfname == fname) {
if (!forceit) {
- SET_ERRMSG(_(
- "E213: Cannot convert (add ! to write without conversion)"));
+ SET_ERRMSG(_("E213: Cannot convert (add ! to write without conversion)"));
goto restore_backup;
}
notconverted = TRUE;
@@ -3054,7 +3154,7 @@ nobackup:
O_WRONLY |
(append ?
(forceit ? (O_APPEND | O_CREAT) : O_APPEND)
- : (O_CREAT | O_TRUNC))
+ : (O_CREAT | O_TRUNC))
, perm < 0 ? 0666 : (perm & 0777))) < 0) {
// A forced write will try to create a new file if the old one
// is still readonly. This may also happen when the directory
@@ -3070,28 +3170,28 @@ nobackup:
SET_ERRMSG(_("E166: Can't open linked file for writing"));
} else {
#endif
- SET_ERRMSG_ARG(_("E212: Can't open file for writing: %s"), fd);
- if (forceit && vim_strchr(p_cpo, CPO_FWRITE) == NULL
- && perm >= 0) {
+ SET_ERRMSG_ARG(_("E212: Can't open file for writing: %s"), fd);
+ if (forceit && vim_strchr(p_cpo, CPO_FWRITE) == NULL
+ && perm >= 0) {
#ifdef UNIX
- // we write to the file, thus it should be marked
- // writable after all
- if (!(perm & 0200)) {
- made_writable = true;
- }
- perm |= 0200;
- if (file_info_old.stat.st_uid != getuid()
- || file_info_old.stat.st_gid != getgid()) {
- perm &= 0777;
- }
+ // we write to the file, thus it should be marked
+ // writable after all
+ if (!(perm & 0200)) {
+ made_writable = true;
+ }
+ perm |= 0200;
+ if (file_info_old.stat.st_uid != getuid()
+ || file_info_old.stat.st_gid != getgid()) {
+ perm &= 0777;
+ }
#endif
- if (!append) { // don't remove when appending
- os_remove((char *)wfname);
- }
- continue;
+ if (!append) { // don't remove when appending
+ os_remove((char *)wfname);
}
-#ifdef UNIX
+ continue;
}
+#ifdef UNIX
+ }
#endif
}
@@ -3256,7 +3356,7 @@ restore_backup:
// Stop when writing done or an error was encountered.
if (!checking_conversion || end == 0) {
- break;
+ break;
}
// If no error happened until now, writing should be ok, so loop to
@@ -3345,17 +3445,15 @@ restore_backup:
if (errmsg == NULL) {
if (write_info.bw_conv_error) {
if (write_info.bw_conv_error_lnum == 0) {
- SET_ERRMSG(_(
- "E513: write error, conversion failed "
- "(make 'fenc' empty to override)"));
+ SET_ERRMSG(_("E513: write error, conversion failed "
+ "(make 'fenc' empty to override)"));
} else {
errmsg_allocated = true;
SET_ERRMSG(xmalloc(300));
- vim_snprintf(
- errmsg, 300,
- _("E513: write error, conversion failed in line %" PRIdLINENR
- " (make 'fenc' empty to override)"),
- write_info.bw_conv_error_lnum);
+ vim_snprintf(errmsg, 300,
+ _("E513: write error, conversion failed in line %" PRIdLINENR
+ " (make 'fenc' empty to override)"),
+ write_info.bw_conv_error_lnum);
}
} else if (got_int) {
SET_ERRMSG(_(e_interr));
@@ -3394,11 +3492,11 @@ restore_backup:
goto fail;
}
- lnum -= start; /* compute number of written lines */
- --no_wait_return; /* may wait for return now */
+ lnum -= start; // compute number of written lines
+ --no_wait_return; // may wait for return now
#if !defined(UNIX)
- fname = sfname; /* use shortname now, for the messages */
+ fname = sfname; // use shortname now, for the messages
#endif
if (!filtering) {
add_quoted_fname((char *)IObuff, IOSIZE, buf, (const char *)fname);
@@ -3406,9 +3504,10 @@ restore_backup:
if (write_info.bw_conv_error) {
STRCAT(IObuff, _(" CONVERSION ERROR"));
c = TRUE;
- if (write_info.bw_conv_error_lnum != 0)
+ if (write_info.bw_conv_error_lnum != 0) {
vim_snprintf_add((char *)IObuff, IOSIZE, _(" in line %" PRId64 ";"),
- (int64_t)write_info.bw_conv_error_lnum);
+ (int64_t)write_info.bw_conv_error_lnum);
+ }
} else if (notconverted) {
STRCAT(IObuff, _("[NOT converted]"));
c = TRUE;
@@ -3427,15 +3526,17 @@ restore_backup:
msg_add_eol();
c = TRUE;
}
- /* may add [unix/dos/mac] */
- if (msg_add_fileformat(fileformat))
+ // may add [unix/dos/mac]
+ if (msg_add_fileformat(fileformat)) {
c = TRUE;
- msg_add_lines(c, (long)lnum, nchars); /* add line/char count */
+ }
+ msg_add_lines(c, (long)lnum, nchars); // add line/char count
if (!shortmess(SHM_WRITE)) {
- if (append)
+ if (append) {
STRCAT(IObuff, shortmess(SHM_WRI) ? _(" [a]") : _(" appended"));
- else
+ } else {
STRCAT(IObuff, shortmess(SHM_WRI) ? _(" [w]") : _(" written"));
+ }
}
set_keep_msg(msg_trunc_attr(IObuff, FALSE, 0), 0);
@@ -3463,10 +3564,11 @@ restore_backup:
*/
if (overwriting) {
ml_timestamp(buf);
- if (append)
+ if (append) {
buf->b_flags &= ~BF_NEW;
- else
+ } else {
buf->b_flags &= ~BF_WRITE_MASK;
+ }
}
/*
@@ -3502,11 +3604,12 @@ restore_backup:
if (org == NULL
|| (empty_fd = os_open(org,
- O_CREAT | O_EXCL | O_NOFOLLOW,
- perm < 0 ? 0666 : (perm & 0777))) < 0)
+ O_CREAT | O_EXCL | O_NOFOLLOW,
+ perm < 0 ? 0666 : (perm & 0777))) < 0) {
EMSG(_("E206: patchmode: can't touch empty original file"));
- else
+ } else {
close(empty_fd);
+ }
}
if (org != NULL) {
os_setperm(org, os_getperm((const char *)fname) & 0777);
@@ -3529,23 +3632,24 @@ restore_backup:
* Finish up. We get here either after failure or success.
*/
fail:
- --no_wait_return; /* may wait for return now */
+ --no_wait_return; // may wait for return now
nofail:
- /* Done saving, we accept changed buffer warnings again */
+ // Done saving, we accept changed buffer warnings again
buf->b_saving = false;
xfree(backup);
- if (buffer != smallbuf)
+ if (buffer != smallbuf) {
xfree(buffer);
+ }
xfree(fenc_tofree);
xfree(write_info.bw_conv_buf);
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
if (write_info.bw_iconv_fd != (iconv_t)-1) {
iconv_close(write_info.bw_iconv_fd);
write_info.bw_iconv_fd = (iconv_t)-1;
}
-# endif
+#endif
#ifdef HAVE_ACL
mch_free_acl(acl);
#endif
@@ -3577,9 +3681,8 @@ nofail:
const int attr = HL_ATTR(HLF_E); // Set highlight for error messages.
MSG_PUTS_ATTR(_("\nWARNING: Original file may be lost or damaged\n"),
attr | MSG_HIST);
- MSG_PUTS_ATTR(_(
- "don't quit the editor until the file is successfully written!"),
- attr | MSG_HIST);
+ MSG_PUTS_ATTR(_("don't quit the editor until the file is successfully written!"),
+ attr | MSG_HIST);
/* Update the timestamp to avoid an "overwrite changed file"
* prompt when writing again. */
@@ -3605,7 +3708,7 @@ nofail:
if (!should_abort(retval)) {
aco_save_T aco;
- curbuf->b_no_eol_lnum = 0; /* in case it was set by the previous read */
+ curbuf->b_no_eol_lnum = 0; // in case it was set by the previous read
/*
* Apply POST autocommands.
@@ -3613,24 +3716,26 @@ nofail:
*/
aucmd_prepbuf(&aco, buf);
- if (append)
+ if (append) {
apply_autocmds_exarg(EVENT_FILEAPPENDPOST, fname, fname,
- FALSE, curbuf, eap);
- else if (filtering)
+ FALSE, curbuf, eap);
+ } else if (filtering) {
apply_autocmds_exarg(EVENT_FILTERWRITEPOST, NULL, fname,
- FALSE, curbuf, eap);
- else if (reset_changed && whole)
+ FALSE, curbuf, eap);
+ } else if (reset_changed && whole) {
apply_autocmds_exarg(EVENT_BUFWRITEPOST, fname, fname,
- FALSE, curbuf, eap);
- else
+ FALSE, curbuf, eap);
+ } else {
apply_autocmds_exarg(EVENT_FILEWRITEPOST, fname, fname,
- FALSE, curbuf, eap);
+ FALSE, curbuf, eap);
+ }
- /* restore curwin/curbuf and a few other things */
+ // restore curwin/curbuf and a few other things
aucmd_restbuf(&aco);
- if (aborting()) /* autocmds may abort script processing */
+ if (aborting()) { // autocmds may abort script processing
retval = FALSE;
+ }
}
got_int |= prev_got_int;
@@ -3647,16 +3752,18 @@ nofail:
*/
static int set_rw_fname(char_u *fname, char_u *sfname)
{
- buf_T *buf = curbuf;
+ buf_T *buf = curbuf;
- /* It's like the unnamed buffer is deleted.... */
- if (curbuf->b_p_bl)
- apply_autocmds(EVENT_BUFDELETE, NULL, NULL, FALSE, curbuf);
- apply_autocmds(EVENT_BUFWIPEOUT, NULL, NULL, FALSE, curbuf);
- if (aborting()) /* autocmds may abort script processing */
+ // It's like the unnamed buffer is deleted....
+ if (curbuf->b_p_bl) {
+ apply_autocmds(EVENT_BUFDELETE, NULL, NULL, false, curbuf);
+ }
+ apply_autocmds(EVENT_BUFWIPEOUT, NULL, NULL, false, curbuf);
+ if (aborting()) { // autocmds may abort script processing
return FAIL;
+ }
if (curbuf != buf) {
- /* We are in another buffer now, don't do the renaming. */
+ // We are in another buffer now, don't do the renaming.
EMSG(_(e_auchangedbuf));
return FAIL;
}
@@ -3665,14 +3772,16 @@ static int set_rw_fname(char_u *fname, char_u *sfname)
curbuf->b_flags |= BF_NOTEDITED;
}
- /* ....and a new named one is created */
- apply_autocmds(EVENT_BUFNEW, NULL, NULL, FALSE, curbuf);
- if (curbuf->b_p_bl)
- apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, curbuf);
- if (aborting()) /* autocmds may abort script processing */
+ // ....and a new named one is created
+ apply_autocmds(EVENT_BUFNEW, NULL, NULL, false, curbuf);
+ if (curbuf->b_p_bl) {
+ apply_autocmds(EVENT_BUFADD, NULL, NULL, false, curbuf);
+ }
+ if (aborting()) { // autocmds may abort script processing
return FAIL;
+ }
- /* Do filetype detection now if 'filetype' is empty. */
+ // Do filetype detection now if 'filetype' is empty.
if (*curbuf->b_p_ft == NUL) {
if (au_has_group((char_u *)"filetypedetect")) {
(void)do_doautocmd((char_u *)"filetypedetect BufRead", false, NULL);
@@ -3691,8 +3800,8 @@ static int set_rw_fname(char_u *fname, char_u *sfname)
/// @param[in] buf_len ret_buf length.
/// @param[in] buf buf_T file name is coming from.
/// @param[in] fname File name to write.
-static void add_quoted_fname(char *const ret_buf, const size_t buf_len,
- const buf_T *const buf, const char *fname)
+static void add_quoted_fname(char *const ret_buf, const size_t buf_len, const buf_T *const buf,
+ const char *fname)
FUNC_ATTR_NONNULL_ARG(1)
{
if (fname == NULL) {
@@ -3735,25 +3844,26 @@ static bool msg_add_fileformat(int eol_type)
*/
void msg_add_lines(int insert_space, long lnum, off_T nchars)
{
- char_u *p;
+ char_u *p;
p = IObuff + STRLEN(IObuff);
- if (insert_space)
+ if (insert_space) {
*p++ = ' ';
- if (shortmess(SHM_LINES)) {
- sprintf((char *)p, "%" PRId64 "L, %" PRId64 "C",
- (int64_t)lnum, (int64_t)nchars);
}
- else {
- if (lnum == 1)
+ if (shortmess(SHM_LINES)) {
+ sprintf((char *)p, "%" PRId64 "L, %" PRId64 "C",
+ (int64_t)lnum, (int64_t)nchars);
+ } else {
+ if (lnum == 1) {
STRCPY(p, _("1 line, "));
- else
+ } else {
sprintf((char *)p, _("%" PRId64 " lines, "), (int64_t)lnum);
+ }
p += STRLEN(p);
- if (nchars == 1)
+ if (nchars == 1) {
STRCPY(p, _("1 character"));
- else {
+ } else {
sprintf((char *)p, _("%" PRId64 " characters"), (int64_t)nchars);
}
}
@@ -3765,7 +3875,7 @@ void msg_add_lines(int insert_space, long lnum, off_T nchars)
static void msg_add_eol(void)
{
STRCAT(IObuff,
- shortmess(SHM_LAST) ? _("[noeol]") : _("[Incomplete last line]"));
+ shortmess(SHM_LAST) ? _("[noeol]") : _("[Incomplete last line]"));
}
/*
@@ -3816,17 +3926,17 @@ static bool time_differs(long t1, long t2) FUNC_ATTR_CONST
static int buf_write_bytes(struct bw_info *ip)
{
int wlen;
- char_u *buf = ip->bw_buf; /* data to write */
- int len = ip->bw_len; /* length of data */
+ char_u *buf = ip->bw_buf; // data to write
+ int len = ip->bw_len; // length of data
#ifdef HAS_BW_FLAGS
- int flags = ip->bw_flags; /* extra flags */
+ int flags = ip->bw_flags; // extra flags
#endif
/*
* Skip conversion when writing the BOM.
*/
if (!(flags & FIO_NOCONVERT)) {
- char_u *p;
+ char_u *p;
unsigned c;
int n;
@@ -3834,9 +3944,10 @@ static int buf_write_bytes(struct bw_info *ip)
/*
* Convert latin1 in the buffer to UTF-8 in the file.
*/
- p = ip->bw_conv_buf; /* translate to buffer */
- for (wlen = 0; wlen < len; ++wlen)
+ p = ip->bw_conv_buf; // translate to buffer
+ for (wlen = 0; wlen < len; ++wlen) {
p += utf_char2bytes(buf[wlen], p);
+ }
buf = ip->bw_conv_buf;
len = (int)(p - ip->bw_conv_buf);
} else if (flags & (FIO_UCS4 | FIO_UTF16 | FIO_UCS2 | FIO_LATIN1)) {
@@ -3844,10 +3955,11 @@ static int buf_write_bytes(struct bw_info *ip)
* Convert UTF-8 bytes in the buffer to UCS-2, UCS-4, UTF-16 or
* Latin1 chars in the file.
*/
- if (flags & FIO_LATIN1)
- p = buf; /* translate in-place (can only get shorter) */
- else
- p = ip->bw_conv_buf; /* translate to buffer */
+ if (flags & FIO_LATIN1) {
+ p = buf; // translate in-place (can only get shorter)
+ } else {
+ p = ip->bw_conv_buf; // translate to buffer
+ }
for (wlen = 0; wlen < len; wlen += n) {
if (wlen == 0 && ip->bw_restlen != 0) {
int l;
@@ -3856,30 +3968,33 @@ static int buf_write_bytes(struct bw_info *ip)
* buf[] to get a full sequence. Might still be too
* short! */
l = CONV_RESTLEN - ip->bw_restlen;
- if (l > len)
+ if (l > len) {
l = len;
+ }
memmove(ip->bw_rest + ip->bw_restlen, buf, (size_t)l);
n = utf_ptr2len_len(ip->bw_rest, ip->bw_restlen + l);
if (n > ip->bw_restlen + len) {
/* We have an incomplete byte sequence at the end to
* be written. We can't convert it without the
* remaining bytes. Keep them for the next call. */
- if (ip->bw_restlen + len > CONV_RESTLEN)
+ if (ip->bw_restlen + len > CONV_RESTLEN) {
return FAIL;
+ }
ip->bw_restlen += len;
break;
}
- if (n > 1)
+ if (n > 1) {
c = utf_ptr2char(ip->bw_rest);
- else
+ } else {
c = ip->bw_rest[0];
+ }
if (n >= ip->bw_restlen) {
n -= ip->bw_restlen;
ip->bw_restlen = 0;
} else {
ip->bw_restlen -= n;
memmove(ip->bw_rest, ip->bw_rest + n,
- (size_t)ip->bw_restlen);
+ (size_t)ip->bw_restlen);
n = 0;
}
} else {
@@ -3888,42 +4003,45 @@ static int buf_write_bytes(struct bw_info *ip)
/* We have an incomplete byte sequence at the end to
* be written. We can't convert it without the
* remaining bytes. Keep them for the next call. */
- if (len - wlen > CONV_RESTLEN)
+ if (len - wlen > CONV_RESTLEN) {
return FAIL;
+ }
ip->bw_restlen = len - wlen;
memmove(ip->bw_rest, buf + wlen,
- (size_t)ip->bw_restlen);
+ (size_t)ip->bw_restlen);
break;
}
- if (n > 1)
+ if (n > 1) {
c = utf_ptr2char(buf + wlen);
- else
+ } else {
c = buf[wlen];
+ }
}
if (ucs2bytes(c, &p, flags) && !ip->bw_conv_error) {
ip->bw_conv_error = TRUE;
ip->bw_conv_error_lnum = ip->bw_start_lnum;
}
- if (c == NL)
+ if (c == NL) {
++ip->bw_start_lnum;
+ }
}
- if (flags & FIO_LATIN1)
+ if (flags & FIO_LATIN1) {
len = (int)(p - buf);
- else {
+ } else {
buf = ip->bw_conv_buf;
len = (int)(p - ip->bw_conv_buf);
}
}
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
if (ip->bw_iconv_fd != (iconv_t)-1) {
- const char *from;
+ const char *from;
size_t fromlen;
- char *to;
+ char *to;
size_t tolen;
- /* Convert with iconv(). */
+ // Convert with iconv().
if (ip->bw_restlen > 0) {
char *fp;
@@ -3946,7 +4064,7 @@ static int buf_write_bytes(struct bw_info *ip)
if (ip->bw_first) {
size_t save_len = tolen;
- /* output the initial shift state sequence */
+ // output the initial shift state sequence
(void)iconv(ip->bw_iconv_fd, NULL, NULL, &to, &tolen);
/* There is a bug in iconv() on Linux (which appears to be
@@ -3969,15 +4087,16 @@ static int buf_write_bytes(struct bw_info *ip)
return FAIL;
}
- /* copy remainder to ip->bw_rest[] to be used for the next call. */
- if (fromlen > 0)
+ // copy remainder to ip->bw_rest[] to be used for the next call.
+ if (fromlen > 0) {
memmove(ip->bw_rest, (void *)from, fromlen);
+ }
ip->bw_restlen = (int)fromlen;
buf = ip->bw_conv_buf;
len = (int)((char_u *)to - ip->bw_conv_buf);
}
-# endif
+#endif
}
if (ip->bw_fd < 0) {
@@ -3997,7 +4116,7 @@ static int buf_write_bytes(struct bw_info *ip)
/// @return true for an error, false when it's OK.
static bool ucs2bytes(unsigned c, char_u **pp, int flags) FUNC_ATTR_NONNULL_ALL
{
- char_u *p = *pp;
+ char_u *p = *pp;
bool error = false;
int cc;
@@ -4043,12 +4162,13 @@ static bool ucs2bytes(unsigned c, char_u **pp, int flags) FUNC_ATTR_NONNULL_ALL
*p++ = (c >> 8);
*p++ = c;
}
- } else { /* Latin1 */
+ } else { // Latin1
if (c >= 0x100) {
error = true;
*p++ = 0xBF;
- } else
+ } else {
*p++ = c;
+ }
}
*pp = p;
@@ -4103,25 +4223,29 @@ static int get_fio_flags(const char_u *name)
prop = enc_canon_props(name);
if (prop & ENC_UNICODE) {
if (prop & ENC_2BYTE) {
- if (prop & ENC_ENDIAN_L)
+ if (prop & ENC_ENDIAN_L) {
return FIO_UCS2 | FIO_ENDIAN_L;
+ }
return FIO_UCS2;
}
if (prop & ENC_4BYTE) {
- if (prop & ENC_ENDIAN_L)
+ if (prop & ENC_ENDIAN_L) {
return FIO_UCS4 | FIO_ENDIAN_L;
+ }
return FIO_UCS4;
}
if (prop & ENC_2WORD) {
- if (prop & ENC_ENDIAN_L)
+ if (prop & ENC_ENDIAN_L) {
return FIO_UTF16 | FIO_ENDIAN_L;
+ }
return FIO_UTF16;
}
return FIO_UTF8;
}
- if (prop & ENC_LATIN1)
+ if (prop & ENC_LATIN1) {
return FIO_LATIN1;
- /* must be ENC_DBCS, requires iconv() */
+ }
+ // must be ENC_DBCS, requires iconv()
return 0;
}
@@ -4135,34 +4259,37 @@ static int get_fio_flags(const char_u *name)
*/
static char_u *check_for_bom(char_u *p, long size, int *lenp, int flags)
{
- char *name = NULL;
+ char *name = NULL;
int len = 2;
if (p[0] == 0xef && p[1] == 0xbb && size >= 3 && p[2] == 0xbf
&& (flags == FIO_ALL || flags == FIO_UTF8 || flags == 0)) {
- name = "utf-8"; /* EF BB BF */
+ name = "utf-8"; // EF BB BF
len = 3;
} else if (p[0] == 0xff && p[1] == 0xfe) {
if (size >= 4 && p[2] == 0 && p[3] == 0
&& (flags == FIO_ALL || flags == (FIO_UCS4 | FIO_ENDIAN_L))) {
- name = "ucs-4le"; /* FF FE 00 00 */
+ name = "ucs-4le"; // FF FE 00 00
len = 4;
- } else if (flags == (FIO_UCS2 | FIO_ENDIAN_L))
- name = "ucs-2le"; /* FF FE */
- else if (flags == FIO_ALL || flags == (FIO_UTF16 | FIO_ENDIAN_L))
- /* utf-16le is preferred, it also works for ucs-2le text */
- name = "utf-16le"; /* FF FE */
+ } else if (flags == (FIO_UCS2 | FIO_ENDIAN_L)) {
+ name = "ucs-2le"; // FF FE
+ } else if (flags == FIO_ALL ||
+ flags == (FIO_UTF16 | FIO_ENDIAN_L)) {
+ // utf-16le is preferred, it also works for ucs-2le text
+ name = "utf-16le"; // FF FE
+ }
} else if (p[0] == 0xfe && p[1] == 0xff
&& (flags == FIO_ALL || flags == FIO_UCS2 || flags ==
FIO_UTF16)) {
- /* Default to utf-16, it works also for ucs-2 text. */
- if (flags == FIO_UCS2)
- name = "ucs-2"; /* FE FF */
- else
- name = "utf-16"; /* FE FF */
+ // Default to utf-16, it works also for ucs-2 text.
+ if (flags == FIO_UCS2) {
+ name = "ucs-2"; // FE FF
+ } else {
+ name = "utf-16"; // FE FF
+ }
} else if (size >= 4 && p[0] == 0 && p[1] == 0 && p[2] == 0xfe
&& p[3] == 0xff && (flags == FIO_ALL || flags == FIO_UCS4)) {
- name = "ucs-4"; /* 00 00 FE FF */
+ name = "ucs-4"; // 00 00 FE FF
len = 4;
}
@@ -4177,15 +4304,16 @@ static char_u *check_for_bom(char_u *p, long size, int *lenp, int flags)
static int make_bom(char_u *buf, char_u *name)
{
int flags;
- char_u *p;
+ char_u *p;
flags = get_fio_flags(name);
- /* Can't put a BOM in a non-Unicode file. */
- if (flags == FIO_LATIN1 || flags == 0)
+ // Can't put a BOM in a non-Unicode file.
+ if (flags == FIO_LATIN1 || flags == 0) {
return 0;
+ }
- if (flags == FIO_UTF8) { /* UTF-8 */
+ if (flags == FIO_UTF8) { // UTF-8
buf[0] = 0xef;
buf[1] = 0xbb;
buf[2] = 0xbf;
@@ -4205,7 +4333,7 @@ static int make_bom(char_u *buf, char_u *name)
/// name.
void shorten_buf_fname(buf_T *buf, char_u *dirname, int force)
{
- char_u *p;
+ char_u *p;
if (buf->b_fname != NULL
&& !bt_nofile(buf)
@@ -4234,14 +4362,14 @@ void shorten_fnames(int force)
os_dirname(dirname, MAXPATHL);
FOR_ALL_BUFFERS(buf) {
- shorten_buf_fname(buf, dirname, force);
+ shorten_buf_fname(buf, dirname, force);
// Always make the swap file name a full path, a "nofile" buffer may
// also have a swap file.
mf_fullname(buf->b_ml.ml_mfp);
}
status_redraw_all();
- redraw_tabline = TRUE;
+ redraw_tabline = true;
}
/// Get new filename ended by given extension.
@@ -4507,11 +4635,11 @@ int vim_rename(const char_u *from, const char_u *to)
int fd_in;
int fd_out;
int n;
- char *errmsg = NULL;
- char *buffer;
+ char *errmsg = NULL;
+ char *buffer;
long perm;
#ifdef HAVE_ACL
- vim_acl_T acl; /* ACL from original file */
+ vim_acl_T acl; // ACL from original file
#endif
bool use_tmp_file = false;
@@ -4551,8 +4679,9 @@ int vim_rename(const char_u *from, const char_u *to)
* Find a name that doesn't exist and is in the same directory.
* Rename "from" to "tempname" and then rename "tempname" to "to".
*/
- if (STRLEN(from) >= MAXPATHL - 5)
+ if (STRLEN(from) >= MAXPATHL - 5) {
return -1;
+ }
STRCPY(tempname, from);
for (n = 123; n < 99999; n++) {
char * tail = (char *)path_tail(tempname);
@@ -4587,8 +4716,9 @@ int vim_rename(const char_u *from, const char_u *to)
/*
* First try a normal rename, return if it works.
*/
- if (os_rename(from, to) == OK)
+ if (os_rename(from, to) == OK) {
return 0;
+ }
/*
* Rename() failed, try copying the file.
@@ -4606,9 +4736,9 @@ int vim_rename(const char_u *from, const char_u *to)
return -1;
}
- /* Create the new file with same permissions as the original. */
+ // Create the new file with same permissions as the original.
fd_out = os_open((char *)to,
- O_CREAT|O_EXCL|O_WRONLY|O_NOFOLLOW, (int)perm);
+ O_CREAT|O_EXCL|O_WRONLY|O_NOFOLLOW, (int)perm);
if (fd_out < 0) {
close(fd_in);
#ifdef HAVE_ACL
@@ -4629,16 +4759,18 @@ int vim_rename(const char_u *from, const char_u *to)
return -1;
}
- while ((n = read_eintr(fd_in, buffer, BUFSIZE)) > 0)
+ while ((n = read_eintr(fd_in, buffer, BUFSIZE)) > 0) {
if (write_eintr(fd_out, buffer, n) != n) {
errmsg = _("E208: Error writing to \"%s\"");
break;
}
+ }
xfree(buffer);
close(fd_in);
- if (close(fd_out) < 0)
+ if (close(fd_out) < 0) {
errmsg = _("E209: Error closing \"%s\"");
+ }
if (n < 0) {
errmsg = _("E210: Error reading \"%s\"");
to = from;
@@ -4660,23 +4792,23 @@ int vim_rename(const char_u *from, const char_u *to)
static int already_warned = FALSE;
-// Check if any not hidden buffer has been changed.
-// Postpone the check if there are characters in the stuff buffer, a global
-// command is being executed, a mapping is being executed or an autocommand is
-// busy.
-// Returns TRUE if some message was written (screen should be redrawn and
-// cursor positioned).
-int
-check_timestamps(
- int focus // called for GUI focus event
-)
+/// Check if any not hidden buffer has been changed.
+/// Postpone the check if there are characters in the stuff buffer, a global
+/// command is being executed, a mapping is being executed or an autocommand is
+/// busy.
+///
+/// @param focus called for GUI focus event
+///
+/// @return TRUE if some message was written (screen should be redrawn and cursor positioned).
+int check_timestamps(int focus)
{
int didit = 0;
/* Don't check timestamps while system() or another low-level function may
* cause us to lose and gain focus. */
- if (no_check_timestamps > 0)
+ if (no_check_timestamps > 0) {
return FALSE;
+ }
/* Avoid doing a check twice. The OK/Reload dialog can cause a focus
* event and we would keep on checking if the file is steadily growing.
@@ -4687,8 +4819,8 @@ check_timestamps(
}
if (!stuff_empty() || global_busy || !typebuf_typed()
- || autocmd_busy || curbuf_lock > 0 || allbuf_lock > 0
- ) {
+ || autocmd_busy || curbuf->b_ro_locked > 0 ||
+ allbuf_lock > 0) {
need_check_timestamps = true; // check later
} else {
no_wait_return++;
@@ -4728,12 +4860,12 @@ check_timestamps(
*/
static int move_lines(buf_T *frombuf, buf_T *tobuf)
{
- buf_T *tbuf = curbuf;
+ buf_T *tbuf = curbuf;
int retval = OK;
linenr_T lnum;
- char_u *p;
+ char_u *p;
- /* Copy the lines in "frombuf" to "tobuf". */
+ // Copy the lines in "frombuf" to "tobuf".
curbuf = tobuf;
for (lnum = 1; lnum <= frombuf->b_ml.ml_line_count; lnum++) {
p = vim_strsave(ml_get_buf(frombuf, lnum, false));
@@ -4745,7 +4877,7 @@ static int move_lines(buf_T *frombuf, buf_T *tobuf)
xfree(p);
}
- /* Delete all the lines in "frombuf". */
+ // Delete all the lines in "frombuf".
if (retval != FAIL) {
curbuf = frombuf;
for (lnum = curbuf->b_ml.ml_line_count; lnum > 0; lnum--) {
@@ -4773,17 +4905,17 @@ int buf_check_timestamp(buf_T *buf)
FUNC_ATTR_NONNULL_ALL
{
int retval = 0;
- char_u *path;
- char *mesg = NULL;
- char *mesg2 = "";
+ char_u *path;
+ char *mesg = NULL;
+ char *mesg2 = "";
bool helpmesg = false;
bool reload = false;
bool can_reload = false;
uint64_t orig_size = buf->b_orig_size;
int orig_mode = buf->b_orig_mode;
static bool busy = false;
- char_u *s;
- char *reason;
+ char_u *s;
+ char *reason;
bufref_T bufref;
set_bufref(&bufref, buf);
@@ -4796,9 +4928,9 @@ int buf_check_timestamp(buf_T *buf)
|| buf->b_ml.ml_mfp == NULL
|| !bt_normal(buf)
|| buf->b_saving
- || busy
- )
+ || busy) {
return 0;
+ }
FileInfo file_info;
bool file_info_ok;
@@ -4884,24 +5016,22 @@ int buf_check_timestamp(buf_T *buf)
// changed.
if (reason[2] == 'n') {
mesg = _(
- "W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as well");
+ "W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as well");
mesg2 = _("See \":help W12\" for more info.");
} else if (reason[1] == 'h') {
- mesg = _(
- "W11: Warning: File \"%s\" has changed since editing started");
+ mesg = _("W11: Warning: File \"%s\" has changed since editing started");
mesg2 = _("See \":help W11\" for more info.");
} else if (*reason == 'm') {
- mesg = _(
- "W16: Warning: Mode of file \"%s\" has changed since editing started");
+ mesg = _("W16: Warning: Mode of file \"%s\" has changed since editing started");
mesg2 = _("See \":help W16\" for more info.");
- } else
+ } else {
/* Only timestamp changed, store it to avoid a warning
* in check_mtime() later. */
buf->b_mtime_read = buf->b_mtime;
+ }
}
}
}
-
} else if ((buf->b_flags & BF_NEW) && !(buf->b_flags & BF_NEW_W)
&& os_path_exists(buf->b_ffname)) {
retval = 1;
@@ -4926,8 +5056,8 @@ int buf_check_timestamp(buf_T *buf)
xstrlcat(tbuf, "\n", tbuf_len - 1);
xstrlcat(tbuf, mesg2, tbuf_len - 1);
}
- if (do_dialog(VIM_WARNING, (char_u *) _("Warning"), (char_u *) tbuf,
- (char_u *) _("&OK\n&Load File"), 1, NULL, true) == 2) {
+ if (do_dialog(VIM_WARNING, (char_u *)_("Warning"), (char_u *)tbuf,
+ (char_u *)_("&OK\n&Load File"), 1, NULL, true) == 2) {
reload = true;
}
} else if (State > NORMAL_BUSY || (State & CMDLINE) || already_warned) {
@@ -4963,17 +5093,14 @@ int buf_check_timestamp(buf_T *buf)
}
if (reload) {
- /* Reload the buffer. */
+ // Reload the buffer.
buf_reload(buf, orig_mode);
if (buf->b_p_udf && buf->b_ffname != NULL) {
char_u hash[UNDO_HASH_SIZE];
- buf_T *save_curbuf = curbuf;
- /* Any existing undo file is unusable, write it now. */
- curbuf = buf;
- u_compute_hash(hash);
- u_write_undo(NULL, FALSE, buf, hash);
- curbuf = save_curbuf;
+ // Any existing undo file is unusable, write it now.
+ u_compute_hash(buf, hash);
+ u_write_undo(NULL, false, buf, hash);
}
}
@@ -4997,13 +5124,13 @@ void buf_reload(buf_T *buf, int orig_mode)
pos_T old_cursor;
linenr_T old_topline;
int old_ro = buf->b_p_ro;
- buf_T *savebuf;
+ buf_T *savebuf;
bufref_T bufref;
int saved = OK;
aco_save_T aco;
int flags = READ_NEW;
- /* set curwin/curbuf for "buf" and save some things */
+ // set curwin/curbuf for "buf" and save some things
aucmd_prepbuf(&aco, buf);
// We only want to read the text from the file, not reset the syntax
@@ -5015,10 +5142,10 @@ void buf_reload(buf_T *buf, int orig_mode)
old_topline = curwin->w_topline;
if (p_ur < 0 || curbuf->b_ml.ml_line_count <= p_ur) {
- /* Save all the text, so that the reload can be undone.
- * Sync first so that this is a separate undo-able action. */
- u_sync(FALSE);
- saved = u_savecommon(0, curbuf->b_ml.ml_line_count + 1, 0, TRUE);
+ // Save all the text, so that the reload can be undone.
+ // Sync first so that this is a separate undo-able action.
+ u_sync(false);
+ saved = u_savecommon(curbuf, 0, curbuf->b_ml.ml_line_count + 1, 0, true);
flags |= READ_KEEP_UNDO;
}
@@ -5027,14 +5154,14 @@ void buf_reload(buf_T *buf, int orig_mode)
// buffer contents. But if reading the file fails we should keep
// the old contents. Can't use memory only, the file might be
// too big. Use a hidden buffer to move the buffer contents to.
- if (BUFEMPTY() || saved == FAIL) {
+ if (buf_is_empty(curbuf) || saved == FAIL) {
savebuf = NULL;
} else {
// Allocate a buffer without putting it in the buffer list.
savebuf = buflist_new(NULL, NULL, (linenr_T)1, BLN_DUMMY);
set_bufref(&bufref, savebuf);
if (savebuf != NULL && buf == curbuf) {
- /* Open the memline. */
+ // Open the memline.
curbuf = savebuf;
curwin->w_buffer = savebuf;
saved = ml_open(curbuf);
@@ -5044,7 +5171,7 @@ void buf_reload(buf_T *buf, int orig_mode)
if (savebuf == NULL || saved == FAIL || buf != curbuf
|| move_lines(buf, savebuf) == FAIL) {
EMSG2(_("E462: Could not prepare for reloading \"%s\""),
- buf->b_fname);
+ buf->b_fname);
saved = FAIL;
}
}
@@ -5060,7 +5187,7 @@ void buf_reload(buf_T *buf, int orig_mode)
if (savebuf != NULL && bufref_valid(&bufref) && buf == curbuf) {
// Put the text back from the save buffer. First
// delete any lines that readfile() added.
- while (!BUFEMPTY()) {
+ while (!buf_is_empty(curbuf)) {
if (ml_delete(buf->b_ml.ml_line_count, false) == FAIL) {
break;
}
@@ -5087,21 +5214,22 @@ void buf_reload(buf_T *buf, int orig_mode)
wipe_buffer(savebuf, false);
}
- /* Invalidate diff info if necessary. */
+ // Invalidate diff info if necessary.
diff_invalidate(curbuf);
/* Restore the topline and cursor position and check it (lines may
* have been removed). */
- if (old_topline > curbuf->b_ml.ml_line_count)
+ if (old_topline > curbuf->b_ml.ml_line_count) {
curwin->w_topline = curbuf->b_ml.ml_line_count;
- else
+ } else {
curwin->w_topline = old_topline;
+ }
curwin->w_cursor = old_cursor;
check_cursor();
update_topline(curwin);
keep_filetype = false;
- /* Update folds unless they are defined manually. */
+ // Update folds unless they are defined manually.
FOR_ALL_TAB_WINDOWS(tp, wp) {
if (wp->w_buffer == curwin->w_buffer
&& !foldmethodIsManual(wp)) {
@@ -5112,15 +5240,16 @@ void buf_reload(buf_T *buf, int orig_mode)
/* If the mode didn't change and 'readonly' was set, keep the old
* value; the user probably used the ":view" command. But don't
* reset it, might have had a read error. */
- if (orig_mode == curbuf->b_orig_mode)
+ if (orig_mode == curbuf->b_orig_mode) {
curbuf->b_p_ro |= old_ro;
+ }
- /* Modelines must override settings done by autocommands. */
+ // Modelines must override settings done by autocommands.
do_modelines(0);
- /* restore curwin/curbuf and a few other things */
+ // restore curwin/curbuf and a few other things
aucmd_restbuf(&aco);
- /* Careful: autocommands may have made "buf" invalid! */
+ // Careful: autocommands may have made "buf" invalid!
}
void buf_store_file_info(buf_T *buf, FileInfo *file_info)
@@ -5137,8 +5266,9 @@ void buf_store_file_info(buf_T *buf, FileInfo *file_info)
*/
void write_lnum_adjust(linenr_T offset)
{
- if (curbuf->b_no_eol_lnum != 0) /* only if there is a missing eol */
+ if (curbuf->b_no_eol_lnum != 0) { // only if there is a missing eol
curbuf->b_no_eol_lnum += offset;
+ }
}
#if defined(BACKSLASH_IN_FILENAME)
@@ -5146,7 +5276,7 @@ void write_lnum_adjust(linenr_T offset)
/// unless when it looks like a URL.
void forward_slash(char_u *fname)
{
- char_u *p;
+ char_u *p;
if (path_with_url((const char *)fname)) {
return;
@@ -5321,18 +5451,19 @@ char_u *vim_tempname(void)
/// @param allow_dirs Allow matching with dir
///
/// @return true if there is a match, false otherwise
-bool match_file_pat(char_u *pattern, regprog_T **prog, char_u *fname,
- char_u *sfname, char_u *tail, int allow_dirs)
+bool match_file_pat(char_u *pattern, regprog_T **prog, char_u *fname, char_u *sfname, char_u *tail,
+ int allow_dirs)
{
regmatch_T regmatch;
bool result = false;
- regmatch.rm_ic = p_fic; /* ignore case if 'fileignorecase' is set */
+ regmatch.rm_ic = p_fic; // ignore case if 'fileignorecase' is set
{
- if (prog != NULL)
+ if (prog != NULL) {
regmatch.regprog = *prog;
- else
+ } else {
regmatch.regprog = vim_regcomp(pattern, RE_MAGIC);
+ }
}
/*
@@ -5371,11 +5502,11 @@ bool match_file_list(char_u *list, char_u *sfname, char_u *ffname)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ARG(1, 3)
{
char_u buf[100];
- char_u *tail;
- char_u *regpat;
+ char_u *tail;
+ char_u *regpat;
char allow_dirs;
bool match;
- char_u *p;
+ char_u *p;
tail = path_tail(sfname);
@@ -5402,25 +5533,27 @@ bool match_file_list(char_u *list, char_u *sfname, char_u *ffname)
/// allow_dirs, otherwise FALSE is put there -- webb.
/// Handle backslashes before special characters, like "\*" and "\ ".
///
-/// Returns NULL on failure.
-char_u * file_pat_to_reg_pat(
- const char_u *pat,
- const char_u *pat_end, // first char after pattern or NULL
- char *allow_dirs, // Result passed back out in here
- int no_bslash // Don't use a backward slash as pathsep
-)
+/// @param pat_end first char after pattern or NULL
+/// @param allow_dirs Result passed back out in here
+/// @param no_bslash Don't use a backward slash as pathsep
+///
+/// @return NULL on failure.
+char_u *file_pat_to_reg_pat(const char_u *pat, const char_u *pat_end, char *allow_dirs,
+ int no_bslash)
FUNC_ATTR_NONNULL_ARG(1)
{
const char_u *endp;
- char_u *reg_pat;
+ char_u *reg_pat;
const char_u *p;
int nested = 0;
- int add_dollar = TRUE;
+ bool add_dollar = true;
- if (allow_dirs != NULL)
+ if (allow_dirs != NULL) {
*allow_dirs = FALSE;
- if (pat_end == NULL)
+ }
+ if (pat_end == NULL) {
pat_end = pat + STRLEN(pat);
+ }
if (pat_end == pat) {
return (char_u *)xstrdup("^$");
@@ -5436,12 +5569,12 @@ char_u * file_pat_to_reg_pat(
case '{':
case '}':
case '~':
- size += 2; /* extra backslash */
+ size += 2; // extra backslash
break;
#ifdef BACKSLASH_IN_FILENAME
case '\\':
case '/':
- size += 4; /* could become "[\/]" */
+ size += 4; // could become "[\/]"
break;
#endif
default:
@@ -5453,11 +5586,13 @@ char_u * file_pat_to_reg_pat(
size_t i = 0;
- if (pat[0] == '*')
- while (pat[0] == '*' && pat < pat_end - 1)
+ if (pat[0] == '*') {
+ while (pat[0] == '*' && pat < pat_end - 1) {
pat++;
- else
+ }
+ } else {
reg_pat[i++] = '^';
+ }
endp = pat_end - 1;
if (endp >= pat && *endp == '*') {
while (endp - pat > 0 && *endp == '*') {
@@ -5470,8 +5605,9 @@ char_u * file_pat_to_reg_pat(
case '*':
reg_pat[i++] = '.';
reg_pat[i++] = '*';
- while (p[1] == '*') /* "**" matches like "*" */
+ while (p[1] == '*') { // "**" matches like "*"
++p;
+ }
break;
case '.':
case '~':
@@ -5482,8 +5618,9 @@ char_u * file_pat_to_reg_pat(
reg_pat[i++] = '.';
break;
case '\\':
- if (p[1] == NUL)
+ if (p[1] == NUL) {
break;
+ }
#ifdef BACKSLASH_IN_FILENAME
if (!no_bslash) {
/* translate:
@@ -5498,8 +5635,9 @@ char_u * file_pat_to_reg_pat(
reg_pat[i++] = '\\';
reg_pat[i++] = '/';
reg_pat[i++] = ']';
- if (allow_dirs != NULL)
+ if (allow_dirs != NULL) {
*allow_dirs = TRUE;
+ }
break;
}
}
@@ -5532,8 +5670,9 @@ char_u * file_pat_to_reg_pat(
#ifdef BACKSLASH_IN_FILENAME
&& (!no_bslash || *p != '\\')
#endif
- )
+ ) {
*allow_dirs = TRUE;
+ }
reg_pat[i++] = '\\';
reg_pat[i++] = *p;
}
@@ -5544,8 +5683,9 @@ char_u * file_pat_to_reg_pat(
reg_pat[i++] = '\\';
reg_pat[i++] = '/';
reg_pat[i++] = ']';
- if (allow_dirs != NULL)
+ if (allow_dirs != NULL) {
*allow_dirs = TRUE;
+ }
break;
#endif
case '{':
@@ -5562,8 +5702,9 @@ char_u * file_pat_to_reg_pat(
if (nested) {
reg_pat[i++] = '\\';
reg_pat[i++] = '|';
- } else
+ } else {
reg_pat[i++] = ',';
+ }
break;
default:
if (allow_dirs != NULL && vim_ispathsep(*p)) {
@@ -5573,8 +5714,9 @@ char_u * file_pat_to_reg_pat(
break;
}
}
- if (add_dollar)
+ if (add_dollar) {
reg_pat[i++] = '$';
+ }
reg_pat[i] = NUL;
if (nested != 0) {
if (nested < 0) {
@@ -5598,8 +5740,9 @@ long read_eintr(int fd, void *buf, size_t bufsize)
for (;; ) {
ret = read(fd, buf, bufsize);
- if (ret >= 0 || errno != EINTR)
+ if (ret >= 0 || errno != EINTR) {
break;
+ }
}
return ret;
}
@@ -5618,10 +5761,12 @@ long write_eintr(int fd, void *buf, size_t bufsize)
while (ret < (long)bufsize) {
wlen = write(fd, (char *)buf + ret, bufsize - ret);
if (wlen < 0) {
- if (errno != EINTR)
+ if (errno != EINTR) {
break;
- } else
+ }
+ } else {
ret += wlen;
+ }
}
return ret;
}
diff --git a/src/nvim/fold.c b/src/nvim/fold.c
index ad8418034a..06b8049176 100644
--- a/src/nvim/fold.c
+++ b/src/nvim/fold.c
@@ -7,12 +7,11 @@
* fold.c: code for folding
*/
-#include <string.h>
#include <inttypes.h>
+#include <string.h>
-#include "nvim/vim.h"
#include "nvim/ascii.h"
-#include "nvim/fold.h"
+#include "nvim/buffer_updates.h"
#include "nvim/change.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
@@ -20,26 +19,28 @@
#include "nvim/eval.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_session.h"
+#include "nvim/extmark.h"
+#include "nvim/fold.h"
#include "nvim/func_attr.h"
+#include "nvim/garray.h"
#include "nvim/indent.h"
-#include "nvim/buffer_updates.h"
-#include "nvim/extmark.h"
#include "nvim/mark.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/garray.h"
#include "nvim/move.h"
+#include "nvim/ops.h"
#include "nvim/option.h"
+#include "nvim/plines.h"
#include "nvim/screen.h"
#include "nvim/strings.h"
#include "nvim/syntax.h"
#include "nvim/undo.h"
-#include "nvim/ops.h"
+#include "nvim/vim.h"
-/* local declarations. {{{1 */
-/* typedef fold_T {{{2 */
+// local declarations. {{{1
+// typedef fold_T {{{2
/*
* The toplevel folds for each window are stored in the w_folds growarray.
* Each toplevel fold can contain an array of second level folds in the
@@ -57,20 +58,20 @@ typedef struct {
// folds too
} fold_T;
-#define FD_OPEN 0 /* fold is open (nested ones can be closed) */
-#define FD_CLOSED 1 /* fold is closed */
-#define FD_LEVEL 2 /* depends on 'foldlevel' (nested folds too) */
+#define FD_OPEN 0 // fold is open (nested ones can be closed)
+#define FD_CLOSED 1 // fold is closed
+#define FD_LEVEL 2 // depends on 'foldlevel' (nested folds too)
-#define MAX_LEVEL 20 /* maximum fold depth */
+#define MAX_LEVEL 20 // maximum fold depth
-/* Define "fline_T", passed to get fold level for a line. {{{2 */
+// Define "fline_T", passed to get fold level for a line. {{{2
typedef struct {
- win_T *wp; /* window */
- linenr_T lnum; /* current line number */
- linenr_T off; /* offset between lnum and real line number */
- linenr_T lnum_save; /* line nr used by foldUpdateIEMSRecurse() */
- int lvl; /* current level (-1 for undefined) */
- int lvl_next; /* level used for next line */
+ win_T *wp; // window
+ linenr_T lnum; // current line number
+ linenr_T off; // offset between lnum and real line number
+ linenr_T lnum_save; // line nr used by foldUpdateIEMSRecurse()
+ int lvl; // current level (-1 for undefined)
+ int lvl_next; // level used for next line
int start; /* number of folds that are forced to start at
this line. */
int end; /* level of fold that is forced to end below
@@ -82,10 +83,10 @@ typedef struct {
// Flag is set when redrawing is needed.
static bool fold_changed;
-/* Function used by foldUpdateIEMSRecurse */
+// Function used by foldUpdateIEMSRecurse
typedef void (*LevelGetter)(fline_T *);
-/* static functions {{{2 */
+// static functions {{{2
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "fold.c.generated.h"
@@ -109,17 +110,17 @@ static linenr_T invalid_bot = (linenr_T)0;
static linenr_T prev_lnum = 0;
static int prev_lnum_lvl = -1;
-/* Flags used for "done" argument of setManualFold. */
+// Flags used for "done" argument of setManualFold.
#define DONE_NOTHING 0
-#define DONE_ACTION 1 /* did close or open a fold */
-#define DONE_FOLD 2 /* did find a fold */
+#define DONE_ACTION 1 // did close or open a fold
+#define DONE_FOLD 2 // did find a fold
static size_t foldstartmarkerlen;
static char_u *foldendmarker;
static size_t foldendmarkerlen;
-/* Exported folding functions. {{{1 */
-/* copyFoldingState() {{{2 */
+// Exported folding functions. {{{1
+// copyFoldingState() {{{2
/*
* Copy that folding state from window "wp_from" to window "wp_to".
*/
@@ -130,24 +131,22 @@ void copyFoldingState(win_T *wp_from, win_T *wp_to)
cloneFoldGrowArray(&wp_from->w_folds, &wp_to->w_folds);
}
-/* hasAnyFolding() {{{2 */
+// hasAnyFolding() {{{2
/*
* Return TRUE if there may be folded lines in the current window.
*/
int hasAnyFolding(win_T *win)
{
- /* very simple now, but can become more complex later */
+ // very simple now, but can become more complex later
return !win->w_buffer->terminal && win->w_p_fen
&& (!foldmethodIsManual(win) || !GA_EMPTY(&win->w_folds));
}
-/* hasFolding() {{{2 */
-/*
- * Return TRUE if line "lnum" in the current window is part of a closed
- * fold.
- * When returning TRUE, *firstp and *lastp are set to the first and last
- * lnum of the sequence of folded lines (skipped when NULL).
- */
+// hasFolding() {{{2
+/// When returning true, *firstp and *lastp are set to the first and last
+/// lnum of the sequence of folded lines (skipped when NULL).
+///
+/// @return true if line "lnum" in the current window is part of a closed fold.
bool hasFolding(linenr_T lnum, linenr_T *firstp, linenr_T *lastp)
{
return hasFoldingWin(curwin, lnum, firstp, lastp, true, NULL);
@@ -162,20 +161,14 @@ bool hasFolding(linenr_T lnum, linenr_T *firstp, linenr_T *lastp)
/// @param[out] infop where to store fold info
///
/// @return true if range contains folds
-bool hasFoldingWin(
- win_T *const win,
- const linenr_T lnum,
- linenr_T *const firstp,
- linenr_T *const lastp,
- const bool cache,
- foldinfo_T *const infop
-)
+bool hasFoldingWin(win_T *const win, const linenr_T lnum, linenr_T *const firstp,
+ linenr_T *const lastp, const bool cache, foldinfo_T *const infop)
{
bool had_folded = false;
linenr_T first = 0;
linenr_T last = 0;
linenr_T lnum_rel = lnum;
- fold_T *fp;
+ fold_T *fp;
int level = 0;
bool use_level = false;
bool maybe_small = false;
@@ -185,8 +178,9 @@ bool hasFoldingWin(
// Return quickly when there is no folding at all in this window.
if (!hasAnyFolding(win)) {
- if (infop != NULL)
+ if (infop != NULL) {
infop->fi_level = 0;
+ }
return false;
}
@@ -209,21 +203,23 @@ bool hasFoldingWin(
*/
garray_T *gap = &win->w_folds;
for (;; ) {
- if (!foldFind(gap, lnum_rel, &fp))
+ if (!foldFind(gap, lnum_rel, &fp)) {
break;
+ }
- /* Remember lowest level of fold that starts in "lnum". */
- if (lnum_rel == fp->fd_top && low_level == 0)
+ // Remember lowest level of fold that starts in "lnum".
+ if (lnum_rel == fp->fd_top && low_level == 0) {
low_level = level + 1;
+ }
first += fp->fd_top;
last += fp->fd_top;
- /* is this fold closed? */
+ // is this fold closed?
had_folded = check_closed(win, fp, &use_level, level,
- &maybe_small, lnum - lnum_rel);
+ &maybe_small, lnum - lnum_rel);
if (had_folded) {
- /* Fold closed: Set last and quit loop. */
+ // Fold closed: Set last and quit loop.
last += fp->fd_len - 1;
break;
}
@@ -248,10 +244,12 @@ bool hasFoldingWin(
if (last > win->w_buffer->b_ml.ml_line_count) {
last = win->w_buffer->b_ml.ml_line_count;
}
- if (lastp != NULL)
+ if (lastp != NULL) {
*lastp = last;
- if (firstp != NULL)
+ }
+ if (firstp != NULL) {
*firstp = first;
+ }
if (infop != NULL) {
infop->fi_level = level + 1;
infop->fi_lnum = first;
@@ -260,7 +258,7 @@ bool hasFoldingWin(
return true;
}
-/* foldLevel() {{{2 */
+// foldLevel() {{{2
/*
* Return fold level at line number "lnum" in the current window.
*/
@@ -268,16 +266,18 @@ int foldLevel(linenr_T lnum)
{
/* While updating the folds lines between invalid_top and invalid_bot have
* an undefined fold level. Otherwise update the folds first. */
- if (invalid_top == (linenr_T)0)
+ if (invalid_top == (linenr_T)0) {
checkupdate(curwin);
- else if (lnum == prev_lnum && prev_lnum_lvl >= 0)
+ } else if (lnum == prev_lnum && prev_lnum_lvl >= 0) {
return prev_lnum_lvl;
- else if (lnum >= invalid_top && lnum <= invalid_bot)
+ } else if (lnum >= invalid_top && lnum <= invalid_bot) {
return -1;
+ }
- /* Return quickly when there is no folding at all in this window. */
- if (!hasAnyFolding(curwin))
+ // Return quickly when there is no folding at all in this window.
+ if (!hasAnyFolding(curwin)) {
return 0;
+ }
return foldLevelWin(curwin, lnum);
}
@@ -307,7 +307,7 @@ foldinfo_T fold_info(win_T *win, linenr_T lnum)
linenr_T last;
if (hasFoldingWin(win, lnum, NULL, &last, false, &info)) {
- info.fi_lines = (long)(last - lnum + 1);
+ info.fi_lines = (last - lnum + 1);
} else {
info.fi_lines = 0;
}
@@ -315,7 +315,7 @@ foldinfo_T fold_info(win_T *win, linenr_T lnum)
return info;
}
-/* foldmethodIsManual() {{{2 */
+// foldmethodIsManual() {{{2
/*
* Return TRUE if 'foldmethod' is "manual"
*/
@@ -324,7 +324,7 @@ int foldmethodIsManual(win_T *wp)
return wp->w_p_fdm[3] == 'u';
}
-/* foldmethodIsIndent() {{{2 */
+// foldmethodIsIndent() {{{2
/*
* Return TRUE if 'foldmethod' is "indent"
*/
@@ -333,7 +333,7 @@ int foldmethodIsIndent(win_T *wp)
return wp->w_p_fdm[0] == 'i';
}
-/* foldmethodIsExpr() {{{2 */
+// foldmethodIsExpr() {{{2
/*
* Return TRUE if 'foldmethod' is "expr"
*/
@@ -342,7 +342,7 @@ int foldmethodIsExpr(win_T *wp)
return wp->w_p_fdm[1] == 'x';
}
-/* foldmethodIsMarker() {{{2 */
+// foldmethodIsMarker() {{{2
/*
* Return TRUE if 'foldmethod' is "marker"
*/
@@ -351,7 +351,7 @@ int foldmethodIsMarker(win_T *wp)
return wp->w_p_fdm[2] == 'r';
}
-/* foldmethodIsSyntax() {{{2 */
+// foldmethodIsSyntax() {{{2
/*
* Return TRUE if 'foldmethod' is "syntax"
*/
@@ -360,7 +360,7 @@ int foldmethodIsSyntax(win_T *wp)
return wp->w_p_fdm[0] == 's';
}
-/* foldmethodIsDiff() {{{2 */
+// foldmethodIsDiff() {{{2
/*
* Return TRUE if 'foldmethod' is "diff"
*/
@@ -377,7 +377,7 @@ void closeFold(pos_T pos, long count)
setFoldRepeat(pos, count, false);
}
-/* closeFoldRecurse() {{{2 */
+// closeFoldRecurse() {{{2
/*
* Close fold for current window at line "lnum" recursively.
*/
@@ -386,19 +386,15 @@ void closeFoldRecurse(pos_T pos)
(void)setManualFold(pos, false, true, NULL);
}
-/* opFoldRange() {{{2 */
-/*
- * Open or Close folds for current window in lines "first" to "last".
- * Used for "zo", "zO", "zc" and "zC" in Visual mode.
- */
-void
-opFoldRange(
- pos_T firstpos,
- pos_T lastpos,
- int opening, // TRUE to open, FALSE to close
- int recurse, // TRUE to do it recursively
- int had_visual // TRUE when Visual selection used
-)
+// opFoldRange() {{{2
+///
+/// Open or Close folds for current window in lines "first" to "last".
+/// Used for "zo", "zO", "zc" and "zC" in Visual mode.
+///
+/// @param opening TRUE to open, FALSE to close
+/// @param recurse TRUE to do it recursively
+/// @param had_visual TRUE when Visual selection used
+void opFoldRange(pos_T firstpos, pos_T lastpos, int opening, int recurse, int had_visual)
{
int done = DONE_NOTHING; // avoid error messages
linenr_T first = firstpos.lnum;
@@ -411,8 +407,9 @@ opFoldRange(
lnum_next = lnum;
/* Opening one level only: next fold to open is after the one going to
* be opened. */
- if (opening && !recurse)
+ if (opening && !recurse) {
(void)hasFolding(lnum, NULL, &lnum_next);
+ }
(void)setManualFold(temp, opening, recurse, &done);
// Closing one level only: next line to close a fold is after just
// closed fold.
@@ -420,14 +417,16 @@ opFoldRange(
(void)hasFolding(lnum, NULL, &lnum_next);
}
}
- if (done == DONE_NOTHING)
+ if (done == DONE_NOTHING) {
EMSG(_(e_nofold));
- /* Force a redraw to remove the Visual highlighting. */
- if (had_visual)
+ }
+ // Force a redraw to remove the Visual highlighting.
+ if (had_visual) {
redraw_curbuf_later(INVERTED);
+ }
}
-/* openFold() {{{2 */
+// openFold() {{{2
/*
* Open fold for current window at line "lnum".
* Repeat "count" times.
@@ -437,7 +436,7 @@ void openFold(pos_T pos, long count)
setFoldRepeat(pos, count, true);
}
-/* openFoldRecurse() {{{2 */
+// openFoldRecurse() {{{2
/*
* Open fold for current window at line "lnum" recursively.
*/
@@ -446,7 +445,7 @@ void openFoldRecurse(pos_T pos)
(void)setManualFold(pos, true, true, NULL);
}
-/* foldOpenCursor() {{{2 */
+// foldOpenCursor() {{{2
/*
* Open folds until the cursor line is not in a closed fold.
*/
@@ -455,7 +454,7 @@ void foldOpenCursor(void)
int done;
checkupdate(curwin);
- if (hasAnyFolding(curwin))
+ if (hasAnyFolding(curwin)) {
for (;; ) {
done = DONE_NOTHING;
(void)setManualFold(curwin->w_cursor, true, false, &done);
@@ -463,9 +462,10 @@ void foldOpenCursor(void)
break;
}
}
+ }
}
-/* newFoldLevel() {{{2 */
+// newFoldLevel() {{{2
/*
* Set new foldlevel for current window.
*/
@@ -488,7 +488,7 @@ void newFoldLevel(void)
static void newFoldLevelWin(win_T *wp)
{
- fold_T *fp;
+ fold_T *fp;
checkupdate(wp);
if (wp->w_fold_manual) {
@@ -496,62 +496,65 @@ static void newFoldLevelWin(win_T *wp)
* manual open/close will then change the flags to FD_OPEN or
* FD_CLOSED for those folds that don't use 'foldlevel'. */
fp = (fold_T *)wp->w_folds.ga_data;
- for (int i = 0; i < wp->w_folds.ga_len; ++i)
+ for (int i = 0; i < wp->w_folds.ga_len; ++i) {
fp[i].fd_flags = FD_LEVEL;
+ }
wp->w_fold_manual = false;
}
changed_window_setting_win(wp);
}
-/* foldCheckClose() {{{2 */
+// foldCheckClose() {{{2
/*
* Apply 'foldlevel' to all folds that don't contain the cursor.
*/
void foldCheckClose(void)
{
- if (*p_fcl != NUL) { /* can only be "all" right now */
+ if (*p_fcl != NUL) { // can only be "all" right now
checkupdate(curwin);
if (checkCloseRec(&curwin->w_folds, curwin->w_cursor.lnum,
- (int)curwin->w_p_fdl))
+ (int)curwin->w_p_fdl)) {
changed_window_setting();
+ }
}
}
-/* checkCloseRec() {{{2 */
+// checkCloseRec() {{{2
static int checkCloseRec(garray_T *gap, linenr_T lnum, int level)
{
- fold_T *fp;
+ fold_T *fp;
int retval = FALSE;
fp = (fold_T *)gap->ga_data;
for (int i = 0; i < gap->ga_len; ++i) {
- /* Only manually opened folds may need to be closed. */
+ // Only manually opened folds may need to be closed.
if (fp[i].fd_flags == FD_OPEN) {
if (level <= 0 && (lnum < fp[i].fd_top
|| lnum >= fp[i].fd_top + fp[i].fd_len)) {
fp[i].fd_flags = FD_LEVEL;
retval = TRUE;
- } else
+ } else {
retval |= checkCloseRec(&fp[i].fd_nested, lnum - fp[i].fd_top,
- level - 1);
+ level - 1);
+ }
}
}
return retval;
}
-/* foldCreateAllowed() {{{2 */
-/*
- * Return TRUE if it's allowed to manually create or delete a fold.
- * Give an error message and return FALSE if not.
- */
-int foldManualAllowed(int create)
+// foldCreateAllowed() {{{2
+/// Return TRUE if it's allowed to manually create or delete a fold.
+/// Give an error message and return FALSE if not.
+int foldManualAllowed(bool create)
{
- if (foldmethodIsManual(curwin) || foldmethodIsMarker(curwin))
+ if (foldmethodIsManual(curwin) || foldmethodIsMarker(curwin)) {
return TRUE;
- if (create)
+ }
+ if (create) {
EMSG(_("E350: Cannot create fold with current 'foldmethod'"));
- else
+ } else {
EMSG(_("E351: Cannot delete fold with current 'foldmethod'"));
+ }
return FALSE;
}
@@ -560,8 +563,8 @@ int foldManualAllowed(int create)
/// window.
void foldCreate(win_T *wp, pos_T start, pos_T end)
{
- fold_T *fp;
- garray_T *gap;
+ fold_T *fp;
+ garray_T *gap;
garray_T fold_ga;
int i;
int cont;
@@ -658,13 +661,14 @@ void foldCreate(win_T *wp, pos_T start, pos_T end)
((fold_T *)fold_ga.ga_data)[j].fd_top -= start_rel.lnum;
}
}
- /* Move remaining entries to after the new fold. */
- if (i < gap->ga_len)
+ // Move remaining entries to after the new fold.
+ if (i < gap->ga_len) {
memmove(fp + 1, (fold_T *)gap->ga_data + i,
sizeof(fold_T) * (size_t)(gap->ga_len - i));
+ }
gap->ga_len = gap->ga_len + 1 - cont;
- /* insert new fold */
+ // insert new fold
fp->fd_nested = fold_ga;
fp->fd_top = start_rel.lnum;
fp->fd_len = end_rel.lnum - start_rel.lnum + 1;
@@ -692,16 +696,11 @@ void foldCreate(win_T *wp, pos_T start, pos_T end)
/// @param end delete all folds from start to end when not 0
/// @param recursive delete recursively if true
/// @param had_visual true when Visual selection used
-void deleteFold(
- win_T *const wp,
- const linenr_T start,
- const linenr_T end,
- const int recursive,
- const bool had_visual // true when Visual selection used
-)
-{
- fold_T *fp;
- fold_T *found_fp = NULL;
+void deleteFold(win_T *const wp, const linenr_T start, const linenr_T end, const int recursive,
+ const bool had_visual)
+{
+ fold_T *fp;
+ fold_T *found_fp = NULL;
linenr_T found_off = 0;
bool maybe_small = false;
int level = 0;
@@ -719,9 +718,10 @@ void deleteFold(
linenr_T lnum_off = 0;
bool use_level = false;
for (;; ) {
- if (!foldFind(gap, lnum - lnum_off, &fp))
+ if (!foldFind(gap, lnum - lnum_off, &fp)) {
break;
- /* lnum is inside this fold, remember info */
+ }
+ // lnum is inside this fold, remember info
found_ga = gap;
found_fp = fp;
found_off = lnum_off;
@@ -732,7 +732,7 @@ void deleteFold(
break;
}
- /* check nested folds */
+ // check nested folds
gap = &fp->fd_nested;
lnum_off += fp->fd_top;
++level;
@@ -790,7 +790,7 @@ void deleteFold(
}
}
-/* clearFolding() {{{2 */
+// clearFolding() {{{2
/*
* Remove all folding for window "win".
*/
@@ -800,7 +800,7 @@ void clearFolding(win_T *win)
win->w_foldinvalid = false;
}
-/* foldUpdate() {{{2 */
+// foldUpdate() {{{2
/*
* Update folds for changes in the buffer of a window.
* Note that inserted/deleted lines must have already been taken care of by
@@ -836,7 +836,7 @@ void foldUpdate(win_T *wp, linenr_T top, linenr_T bot)
|| foldmethodIsSyntax(wp)) {
int save_got_int = got_int;
- /* reset got_int here, otherwise it won't work */
+ // reset got_int here, otherwise it won't work
got_int = FALSE;
foldUpdateIEMS(wp, top, bot);
got_int |= save_got_int;
@@ -856,7 +856,7 @@ void foldUpdateAfterInsert(void)
foldOpenCursor();
}
-/* foldUpdateAll() {{{2 */
+// foldUpdateAll() {{{2
/*
* Update all lines in a window for folding.
* Used when a fold setting changes or after reloading the buffer.
@@ -870,19 +870,17 @@ void foldUpdateAll(win_T *win)
}
// foldMoveTo() {{{2
-//
-// If "updown" is false: Move to the start or end of the fold.
-// If "updown" is true: move to fold at the same level.
-// If not moved return FAIL.
-int foldMoveTo(
- const bool updown,
- const int dir, // FORWARD or BACKWARD
- const long count
-)
+///
+/// If "updown" is false: Move to the start or end of the fold.
+/// If "updown" is true: move to fold at the same level.
+/// @return FAIL if not moved.
+///
+/// @param dir FORWARD or BACKWARD
+int foldMoveTo(const bool updown, const int dir, const long count)
{
int retval = FAIL;
linenr_T lnum;
- fold_T *fp;
+ fold_T *fp;
checkupdate(curwin);
@@ -909,12 +907,14 @@ int foldMoveTo(
/* When moving up, consider a fold above the cursor; when
* moving down consider a fold below the cursor. */
if (dir == FORWARD) {
- if (fp - (fold_T *)gap->ga_data >= gap->ga_len)
+ if (fp - (fold_T *)gap->ga_data >= gap->ga_len) {
break;
+ }
--fp;
} else {
- if (fp == (fold_T *)gap->ga_data)
+ if (fp == (fold_T *)gap->ga_data) {
break;
+ }
}
/* don't look for contained folds, they will always move
* the cursor too far. */
@@ -922,31 +922,34 @@ int foldMoveTo(
}
if (!last) {
- /* Check if this fold is closed. */
+ // Check if this fold is closed.
if (check_closed(curwin, fp, &use_level, level,
&maybe_small, lnum_off)) {
last = true;
}
- /* "[z" and "]z" stop at closed fold */
- if (last && !updown)
+ // "[z" and "]z" stop at closed fold
+ if (last && !updown) {
break;
+ }
}
if (updown) {
if (dir == FORWARD) {
- /* to start of next fold if there is one */
+ // to start of next fold if there is one
if (fp + 1 - (fold_T *)gap->ga_data < gap->ga_len) {
lnum = fp[1].fd_top + lnum_off;
- if (lnum > curwin->w_cursor.lnum)
+ if (lnum > curwin->w_cursor.lnum) {
lnum_found = lnum;
+ }
}
} else {
- /* to end of previous fold if there is one */
+ // to end of previous fold if there is one
if (fp > (fold_T *)gap->ga_data) {
lnum = fp[-1].fd_top + lnum_off + fp[-1].fd_len - 1;
- if (lnum < curwin->w_cursor.lnum)
+ if (lnum < curwin->w_cursor.lnum) {
lnum_found = lnum;
+ }
}
}
} else {
@@ -954,37 +957,42 @@ int foldMoveTo(
* nested folds. */
if (dir == FORWARD) {
lnum = fp->fd_top + lnum_off + fp->fd_len - 1;
- if (lnum > curwin->w_cursor.lnum)
+ if (lnum > curwin->w_cursor.lnum) {
lnum_found = lnum;
+ }
} else {
lnum = fp->fd_top + lnum_off;
- if (lnum < curwin->w_cursor.lnum)
+ if (lnum < curwin->w_cursor.lnum) {
lnum_found = lnum;
+ }
}
}
- if (last)
+ if (last) {
break;
+ }
- /* Check nested folds (if any). */
+ // Check nested folds (if any).
gap = &fp->fd_nested;
lnum_off += fp->fd_top;
++level;
}
if (lnum_found != curwin->w_cursor.lnum) {
- if (retval == FAIL)
+ if (retval == FAIL) {
setpcmark();
+ }
curwin->w_cursor.lnum = lnum_found;
curwin->w_cursor.col = 0;
retval = OK;
- } else
+ } else {
break;
+ }
}
return retval;
}
-/* foldInitWin() {{{2 */
+// foldInitWin() {{{2
/*
* Init the fold info in a new window.
*/
@@ -993,7 +1001,7 @@ void foldInitWin(win_T *new_win)
ga_init(&new_win->w_folds, (int)sizeof(fold_T), 10);
}
-/* find_wl_entry() {{{2 */
+// find_wl_entry() {{{2
/*
* Find an entry in the win->w_lines[] array for buffer line "lnum".
* Only valid entries are considered (for entries where wl_valid is FALSE the
@@ -1004,27 +1012,31 @@ int find_wl_entry(win_T *win, linenr_T lnum)
{
int i;
- for (i = 0; i < win->w_lines_valid; ++i)
+ for (i = 0; i < win->w_lines_valid; ++i) {
if (win->w_lines[i].wl_valid) {
- if (lnum < win->w_lines[i].wl_lnum)
+ if (lnum < win->w_lines[i].wl_lnum) {
return -1;
- if (lnum <= win->w_lines[i].wl_lastlnum)
+ }
+ if (lnum <= win->w_lines[i].wl_lastlnum) {
return i;
+ }
}
+ }
return -1;
}
-/* foldAdjustVisual() {{{2 */
+// foldAdjustVisual() {{{2
/*
* Adjust the Visual area to include any fold at the start or end completely.
*/
void foldAdjustVisual(void)
{
- pos_T *start, *end;
- char_u *ptr;
+ pos_T *start, *end;
+ char_u *ptr;
- if (!VIsual_active || !hasAnyFolding(curwin))
+ if (!VIsual_active || !hasAnyFolding(curwin)) {
return;
+ }
if (ltoreq(VIsual, curwin->w_cursor)) {
start = &VIsual;
@@ -1033,8 +1045,9 @@ void foldAdjustVisual(void)
start = &curwin->w_cursor;
end = &VIsual;
}
- if (hasFolding(start->lnum, &start->lnum, NULL))
+ if (hasFolding(start->lnum, &start->lnum, NULL)) {
start->col = 0;
+ }
if (hasFolding(end->lnum, NULL, &end->lnum)) {
ptr = ml_get(end->lnum);
end->col = (colnr_T)STRLEN(ptr);
@@ -1046,7 +1059,7 @@ void foldAdjustVisual(void)
}
}
-/* cursor_foldstart() {{{2 */
+// cursor_foldstart() {{{2
/*
* Move the cursor to the first line of a closed fold.
*/
@@ -1055,20 +1068,21 @@ void foldAdjustCursor(void)
(void)hasFolding(curwin->w_cursor.lnum, &curwin->w_cursor.lnum, NULL);
}
-/* Internal functions for "fold_T" {{{1 */
-/* cloneFoldGrowArray() {{{2 */
+// Internal functions for "fold_T" {{{1
+// cloneFoldGrowArray() {{{2
/*
* Will "clone" (i.e deep copy) a garray_T of folds.
*/
void cloneFoldGrowArray(garray_T *from, garray_T *to)
{
- fold_T *from_p;
- fold_T *to_p;
+ fold_T *from_p;
+ fold_T *to_p;
ga_init(to, from->ga_itemsize, from->ga_growsize);
- if (GA_EMPTY(from))
+ if (GA_EMPTY(from)) {
return;
+ }
ga_grow(to, from->ga_len);
@@ -1087,17 +1101,16 @@ void cloneFoldGrowArray(garray_T *from, garray_T *to)
}
}
-/* foldFind() {{{2 */
-/*
- * Search for line "lnum" in folds of growarray "gap".
- * Set *fpp to the fold struct for the fold that contains "lnum" or
- * the first fold below it (careful: it can be beyond the end of the array!).
- * Returns FALSE when there is no fold that contains "lnum".
- */
+// foldFind() {{{2
+/// Search for line "lnum" in folds of growarray "gap".
+/// Set *fpp to the fold struct for the fold that contains "lnum" or
+/// the first fold below it (careful: it can be beyond the end of the array!).
+///
+/// @return false when there is no fold that contains "lnum".
static bool foldFind(const garray_T *gap, linenr_T lnum, fold_T **fpp)
{
linenr_T low, high;
- fold_T *fp;
+ fold_T *fp;
if (gap->ga_len == 0) {
*fpp = NULL;
@@ -1114,39 +1127,40 @@ static bool foldFind(const garray_T *gap, linenr_T lnum, fold_T **fpp)
high = gap->ga_len - 1;
while (low <= high) {
linenr_T i = (low + high) / 2;
- if (fp[i].fd_top > lnum)
- /* fold below lnum, adjust high */
+ if (fp[i].fd_top > lnum) {
+ // fold below lnum, adjust high
high = i - 1;
- else if (fp[i].fd_top + fp[i].fd_len <= lnum)
- /* fold above lnum, adjust low */
+ } else if (fp[i].fd_top + fp[i].fd_len <= lnum) {
+ // fold above lnum, adjust low
low = i + 1;
- else {
- /* lnum is inside this fold */
+ } else {
+ // lnum is inside this fold
*fpp = fp + i;
- return TRUE;
+ return true;
}
}
*fpp = fp + low;
return false;
}
-/* foldLevelWin() {{{2 */
+// foldLevelWin() {{{2
/*
* Return fold level at line number "lnum" in window "wp".
*/
static int foldLevelWin(win_T *wp, linenr_T lnum)
{
- fold_T *fp;
+ fold_T *fp;
linenr_T lnum_rel = lnum;
int level = 0;
- garray_T *gap;
+ garray_T *gap;
- /* Recursively search for a fold that contains "lnum". */
+ // Recursively search for a fold that contains "lnum".
gap = &wp->w_folds;
for (;; ) {
- if (!foldFind(gap, lnum_rel, &fp))
+ if (!foldFind(gap, lnum_rel, &fp)) {
break;
- /* Check nested folds. Line number is relative to containing fold. */
+ }
+ // Check nested folds. Line number is relative to containing fold.
gap = &fp->fd_nested;
lnum_rel -= fp->fd_top;
++level;
@@ -1155,19 +1169,19 @@ static int foldLevelWin(win_T *wp, linenr_T lnum)
return level;
}
-/* checkupdate() {{{2 */
+// checkupdate() {{{2
/*
* Check if the folds in window "wp" are invalid and update them if needed.
*/
static void checkupdate(win_T *wp)
{
if (wp->w_foldinvalid) {
- foldUpdate(wp, (linenr_T)1, (linenr_T)MAXLNUM); /* will update all */
+ foldUpdate(wp, (linenr_T)1, (linenr_T)MAXLNUM); // will update all
wp->w_foldinvalid = false;
}
}
-/* setFoldRepeat() {{{2 */
+// setFoldRepeat() {{{2
/*
* Open or close fold for current window at line "lnum".
* Repeat "count" times.
@@ -1181,26 +1195,23 @@ static void setFoldRepeat(pos_T pos, long count, int do_open)
done = DONE_NOTHING;
(void)setManualFold(pos, do_open, false, &done);
if (!(done & DONE_ACTION)) {
- /* Only give an error message when no fold could be opened. */
- if (n == 0 && !(done & DONE_FOLD))
+ // Only give an error message when no fold could be opened.
+ if (n == 0 && !(done & DONE_FOLD)) {
EMSG(_(e_nofold));
+ }
break;
}
}
}
-/* setManualFold() {{{2 */
-/*
- * Open or close the fold in the current window which contains "lnum".
- * Also does this for other windows in diff mode when needed.
- */
-static linenr_T
-setManualFold(
- pos_T pos,
- int opening, // TRUE when opening, FALSE when closing
- int recurse, // TRUE when closing/opening recursive
- int *donep
-)
+// setManualFold() {{{2
+///
+/// Open or close the fold in the current window which contains "lnum".
+/// Also does this for other windows in diff mode when needed.
+///
+/// @param opening TRUE when opening, FALSE when closing
+/// @param recurse TRUE when closing/opening recursive
+static linenr_T setManualFold(pos_T pos, int opening, int recurse, int *donep)
{
linenr_T lnum = pos.lnum;
if (foldmethodIsDiff(curwin) && curwin->w_p_scb) {
@@ -1223,33 +1234,28 @@ setManualFold(
return setManualFoldWin(curwin, lnum, opening, recurse, donep);
}
-/* setManualFoldWin() {{{2 */
-/*
- * Open or close the fold in window "wp" which contains "lnum".
- * "donep", when not NULL, points to flag that is set to DONE_FOLD when some
- * fold was found and to DONE_ACTION when some fold was opened or closed.
- * When "donep" is NULL give an error message when no fold was found for
- * "lnum", but only if "wp" is "curwin".
- * Return the line number of the next line that could be closed.
- * It's only valid when "opening" is TRUE!
- */
-static linenr_T
-setManualFoldWin(
- win_T *wp,
- linenr_T lnum,
- int opening, // TRUE when opening, FALSE when closing
- int recurse, // TRUE when closing/opening recursive
- int *donep
-)
-{
- fold_T *fp;
- fold_T *fp2;
- fold_T *found = NULL;
+// setManualFoldWin() {{{2
+/// Open or close the fold in window "wp" which contains "lnum".
+/// "donep", when not NULL, points to flag that is set to DONE_FOLD when some
+/// fold was found and to DONE_ACTION when some fold was opened or closed.
+/// When "donep" is NULL give an error message when no fold was found for
+/// "lnum", but only if "wp" is "curwin".
+///
+/// @param opening TRUE when opening, FALSE when closing
+/// @param recurse TRUE when closing/opening recursive
+///
+/// @return the line number of the next line that could be closed.
+/// It's only valid when "opening" is TRUE!
+static linenr_T setManualFoldWin(win_T *wp, linenr_T lnum, int opening, int recurse, int *donep)
+{
+ fold_T *fp;
+ fold_T *fp2;
+ fold_T *found = NULL;
int j;
int level = 0;
int use_level = FALSE;
int found_fold = FALSE;
- garray_T *gap;
+ garray_T *gap;
linenr_T next = MAXLNUM;
linenr_T off = 0;
int done = 0;
@@ -1269,43 +1275,47 @@ setManualFoldWin(
break;
}
- /* lnum is inside this fold */
+ // lnum is inside this fold
found_fold = TRUE;
- /* If there is a following fold, continue there next time. */
- if (fp + 1 < (fold_T *)gap->ga_data + gap->ga_len)
+ // If there is a following fold, continue there next time.
+ if (fp + 1 < (fold_T *)gap->ga_data + gap->ga_len) {
next = fp[1].fd_top + off;
+ }
- /* Change from level-dependent folding to manual. */
+ // Change from level-dependent folding to manual.
if (use_level || fp->fd_flags == FD_LEVEL) {
use_level = TRUE;
- if (level >= wp->w_p_fdl)
+ if (level >= wp->w_p_fdl) {
fp->fd_flags = FD_CLOSED;
- else
+ } else {
fp->fd_flags = FD_OPEN;
+ }
fp2 = (fold_T *)fp->fd_nested.ga_data;
- for (j = 0; j < fp->fd_nested.ga_len; ++j)
+ for (j = 0; j < fp->fd_nested.ga_len; ++j) {
fp2[j].fd_flags = FD_LEVEL;
+ }
}
- /* Simple case: Close recursively means closing the fold. */
+ // Simple case: Close recursively means closing the fold.
if (!opening && recurse) {
if (fp->fd_flags != FD_CLOSED) {
done |= DONE_ACTION;
fp->fd_flags = FD_CLOSED;
}
} else if (fp->fd_flags == FD_CLOSED) {
- /* When opening, open topmost closed fold. */
+ // When opening, open topmost closed fold.
if (opening) {
fp->fd_flags = FD_OPEN;
done |= DONE_ACTION;
- if (recurse)
+ if (recurse) {
foldOpenNested(fp);
+ }
}
break;
}
- /* fold is open, check nested folds */
+ // fold is open, check nested folds
found = fp;
gap = &fp->fd_nested;
lnum -= fp->fd_top;
@@ -1313,31 +1323,34 @@ setManualFoldWin(
++level;
}
if (found_fold) {
- /* When closing and not recurse, close deepest open fold. */
+ // When closing and not recurse, close deepest open fold.
if (!opening && found != NULL) {
found->fd_flags = FD_CLOSED;
done |= DONE_ACTION;
}
wp->w_fold_manual = true;
- if (done & DONE_ACTION)
+ if (done & DONE_ACTION) {
changed_window_setting_win(wp);
+ }
done |= DONE_FOLD;
- } else if (donep == NULL && wp == curwin)
+ } else if (donep == NULL && wp == curwin) {
EMSG(_(e_nofold));
+ }
- if (donep != NULL)
+ if (donep != NULL) {
*donep |= done;
+ }
return next;
}
-/* foldOpenNested() {{{2 */
+// foldOpenNested() {{{2
/*
* Open all nested folds in fold "fpr" recursively.
*/
static void foldOpenNested(fold_T *fpr)
{
- fold_T *fp;
+ fold_T *fp;
fp = (fold_T *)fpr->fd_nested.ga_data;
for (int i = 0; i < fpr->fd_nested.ga_len; ++i) {
@@ -1367,15 +1380,16 @@ static void deleteFoldEntry(win_T *const wp, garray_T *const gap, const int idx,
int moved = fp->fd_nested.ga_len;
ga_grow(gap, moved - 1);
{
- /* Get "fp" again, the array may have been reallocated. */
+ // Get "fp" again, the array may have been reallocated.
fp = (fold_T *)gap->ga_data + idx;
// adjust fd_top and fd_flags for the moved folds
fold_T *nfp = (fold_T *)fp->fd_nested.ga_data;
for (int i = 0; i < moved; i++) {
nfp[i].fd_top += fp->fd_top;
- if (fp->fd_flags == FD_LEVEL)
+ if (fp->fd_flags == FD_LEVEL) {
nfp[i].fd_flags = FD_LEVEL;
+ }
if (fp->fd_small == kNone) {
nfp[i].fd_small = kNone;
}
@@ -1394,17 +1408,17 @@ static void deleteFoldEntry(win_T *const wp, garray_T *const gap, const int idx,
}
}
-/* deleteFoldRecurse() {{{2 */
+// deleteFoldRecurse() {{{2
/*
* Delete nested folds in a fold.
*/
void deleteFoldRecurse(buf_T *bp, garray_T *gap)
{
-# define DELETE_FOLD_NESTED(fd) deleteFoldRecurse(bp, &((fd)->fd_nested))
+#define DELETE_FOLD_NESTED(fd) deleteFoldRecurse(bp, &((fd)->fd_nested))
GA_DEEP_CLEAR(gap, fold_T, DELETE_FOLD_NESTED);
}
-/* foldMarkAdjust() {{{2 */
+// foldMarkAdjust() {{{2
/*
* Update line numbers of folds for inserted/deleted lines.
*/
@@ -1412,8 +1426,9 @@ void foldMarkAdjust(win_T *wp, linenr_T line1, linenr_T line2, long amount, long
{
/* If deleting marks from line1 to line2, but not deleting all those
* lines, set line2 so that only deleted lines have their folds removed. */
- if (amount == MAXLNUM && line2 >= line1 && line2 - line1 >= -amount_after)
+ if (amount == MAXLNUM && line2 >= line1 && line2 - line1 >= -amount_after) {
line2 = line1 - amount_after - 1;
+ }
/* If appending a line in Insert mode, it should be included in the fold
* just above the line. */
if ((State & INSERT) && amount == (linenr_T)1 && line2 == MAXLNUM) {
@@ -1423,12 +1438,10 @@ void foldMarkAdjust(win_T *wp, linenr_T line1, linenr_T line2, long amount, long
}
// foldMarkAdjustRecurse() {{{2
-static void foldMarkAdjustRecurse(
- win_T *wp, garray_T *gap,
- linenr_T line1, linenr_T line2, long amount, long amount_after
-)
+static void foldMarkAdjustRecurse(win_T *wp, garray_T *gap, linenr_T line1, linenr_T line2,
+ long amount, long amount_after)
{
- fold_T *fp;
+ fold_T *fp;
linenr_T last;
linenr_T top;
@@ -1438,12 +1451,13 @@ static void foldMarkAdjustRecurse(
/* In Insert mode an inserted line at the top of a fold is considered part
* of the fold, otherwise it isn't. */
- if ((State & INSERT) && amount == (linenr_T)1 && line2 == MAXLNUM)
+ if ((State & INSERT) && amount == (linenr_T)1 && line2 == MAXLNUM) {
top = line1 + 1;
- else
+ } else {
top = line1;
+ }
- /* Find the fold containing or just below "line1". */
+ // Find the fold containing or just below "line1".
(void)foldFind(gap, line1, &fp);
/*
@@ -1452,26 +1466,28 @@ static void foldMarkAdjustRecurse(
for (int i = (int)(fp - (fold_T *)gap->ga_data); i < gap->ga_len; ++i, ++fp) {
/*
* Check for these situations:
- * 1 2 3
- * 1 2 3
- * line1 2 3 4 5
- * 2 3 4 5
- * 2 3 4 5
- * line2 2 3 4 5
- * 3 5 6
- * 3 5 6
+ * 1 2 3
+ * 1 2 3
+ * line1 2 3 4 5
+ * 2 3 4 5
+ * 2 3 4 5
+ * line2 2 3 4 5
+ * 3 5 6
+ * 3 5 6
*/
- last = fp->fd_top + fp->fd_len - 1; /* last line of fold */
+ last = fp->fd_top + fp->fd_len - 1; // last line of fold
- /* 1. fold completely above line1: nothing to do */
- if (last < line1)
+ // 1. fold completely above line1: nothing to do
+ if (last < line1) {
continue;
+ }
- /* 6. fold below line2: only adjust for amount_after */
+ // 6. fold below line2: only adjust for amount_after
if (fp->fd_top > line2) {
- if (amount_after == 0)
+ if (amount_after == 0) {
break;
+ }
fp->fd_top += amount_after;
} else {
if (fp->fd_top >= top && last <= line2) {
@@ -1490,13 +1506,14 @@ static void foldMarkAdjustRecurse(
foldMarkAdjustRecurse(wp, &fp->fd_nested, line1 - fp->fd_top,
line2 - fp->fd_top, amount, amount_after);
if (last <= line2) {
- /* 2. fold contains line1, line2 is below fold */
- if (amount == MAXLNUM)
+ // 2. fold contains line1, line2 is below fold
+ if (amount == MAXLNUM) {
fp->fd_len = line1 - fp->fd_top;
- else
+ } else {
fp->fd_len += amount;
+ }
} else {
- /* 3. fold contains line1 and line2 */
+ // 3. fold contains line1 and line2
fp->fd_len += amount_after;
}
} else {
@@ -1521,7 +1538,7 @@ static void foldMarkAdjustRecurse(
}
}
-/* getDeepestNesting() {{{2 */
+// getDeepestNesting() {{{2
/*
* Get the lowest 'foldlevel' value that makes the deepest nested fold in the
* current window open.
@@ -1536,13 +1553,14 @@ static int getDeepestNestingRecurse(garray_T *gap)
{
int level;
int maxlevel = 0;
- fold_T *fp;
+ fold_T *fp;
fp = (fold_T *)gap->ga_data;
for (int i = 0; i < gap->ga_len; ++i) {
level = getDeepestNestingRecurse(&fp[i].fd_nested) + 1;
- if (level > maxlevel)
+ if (level > maxlevel) {
maxlevel = level;
+ }
}
return maxlevel;
@@ -1557,14 +1575,8 @@ static int getDeepestNestingRecurse(garray_T *gap)
/// @param[out] maybe_smallp true: outer this had fd_small == kNone
/// @param lnum_off line number offset for fp->fd_top
/// @return true if fold is closed
-static bool check_closed(
- win_T *const wp,
- fold_T *const fp,
- bool *const use_levelp,
- const int level,
- bool *const maybe_smallp,
- const linenr_T lnum_off
-)
+static bool check_closed(win_T *const wp, fold_T *const fp, bool *const use_levelp, const int level,
+ bool *const maybe_smallp, const linenr_T lnum_off)
{
bool closed = false;
@@ -1597,13 +1609,9 @@ static bool check_closed(
// checkSmall() {{{2
/// Update fd_small field of fold "fp".
-/// @param lnum_off offset for fp->fd_top
-static void
-checkSmall(
- win_T *const wp,
- fold_T *const fp,
- const linenr_T lnum_off // offset for fp->fd_top
-)
+///
+/// @param lnum_off offset for fp->fd_top
+static void checkSmall(win_T *const wp, fold_T *const fp, const linenr_T lnum_off)
{
if (fp->fd_small == kNone) {
// Mark any nested folds to maybe-small
@@ -1635,7 +1643,7 @@ static void setSmallMaybe(garray_T *gap)
}
}
-/* foldCreateMarkers() {{{2 */
+// foldCreateMarkers() {{{2
/*
* Create a fold from line "start" to line "end" (inclusive) in the current
* window by adding markers.
@@ -1664,17 +1672,16 @@ static void foldCreateMarkers(win_T *wp, pos_T start, pos_T end)
buf_updates_send_changes(buf, start.lnum, num_changed, num_changed, true);
}
-/* foldAddMarker() {{{2 */
+// foldAddMarker() {{{2
/*
* Add "marker[markerlen]" in 'commentstring' to line "lnum".
*/
-static void foldAddMarker(
- buf_T *buf, pos_T pos, const char_u *marker, size_t markerlen)
+static void foldAddMarker(buf_T *buf, pos_T pos, const char_u *marker, size_t markerlen)
{
- char_u *cms = buf->b_p_cms;
- char_u *line;
- char_u *newline;
- char_u *p = (char_u *)strstr((char *)buf->b_p_cms, "%s");
+ char_u *cms = buf->b_p_cms;
+ char_u *line;
+ char_u *newline;
+ char_u *p = (char_u *)strstr((char *)buf->b_p_cms, "%s");
bool line_is_comment = false;
linenr_T lnum = pos.lnum;
@@ -1706,17 +1713,11 @@ static void foldAddMarker(
}
}
-/* deleteFoldMarkers() {{{2 */
-/*
- * Delete the markers for a fold, causing it to be deleted.
- */
-static void
-deleteFoldMarkers(
- win_T *wp,
- fold_T *fp,
- int recursive,
- linenr_T lnum_off // offset for fp->fd_top
-)
+// deleteFoldMarkers() {{{2
+/// Delete the markers for a fold, causing it to be deleted.
+///
+/// @param lnum_off offset for fp->fd_top
+static void deleteFoldMarkers(win_T *wp, fold_T *fp, int recursive, linenr_T lnum_off)
{
if (recursive) {
for (int i = 0; i < fp->fd_nested.ga_len; i++) {
@@ -1736,13 +1737,11 @@ deleteFoldMarkers(
// Delete 'commentstring' if it matches.
// If the marker is not found, there is no error message. Could be a missing
// close-marker.
-static void foldDelMarker(
- buf_T *buf, linenr_T lnum, char_u *marker, size_t markerlen
-)
+static void foldDelMarker(buf_T *buf, linenr_T lnum, char_u *marker, size_t markerlen)
{
- char_u *newline;
- char_u *cms = buf->b_p_cms;
- char_u *cms2;
+ char_u *newline;
+ char_u *cms = buf->b_p_cms;
+ char_u *cms2;
// end marker may be missing and fold extends below the last line
if (lnum > buf->b_ml.ml_line_count) {
@@ -1753,12 +1752,13 @@ static void foldDelMarker(
if (STRNCMP(p, marker, markerlen) != 0) {
continue;
}
- /* Found the marker, include a digit if it's there. */
+ // Found the marker, include a digit if it's there.
size_t len = markerlen;
- if (ascii_isdigit(p[len]))
+ if (ascii_isdigit(p[len])) {
++len;
+ }
if (*cms != NUL) {
- /* Also delete 'commentstring' if it matches. */
+ // Also delete 'commentstring' if it matches.
cms2 = (char_u *)strstr((char *)cms, "%s");
if (p - line >= cms2 - cms
&& STRNCMP(p - (cms2 - cms), cms, cms2 - cms) == 0
@@ -1768,7 +1768,7 @@ static void foldDelMarker(
}
}
if (u_save(lnum - 1, lnum + 1) == OK) {
- /* Make new line: text-before-marker + text-after-marker */
+ // Make new line: text-before-marker + text-after-marker
newline = xmalloc(STRLEN(line) - len + 1);
assert(p >= line);
memcpy(newline, line, (size_t)(p - line));
@@ -1790,34 +1790,35 @@ static void foldDelMarker(
/// @return the text for a closed fold
///
/// Otherwise the result is in allocated memory.
-char_u *get_foldtext(win_T *wp, linenr_T lnum, linenr_T lnume,
- foldinfo_T foldinfo, char_u *buf)
+char_u *get_foldtext(win_T *wp, linenr_T lnum, linenr_T lnume, foldinfo_T foldinfo, char_u *buf)
FUNC_ATTR_NONNULL_ARG(1)
{
- char_u *text = NULL;
- /* an error occurred when evaluating 'fdt' setting */
+ char_u *text = NULL;
+ // an error occurred when evaluating 'fdt' setting
static int got_fdt_error = FALSE;
int save_did_emsg = did_emsg;
- static win_T *last_wp = NULL;
+ static win_T *last_wp = NULL;
static linenr_T last_lnum = 0;
- if (last_wp == NULL || last_wp != wp || last_lnum > lnum || last_lnum == 0)
- /* window changed, try evaluating foldtext setting once again */
+ if (last_wp == NULL || last_wp != wp || last_lnum > lnum || last_lnum == 0) {
+ // window changed, try evaluating foldtext setting once again
got_fdt_error = FALSE;
+ }
- if (!got_fdt_error)
- /* a previous error should not abort evaluating 'foldexpr' */
+ if (!got_fdt_error) {
+ // a previous error should not abort evaluating 'foldexpr'
did_emsg = FALSE;
+ }
if (*wp->w_p_fdt != NUL) {
char dashes[MAX_LEVEL + 2];
- win_T *save_curwin;
+ win_T *save_curwin;
int level;
- char_u *p;
+ char_u *p;
// Set "v:foldstart" and "v:foldend".
- set_vim_var_nr(VV_FOLDSTART, (varnumber_T) lnum);
- set_vim_var_nr(VV_FOLDEND, (varnumber_T) lnume);
+ set_vim_var_nr(VV_FOLDSTART, (varnumber_T)lnum);
+ set_vim_var_nr(VV_FOLDEND, (varnumber_T)lnume);
// Set "v:folddashes" to a string of "level" dashes.
// Set "v:foldlevel" to "level".
@@ -1828,22 +1829,22 @@ char_u *get_foldtext(win_T *wp, linenr_T lnum, linenr_T lnume,
memset(dashes, '-', (size_t)level);
dashes[level] = NUL;
set_vim_var_string(VV_FOLDDASHES, dashes, -1);
- set_vim_var_nr(VV_FOLDLEVEL, (varnumber_T) level);
+ set_vim_var_nr(VV_FOLDLEVEL, (varnumber_T)level);
- /* skip evaluating foldtext on errors */
+ // skip evaluating foldtext on errors
if (!got_fdt_error) {
save_curwin = curwin;
curwin = wp;
curbuf = wp->w_buffer;
emsg_silent++; // handle exceptions, but don't display errors
- text = eval_to_string_safe(
- wp->w_p_fdt, NULL,
- was_set_insecurely(wp, (char_u *)"foldtext", OPT_LOCAL));
+ text = eval_to_string_safe(wp->w_p_fdt, NULL,
+ was_set_insecurely(wp, (char_u *)"foldtext", OPT_LOCAL));
emsg_silent--;
- if (text == NULL || did_emsg)
+ if (text == NULL || did_emsg) {
got_fdt_error = TRUE;
+ }
curwin = save_curwin;
curbuf = curwin->w_buffer;
@@ -1852,8 +1853,9 @@ char_u *get_foldtext(win_T *wp, linenr_T lnum, linenr_T lnume,
last_wp = wp;
set_vim_var_string(VV_FOLDDASHES, NULL, -1);
- if (!did_emsg && save_did_emsg)
+ if (!did_emsg && save_did_emsg) {
did_emsg = save_did_emsg;
+ }
if (text != NULL) {
/* Replace unprintable characters, if there are any. But
@@ -1866,13 +1868,14 @@ char_u *get_foldtext(win_T *wp, linenr_T lnum, linenr_T lnume,
break;
}
p += len - 1;
- } else if (*p == TAB)
+ } else if (*p == TAB) {
*p = ' ';
- else if (ptr2cells(p) > 1)
+ } else if (ptr2cells(p) > 1) {
break;
+ }
}
if (*p != NUL) {
- p = (char_u *)transstr((const char *)text);
+ p = (char_u *)transstr((const char *)text, true);
xfree(text);
text = p;
}
@@ -1890,35 +1893,37 @@ char_u *get_foldtext(win_T *wp, linenr_T lnum, linenr_T lnume,
return text;
}
-/* foldtext_cleanup() {{{2 */
+// foldtext_cleanup() {{{2
/*
* Remove 'foldmarker' and 'commentstring' from "str" (in-place).
*/
void foldtext_cleanup(char_u *str)
{
- char_u *s;
- char_u *p;
- int did1 = FALSE;
- int did2 = FALSE;
+ char_u *s;
+ char_u *p;
+ bool did1 = false;
+ bool did2 = false;
- /* Ignore leading and trailing white space in 'commentstring'. */
+ // Ignore leading and trailing white space in 'commentstring'.
char_u *cms_start = skipwhite(curbuf->b_p_cms);
size_t cms_slen = STRLEN(cms_start);
- while (cms_slen > 0 && ascii_iswhite(cms_start[cms_slen - 1]))
+ while (cms_slen > 0 && ascii_iswhite(cms_start[cms_slen - 1])) {
--cms_slen;
+ }
- /* locate "%s" in 'commentstring', use the part before and after it. */
+ // locate "%s" in 'commentstring', use the part before and after it.
char_u *cms_end = (char_u *)strstr((char *)cms_start, "%s");
size_t cms_elen = 0;
if (cms_end != NULL) {
cms_elen = cms_slen - (size_t)(cms_end - cms_start);
cms_slen = (size_t)(cms_end - cms_start);
- /* exclude white space before "%s" */
- while (cms_slen > 0 && ascii_iswhite(cms_start[cms_slen - 1]))
+ // exclude white space before "%s"
+ while (cms_slen > 0 && ascii_iswhite(cms_start[cms_slen - 1])) {
--cms_slen;
+ }
- /* skip "%s" and white space after it */
+ // skip "%s" and white space after it
s = skipwhite(cms_end + 2);
cms_elen -= (size_t)(s - cms_end);
cms_end = s;
@@ -1927,18 +1932,21 @@ void foldtext_cleanup(char_u *str)
for (s = str; *s != NUL; ) {
size_t len = 0;
- if (STRNCMP(s, curwin->w_p_fmr, foldstartmarkerlen) == 0)
+ if (STRNCMP(s, curwin->w_p_fmr, foldstartmarkerlen) == 0) {
len = foldstartmarkerlen;
- else if (STRNCMP(s, foldendmarker, foldendmarkerlen) == 0)
+ } else if (STRNCMP(s, foldendmarker, foldendmarkerlen) == 0) {
len = foldendmarkerlen;
+ }
if (len > 0) {
- if (ascii_isdigit(s[len]))
+ if (ascii_isdigit(s[len])) {
++len;
+ }
/* May remove 'commentstring' start. Useful when it's a double
* quote and we already removed a double quote. */
- for (p = s; p > str && ascii_iswhite(p[-1]); --p)
+ for (p = s; p > str && ascii_iswhite(p[-1]); --p) {
;
+ }
if (p >= str + cms_slen
&& STRNCMP(p - cms_slen, cms_start, cms_slen) == 0) {
len += (size_t)(s - p) + cms_slen;
@@ -1947,16 +1955,17 @@ void foldtext_cleanup(char_u *str)
} else if (cms_end != NULL) {
if (!did1 && cms_slen > 0 && STRNCMP(s, cms_start, cms_slen) == 0) {
len = cms_slen;
- did1 = TRUE;
+ did1 = true;
} else if (!did2 && cms_elen > 0
&& STRNCMP(s, cms_end, cms_elen) == 0) {
len = cms_elen;
- did2 = TRUE;
+ did2 = true;
}
}
if (len != 0) {
- while (ascii_iswhite(s[len]))
+ while (ascii_iswhite(s[len])) {
++len;
+ }
STRMOVE(s, s + len);
} else {
MB_PTR_ADV(s);
@@ -1964,10 +1973,10 @@ void foldtext_cleanup(char_u *str)
}
}
-/* Folding by indent, expr, marker and syntax. {{{1 */
-/* Function declarations. {{{2 */
+// Folding by indent, expr, marker and syntax. {{{1
+// Function declarations. {{{2
-/* foldUpdateIEMS() {{{2 */
+// foldUpdateIEMS() {{{2
/*
* Update the folding for window "wp", at least from lines "top" to "bot".
* IEMS = "Indent Expr Marker Syntax"
@@ -1976,28 +1985,30 @@ static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot)
{
fline_T fline;
LevelGetter getlevel = NULL;
- fold_T *fp;
+ fold_T *fp;
- /* Avoid problems when being called recursively. */
- if (invalid_top != (linenr_T)0)
+ // Avoid problems when being called recursively.
+ if (invalid_top != (linenr_T)0) {
return;
+ }
if (wp->w_foldinvalid) {
- /* Need to update all folds. */
+ // Need to update all folds.
top = 1;
bot = wp->w_buffer->b_ml.ml_line_count;
wp->w_foldinvalid = false;
- /* Mark all folds a maybe-small. */
+ // Mark all folds a maybe-small.
setSmallMaybe(&wp->w_folds);
}
- /* add the context for "diff" folding */
+ // add the context for "diff" folding
if (foldmethodIsDiff(wp)) {
- if (top > diff_context)
+ if (top > diff_context) {
top -= diff_context;
- else
+ } else {
top = 1;
+ }
bot += diff_context;
}
@@ -2022,7 +2033,7 @@ static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot)
if (foldmethodIsMarker(wp)) {
getlevel = foldlevelMarker;
- /* Init marker variables to speed up foldlevelMarker(). */
+ // Init marker variables to speed up foldlevelMarker().
parseMarker(wp);
/* Need to get the level of the line above top, it is used if there is
@@ -2031,7 +2042,7 @@ static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot)
// Get the fold level at top - 1.
const int level = foldLevelWin(wp, top - 1);
- /* The fold may end just above the top, check for that. */
+ // The fold may end just above the top, check for that.
fline.lnum = top - 1;
fline.lvl = level;
getlevel(&fline);
@@ -2039,10 +2050,11 @@ static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot)
/* If a fold started here, we already had the level, if it stops
* here, we need to use lvl_next. Could also start and end a fold
* in the same line. */
- if (fline.lvl > level)
+ if (fline.lvl > level) {
fline.lvl = level - (fline.lvl - fline.lvl_next);
- else
+ } else {
fline.lvl = fline.lvl_next;
+ }
}
fline.lnum = top;
getlevel(&fline);
@@ -2052,14 +2064,16 @@ static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot)
getlevel = foldlevelExpr;
/* start one line back, because a "<1" may indicate the end of a
* fold in the topline */
- if (top > 1)
+ if (top > 1) {
--fline.lnum;
- } else if (foldmethodIsSyntax(wp))
+ }
+ } else if (foldmethodIsSyntax(wp)) {
getlevel = foldlevelSyntax;
- else if (foldmethodIsDiff(wp))
+ } else if (foldmethodIsDiff(wp)) {
getlevel = foldlevelDiff;
- else
+ } else {
getlevel = foldlevelIndent;
+ }
/* Backup to a line for which the fold level is defined. Since it's
* always defined for line one, we will stop there. */
@@ -2069,8 +2083,9 @@ static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot)
* the next line, but we search backwards here. */
fline.lvl_next = -1;
getlevel(&fline);
- if (fline.lvl >= 0)
+ if (fline.lvl >= 0) {
break;
+ }
}
}
@@ -2083,14 +2098,15 @@ static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot)
*/
if (foldlevelSyntax == getlevel) {
garray_T *gap = &wp->w_folds;
- fold_T *fpn = NULL;
+ fold_T *fpn = NULL;
int current_fdl = 0;
linenr_T fold_start_lnum = 0;
linenr_T lnum_rel = fline.lnum;
while (current_fdl < fline.lvl) {
- if (!foldFind(gap, lnum_rel, &fpn))
+ if (!foldFind(gap, lnum_rel, &fpn)) {
break;
+ }
++current_fdl;
fold_start_lnum += fpn->fd_top;
@@ -2100,8 +2116,9 @@ static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot)
if (fpn != NULL && current_fdl == fline.lvl) {
linenr_T fold_end_lnum = fold_start_lnum + fpn->fd_len;
- if (fold_end_lnum > bot)
+ if (fold_end_lnum > bot) {
bot = fold_end_lnum;
+ }
}
}
@@ -2114,34 +2131,37 @@ static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot)
while (!got_int) {
/* Always stop at the end of the file ("end" can be past the end of
* the file). */
- if (fline.lnum > wp->w_buffer->b_ml.ml_line_count)
+ if (fline.lnum > wp->w_buffer->b_ml.ml_line_count) {
break;
+ }
if (fline.lnum > end) {
/* For "marker", "expr" and "syntax" methods: If a change caused
* a fold to be removed, we need to continue at least until where
* it ended. */
if (getlevel != foldlevelMarker
&& getlevel != foldlevelSyntax
- && getlevel != foldlevelExpr)
+ && getlevel != foldlevelExpr) {
break;
+ }
if ((start <= end
&& foldFind(&wp->w_folds, end, &fp)
&& fp->fd_top + fp->fd_len - 1 > end)
|| (fline.lvl == 0
&& foldFind(&wp->w_folds, fline.lnum, &fp)
- && fp->fd_top < fline.lnum))
+ && fp->fd_top < fline.lnum)) {
end = fp->fd_top + fp->fd_len - 1;
- else if (getlevel == foldlevelSyntax
- && foldLevelWin(wp, fline.lnum) != fline.lvl)
+ } else if (getlevel == foldlevelSyntax
+ && foldLevelWin(wp, fline.lnum) != fline.lvl) {
/* For "syntax" method: Compare the foldlevel that the syntax
* tells us to the foldlevel from the existing folds. If they
* don't match continue updating folds. */
end = fline.lnum;
- else
+ } else {
break;
+ }
}
- /* A level 1 fold starts at a line with foldlevel > 0. */
+ // A level 1 fold starts at a line with foldlevel > 0.
if (fline.lvl > 0) {
invalid_top = fline.lnum;
invalid_bot = end;
@@ -2149,8 +2169,9 @@ static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot)
FD_LEVEL);
start = fline.lnum;
} else {
- if (fline.lnum == wp->w_buffer->b_ml.ml_line_count)
+ if (fline.lnum == wp->w_buffer->b_ml.ml_line_count) {
break;
+ }
++fline.lnum;
fline.lvl = fline.lvl_next;
getlevel(&fline);
@@ -2160,56 +2181,58 @@ static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot)
// There can't be any folds from start until end now.
foldRemove(wp, &wp->w_folds, start, end);
- /* If some fold changed, need to redraw and position cursor. */
- if (fold_changed && wp->w_p_fen)
+ // If some fold changed, need to redraw and position cursor.
+ if (fold_changed && wp->w_p_fen) {
changed_window_setting_win(wp);
+ }
/* If we updated folds past "bot", need to redraw more lines. Don't do
* this in other situations, the changed lines will be redrawn anyway and
* this method can cause the whole window to be updated. */
if (end != bot) {
- if (wp->w_redraw_top == 0 || wp->w_redraw_top > top)
+ if (wp->w_redraw_top == 0 || wp->w_redraw_top > top) {
wp->w_redraw_top = top;
- if (wp->w_redraw_bot < end)
+ }
+ if (wp->w_redraw_bot < end) {
wp->w_redraw_bot = end;
+ }
}
invalid_top = (linenr_T)0;
}
-/* foldUpdateIEMSRecurse() {{{2 */
-/*
- * Update a fold that starts at "flp->lnum". At this line there is always a
- * valid foldlevel, and its level >= "level".
- * "flp" is valid for "flp->lnum" when called and it's valid when returning.
- * "flp->lnum" is set to the lnum just below the fold, if it ends before
- * "bot", it's "bot" plus one if the fold continues and it's bigger when using
- * the marker method and a text change made following folds to change.
- * When returning, "flp->lnum_save" is the line number that was used to get
- * the level when the level at "flp->lnum" is invalid.
- * Remove any folds from "startlnum" up to here at this level.
- * Recursively update nested folds.
- * Below line "bot" there are no changes in the text.
- * "flp->lnum", "flp->lnum_save" and "bot" are relative to the start of the
- * outer fold.
- * "flp->off" is the offset to the real line number in the buffer.
- *
- * All this would be a lot simpler if all folds in the range would be deleted
- * and then created again. But we would lose all information about the
- * folds, even when making changes that don't affect the folding (e.g. "vj~").
- *
- * Returns bot, which may have been increased for lines that also need to be
- * updated as a result of a detected change in the fold.
- */
-static linenr_T foldUpdateIEMSRecurse(
- garray_T *const gap, const int level, const linenr_T startlnum,
- fline_T *const flp, LevelGetter getlevel, linenr_T bot,
- const char topflags // containing fold flags
-)
+// foldUpdateIEMSRecurse() {{{2
+/// Update a fold that starts at "flp->lnum". At this line there is always a
+/// valid foldlevel, and its level >= "level".
+///
+/// "flp" is valid for "flp->lnum" when called and it's valid when returning.
+/// "flp->lnum" is set to the lnum just below the fold, if it ends before
+/// "bot", it's "bot" plus one if the fold continues and it's bigger when using
+/// the marker method and a text change made following folds to change.
+/// When returning, "flp->lnum_save" is the line number that was used to get
+/// the level when the level at "flp->lnum" is invalid.
+/// Remove any folds from "startlnum" up to here at this level.
+/// Recursively update nested folds.
+/// Below line "bot" there are no changes in the text.
+/// "flp->lnum", "flp->lnum_save" and "bot" are relative to the start of the
+/// outer fold.
+/// "flp->off" is the offset to the real line number in the buffer.
+///
+/// All this would be a lot simpler if all folds in the range would be deleted
+/// and then created again. But we would lose all information about the
+/// folds, even when making changes that don't affect the folding (e.g. "vj~").
+///
+/// @param topflags containing fold flags
+///
+/// @return bot, which may have been increased for lines that also need to be
+/// updated as a result of a detected change in the fold.
+static linenr_T foldUpdateIEMSRecurse(garray_T *const gap, const int level,
+ const linenr_T startlnum, fline_T *const flp,
+ LevelGetter getlevel, linenr_T bot, const char topflags)
{
linenr_T ll;
- fold_T *fp = NULL;
- fold_T *fp2;
+ fold_T *fp = NULL;
+ fold_T *fp2;
int lvl = level;
linenr_T startlnum2 = startlnum;
const linenr_T firstlnum = flp->lnum; // first lnum we got
@@ -2247,7 +2270,7 @@ static linenr_T foldUpdateIEMSRecurse(
*/
flp->lnum_save = flp->lnum;
while (!got_int) {
- /* Updating folds can be slow, check for CTRL-C. */
+ // Updating folds can be slow, check for CTRL-C.
line_breakcheck();
/* Set "lvl" to the level of line "flp->lnum". When flp->start is set
@@ -2255,11 +2278,13 @@ static linenr_T foldUpdateIEMSRecurse(
* force the fold to end. Do the same when had_end is set: Previous
* line was marked as end of a fold. */
lvl = flp->lvl;
- if (lvl > MAX_LEVEL)
+ if (lvl > MAX_LEVEL) {
lvl = MAX_LEVEL;
+ }
if (flp->lnum > firstlnum
- && (level > lvl - flp->start || level >= flp->had_end))
+ && (level > lvl - flp->start || level >= flp->had_end)) {
lvl = 0;
+ }
if (flp->lnum > bot && !finish && fp != NULL) {
/* For "marker" and "syntax" methods:
@@ -2270,8 +2295,9 @@ static linenr_T foldUpdateIEMSRecurse(
*/
if (getlevel != foldlevelMarker
&& getlevel != foldlevelExpr
- && getlevel != foldlevelSyntax)
+ && getlevel != foldlevelSyntax) {
break;
+ }
i = 0;
fp2 = fp;
if (lvl >= level) {
@@ -2312,10 +2338,11 @@ static linenr_T foldUpdateIEMSRecurse(
while (!got_int) {
/* set concat to 1 if it's allowed to concatenated this fold
* with a previous one that touches it. */
- if (flp->start != 0 || flp->had_end <= MAX_LEVEL)
+ if (flp->start != 0 || flp->had_end <= MAX_LEVEL) {
concat = 0;
- else
+ } else {
concat = 1;
+ }
/* Find an existing fold to re-use. Preferably one that
* includes startlnum, otherwise one that ends just before
@@ -2342,14 +2369,14 @@ static linenr_T foldUpdateIEMSRecurse(
// nested folds (with relative line numbers) down.
foldMarkAdjustRecurse(flp->wp, &fp->fd_nested,
(linenr_T)0, (linenr_T)MAXLNUM,
- (long)(fp->fd_top - firstlnum), 0L);
+ (fp->fd_top - firstlnum), 0L);
} else {
// Will move fold down, move nested folds relatively up.
foldMarkAdjustRecurse(flp->wp, &fp->fd_nested,
(linenr_T)0,
- (long)(firstlnum - fp->fd_top - 1),
+ (firstlnum - fp->fd_top - 1),
(linenr_T)MAXLNUM,
- (long)(fp->fd_top - firstlnum));
+ (fp->fd_top - firstlnum));
}
fp->fd_len += fp->fd_top - firstlnum;
fp->fd_top = firstlnum;
@@ -2412,7 +2439,7 @@ static linenr_T foldUpdateIEMSRecurse(
* to stop just above startlnum. */
fp->fd_len = startlnum - fp->fd_top;
foldMarkAdjustRecurse(flp->wp, &fp->fd_nested,
- (linenr_T)fp->fd_len, (linenr_T)MAXLNUM,
+ fp->fd_len, (linenr_T)MAXLNUM,
(linenr_T)MAXLNUM, 0L);
fold_changed = true;
}
@@ -2438,10 +2465,12 @@ static linenr_T foldUpdateIEMSRecurse(
fp->fd_flags = FD_OPEN;
} else if (i <= 0) {
fp->fd_flags = topflags;
- if (topflags != FD_LEVEL)
+ if (topflags != FD_LEVEL) {
flp->wp->w_fold_manual = true;
- } else
+ }
+ } else {
fp->fd_flags = (fp - 1)->fd_flags;
+ }
fp->fd_small = kNone;
// If using the "marker", "expr" or "syntax" method, we
// need to continue until the end of the fold is found.
@@ -2490,7 +2519,7 @@ static linenr_T foldUpdateIEMSRecurse(
bot += fp->fd_top;
startlnum2 = flp->lnum;
- /* This fold may end at the same line, don't incr. flp->lnum. */
+ // This fold may end at the same line, don't incr. flp->lnum.
} else {
/*
* Get the level of the next line, then continue the loop to check
@@ -2501,20 +2530,23 @@ static linenr_T foldUpdateIEMSRecurse(
flp->lnum = flp->lnum_save;
ll = flp->lnum + 1;
while (!got_int) {
- /* Make the previous level available to foldlevel(). */
+ // Make the previous level available to foldlevel().
prev_lnum = flp->lnum;
prev_lnum_lvl = flp->lvl;
- if (++flp->lnum > linecount)
+ if (++flp->lnum > linecount) {
break;
+ }
flp->lvl = flp->lvl_next;
getlevel(flp);
- if (flp->lvl >= 0 || flp->had_end <= MAX_LEVEL)
+ if (flp->lvl >= 0 || flp->had_end <= MAX_LEVEL) {
break;
+ }
}
prev_lnum = 0;
- if (flp->lnum > linecount)
+ if (flp->lnum > linecount) {
break;
+ }
/* leave flp->lnum_save to lnum of the line that was used to get
* the level, flp->lnum to the lnum of the next line. */
@@ -2523,8 +2555,9 @@ static linenr_T foldUpdateIEMSRecurse(
}
}
- if (fp == NULL) /* only happens when got_int is set */
+ if (fp == NULL) { // only happens when got_int is set
return bot;
+ }
/*
* Get here when:
@@ -2573,18 +2606,19 @@ static linenr_T foldUpdateIEMSRecurse(
}
}
- /* delete following folds that end before the current line */
+ // delete following folds that end before the current line
for (;; ) {
fp2 = fp + 1;
if (fp2 >= (fold_T *)gap->ga_data + gap->ga_len
- || fp2->fd_top > flp->lnum)
+ || fp2->fd_top > flp->lnum) {
break;
+ }
if (fp2->fd_top + fp2->fd_len > flp->lnum) {
if (fp2->fd_top < flp->lnum) {
// Make fold that includes lnum start at lnum.
foldMarkAdjustRecurse(flp->wp, &fp2->fd_nested,
- (linenr_T)0, (long)(flp->lnum - fp2->fd_top - 1),
- (linenr_T)MAXLNUM, (long)(fp2->fd_top-flp->lnum));
+ (linenr_T)0, (flp->lnum - fp2->fd_top - 1),
+ (linenr_T)MAXLNUM, (fp2->fd_top-flp->lnum));
fp2->fd_len -= flp->lnum - fp2->fd_top;
fp2->fd_top = flp->lnum;
fold_changed = true;
@@ -2602,19 +2636,20 @@ static linenr_T foldUpdateIEMSRecurse(
/* Need to redraw the lines we inspected, which might be further down than
* was asked for. */
- if (bot < flp->lnum - 1)
+ if (bot < flp->lnum - 1) {
bot = flp->lnum - 1;
+ }
return bot;
}
-/* foldInsert() {{{2 */
+// foldInsert() {{{2
/*
* Insert a new fold in "gap" at position "i".
*/
static void foldInsert(garray_T *gap, int i)
{
- fold_T *fp;
+ fold_T *fp;
ga_grow(gap, 1);
@@ -2626,7 +2661,7 @@ static void foldInsert(garray_T *gap, int i)
ga_init(&fp->fd_nested, (int)sizeof(fold_T), 10);
}
-/* foldSplit() {{{2 */
+// foldSplit() {{{2
/*
* Split the "i"th fold in "gap", which starts before "top" and ends below
* "bot" in two pieces, one ending above "top" and the other starting below
@@ -2634,14 +2669,12 @@ static void foldInsert(garray_T *gap, int i)
* The caller must first have taken care of any nested folds from "top" to
* "bot"!
*/
-static void foldSplit(buf_T *buf, garray_T *const gap,
- const int i, const linenr_T top,
- const linenr_T bot
- )
+static void foldSplit(buf_T *buf, garray_T *const gap, const int i, const linenr_T top,
+ const linenr_T bot)
{
- fold_T *fp2;
+ fold_T *fp2;
- /* The fold continues below bot, need to split it. */
+ // The fold continues below bot, need to split it.
foldInsert(gap, i + 1);
fold_T *const fp = (fold_T *)gap->ga_data + i;
@@ -2674,7 +2707,7 @@ static void foldSplit(buf_T *buf, garray_T *const gap,
fold_changed = true;
}
-/* foldRemove() {{{2 */
+// foldRemove() {{{2
/*
* Remove folds within the range "top" to and including "bot".
* Check for these situations:
@@ -2693,11 +2726,9 @@ static void foldSplit(buf_T *buf, garray_T *const gap,
* 5: made to start below "bot".
* 6: not changed
*/
-static void foldRemove(
- win_T *const wp, garray_T *gap, linenr_T top, linenr_T bot
-)
+static void foldRemove(win_T *const wp, garray_T *gap, linenr_T top, linenr_T bot)
{
- fold_T *fp = NULL;
+ fold_T *fp = NULL;
if (bot < top) {
return; // nothing to do
@@ -2730,10 +2761,9 @@ static void foldRemove(
fold_changed = true;
if (fp->fd_top + fp->fd_len - 1 > bot) {
// 5: Make fold that includes bot start below bot.
- foldMarkAdjustRecurse(
- wp, &fp->fd_nested,
- (linenr_T)0, (long)(bot - fp->fd_top),
- (linenr_T)MAXLNUM, (long)(fp->fd_top - bot - 1));
+ foldMarkAdjustRecurse(wp, &fp->fd_nested,
+ (linenr_T)0, (bot - fp->fd_top),
+ (linenr_T)MAXLNUM, (fp->fd_top - bot - 1));
fp->fd_len -= bot - fp->fd_top + 1;
fp->fd_top = bot + 1;
break;
@@ -2746,10 +2776,7 @@ static void foldRemove(
}
// foldReverseOrder() {{{2
-static void foldReverseOrder(
- garray_T *gap,
- const linenr_T start_arg,
- const linenr_T end_arg)
+static void foldReverseOrder(garray_T *gap, const linenr_T start_arg, const linenr_T end_arg)
{
linenr_T start = start_arg;
linenr_T end = end_arg;
@@ -2804,11 +2831,8 @@ static void truncate_fold(win_T *const wp, fold_T *fp, linenr_T end)
#define VALID_FOLD(fp, gap) \
((gap)->ga_len > 0 && (fp) < ((fold_T *)(gap)->ga_data + (gap)->ga_len))
#define FOLD_INDEX(fp, gap) ((size_t)(fp - ((fold_T *)(gap)->ga_data)))
-void foldMoveRange(
- win_T *const wp, garray_T *gap,
- const linenr_T line1, const linenr_T line2,
- const linenr_T dest
-)
+void foldMoveRange(win_T *const wp, garray_T *gap, const linenr_T line1, const linenr_T line2,
+ const linenr_T dest)
{
fold_T *fp;
const linenr_T range_len = line2 - line1 + 1;
@@ -2908,7 +2932,7 @@ void foldMoveRange(
#undef VALID_FOLD
#undef FOLD_INDEX
-/* foldMerge() {{{2 */
+// foldMerge() {{{2
/*
* Merge two adjacent folds (and the nested ones in them).
* This only works correctly when the folds are really adjacent! Thus "fp1"
@@ -2918,11 +2942,11 @@ void foldMoveRange(
*/
static void foldMerge(win_T *const wp, fold_T *fp1, garray_T *gap, fold_T *fp2)
{
- fold_T *fp3;
- fold_T *fp4;
+ fold_T *fp3;
+ fold_T *fp4;
int idx;
- garray_T *gap1 = &fp1->fd_nested;
- garray_T *gap2 = &fp2->fd_nested;
+ garray_T *gap1 = &fp1->fd_nested;
+ garray_T *gap2 = &fp2->fd_nested;
/* If the last nested fold in fp1 touches the first nested fold in fp2,
* merge them recursively. */
@@ -2930,7 +2954,7 @@ static void foldMerge(win_T *const wp, fold_T *fp1, garray_T *gap, fold_T *fp2)
foldMerge(wp, fp3, gap2, fp4);
}
- /* Move nested folds in fp2 to the end of fp1. */
+ // Move nested folds in fp2 to the end of fp1.
if (!GA_EMPTY(gap2)) {
ga_grow(gap1, gap2->ga_len);
for (idx = 0; idx < gap2->ga_len; ++idx) {
@@ -2947,7 +2971,7 @@ static void foldMerge(win_T *const wp, fold_T *fp1, garray_T *gap, fold_T *fp2)
fold_changed = true;
}
-/* foldlevelIndent() {{{2 */
+// foldlevelIndent() {{{2
/*
* Low level function to get the foldlevel for the "indent" method.
* Doesn't use any caching.
@@ -2955,43 +2979,45 @@ static void foldMerge(win_T *const wp, fold_T *fp1, garray_T *gap, fold_T *fp2)
*/
static void foldlevelIndent(fline_T *flp)
{
- char_u *s;
- buf_T *buf;
+ char_u *s;
+ buf_T *buf;
linenr_T lnum = flp->lnum + flp->off;
buf = flp->wp->w_buffer;
- s = skipwhite(ml_get_buf(buf, lnum, FALSE));
+ s = skipwhite(ml_get_buf(buf, lnum, false));
/* empty line or lines starting with a character in 'foldignore': level
* depends on surrounding lines */
if (*s == NUL || vim_strchr(flp->wp->w_p_fdi, *s) != NULL) {
- /* first and last line can't be undefined, use level 0 */
- if (lnum == 1 || lnum == buf->b_ml.ml_line_count)
+ // first and last line can't be undefined, use level 0
+ if (lnum == 1 || lnum == buf->b_ml.ml_line_count) {
flp->lvl = 0;
- else
+ } else {
flp->lvl = -1;
+ }
} else {
flp->lvl = get_indent_buf(buf, lnum) / get_sw_value(buf);
}
if (flp->lvl > flp->wp->w_p_fdn) {
- flp->lvl = (int) MAX(0, flp->wp->w_p_fdn);
+ flp->lvl = (int)MAX(0, flp->wp->w_p_fdn);
}
}
-/* foldlevelDiff() {{{2 */
+// foldlevelDiff() {{{2
/*
* Low level function to get the foldlevel for the "diff" method.
* Doesn't use any caching.
*/
static void foldlevelDiff(fline_T *flp)
{
- if (diff_infold(flp->wp, flp->lnum + flp->off))
+ if (diff_infold(flp->wp, flp->lnum + flp->off)) {
flp->lvl = 1;
- else
+ } else {
flp->lvl = 0;
+ }
}
-/* foldlevelExpr() {{{2 */
+// foldlevelExpr() {{{2
/*
* Low level function to get the foldlevel for the "expr" method.
* Doesn't use any caching.
@@ -2999,20 +3025,21 @@ static void foldlevelDiff(fline_T *flp)
*/
static void foldlevelExpr(fline_T *flp)
{
- win_T *win;
+ win_T *win;
int c;
linenr_T lnum = flp->lnum + flp->off;
win = curwin;
curwin = flp->wp;
curbuf = flp->wp->w_buffer;
- set_vim_var_nr(VV_LNUM, (varnumber_T) lnum);
+ set_vim_var_nr(VV_LNUM, (varnumber_T)lnum);
flp->start = 0;
flp->had_end = flp->end;
flp->end = MAX_LEVEL + 1;
- if (lnum <= 1)
+ if (lnum <= 1) {
flp->lvl = 0;
+ }
/* KeyTyped may be reset to 0 when calling a function which invokes
* do_cmdline(). To make 'foldopen' work correctly restore KeyTyped. */
@@ -3021,46 +3048,54 @@ static void foldlevelExpr(fline_T *flp)
KeyTyped = save_keytyped;
switch (c) {
- /* "a1", "a2", .. : add to the fold level */
- case 'a': if (flp->lvl >= 0) {
+ // "a1", "a2", .. : add to the fold level
+ case 'a':
+ if (flp->lvl >= 0) {
flp->lvl += n;
flp->lvl_next = flp->lvl;
- }
+ }
flp->start = n;
break;
- /* "s1", "s2", .. : subtract from the fold level */
- case 's': if (flp->lvl >= 0) {
- if (n > flp->lvl)
+ // "s1", "s2", .. : subtract from the fold level
+ case 's':
+ if (flp->lvl >= 0) {
+ if (n > flp->lvl) {
flp->lvl_next = 0;
- else
+ } else {
flp->lvl_next = flp->lvl - n;
+ }
flp->end = flp->lvl_next + 1;
- }
+ }
break;
- /* ">1", ">2", .. : start a fold with a certain level */
- case '>': flp->lvl = n;
+ // ">1", ">2", .. : start a fold with a certain level
+ case '>':
+ flp->lvl = n;
flp->lvl_next = n;
flp->start = 1;
break;
- /* "<1", "<2", .. : end a fold with a certain level */
- case '<': flp->lvl_next = n - 1;
+ // "<1", "<2", .. : end a fold with a certain level
+ case '<':
+ flp->lvl_next = n - 1;
flp->end = n;
break;
- /* "=": No change in level */
- case '=': flp->lvl_next = flp->lvl;
+ // "=": No change in level
+ case '=':
+ flp->lvl_next = flp->lvl;
break;
- /* "-1", "0", "1", ..: set fold level */
- default: if (n < 0)
+ // "-1", "0", "1", ..: set fold level
+ default:
+ if (n < 0) {
/* Use the current level for the next line, so that "a1"
* will work there. */
flp->lvl_next = flp->lvl;
- else
+ } else {
flp->lvl_next = n;
+ }
flp->lvl = n;
break;
}
@@ -3072,15 +3107,16 @@ static void foldlevelExpr(fline_T *flp)
flp->lvl = 0;
flp->lvl_next = 0;
}
- if (lnum == curbuf->b_ml.ml_line_count)
+ if (lnum == curbuf->b_ml.ml_line_count) {
flp->lvl_next = 0;
+ }
}
curwin = win;
curbuf = curwin->w_buffer;
}
-/* parseMarker() {{{2 */
+// parseMarker() {{{2
/*
* Parse 'foldmarker' and set "foldendmarker", "foldstartmarkerlen" and
* "foldendmarkerlen".
@@ -3093,7 +3129,7 @@ static void parseMarker(win_T *wp)
foldendmarkerlen = STRLEN(foldendmarker);
}
-/* foldlevelMarker() {{{2 */
+// foldlevelMarker() {{{2
/*
* Low level function to get the foldlevel for the "marker" method.
* "foldendmarker", "foldstartmarkerlen" and "foldendmarkerlen" must have been
@@ -3105,38 +3141,39 @@ static void parseMarker(win_T *wp)
*/
static void foldlevelMarker(fline_T *flp)
{
- char_u *startmarker;
+ char_u *startmarker;
int cstart;
int cend;
int start_lvl = flp->lvl;
- char_u *s;
+ char_u *s;
int n;
- /* cache a few values for speed */
+ // cache a few values for speed
startmarker = flp->wp->w_p_fmr;
cstart = *startmarker;
++startmarker;
cend = *foldendmarker;
- /* Default: no start found, next level is same as current level */
+ // Default: no start found, next level is same as current level
flp->start = 0;
flp->lvl_next = flp->lvl;
- s = ml_get_buf(flp->wp->w_buffer, flp->lnum + flp->off, FALSE);
+ s = ml_get_buf(flp->wp->w_buffer, flp->lnum + flp->off, false);
while (*s) {
if (*s == cstart
&& STRNCMP(s + 1, startmarker, foldstartmarkerlen - 1) == 0) {
- /* found startmarker: set flp->lvl */
+ // found startmarker: set flp->lvl
s += foldstartmarkerlen;
if (ascii_isdigit(*s)) {
n = atoi((char *)s);
if (n > 0) {
flp->lvl = n;
flp->lvl_next = n;
- if (n <= start_lvl)
+ if (n <= start_lvl) {
flp->start = 1;
- else
+ } else {
flp->start = n - start_lvl;
+ }
}
} else {
++flp->lvl;
@@ -3145,16 +3182,17 @@ static void foldlevelMarker(fline_T *flp)
}
} else if (*s == cend && STRNCMP(s + 1, foldendmarker + 1,
foldendmarkerlen - 1) == 0) {
- /* found endmarker: set flp->lvl_next */
+ // found endmarker: set flp->lvl_next
s += foldendmarkerlen;
if (ascii_isdigit(*s)) {
n = atoi((char *)s);
if (n > 0) {
flp->lvl = n;
flp->lvl_next = n - 1;
- /* never start a fold with an end marker */
- if (flp->lvl_next > start_lvl)
+ // never start a fold with an end marker
+ if (flp->lvl_next > start_lvl) {
flp->lvl_next = start_lvl;
+ }
}
} else {
flp->lvl_next--;
@@ -3164,12 +3202,13 @@ static void foldlevelMarker(fline_T *flp)
}
}
- /* The level can't go negative, must be missing a start marker. */
- if (flp->lvl_next < 0)
+ // The level can't go negative, must be missing a start marker.
+ if (flp->lvl_next < 0) {
flp->lvl_next = 0;
+ }
}
-/* foldlevelSyntax() {{{2 */
+// foldlevelSyntax() {{{2
/*
* Low level function to get the foldlevel for the "syntax" method.
* Doesn't use any caching.
@@ -3179,20 +3218,20 @@ static void foldlevelSyntax(fline_T *flp)
linenr_T lnum = flp->lnum + flp->off;
int n;
- /* Use the maximum fold level at the start of this line and the next. */
+ // Use the maximum fold level at the start of this line and the next.
flp->lvl = syn_get_foldlevel(flp->wp, lnum);
flp->start = 0;
if (lnum < flp->wp->w_buffer->b_ml.ml_line_count) {
n = syn_get_foldlevel(flp->wp, lnum + 1);
if (n > flp->lvl) {
- flp->start = n - flp->lvl; /* fold(s) start here */
+ flp->start = n - flp->lvl; // fold(s) start here
flp->lvl = n;
}
}
}
-/* functions for storing the fold state in a View {{{1 */
-/* put_folds() {{{2 */
+// functions for storing the fold state in a View {{{1
+// put_folds() {{{2
/*
* Write commands to "fd" to restore the manual folds in window "wp".
@@ -3208,14 +3247,15 @@ int put_folds(FILE *fd, win_T *wp)
}
}
- /* If some folds are manually opened/closed, need to restore that. */
- if (wp->w_fold_manual)
+ // If some folds are manually opened/closed, need to restore that.
+ if (wp->w_fold_manual) {
return put_foldopen_recurse(fd, wp, &wp->w_folds, (linenr_T)0);
+ }
return OK;
}
-/* put_folds_recurse() {{{2 */
+// put_folds_recurse() {{{2
/*
* Write commands to "fd" to recreate manually created folds.
* Returns FAIL when writing failed.
@@ -3224,20 +3264,22 @@ static int put_folds_recurse(FILE *fd, garray_T *gap, linenr_T off)
{
fold_T *fp = (fold_T *)gap->ga_data;
for (int i = 0; i < gap->ga_len; i++) {
- /* Do nested folds first, they will be created closed. */
- if (put_folds_recurse(fd, &fp->fd_nested, off + fp->fd_top) == FAIL)
+ // Do nested folds first, they will be created closed.
+ if (put_folds_recurse(fd, &fp->fd_nested, off + fp->fd_top) == FAIL) {
return FAIL;
+ }
if (fprintf(fd, "%" PRId64 ",%" PRId64 "fold",
(int64_t)(fp->fd_top + off),
(int64_t)(fp->fd_top + off + fp->fd_len - 1)) < 0
- || put_eol(fd) == FAIL)
+ || put_eol(fd) == FAIL) {
return FAIL;
+ }
++fp;
}
return OK;
}
-/* put_foldopen_recurse() {{{2 */
+// put_foldopen_recurse() {{{2
/*
* Write commands to "fd" to open and close manually opened/closed folds.
* Returns FAIL when writing failed.
@@ -3250,19 +3292,22 @@ static int put_foldopen_recurse(FILE *fd, win_T *wp, garray_T *gap, linenr_T off
for (int i = 0; i < gap->ga_len; i++) {
if (fp->fd_flags != FD_LEVEL) {
if (!GA_EMPTY(&fp->fd_nested)) {
- /* open nested folds while this fold is open */
+ // open nested folds while this fold is open
if (fprintf(fd, "%" PRId64, (int64_t)(fp->fd_top + off)) < 0
|| put_eol(fd) == FAIL
- || put_line(fd, "normal! zo") == FAIL)
+ || put_line(fd, "normal! zo") == FAIL) {
return FAIL;
+ }
if (put_foldopen_recurse(fd, wp, &fp->fd_nested,
- off + fp->fd_top)
- == FAIL)
+ off + fp->fd_top)
+ == FAIL) {
return FAIL;
- /* close the parent when needed */
+ }
+ // close the parent when needed
if (fp->fd_flags == FD_CLOSED) {
- if (put_fold_open_close(fd, fp, off) == FAIL)
+ if (put_fold_open_close(fd, fp, off) == FAIL) {
return FAIL;
+ }
}
} else {
/* Open or close the leaf according to the window foldlevel.
@@ -3270,9 +3315,11 @@ static int put_foldopen_recurse(FILE *fd, win_T *wp, garray_T *gap, linenr_T off
* the parent. */
level = foldLevelWin(wp, off + fp->fd_top);
if ((fp->fd_flags == FD_CLOSED && wp->w_p_fdl >= level)
- || (fp->fd_flags != FD_CLOSED && wp->w_p_fdl < level))
- if (put_fold_open_close(fd, fp, off) == FAIL)
+ || (fp->fd_flags != FD_CLOSED && wp->w_p_fdl < level)) {
+ if (put_fold_open_close(fd, fp, off) == FAIL) {
return FAIL;
+ }
+ }
}
}
++fp;
@@ -3281,7 +3328,7 @@ static int put_foldopen_recurse(FILE *fd, win_T *wp, garray_T *gap, linenr_T off
return OK;
}
-/* put_fold_open_close() {{{2 */
+// put_fold_open_close() {{{2
/*
* Write the open or close command to "fd".
* Returns FAIL when writing failed.
@@ -3291,11 +3338,12 @@ static int put_fold_open_close(FILE *fd, fold_T *fp, linenr_T off)
if (fprintf(fd, "%" PRId64, (int64_t)(fp->fd_top + off)) < 0
|| put_eol(fd) == FAIL
|| fprintf(fd, "normal! z%c",
- fp->fd_flags == FD_CLOSED ? 'c' : 'o') < 0
- || put_eol(fd) == FAIL)
+ fp->fd_flags == FD_CLOSED ? 'c' : 'o') < 0
+ || put_eol(fd) == FAIL) {
return FAIL;
+ }
return OK;
}
-/* }}}1 */
+// }}}1
diff --git a/src/nvim/fold.h b/src/nvim/fold.h
index 95c4b0c1dc..37fab4da60 100644
--- a/src/nvim/fold.h
+++ b/src/nvim/fold.h
@@ -21,6 +21,8 @@ typedef struct foldinfo {
long fi_lines;
} foldinfo_T;
+#define FOLDINFO_INIT { 0, 0, 0, 0 }
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "fold.h.generated.h"
diff --git a/src/nvim/garray.c b/src/nvim/garray.c
index 1cfc2b6176..bc3b7211c9 100644
--- a/src/nvim/garray.c
+++ b/src/nvim/garray.c
@@ -5,16 +5,16 @@
///
/// Functions for handling growing arrays.
-#include <string.h>
#include <inttypes.h>
+#include <string.h>
-#include "nvim/vim.h"
#include "nvim/ascii.h"
+#include "nvim/garray.h"
#include "nvim/log.h"
#include "nvim/memory.h"
#include "nvim/path.h"
-#include "nvim/garray.h"
#include "nvim/strings.h"
+#include "nvim/vim.h"
// #include "nvim/globals.h"
#include "nvim/memline.h"
@@ -146,11 +146,11 @@ void ga_remove_duplicate_strings(garray_T *gap)
char_u *ga_concat_strings_sep(const garray_T *gap, const char *sep)
FUNC_ATTR_NONNULL_RET
{
- const size_t nelem = (size_t) gap->ga_len;
+ const size_t nelem = (size_t)gap->ga_len;
const char **strings = gap->ga_data;
if (nelem == 0) {
- return (char_u *) xstrdup("");
+ return (char_u *)xstrdup("");
}
size_t len = 0;
@@ -169,7 +169,7 @@ char_u *ga_concat_strings_sep(const garray_T *gap, const char *sep)
}
strcpy(s, strings[nelem - 1]);
- return (char_u *) ret;
+ return (char_u *)ret;
}
/// For a growing array that contains a list of strings: concatenate all the
@@ -178,7 +178,7 @@ char_u *ga_concat_strings_sep(const garray_T *gap, const char *sep)
/// @param gap
///
/// @returns the concatenated strings
-char_u* ga_concat_strings(const garray_T *gap) FUNC_ATTR_NONNULL_RET
+char_u *ga_concat_strings(const garray_T *gap) FUNC_ATTR_NONNULL_RET
{
return ga_concat_strings_sep(gap, ",");
}
@@ -198,7 +198,7 @@ void ga_concat(garray_T *gap, const char_u *restrict s)
return;
}
- ga_concat_len(gap, (const char *restrict) s, strlen((char *) s));
+ ga_concat_len(gap, (const char *restrict)s, strlen((char *)s));
}
/// Concatenate a string to a growarray which contains characters
@@ -206,15 +206,14 @@ void ga_concat(garray_T *gap, const char_u *restrict s)
/// @param[out] gap Growarray to modify.
/// @param[in] s String to concatenate.
/// @param[in] len String length.
-void ga_concat_len(garray_T *const gap, const char *restrict s,
- const size_t len)
+void ga_concat_len(garray_T *const gap, const char *restrict s, const size_t len)
FUNC_ATTR_NONNULL_ALL
{
if (len) {
- ga_grow(gap, (int) len);
+ ga_grow(gap, (int)len);
char *data = gap->ga_data;
memcpy(data + gap->ga_len, s, len);
- gap->ga_len += (int) len;
+ gap->ga_len += (int)len;
}
}
diff --git a/src/nvim/generators/gen_api_dispatch.lua b/src/nvim/generators/gen_api_dispatch.lua
index d2a7c16186..99d80cdebc 100644
--- a/src/nvim/generators/gen_api_dispatch.lua
+++ b/src/nvim/generators/gen_api_dispatch.lua
@@ -7,7 +7,7 @@ if arg[1] == '--help' then
print(' 2: dispatch output file (dispatch_wrappers.generated.h)')
print(' 3: functions metadata output file (funcs_metadata.generated.h)')
print(' 4: API metadata output file (api_metadata.mpack)')
- print(' 5: lua C bindings output file (msgpack_lua_c_bindings.generated.c)')
+ print(' 5: lua C bindings output file (lua_api_c_bindings.generated.c)')
print(' rest: C files where API functions are defined')
end
assert(#arg >= 4)
@@ -247,7 +247,7 @@ for i = 1, #functions do
(j - 1)..'].type == kObjectTypeInteger) {')
output:write('\n '..converted..' = (Float)args.items['..(j - 1)..'].data.integer;')
end
- -- accept empty lua tables as empty dictionarys
+ -- accept empty lua tables as empty dictionaries
if rt:match('^Dictionary') then
output:write('\n } else if (args.items['..(j - 1)..'].type == kObjectTypeArray && args.items['..(j - 1)..'].data.array.size == 0) {') --luacheck: ignore 631
output:write('\n '..converted..' = (Dictionary)ARRAY_DICT_INIT;')
@@ -321,8 +321,6 @@ end
output:write([[
void msgpack_rpc_init_method_table(void)
{
- methods = map_new(String, MsgpackRpcRequestHandler)();
-
]])
for i = 1, #functions do
@@ -380,7 +378,7 @@ output:write('\n')
local lua_c_functions = {}
local function process_function(fn)
- local lua_c_function_name = ('nlua_msgpack_%s'):format(fn.name)
+ local lua_c_function_name = ('nlua_api_%s'):format(fn.name)
write_shifted_output(output, string.format([[
static int %s(lua_State *lstate)
diff --git a/src/nvim/generators/gen_eval.lua b/src/nvim/generators/gen_eval.lua
index 679895421a..945fa5099f 100644
--- a/src/nvim/generators/gen_eval.lua
+++ b/src/nvim/generators/gen_eval.lua
@@ -42,7 +42,7 @@ gperfpipe:write([[
%language=ANSI-C
%global-table
%readonly-tables
-%define initializer-suffix ,0,0,NULL,NULL
+%define initializer-suffix ,0,0,BASE_NONE,NULL,NULL
%define word-array-name functions
%define hash-function-name hash_internal_func_gperf
%define lookup-function-name find_internal_func_gperf
@@ -59,9 +59,10 @@ for name, def in pairs(funcs) do
elseif #args == 1 then
args[2] = 'MAX_FUNC_ARGS'
end
+ local base = def.base or "BASE_NONE"
local func = def.func or ('f_' .. name)
local data = def.data or "NULL"
- gperfpipe:write(('%s, %s, %s, &%s, (FunPtr)%s\n')
- :format(name, args[1], args[2], func, data))
+ gperfpipe:write(('%s, %s, %s, %s, &%s, (FunPtr)%s\n')
+ :format(name, args[1], args[2], base, func, data))
end
gperfpipe:close()
diff --git a/src/nvim/generators/gen_options.lua b/src/nvim/generators/gen_options.lua
index d80a6219eb..0454c54faf 100644
--- a/src/nvim/generators/gen_options.lua
+++ b/src/nvim/generators/gen_options.lua
@@ -69,8 +69,6 @@ local get_flags = function(o)
{'alloced'},
{'nodefault'},
{'no_mkrc'},
- {'vi_def'},
- {'vim'},
{'secure'},
{'gettext'},
{'noglob'},
@@ -120,8 +118,11 @@ local get_value = function(v)
return '(char_u *) ' .. value_dumpers[type(v)](v)
end
-local get_defaults = function(d)
- return ('{' .. get_value(d.vi) .. ', ' .. get_value(d.vim) .. '}')
+local get_defaults = function(d,n)
+ if d == nil then
+ error("option '"..n.."' should have a default value")
+ end
+ return get_value(d)
end
local defines = {}
@@ -170,11 +171,11 @@ local dump_option = function(i, o)
if o.defaults.condition then
w(get_cond(o.defaults.condition))
end
- w(' .def_val=' .. get_defaults(o.defaults.if_true))
+ w(' .def_val=' .. get_defaults(o.defaults.if_true, o.full_name))
if o.defaults.condition then
if o.defaults.if_false then
w('#else')
- w(' .def_val=' .. get_defaults(o.defaults.if_false))
+ w(' .def_val=' .. get_defaults(o.defaults.if_false, o.full_name))
end
w('#endif')
end
diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c
index 5c2eed363e..beb4ff4da6 100644
--- a/src/nvim/getchar.c
+++ b/src/nvim/getchar.c
@@ -11,22 +11,25 @@
*/
#include <assert.h>
+#include <inttypes.h>
#include <stdbool.h>
#include <string.h>
-#include <inttypes.h>
-#include "nvim/assert.h"
-#include "nvim/vim.h"
#include "nvim/ascii.h"
-#include "nvim/getchar.h"
+#include "nvim/assert.h"
#include "nvim/buffer_defs.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
#include "nvim/edit.h"
#include "nvim/eval.h"
+#include "nvim/event/loop.h"
#include "nvim/ex_docmd.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/keymap.h"
#include "nvim/lua/executor.h"
#include "nvim/main.h"
#include "nvim/mbyte.h"
@@ -34,24 +37,21 @@
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/keymap.h"
-#include "nvim/garray.h"
#include "nvim/move.h"
#include "nvim/normal.h"
#include "nvim/ops.h"
#include "nvim/option.h"
+#include "nvim/os/fileio.h"
+#include "nvim/os/input.h"
+#include "nvim/os/os.h"
+#include "nvim/plines.h"
#include "nvim/regexp.h"
#include "nvim/screen.h"
-#include "nvim/ex_session.h"
#include "nvim/state.h"
#include "nvim/strings.h"
#include "nvim/ui.h"
#include "nvim/undo.h"
-#include "nvim/event/loop.h"
-#include "nvim/os/input.h"
-#include "nvim/os/os.h"
-#include "nvim/os/fileio.h"
-#include "nvim/api/private/handle.h"
+#include "nvim/vim.h"
/// Index in scriptin
@@ -163,7 +163,7 @@ static size_t last_recorded_len = 0; // number of last recorded chars
*/
void free_buff(buffheader_T *buf)
{
- buffblock_T *p, *np;
+ buffblock_T *p, *np;
for (p = buf->bh_first.b_next; p != NULL; p = np) {
np = p->b_next;
@@ -172,17 +172,15 @@ void free_buff(buffheader_T *buf)
buf->bh_first.b_next = NULL;
}
-/*
- * Return the contents of a buffer as a single string.
- * K_SPECIAL and CSI in the returned string are escaped.
- */
-static char_u *get_buffcont(buffheader_T *buffer,
- int dozero // count == zero is not an error
- )
+/// Return the contents of a buffer as a single string.
+/// K_SPECIAL and CSI in the returned string are escaped.
+///
+/// @param dozero count == zero is not an error
+static char_u *get_buffcont(buffheader_T *buffer, int dozero)
{
size_t count = 0;
- char_u *p = NULL;
- char_u *p2;
+ char_u *p = NULL;
+ char_u *p2;
// compute the total length of the string
for (const buffblock_T *bp = buffer->bh_first.b_next;
@@ -211,7 +209,7 @@ static char_u *get_buffcont(buffheader_T *buffer,
*/
char_u *get_recorded(void)
{
- char_u *p;
+ char_u *p;
size_t len;
p = get_buffcont(&recordbuff, TRUE);
@@ -231,8 +229,9 @@ char_u *get_recorded(void)
* When stopping recording from Insert mode with CTRL-O q, also remove the
* CTRL-O.
*/
- if (len > 0 && restart_edit != 0 && p[len - 1] == Ctrl_O)
+ if (len > 0 && restart_edit != 0 && p[len - 1] == Ctrl_O) {
p[len - 1] = NUL;
+ }
return p;
}
@@ -253,8 +252,7 @@ char_u *get_inserted(void)
/// @param[out] buf Buffer to add to.
/// @param[in] s String to add.
/// @param[in] slen String length or -1 for NUL-terminated string.
-static void add_buff(buffheader_T *const buf, const char *const s,
- ptrdiff_t slen)
+static void add_buff(buffheader_T *const buf, const char *const s, ptrdiff_t slen)
{
if (slen < 0) {
slen = (ptrdiff_t)strlen(s);
@@ -354,8 +352,9 @@ static int read_readbuffers(int advance)
int c;
c = read_readbuf(&readbuf1, advance);
- if (c == NUL)
+ if (c == NUL) {
c = read_readbuf(&readbuf2, advance);
+ }
return c;
}
@@ -583,8 +582,9 @@ void AppendToRedobuffLit(const char_u *str, int len)
*/
void AppendCharToRedobuff(int c)
{
- if (!block_redo)
+ if (!block_redo) {
add_char_buff(&redobuff, c);
+ }
}
/*
@@ -592,8 +592,9 @@ void AppendCharToRedobuff(int c)
*/
void AppendNumberToRedobuff(long n)
{
- if (!block_redo)
+ if (!block_redo) {
add_num_buff(&redobuff, n);
+ }
}
/*
@@ -840,6 +841,14 @@ static void init_typebuf(void)
}
}
+void init_default_mappings(void)
+{
+ add_map((char_u *)"Y y$", NORMAL, true);
+ add_map((char_u *)"<C-L> <Cmd>nohlsearch<Bar>diffupdate<CR><C-L>", NORMAL, true);
+ add_map((char_u *)"<C-U> <C-G>u<C-U>", INSERT, true);
+ add_map((char_u *)"<C-W> <C-G>u<C-W>", INSERT, true);
+}
+
// Insert a string in position 'offset' in the typeahead buffer (for "@r"
// and ":normal" command, vgetorpeek() and check_termcode())
//
@@ -857,10 +866,9 @@ static void init_typebuf(void)
// If silent is true, cmd_silent is set when the characters are obtained.
//
// return FAIL for failure, OK otherwise
-int ins_typebuf(char_u *str, int noremap, int offset,
- bool nottyped, bool silent)
+int ins_typebuf(char_u *str, int noremap, int offset, bool nottyped, bool silent)
{
- char_u *s1, *s2;
+ char_u *s1, *s2;
int newlen;
int addlen;
int i;
@@ -869,8 +877,9 @@ int ins_typebuf(char_u *str, int noremap, int offset,
int nrm;
init_typebuf();
- if (++typebuf.tb_change_cnt == 0)
+ if (++typebuf.tb_change_cnt == 0) {
typebuf.tb_change_cnt = 1;
+ }
addlen = (int)STRLEN(str);
@@ -916,12 +925,13 @@ int ins_typebuf(char_u *str, int noremap, int offset,
typebuf.tb_buf = s1;
memmove(s2 + newoff, typebuf.tb_noremap + typebuf.tb_off,
- (size_t)offset);
+ (size_t)offset);
memmove(s2 + newoff + offset + addlen,
- typebuf.tb_noremap + typebuf.tb_off + offset,
- (size_t)(typebuf.tb_len - offset));
- if (typebuf.tb_noremap != noremapbuf_init)
+ typebuf.tb_noremap + typebuf.tb_off + offset,
+ (size_t)(typebuf.tb_len - offset));
+ if (typebuf.tb_noremap != noremapbuf_init) {
xfree(typebuf.tb_noremap);
+ }
typebuf.tb_noremap = s2;
typebuf.tb_off = newoff;
@@ -940,26 +950,29 @@ int ins_typebuf(char_u *str, int noremap, int offset,
/*
* Adjust typebuf.tb_noremap[] for the new characters:
* If noremap == REMAP_NONE or REMAP_SCRIPT: new characters are
- * (sometimes) not remappable
+ * (sometimes) not remappable
* If noremap == REMAP_YES: all the new characters are mappable
* If noremap > 0: "noremap" characters are not remappable, the rest
- * mappable
+ * mappable
*/
- if (noremap == REMAP_SKIP)
+ if (noremap == REMAP_SKIP) {
nrm = 1;
- else if (noremap < 0)
+ } else if (noremap < 0) {
nrm = addlen;
- else
+ } else {
nrm = noremap;
- for (i = 0; i < addlen; ++i)
+ }
+ for (i = 0; i < addlen; ++i) {
typebuf.tb_noremap[typebuf.tb_off + i + offset] =
- (char_u)((--nrm >= 0) ? val : RM_YES);
+ (char_u)((--nrm >= 0) ? val : RM_YES);
+ }
/* tb_maplen and tb_silent only remember the length of mapped and/or
* silent mappings at the start of the buffer, assuming that a mapped
* sequence doesn't result in typed characters. */
- if (nottyped || typebuf.tb_maplen > offset)
+ if (nottyped || typebuf.tb_maplen > offset) {
typebuf.tb_maplen += addlen;
+ }
if (silent || typebuf.tb_silent > offset) {
typebuf.tb_silent += addlen;
cmd_silent = true;
@@ -991,18 +1004,16 @@ void ins_char_typebuf(int c)
(void)ins_typebuf(buf, KeyNoremap, 0, !KeyTyped, cmd_silent);
}
-/*
- * Return TRUE if the typeahead buffer was changed (while waiting for a
- * character to arrive). Happens when a message was received from a client or
- * from feedkeys().
- * But check in a more generic way to avoid trouble: When "typebuf.tb_buf"
- * changed it was reallocated and the old pointer can no longer be used.
- * Or "typebuf.tb_off" may have been changed and we would overwrite characters
- * that was just added.
- */
-bool typebuf_changed(
- int tb_change_cnt // old value of typebuf.tb_change_cnt
-)
+/// Return TRUE if the typeahead buffer was changed (while waiting for a
+/// character to arrive). Happens when a message was received from a client or
+/// from feedkeys().
+/// But check in a more generic way to avoid trouble: When "typebuf.tb_buf"
+/// changed it was reallocated and the old pointer can no longer be used.
+/// Or "typebuf.tb_off" may have been changed and we would overwrite characters
+/// that was just added.
+///
+/// @param tb_change_cnt old value of typebuf.tb_change_cnt
+bool typebuf_changed(int tb_change_cnt)
{
return tb_change_cnt != 0 && (typebuf.tb_change_cnt != tb_change_cnt
|| typebuf_was_filled
@@ -1043,8 +1054,9 @@ void del_typebuf(int len, int offset)
* Easy case: Just increase typebuf.tb_off.
*/
if (offset == 0 && typebuf.tb_buflen - (typebuf.tb_off + len)
- >= 3 * MAXMAPLEN + 3)
+ >= 3 * MAXMAPLEN + 3) {
typebuf.tb_off += len;
+ }
/*
* Have to move the characters in typebuf.tb_buf[] and typebuf.tb_noremap[]
*/
@@ -1055,9 +1067,9 @@ void del_typebuf(int len, int offset)
*/
if (typebuf.tb_off > MAXMAPLEN) {
memmove(typebuf.tb_buf + MAXMAPLEN,
- typebuf.tb_buf + typebuf.tb_off, (size_t)offset);
+ typebuf.tb_buf + typebuf.tb_off, (size_t)offset);
memmove(typebuf.tb_noremap + MAXMAPLEN,
- typebuf.tb_noremap + typebuf.tb_off, (size_t)offset);
+ typebuf.tb_noremap + typebuf.tb_off, (size_t)offset);
typebuf.tb_off = MAXMAPLEN;
}
// adjust typebuf.tb_buf (include the NUL at the end)
@@ -1067,8 +1079,8 @@ void del_typebuf(int len, int offset)
typebuf.tb_buf + i + len, (size_t)bytes);
// adjust typebuf.tb_noremap[]
memmove(typebuf.tb_noremap + typebuf.tb_off + offset,
- typebuf.tb_noremap + i + len,
- (size_t)(typebuf.tb_len - offset));
+ typebuf.tb_noremap + i + len,
+ (size_t)(typebuf.tb_len - offset));
}
if (typebuf.tb_maplen > offset) { // adjust tb_maplen
@@ -1160,8 +1172,9 @@ static void gotchars(const char_u *chars, size_t len)
void may_sync_undo(void)
{
if ((!(State & (INSERT + CMDLINE)) || arrow_used)
- && scriptin[curscript] == NULL)
- u_sync(FALSE);
+ && scriptin[curscript] == NULL) {
+ u_sync(false);
+ }
}
/*
@@ -1177,8 +1190,9 @@ void alloc_typebuf(void)
typebuf.tb_maplen = 0;
typebuf.tb_silent = 0;
typebuf.tb_no_abbr_cnt = 0;
- if (++typebuf.tb_change_cnt == 0)
+ if (++typebuf.tb_change_cnt == 0) {
typebuf.tb_change_cnt = 1;
+ }
}
/*
@@ -1256,13 +1270,10 @@ void restore_typeahead(tasave_T *tp)
readbuf2 = tp->save_readbuf2;
}
-/*
- * Open a new script file for the ":source!" command.
- */
-void openscript(
- char_u *name,
- bool directly // when true execute directly
-)
+/// Open a new script file for the ":source!" command.
+///
+/// @param directly when true execute directly
+void openscript(char_u *name, bool directly)
{
if (curscript + 1 == NSCRIPT) {
EMSG(_(e_nesting));
@@ -1343,15 +1354,17 @@ static void closescript(void)
file_free(scriptin[curscript], false);
scriptin[curscript] = NULL;
- if (curscript > 0)
+ if (curscript > 0) {
--curscript;
+ }
}
#if defined(EXITFREE)
void close_all_scripts(void)
{
- while (scriptin[0] != NULL)
+ while (scriptin[0] != NULL) {
closescript();
+ }
}
#endif
@@ -1452,60 +1465,81 @@ int vgetc(void)
continue;
}
c = TO_SPECIAL(c2, c);
-
}
// a keypad or special function key was not mapped, use it like
// its ASCII equivalent
switch (c) {
- case K_KPLUS: c = '+'; break;
- case K_KMINUS: c = '-'; break;
- case K_KDIVIDE: c = '/'; break;
- case K_KMULTIPLY: c = '*'; break;
- case K_KENTER: c = CAR; break;
- case K_KPOINT: c = '.'; break;
- case K_KCOMMA: c = ','; break;
- case K_KEQUAL: c = '='; break;
- case K_K0: c = '0'; break;
- case K_K1: c = '1'; break;
- case K_K2: c = '2'; break;
- case K_K3: c = '3'; break;
- case K_K4: c = '4'; break;
- case K_K5: c = '5'; break;
- case K_K6: c = '6'; break;
- case K_K7: c = '7'; break;
- case K_K8: c = '8'; break;
- case K_K9: c = '9'; break;
-
- case K_XHOME:
- case K_ZHOME:
- if (mod_mask == MOD_MASK_SHIFT) {
- c = K_S_HOME;
- mod_mask = 0;
- } else if (mod_mask == MOD_MASK_CTRL) {
- c = K_C_HOME;
- mod_mask = 0;
- } else {
- c = K_HOME;
- }
- break;
- case K_XEND:
- case K_ZEND:
- if (mod_mask == MOD_MASK_SHIFT) {
- c = K_S_END;
- mod_mask = 0;
- } else if (mod_mask == MOD_MASK_CTRL) {
- c = K_C_END;
- mod_mask = 0;
- } else {
- c = K_END;
- }
- break;
+ case K_KPLUS:
+ c = '+'; break;
+ case K_KMINUS:
+ c = '-'; break;
+ case K_KDIVIDE:
+ c = '/'; break;
+ case K_KMULTIPLY:
+ c = '*'; break;
+ case K_KENTER:
+ c = CAR; break;
+ case K_KPOINT:
+ c = '.'; break;
+ case K_KCOMMA:
+ c = ','; break;
+ case K_KEQUAL:
+ c = '='; break;
+ case K_K0:
+ c = '0'; break;
+ case K_K1:
+ c = '1'; break;
+ case K_K2:
+ c = '2'; break;
+ case K_K3:
+ c = '3'; break;
+ case K_K4:
+ c = '4'; break;
+ case K_K5:
+ c = '5'; break;
+ case K_K6:
+ c = '6'; break;
+ case K_K7:
+ c = '7'; break;
+ case K_K8:
+ c = '8'; break;
+ case K_K9:
+ c = '9'; break;
+
+ case K_XHOME:
+ case K_ZHOME:
+ if (mod_mask == MOD_MASK_SHIFT) {
+ c = K_S_HOME;
+ mod_mask = 0;
+ } else if (mod_mask == MOD_MASK_CTRL) {
+ c = K_C_HOME;
+ mod_mask = 0;
+ } else {
+ c = K_HOME;
+ }
+ break;
+ case K_XEND:
+ case K_ZEND:
+ if (mod_mask == MOD_MASK_SHIFT) {
+ c = K_S_END;
+ mod_mask = 0;
+ } else if (mod_mask == MOD_MASK_CTRL) {
+ c = K_C_END;
+ mod_mask = 0;
+ } else {
+ c = K_END;
+ }
+ break;
- case K_XUP: c = K_UP; break;
- case K_XDOWN: c = K_DOWN; break;
- case K_XLEFT: c = K_LEFT; break;
- case K_XRIGHT: c = K_RIGHT; break;
+ case K_XUP:
+ c = K_UP; break;
+ case K_XDOWN:
+ c = K_DOWN; break;
+ case K_XLEFT:
+ c = K_LEFT; break;
+ case K_XRIGHT:
+ c = K_RIGHT; break;
}
// For a multi-byte character get all the bytes and return the
@@ -1555,8 +1589,8 @@ int vgetc(void)
*/
may_garbage_collect = false;
- // Exec lua callbacks for on_keystroke
- nlua_execute_log_keystroke(c);
+ // Execute Lua on_key callbacks.
+ nlua_execute_on_key(c);
return c;
}
@@ -1600,8 +1634,9 @@ int plain_vgetc(void)
*/
int vpeekc(void)
{
- if (old_char != -1)
+ if (old_char != -1) {
return old_char;
+ }
return vgetorpeek(false);
}
@@ -1615,8 +1650,9 @@ int vpeekc_any(void)
int c;
c = vpeekc();
- if (c == NUL && typebuf.tb_len > 0)
+ if (c == NUL && typebuf.tb_len > 0) {
c = ESC;
+ }
return c;
}
@@ -1670,10 +1706,10 @@ static int vgetorpeek(bool advance)
{
int c, c1;
int keylen;
- char_u *s;
- mapblock_T *mp;
- mapblock_T *mp2;
- mapblock_T *mp_match;
+ char_u *s;
+ mapblock_T *mp;
+ mapblock_T *mp2;
+ mapblock_T *mp_match;
int mp_match_len = 0;
bool timedout = false; // waited for more than 1 second
// for mapping to complete
@@ -1692,7 +1728,7 @@ static int vgetorpeek(bool advance)
/*
* This function doesn't work very well when called recursively. This may
* happen though, because of:
- * 1. The call to add_to_showcmd(). char_avail() is then used to check if
+ * 1. The call to add_to_showcmd(). char_avail() is then used to check if
* there is a character available, which calls this function. In that
* case we must return NUL, to indicate no character is available.
* 2. A GUI callback function writes to the screen, causing a
@@ -1701,16 +1737,17 @@ static int vgetorpeek(bool advance)
* thus it should be OK. But don't get a key from the user then.
*/
if (vgetc_busy > 0
- && ex_normal_busy == 0
- )
+ && ex_normal_busy == 0) {
return NUL;
+ }
local_State = get_real_state();
++vgetc_busy;
- if (advance)
+ if (advance) {
KeyStuffed = FALSE;
+ }
init_typebuf();
start_stuff();
@@ -1723,8 +1760,9 @@ static int vgetorpeek(bool advance)
*/
if (typeahead_char != 0) {
c = typeahead_char;
- if (advance)
+ if (advance) {
typeahead_char = 0;
+ }
} else {
c = read_readbuffers(advance);
}
@@ -1794,7 +1832,7 @@ static int vgetorpeek(bool advance)
* - typebuf.tb_buf[typebuf.tb_off] should not be remapped
* - in insert or cmdline mode and 'paste' option set
* - waiting for "hit return to continue" and CR or SPACE
- * typed
+ * typed
* - waiting for a char with --more--
* - in Ctrl-X mode, and we get a valid char for that mode
*/
@@ -1813,8 +1851,8 @@ static int vgetorpeek(bool advance)
&& State != CONFIRM
&& !((ctrl_x_mode_not_default() && vim_is_ctrl_x_key(c1))
|| ((compl_cont_status & CONT_LOCAL)
- && (c1 == Ctrl_N || c1 == Ctrl_P)))
- ) {
+ && (c1 == Ctrl_N ||
+ c1 == Ctrl_P)))) {
if (c1 == K_SPECIAL) {
nolmaplen = 2;
} else {
@@ -1856,14 +1894,16 @@ static int vgetorpeek(bool advance)
// find the match length of this mapping
for (mlen = 1; mlen < typebuf.tb_len; mlen++) {
c2 = typebuf.tb_buf[typebuf.tb_off + mlen];
- if (nomap > 0)
+ if (nomap > 0) {
--nomap;
- else if (c2 == K_SPECIAL)
+ } else if (c2 == K_SPECIAL) {
nomap = 2;
- else
+ } else {
LANGMAP_ADJUST(c2, TRUE);
- if (mp->m_keys[mlen] != c2)
+ }
+ if (mp->m_keys[mlen] != c2) {
break;
+ }
}
/* Don't allow mapping the first byte(s) of a
@@ -1894,17 +1934,21 @@ static int vgetorpeek(bool advance)
&& (mp->m_keys[0] != K_SPECIAL
|| mp->m_keys[1] != KS_EXTRA
|| mp->m_keys[2]
- != (int)KE_SNR))
+ != (int)KE_SNR)) {
continue;
+ }
/*
* If one of the typed keys cannot be
* remapped, skip the entry.
*/
- for (n = mlen; --n >= 0; )
- if (*s++ & (RM_NONE|RM_ABBR))
+ for (n = mlen; --n >= 0; ) {
+ if (*s++ & (RM_NONE|RM_ABBR)) {
break;
- if (n >= 0)
+ }
+ }
+ if (n >= 0) {
continue;
+ }
if (keylen > typebuf.tb_len) {
if (!timedout && !(mp_match != NULL
@@ -2022,10 +2066,11 @@ static int vgetorpeek(bool advance)
*/
if (++mapdepth >= p_mmd) {
EMSG(_("E223: recursive mapping"));
- if (State & CMDLINE)
+ if (State & CMDLINE) {
redrawcmdline();
- else
+ } else {
setcursor();
+ }
flush_buffers(FLUSH_MINIMAL);
mapdepth = 0; // for next one
c = -1;
@@ -2082,9 +2127,9 @@ static int vgetorpeek(bool advance)
* If m_noremap is set, don't remap the whole 'to'
* part.
*/
- if (s == NULL)
+ if (s == NULL) {
i = FAIL;
- else {
+ } else {
int noremap;
// If this is a LANGMAP mapping, then we didn't record the keys
@@ -2093,20 +2138,22 @@ static int vgetorpeek(bool advance)
gotchars(s, STRLEN(s));
}
- if (save_m_noremap != REMAP_YES)
+ if (save_m_noremap != REMAP_YES) {
noremap = save_m_noremap;
- else if (
- STRNCMP(s, save_m_keys != NULL
+ } else if (
+ STRNCMP(s, save_m_keys != NULL
? save_m_keys : mp->m_keys,
- (size_t)keylen)
- != 0)
+ (size_t)keylen)
+ != 0) {
noremap = REMAP_YES;
- else
+ } else {
noremap = REMAP_SKIP;
+ }
i = ins_typebuf(s, noremap,
- 0, TRUE, cmd_silent || save_m_silent);
- if (save_m_expr)
+ 0, TRUE, cmd_silent || save_m_silent);
+ if (save_m_expr) {
xfree(s);
+ }
}
xfree(save_m_keys);
xfree(save_m_str);
@@ -2144,7 +2191,7 @@ static int vgetorpeek(bool advance)
&& (c = inchar(typebuf.tb_buf + typebuf.tb_off + typebuf.tb_len,
3, 25L)) == 0) {
colnr_T col = 0, vcol;
- char_u *ptr;
+ char_u *ptr;
if (mode_displayed) {
unshowmode(true);
@@ -2230,20 +2277,22 @@ static int vgetorpeek(bool advance)
timedout = true;
continue;
}
- /* When 'insertmode' is set, ESC just beeps in Insert
- * mode. Use CTRL-L to make edit() return.
- * For the command line only CTRL-C always breaks it.
- * For the cmdline window: Alternate between ESC and
- * CTRL-C: ESC for most situations and CTRL-C to close the
- * cmdline window. */
- if (p_im && (State & INSERT))
+ // When 'insertmode' is set, ESC just beeps in Insert
+ // mode. Use CTRL-L to make edit() return.
+ // In Ex-mode \n is compatible with original Vim behaviour.
+ // For the command line only CTRL-C always breaks it.
+ // For the cmdline window: Alternate between ESC and
+ // CTRL-C: ESC for most situations and CTRL-C to close the
+ // cmdline window.
+ if (p_im && (State & INSERT)) {
c = Ctrl_L;
- else if ((State & CMDLINE)
- || (cmdwin_type > 0 && tc == ESC)
- )
+ } else if (exmode_active) {
+ c = '\n';
+ } else if ((State & CMDLINE) || (cmdwin_type > 0 && tc == ESC)) {
c = Ctrl_C;
- else
+ } else {
c = ESC;
+ }
tc = c;
break;
}
@@ -2289,11 +2338,13 @@ static int vgetorpeek(bool advance)
curwin->w_wcol = new_wcol;
curwin->w_wrow = new_wrow;
push_showcmd();
- if (typebuf.tb_len > SHOWCMD_COLS)
+ if (typebuf.tb_len > SHOWCMD_COLS) {
i = typebuf.tb_len - SHOWCMD_COLS;
- while (i < typebuf.tb_len)
+ }
+ while (i < typebuf.tb_len) {
(void)add_to_showcmd(typebuf.tb_buf[typebuf.tb_off
+ i++]);
+ }
curwin->w_wcol = old_wcol;
curwin->w_wrow = old_wrow;
}
@@ -2336,8 +2387,9 @@ static int vgetorpeek(bool advance)
typebuf.tb_buflen - typebuf.tb_off - typebuf.tb_len - 1,
wait_time);
- if (i != 0)
+ if (i != 0) {
pop_showcmd();
+ }
if (c1 == 1) {
if (State & INSERT) {
edit_unputchar();
@@ -2373,8 +2425,8 @@ static int vgetorpeek(bool advance)
/*
* The "INSERT" message is taken care of here:
- * if we return an ESC to exit insert mode, the message is deleted
- * if we don't return an ESC but deleted the message before, redisplay it
+ * if we return an ESC to exit insert mode, the message is deleted
+ * if we don't return an ESC but deleted the message before, redisplay it
*/
if (advance && p_smd && msg_silent == 0 && (State & INSERT)) {
if (c == ESC && !mode_deleted && !no_mapping && mode_displayed) {
@@ -2408,34 +2460,30 @@ static int vgetorpeek(bool advance)
return c;
}
-/*
- * inchar() - get one character from
- * 1. a scriptfile
- * 2. the keyboard
- *
- * As much characters as we can get (upto 'maxlen') are put in "buf" and
- * NUL terminated (buffer length must be 'maxlen' + 1).
- * Minimum for "maxlen" is 3!!!!
- *
- * "tb_change_cnt" is the value of typebuf.tb_change_cnt if "buf" points into
- * it. When typebuf.tb_change_cnt changes (e.g., when a message is received
- * from a remote client) "buf" can no longer be used. "tb_change_cnt" is 0
- * otherwise.
- *
- * If we got an interrupt all input is read until none is available.
- *
- * If wait_time == 0 there is no waiting for the char.
- * If wait_time == n we wait for n msec for a character to arrive.
- * If wait_time == -1 we wait forever for a character to arrive.
- *
- * Return the number of obtained characters.
- * Return -1 when end of input script reached.
- */
-int inchar(
- char_u *buf,
- int maxlen,
- long wait_time // milli seconds
-)
+/// inchar() - get one character from
+/// 1. a scriptfile
+/// 2. the keyboard
+///
+/// As much characters as we can get (up to 'maxlen') are put in "buf" and
+/// NUL terminated (buffer length must be 'maxlen' + 1).
+/// Minimum for "maxlen" is 3!!!!
+///
+/// "tb_change_cnt" is the value of typebuf.tb_change_cnt if "buf" points into
+/// it. When typebuf.tb_change_cnt changes (e.g., when a message is received
+/// from a remote client) "buf" can no longer be used. "tb_change_cnt" is 0
+/// otherwise.
+///
+/// If we got an interrupt all input is read until none is available.
+///
+/// If wait_time == 0 there is no waiting for the char.
+/// If wait_time == n we wait for n msec for a character to arrive.
+/// If wait_time == -1 we wait forever for a character to arrive.
+///
+/// Return the number of obtained characters.
+/// Return -1 when end of input script reached.
+///
+/// @param wait_time milli seconds
+int inchar(char_u *buf, int maxlen, long wait_time)
{
int len = 0; // Init for GCC.
int retesc = false; // Return ESC with gotint.
@@ -2541,10 +2589,10 @@ int fix_input_buffer(char_u *buf, int len)
// Reading from script, need to process special bytes
int i;
- char_u *p = buf;
+ char_u *p = buf;
// Two characters are special: NUL and K_SPECIAL.
- // Replace NUL by K_SPECIAL KS_ZERO KE_FILLER
+ // Replace NUL by K_SPECIAL KS_ZERO KE_FILLER
// Replace K_SPECIAL by K_SPECIAL KS_SPECIAL KE_FILLER
// Replace CSI by K_SPECIAL KS_EXTRA KE_CSI
for (i = len; --i >= 0; ++p) {
@@ -2585,9 +2633,8 @@ int fix_input_buffer(char_u *buf, int len)
/// @param[in] orig_rhs_len `strlen` of orig_rhs.
/// @param[in] cpo_flags See param docs for @ref replace_termcodes.
/// @param[out] mapargs MapArguments struct holding the replaced strings.
-void set_maparg_lhs_rhs(const char_u *orig_lhs, const size_t orig_lhs_len,
- const char_u *orig_rhs, const size_t orig_rhs_len,
- int cpo_flags, MapArguments *mapargs)
+void set_maparg_lhs_rhs(const char_u *orig_lhs, const size_t orig_lhs_len, const char_u *orig_rhs,
+ const size_t orig_rhs_len, int cpo_flags, MapArguments *mapargs)
{
char_u *lhs_buf = NULL;
char_u *rhs_buf = NULL;
@@ -2754,11 +2801,10 @@ int str_to_mapargs(const char_u *strargs, bool is_unmap, MapArguments *mapargs)
/// @param mode @see do_map
/// @param is_abbrev @see do_map
/// @param buf Target Buffer
-int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev,
- buf_T *buf)
+int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev, buf_T *buf)
{
- mapblock_T *mp, **mpp;
- char_u *p;
+ mapblock_T *mp, **mpp;
+ char_u *p;
int n;
int len = 0; // init for GCC
int did_it = false;
@@ -2767,8 +2813,8 @@ int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev,
int retval = 0;
int hash;
int new_hash;
- mapblock_T **abbr_table;
- mapblock_T **map_table;
+ mapblock_T **abbr_table;
+ mapblock_T **map_table;
int noremap;
map_table = maphash;
@@ -3138,15 +3184,15 @@ int do_map(int maptype, char_u *arg, int mode, bool is_abbrev)
MapArguments parsed_args;
int result = str_to_mapargs(arg, maptype == 1, &parsed_args);
switch (result) {
- case 0:
- break;
- case 1:
- // invalid arguments
- goto free_and_return;
- default:
- assert(false && "Unknown return code from str_to_mapargs!");
- result = -1;
- goto free_and_return;
+ case 0:
+ break;
+ case 1:
+ // invalid arguments
+ goto free_and_return;
+ default:
+ assert(false && "Unknown return code from str_to_mapargs!");
+ result = -1;
+ goto free_and_return;
} // switch
result = buf_do_map(maptype, &parsed_args, mode, is_abbrev, curbuf);
@@ -3163,7 +3209,7 @@ free_and_return:
*/
static void mapblock_free(mapblock_T **mpp)
{
- mapblock_T *mp;
+ mapblock_T *mp;
mp = *mpp;
xfree(mp->m_keys);
@@ -3189,7 +3235,7 @@ static void validate_maphash(void)
*/
int get_map_mode(char_u **cmdp, bool forceit)
{
- char_u *p;
+ char_u *p;
int modec;
int mode;
@@ -3243,21 +3289,19 @@ void map_clear_mode(char_u *cmdp, char_u *arg, int forceit, int abbr)
mode = get_map_mode(&cmdp, forceit);
map_clear_int(curbuf, mode,
- local,
- abbr);
+ local,
+ abbr);
}
-/*
- * Clear all mappings in "mode".
- */
-void map_clear_int(
- buf_T *buf, // buffer for local mappings
- int mode, // mode in which to delete
- bool local, // true for buffer-local mappings
- bool abbr // true for abbreviations
-)
+/// Clear all mappings in "mode".
+///
+/// @param buf, buffer for local mappings
+/// @param mode mode in which to delete
+/// @param local true for buffer-local mappings
+/// @param abbr true for abbreviations
+void map_clear_int(buf_T *buf, int mode, bool local, bool abbr)
{
- mapblock_T *mp, **mpp;
+ mapblock_T *mp, **mpp;
int hash;
int new_hash;
@@ -3274,10 +3318,11 @@ void map_clear_int(
mpp = &first_abbr;
}
} else {
- if (local)
+ if (local) {
mpp = &buf->b_maphash[hash];
- else
+ } else {
mpp = &maphash[hash];
+ }
}
while (*mpp != NULL) {
mp = *mpp;
@@ -3355,10 +3400,8 @@ char *map_mode_to_chars(int mode)
return (char *)mapmode.ga_data;
}
-static void showmap(
- mapblock_T *mp,
- bool local // true for buffer-local map
-)
+/// @param local true for buffer-local map
+static void showmap(mapblock_T *mp, bool local)
{
size_t len = 1;
@@ -3380,8 +3423,9 @@ static void showmap(
xfree(mapchars);
}
- while (++len <= 3)
+ while (++len <= 3) {
msg_putchar(' ');
+ }
// Display the LHS. Get length of what we write.
len = (size_t)msg_outtrans_special(mp->m_keys, true, 0);
@@ -3398,10 +3442,11 @@ static void showmap(
msg_putchar(' ');
}
- if (local)
+ if (local) {
msg_putchar('@');
- else
+ } else {
msg_putchar(' ');
+ }
/* Use FALSE below if we only want things like <Up> to show up as such on
* the rhs, and not M-x etc, TRUE gets both -- webb */
@@ -3431,8 +3476,7 @@ static void showmap(
/// @param[in] abbr true if checking abbreviations in place of mappings.
///
/// @return true if there is at least one mapping with given parameters.
-bool map_to_exists(const char *const str, const char *const modechars,
- const bool abbr)
+bool map_to_exists(const char *const str, const char *const modechars, const bool abbr)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE
{
int mode = 0;
@@ -3477,7 +3521,7 @@ bool map_to_exists(const char *const str, const char *const modechars,
/// @return true if there is at least one mapping with given parameters.
int map_to_exists_mode(const char *const rhs, const int mode, const bool abbr)
{
- mapblock_T *mp;
+ mapblock_T *mp;
int hash;
bool exp_buffer = false;
@@ -3523,29 +3567,25 @@ static int expand_mapmodes = 0;
static bool expand_isabbrev = false;
static bool expand_buffer = false;
-/*
- * Work out what to complete when doing command line completion of mapping
- * or abbreviation names.
- */
-char_u *set_context_in_map_cmd(
- expand_T *xp,
- char_u *cmd,
- char_u *arg,
- bool forceit, // true if '!' given
- bool isabbrev, // true if abbreviation
- bool isunmap, // true if unmap/unabbrev command
- cmdidx_T cmdidx
-)
+/// Work out what to complete when doing command line completion of mapping
+/// or abbreviation names.
+///
+/// @param forceit true if '!' given
+/// @param isabbrev true if abbreviation
+/// @param isunmap true if unmap/unabbrev command
+char_u *set_context_in_map_cmd(expand_T *xp, char_u *cmd, char_u *arg, bool forceit, bool isabbrev,
+ bool isunmap, cmdidx_T cmdidx)
{
- if (forceit && cmdidx != CMD_map && cmdidx != CMD_unmap)
+ if (forceit && cmdidx != CMD_map && cmdidx != CMD_unmap) {
xp->xp_context = EXPAND_NOTHING;
- else {
- if (isunmap)
+ } else {
+ if (isunmap) {
expand_mapmodes = get_map_mode(&cmd, forceit || isabbrev);
- else {
+ } else {
expand_mapmodes = INSERT + CMDLINE;
- if (!isabbrev)
+ if (!isabbrev) {
expand_mapmodes += VISUAL + SELECTMODE + NORMAL + OP_PENDING;
+ }
}
expand_isabbrev = isabbrev;
xp->xp_context = EXPAND_MAPPINGS;
@@ -3593,11 +3633,11 @@ char_u *set_context_in_map_cmd(
// Return OK if matches found, FAIL otherwise.
int ExpandMappings(regmatch_T *regmatch, int *num_file, char_u ***file)
{
- mapblock_T *mp;
+ mapblock_T *mp;
int hash;
int count;
int round;
- char_u *p;
+ char_u *p;
int i;
validate_maphash();
@@ -3632,10 +3672,11 @@ int ExpandMappings(regmatch_T *regmatch, int *num_file, char_u ***file)
}
if (vim_regexec(regmatch, p, (colnr_T)0)) {
- if (round == 1)
+ if (round == 1) {
++count;
- else
+ } else {
(*file)[count++] = vim_strsave(p);
+ }
}
}
@@ -3645,17 +3686,18 @@ int ExpandMappings(regmatch_T *regmatch, int *num_file, char_u ***file)
break; // for (hash)
}
mp = first_abbr;
- } else if (expand_buffer)
+ } else if (expand_buffer) {
mp = curbuf->b_maphash[hash];
- else
+ } else {
mp = maphash[hash];
+ }
for (; mp; mp = mp->m_next) {
if (mp->m_mode & expand_mapmodes) {
p = translate_mapping(mp->m_keys, CPO_TO_CPO_FLAGS);
if (p != NULL && vim_regexec(regmatch, p, (colnr_T)0)) {
- if (round == 1)
+ if (round == 1) {
++count;
- else {
+ } else {
(*file)[count++] = p;
p = NULL;
}
@@ -3675,9 +3717,9 @@ int ExpandMappings(regmatch_T *regmatch, int *num_file, char_u ***file)
} // for (round)
if (count > 1) {
- char_u **ptr1;
- char_u **ptr2;
- char_u **ptr3;
+ char_u **ptr1;
+ char_u **ptr2;
+ char_u **ptr3;
// Sort the matches
sort_strings(*file, count);
@@ -3688,9 +3730,9 @@ int ExpandMappings(regmatch_T *regmatch, int *num_file, char_u ***file)
ptr3 = ptr1 + count;
while (ptr2 < ptr3) {
- if (STRCMP(*ptr1, *ptr2))
+ if (STRCMP(*ptr1, *ptr2)) {
*++ptr1 = *ptr2++;
- else {
+ } else {
xfree(*ptr2++);
count--;
}
@@ -3722,10 +3764,10 @@ bool check_abbr(int c, char_u *ptr, int col, int mincol)
int len;
int scol; // starting column of the abbr.
int j;
- char_u *s;
+ char_u *s;
char_u tb[MB_MAXBYTES + 4];
- mapblock_T *mp;
- mapblock_T *mp2;
+ mapblock_T *mp;
+ mapblock_T *mp2;
int clen = 0; // length in characters
bool is_id = true;
@@ -3769,8 +3811,9 @@ bool check_abbr(int c, char_u *ptr, int col, int mincol)
scol = (int)(p - ptr);
}
- if (scol < mincol)
+ if (scol < mincol) {
scol = mincol;
+ }
if (scol < col) { // there is a word in front of the cursor
ptr += scol;
len = col - scol;
@@ -3848,17 +3891,19 @@ bool check_abbr(int c, char_u *ptr, int col, int mincol)
// insert the last typed char
(void)ins_typebuf(tb, 1, 0, true, mp->m_silent);
}
- if (mp->m_expr)
+ if (mp->m_expr) {
s = eval_map_expr(mp->m_str, c);
- else
+ } else {
s = mp->m_str;
+ }
if (s != NULL) {
// insert the to string
(void)ins_typebuf(s, mp->m_noremap, 0, true, mp->m_silent);
// no abbrev. for these chars
typebuf.tb_no_abbr_cnt += (int)STRLEN(s) + j + 1;
- if (mp->m_expr)
+ if (mp->m_expr) {
xfree(s);
+ }
}
tb[0] = Ctrl_H;
@@ -3873,20 +3918,16 @@ bool check_abbr(int c, char_u *ptr, int col, int mincol)
return false;
}
-/*
- * Evaluate the RHS of a mapping or abbreviations and take care of escaping
- * special characters.
- */
-static char_u *
-eval_map_expr (
- char_u *str,
- int c // NUL or typed character for abbreviation
-)
+/// Evaluate the RHS of a mapping or abbreviations and take care of escaping
+/// special characters.
+///
+/// @param c NUL or typed character for abbreviation
+static char_u *eval_map_expr(char_u *str, int c)
{
- char_u *res;
- char_u *p;
- char_u *expr;
- char_u *save_cmd;
+ char_u *res;
+ char_u *p;
+ char_u *expr;
+ char_u *save_cmd;
pos_T save_cursor;
int save_msg_col;
int save_msg_row;
@@ -3906,9 +3947,9 @@ eval_map_expr (
save_cursor = curwin->w_cursor;
save_msg_col = msg_col;
save_msg_row = msg_row;
- p = eval_to_string(expr, NULL, FALSE);
- --textlock;
- --ex_normal_lock;
+ p = eval_to_string(expr, NULL, false);
+ textlock--;
+ ex_normal_lock--;
curwin->w_cursor = save_cursor;
msg_col = save_msg_col;
msg_row = save_msg_row;
@@ -3916,8 +3957,9 @@ eval_map_expr (
restore_cmdline_alloc(save_cmd);
xfree(expr);
- if (p == NULL)
+ if (p == NULL) {
return NULL;
+ }
// Escape CSI in the result to be able to use the string as typeahead.
res = vim_strsave_escape_csi(p);
xfree(p);
@@ -3960,7 +4002,7 @@ char_u *vim_strsave_escape_csi(char_u *p)
*/
void vim_unescape_csi(char_u *p)
{
- char_u *s = p, *d = p;
+ char_u *s = p, *d = p;
while (*s != NUL) {
if (s[0] == K_SPECIAL && s[1] == KS_SPECIAL && s[2] == KE_FILLER) {
@@ -3970,26 +4012,23 @@ void vim_unescape_csi(char_u *p)
&& s[1] == KS_EXTRA && s[2] == (int)KE_CSI) {
*d++ = CSI;
s += 3;
- } else
+ } else {
*d++ = *s++;
+ }
}
*d = NUL;
}
-/*
- * Write map commands for the current mappings to an .exrc file.
- * Return FAIL on error, OK otherwise.
- */
-int
-makemap(
- FILE *fd,
- buf_T *buf // buffer for local mappings or NULL
-)
+/// Write map commands for the current mappings to an .exrc file.
+/// Return FAIL on error, OK otherwise.
+///
+/// @param buf buffer for local mappings or NULL
+int makemap(FILE *fd, buf_T *buf)
{
- mapblock_T *mp;
+ mapblock_T *mp;
char_u c1, c2, c3;
- char_u *p;
- char *cmd;
+ char_u *p;
+ char *cmd;
int abbr;
int hash;
bool did_cpo = false;
@@ -4199,13 +4238,14 @@ makemap(
// return FAIL for failure, OK otherwise
int put_escstr(FILE *fd, char_u *strstart, int what)
{
- char_u *str = strstart;
+ char_u *str = strstart;
int c;
// :map xx <Nop>
if (*str == NUL && what == 1) {
- if (fprintf(fd, "<Nop>") < 0)
+ if (fprintf(fd, "<Nop>") < 0) {
return FAIL;
+ }
return OK;
}
@@ -4214,9 +4254,11 @@ int put_escstr(FILE *fd, char_u *strstart, int what)
// K_SPECIAL and CSI bytes.
const char *p = mb_unescape((const char **)&str);
if (p != NULL) {
- while (*p != NUL)
- if (fputc(*p++, fd) < 0)
+ while (*p != NUL) {
+ if (fputc(*p++, fd) < 0) {
return FAIL;
+ }
+ }
--str;
continue;
}
@@ -4251,11 +4293,13 @@ int put_escstr(FILE *fd, char_u *strstart, int what)
*/
if (c == NL) {
if (what == 2) {
- if (fprintf(fd, "\\\026\n") < 0)
+ if (fprintf(fd, "\\\026\n") < 0) {
return FAIL;
+ }
} else {
- if (fprintf(fd, "<NL>") < 0)
+ if (fprintf(fd, "<NL>") < 0) {
return FAIL;
+ }
}
continue;
}
@@ -4272,39 +4316,38 @@ int put_escstr(FILE *fd, char_u *strstart, int what)
* A space in the lhs of a :map needs a CTRL-V.
*/
if (what == 2 && (ascii_iswhite(c) || c == '"' || c == '\\')) {
- if (putc('\\', fd) < 0)
+ if (putc('\\', fd) < 0) {
return FAIL;
+ }
} else if (c < ' ' || c > '~' || c == '|'
|| (what == 0 && c == ' ')
|| (what == 1 && str == strstart && c == ' ')
|| (what != 2 && c == '<')) {
- if (putc(Ctrl_V, fd) < 0)
+ if (putc(Ctrl_V, fd) < 0) {
return FAIL;
+ }
}
- if (putc(c, fd) < 0)
+ if (putc(c, fd) < 0) {
return FAIL;
+ }
}
return OK;
}
-/*
- * Check the string "keys" against the lhs of all mappings.
- * Return pointer to rhs of mapping (mapblock->m_str).
- * NULL when no mapping found.
- */
-char_u *
-check_map (
- char_u *keys,
- int mode,
- int exact, // require exact match
- int ign_mod, // ignore preceding modifier
- int abbr, // do abbreviations
- mapblock_T **mp_ptr, // return: pointer to mapblock or NULL
- int *local_ptr // return: buffer-local mapping or NULL
-)
+/// Check the string "keys" against the lhs of all mappings.
+/// Return pointer to rhs of mapping (mapblock->m_str).
+/// NULL when no mapping found.
+///
+/// @param exact require exact match
+/// @param ign_mod ignore preceding modifier
+/// @param abbr do abbreviations
+/// @param mp_ptr return: pointer to mapblock or NULL
+/// @param local_ptr return: buffer-local mapping or NULL
+char_u *check_map(char_u *keys, int mode, int exact, int ign_mod, int abbr, mapblock_T **mp_ptr,
+ int *local_ptr)
{
int len, minlen;
- mapblock_T *mp;
+ mapblock_T *mp;
validate_maphash();
@@ -4339,10 +4382,12 @@ check_map (
}
minlen = keylen < len ? keylen : len;
if (STRNCMP(s, keys, minlen) == 0) {
- if (mp_ptr != NULL)
+ if (mp_ptr != NULL) {
*mp_ptr = mp;
- if (local_ptr != NULL)
+ }
+ if (local_ptr != NULL) {
*local_ptr = local;
+ }
return mp->m_str;
}
}
@@ -4354,37 +4399,41 @@ check_map (
}
-/*
- * Add a mapping "map" for mode "mode".
- * Need to put string in allocated memory, because do_map() will modify it.
- */
-void add_map(char_u *map, int mode)
+/// Add a mapping. Unlike @ref do_map this copies the {map} argument, so
+/// static or read-only strings can be used.
+///
+/// @param map C-string containing the arguments of the map/abbrev command,
+/// i.e. everything except the initial `:[X][nore]map`.
+/// @param mode Bitflags representing the mode in which to set the mapping.
+/// See @ref get_map_mode.
+/// @param nore If true, make a non-recursive mapping.
+void add_map(char_u *map, int mode, bool nore)
{
- char_u *s;
- char_u *cpo_save = p_cpo;
+ char_u *s;
+ char_u *cpo_save = p_cpo;
p_cpo = (char_u *)""; // Allow <> notation
+ // Need to put string in allocated memory, because do_map() will modify it.
s = vim_strsave(map);
- (void)do_map(0, s, mode, FALSE);
+ (void)do_map(nore ? 2 : 0, s, mode, false);
xfree(s);
p_cpo = cpo_save;
}
-// Translate an internal mapping/abbreviation representation into the
-// corresponding external one recognized by :map/:abbrev commands.
-//
-// This function is called when expanding mappings/abbreviations on the
-// command-line.
-//
-// It uses a growarray to build the translation string since the latter can be
-// wider than the original description. The caller has to free the string
-// afterwards.
-//
-// Returns NULL when there is a problem.
-static char_u * translate_mapping (
- char_u *str,
- int cpo_flags // Value of various flags present in &cpo
-)
+/// Translate an internal mapping/abbreviation representation into the
+/// corresponding external one recognized by :map/:abbrev commands.
+///
+/// This function is called when expanding mappings/abbreviations on the
+/// command-line.
+///
+/// It uses a growarray to build the translation string since the latter can be
+/// wider than the original description. The caller has to free the string
+/// afterwards.
+///
+/// @param cpo_flags Value of various flags present in &cpo
+///
+/// @return NULL when there is a problem.
+static char_u *translate_mapping(char_u *str, int cpo_flags)
{
garray_T ga;
ga_init(&ga, 1, 40);
@@ -4432,8 +4481,9 @@ static bool typebuf_match_len(const uint8_t *str, int *mlen)
{
int i;
for (i = 0; i < typebuf.tb_len && str[i]; i++) {
- if (str[i] != typebuf.tb_buf[typebuf.tb_off + i])
+ if (str[i] != typebuf.tb_buf[typebuf.tb_off + i]) {
break;
+ }
}
*mlen = i;
return str[i] == NUL; // matched the whole string
@@ -4454,7 +4504,7 @@ mapblock_T *get_maphash(int index, buf_T *buf)
}
/// Get command argument for <Cmd> key
-char_u * getcmdkeycmd(int promptc, void *cookie, int indent, bool do_concat)
+char_u *getcmdkeycmd(int promptc, void *cookie, int indent, bool do_concat)
{
garray_T line_ga;
int c1 = -1, c2;
diff --git a/src/nvim/globals.h b/src/nvim/globals.h
index 7c7ce5e65f..4d54907a75 100644
--- a/src/nvim/globals.h
+++ b/src/nvim/globals.h
@@ -138,14 +138,14 @@ EXTERN int mod_mask INIT(= 0x0); // current key modifiers
// update_screen().
EXTERN int cmdline_row;
-EXTERN int redraw_cmdline INIT(= false); // cmdline must be redrawn
-EXTERN int clear_cmdline INIT(= false); // cmdline must be cleared
-EXTERN int mode_displayed INIT(= false); // mode is being displayed
-EXTERN int cmdline_star INIT(= false); // cmdline is crypted
-EXTERN int redrawing_cmdline INIT(= false); // cmdline is being redrawn
-EXTERN int cmdline_was_last_drawn INIT(= false); // cmdline was last drawn
+EXTERN bool redraw_cmdline INIT(= false); // cmdline must be redrawn
+EXTERN bool clear_cmdline INIT(= false); // cmdline must be cleared
+EXTERN bool mode_displayed INIT(= false); // mode is being displayed
+EXTERN int cmdline_star INIT(= false); // cmdline is encrypted
+EXTERN bool redrawing_cmdline INIT(= false); // cmdline is being redrawn
+EXTERN bool cmdline_was_last_drawn INIT(= false); // cmdline was last drawn
-EXTERN int exec_from_reg INIT(= false); // executing register
+EXTERN bool exec_from_reg INIT(= false); // executing register
// When '$' is included in 'cpoptions' option set:
// When a change command is given that deletes only part of a line, a dollar
@@ -165,7 +165,7 @@ EXTERN int compl_interrupted INIT(= false);
// Set when doing something for completion that may call edit() recursively,
// which is not allowed. Also used to disable folding during completion
-EXTERN int compl_busy INIT(= false);
+EXTERN bool compl_busy INIT(= false);
// List of flags for method of completion.
EXTERN int compl_cont_status INIT(= 0);
@@ -201,23 +201,23 @@ EXTERN bool msg_did_scroll INIT(= false);
EXTERN char_u *keep_msg INIT(= NULL); // msg to be shown after redraw
EXTERN int keep_msg_attr INIT(= 0); // highlight attr for keep_msg
-EXTERN int keep_msg_more INIT(= false); // keep_msg was set by msgmore()
-EXTERN int need_fileinfo INIT(= false); // do fileinfo() after redraw
+EXTERN bool keep_msg_more INIT(= false); // keep_msg was set by msgmore()
+EXTERN bool need_fileinfo INIT(= false); // do fileinfo() after redraw
EXTERN int msg_scroll INIT(= false); // msg_start() will scroll
-EXTERN int msg_didout INIT(= false); // msg_outstr() was used in line
-EXTERN int msg_didany INIT(= false); // msg_outstr() was used at all
-EXTERN int msg_nowait INIT(= false); // don't wait for this msg
+EXTERN bool msg_didout INIT(= false); // msg_outstr() was used in line
+EXTERN bool msg_didany INIT(= false); // msg_outstr() was used at all
+EXTERN bool msg_nowait INIT(= false); // don't wait for this msg
EXTERN int emsg_off INIT(= 0); // don't display errors for now,
// unless 'debug' is set.
-EXTERN int info_message INIT(= false); // printing informative message
+EXTERN bool info_message INIT(= false); // printing informative message
EXTERN bool msg_hist_off INIT(= false); // don't add messages to history
-EXTERN int need_clr_eos INIT(= false); // need to clear text before
+EXTERN bool need_clr_eos INIT(= false); // need to clear text before
// displaying a message.
EXTERN int emsg_skip INIT(= 0); // don't display errors for
// expression that is skipped
EXTERN bool emsg_severe INIT(= false); // use message of next of several
// emsg() calls for throw
-EXTERN int did_endif INIT(= false); // just had ":endif"
+EXTERN bool did_endif INIT(= false); // just had ":endif"
EXTERN dict_T vimvardict; // Dictionary with v: variables
EXTERN dict_T globvardict; // Dictionary with g: variables
/// g: value
@@ -225,25 +225,24 @@ EXTERN dict_T globvardict; // Dictionary with g: variables
EXTERN int did_emsg; // set by emsg() when the message
// is displayed or thrown
EXTERN bool called_vim_beep; // set if vim_beep() is called
-EXTERN int did_emsg_syntax; // did_emsg set because of a
+EXTERN bool did_emsg_syntax; // did_emsg set because of a
// syntax error
EXTERN int called_emsg; // always set by emsg()
EXTERN int ex_exitval INIT(= 0); // exit value for ex mode
EXTERN bool emsg_on_display INIT(= false); // there is an error message
-EXTERN int rc_did_emsg INIT(= false); // vim_regcomp() called emsg()
+EXTERN bool rc_did_emsg INIT(= false); // vim_regcomp() called emsg()
-EXTERN int no_wait_return INIT(= 0); // don't wait for return for now
-EXTERN int need_wait_return INIT(= 0); // need to wait for return later
-EXTERN int did_wait_return INIT(= false); // wait_return() was used and
- // nothing written since then
-EXTERN int need_maketitle INIT(= true); // call maketitle() soon
+EXTERN int no_wait_return INIT(= 0); // don't wait for return for now
+EXTERN bool need_wait_return INIT(= false); // need to wait for return later
+EXTERN bool did_wait_return INIT(= false); // wait_return() was used and
+ // nothing written since then
+EXTERN bool need_maketitle INIT(= true); // call maketitle() soon
EXTERN int quit_more INIT(= false); // 'q' hit at "--more--" msg
-EXTERN int ex_keep_indent INIT(= false); // getexmodeline(): keep indent
EXTERN int vgetc_busy INIT(= 0); // when inside vgetc() then > 0
-EXTERN int didset_vim INIT(= false); // did set $VIM ourselves
-EXTERN int didset_vimruntime INIT(= false); // idem for $VIMRUNTIME
+EXTERN bool didset_vim INIT(= false); // did set $VIM ourselves
+EXTERN bool didset_vimruntime INIT(= false); // idem for $VIMRUNTIME
/// Lines left before a "more" message. Ex mode needs to be able to reset this
/// after you type something.
@@ -369,7 +368,7 @@ EXTERN colnr_T search_match_endcol; // col nr of match end
EXTERN linenr_T search_first_line INIT(= 0); // for :{FIRST},{last}s/pat
EXTERN linenr_T search_last_line INIT(= MAXLNUM); // for :{first},{LAST}s/pat
-EXTERN int no_smartcase INIT(= false); // don't use 'smartcase' once
+EXTERN bool no_smartcase INIT(= false); // don't use 'smartcase' once
EXTERN int need_check_timestamps INIT(= false); // need to check file
// timestamps asap
@@ -450,7 +449,7 @@ EXTERN frame_T *topframe; // top of the window frame tree
EXTERN tabpage_T *first_tabpage;
EXTERN tabpage_T *lastused_tabpage;
EXTERN tabpage_T *curtab;
-EXTERN int redraw_tabline INIT(= false); // need to redraw tabline
+EXTERN bool redraw_tabline INIT(= false); // need to redraw tabline
// Iterates over all tabs in the tab list
# define FOR_ALL_TABS(tp) for (tabpage_T *tp = first_tabpage; tp != NULL; tp = tp->tp_next)
@@ -502,15 +501,12 @@ EXTERN volatile int full_screen INIT(= false);
/// Non-zero when only "safe" commands are allowed, e.g. when sourcing .exrc or
/// .vimrc in current directory.
-EXTERN int secure INIT(= false);
+EXTERN int secure INIT(= 0);
/// Non-zero when changing text and jumping to another window/buffer is not
/// allowed.
EXTERN int textlock INIT(= 0);
-/// Non-zero when the current buffer can't be changed. Used for FileChangedRO.
-EXTERN int curbuf_lock INIT(= 0);
-
/// Non-zero when no buffer name can be changed, no buffer can be deleted and
/// current directory can't be changed. Used for SwapExists et al.
EXTERN int allbuf_lock INIT(= 0);
@@ -528,6 +524,8 @@ EXTERN pos_T VIsual;
EXTERN int VIsual_active INIT(= false);
/// Whether Select mode is active.
EXTERN int VIsual_select INIT(= false);
+/// Restart Select mode when next cmd finished
+EXTERN int restart_VIsual_select INIT(= 0);
/// Whether to restart the selection after a Select-mode mapping or menu.
EXTERN int VIsual_reselect;
/// Type of Visual mode.
@@ -559,7 +557,7 @@ EXTERN int end_comment_pending INIT(= NUL);
// know that it should not attempt to perform scrollbinding due to the scroll
// that was a result of the ":syncbind." (Otherwise, check_scrollbind() will
// undo some of the work done by ":syncbind.") -ralston
-EXTERN int did_syncbind INIT(= false);
+EXTERN bool did_syncbind INIT(= false);
// This flag is set when a smart indent has been performed. When the next typed
// character is a '{' the inserted tab will be deleted again.
@@ -624,8 +622,8 @@ EXTERN long opcount INIT(= 0); // count for pending operator
EXTERN int motion_force INIT(=0); // motion force for pending operator
// Ex Mode (Q) state
-EXTERN int exmode_active INIT(= 0); // Zero, EXMODE_NORMAL or EXMODE_VIM.
-EXTERN int ex_no_reprint INIT(=false); // No need to print after z or p.
+EXTERN bool exmode_active INIT(= false); // true if Ex mode is active
+EXTERN bool ex_no_reprint INIT(=false); // No need to print after z or p.
EXTERN int reg_recording INIT(= 0); // register for recording or zero
EXTERN int reg_executing INIT(= 0); // register being executed or zero
@@ -646,7 +644,7 @@ EXTERN int arrow_used; // Normally false, set to true after
EXTERN bool ins_at_eol INIT(= false); // put cursor after eol when
// restarting edit after CTRL-O
-EXTERN int no_abbr INIT(= true); // true when no abbreviations loaded
+EXTERN bool no_abbr INIT(= true); // true when no abbreviations loaded
EXTERN int mapped_ctrl_c INIT(= 0); // Modes where CTRL-C is mapped.
@@ -666,7 +664,7 @@ EXTERN bool cmd_silent INIT(= false); // don't echo the command line
EXTERN int swap_exists_action INIT(= SEA_NONE);
// For dialog when swap file already
// exists.
-EXTERN int swap_exists_did_quit INIT(= false);
+EXTERN bool swap_exists_did_quit INIT(= false);
// Selected "quit" at the dialog.
EXTERN char_u IObuff[IOSIZE]; ///< Buffer for sprintf, I/O, etc.
@@ -703,14 +701,14 @@ EXTERN bool do_redraw INIT(= false); // extra redraw once
EXTERN bool must_redraw_pum INIT(= false); // redraw pum. NB: must_redraw
// should also be set.
-EXTERN int need_highlight_changed INIT(= true);
+EXTERN bool need_highlight_changed INIT(= true);
EXTERN FILE *scriptout INIT(= NULL); ///< Stream to write script to.
// volatile because it is used in a signal handler.
EXTERN volatile int got_int INIT(= false); // set to true when interrupt
// signal occurred
-EXTERN int bangredo INIT(= false); // set to true with ! command
+EXTERN bool bangredo INIT(= false); // set to true with ! command
EXTERN int searchcmdlen; // length of previous search cmd
EXTERN int reg_do_extmatch INIT(= 0); // Used when compiling regexp:
// REX_SET to allow \z\(...\),
@@ -720,14 +718,14 @@ EXTERN reg_extmatch_T *re_extmatch_in INIT(= NULL);
// Set by vim_regexec() to store \z\(...\) matches
EXTERN reg_extmatch_T *re_extmatch_out INIT(= NULL);
-EXTERN int did_outofmem_msg INIT(= false);
+EXTERN bool did_outofmem_msg INIT(= false);
// set after out of memory msg
-EXTERN int did_swapwrite_msg INIT(= false);
+EXTERN bool did_swapwrite_msg INIT(= false);
// set after swap write error msg
EXTERN int global_busy INIT(= 0); // set when :global is executing
-EXTERN int listcmd_busy INIT(= false); // set when :argdo, :windo or
+EXTERN bool listcmd_busy INIT(= false); // set when :argdo, :windo or
// :bufdo is executing
-EXTERN int need_start_insertmode INIT(= false);
+EXTERN bool need_start_insertmode INIT(= false);
// start insert mode soon
EXTERN char_u *last_cmdline INIT(= NULL); // last command line (for ":)
EXTERN char_u *repeat_cmdline INIT(= NULL); // command line for "."
@@ -735,16 +733,16 @@ EXTERN char_u *new_last_cmdline INIT(= NULL); // new value for last_cmdline
EXTERN char_u *autocmd_fname INIT(= NULL); // fname for <afile> on cmdline
EXTERN int autocmd_bufnr INIT(= 0); // fnum for <abuf> on cmdline
EXTERN char_u *autocmd_match INIT(= NULL); // name for <amatch> on cmdline
-EXTERN int did_cursorhold INIT(= false); // set when CursorHold t'gerd
+EXTERN bool did_cursorhold INIT(= false); // set when CursorHold t'gerd
EXTERN int postponed_split INIT(= 0); // for CTRL-W CTRL-] command
EXTERN int postponed_split_flags INIT(= 0); // args for win_split()
EXTERN int postponed_split_tab INIT(= 0); // cmdmod.tab
EXTERN int g_do_tagpreview INIT(= 0); // for tag preview commands:
// height of preview window
-EXTERN int g_tag_at_cursor INIT(= false); // whether the tag command comes
- // from the command line (0) or was
- // invoked as a normal command (1)
+EXTERN bool g_tag_at_cursor INIT(= false); // whether the tag command comes
+ // from the command line (0) or was
+ // invoked as a normal command (1)
EXTERN int replace_offset INIT(= 0); // offset for replace_push()
@@ -758,7 +756,7 @@ EXTERN int keep_help_flag INIT(= false); // doing :ta from help file
// everywhere.
EXTERN char_u *empty_option INIT(= (char_u *)"");
-EXTERN int redir_off INIT(= false); // no redirection for a moment
+EXTERN bool redir_off INIT(= false); // no redirection for a moment
EXTERN FILE *redir_fd INIT(= NULL); // message redirection file
EXTERN int redir_reg INIT(= 0); // message redirection register
EXTERN int redir_vname INIT(= 0); // message redirection variable
@@ -792,8 +790,8 @@ extern char_u *compiled_sys;
EXTERN char_u *globaldir INIT(= NULL);
// Whether 'keymodel' contains "stopsel" and "startsel".
-EXTERN int km_stopsel INIT(= false);
-EXTERN int km_startsel INIT(= false);
+EXTERN bool km_stopsel INIT(= false);
+EXTERN bool km_startsel INIT(= false);
EXTERN int cedit_key INIT(= -1); ///< key value of 'cedit' option
EXTERN int cmdwin_type INIT(= 0); ///< type of cmdline window or 0
@@ -941,13 +939,18 @@ EXTERN char_u e_readonlyvar[] INIT(= N_(
"E46: Cannot change read-only variable \"%.*s\""));
EXTERN char_u e_stringreq[] INIT(= N_("E928: String required"));
EXTERN char_u e_dictreq[] INIT(= N_("E715: Dictionary required"));
+EXTERN char_u e_blobidx[] INIT(= N_("E979: Blob index out of range: %" PRId64));
+EXTERN char_u e_invalblob[] INIT(= N_("E978: Invalid operation for Blob"));
EXTERN char_u e_toomanyarg[] INIT(= N_(
"E118: Too many arguments for function: %s"));
EXTERN char_u e_dictkey[] INIT(= N_(
"E716: Key not present in Dictionary: \"%s\""));
EXTERN char_u e_listreq[] INIT(= N_("E714: List required"));
+EXTERN char_u e_listblobreq[] INIT(= N_("E897: List or Blob required"));
EXTERN char_u e_listdictarg[] INIT(= N_(
"E712: Argument of %s must be a List or Dictionary"));
+EXTERN char_u e_listdictblobarg[] INIT(= N_(
+ "E896: Argument of %s must be a List, Dictionary or Blob"));
EXTERN char_u e_readerrf[] INIT(= N_("E47: Error while reading errorfile"));
EXTERN char_u e_sandbox[] INIT(= N_("E48: Not allowed in sandbox"));
EXTERN char_u e_secure[] INIT(= N_("E523: Not allowed here"));
@@ -974,6 +977,7 @@ EXTERN char_u e_write[] INIT(= N_("E80: Error while writing"));
EXTERN char_u e_zerocount[] INIT(= N_("E939: Positive count required"));
EXTERN char_u e_usingsid[] INIT(= N_(
"E81: Using <SID> not in a script context"));
+EXTERN char_u e_missingparen[] INIT(= N_("E107: Missing parentheses: %s"));
EXTERN char_u e_maxmempat[] INIT(= N_(
"E363: pattern uses more memory than 'maxmempattern'"));
EXTERN char_u e_emptybuf[] INIT(= N_("E749: empty buffer"));
diff --git a/src/nvim/grid_defs.h b/src/nvim/grid_defs.h
index 724363674c..dee096214f 100644
--- a/src/nvim/grid_defs.h
+++ b/src/nvim/grid_defs.h
@@ -86,7 +86,7 @@ struct ScreenGrid {
int zindex;
// Below is state owned by the compositor. Should generally not be set/read
- // outside this module, except for specific compatibilty hacks
+ // outside this module, except for specific compatibility hacks
// position of the grid on the composed screen.
int comp_row;
diff --git a/src/nvim/hardcopy.c b/src/nvim/hardcopy.c
index abba5425e7..df2c494ace 100644
--- a/src/nvim/hardcopy.c
+++ b/src/nvim/hardcopy.c
@@ -6,35 +6,35 @@
*/
#include <assert.h>
-#include <string.h>
#include <inttypes.h>
+#include <string.h>
-#include "nvim/vim.h"
#include "nvim/ascii.h"
+#include "nvim/vim.h"
#ifdef HAVE_LOCALE_H
# include <locale.h>
#endif
-#include "nvim/hardcopy.h"
#include "nvim/buffer.h"
#include "nvim/charset.h"
#include "nvim/eval.h"
#include "nvim/ex_cmds2.h"
#include "nvim/ex_docmd.h"
#include "nvim/fileio.h"
+#include "nvim/garray.h"
+#include "nvim/hardcopy.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/message.h"
-#include "nvim/garray.h"
#include "nvim/option.h"
+#include "nvim/os/input.h"
+#include "nvim/os/os.h"
#include "nvim/path.h"
#include "nvim/screen.h"
#include "nvim/strings.h"
#include "nvim/syntax.h"
#include "nvim/ui.h"
#include "nvim/version.h"
-#include "nvim/os/os.h"
-#include "nvim/os/input.h"
/*
* To implement printing on a platform, the following functions must be
@@ -98,20 +98,20 @@
static option_table_T printer_opts[OPT_PRINT_NUM_OPTIONS]
=
{
- {"top", TRUE, 0, NULL, 0, FALSE},
- {"bottom", TRUE, 0, NULL, 0, FALSE},
- {"left", TRUE, 0, NULL, 0, FALSE},
- {"right", TRUE, 0, NULL, 0, FALSE},
- {"header", TRUE, 0, NULL, 0, FALSE},
- {"syntax", FALSE, 0, NULL, 0, FALSE},
- {"number", FALSE, 0, NULL, 0, FALSE},
- {"wrap", FALSE, 0, NULL, 0, FALSE},
- {"duplex", FALSE, 0, NULL, 0, FALSE},
- {"portrait", FALSE, 0, NULL, 0, FALSE},
- {"paper", FALSE, 0, NULL, 0, FALSE},
- {"collate", FALSE, 0, NULL, 0, FALSE},
- {"jobsplit", FALSE, 0, NULL, 0, FALSE},
- {"formfeed", FALSE, 0, NULL, 0, FALSE},
+ { "top", TRUE, 0, NULL, 0, FALSE },
+ { "bottom", TRUE, 0, NULL, 0, FALSE },
+ { "left", TRUE, 0, NULL, 0, FALSE },
+ { "right", TRUE, 0, NULL, 0, FALSE },
+ { "header", TRUE, 0, NULL, 0, FALSE },
+ { "syntax", FALSE, 0, NULL, 0, FALSE },
+ { "number", FALSE, 0, NULL, 0, FALSE },
+ { "wrap", FALSE, 0, NULL, 0, FALSE },
+ { "duplex", FALSE, 0, NULL, 0, FALSE },
+ { "portrait", FALSE, 0, NULL, 0, FALSE },
+ { "paper", FALSE, 0, NULL, 0, FALSE },
+ { "collate", FALSE, 0, NULL, 0, FALSE },
+ { "jobsplit", FALSE, 0, NULL, 0, FALSE },
+ { "formfeed", FALSE, 0, NULL, 0, FALSE },
}
;
@@ -140,22 +140,22 @@ static uint32_t curr_bg;
static uint32_t curr_fg;
static int page_count;
-# define OPT_MBFONT_USECOURIER 0
-# define OPT_MBFONT_ASCII 1
-# define OPT_MBFONT_REGULAR 2
-# define OPT_MBFONT_BOLD 3
-# define OPT_MBFONT_OBLIQUE 4
-# define OPT_MBFONT_BOLDOBLIQUE 5
-# define OPT_MBFONT_NUM_OPTIONS 6
+#define OPT_MBFONT_USECOURIER 0
+#define OPT_MBFONT_ASCII 1
+#define OPT_MBFONT_REGULAR 2
+#define OPT_MBFONT_BOLD 3
+#define OPT_MBFONT_OBLIQUE 4
+#define OPT_MBFONT_BOLDOBLIQUE 5
+#define OPT_MBFONT_NUM_OPTIONS 6
static option_table_T mbfont_opts[OPT_MBFONT_NUM_OPTIONS] =
{
- {"c", FALSE, 0, NULL, 0, FALSE},
- {"a", FALSE, 0, NULL, 0, FALSE},
- {"r", FALSE, 0, NULL, 0, FALSE},
- {"b", FALSE, 0, NULL, 0, FALSE},
- {"i", FALSE, 0, NULL, 0, FALSE},
- {"o", FALSE, 0, NULL, 0, FALSE},
+ { "c", FALSE, 0, NULL, 0, FALSE },
+ { "a", FALSE, 0, NULL, 0, FALSE },
+ { "r", FALSE, 0, NULL, 0, FALSE },
+ { "b", FALSE, 0, NULL, 0, FALSE },
+ { "i", FALSE, 0, NULL, 0, FALSE },
+ { "o", FALSE, 0, NULL, 0, FALSE },
};
/*
@@ -183,31 +183,31 @@ struct prt_ps_font_S {
int uline_width;
int bbox_min_y;
int bbox_max_y;
- char *(ps_fontname[4]);
+ char *(ps_fontname[4]);
};
/* Structures to map user named encoding and mapping to PS equivalents for
* building CID font name */
struct prt_ps_encoding_S {
- char *encoding;
- char *cmap_encoding;
+ char *encoding;
+ char *cmap_encoding;
int needs_charset;
};
struct prt_ps_charset_S {
- char *charset;
- char *cmap_charset;
+ char *charset;
+ char *cmap_charset;
int has_charset;
};
// Collections of encodings and charsets for multi-byte printing
struct prt_ps_mbfont_S {
int num_encodings;
- struct prt_ps_encoding_S *encodings;
+ struct prt_ps_encoding_S *encodings;
int num_charsets;
- struct prt_ps_charset_S *charsets;
- char *ascii_enc;
- char *defcs;
+ struct prt_ps_charset_S *charsets;
+ char *ascii_enc;
+ char *defcs;
};
// Types of PS resource file currently used
@@ -234,14 +234,14 @@ struct prt_ps_resource_S {
};
struct prt_dsc_comment_S {
- char *string;
+ char *string;
int len;
int type;
};
struct prt_dsc_line_S {
int type;
- char_u *string;
+ char_u *string;
int len;
};
@@ -286,15 +286,14 @@ char_u *parse_printmbfont(void)
* Returns an error message for an illegal option, NULL otherwise.
* Only used for the printer at the moment...
*/
-static char_u *parse_list_options(char_u *option_str, option_table_T *table,
- size_t table_size)
+static char_u *parse_list_options(char_u *option_str, option_table_T *table, size_t table_size)
{
option_table_T *old_opts;
- char_u *ret = NULL;
- char_u *stringp;
- char_u *colonp;
- char_u *commap;
- char_u *p;
+ char_u *ret = NULL;
+ char_u *stringp;
+ char_u *colonp;
+ char_u *commap;
+ char_u *p;
size_t idx = 0; // init for GCC
int len;
@@ -317,14 +316,17 @@ static char_u *parse_list_options(char_u *option_str, option_table_T *table,
break;
}
commap = vim_strchr(stringp, ',');
- if (commap == NULL)
+ if (commap == NULL) {
commap = option_str + STRLEN(option_str);
+ }
len = (int)(colonp - stringp);
- for (idx = 0; idx < table_size; ++idx)
- if (STRNICMP(stringp, table[idx].name, len) == 0)
+ for (idx = 0; idx < table_size; ++idx) {
+ if (STRNICMP(stringp, table[idx].name, len) == 0) {
break;
+ }
+ }
if (idx == table_size) {
ret = (char_u *)N_("E551: Illegal component");
@@ -347,8 +349,9 @@ static char_u *parse_list_options(char_u *option_str, option_table_T *table,
table[idx].strlen = (int)(commap - p);
stringp = commap;
- if (*stringp == ',')
+ if (*stringp == ',') {
++stringp;
+ }
}
if (ret != NULL) {
@@ -401,16 +404,18 @@ static void prt_get_attr(int hl_id, prt_text_attr_T *pattr, int modec)
colorindex = atoi(color);
}
- if (colorindex >= 0 && colorindex < t_colors)
+ if (colorindex >= 0 && colorindex < t_colors) {
fg_color = prt_get_term_color(colorindex);
- else
+ } else {
fg_color = PRCOLOR_BLACK;
+ }
}
- if (fg_color == PRCOLOR_WHITE)
+ if (fg_color == PRCOLOR_WHITE) {
fg_color = PRCOLOR_BLACK;
- else if (*p_bg == 'd')
+ } else if (*p_bg == 'd') {
fg_color = darken_rgb(fg_color);
+ }
pattr->fg_color = fg_color;
pattr->bg_color = PRCOLOR_WHITE;
@@ -432,8 +437,7 @@ static void prt_set_bg(uint32_t bg)
}
}
-static void prt_set_font(const TriState bold, const TriState italic,
- const TriState underline)
+static void prt_set_font(const TriState bold, const TriState italic, const TriState underline)
{
if (curr_bold != bold
|| curr_italic != italic
@@ -446,8 +450,8 @@ static void prt_set_font(const TriState bold, const TriState italic,
}
// Print the line number in the left margin.
-static void prt_line_number(prt_settings_T *const psettings,
- const int page_line, const linenr_T lnum)
+static void prt_line_number(prt_settings_T *const psettings, const int page_line,
+ const linenr_T lnum)
{
prt_set_fg(psettings->number.fg_color);
prt_set_bg(psettings->number.bg_color);
@@ -504,18 +508,19 @@ int prt_get_unit(int idx)
int i;
static char *(units[4]) = PRT_UNIT_NAMES;
- if (printer_opts[idx].present)
- for (i = 0; i < 4; ++i)
+ if (printer_opts[idx].present) {
+ for (i = 0; i < 4; ++i) {
if (STRNICMP(printer_opts[idx].string, units[i], 2) == 0) {
u = i;
break;
}
+ }
+ }
return u;
}
// Print the page header.
-static void prt_header(prt_settings_T *const psettings, const int pagenum,
- const linenr_T lnum)
+static void prt_header(prt_settings_T *const psettings, const int pagenum, const linenr_T lnum)
{
int width = psettings->chars_per_line;
@@ -548,8 +553,8 @@ static void prt_header(prt_settings_T *const psettings, const int pagenum,
use_sandbox = was_set_insecurely(curwin, (char_u *)"printheader", 0);
build_stl_str_hl(curwin, tbuf, (size_t)width + IOSIZE,
- p_header, use_sandbox,
- ' ', width, NULL, NULL);
+ p_header, use_sandbox,
+ ' ', width, NULL, NULL);
// Reset line numbers
curwin->w_cursor.lnum = tmp_lnum;
@@ -616,17 +621,19 @@ void ex_hardcopy(exarg_T *eap)
settings.has_color = TRUE;
if (*eap->arg == '>') {
- char_u *errormsg = NULL;
+ char_u *errormsg = NULL;
// Expand things like "%.ps".
if (expand_filename(eap, eap->cmdlinep, &errormsg) == FAIL) {
- if (errormsg != NULL)
+ if (errormsg != NULL) {
EMSG(errormsg);
+ }
return;
}
settings.outfile = skipwhite(eap->arg + 1);
- } else if (*eap->arg != NUL)
+ } else if (*eap->arg != NUL) {
settings.arguments = eap->arg;
+ }
/*
* Initialise for printing. Ask the user for settings, unless forceit is
@@ -636,24 +643,26 @@ void ex_hardcopy(exarg_T *eap)
* PS.)
*/
if (mch_print_init(&settings,
- curbuf->b_fname == NULL
+ curbuf->b_fname == NULL
? (char_u *)buf_spname(curbuf)
: curbuf->b_sfname == NULL
? curbuf->b_fname
: curbuf->b_sfname,
- eap->forceit) == FAIL)
+ eap->forceit) == FAIL) {
return;
+ }
settings.modec = 'c';
- if (!syntax_present(curwin))
+ if (!syntax_present(curwin)) {
settings.do_syntax = FALSE;
- else if (printer_opts[OPT_PRINT_SYNTAX].present
- && TOLOWER_ASC(printer_opts[OPT_PRINT_SYNTAX].string[0]) != 'a')
+ } else if (printer_opts[OPT_PRINT_SYNTAX].present
+ && TOLOWER_ASC(printer_opts[OPT_PRINT_SYNTAX].string[0]) != 'a') {
settings.do_syntax =
(TOLOWER_ASC(printer_opts[OPT_PRINT_SYNTAX].string[0]) == 'y');
- else
+ } else {
settings.do_syntax = settings.has_color;
+ }
// Set up printing attributes for line numbers
settings.number.fg_color = PRCOLOR_BLACK;
@@ -675,8 +684,9 @@ void ex_hardcopy(exarg_T *eap)
/*
* Estimate the total lines to be printed
*/
- for (lnum = eap->line1; lnum <= eap->line2; lnum++)
+ for (lnum = eap->line1; lnum <= eap->line2; lnum++) {
bytes_to_print += STRLEN(skipwhite(ml_get(lnum)));
+ }
if (bytes_to_print == 0) {
MSG(_("No text to be printed"));
goto print_fail_no_begin;
@@ -697,8 +707,9 @@ void ex_hardcopy(exarg_T *eap)
jobsplit = (printer_opts[OPT_PRINT_JOBSPLIT].present
&& TOLOWER_ASC(printer_opts[OPT_PRINT_JOBSPLIT].string[0]) == 'y');
- if (!mch_print_begin(&settings))
+ if (!mch_print_begin(&settings)) {
goto print_fail_no_begin;
+ }
/*
* Loop over collated copies: 1 2 3, 1 2 3, ...
@@ -718,8 +729,9 @@ void ex_hardcopy(exarg_T *eap)
if (jobsplit && collated_copies > 0) {
// Splitting jobs: Stop a previous job and start a new one.
mch_print_end(&settings);
- if (!mch_print_begin(&settings))
+ if (!mch_print_begin(&settings)) {
goto print_fail_no_begin;
+ }
}
/*
@@ -746,34 +758,38 @@ void ex_hardcopy(exarg_T *eap)
// Check for interrupt character every page.
os_breakcheck();
- if (got_int || settings.user_abort)
+ if (got_int || settings.user_abort) {
goto print_fail;
+ }
assert(prtpos.bytes_printed <= SIZE_MAX / 100);
sprintf((char *)IObuff, _("Printing page %d (%zu%%)"),
page_count + 1 + side,
prtpos.bytes_printed * 100 / bytes_to_print);
- if (!mch_print_begin_page(IObuff))
+ if (!mch_print_begin_page(IObuff)) {
goto print_fail;
+ }
- if (settings.n_collated_copies > 1)
+ if (settings.n_collated_copies > 1) {
sprintf((char *)IObuff + STRLEN(IObuff),
- _(" Copy %d of %d"),
- collated_copies + 1,
- settings.n_collated_copies);
+ _(" Copy %d of %d"),
+ collated_copies + 1,
+ settings.n_collated_copies);
+ }
prt_message(IObuff);
/*
* Output header if required
*/
- if (prt_header_height() > 0)
+ if (prt_header_height() > 0) {
prt_header(&settings, page_count + 1 + side,
- prtpos.file_line);
+ prtpos.file_line);
+ }
for (page_line = 0; page_line < settings.lines_per_page;
++page_line) {
prtpos.column = hardcopy_line(&settings,
- page_line, &prtpos);
+ page_line, &prtpos);
if (prtpos.column == 0) {
// finished a file line
prtpos.bytes_printed +=
@@ -803,19 +819,21 @@ void ex_hardcopy(exarg_T *eap)
if (prtpos.file_line > eap->line2 && settings.duplex
&& side == 0
&& uncollated_copies + 1 < settings.n_uncollated_copies) {
- if (!mch_print_blank_page())
+ if (!mch_print_blank_page()) {
goto print_fail;
+ }
}
}
- if (settings.duplex && prtpos.file_line <= eap->line2)
+ if (settings.duplex && prtpos.file_line <= eap->line2) {
++page_count;
+ }
// Remember the position where the next page starts.
page_prtpos = prtpos;
}
vim_snprintf((char *)IObuff, IOSIZE, _("Printed: %s"),
- settings.jobname);
+ settings.jobname);
prt_message(IObuff);
}
@@ -837,7 +855,7 @@ print_fail_no_begin:
static colnr_T hardcopy_line(prt_settings_T *psettings, int page_line, prt_pos_T *ppos)
{
colnr_T col;
- char_u *line;
+ char_u *line;
int need_break = FALSE;
int outputlen;
int tab_spaces;
@@ -848,8 +866,9 @@ static colnr_T hardcopy_line(prt_settings_T *psettings, int page_line, prt_pos_T
if (ppos->column == 0 || ppos->ff) {
print_pos = 0;
tab_spaces = 0;
- if (!ppos->ff && prt_use_number())
+ if (!ppos->ff && prt_use_number()) {
prt_line_number(psettings, page_line, ppos->file_line);
+ }
ppos->ff = FALSE;
} else {
// left over from wrap halfway through a tab
@@ -870,10 +889,11 @@ static colnr_T hardcopy_line(prt_settings_T *psettings, int page_line, prt_pos_T
// syntax highlighting stuff.
if (psettings->do_syntax) {
id = syn_get_id(curwin, ppos->file_line, col, 1, NULL, FALSE);
- if (id > 0)
+ if (id > 0) {
id = syn_get_final_id(id);
- else
+ } else {
id = 0;
+ }
// Get the line again, a multi-line regexp may invalidate it.
line = ml_get(ppos->file_line);
@@ -900,8 +920,9 @@ static colnr_T hardcopy_line(prt_settings_T *psettings, int page_line, prt_pos_T
need_break = mch_print_text_out((char_u *)" ", 1);
print_pos++;
tab_spaces--;
- if (need_break)
+ if (need_break) {
break;
+ }
}
// Keep the TAB if we didn't finish it.
if (need_break && tab_spaces > 0) {
@@ -930,8 +951,9 @@ static colnr_T hardcopy_line(prt_settings_T *psettings, int page_line, prt_pos_T
&& (line[col] == NUL
|| (printer_opts[OPT_PRINT_WRAP].present
&& TOLOWER_ASC(printer_opts[OPT_PRINT_WRAP].string[0])
- == 'n')))
+ == 'n'))) {
return 0;
+ }
return col;
}
@@ -1000,7 +1022,7 @@ static struct prt_ps_font_S prt_ps_courier_font =
600,
-100, 50,
-250, 805,
- {"Courier", "Courier-Bold", "Courier-Oblique", "Courier-BoldOblique"}
+ { "Courier", "Courier-Bold", "Courier-Oblique", "Courier-BoldOblique" }
};
// Generic font metrics for multi-byte fonts
@@ -1009,7 +1031,7 @@ static struct prt_ps_font_S prt_ps_mb_font =
1000,
-100, 50,
-250, 805,
- {NULL, NULL, NULL, NULL}
+ { NULL, NULL, NULL, NULL }
};
// Pointer to current font set being used
@@ -1027,25 +1049,25 @@ static struct prt_ps_font_S *prt_ps_font;
// Japanese encodings and charsets
static struct prt_ps_encoding_S j_encodings[] =
{
- {"iso-2022-jp", NULL, (CS_JIS_C_1978|CS_JIS_X_1983|CS_JIS_X_1990|
- CS_NEC)},
- {"euc-jp", "EUC", (CS_JIS_C_1978|CS_JIS_X_1983|CS_JIS_X_1990)},
- {"sjis", "RKSJ", (CS_JIS_C_1978|CS_JIS_X_1983|CS_MSWINDOWS|
- CS_KANJITALK6|CS_KANJITALK7)},
- {"cp932", "RKSJ", CS_JIS_X_1983},
- {"ucs-2", "UCS2", CS_JIS_X_1990},
- {"utf-8", "UTF8", CS_JIS_X_1990}
+ { "iso-2022-jp", NULL, (CS_JIS_C_1978|CS_JIS_X_1983|CS_JIS_X_1990|
+ CS_NEC) },
+ { "euc-jp", "EUC", (CS_JIS_C_1978|CS_JIS_X_1983|CS_JIS_X_1990) },
+ { "sjis", "RKSJ", (CS_JIS_C_1978|CS_JIS_X_1983|CS_MSWINDOWS|
+ CS_KANJITALK6|CS_KANJITALK7) },
+ { "cp932", "RKSJ", CS_JIS_X_1983 },
+ { "ucs-2", "UCS2", CS_JIS_X_1990 },
+ { "utf-8", "UTF8", CS_JIS_X_1990 }
};
static struct prt_ps_charset_S j_charsets[] =
{
- {"JIS_C_1978", "78", CS_JIS_C_1978},
- {"JIS_X_1983", NULL, CS_JIS_X_1983},
- {"JIS_X_1990", "Hojo", CS_JIS_X_1990},
- {"NEC", "Ext", CS_NEC},
- {"MSWINDOWS", "90ms", CS_MSWINDOWS},
- {"CP932", "90ms", CS_JIS_X_1983},
- {"KANJITALK6", "83pv", CS_KANJITALK6},
- {"KANJITALK7", "90pv", CS_KANJITALK7}
+ { "JIS_C_1978", "78", CS_JIS_C_1978 },
+ { "JIS_X_1983", NULL, CS_JIS_X_1983 },
+ { "JIS_X_1990", "Hojo", CS_JIS_X_1990 },
+ { "NEC", "Ext", CS_NEC },
+ { "MSWINDOWS", "90ms", CS_MSWINDOWS },
+ { "CP932", "90ms", CS_JIS_X_1983 },
+ { "KANJITALK6", "83pv", CS_KANJITALK6 },
+ { "KANJITALK7", "90pv", CS_KANJITALK7 }
};
#define CS_GB_2312_80 (0x01)
@@ -1059,23 +1081,23 @@ static struct prt_ps_charset_S j_charsets[] =
// Simplified Chinese encodings and charsets
static struct prt_ps_encoding_S sc_encodings[] =
{
- {"iso-2022", NULL, (CS_GB_2312_80|CS_GBT_12345_90)},
- {"gb18030", NULL, CS_GBK2K},
- {"euc-cn", "EUC", (CS_GB_2312_80|CS_GBT_12345_90|CS_SC_MAC|
- CS_GBT_90_MAC)},
- {"gbk", "EUC", CS_GBK},
- {"ucs-2", "UCS2", CS_SC_ISO10646},
- {"utf-8", "UTF8", CS_SC_ISO10646}
+ { "iso-2022", NULL, (CS_GB_2312_80|CS_GBT_12345_90) },
+ { "gb18030", NULL, CS_GBK2K },
+ { "euc-cn", "EUC", (CS_GB_2312_80|CS_GBT_12345_90|CS_SC_MAC|
+ CS_GBT_90_MAC) },
+ { "gbk", "EUC", CS_GBK },
+ { "ucs-2", "UCS2", CS_SC_ISO10646 },
+ { "utf-8", "UTF8", CS_SC_ISO10646 }
};
static struct prt_ps_charset_S sc_charsets[] =
{
- {"GB_2312-80", "GB", CS_GB_2312_80},
- {"GBT_12345-90","GBT", CS_GBT_12345_90},
- {"MAC", "GBpc", CS_SC_MAC},
- {"GBT-90_MAC", "GBTpc", CS_GBT_90_MAC},
- {"GBK", "GBK", CS_GBK},
- {"GB18030", "GBK2K", CS_GBK2K},
- {"ISO10646", "UniGB", CS_SC_ISO10646}
+ { "GB_2312-80", "GB", CS_GB_2312_80 },
+ { "GBT_12345-90", "GBT", CS_GBT_12345_90 },
+ { "MAC", "GBpc", CS_SC_MAC },
+ { "GBT-90_MAC", "GBTpc", CS_GBT_90_MAC },
+ { "GBK", "GBK", CS_GBK },
+ { "GB18030", "GBK2K", CS_GBK2K },
+ { "ISO10646", "UniGB", CS_SC_ISO10646 }
};
#define CS_CNS_PLANE_1 (0x01)
@@ -1095,33 +1117,33 @@ static struct prt_ps_charset_S sc_charsets[] =
// Traditional Chinese encodings and charsets
static struct prt_ps_encoding_S tc_encodings[] =
{
- {"iso-2022", NULL, (CS_CNS_PLANE_1|CS_CNS_PLANE_2)},
- {"euc-tw", "EUC", CS_CNS_PLANE_1_2},
- {"big5", "B5", (CS_B5|CS_ETEN|CS_HK_GCCS|CS_HK_SCS|
- CS_HK_SCS_ETEN|CS_MTHKL|CS_MTHKS|CS_DLHKL|
- CS_DLHKS)},
- {"cp950", "B5", CS_B5},
- {"ucs-2", "UCS2", CS_TC_ISO10646},
- {"utf-8", "UTF8", CS_TC_ISO10646},
- {"utf-16", "UTF16", CS_TC_ISO10646},
- {"utf-32", "UTF32", CS_TC_ISO10646}
+ { "iso-2022", NULL, (CS_CNS_PLANE_1|CS_CNS_PLANE_2) },
+ { "euc-tw", "EUC", CS_CNS_PLANE_1_2 },
+ { "big5", "B5", (CS_B5|CS_ETEN|CS_HK_GCCS|CS_HK_SCS|
+ CS_HK_SCS_ETEN|CS_MTHKL|CS_MTHKS|CS_DLHKL|
+ CS_DLHKS) },
+ { "cp950", "B5", CS_B5 },
+ { "ucs-2", "UCS2", CS_TC_ISO10646 },
+ { "utf-8", "UTF8", CS_TC_ISO10646 },
+ { "utf-16", "UTF16", CS_TC_ISO10646 },
+ { "utf-32", "UTF32", CS_TC_ISO10646 }
};
static struct prt_ps_charset_S tc_charsets[] =
{
- {"CNS_1992_1", "CNS1", CS_CNS_PLANE_1},
- {"CNS_1992_2", "CNS2", CS_CNS_PLANE_2},
- {"CNS_1993", "CNS", CS_CNS_PLANE_1_2},
- {"BIG5", NULL, CS_B5},
- {"CP950", NULL, CS_B5},
- {"ETEN", "ETen", CS_ETEN},
- {"HK_GCCS", "HKgccs", CS_HK_GCCS},
- {"SCS", "HKscs", CS_HK_SCS},
- {"SCS_ETEN", "ETHK", CS_HK_SCS_ETEN},
- {"MTHKL", "HKm471", CS_MTHKL},
- {"MTHKS", "HKm314", CS_MTHKS},
- {"DLHKL", "HKdla", CS_DLHKL},
- {"DLHKS", "HKdlb", CS_DLHKS},
- {"ISO10646", "UniCNS", CS_TC_ISO10646}
+ { "CNS_1992_1", "CNS1", CS_CNS_PLANE_1 },
+ { "CNS_1992_2", "CNS2", CS_CNS_PLANE_2 },
+ { "CNS_1993", "CNS", CS_CNS_PLANE_1_2 },
+ { "BIG5", NULL, CS_B5 },
+ { "CP950", NULL, CS_B5 },
+ { "ETEN", "ETen", CS_ETEN },
+ { "HK_GCCS", "HKgccs", CS_HK_GCCS },
+ { "SCS", "HKscs", CS_HK_SCS },
+ { "SCS_ETEN", "ETHK", CS_HK_SCS_ETEN },
+ { "MTHKL", "HKm471", CS_MTHKL },
+ { "MTHKS", "HKm314", CS_MTHKS },
+ { "DLHKL", "HKdla", CS_DLHKL },
+ { "DLHKS", "HKdlb", CS_DLHKS },
+ { "ISO10646", "UniCNS", CS_TC_ISO10646 }
};
#define CS_KR_X_1992 (0x01)
@@ -1132,24 +1154,24 @@ static struct prt_ps_charset_S tc_charsets[] =
// Korean encodings and charsets
static struct prt_ps_encoding_S k_encodings[] =
{
- {"iso-2022-kr", NULL, CS_KR_X_1992},
- {"euc-kr", "EUC", (CS_KR_X_1992|CS_KR_MAC)},
- {"johab", "Johab", CS_KR_X_1992},
- {"cp1361", "Johab", CS_KR_X_1992},
- {"uhc", "UHC", CS_KR_X_1992_MS},
- {"cp949", "UHC", CS_KR_X_1992_MS},
- {"ucs-2", "UCS2", CS_KR_ISO10646},
- {"utf-8", "UTF8", CS_KR_ISO10646}
+ { "iso-2022-kr", NULL, CS_KR_X_1992 },
+ { "euc-kr", "EUC", (CS_KR_X_1992|CS_KR_MAC) },
+ { "johab", "Johab", CS_KR_X_1992 },
+ { "cp1361", "Johab", CS_KR_X_1992 },
+ { "uhc", "UHC", CS_KR_X_1992_MS },
+ { "cp949", "UHC", CS_KR_X_1992_MS },
+ { "ucs-2", "UCS2", CS_KR_ISO10646 },
+ { "utf-8", "UTF8", CS_KR_ISO10646 }
};
static struct prt_ps_charset_S k_charsets[] =
{
- {"KS_X_1992", "KSC", CS_KR_X_1992},
- {"CP1361", "KSC", CS_KR_X_1992},
- {"MAC", "KSCpc", CS_KR_MAC},
- {"MSWINDOWS", "KSCms", CS_KR_X_1992_MS},
- {"CP949", "KSCms", CS_KR_X_1992_MS},
- {"WANSUNG", "KSCms", CS_KR_X_1992_MS},
- {"ISO10646", "UniKS", CS_KR_ISO10646}
+ { "KS_X_1992", "KSC", CS_KR_X_1992 },
+ { "CP1361", "KSC", CS_KR_X_1992 },
+ { "MAC", "KSCpc", CS_KR_MAC },
+ { "MSWINDOWS", "KSCms", CS_KR_X_1992_MS },
+ { "CP949", "KSCms", CS_KR_X_1992_MS },
+ { "WANSUNG", "KSCms", CS_KR_X_1992_MS },
+ { "ISO10646", "UniKS", CS_KR_ISO10646 }
};
static struct prt_ps_mbfont_S prt_ps_mbfonts[] =
@@ -1196,7 +1218,7 @@ static struct prt_ps_mbfont_S prt_ps_mbfonts[] =
*
* VIM Prolog CIDProlog
* 6.2 1.3
- * 7.0 1.4 1.0
+ * 7.0 1.4 1.0
*/
#define PRT_PROLOG_VERSION ((char_u *)"1.4")
#define PRT_CID_PROLOG_VERSION ((char_u *)"1.0")
@@ -1224,11 +1246,11 @@ static struct prt_ps_mbfont_S prt_ps_mbfonts[] =
#define SIZEOF_CSTR(s) (sizeof(s) - 1)
static struct prt_dsc_comment_S prt_dsc_table[] =
{
- {PRT_DSC_TITLE, SIZEOF_CSTR(PRT_DSC_TITLE), PRT_DSC_TITLE_TYPE},
- {PRT_DSC_VERSION, SIZEOF_CSTR(PRT_DSC_VERSION),
- PRT_DSC_VERSION_TYPE},
- {PRT_DSC_ENDCOMMENTS, SIZEOF_CSTR(PRT_DSC_ENDCOMMENTS),
- PRT_DSC_ENDCOMMENTS_TYPE}
+ { PRT_DSC_TITLE, SIZEOF_CSTR(PRT_DSC_TITLE), PRT_DSC_TITLE_TYPE },
+ { PRT_DSC_VERSION, SIZEOF_CSTR(PRT_DSC_VERSION),
+ PRT_DSC_VERSION_TYPE },
+ { PRT_DSC_ENDCOMMENTS, SIZEOF_CSTR(PRT_DSC_ENDCOMMENTS),
+ PRT_DSC_ENDCOMMENTS_TYPE }
};
@@ -1359,14 +1381,15 @@ static void prt_write_boolean(int b)
static void prt_def_font(char *new_name, char *encoding, int height, char *font)
{
vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
- "/_%s /VIM-%s /%s ref\n", new_name, encoding, font);
+ "/_%s /VIM-%s /%s ref\n", new_name, encoding, font);
prt_write_file(prt_line_buffer);
- if (prt_out_mbyte)
+ if (prt_out_mbyte) {
sprintf((char *)prt_line_buffer, "/%s %d %f /_%s sffs\n",
- new_name, height, 500./prt_ps_courier_font.wx, new_name);
- else
+ new_name, height, 500./prt_ps_courier_font.wx, new_name);
+ } else {
vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
- "/%s %d /_%s ffs\n", new_name, height, new_name);
+ "/%s %d /_%s ffs\n", new_name, height, new_name);
+ }
prt_write_file(prt_line_buffer);
}
@@ -1376,10 +1399,10 @@ static void prt_def_font(char *new_name, char *encoding, int height, char *font)
static void prt_def_cidfont(char *new_name, int height, char *cidfont)
{
vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
- "/_%s /%s[/%s] vim_composefont\n", new_name, prt_cmap, cidfont);
+ "/_%s /%s[/%s] vim_composefont\n", new_name, prt_cmap, cidfont);
prt_write_file(prt_line_buffer);
vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
- "/%s %d /_%s ffs\n", new_name, height, new_name);
+ "/%s %d /_%s ffs\n", new_name, height, new_name);
prt_write_file(prt_line_buffer);
}
@@ -1389,7 +1412,7 @@ static void prt_def_cidfont(char *new_name, int height, char *cidfont)
static void prt_dup_cidfont(char *original_name, char *new_name)
{
vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
- "/%s %s d\n", new_name, original_name);
+ "/%s %s d\n", new_name, original_name);
prt_write_file(prt_line_buffer);
}
@@ -1402,10 +1425,12 @@ static void prt_real_bits(double real, int precision, int *pinteger, int *pfract
{
int integer = (int)real;
double fraction = real - integer;
- if (real < integer)
+ if (real < integer) {
fraction = -fraction;
- for (int i = 0; i < precision; i++)
+ }
+ for (int i = 0; i < precision; i++) {
fraction *= 10.0;
+ }
*pinteger = integer;
*pfraction = (int)(fraction + 0.5);
@@ -1447,7 +1472,7 @@ static void prt_write_real(double val, int prec)
static void prt_def_var(char *name, double value, int prec)
{
vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
- "/%s ", name);
+ "/%s ", name);
prt_write_file(prt_line_buffer);
prt_write_real(value, prec);
sprintf((char *)prt_line_buffer, "d\n");
@@ -1500,16 +1525,18 @@ static void prt_flush_buffer(void)
prt_write_string("ul\n");
}
// Draw the text
- if (prt_out_mbyte)
+ if (prt_out_mbyte) {
prt_write_string("<");
- else
+ } else {
prt_write_string("(");
+ }
assert(prt_ps_buffer.ga_len >= 0);
prt_write_file_raw_len(prt_ps_buffer.ga_data, (size_t)prt_ps_buffer.ga_len);
- if (prt_out_mbyte)
+ if (prt_out_mbyte) {
prt_write_string(">");
- else
+ } else {
prt_write_string(")");
+ }
// Add a moveto if need be and use the appropriate show procedure
if (prt_do_moveto) {
prt_write_real(prt_pos_x_moveto, 2);
@@ -1529,15 +1556,16 @@ static void prt_resource_name(char_u *filename, void *cookie)
{
char_u *resource_filename = cookie;
- if (STRLEN(filename) >= MAXPATHL)
+ if (STRLEN(filename) >= MAXPATHL) {
*resource_filename = NUL;
- else
+ } else {
STRCPY(resource_filename, filename);
+ }
}
static int prt_find_resource(char *name, struct prt_ps_resource_S *resource)
{
- char_u *buffer;
+ char_u *buffer;
int retval;
buffer = xmallocz(MAXPATHL);
@@ -1568,15 +1596,17 @@ static int prt_resfile_next_line(void)
// Move to start of next line and then find end of line
idx = prt_resfile.line_end + 1;
while (idx < prt_resfile.len) {
- if (prt_resfile.buffer[idx] != PSLF && prt_resfile.buffer[idx] != PSCR)
+ if (prt_resfile.buffer[idx] != PSLF && prt_resfile.buffer[idx] != PSCR) {
break;
+ }
idx++;
}
prt_resfile.line_start = idx;
while (idx < prt_resfile.len) {
- if (prt_resfile.buffer[idx] == PSLF || prt_resfile.buffer[idx] == PSCR)
+ if (prt_resfile.buffer[idx] == PSLF || prt_resfile.buffer[idx] == PSCR) {
break;
+ }
idx++;
}
prt_resfile.line_end = idx;
@@ -1592,7 +1622,7 @@ static int prt_resfile_strncmp(int offset, const char *string, int len)
return 1;
}
return STRNCMP(&prt_resfile.buffer[prt_resfile.line_start + offset],
- string, len);
+ string, len);
}
static int prt_resfile_skip_nonws(int offset)
@@ -1601,8 +1631,9 @@ static int prt_resfile_skip_nonws(int offset)
idx = prt_resfile.line_start + offset;
while (idx < prt_resfile.line_end) {
- if (isspace(prt_resfile.buffer[idx]))
+ if (isspace(prt_resfile.buffer[idx])) {
return idx - prt_resfile.line_start;
+ }
idx++;
}
return -1;
@@ -1614,8 +1645,9 @@ static int prt_resfile_skip_ws(int offset)
idx = prt_resfile.line_start + offset;
while (idx < prt_resfile.line_end) {
- if (!isspace(prt_resfile.buffer[idx]))
+ if (!isspace(prt_resfile.buffer[idx])) {
return idx - prt_resfile.line_start;
+ }
idx++;
}
return -1;
@@ -1685,10 +1717,10 @@ static bool prt_open_resource(struct prt_ps_resource_S *resource)
// Parse first line to ensure valid resource file
prt_resfile.len = (int)fread((char *)prt_resfile.buffer, sizeof(char_u),
- PRT_FILE_BUFFER_LEN, fd_resource);
+ PRT_FILE_BUFFER_LEN, fd_resource);
if (ferror(fd_resource)) {
EMSG2(_("E457: Can't read PostScript resource file \"%s\""),
- resource->filename);
+ resource->filename);
fclose(fd_resource);
return false;
}
@@ -1702,7 +1734,7 @@ static bool prt_open_resource(struct prt_ps_resource_S *resource)
int offset = 0;
if (prt_resfile_strncmp(offset, PRT_RESOURCE_HEADER,
- (int)STRLEN(PRT_RESOURCE_HEADER)) != 0) {
+ (int)STRLEN(PRT_RESOURCE_HEADER)) != 0) {
EMSG2(_("E618: file \"%s\" is not a PostScript resource file"),
resource->filename);
return false;
@@ -1719,7 +1751,7 @@ static bool prt_open_resource(struct prt_ps_resource_S *resource)
return false;
}
if (prt_resfile_strncmp(offset, PRT_RESOURCE_RESOURCE,
- (int)STRLEN(PRT_RESOURCE_RESOURCE)) != 0) {
+ (int)STRLEN(PRT_RESOURCE_RESOURCE)) != 0) {
EMSG2(_("E619: file \"%s\" is not a supported PostScript resource file"),
resource->filename);
return false;
@@ -1767,7 +1799,7 @@ static bool prt_open_resource(struct prt_ps_resource_S *resource)
break;
case PRT_DSC_ENDCOMMENTS_TYPE:
- // Wont find title or resource after this comment, stop searching
+ // Won't find title or resource after this comment, stop searching
seen_all = true;
break;
@@ -1786,8 +1818,7 @@ static bool prt_open_resource(struct prt_ps_resource_S *resource)
return true;
}
-static bool prt_check_resource(const struct prt_ps_resource_S *resource,
- const char_u *version)
+static bool prt_check_resource(const struct prt_ps_resource_S *resource, const char_u *version)
FUNC_ATTR_NONNULL_ALL
{
// Version number m.n should match, the revision number does not matter
@@ -1809,14 +1840,14 @@ static void prt_dsc_start(void)
static void prt_dsc_noarg(char *comment)
{
vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
- "%%%%%s\n", comment);
+ "%%%%%s\n", comment);
prt_write_file(prt_line_buffer);
}
static void prt_dsc_textline(char *comment, char *text)
{
vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
- "%%%%%s: %s\n", comment, text);
+ "%%%%%s: %s\n", comment, text);
prt_write_file(prt_line_buffer);
}
@@ -1824,7 +1855,7 @@ static void prt_dsc_text(char *comment, char *text)
{
// TODO(vim): - should scan 'text' for any chars needing escaping!
vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
- "%%%%%s: (%s)\n", comment, text);
+ "%%%%%s: (%s)\n", comment, text);
prt_write_file(prt_line_buffer);
}
@@ -1835,7 +1866,7 @@ static void prt_dsc_ints(char *comment, int count, int *ints)
int i;
vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
- "%%%%%s:", comment);
+ "%%%%%s:", comment);
prt_write_file(prt_line_buffer);
for (i = 0; i < count; i++) {
@@ -1846,23 +1877,21 @@ static void prt_dsc_ints(char *comment, int count, int *ints)
prt_write_string("\n");
}
-static void prt_dsc_resources(
- const char *comment, // if NULL add to previous
- const char *type,
- const char *string
-)
+/// @param comment if NULL add to previous
+static void prt_dsc_resources(const char *comment, const char *type, const char *string)
FUNC_ATTR_NONNULL_ARG(2, 3)
{
- if (comment != NULL)
+ if (comment != NULL) {
vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
- "%%%%%s: %s", comment, type);
- else
+ "%%%%%s: %s", comment, type);
+ } else {
vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
- "%%%%+ %s", type);
+ "%%%%+ %s", type);
+ }
prt_write_file(prt_line_buffer);
vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
- " %s\n", string);
+ " %s\n", string);
prt_write_file(prt_line_buffer);
}
@@ -1871,10 +1900,12 @@ static void prt_dsc_font_resource(char *resource, struct prt_ps_font_S *ps_font)
int i;
prt_dsc_resources(resource, "font",
- ps_font->ps_fontname[PRT_PS_FONT_ROMAN]);
- for (i = PRT_PS_FONT_BOLD; i <= PRT_PS_FONT_BOLDOBLIQUE; i++)
- if (ps_font->ps_fontname[i] != NULL)
+ ps_font->ps_fontname[PRT_PS_FONT_ROMAN]);
+ for (i = PRT_PS_FONT_BOLD; i <= PRT_PS_FONT_BOLDOBLIQUE; i++) {
+ if (ps_font->ps_fontname[i] != NULL) {
prt_dsc_resources(NULL, "font", ps_font->ps_fontname[i]);
+ }
+ }
}
static void prt_dsc_requirements(int duplex, int tumble, int collate, int color, int num_copies)
@@ -1882,21 +1913,25 @@ static void prt_dsc_requirements(int duplex, int tumble, int collate, int color,
/* Only output the comment if we need to.
* Note: tumble is ignored if we are not duplexing
*/
- if (!(duplex || collate || color || (num_copies > 1)))
+ if (!(duplex || collate || color || (num_copies > 1))) {
return;
+ }
sprintf((char *)prt_line_buffer, "%%%%Requirements:");
prt_write_file(prt_line_buffer);
if (duplex) {
prt_write_string(" duplex");
- if (tumble)
+ if (tumble) {
prt_write_string("(tumble)");
+ }
}
- if (collate)
+ if (collate) {
prt_write_string(" collate");
- if (color)
+ }
+ if (color) {
prt_write_string(" color");
+ }
if (num_copies > 1) {
prt_write_string(" numcopies(");
// Note: no space wanted so don't use prt_write_int()
@@ -1908,23 +1943,26 @@ static void prt_dsc_requirements(int duplex, int tumble, int collate, int color,
prt_write_string("\n");
}
-static void prt_dsc_docmedia(char *paper_name, double width, double height, double weight, char *colour, char *type)
+static void prt_dsc_docmedia(char *paper_name, double width, double height, double weight,
+ char *colour, char *type)
{
vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
- "%%%%DocumentMedia: %s ", paper_name);
+ "%%%%DocumentMedia: %s ", paper_name);
prt_write_file(prt_line_buffer);
prt_write_real(width, 2);
prt_write_real(height, 2);
prt_write_real(weight, 2);
- if (colour == NULL)
+ if (colour == NULL) {
prt_write_string("()");
- else
+ } else {
prt_write_string(colour);
+ }
prt_write_string(" ");
- if (type == NULL)
+ if (type == NULL) {
prt_write_string("()");
- else
+ } else {
prt_write_string(type);
+ }
prt_write_string("\n");
}
@@ -1938,8 +1976,9 @@ void mch_print_cleanup(void)
* one style).
*/
for (i = PRT_PS_FONT_ROMAN; i <= PRT_PS_FONT_BOLDOBLIQUE; i++) {
- if (prt_ps_mb_font.ps_fontname[i] != NULL)
+ if (prt_ps_mb_font.ps_fontname[i] != NULL) {
xfree(prt_ps_mb_font.ps_fontname[i]);
+ }
prt_ps_mb_font.ps_fontname[i] = NULL;
}
}
@@ -1993,7 +2032,8 @@ static double to_device_units(int idx, double physsize, int def_number)
/*
* Calculate margins for given width and height from printoptions settings.
*/
-static void prt_page_margins(double width, double height, double *left, double *right, double *top, double *bottom)
+static void prt_page_margins(double width, double height, double *left, double *right, double *top,
+ double *bottom)
{
*left = to_device_units(OPT_PRINT_LEFT, width, 10);
*right = width - to_device_units(OPT_PRINT_RIGHT, width, 5);
@@ -2015,11 +2055,13 @@ static int prt_get_cpl(void)
/* If we are outputting multi-byte characters then line numbers will be
* printed with half width characters
*/
- if (prt_out_mbyte)
+ if (prt_out_mbyte) {
prt_number_width /= 2;
+ }
prt_left_margin += prt_number_width;
- } else
+ } else {
prt_number_width = 0.0;
+ }
return (int)((prt_right_margin - prt_left_margin) / prt_char_width);
}
@@ -2044,11 +2086,11 @@ static int prt_get_lpp(void)
* case where the font height can exceed the line height.
*/
prt_bgcol_offset = PRT_PS_FONT_TO_USER(prt_line_height,
- prt_ps_font->bbox_min_y);
+ prt_ps_font->bbox_min_y);
if ((prt_ps_font->bbox_max_y - prt_ps_font->bbox_min_y) < 1000.0) {
prt_bgcol_offset -= PRT_PS_FONT_TO_USER(prt_line_height,
- (1000.0 - (prt_ps_font->bbox_max_y -
- prt_ps_font->bbox_min_y)) / 2);
+ (1000.0 - (prt_ps_font->bbox_max_y -
+ prt_ps_font->bbox_min_y)) / 2);
}
// Get height for topmost line based on background rect offset.
@@ -2063,11 +2105,12 @@ static int prt_get_lpp(void)
return lpp - prt_header_height();
}
-static int prt_match_encoding(char *p_encoding, struct prt_ps_mbfont_S *p_cmap, struct prt_ps_encoding_S **pp_mbenc)
+static int prt_match_encoding(char *p_encoding, struct prt_ps_mbfont_S *p_cmap,
+ struct prt_ps_encoding_S **pp_mbenc)
{
int mbenc;
int enc_len;
- struct prt_ps_encoding_S *p_mbenc;
+ struct prt_ps_encoding_S *p_mbenc;
*pp_mbenc = NULL;
// Look for recognised encoding
@@ -2083,7 +2126,8 @@ static int prt_match_encoding(char *p_encoding, struct prt_ps_mbfont_S *p_cmap,
return FALSE;
}
-static int prt_match_charset(char *p_charset, struct prt_ps_mbfont_S *p_cmap, struct prt_ps_charset_S **pp_mbchar)
+static int prt_match_charset(char *p_charset, struct prt_ps_mbfont_S *p_cmap,
+ struct prt_ps_charset_S **pp_mbchar)
{
int mbchar;
int char_len;
@@ -2108,24 +2152,25 @@ static int prt_match_charset(char *p_charset, struct prt_ps_mbfont_S *p_cmap, st
int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit)
{
int i;
- char *paper_name;
+ char *paper_name;
int paper_strlen;
int fontsize;
- char_u *p;
+ char_u *p;
int props;
int cmap = 0;
- char_u *p_encoding;
+ char_u *p_encoding;
struct prt_ps_encoding_S *p_mbenc;
struct prt_ps_encoding_S *p_mbenc_first;
- struct prt_ps_charset_S *p_mbchar = NULL;
+ struct prt_ps_charset_S *p_mbchar = NULL;
/*
* Set up font and encoding.
*/
p_encoding = enc_skip(p_penc);
- if (*p_encoding == NUL)
+ if (*p_encoding == NUL) {
p_encoding = enc_skip(p_enc);
+ }
/* Look for a multi-byte font that matches the encoding and character set.
* Only look if multi-byte character set is defined, or using multi-byte
@@ -2136,16 +2181,18 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit)
if (!(props & ENC_8BIT) && ((*p_pmcs != NUL) || !(props & ENC_UNICODE))) {
p_mbenc_first = NULL;
int effective_cmap = 0;
- for (cmap = 0; cmap < (int)ARRAY_SIZE(prt_ps_mbfonts); cmap++)
+ for (cmap = 0; cmap < (int)ARRAY_SIZE(prt_ps_mbfonts); cmap++) {
if (prt_match_encoding((char *)p_encoding, &prt_ps_mbfonts[cmap],
&p_mbenc)) {
if (p_mbenc_first == NULL) {
p_mbenc_first = p_mbenc;
effective_cmap = cmap;
}
- if (prt_match_charset((char *)p_pmcs, &prt_ps_mbfonts[cmap], &p_mbchar))
+ if (prt_match_charset((char *)p_pmcs, &prt_ps_mbfonts[cmap], &p_mbchar)) {
break;
+ }
}
+ }
// Use first encoding matched if no charset matched
if (p_mbenc_first != NULL && p_mbchar == NULL) {
@@ -2205,7 +2252,6 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit)
prt_build_cid_fontname(PRT_PS_FONT_BOLD,
mbfont_opts[OPT_MBFONT_BOLD].string,
mbfont_opts[OPT_MBFONT_BOLD].strlen);
-
}
if (mbfont_opts[OPT_MBFONT_OBLIQUE].present) {
prt_build_cid_fontname(PRT_PS_FONT_OBLIQUE,
@@ -2221,8 +2267,8 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit)
// Check if need to use Courier for ASCII code range, and if so pick up
// the encoding to use
prt_use_courier = (
- mbfont_opts[OPT_MBFONT_USECOURIER].present
- && (TOLOWER_ASC(mbfont_opts[OPT_MBFONT_USECOURIER].string[0]) == 'y'));
+ mbfont_opts[OPT_MBFONT_USECOURIER].present
+ && (TOLOWER_ASC(mbfont_opts[OPT_MBFONT_USECOURIER].string[0]) == 'y'));
if (prt_use_courier) {
// Use national ASCII variant unless ASCII wanted
if (mbfont_opts[OPT_MBFONT_ASCII].present
@@ -2252,13 +2298,16 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit)
paper_name = "A4";
paper_strlen = 2;
}
- for (i = 0; i < (int)PRT_MEDIASIZE_LEN; ++i)
+ for (i = 0; i < (int)PRT_MEDIASIZE_LEN; ++i) {
if (STRLEN(prt_mediasize[i].name) == (unsigned)paper_strlen
&& STRNICMP(prt_mediasize[i].name, paper_name,
- paper_strlen) == 0)
+ paper_strlen) == 0) {
break;
- if (i == PRT_MEDIASIZE_LEN)
+ }
+ }
+ if (i == PRT_MEDIASIZE_LEN) {
i = 0;
+ }
prt_media = i;
/*
@@ -2280,7 +2329,7 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit)
// needs to be done before the cpl and lpp are calculated.
double left, right, top, bottom;
prt_page_margins(prt_page_width, prt_page_height, &left, &right, &top,
- &bottom);
+ &bottom);
prt_left_margin = left;
prt_right_margin = right;
prt_top_margin = top;
@@ -2290,9 +2339,11 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit)
* Set up the font size.
*/
fontsize = PRT_PS_DEFAULT_FONTSIZE;
- for (p = p_pfn; (p = vim_strchr(p, ':')) != NULL; ++p)
- if (p[1] == 'h' && ascii_isdigit(p[2]))
+ for (p = p_pfn; (p = vim_strchr(p, ':')) != NULL; ++p) {
+ if (p[1] == 'h' && ascii_isdigit(p[2])) {
fontsize = atoi((char *)p + 2);
+ }
+ }
prt_font_metrics(fontsize);
/*
@@ -2340,8 +2391,9 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit)
prt_duplex = FALSE;
psettings->duplex = 0;
} else if (STRNICMP(printer_opts[OPT_PRINT_DUPLEX].string, "short", 5)
- == 0)
+ == 0) {
prt_tumble = TRUE;
+ }
}
// For now user abort not supported
@@ -2369,8 +2421,9 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit)
}
prt_bufsiz = psettings->chars_per_line;
- if (prt_out_mbyte)
+ if (prt_out_mbyte) {
prt_bufsiz *= 2;
+ }
ga_init(&prt_ps_buffer, (int)sizeof(char), prt_bufsiz);
prt_page_num = 0;
@@ -2389,7 +2442,7 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit)
static int prt_add_resource(struct prt_ps_resource_S *resource)
{
- FILE* fd_resource;
+ FILE * fd_resource;
char_u resource_buffer[512];
size_t bytes_read;
@@ -2398,22 +2451,31 @@ static int prt_add_resource(struct prt_ps_resource_S *resource)
EMSG2(_("E456: Can't open file \"%s\""), resource->filename);
return FALSE;
}
- prt_dsc_resources("BeginResource", prt_resource_types[resource->type],
- (char *)resource->title);
+ switch (resource->type) {
+ case PRT_RESOURCE_TYPE_PROCSET:
+ case PRT_RESOURCE_TYPE_ENCODING:
+ case PRT_RESOURCE_TYPE_CMAP:
+ prt_dsc_resources("BeginResource", prt_resource_types[resource->type],
+ (char *)resource->title);
+ break;
+ default:
+ return FALSE;
+ }
prt_dsc_textline("BeginDocument", (char *)resource->filename);
for (;; ) {
bytes_read = fread((char *)resource_buffer, sizeof(char_u),
- sizeof(resource_buffer), fd_resource);
+ sizeof(resource_buffer), fd_resource);
if (ferror(fd_resource)) {
EMSG2(_("E457: Can't read PostScript resource file \"%s\""),
- resource->filename);
+ resource->filename);
fclose(fd_resource);
return FALSE;
}
- if (bytes_read == 0)
+ if (bytes_read == 0) {
break;
+ }
prt_write_file_raw_len(resource_buffer, bytes_read);
if (prt_file_error) {
fclose(fd_resource);
@@ -2439,8 +2501,8 @@ int mch_print_begin(prt_settings_T *psettings)
struct prt_ps_resource_S res_prolog;
struct prt_ps_resource_S res_encoding;
char buffer[256];
- char_u *p_encoding;
- char_u *p;
+ char_u *p_encoding;
+ char_u *p;
struct prt_ps_resource_S res_cidfont;
struct prt_ps_resource_S res_cmap;
int retval = FALSE;
@@ -2460,8 +2522,9 @@ int mch_print_begin(prt_settings_T *psettings)
char *p_time = os_ctime(ctime_buf, sizeof(ctime_buf));
// Note: os_ctime() adds a \n so we have to remove it :-(
p = vim_strchr((char_u *)p_time, '\n');
- if (p != NULL)
+ if (p != NULL) {
*p = NUL;
+ }
prt_dsc_textline("CreationDate", p_time);
prt_dsc_textline("DocumentData", "Clean8Bit");
prt_dsc_textline("Orientation", "Portrait");
@@ -2471,8 +2534,8 @@ int mch_print_begin(prt_settings_T *psettings)
* user coordinate system! We have to recalculate right and bottom
* coordinates based on the font metrics for the bbox to be accurate. */
prt_page_margins(prt_mediasize[prt_media].width,
- prt_mediasize[prt_media].height,
- &left, &right, &top, &bottom);
+ prt_mediasize[prt_media].height,
+ &left, &right, &top, &bottom);
bbox[0] = (int)left;
if (prt_portrait) {
/* In portrait printing the fixed point is the top left corner so we
@@ -2507,9 +2570,10 @@ int mch_print_begin(prt_settings_T *psettings)
}
if (prt_out_mbyte) {
prt_dsc_font_resource((prt_use_courier ? NULL
- : "DocumentNeededResources"), &prt_ps_mb_font);
- if (!prt_custom_cmap)
+ : "DocumentNeededResources"), &prt_ps_mb_font);
+ if (!prt_custom_cmap) {
prt_dsc_resources(NULL, "cmap", prt_cmap);
+ }
}
// Search for external resources VIM supplies
@@ -2517,20 +2581,24 @@ int mch_print_begin(prt_settings_T *psettings)
EMSG(_("E456: Can't find PostScript resource file \"prolog.ps\""));
return FALSE;
}
- if (!prt_open_resource(&res_prolog))
+ if (!prt_open_resource(&res_prolog)) {
return FALSE;
- if (!prt_check_resource(&res_prolog, PRT_PROLOG_VERSION))
+ }
+ if (!prt_check_resource(&res_prolog, PRT_PROLOG_VERSION)) {
return FALSE;
+ }
if (prt_out_mbyte) {
// Look for required version of multi-byte printing procset
if (!prt_find_resource("cidfont", &res_cidfont)) {
EMSG(_("E456: Can't find PostScript resource file \"cidfont.ps\""));
return FALSE;
}
- if (!prt_open_resource(&res_cidfont))
+ if (!prt_open_resource(&res_cidfont)) {
return FALSE;
- if (!prt_check_resource(&res_cidfont, PRT_CID_PROLOG_VERSION))
+ }
+ if (!prt_check_resource(&res_cidfont, PRT_CID_PROLOG_VERSION)) {
return FALSE;
+ }
}
/* Find an encoding to use for printing.
@@ -2554,28 +2622,31 @@ int mch_print_begin(prt_settings_T *psettings)
p_encoding = (char_u *)"latin1";
if (!prt_find_resource((char *)p_encoding, &res_encoding)) {
EMSG2(_("E456: Can't find PostScript resource file \"%s.ps\""),
- p_encoding);
+ p_encoding);
return FALSE;
}
}
}
- if (!prt_open_resource(&res_encoding))
+ if (!prt_open_resource(&res_encoding)) {
return FALSE;
+ }
/* For the moment there are no checks on encoding resource files to
* perform */
} else {
p_encoding = enc_skip(p_penc);
- if (*p_encoding == NUL)
+ if (*p_encoding == NUL) {
p_encoding = enc_skip(p_enc);
+ }
if (prt_use_courier) {
// Include ASCII range encoding vector
if (!prt_find_resource(prt_ascii_encoding, &res_encoding)) {
EMSG2(_("E456: Can't find PostScript resource file \"%s.ps\""),
- prt_ascii_encoding);
+ prt_ascii_encoding);
return FALSE;
}
- if (!prt_open_resource(&res_encoding))
+ if (!prt_open_resource(&res_encoding)) {
return FALSE;
+ }
/* For the moment there are no checks on encoding resource files to
* perform */
}
@@ -2596,11 +2667,12 @@ int mch_print_begin(prt_settings_T *psettings)
// Find user supplied CMap
if (!prt_find_resource(prt_cmap, &res_cmap)) {
EMSG2(_("E456: Can't find PostScript resource file \"%s.ps\""),
- prt_cmap);
+ prt_cmap);
return FALSE;
}
- if (!prt_open_resource(&res_cmap))
+ if (!prt_open_resource(&res_cmap)) {
return FALSE;
+ }
}
// List resources supplied
@@ -2628,8 +2700,8 @@ int mch_print_begin(prt_settings_T *psettings)
prt_dsc_resources(NULL, "encoding", buffer);
}
prt_dsc_requirements(prt_duplex, prt_tumble, prt_collate,
- psettings->do_syntax
- , prt_num_copies);
+ psettings->do_syntax
+ , prt_num_copies);
prt_dsc_noarg("EndComments");
/*
@@ -2643,9 +2715,10 @@ int mch_print_begin(prt_settings_T *psettings)
}
if (prt_out_mbyte) {
prt_dsc_font_resource((prt_use_courier ? NULL : "PageResources"),
- &prt_ps_mb_font);
- if (!prt_custom_cmap)
+ &prt_ps_mb_font);
+ if (!prt_custom_cmap) {
prt_dsc_resources(NULL, "cmap", prt_cmap);
+ }
}
// Paper will be used for all pages
@@ -2672,11 +2745,13 @@ int mch_print_begin(prt_settings_T *psettings)
}
}
- if (!prt_out_mbyte || prt_use_courier)
+ if (!prt_out_mbyte || prt_use_courier) {
/* There will be only one Roman font encoding to be included in the PS
* file. */
- if (!prt_add_resource(&res_encoding))
+ if (!prt_add_resource(&res_encoding)) {
return FALSE;
+ }
+ }
prt_dsc_noarg("EndProlog");
@@ -2702,44 +2777,47 @@ int mch_print_begin(prt_settings_T *psettings)
if (!prt_out_mbyte || prt_use_courier) {
/* When using Courier for ASCII range when printing multi-byte, need to
* pick up ASCII encoding to use with it. */
- if (prt_use_courier)
+ if (prt_use_courier) {
p_encoding = (char_u *)prt_ascii_encoding;
+ }
prt_dsc_resources("IncludeResource", "font",
- prt_ps_courier_font.ps_fontname[PRT_PS_FONT_ROMAN]);
+ prt_ps_courier_font.ps_fontname[PRT_PS_FONT_ROMAN]);
prt_def_font("F0", (char *)p_encoding, (int)prt_line_height,
- prt_ps_courier_font.ps_fontname[PRT_PS_FONT_ROMAN]);
+ prt_ps_courier_font.ps_fontname[PRT_PS_FONT_ROMAN]);
prt_dsc_resources("IncludeResource", "font",
- prt_ps_courier_font.ps_fontname[PRT_PS_FONT_BOLD]);
+ prt_ps_courier_font.ps_fontname[PRT_PS_FONT_BOLD]);
prt_def_font("F1", (char *)p_encoding, (int)prt_line_height,
- prt_ps_courier_font.ps_fontname[PRT_PS_FONT_BOLD]);
+ prt_ps_courier_font.ps_fontname[PRT_PS_FONT_BOLD]);
prt_dsc_resources("IncludeResource", "font",
- prt_ps_courier_font.ps_fontname[PRT_PS_FONT_OBLIQUE]);
+ prt_ps_courier_font.ps_fontname[PRT_PS_FONT_OBLIQUE]);
prt_def_font("F2", (char *)p_encoding, (int)prt_line_height,
- prt_ps_courier_font.ps_fontname[PRT_PS_FONT_OBLIQUE]);
+ prt_ps_courier_font.ps_fontname[PRT_PS_FONT_OBLIQUE]);
prt_dsc_resources("IncludeResource", "font",
- prt_ps_courier_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE]);
+ prt_ps_courier_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE]);
prt_def_font("F3", (char *)p_encoding, (int)prt_line_height,
- prt_ps_courier_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE]);
+ prt_ps_courier_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE]);
}
if (prt_out_mbyte) {
- /* Define the CID fonts to be used in the job. Typically CJKV fonts do
+ /* Define the CID fonts to be used in the job. Typically CJKV fonts do
* not have an italic form being a western style, so where no font is
* defined for these faces VIM falls back to an existing face.
* Note: if using Courier for the ASCII range then the printout will
* have bold/italic/bolditalic regardless of the setting of printmbfont.
*/
prt_dsc_resources("IncludeResource", "font",
- prt_ps_mb_font.ps_fontname[PRT_PS_FONT_ROMAN]);
- if (!prt_custom_cmap)
+ prt_ps_mb_font.ps_fontname[PRT_PS_FONT_ROMAN]);
+ if (!prt_custom_cmap) {
prt_dsc_resources("IncludeResource", "cmap", prt_cmap);
+ }
prt_def_cidfont("CF0", (int)prt_line_height,
- prt_ps_mb_font.ps_fontname[PRT_PS_FONT_ROMAN]);
+ prt_ps_mb_font.ps_fontname[PRT_PS_FONT_ROMAN]);
if (prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLD] != NULL) {
prt_dsc_resources("IncludeResource", "font",
- prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLD]);
- if (!prt_custom_cmap)
+ prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLD]);
+ if (!prt_custom_cmap) {
prt_dsc_resources("IncludeResource", "cmap", prt_cmap);
+ }
prt_def_cidfont("CF1", (int)prt_line_height,
prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLD]);
} else {
@@ -2748,9 +2826,10 @@ int mch_print_begin(prt_settings_T *psettings)
}
if (prt_ps_mb_font.ps_fontname[PRT_PS_FONT_OBLIQUE] != NULL) {
prt_dsc_resources("IncludeResource", "font",
- prt_ps_mb_font.ps_fontname[PRT_PS_FONT_OBLIQUE]);
- if (!prt_custom_cmap)
+ prt_ps_mb_font.ps_fontname[PRT_PS_FONT_OBLIQUE]);
+ if (!prt_custom_cmap) {
prt_dsc_resources("IncludeResource", "cmap", prt_cmap);
+ }
prt_def_cidfont("CF2", (int)prt_line_height,
prt_ps_mb_font.ps_fontname[PRT_PS_FONT_OBLIQUE]);
} else {
@@ -2759,9 +2838,10 @@ int mch_print_begin(prt_settings_T *psettings)
}
if (prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE] != NULL) {
prt_dsc_resources("IncludeResource", "font",
- prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE]);
- if (!prt_custom_cmap)
+ prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE]);
+ if (!prt_custom_cmap) {
prt_dsc_resources("IncludeResource", "cmap", prt_cmap);
+ }
prt_def_cidfont("CF3", (int)prt_line_height,
prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE]);
} else {
@@ -2772,9 +2852,9 @@ int mch_print_begin(prt_settings_T *psettings)
// Misc constant vars used for underlining and background rects
prt_def_var("UO", PRT_PS_FONT_TO_USER(prt_line_height,
- prt_ps_font->uline_offset), 2);
+ prt_ps_font->uline_offset), 2);
prt_def_var("UW", PRT_PS_FONT_TO_USER(prt_line_height,
- prt_ps_font->uline_width), 2);
+ prt_ps_font->uline_width), 2);
prt_def_var("BO", prt_bgcol_offset, 2);
prt_dsc_noarg("EndSetup");
@@ -2810,7 +2890,7 @@ void mch_print_end(prt_settings_T *psettings)
prt_message((char_u *)_("Sending to printer..."));
// Not printing to a file: use 'printexpr' to print the file.
- if (eval_printexpr((char *) prt_ps_file_name, (char *) psettings->arguments)
+ if (eval_printexpr((char *)prt_ps_file_name, (char *)psettings->arguments)
== FAIL) {
EMSG(_("E365: Failed to print PostScript file"));
} else {
@@ -2845,10 +2925,11 @@ int mch_print_begin_page(char_u *str)
prt_write_string("sv\n0 g\n");
prt_in_ascii = !prt_out_mbyte;
- if (prt_out_mbyte)
+ if (prt_out_mbyte) {
prt_write_string("CF0 sf\n");
- else
+ } else {
prt_write_string("F0 sf\n");
+ }
prt_fgcol = PRCOLOR_BLACK;
prt_bgcol = PRCOLOR_WHITE;
prt_font = PRT_PS_FONT_ROMAN;
@@ -2975,9 +3056,9 @@ int mch_print_text_out(char_u *const textp, size_t len)
b = prt_fgcol & 0xff;
prt_write_real(r / 255.0, 3);
- if (r == g && g == b)
+ if (r == g && g == b) {
prt_write_string("g\n");
- else {
+ } else {
prt_write_real(g / 255.0, 3);
prt_write_real(b / 255.0, 3);
prt_write_string("r\n");
@@ -2995,8 +3076,9 @@ int mch_print_text_out(char_u *const textp, size_t len)
}
prt_need_bgcol = false;
- if (prt_need_underline)
+ if (prt_need_underline) {
prt_do_underline = prt_underline;
+ }
prt_need_underline = false;
prt_attribute_change = false;
@@ -3034,14 +3116,22 @@ int mch_print_text_out(char_u *const textp, size_t len)
*/
ga_append(&prt_ps_buffer, '\\');
switch (ch) {
- case BS: ga_append(&prt_ps_buffer, 'b'); break;
- case TAB: ga_append(&prt_ps_buffer, 't'); break;
- case NL: ga_append(&prt_ps_buffer, 'n'); break;
- case FF: ga_append(&prt_ps_buffer, 'f'); break;
- case CAR: ga_append(&prt_ps_buffer, 'r'); break;
- case '(': ga_append(&prt_ps_buffer, '('); break;
- case ')': ga_append(&prt_ps_buffer, ')'); break;
- case '\\': ga_append(&prt_ps_buffer, '\\'); break;
+ case BS:
+ ga_append(&prt_ps_buffer, 'b'); break;
+ case TAB:
+ ga_append(&prt_ps_buffer, 't'); break;
+ case NL:
+ ga_append(&prt_ps_buffer, 'n'); break;
+ case FF:
+ ga_append(&prt_ps_buffer, 'f'); break;
+ case CAR:
+ ga_append(&prt_ps_buffer, 'r'); break;
+ case '(':
+ ga_append(&prt_ps_buffer, '('); break;
+ case ')':
+ ga_append(&prt_ps_buffer, ')'); break;
+ case '\\':
+ ga_append(&prt_ps_buffer, '\\'); break;
default:
sprintf((char *)ch_buff, "%03o", (unsigned int)ch);
@@ -3050,8 +3140,9 @@ int mch_print_text_out(char_u *const textp, size_t len)
ga_append(&prt_ps_buffer, (char)ch_buff[2]);
break;
}
- } else
+ } else {
ga_append(&prt_ps_buffer, (char)ch);
+ }
}
// Need to free any translated characters
@@ -3063,7 +3154,7 @@ int mch_print_text_out(char_u *const textp, size_t len)
// The downside of fp - use relative error on right margin check
const double next_pos = prt_pos_x + prt_char_width;
const bool need_break = (next_pos > prt_right_margin)
- && ((next_pos - prt_right_margin) > (prt_right_margin * 1e-5));
+ && ((next_pos - prt_right_margin) > (prt_right_margin * 1e-5));
if (need_break) {
prt_flush_buffer();
@@ -3072,15 +3163,16 @@ int mch_print_text_out(char_u *const textp, size_t len)
return need_break;
}
-void mch_print_set_font(const TriState iBold, const TriState iItalic,
- const TriState iUnderline)
+void mch_print_set_font(const TriState iBold, const TriState iItalic, const TriState iUnderline)
{
int font = 0;
- if (iBold)
+ if (iBold) {
font |= 0x01;
- if (iItalic)
+ }
+ if (iItalic) {
font |= 0x02;
+ }
if (font != prt_font) {
prt_font = font;
diff --git a/src/nvim/hashtab.c b/src/nvim/hashtab.c
index 526bc284a4..a8e5de839a 100644
--- a/src/nvim/hashtab.c
+++ b/src/nvim/hashtab.c
@@ -22,15 +22,15 @@
/// memory).
#include <assert.h>
+#include <inttypes.h>
#include <stdbool.h>
#include <string.h>
-#include <inttypes.h>
-#include "nvim/vim.h"
#include "nvim/ascii.h"
#include "nvim/hashtab.h"
-#include "nvim/message.h"
#include "nvim/memory.h"
+#include "nvim/message.h"
+#include "nvim/vim.h"
// Magic value for algorithm that walks through the array.
#define PERTURB_SHIFT 5
@@ -102,8 +102,7 @@ hashitem_T *hash_find(const hashtab_T *const ht, const char_u *const key)
///
/// @warning Returned pointer becomes invalid as soon as the hash table
/// is changed in any way.
-hashitem_T *hash_find_len(const hashtab_T *const ht, const char *const key,
- const size_t len)
+hashitem_T *hash_find_len(const hashtab_T *const ht, const char *const key, const size_t len)
{
return hash_lookup(ht, key, len, hash_hash_len(key, len));
}
@@ -119,8 +118,7 @@ hashitem_T *hash_find_len(const hashtab_T *const ht, const char *const key,
/// used for that key.
/// WARNING: Returned pointer becomes invalid as soon as the hash table
/// is changed in any way.
-hashitem_T *hash_lookup(const hashtab_T *const ht,
- const char *const key, const size_t key_len,
+hashitem_T *hash_lookup(const hashtab_T *const ht, const char *const key, const size_t key_len,
const hash_T hash)
{
#ifdef HT_DEBUG
@@ -336,7 +334,7 @@ static void hash_may_resize(hashtab_T *ht, size_t minitems)
bool newarray_is_small = newsize == HT_INIT_SIZE;
bool keep_smallarray = newarray_is_small
- && ht->ht_array == ht->ht_smallarray;
+ && ht->ht_array == ht->ht_smallarray;
// Make sure that oldarray and newarray do not overlap,
// so that copying is possible.
@@ -387,7 +385,7 @@ static void hash_may_resize(hashtab_T *ht, size_t minitems)
}
#define HASH_CYCLE_BODY(hash, p) \
- hash = hash * 101 + *p++
+ hash = hash * 101 + *p++
/// Get the hash number for a key.
///
diff --git a/src/nvim/highlight.c b/src/nvim/highlight.c
index 79e474fa2e..bb325b3f25 100644
--- a/src/nvim/highlight.c
+++ b/src/nvim/highlight.c
@@ -3,9 +3,11 @@
// highlight.c: low level code for UI and syntax highlighting
-#include "nvim/vim.h"
+#include "nvim/api/private/defs.h"
+#include "nvim/api/private/helpers.h"
#include "nvim/highlight.h"
#include "nvim/highlight_defs.h"
+#include "nvim/lua/executor.h"
#include "nvim/map.h"
#include "nvim/message.h"
#include "nvim/option.h"
@@ -13,9 +15,7 @@
#include "nvim/screen.h"
#include "nvim/syntax.h"
#include "nvim/ui.h"
-#include "nvim/api/private/defs.h"
-#include "nvim/api/private/helpers.h"
-#include "nvim/lua/executor.h"
+#include "nvim/vim.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "highlight.c.generated.h"
@@ -25,28 +25,22 @@ static bool hlstate_active = false;
static kvec_t(HlEntry) attr_entries = KV_INITIAL_VALUE;
-static Map(HlEntry, int) *attr_entry_ids;
-static Map(int, int) *combine_attr_entries;
-static Map(int, int) *blend_attr_entries;
-static Map(int, int) *blendthrough_attr_entries;
+static Map(HlEntry, int) attr_entry_ids = MAP_INIT;
+static Map(int, int) combine_attr_entries = MAP_INIT;
+static Map(int, int) blend_attr_entries = MAP_INIT;
+static Map(int, int) blendthrough_attr_entries = MAP_INIT;
/// highlight entries private to a namespace
-static Map(ColorKey, ColorItem) *ns_hl;
+static Map(ColorKey, ColorItem) ns_hl;
void highlight_init(void)
{
- attr_entry_ids = map_new(HlEntry, int)();
- combine_attr_entries = map_new(int, int)();
- blend_attr_entries = map_new(int, int)();
- blendthrough_attr_entries = map_new(int, int)();
- ns_hl = map_new(ColorKey, ColorItem)();
-
// index 0 is no attribute, add dummy entry:
kv_push(attr_entries, ((HlEntry){ .attr = HLATTRS_INIT, .kind = kHlUnknown,
.id1 = 0, .id2 = 0 }));
}
-/// @return TRUE if hl table was reset
+/// @return true if hl table was reset
bool highlight_use_hlstate(void)
{
if (hlstate_active) {
@@ -71,7 +65,7 @@ static int get_attr_entry(HlEntry entry)
entry.id2 = 0;
}
- int id = map_get(HlEntry, int)(attr_entry_ids, entry);
+ int id = map_get(HlEntry, int)(&attr_entry_ids, entry);
if (id > 0) {
return id;
}
@@ -104,7 +98,7 @@ static int get_attr_entry(HlEntry entry)
id = (int)next_id;
kv_push(attr_entries, entry);
- map_put(HlEntry, int)(attr_entry_ids, entry, id);
+ map_put(HlEntry, int)(&attr_entry_ids, entry, id);
Array inspect = hl_inspect(id);
@@ -154,7 +148,7 @@ void ns_hl_def(NS ns_id, int hl_id, HlAttrs attrs, int link_id)
{
DecorProvider *p = get_decor_provider(ns_id, true);
if ((attrs.rgb_ae_attr & HL_DEFAULT)
- && map_has(ColorKey, ColorItem)(ns_hl, ColorKey(ns_id, hl_id))) {
+ && map_has(ColorKey, ColorItem)(&ns_hl, ColorKey(ns_id, hl_id))) {
return;
}
int attr_id = link_id > 0 ? -1 : hl_get_syn_attr(ns_id, hl_id, attrs);
@@ -162,7 +156,7 @@ void ns_hl_def(NS ns_id, int hl_id, HlAttrs attrs, int link_id)
.link_id = link_id,
.version = p->hl_valid,
.is_default = (attrs.rgb_ae_attr & HL_DEFAULT) };
- map_put(ColorKey, ColorItem)(ns_hl, ColorKey(ns_id, hl_id), it);
+ map_put(ColorKey, ColorItem)(&ns_hl, ColorKey(ns_id, hl_id), it);
}
int ns_get_hl(NS ns_id, int hl_id, bool link, bool nodefault)
@@ -177,7 +171,7 @@ int ns_get_hl(NS ns_id, int hl_id, bool link, bool nodefault)
}
DecorProvider *p = get_decor_provider(ns_id, true);
- ColorItem it = map_get(ColorKey, ColorItem)(ns_hl, ColorKey(ns_id, hl_id));
+ ColorItem it = map_get(ColorKey, ColorItem)(&ns_hl, ColorKey(ns_id, hl_id));
// TODO(bfredl): map_ref true even this?
bool valid_cache = it.version >= p->hl_valid;
@@ -220,7 +214,7 @@ int ns_get_hl(NS ns_id, int hl_id, bool link, bool nodefault)
it.attr_id = fallback ? -1 : hl_get_syn_attr((int)ns_id, hl_id, attrs);
it.version = p->hl_valid-tmp;
it.is_default = attrs.rgb_ae_attr & HL_DEFAULT;
- map_put(ColorKey, ColorItem)(ns_hl, ColorKey(ns_id, hl_id), it);
+ map_put(ColorKey, ColorItem)(&ns_hl, ColorKey(ns_id, hl_id), it);
}
if (it.is_default && nodefault) {
@@ -367,19 +361,19 @@ void update_window_hl(win_T *wp, bool invalid)
int hl_get_underline(void)
{
return get_attr_entry((HlEntry){
- .attr = (HlAttrs){
- .cterm_ae_attr = (int16_t)HL_UNDERLINE,
- .cterm_fg_color = 0,
- .cterm_bg_color = 0,
- .rgb_ae_attr = (int16_t)HL_UNDERLINE,
- .rgb_fg_color = -1,
- .rgb_bg_color = -1,
- .rgb_sp_color = -1,
- .hl_blend = -1,
- },
- .kind = kHlUI,
- .id1 = 0,
- .id2 = 0,
+ .attr = (HlAttrs){
+ .cterm_ae_attr = (int16_t)HL_UNDERLINE,
+ .cterm_fg_color = 0,
+ .cterm_bg_color = 0,
+ .rgb_ae_attr = (int16_t)HL_UNDERLINE,
+ .rgb_fg_color = -1,
+ .rgb_bg_color = -1,
+ .rgb_sp_color = -1,
+ .hl_blend = -1,
+ },
+ .kind = kHlUI,
+ .id1 = 0,
+ .id2 = 0,
});
}
@@ -395,28 +389,28 @@ void clear_hl_tables(bool reinit)
{
if (reinit) {
kv_size(attr_entries) = 1;
- map_clear(HlEntry, int)(attr_entry_ids);
- map_clear(int, int)(combine_attr_entries);
- map_clear(int, int)(blend_attr_entries);
- map_clear(int, int)(blendthrough_attr_entries);
+ map_clear(HlEntry, int)(&attr_entry_ids);
+ map_clear(int, int)(&combine_attr_entries);
+ map_clear(int, int)(&blend_attr_entries);
+ map_clear(int, int)(&blendthrough_attr_entries);
memset(highlight_attr_last, -1, sizeof(highlight_attr_last));
highlight_attr_set_all();
highlight_changed();
screen_invalidate_highlights();
} else {
kv_destroy(attr_entries);
- map_free(HlEntry, int)(attr_entry_ids);
- map_free(int, int)(combine_attr_entries);
- map_free(int, int)(blend_attr_entries);
- map_free(int, int)(blendthrough_attr_entries);
- map_free(ColorKey, ColorItem)(ns_hl);
+ map_destroy(HlEntry, int)(&attr_entry_ids);
+ map_destroy(int, int)(&combine_attr_entries);
+ map_destroy(int, int)(&blend_attr_entries);
+ map_destroy(int, int)(&blendthrough_attr_entries);
+ map_destroy(ColorKey, ColorItem)(&ns_hl);
}
}
void hl_invalidate_blends(void)
{
- map_clear(int, int)(blend_attr_entries);
- map_clear(int, int)(blendthrough_attr_entries);
+ map_clear(int, int)(&blend_attr_entries);
+ map_clear(int, int)(&blendthrough_attr_entries);
highlight_changed();
update_window_hl(curwin, true);
}
@@ -437,7 +431,7 @@ int hl_combine_attr(int char_attr, int prim_attr)
// TODO(bfredl): could use a struct for clearer intent.
int combine_tag = (char_attr << 16) + prim_attr;
- int id = map_get(int, int)(combine_attr_entries, combine_tag);
+ int id = map_get(int, int)(&combine_attr_entries, combine_tag);
if (id > 0) {
return id;
}
@@ -494,7 +488,7 @@ int hl_combine_attr(int char_attr, int prim_attr)
id = get_attr_entry((HlEntry){ .attr = new_en, .kind = kHlCombine,
.id1 = char_attr, .id2 = prim_attr });
if (id > 0) {
- map_put(int, int)(combine_attr_entries, combine_tag, id);
+ map_put(int, int)(&combine_attr_entries, combine_tag, id);
}
return id;
@@ -550,8 +544,8 @@ int hl_blend_attrs(int back_attr, int front_attr, bool *through)
int combine_tag = (back_attr << 16) + front_attr;
Map(int, int) *map = (*through
- ? blendthrough_attr_entries
- : blend_attr_entries);
+ ? &blendthrough_attr_entries
+ : &blend_attr_entries);
int id = map_get(int, int)(map, combine_tag);
if (id > 0) {
return id;
@@ -654,23 +648,23 @@ static int hl_cterm2rgb_color(int nr)
};
static char_u ansi_table[16][4] = {
// R G B idx
- { 0, 0, 0, 1 } , // black
- { 224, 0, 0, 2 } , // dark red
- { 0, 224, 0, 3 } , // dark green
- { 224, 224, 0, 4 } , // dark yellow / brown
- { 0, 0, 224, 5 } , // dark blue
- { 224, 0, 224, 6 } , // dark magenta
- { 0, 224, 224, 7 } , // dark cyan
- { 224, 224, 224, 8 } , // light grey
-
- { 128, 128, 128, 9 } , // dark grey
- { 255, 64, 64, 10 } , // light red
- { 64, 255, 64, 11 } , // light green
- { 255, 255, 64, 12 } , // yellow
- { 64, 64, 255, 13 } , // light blue
- { 255, 64, 255, 14 } , // light magenta
- { 64, 255, 255, 15 } , // light cyan
- { 255, 255, 255, 16 } , // white
+ { 0, 0, 0, 1 }, // black
+ { 224, 0, 0, 2 }, // dark red
+ { 0, 224, 0, 3 }, // dark green
+ { 224, 224, 0, 4 }, // dark yellow / brown
+ { 0, 0, 224, 5 }, // dark blue
+ { 224, 0, 224, 6 }, // dark magenta
+ { 0, 224, 224, 7 }, // dark cyan
+ { 224, 224, 224, 8 }, // light grey
+
+ { 128, 128, 128, 9 }, // dark grey
+ { 255, 64, 64, 10 }, // light red
+ { 64, 255, 64, 11 }, // light green
+ { 255, 255, 64, 12 }, // yellow
+ { 64, 64, 255, 13 }, // light blue
+ { 255, 64, 255, 14 }, // light magenta
+ { 64, 255, 255, 15 }, // light cyan
+ { 255, 255, 255, 16 }, // white
};
int r = 0;
@@ -796,7 +790,7 @@ Dictionary hlattrs2dict(HlAttrs ae, bool use_rgb)
}
if (ae.hl_blend > -1) {
- PUT(hl, "blend", INTEGER_OBJ(ae.hl_blend));
+ PUT(hl, "blend", INTEGER_OBJ(ae.hl_blend));
}
return hl;
@@ -853,7 +847,7 @@ HlAttrs dict2hlattrs(Dictionary dict, bool use_rgb, int *link_id, Error *err)
err)) {
cterm_mask |= flags[m].flag;
}
- break;
+ break;
}
}
}
@@ -921,9 +915,9 @@ HlAttrs dict2hlattrs(Dictionary dict, bool use_rgb, int *link_id, Error *err)
hlattrs.rgb_fg_color = fg;
hlattrs.rgb_sp_color = sp;
hlattrs.cterm_bg_color =
- ctermbg == -1 ? cterm_normal_bg_color : ctermbg + 1;
+ ctermbg == -1 ? cterm_normal_bg_color : ctermbg + 1;
hlattrs.cterm_fg_color =
- ctermfg == -1 ? cterm_normal_fg_color : ctermfg + 1;
+ ctermfg == -1 ? cterm_normal_fg_color : ctermfg + 1;
hlattrs.cterm_ae_attr = cterm_mask;
} else {
hlattrs.cterm_ae_attr = cterm_mask;
@@ -951,34 +945,34 @@ static void hl_inspect_impl(Array *arr, int attr)
HlEntry e = kv_A(attr_entries, attr);
switch (e.kind) {
- case kHlSyntax:
- PUT(item, "kind", STRING_OBJ(cstr_to_string("syntax")));
- PUT(item, "hi_name",
- STRING_OBJ(cstr_to_string((char *)syn_id2name(e.id1))));
- break;
-
- case kHlUI:
- PUT(item, "kind", STRING_OBJ(cstr_to_string("ui")));
- const char *ui_name = (e.id1 == -1) ? "Normal" : hlf_names[e.id1];
- PUT(item, "ui_name", STRING_OBJ(cstr_to_string(ui_name)));
- PUT(item, "hi_name",
- STRING_OBJ(cstr_to_string((char *)syn_id2name(e.id2))));
- break;
-
- case kHlTerminal:
- PUT(item, "kind", STRING_OBJ(cstr_to_string("term")));
- break;
-
- case kHlCombine:
- case kHlBlend:
- case kHlBlendThrough:
- // attribute combination is associative, so flatten to an array
- hl_inspect_impl(arr, e.id1);
- hl_inspect_impl(arr, e.id2);
- return;
-
- case kHlUnknown:
- return;
+ case kHlSyntax:
+ PUT(item, "kind", STRING_OBJ(cstr_to_string("syntax")));
+ PUT(item, "hi_name",
+ STRING_OBJ(cstr_to_string((char *)syn_id2name(e.id1))));
+ break;
+
+ case kHlUI:
+ PUT(item, "kind", STRING_OBJ(cstr_to_string("ui")));
+ const char *ui_name = (e.id1 == -1) ? "Normal" : hlf_names[e.id1];
+ PUT(item, "ui_name", STRING_OBJ(cstr_to_string(ui_name)));
+ PUT(item, "hi_name",
+ STRING_OBJ(cstr_to_string((char *)syn_id2name(e.id2))));
+ break;
+
+ case kHlTerminal:
+ PUT(item, "kind", STRING_OBJ(cstr_to_string("term")));
+ break;
+
+ case kHlCombine:
+ case kHlBlend:
+ case kHlBlendThrough:
+ // attribute combination is associative, so flatten to an array
+ hl_inspect_impl(arr, e.id1);
+ hl_inspect_impl(arr, e.id2);
+ return;
+
+ case kHlUnknown:
+ return;
}
PUT(item, "id", INTEGER_OBJ(attr));
ADD(*arr, DICTIONARY_OBJ(item));
diff --git a/src/nvim/highlight_defs.h b/src/nvim/highlight_defs.h
index ed4aefb577..a0e8bad11f 100644
--- a/src/nvim/highlight_defs.h
+++ b/src/nvim/highlight_defs.h
@@ -63,7 +63,9 @@ typedef enum {
, HLF_M // "--More--" message
, HLF_CM // Mode (e.g., "-- INSERT --")
, HLF_N // line number for ":number" and ":#" commands
- , HLF_CLN // current line number
+ , HLF_LNA // LineNrAbove
+ , HLF_LNB // LineNrBelow
+ , HLF_CLN // current line number when 'cursorline' is set
, HLF_R // return to continue message and yes/no questions
, HLF_S // status lines
, HLF_SNC // status lines of not-current windows
@@ -118,6 +120,8 @@ EXTERN const char *hlf_names[] INIT(= {
[HLF_M] = "MoreMsg",
[HLF_CM] = "ModeMsg",
[HLF_N] = "LineNr",
+ [HLF_LNA] = "LineNrAbove",
+ [HLF_LNB] = "LineNrBelow",
[HLF_CLN] = "CursorLineNr",
[HLF_R] = "Question",
[HLF_S] = "StatusLine",
diff --git a/src/nvim/indent.c b/src/nvim/indent.c
index 8fa61515ef..a3ee3983e5 100644
--- a/src/nvim/indent.c
+++ b/src/nvim/indent.c
@@ -7,24 +7,25 @@
#include "nvim/ascii.h"
#include "nvim/assert.h"
+#include "nvim/buffer.h"
#include "nvim/change.h"
-#include "nvim/indent.h"
-#include "nvim/eval.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
-#include "nvim/mark.h"
+#include "nvim/eval.h"
#include "nvim/extmark.h"
+#include "nvim/indent.h"
+#include "nvim/mark.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/misc1.h"
#include "nvim/move.h"
#include "nvim/option.h"
+#include "nvim/plines.h"
#include "nvim/regexp.h"
#include "nvim/screen.h"
#include "nvim/search.h"
#include "nvim/strings.h"
#include "nvim/undo.h"
-#include "nvim/buffer.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -62,10 +63,10 @@ int get_indent_buf(buf_T *buf, linenr_T lnum)
}
-// Count the size (in window cells) of the indent in line "ptr", with
-// 'tabstop' at "ts".
-// If @param list is TRUE, count only screen size for tabs.
-int get_indent_str(const char_u *ptr, int ts, int list)
+/// Count the size (in window cells) of the indent in line "ptr", with
+/// 'tabstop' at "ts".
+/// If @param list is true, count only screen size for tabs.
+int get_indent_str(const char_u *ptr, int ts, bool list)
FUNC_ATTR_NONNULL_ALL
{
int count = 0;
@@ -91,9 +92,9 @@ int get_indent_str(const char_u *ptr, int ts, int list)
return count;
}
-// Count the size (in window cells) of the indent in line "ptr", using
-// variable tabstops.
-// if "list" is true, count only screen size for tabs.
+/// Count the size (in window cells) of the indent in line "ptr", using
+/// variable tabstops.
+/// if "list" is true, count only screen size for tabs.
int get_indent_str_vtab(const char_u *ptr, long ts, long *vts, bool list)
{
int count = 0;
@@ -432,7 +433,7 @@ int get_number_indent(linenr_T lnum)
// Return appropriate space number for breakindent, taking influencing
// parameters into account. Window must be specified, since it is not
// necessarily always the current one.
-int get_breakindent_win(win_T *wp, const char_u *line)
+int get_breakindent_win(win_T *wp, char_u *line)
FUNC_ATTR_NONNULL_ALL
{
static int prev_indent = 0; // Cached indent value.
@@ -443,8 +444,8 @@ int get_breakindent_win(win_T *wp, const char_u *line)
int bri = 0;
// window width minus window margin space, i.e. what rests for text
const int eff_wwidth = wp->w_width_inner
- - ((wp->w_p_nu || wp->w_p_rnu)
- && (vim_strchr(p_cpo, CPO_NUMCOL) == NULL)
+ - ((wp->w_p_nu || wp->w_p_rnu)
+ && (vim_strchr(p_cpo, CPO_NUMCOL) == NULL)
? number_width(wp) + 1 : 0);
// used cached indent, unless pointer or 'tabstop' changed
@@ -462,12 +463,33 @@ int get_breakindent_win(win_T *wp, const char_u *line)
}
bri = prev_indent + wp->w_briopt_shift;
+ // Add offset for number column, if 'n' is in 'cpoptions'
+ bri += win_col_off2(wp);
+
+ // add additional indent for numbered lists
+ if (wp->w_briopt_list != 0) {
+ regmatch_T regmatch = {
+ .regprog = vim_regcomp(curbuf->b_p_flp,
+ RE_MAGIC + RE_STRING + RE_AUTO + RE_STRICT),
+ };
+
+ if (regmatch.regprog != NULL) {
+ regmatch.rm_ic = false;
+ if (vim_regexec(&regmatch, line, 0)) {
+ if (wp->w_briopt_list > 0) {
+ bri += wp->w_briopt_list;
+ } else {
+ bri = (int)(*regmatch.endp - *regmatch.startp);
+ }
+ }
+ vim_regfree(regmatch.regprog);
+ }
+ }
+
// indent minus the length of the showbreak string
if (wp->w_briopt_sbr) {
- bri -= vim_strsize(p_sbr);
+ bri -= vim_strsize(get_showbreak_value(wp));
}
- // Add offset for number column, if 'n' is in 'cpoptions'
- bri += win_col_off2(wp);
// never indent past left window margin
if (bri < 0) {
@@ -488,7 +510,7 @@ int get_breakindent_win(win_T *wp, const char_u *line)
// the line.
int inindent(int extra)
{
- char_u *ptr;
+ char_u *ptr;
colnr_T col;
for (col = 0, ptr = get_cursor_line_ptr(); ascii_iswhite(*ptr); ++col) {
@@ -511,15 +533,14 @@ int get_expr_indent(void)
colnr_T save_curswant;
int save_set_curswant;
int save_State;
- int use_sandbox = was_set_insecurely(
- curwin, (char_u *)"indentexpr", OPT_LOCAL);
+ int use_sandbox = was_set_insecurely(curwin, (char_u *)"indentexpr", OPT_LOCAL);
// Save and restore cursor position and curswant, in case it was changed
// * via :normal commands.
save_pos = curwin->w_cursor;
save_curswant = curwin->w_curswant;
save_set_curswant = curwin->w_set_curswant;
- set_vim_var_nr(VV_LNUM, (varnumber_T) curwin->w_cursor.lnum);
+ set_vim_var_nr(VV_LNUM, (varnumber_T)curwin->w_cursor.lnum);
if (use_sandbox) {
sandbox++;
@@ -700,11 +721,11 @@ int get_lisp_indent(void)
quotecount = 0;
if (vi_lisp || ((*that != '"') && (*that != '\'')
- && (*that != '#') && ((*that < '0') || (*that > '9')))) {
+ && (*that != '#') && ((*that < '0') || (*that > '9')))) {
while (*that
&& (!ascii_iswhite(*that) || quotecount || parencount)
&& (!((*that == '(' || *that == '[')
- && !quotecount && !parencount && vi_lisp))) {
+ && !quotecount && !parencount && vi_lisp))) {
if (*that == '"') {
quotecount = !quotecount;
}
diff --git a/src/nvim/keymap.c b/src/nvim/keymap.c
index 6dacace0a4..b724d82f7c 100644
--- a/src/nvim/keymap.c
+++ b/src/nvim/keymap.c
@@ -5,16 +5,16 @@
#include <inttypes.h>
#include <limits.h>
-#include "nvim/vim.h"
#include "nvim/ascii.h"
-#include "nvim/keymap.h"
#include "nvim/charset.h"
-#include "nvim/memory.h"
#include "nvim/edit.h"
#include "nvim/eval.h"
+#include "nvim/keymap.h"
+#include "nvim/memory.h"
#include "nvim/message.h"
-#include "nvim/strings.h"
#include "nvim/mouse.h"
+#include "nvim/strings.h"
+#include "nvim/vim.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "keymap.c.generated.h"
@@ -51,48 +51,48 @@ static const struct modmasktable {
static char_u modifier_keys_table[] =
{
- /* mod mask with modifier without modifier */
- MOD_MASK_SHIFT, '&', '9', '@', '1', /* begin */
- MOD_MASK_SHIFT, '&', '0', '@', '2', /* cancel */
- MOD_MASK_SHIFT, '*', '1', '@', '4', /* command */
- MOD_MASK_SHIFT, '*', '2', '@', '5', /* copy */
- MOD_MASK_SHIFT, '*', '3', '@', '6', /* create */
- MOD_MASK_SHIFT, '*', '4', 'k', 'D', /* delete char */
- MOD_MASK_SHIFT, '*', '5', 'k', 'L', /* delete line */
- MOD_MASK_SHIFT, '*', '7', '@', '7', /* end */
- MOD_MASK_CTRL, KS_EXTRA, (int)KE_C_END, '@', '7', /* end */
- MOD_MASK_SHIFT, '*', '9', '@', '9', /* exit */
- MOD_MASK_SHIFT, '*', '0', '@', '0', /* find */
- MOD_MASK_SHIFT, '#', '1', '%', '1', /* help */
- MOD_MASK_SHIFT, '#', '2', 'k', 'h', /* home */
- MOD_MASK_CTRL, KS_EXTRA, (int)KE_C_HOME, 'k', 'h', /* home */
- MOD_MASK_SHIFT, '#', '3', 'k', 'I', /* insert */
- MOD_MASK_SHIFT, '#', '4', 'k', 'l', /* left arrow */
- MOD_MASK_CTRL, KS_EXTRA, (int)KE_C_LEFT, 'k', 'l', /* left arrow */
- MOD_MASK_SHIFT, '%', 'a', '%', '3', /* message */
- MOD_MASK_SHIFT, '%', 'b', '%', '4', /* move */
- MOD_MASK_SHIFT, '%', 'c', '%', '5', /* next */
- MOD_MASK_SHIFT, '%', 'd', '%', '7', /* options */
- MOD_MASK_SHIFT, '%', 'e', '%', '8', /* previous */
- MOD_MASK_SHIFT, '%', 'f', '%', '9', /* print */
- MOD_MASK_SHIFT, '%', 'g', '%', '0', /* redo */
- MOD_MASK_SHIFT, '%', 'h', '&', '3', /* replace */
- MOD_MASK_SHIFT, '%', 'i', 'k', 'r', /* right arr. */
- MOD_MASK_CTRL, KS_EXTRA, (int)KE_C_RIGHT, 'k', 'r', /* right arr. */
- MOD_MASK_SHIFT, '%', 'j', '&', '5', /* resume */
- MOD_MASK_SHIFT, '!', '1', '&', '6', /* save */
- MOD_MASK_SHIFT, '!', '2', '&', '7', /* suspend */
- MOD_MASK_SHIFT, '!', '3', '&', '8', /* undo */
- MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_UP, 'k', 'u', /* up arrow */
- MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_DOWN, 'k', 'd', /* down arrow */
-
- /* vt100 F1 */
+ // mod mask with modifier without modifier
+ MOD_MASK_SHIFT, '&', '9', '@', '1', // begin
+ MOD_MASK_SHIFT, '&', '0', '@', '2', // cancel
+ MOD_MASK_SHIFT, '*', '1', '@', '4', // command
+ MOD_MASK_SHIFT, '*', '2', '@', '5', // copy
+ MOD_MASK_SHIFT, '*', '3', '@', '6', // create
+ MOD_MASK_SHIFT, '*', '4', 'k', 'D', // delete char
+ MOD_MASK_SHIFT, '*', '5', 'k', 'L', // delete line
+ MOD_MASK_SHIFT, '*', '7', '@', '7', // end
+ MOD_MASK_CTRL, KS_EXTRA, (int)KE_C_END, '@', '7', // end
+ MOD_MASK_SHIFT, '*', '9', '@', '9', // exit
+ MOD_MASK_SHIFT, '*', '0', '@', '0', // find
+ MOD_MASK_SHIFT, '#', '1', '%', '1', // help
+ MOD_MASK_SHIFT, '#', '2', 'k', 'h', // home
+ MOD_MASK_CTRL, KS_EXTRA, (int)KE_C_HOME, 'k', 'h', // home
+ MOD_MASK_SHIFT, '#', '3', 'k', 'I', // insert
+ MOD_MASK_SHIFT, '#', '4', 'k', 'l', // left arrow
+ MOD_MASK_CTRL, KS_EXTRA, (int)KE_C_LEFT, 'k', 'l', // left arrow
+ MOD_MASK_SHIFT, '%', 'a', '%', '3', // message
+ MOD_MASK_SHIFT, '%', 'b', '%', '4', // move
+ MOD_MASK_SHIFT, '%', 'c', '%', '5', // next
+ MOD_MASK_SHIFT, '%', 'd', '%', '7', // options
+ MOD_MASK_SHIFT, '%', 'e', '%', '8', // previous
+ MOD_MASK_SHIFT, '%', 'f', '%', '9', // print
+ MOD_MASK_SHIFT, '%', 'g', '%', '0', // redo
+ MOD_MASK_SHIFT, '%', 'h', '&', '3', // replace
+ MOD_MASK_SHIFT, '%', 'i', 'k', 'r', // right arr.
+ MOD_MASK_CTRL, KS_EXTRA, (int)KE_C_RIGHT, 'k', 'r', // right arr.
+ MOD_MASK_SHIFT, '%', 'j', '&', '5', // resume
+ MOD_MASK_SHIFT, '!', '1', '&', '6', // save
+ MOD_MASK_SHIFT, '!', '2', '&', '7', // suspend
+ MOD_MASK_SHIFT, '!', '3', '&', '8', // undo
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_UP, 'k', 'u', // up arrow
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_DOWN, 'k', 'd', // down arrow
+
+ // vt100 F1
MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_XF1, KS_EXTRA, (int)KE_XF1,
MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_XF2, KS_EXTRA, (int)KE_XF2,
MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_XF3, KS_EXTRA, (int)KE_XF3,
MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_XF4, KS_EXTRA, (int)KE_XF4,
- MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F1, 'k', '1', /* F1 */
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F1, 'k', '1', // F1
MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F2, 'k', '2',
MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F3, 'k', '3',
MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F4, 'k', '4',
@@ -101,7 +101,7 @@ static char_u modifier_keys_table[] =
MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F7, 'k', '7',
MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F8, 'k', '8',
MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F9, 'k', '9',
- MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F10, 'k', ';', /* F10 */
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F10, 'k', ';', // F10
MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F11, 'F', '1',
MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F12, 'F', '2',
@@ -133,7 +133,7 @@ static char_u modifier_keys_table[] =
MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F36, 'F', 'Q',
MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F37, 'F', 'R',
- /* TAB pseudo code*/
+ // TAB pseudo code
MOD_MASK_SHIFT, 'k', 'B', KS_EXTRA, (int)KE_TAB,
NUL
@@ -397,22 +397,38 @@ int handle_x_keys(const int key)
FUNC_ATTR_CONST FUNC_ATTR_WARN_UNUSED_RESULT
{
switch (key) {
- case K_XUP: return K_UP;
- case K_XDOWN: return K_DOWN;
- case K_XLEFT: return K_LEFT;
- case K_XRIGHT: return K_RIGHT;
- case K_XHOME: return K_HOME;
- case K_ZHOME: return K_HOME;
- case K_XEND: return K_END;
- case K_ZEND: return K_END;
- case K_XF1: return K_F1;
- case K_XF2: return K_F2;
- case K_XF3: return K_F3;
- case K_XF4: return K_F4;
- case K_S_XF1: return K_S_F1;
- case K_S_XF2: return K_S_F2;
- case K_S_XF3: return K_S_F3;
- case K_S_XF4: return K_S_F4;
+ case K_XUP:
+ return K_UP;
+ case K_XDOWN:
+ return K_DOWN;
+ case K_XLEFT:
+ return K_LEFT;
+ case K_XRIGHT:
+ return K_RIGHT;
+ case K_XHOME:
+ return K_HOME;
+ case K_ZHOME:
+ return K_HOME;
+ case K_XEND:
+ return K_END;
+ case K_ZEND:
+ return K_END;
+ case K_XF1:
+ return K_F1;
+ case K_XF2:
+ return K_F2;
+ case K_XF3:
+ return K_F3;
+ case K_XF4:
+ return K_F4;
+ case K_S_XF1:
+ return K_S_F1;
+ case K_S_XF2:
+ return K_S_F2;
+ case K_S_XF3:
+ return K_S_F3;
+ case K_S_XF4:
+ return K_S_F4;
}
return key;
}
@@ -427,31 +443,33 @@ char_u *get_special_key_name(int c, int modifiers)
int i, idx;
int table_idx;
- char_u *s;
+ char_u *s;
string[0] = '<';
idx = 1;
- /* Key that stands for a normal character. */
- if (IS_SPECIAL(c) && KEY2TERMCAP0(c) == KS_KEY)
+ // Key that stands for a normal character.
+ if (IS_SPECIAL(c) && KEY2TERMCAP0(c) == KS_KEY) {
c = KEY2TERMCAP1(c);
+ }
/*
* Translate shifted special keys into unshifted keys and set modifier.
* Same for CTRL and ALT modifiers.
*/
if (IS_SPECIAL(c)) {
- for (i = 0; modifier_keys_table[i] != 0; i += MOD_KEYS_ENTRY_SIZE)
- if ( KEY2TERMCAP0(c) == (int)modifier_keys_table[i + 1]
- && (int)KEY2TERMCAP1(c) == (int)modifier_keys_table[i + 2]) {
+ for (i = 0; modifier_keys_table[i] != 0; i += MOD_KEYS_ENTRY_SIZE) {
+ if (KEY2TERMCAP0(c) == (int)modifier_keys_table[i + 1]
+ && (int)KEY2TERMCAP1(c) == (int)modifier_keys_table[i + 2]) {
modifiers |= modifier_keys_table[i];
c = TERMCAP2KEY(modifier_keys_table[i + 3],
- modifier_keys_table[i + 4]);
+ modifier_keys_table[i + 4]);
break;
}
+ }
}
- /* try to find the key in the special key table */
+ // try to find the key in the special key table
table_idx = find_special_key_in_table(c);
/*
@@ -459,14 +477,13 @@ char_u *get_special_key_name(int c, int modifiers)
* extract modifiers.
*/
if (c > 0
- && (*mb_char2len)(c) == 1
- ) {
+ && (*mb_char2len)(c) == 1) {
if (table_idx < 0
&& (!vim_isprintc(c) || (c & 0x7f) == ' ')
&& (c & 0x80)) {
c &= 0x7f;
modifiers |= MOD_MASK_ALT;
- /* try again, to find the un-alted key in the special key table */
+ // try again, to find the un-alted key in the special key table
table_idx = find_special_key_in_table(c);
}
if (table_idx < 0 && !vim_isprintc(c) && c < ' ') {
@@ -475,15 +492,16 @@ char_u *get_special_key_name(int c, int modifiers)
}
}
- /* translate the modifier into a string */
- for (i = 0; mod_mask_table[i].name != 'A'; i++)
+ // translate the modifier into a string
+ for (i = 0; mod_mask_table[i].name != 'A'; i++) {
if ((modifiers & mod_mask_table[i].mod_mask)
== mod_mask_table[i].mod_flag) {
string[idx++] = mod_mask_table[i].name;
string[idx++] = (char_u)'-';
}
+ }
- if (table_idx < 0) { /* unknown special key, may output t_xx */
+ if (table_idx < 0) { // unknown special key, may output t_xx
if (IS_SPECIAL(c)) {
string[idx++] = 't';
string[idx++] = '_';
@@ -497,16 +515,17 @@ char_u *get_special_key_name(int c, int modifiers)
string[idx++] = (char_u)c;
} else {
s = transchar(c);
- while (*s)
+ while (*s) {
string[idx++] = *s++;
+ }
}
}
} else { // use name of special key
size_t len = STRLEN(key_names_table[table_idx].name);
if ((int)len + idx + 2 <= MAX_KEY_NAME_LEN) {
- STRCPY(string + idx, key_names_table[table_idx].name);
- idx += (int)len;
+ STRCPY(string + idx, key_names_table[table_idx].name);
+ idx += (int)len;
}
}
string[idx++] = '>';
@@ -525,9 +544,8 @@ char_u *get_special_key_name(int c, int modifiers)
/// @param[in] in_string Inside a double quoted string
///
/// @return Number of characters added to dst, zero for no match.
-unsigned int trans_special(const char_u **srcp, const size_t src_len,
- char_u *const dst, const bool keycode,
- const bool in_string)
+unsigned int trans_special(const char_u **srcp, const size_t src_len, char_u *const dst,
+ const bool keycode, const bool in_string)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
int modifiers = 0;
@@ -543,7 +561,7 @@ unsigned int trans_special(const char_u **srcp, const size_t src_len,
/// Put the character sequence for "key" with "modifiers" into "dst" and return
/// the resulting length.
-/// When "keycode" is TRUE prefer key code, e.g. K_DEL instead of DEL.
+/// When "keycode" is true prefer key code, e.g. K_DEL instead of DEL.
/// The sequence is not NUL terminated.
/// This is how characters in a string are encoded.
unsigned int special_to_buf(int key, int modifiers, bool keycode, char_u *dst)
@@ -582,9 +600,8 @@ unsigned int special_to_buf(int key, int modifiers, bool keycode, char_u *dst)
/// @param[in] in_string In string, double quote is escaped
///
/// @return Key and modifiers or 0 if there is no match.
-int find_special_key(const char_u **srcp, const size_t src_len, int *const modp,
- const bool keycode, const bool keep_x_key,
- const bool in_string)
+int find_special_key(const char_u **srcp, const size_t src_len, int *const modp, const bool keycode,
+ const bool keep_x_key, const bool in_string)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
const char_u *last_dash;
@@ -628,7 +645,11 @@ int find_special_key(const char_u **srcp, const size_t src_len, int *const modp,
if (end - bp > 3 && bp[0] == 't' && bp[1] == '_') {
bp += 3; // skip t_xx, xx may be '-' or '>'
} else if (end - bp > 4 && STRNICMP(bp, "char-", 5) == 0) {
- vim_str2nr(bp + 5, NULL, &l, STR2NR_ALL, NULL, NULL, 0);
+ vim_str2nr(bp + 5, NULL, &l, STR2NR_ALL, NULL, NULL, 0, true);
+ if (l == 0) {
+ EMSG(_(e_invarg));
+ return 0;
+ }
bp += l + 5;
break;
}
@@ -637,7 +658,7 @@ int find_special_key(const char_u **srcp, const size_t src_len, int *const modp,
if (bp <= end && *bp == '>') { // found matching '>'
end_of_name = bp + 1;
- /* Which modifiers are given? */
+ // Which modifiers are given?
modifiers = 0x0;
for (bp = src + 1; bp < last_dash; bp++) {
if (*bp != '-') {
@@ -654,7 +675,11 @@ int find_special_key(const char_u **srcp, const size_t src_len, int *const modp,
if (STRNICMP(last_dash + 1, "char-", 5) == 0
&& ascii_isdigit(last_dash[6])) {
// <Char-123> or <Char-033> or <Char-0x33>
- vim_str2nr(last_dash + 6, NULL, NULL, STR2NR_ALL, NULL, &n, 0);
+ vim_str2nr(last_dash + 6, NULL, &l, STR2NR_ALL, NULL, &n, 0, true);
+ if (l == 0) {
+ EMSG(_(e_invarg));
+ return 0;
+ }
key = (int)n;
} else {
int off = 1;
@@ -787,13 +812,14 @@ int get_mouse_button(int code, bool *is_click, bool *is_drag)
{
int i;
- for (i = 0; mouse_table[i].pseudo_code; i++)
+ for (i = 0; mouse_table[i].pseudo_code; i++) {
if (code == mouse_table[i].pseudo_code) {
*is_click = mouse_table[i].is_click;
*is_drag = mouse_table[i].is_drag;
return mouse_table[i].button;
}
- return 0; /* Shouldn't get here */
+ }
+ return 0; // Shouldn't get here
}
/// Replace any terminal code strings with the equivalent internal
@@ -821,9 +847,8 @@ int get_mouse_button(int code, bool *is_click, bool *is_drag)
/// @return Pointer to an allocated memory in case of success, "from" in case of
/// failure. In case of success returned pointer is also saved to
/// "bufp".
-char_u *replace_termcodes(const char_u *from, const size_t from_len,
- char_u **bufp, const bool from_part, const bool do_lt,
- const bool special, int cpo_flags)
+char_u *replace_termcodes(const char_u *from, const size_t from_len, char_u **bufp,
+ const bool from_part, const bool do_lt, const bool special, int cpo_flags)
FUNC_ATTR_NONNULL_ALL
{
ssize_t i;
@@ -833,7 +858,7 @@ char_u *replace_termcodes(const char_u *from, const size_t from_len,
const char_u *src;
const char_u *const end = from + from_len - 1;
int do_backslash; // backslash is a special character
- char_u *result; // buffer for resulting string
+ char_u *result; // buffer for resulting string
do_backslash = !(cpo_flags&FLAG_CPO_BSLASH);
@@ -889,7 +914,7 @@ char_u *replace_termcodes(const char_u *from, const size_t from_len,
}
if (special) {
- char_u *p, *s, len;
+ char_u *p, *s, len;
// Replace <Leader> by the value of "mapleader".
// Replace <LocalLeader> by the value of "maplocalleader".
diff --git a/src/nvim/keymap.h b/src/nvim/keymap.h
index d31196d412..9fc44f6f84 100644
--- a/src/nvim/keymap.h
+++ b/src/nvim/keymap.h
@@ -9,11 +9,11 @@
* Any special key code sequences are replaced by these codes.
*/
-/*
- * For MSDOS some keys produce codes larger than 0xff. They are split into two
- * chars, the first one is K_NUL.
- */
-#define K_NUL (0xce) // for MSDOS: special key follows
+//
+// For MS-DOS some keys produce codes larger than 0xff. They are split into two
+// chars, the first one is K_NUL.
+//
+#define K_NUL (0xce) // for MS-DOS: special key follows
/*
* K_SPECIAL is the first byte of a special key code and is always followed by
diff --git a/src/nvim/log.c b/src/nvim/log.c
index 324382a0f7..5539e3d6c5 100644
--- a/src/nvim/log.c
+++ b/src/nvim/log.c
@@ -17,9 +17,9 @@
#include "auto/config.h"
#include "nvim/log.h"
-#include "nvim/types.h"
#include "nvim/os/os.h"
#include "nvim/os/time.h"
+#include "nvim/types.h"
#define LOG_FILE_ENV "NVIM_LOG_FILE"
@@ -124,8 +124,8 @@ void log_unlock(void)
/// @param line_num Source line number, or -1
/// @param eol Append linefeed "\n"
/// @param fmt printf-style format string
-bool logmsg(int log_level, const char *context, const char *func_name,
- int line_num, bool eol, const char *fmt, ...)
+bool logmsg(int log_level, const char *context, const char *func_name, int line_num, bool eol,
+ const char *fmt, ...)
FUNC_ATTR_UNUSED FUNC_ATTR_PRINTF(6, 7)
{
if (log_level < MIN_LOG_LEVEL) {
@@ -215,8 +215,7 @@ FILE *open_log_file(void)
}
#ifdef HAVE_EXECINFO_BACKTRACE
-void log_callstack_to_file(FILE *log_file, const char *const func_name,
- const int line_num)
+void log_callstack_to_file(FILE *log_file, const char *const func_name, const int line_num)
{
void *trace[100];
int trace_size = backtrace(trace, ARRAY_SIZE(trace));
@@ -268,8 +267,7 @@ end:
#endif
static bool do_log_to_file(FILE *log_file, int log_level, const char *context,
- const char *func_name, int line_num, bool eol,
- const char *fmt, ...)
+ const char *func_name, int line_num, bool eol, const char *fmt, ...)
FUNC_ATTR_PRINTF(7, 8)
{
va_list args;
@@ -281,9 +279,8 @@ static bool do_log_to_file(FILE *log_file, int log_level, const char *context,
return ret;
}
-static bool v_do_log_to_file(FILE *log_file, int log_level,
- const char *context, const char *func_name,
- int line_num, bool eol, const char *fmt,
+static bool v_do_log_to_file(FILE *log_file, int log_level, const char *context,
+ const char *func_name, int line_num, bool eol, const char *fmt,
va_list args)
{
static const char *log_levels[] = {
@@ -317,10 +314,10 @@ static bool v_do_log_to_file(FILE *log_file, int log_level,
? fprintf(log_file, "%s %s.%03d %-5" PRId64 " %s",
log_levels[log_level], date_time, millis, pid,
(context == NULL ? "?:" : context))
- : fprintf(log_file, "%s %s.%03d %-5" PRId64 " %s%s:%d: ",
- log_levels[log_level], date_time, millis, pid,
- (context == NULL ? "" : context),
- func_name, line_num);
+ : fprintf(log_file, "%s %s.%03d %-5" PRId64 " %s%s:%d: ",
+ log_levels[log_level], date_time, millis, pid,
+ (context == NULL ? "" : context),
+ func_name, line_num);
if (rv < 0) {
return false;
}
diff --git a/src/nvim/log.h b/src/nvim/log.h
index 17d754c033..654b682de8 100644
--- a/src/nvim/log.h
+++ b/src/nvim/log.h
@@ -7,7 +7,7 @@
#include "auto/config.h"
#include "nvim/macros.h"
-// USDT probes. Example invokation:
+// USDT probes. Example invocation:
// NVIM_PROBE(nvim_foo_bar, 1, string.data);
#if defined(HAVE_SYS_SDT_H)
#include <sys/sdt.h> // NOLINT
diff --git a/src/nvim/lua/converter.c b/src/nvim/lua/converter.c
index ce8c9b0d06..fac5bab664 100644
--- a/src/nvim/lua/converter.c
+++ b/src/nvim/lua/converter.c
@@ -1,33 +1,31 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+#include <assert.h>
+#include <lauxlib.h>
#include <lua.h>
#include <lualib.h>
-#include <lauxlib.h>
-#include <assert.h>
-#include <stdint.h>
#include <stdbool.h>
+#include <stdint.h>
#include "nvim/api/private/defs.h"
#include "nvim/api/private/helpers.h"
+#include "nvim/assert.h"
#include "nvim/func_attr.h"
#include "nvim/memory.h"
-#include "nvim/assert.h"
// FIXME: vim.h is not actually needed, but otherwise it states MAXPATHL is
// redefined
-#include "nvim/vim.h"
-#include "nvim/globals.h"
-#include "nvim/message.h"
+#include "nvim/ascii.h"
+#include "nvim/eval/decode.h"
#include "nvim/eval/typval.h"
#include "nvim/eval/userfunc.h"
-#include "nvim/ascii.h"
-#include "nvim/macros.h"
-
+#include "nvim/globals.h"
#include "nvim/lib/kvec.h"
-#include "nvim/eval/decode.h"
-
#include "nvim/lua/converter.h"
#include "nvim/lua/executor.h"
+#include "nvim/macros.h"
+#include "nvim/message.h"
+#include "nvim/vim.h"
/// Determine, which keys lua table contains
typedef struct {
@@ -49,7 +47,7 @@ typedef struct {
#define VAL_IDX_VALUE false
#define LUA_PUSH_STATIC_STRING(lstate, s) \
- lua_pushlstring(lstate, s, sizeof(s) - 1)
+ lua_pushlstring(lstate, s, sizeof(s) - 1)
static LuaTableProps nlua_traverse_table(lua_State *const lstate)
@@ -71,57 +69,56 @@ static LuaTableProps nlua_traverse_table(lua_State *const lstate)
lua_pushnil(lstate);
while (lua_next(lstate, -2)) {
switch (lua_type(lstate, -2)) {
- case LUA_TSTRING: {
- size_t len;
- const char *s = lua_tolstring(lstate, -2, &len);
- if (memchr(s, NUL, len) != NULL) {
- ret.has_string_with_nul = true;
- }
- ret.string_keys_num++;
- break;
+ case LUA_TSTRING: {
+ size_t len;
+ const char *s = lua_tolstring(lstate, -2, &len);
+ if (memchr(s, NUL, len) != NULL) {
+ ret.has_string_with_nul = true;
}
- case LUA_TNUMBER: {
- const lua_Number n = lua_tonumber(lstate, -2);
- if (n > (lua_Number)SIZE_MAX || n <= 0
- || ((lua_Number)((size_t)n)) != n) {
- other_keys_num++;
- } else {
- const size_t idx = (size_t)n;
- if (idx > ret.maxidx) {
- ret.maxidx = idx;
- }
+ ret.string_keys_num++;
+ break;
+ }
+ case LUA_TNUMBER: {
+ const lua_Number n = lua_tonumber(lstate, -2);
+ if (n > (lua_Number)SIZE_MAX || n <= 0
+ || ((lua_Number)((size_t)n)) != n) {
+ other_keys_num++;
+ } else {
+ const size_t idx = (size_t)n;
+ if (idx > ret.maxidx) {
+ ret.maxidx = idx;
}
- break;
}
- case LUA_TBOOLEAN: {
- const bool b = lua_toboolean(lstate, -2);
- if (b == TYPE_IDX_VALUE) {
- if (lua_type(lstate, -1) == LUA_TNUMBER) {
- lua_Number n = lua_tonumber(lstate, -1);
- if (n == (lua_Number)kObjectTypeFloat
- || n == (lua_Number)kObjectTypeArray
- || n == (lua_Number)kObjectTypeDictionary) {
- ret.has_type_key = true;
- ret.type = (ObjectType)n;
- } else {
- other_keys_num++;
- }
+ break;
+ }
+ case LUA_TBOOLEAN: {
+ const bool b = lua_toboolean(lstate, -2);
+ if (b == TYPE_IDX_VALUE) {
+ if (lua_type(lstate, -1) == LUA_TNUMBER) {
+ lua_Number n = lua_tonumber(lstate, -1);
+ if (n == (lua_Number)kObjectTypeFloat
+ || n == (lua_Number)kObjectTypeArray
+ || n == (lua_Number)kObjectTypeDictionary) {
+ ret.has_type_key = true;
+ ret.type = (ObjectType)n;
} else {
other_keys_num++;
}
} else {
- has_val_key = true;
- val_type = lua_type(lstate, -1);
- if (val_type == LUA_TNUMBER) {
- ret.val = lua_tonumber(lstate, -1);
- }
+ other_keys_num++;
+ }
+ } else {
+ has_val_key = true;
+ val_type = lua_type(lstate, -1);
+ if (val_type == LUA_TNUMBER) {
+ ret.val = lua_tonumber(lstate, -1);
}
- break;
- }
- default: {
- other_keys_num++;
- break;
}
+ break;
+ }
+ default:
+ other_keys_num++;
+ break;
}
tsize++;
lua_pop(lstate, 1);
@@ -196,8 +193,9 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv)
{
bool ret = true;
const int initial_size = lua_gettop(lstate);
- kvec_t(TVPopStackItem) stack = KV_INITIAL_VALUE;
- kv_push(stack, ((TVPopStackItem) { ret_tv, false, false, 0 }));
+ kvec_withinit_t(TVPopStackItem, 2) stack = KV_INITIAL_VALUE;
+ kvi_init(stack);
+ kvi_push(stack, ((TVPopStackItem) { ret_tv, false, false, 0 }));
while (ret && kv_size(stack)) {
if (!lua_checkstack(lstate, lua_gettop(lstate) + 3)) {
emsgf(_("E1502: Lua failed to grow stack to %i"), lua_gettop(lstate) + 3);
@@ -234,7 +232,7 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv)
tv_list_append_owned_tv(kv_pair, (typval_T) {
.v_type = VAR_UNKNOWN,
});
- kv_push(stack, cur);
+ kvi_push(stack, cur);
tv_list_append_list(cur.tv->vval.v_list, kv_pair);
cur = (TVPopStackItem) {
.tv = TV_LIST_ITEM_TV(tv_list_last(kv_pair)),
@@ -247,7 +245,7 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv)
if (tv_dict_add(cur.tv->vval.v_dict, di) == FAIL) {
abort();
}
- kv_push(stack, cur);
+ kvi_push(stack, cur);
cur = (TVPopStackItem) { &di->di_tv, false, false, 0 };
}
} else {
@@ -265,7 +263,7 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv)
tv_list_append_owned_tv(cur.tv->vval.v_list, (typval_T) {
.v_type = VAR_UNKNOWN,
});
- kv_push(stack, cur);
+ kvi_push(stack, cur);
// TODO(ZyX-I): Use indexes, here list item *will* be reallocated.
cur = (TVPopStackItem) {
.tv = TV_LIST_ITEM_TV(tv_list_last(cur.tv->vval.v_list)),
@@ -282,159 +280,149 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv)
.vval = { .v_number = 0 },
};
switch (lua_type(lstate, -1)) {
- case LUA_TNIL: {
- cur.tv->v_type = VAR_SPECIAL;
- cur.tv->vval.v_special = kSpecialVarNull;
- break;
- }
- case LUA_TBOOLEAN: {
- cur.tv->v_type = VAR_BOOL;
- cur.tv->vval.v_bool = (lua_toboolean(lstate, -1)
+ case LUA_TNIL:
+ cur.tv->v_type = VAR_SPECIAL;
+ cur.tv->vval.v_special = kSpecialVarNull;
+ break;
+ case LUA_TBOOLEAN:
+ cur.tv->v_type = VAR_BOOL;
+ cur.tv->vval.v_bool = (lua_toboolean(lstate, -1)
? kBoolVarTrue
: kBoolVarFalse);
- break;
+ break;
+ case LUA_TSTRING: {
+ size_t len;
+ const char *s = lua_tolstring(lstate, -1, &len);
+ *cur.tv = decode_string(s, len, kNone, true, false);
+ if (cur.tv->v_type == VAR_UNKNOWN) {
+ ret = false;
}
- case LUA_TSTRING: {
- size_t len;
- const char *s = lua_tolstring(lstate, -1, &len);
- *cur.tv = decode_string(s, len, kNone, true, false);
- if (cur.tv->v_type == VAR_UNKNOWN) {
- ret = false;
- }
- break;
+ break;
+ }
+ case LUA_TNUMBER: {
+ const lua_Number n = lua_tonumber(lstate, -1);
+ if (n > (lua_Number)VARNUMBER_MAX || n < (lua_Number)VARNUMBER_MIN
+ || ((lua_Number)((varnumber_T)n)) != n) {
+ cur.tv->v_type = VAR_FLOAT;
+ cur.tv->vval.v_float = (float_T)n;
+ } else {
+ cur.tv->v_type = VAR_NUMBER;
+ cur.tv->vval.v_number = (varnumber_T)n;
}
- case LUA_TNUMBER: {
- const lua_Number n = lua_tonumber(lstate, -1);
- if (n > (lua_Number)VARNUMBER_MAX || n < (lua_Number)VARNUMBER_MIN
- || ((lua_Number)((varnumber_T)n)) != n) {
- cur.tv->v_type = VAR_FLOAT;
- cur.tv->vval.v_float = (float_T)n;
- } else {
- cur.tv->v_type = VAR_NUMBER;
- cur.tv->vval.v_number = (varnumber_T)n;
- }
- break;
+ break;
+ }
+ case LUA_TTABLE: {
+ // Only need to track table refs if we have a metatable associated.
+ LuaRef table_ref = LUA_NOREF;
+ if (lua_getmetatable(lstate, -1)) {
+ lua_pop(lstate, 1);
+ table_ref = nlua_ref(lstate, -1);
}
- case LUA_TTABLE: {
- // Only need to track table refs if we have a metatable associated.
- LuaRef table_ref = LUA_NOREF;
- if (lua_getmetatable(lstate, -1)) {
- lua_pop(lstate, 1);
- table_ref = nlua_ref(lstate, -1);
- }
- const LuaTableProps table_props = nlua_traverse_table(lstate);
+ const LuaTableProps table_props = nlua_traverse_table(lstate);
- for (size_t i = 0; i < kv_size(stack); i++) {
- const TVPopStackItem item = kv_A(stack, i);
- if (item.container && lua_rawequal(lstate, -1, item.idx)) {
- tv_copy(item.tv, cur.tv);
- cur.container = false;
- goto nlua_pop_typval_table_processing_end;
- }
+ for (size_t i = 0; i < kv_size(stack); i++) {
+ const TVPopStackItem item = kv_A(stack, i);
+ if (item.container && lua_rawequal(lstate, -1, item.idx)) {
+ tv_copy(item.tv, cur.tv);
+ cur.container = false;
+ goto nlua_pop_typval_table_processing_end;
}
+ }
- switch (table_props.type) {
- case kObjectTypeArray: {
- cur.tv->v_type = VAR_LIST;
- cur.tv->vval.v_list = tv_list_alloc((ptrdiff_t)table_props.maxidx);
+ switch (table_props.type) {
+ case kObjectTypeArray:
+ cur.tv->v_type = VAR_LIST;
+ cur.tv->vval.v_list = tv_list_alloc((ptrdiff_t)table_props.maxidx);
+ cur.tv->vval.v_list->lua_table_ref = table_ref;
+ tv_list_ref(cur.tv->vval.v_list);
+ if (table_props.maxidx != 0) {
+ cur.container = true;
+ cur.idx = lua_gettop(lstate);
+ kvi_push(stack, cur);
+ }
+ break;
+ case kObjectTypeDictionary:
+ if (table_props.string_keys_num == 0) {
+ cur.tv->v_type = VAR_DICT;
+ cur.tv->vval.v_dict = tv_dict_alloc();
+ cur.tv->vval.v_dict->dv_refcount++;
+ cur.tv->vval.v_dict->lua_table_ref = table_ref;
+ } else {
+ cur.special = table_props.has_string_with_nul;
+ if (table_props.has_string_with_nul) {
+ decode_create_map_special_dict(cur.tv, (ptrdiff_t)table_props.string_keys_num);
+ assert(cur.tv->v_type == VAR_DICT);
+ dictitem_T *const val_di = tv_dict_find(cur.tv->vval.v_dict,
+ S_LEN("_VAL"));
+ assert(val_di != NULL);
+ cur.tv = &val_di->di_tv;
cur.tv->vval.v_list->lua_table_ref = table_ref;
- tv_list_ref(cur.tv->vval.v_list);
- if (table_props.maxidx != 0) {
- cur.container = true;
- cur.idx = lua_gettop(lstate);
- kv_push(stack, cur);
- }
- break;
- }
- case kObjectTypeDictionary: {
- if (table_props.string_keys_num == 0) {
- cur.tv->v_type = VAR_DICT;
- cur.tv->vval.v_dict = tv_dict_alloc();
- cur.tv->vval.v_dict->dv_refcount++;
- cur.tv->vval.v_dict->lua_table_ref = table_ref;
- } else {
- cur.special = table_props.has_string_with_nul;
- if (table_props.has_string_with_nul) {
- decode_create_map_special_dict(
- cur.tv, (ptrdiff_t)table_props.string_keys_num);
- assert(cur.tv->v_type == VAR_DICT);
- dictitem_T *const val_di = tv_dict_find(cur.tv->vval.v_dict,
- S_LEN("_VAL"));
- assert(val_di != NULL);
- cur.tv = &val_di->di_tv;
- cur.tv->vval.v_list->lua_table_ref = table_ref;
- assert(cur.tv->v_type == VAR_LIST);
- } else {
- cur.tv->v_type = VAR_DICT;
- cur.tv->vval.v_dict = tv_dict_alloc();
- cur.tv->vval.v_dict->dv_refcount++;
- cur.tv->vval.v_dict->lua_table_ref = table_ref;
- }
- cur.container = true;
- cur.idx = lua_gettop(lstate);
- kv_push(stack, cur);
- lua_pushnil(lstate);
- }
- break;
- }
- case kObjectTypeFloat: {
- cur.tv->v_type = VAR_FLOAT;
- cur.tv->vval.v_float = (float_T)table_props.val;
- break;
- }
- case kObjectTypeNil: {
- EMSG(_("E5100: Cannot convert given lua table: table "
- "should either have a sequence of positive integer keys "
- "or contain only string keys"));
- ret = false;
- break;
- }
- default: {
- abort();
+ assert(cur.tv->v_type == VAR_LIST);
+ } else {
+ cur.tv->v_type = VAR_DICT;
+ cur.tv->vval.v_dict = tv_dict_alloc();
+ cur.tv->vval.v_dict->dv_refcount++;
+ cur.tv->vval.v_dict->lua_table_ref = table_ref;
}
+ cur.container = true;
+ cur.idx = lua_gettop(lstate);
+ kvi_push(stack, cur);
+ lua_pushnil(lstate);
}
-nlua_pop_typval_table_processing_end:
break;
- }
- case LUA_TFUNCTION: {
- LuaCFunctionState *state = xmalloc(sizeof(LuaCFunctionState));
- state->lua_callable.func_ref = nlua_ref(lstate, -1);
-
- char_u *name = register_cfunc(
- &nlua_CFunction_func_call,
- &nlua_CFunction_func_free,
- state);
-
- cur.tv->v_type = VAR_FUNC;
- cur.tv->vval.v_string = vim_strsave(name);
+ case kObjectTypeFloat:
+ cur.tv->v_type = VAR_FLOAT;
+ cur.tv->vval.v_float = (float_T)table_props.val;
break;
- }
- case LUA_TUSERDATA: {
- // TODO(bfredl): check mt.__call and convert to function?
- nlua_pushref(lstate, nlua_nil_ref);
- bool is_nil = lua_rawequal(lstate, -2, -1);
- lua_pop(lstate, 1);
- if (is_nil) {
- cur.tv->v_type = VAR_SPECIAL;
- cur.tv->vval.v_special = kSpecialVarNull;
- } else {
- EMSG(_("E5101: Cannot convert given lua type"));
- ret = false;
- }
+ case kObjectTypeNil:
+ EMSG(_("E5100: Cannot convert given lua table: table "
+ "should either have a sequence of positive integer keys "
+ "or contain only string keys"));
+ ret = false;
break;
+ default:
+ abort();
}
- default: {
+nlua_pop_typval_table_processing_end:
+ break;
+ }
+ case LUA_TFUNCTION: {
+ LuaCFunctionState *state = xmalloc(sizeof(LuaCFunctionState));
+ state->lua_callable.func_ref = nlua_ref(lstate, -1);
+
+ char_u *name = register_cfunc(&nlua_CFunction_func_call,
+ &nlua_CFunction_func_free,
+ state);
+
+ cur.tv->v_type = VAR_FUNC;
+ cur.tv->vval.v_string = vim_strsave(name);
+ break;
+ }
+ case LUA_TUSERDATA: {
+ // TODO(bfredl): check mt.__call and convert to function?
+ nlua_pushref(lstate, nlua_nil_ref);
+ bool is_nil = lua_rawequal(lstate, -2, -1);
+ lua_pop(lstate, 1);
+ if (is_nil) {
+ cur.tv->v_type = VAR_SPECIAL;
+ cur.tv->vval.v_special = kSpecialVarNull;
+ } else {
EMSG(_("E5101: Cannot convert given lua type"));
ret = false;
- break;
}
+ break;
+ }
+ default:
+ EMSG(_("E5101: Cannot convert given lua type"));
+ ret = false;
+ break;
}
if (!cur.container) {
lua_pop(lstate, 1);
}
}
- kv_destroy(stack);
+ kvi_destroy(stack);
if (!ret) {
tv_clear(ret_tv);
*ret_tv = (typval_T) {
@@ -453,89 +441,97 @@ static bool typval_conv_special = false;
#define TYPVAL_ENCODE_ALLOW_SPECIALS true
#define TYPVAL_ENCODE_CONV_NIL(tv) \
- do { \
- if (typval_conv_special) { \
- lua_pushnil(lstate); \
- } else { \
- nlua_pushref(lstate, nlua_nil_ref); \
- } \
- } while (0)
+ do { \
+ if (typval_conv_special) { \
+ lua_pushnil(lstate); \
+ } else { \
+ nlua_pushref(lstate, nlua_nil_ref); \
+ } \
+ } while (0)
#define TYPVAL_ENCODE_CONV_BOOL(tv, num) \
- lua_pushboolean(lstate, (bool)(num))
+ lua_pushboolean(lstate, (bool)(num))
#define TYPVAL_ENCODE_CONV_NUMBER(tv, num) \
- lua_pushnumber(lstate, (lua_Number)(num))
+ lua_pushnumber(lstate, (lua_Number)(num))
#define TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER TYPVAL_ENCODE_CONV_NUMBER
#define TYPVAL_ENCODE_CONV_FLOAT(tv, flt) \
- TYPVAL_ENCODE_CONV_NUMBER(tv, flt)
+ TYPVAL_ENCODE_CONV_NUMBER(tv, flt)
#define TYPVAL_ENCODE_CONV_STRING(tv, str, len) \
- lua_pushlstring(lstate, (const char *)(str), (len))
+ lua_pushlstring(lstate, (const char *)(str), (len))
#define TYPVAL_ENCODE_CONV_STR_STRING TYPVAL_ENCODE_CONV_STRING
#define TYPVAL_ENCODE_CONV_EXT_STRING(tv, str, len, type) \
- TYPVAL_ENCODE_CONV_NIL(tv)
+ TYPVAL_ENCODE_CONV_NIL(tv)
+
+#define TYPVAL_ENCODE_CONV_BLOB(tv, blob, len) \
+ do { \
+ const blob_T *const blob_ = (blob); \
+ lua_pushlstring(lstate, \
+ blob_ != NULL ? (const char *)blob_->bv_ga.ga_data : "", \
+ (size_t)(len)); \
+ } while (0)
#define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun) \
- do { \
- TYPVAL_ENCODE_CONV_NIL(tv); \
- goto typval_encode_stop_converting_one_item; \
- } while (0)
+ do { \
+ TYPVAL_ENCODE_CONV_NIL(tv); \
+ goto typval_encode_stop_converting_one_item; \
+ } while (0)
#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, len)
#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, len)
#define TYPVAL_ENCODE_CONV_FUNC_END(tv)
#define TYPVAL_ENCODE_CONV_EMPTY_LIST(tv) \
- lua_createtable(lstate, 0, 0)
+ lua_createtable(lstate, 0, 0)
#define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, dict) \
- do { \
- if (typval_conv_special) { \
- nlua_create_typed_table(lstate, 0, 0, kObjectTypeDictionary); \
- } else { \
- lua_createtable(lstate, 0, 0); \
- nlua_pushref(lstate, nlua_empty_dict_ref); \
- lua_setmetatable(lstate, -2); \
- } \
- } while (0)
+ do { \
+ if (typval_conv_special) { \
+ nlua_create_typed_table(lstate, 0, 0, kObjectTypeDictionary); \
+ } else { \
+ lua_createtable(lstate, 0, 0); \
+ nlua_pushref(lstate, nlua_empty_dict_ref); \
+ lua_setmetatable(lstate, -2); \
+ } \
+ } while (0)
#define TYPVAL_ENCODE_CONV_LIST_START(tv, len) \
- do { \
- if (!lua_checkstack(lstate, lua_gettop(lstate) + 3)) { \
- emsgf(_("E5102: Lua failed to grow stack to %i"), \
- lua_gettop(lstate) + 3); \
- return false; \
- } \
- lua_createtable(lstate, (int)(len), 0); \
- lua_pushnumber(lstate, 1); \
- } while (0)
+ do { \
+ if (!lua_checkstack(lstate, lua_gettop(lstate) + 3)) { \
+ emsgf(_("E5102: Lua failed to grow stack to %i"), \
+ lua_gettop(lstate) + 3); \
+ return false; \
+ } \
+ lua_createtable(lstate, (int)(len), 0); \
+ lua_pushnumber(lstate, 1); \
+ } while (0)
#define TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START(tv, mpsv)
#define TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(tv) \
- do { \
- lua_Number idx = lua_tonumber(lstate, -2); \
- lua_rawset(lstate, -3); \
- lua_pushnumber(lstate, idx + 1); \
- } while (0)
+ do { \
+ lua_Number idx = lua_tonumber(lstate, -2); \
+ lua_rawset(lstate, -3); \
+ lua_pushnumber(lstate, idx + 1); \
+ } while (0)
#define TYPVAL_ENCODE_CONV_LIST_END(tv) \
- lua_rawset(lstate, -3)
+ lua_rawset(lstate, -3)
#define TYPVAL_ENCODE_CONV_DICT_START(tv, dict, len) \
- do { \
- if (!lua_checkstack(lstate, lua_gettop(lstate) + 3)) { \
- emsgf(_("E5102: Lua failed to grow stack to %i"), \
- lua_gettop(lstate) + 3); \
- return false; \
- } \
- lua_createtable(lstate, 0, (int)(len)); \
- } while (0)
+ do { \
+ if (!lua_checkstack(lstate, lua_gettop(lstate) + 3)) { \
+ emsgf(_("E5102: Lua failed to grow stack to %i"), \
+ lua_gettop(lstate) + 3); \
+ return false; \
+ } \
+ lua_createtable(lstate, 0, (int)(len)); \
+ } while (0)
#define TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK(label, kv_pair)
@@ -544,26 +540,26 @@ static bool typval_conv_special = false;
#define TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(tv, dict)
#define TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(tv, dict) \
- lua_rawset(lstate, -3)
+ lua_rawset(lstate, -3)
#define TYPVAL_ENCODE_CONV_DICT_END(tv, dict) \
- TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(tv, dict)
+ TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(tv, dict)
#define TYPVAL_ENCODE_CONV_RECURSE(val, conv_type) \
- do { \
- for (size_t backref = kv_size(*mpstack); backref; backref--) { \
- const MPConvStackVal mpval = kv_A(*mpstack, backref - 1); \
- if (mpval.type == conv_type) { \
- if (conv_type == kMPConvDict \
+ do { \
+ for (size_t backref = kv_size(*mpstack); backref; backref--) { \
+ const MPConvStackVal mpval = kv_A(*mpstack, backref - 1); \
+ if (mpval.type == conv_type) { \
+ if (conv_type == kMPConvDict \
? (void *)mpval.data.d.dict == (void *)(val) \
: (void *)mpval.data.l.list == (void *)(val)) { \
- lua_pushvalue(lstate, \
- -((int)((kv_size(*mpstack) - backref + 1) * 2))); \
- break; \
- } \
+ lua_pushvalue(lstate, \
+ -((int)((kv_size(*mpstack) - backref + 1) * 2))); \
+ break; \
} \
} \
- } while (0)
+ } \
+ } while (0)
#define TYPVAL_ENCODE_SCOPE static
#define TYPVAL_ENCODE_NAME lua
@@ -578,6 +574,7 @@ static bool typval_conv_special = false;
#undef TYPVAL_ENCODE_CONV_STRING
#undef TYPVAL_ENCODE_CONV_STR_STRING
#undef TYPVAL_ENCODE_CONV_EXT_STRING
+#undef TYPVAL_ENCODE_CONV_BLOB
#undef TYPVAL_ENCODE_CONV_NUMBER
#undef TYPVAL_ENCODE_CONV_FLOAT
#undef TYPVAL_ENCODE_CONV_FUNC_START
@@ -664,9 +661,7 @@ static inline void nlua_push_type(lua_State *lstate, ObjectType type)
/// @param[in] narr Number of “array” entries to be populated later.
/// @param[in] nrec Number of “dictionary” entries to be populated later.
/// @param[in] type Type of the table.
-static inline void nlua_create_typed_table(lua_State *lstate,
- const size_t narr,
- const size_t nrec,
+static inline void nlua_create_typed_table(lua_State *lstate, const size_t narr, const size_t nrec,
const ObjectType type)
FUNC_ATTR_NONNULL_ALL
{
@@ -723,8 +718,7 @@ void nlua_push_Boolean(lua_State *lstate, const Boolean b, bool special)
/// Convert given Dictionary to lua table
///
/// Leaves converted table on top of the stack.
-void nlua_push_Dictionary(lua_State *lstate, const Dictionary dict,
- bool special)
+void nlua_push_Dictionary(lua_State *lstate, const Dictionary dict, bool special)
FUNC_ATTR_NONNULL_ALL
{
if (dict.size == 0 && special) {
@@ -757,11 +751,11 @@ void nlua_push_Array(lua_State *lstate, const Array array, bool special)
}
#define GENERATE_INDEX_FUNCTION(type) \
-void nlua_push_##type(lua_State *lstate, const type item, bool special) \
+ void nlua_push_##type(lua_State *lstate, const type item, bool special) \
FUNC_ATTR_NONNULL_ALL \
-{ \
- lua_pushnumber(lstate, (lua_Number)(item)); \
-}
+ { \
+ lua_pushnumber(lstate, (lua_Number)(item)); \
+ }
GENERATE_INDEX_FUNCTION(Buffer)
GENERATE_INDEX_FUNCTION(Window)
@@ -776,23 +770,22 @@ void nlua_push_Object(lua_State *lstate, const Object obj, bool special)
FUNC_ATTR_NONNULL_ALL
{
switch (obj.type) {
- case kObjectTypeNil: {
- if (special) {
- lua_pushnil(lstate);
- } else {
- nlua_pushref(lstate, nlua_nil_ref);
- }
- break;
- }
- case kObjectTypeLuaRef: {
- nlua_pushref(lstate, obj.data.luaref);
- break;
+ case kObjectTypeNil:
+ if (special) {
+ lua_pushnil(lstate);
+ } else {
+ nlua_pushref(lstate, nlua_nil_ref);
}
+ break;
+ case kObjectTypeLuaRef: {
+ nlua_pushref(lstate, obj.data.luaref);
+ break;
+ }
#define ADD_TYPE(type, data_key) \
- case kObjectType##type: { \
- nlua_push_##type(lstate, obj.data.data_key, special); \
- break; \
- }
+case kObjectType##type: { \
+ nlua_push_##type(lstate, obj.data.data_key, special); \
+ break; \
+}
ADD_TYPE(Boolean, boolean)
ADD_TYPE(Integer, integer)
ADD_TYPE(Float, floating)
@@ -801,10 +794,10 @@ void nlua_push_Object(lua_State *lstate, const Object obj, bool special)
ADD_TYPE(Dictionary, dictionary)
#undef ADD_TYPE
#define ADD_REMOTE_TYPE(type) \
- case kObjectType##type: { \
- nlua_push_##type(lstate, (type)obj.data.integer, special); \
- break; \
- }
+case kObjectType##type: { \
+ nlua_push_##type(lstate, (type)obj.data.integer, special); \
+ break; \
+}
ADD_REMOTE_TYPE(Buffer)
ADD_REMOTE_TYPE(Window)
ADD_REMOTE_TYPE(Tabpage)
@@ -873,8 +866,7 @@ Boolean nlua_pop_Boolean(lua_State *lstate, Error *err)
/// @param[in] type Type to check.
///
/// @return @see nlua_traverse_table().
-static inline LuaTableProps nlua_check_type(lua_State *const lstate,
- Error *const err,
+static inline LuaTableProps nlua_check_type(lua_State *const lstate, Error *const err,
const ObjectType type)
FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_WARN_UNUSED_RESULT
{
@@ -927,8 +919,7 @@ Float nlua_pop_Float(lua_State *lstate, Error *err)
/// @param lstate Lua state.
/// @param[in] table_props nlua_traverse_table() output.
/// @param[out] err Location where error will be saved.
-static Array nlua_pop_Array_unchecked(lua_State *const lstate,
- const LuaTableProps table_props,
+static Array nlua_pop_Array_unchecked(lua_State *const lstate, const LuaTableProps table_props,
Error *const err)
{
Array ret = { .size = table_props.maxidx, .items = NULL };
@@ -980,10 +971,8 @@ Array nlua_pop_Array(lua_State *lstate, Error *err)
/// @param lstate Lua interpreter state.
/// @param[in] table_props nlua_traverse_table() output.
/// @param[out] err Location where error will be saved.
-static Dictionary nlua_pop_Dictionary_unchecked(lua_State *lstate,
- const LuaTableProps table_props,
- bool ref,
- Error *err)
+static Dictionary nlua_pop_Dictionary_unchecked(lua_State *lstate, const LuaTableProps table_props,
+ bool ref, Error *err)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
Dictionary ret = { .size = table_props.string_keys_num, .items = NULL };
@@ -1060,15 +1049,16 @@ Object nlua_pop_Object(lua_State *const lstate, bool ref, Error *const err)
{
Object ret = NIL;
const int initial_size = lua_gettop(lstate);
- kvec_t(ObjPopStackItem) stack = KV_INITIAL_VALUE;
- kv_push(stack, ((ObjPopStackItem) { &ret, false }));
+ kvec_withinit_t(ObjPopStackItem, 2) stack = KV_INITIAL_VALUE;
+ kvi_init(stack);
+ kvi_push(stack, ((ObjPopStackItem) { &ret, false }));
while (!ERROR_SET(err) && kv_size(stack)) {
- if (!lua_checkstack(lstate, lua_gettop(lstate) + 3)) {
- api_set_error(err, kErrorTypeException, "Lua failed to grow stack");
- break;
- }
ObjPopStackItem cur = kv_pop(stack);
if (cur.container) {
+ if (!lua_checkstack(lstate, lua_gettop(lstate) + 3)) {
+ api_set_error(err, kErrorTypeException, "Lua failed to grow stack");
+ break;
+ }
if (cur.obj->type == kObjectTypeDictionary) {
// stack: …, dict, key
if (cur.obj->data.dictionary.size
@@ -1095,7 +1085,7 @@ Object nlua_pop_Object(lua_State *const lstate, bool ref, Error *const err)
.data = xmemdupz(s, len),
.size = len,
};
- kv_push(stack, cur);
+ kvi_push(stack, cur);
cur = (ObjPopStackItem) {
.obj = &cur.obj->data.dictionary.items[idx].value,
.container = false,
@@ -1117,7 +1107,7 @@ Object nlua_pop_Object(lua_State *const lstate, bool ref, Error *const err)
lua_pop(lstate, 2);
continue;
}
- kv_push(stack, cur);
+ kvi_push(stack, cur);
cur = (ObjPopStackItem) {
.obj = &cur.obj->data.array.items[idx],
.container = false,
@@ -1127,119 +1117,110 @@ Object nlua_pop_Object(lua_State *const lstate, bool ref, Error *const err)
assert(!cur.container);
*cur.obj = NIL;
switch (lua_type(lstate, -1)) {
- case LUA_TNIL: {
- break;
- }
- case LUA_TBOOLEAN: {
- *cur.obj = BOOLEAN_OBJ(lua_toboolean(lstate, -1));
- break;
- }
- case LUA_TSTRING: {
- size_t len;
- const char *s = lua_tolstring(lstate, -1, &len);
- *cur.obj = STRING_OBJ(((String) {
+ case LUA_TNIL:
+ break;
+ case LUA_TBOOLEAN:
+ *cur.obj = BOOLEAN_OBJ(lua_toboolean(lstate, -1));
+ break;
+ case LUA_TSTRING: {
+ size_t len;
+ const char *s = lua_tolstring(lstate, -1, &len);
+ *cur.obj = STRING_OBJ(((String) {
.data = xmemdupz(s, len),
.size = len,
}));
- break;
+ break;
+ }
+ case LUA_TNUMBER: {
+ const lua_Number n = lua_tonumber(lstate, -1);
+ if (n > (lua_Number)API_INTEGER_MAX || n < (lua_Number)API_INTEGER_MIN
+ || ((lua_Number)((Integer)n)) != n) {
+ *cur.obj = FLOAT_OBJ((Float)n);
+ } else {
+ *cur.obj = INTEGER_OBJ((Integer)n);
}
- case LUA_TNUMBER: {
- const lua_Number n = lua_tonumber(lstate, -1);
- if (n > (lua_Number)API_INTEGER_MAX || n < (lua_Number)API_INTEGER_MIN
- || ((lua_Number)((Integer)n)) != n) {
- *cur.obj = FLOAT_OBJ((Float)n);
- } else {
- *cur.obj = INTEGER_OBJ((Integer)n);
+ break;
+ }
+ case LUA_TTABLE: {
+ const LuaTableProps table_props = nlua_traverse_table(lstate);
+
+ switch (table_props.type) {
+ case kObjectTypeArray:
+ *cur.obj = ARRAY_OBJ(((Array) {
+ .items = NULL,
+ .size = 0,
+ .capacity = 0,
+ }));
+ if (table_props.maxidx != 0) {
+ cur.obj->data.array.items =
+ xcalloc(table_props.maxidx,
+ sizeof(cur.obj->data.array.items[0]));
+ cur.obj->data.array.capacity = table_props.maxidx;
+ cur.container = true;
+ kvi_push(stack, cur);
}
break;
- }
- case LUA_TTABLE: {
- const LuaTableProps table_props = nlua_traverse_table(lstate);
-
- switch (table_props.type) {
- case kObjectTypeArray: {
- *cur.obj = ARRAY_OBJ(((Array) {
- .items = NULL,
- .size = 0,
- .capacity = 0,
- }));
- if (table_props.maxidx != 0) {
- cur.obj->data.array.items =
- xcalloc(table_props.maxidx,
- sizeof(cur.obj->data.array.items[0]));
- cur.obj->data.array.capacity = table_props.maxidx;
- cur.container = true;
- kv_push(stack, cur);
- }
- break;
- }
- case kObjectTypeDictionary: {
- *cur.obj = DICTIONARY_OBJ(((Dictionary) {
- .items = NULL,
- .size = 0,
- .capacity = 0,
- }));
- if (table_props.string_keys_num != 0) {
- cur.obj->data.dictionary.items =
- xcalloc(table_props.string_keys_num,
- sizeof(cur.obj->data.dictionary.items[0]));
- cur.obj->data.dictionary.capacity = table_props.string_keys_num;
- cur.container = true;
- kv_push(stack, cur);
- lua_pushnil(lstate);
- }
- break;
- }
- case kObjectTypeFloat: {
- *cur.obj = FLOAT_OBJ((Float)table_props.val);
- break;
- }
- case kObjectTypeNil: {
- api_set_error(err, kErrorTypeValidation,
- "Cannot convert given lua table");
- break;
- }
- default: {
- abort();
- }
+ case kObjectTypeDictionary:
+ *cur.obj = DICTIONARY_OBJ(((Dictionary) {
+ .items = NULL,
+ .size = 0,
+ .capacity = 0,
+ }));
+ if (table_props.string_keys_num != 0) {
+ cur.obj->data.dictionary.items =
+ xcalloc(table_props.string_keys_num,
+ sizeof(cur.obj->data.dictionary.items[0]));
+ cur.obj->data.dictionary.capacity = table_props.string_keys_num;
+ cur.container = true;
+ kvi_push(stack, cur);
+ lua_pushnil(lstate);
}
break;
- }
-
- case LUA_TFUNCTION: {
- if (ref) {
- *cur.obj = LUAREF_OBJ(nlua_ref(lstate, -1));
- } else {
- goto type_error;
- }
+ case kObjectTypeFloat:
+ *cur.obj = FLOAT_OBJ((Float)table_props.val);
+ break;
+ case kObjectTypeNil:
+ api_set_error(err, kErrorTypeValidation,
+ "Cannot convert given lua table");
break;
+ default:
+ abort();
}
+ break;
+ }
- case LUA_TUSERDATA: {
- nlua_pushref(lstate, nlua_nil_ref);
- bool is_nil = lua_rawequal(lstate, -2, -1);
- lua_pop(lstate, 1);
- if (is_nil) {
- *cur.obj = NIL;
- } else {
- api_set_error(err, kErrorTypeValidation,
- "Cannot convert userdata");
- }
- break;
+ case LUA_TFUNCTION:
+ if (ref) {
+ *cur.obj = LUAREF_OBJ(nlua_ref(lstate, -1));
+ } else {
+ goto type_error;
}
+ break;
- default: {
-type_error:
+ case LUA_TUSERDATA: {
+ nlua_pushref(lstate, nlua_nil_ref);
+ bool is_nil = lua_rawequal(lstate, -2, -1);
+ lua_pop(lstate, 1);
+ if (is_nil) {
+ *cur.obj = NIL;
+ } else {
api_set_error(err, kErrorTypeValidation,
- "Cannot convert given lua type");
- break;
+ "Cannot convert userdata");
}
+ break;
+ }
+
+ default:
+type_error:
+ api_set_error(err, kErrorTypeValidation,
+ "Cannot convert given lua type");
+ break;
}
if (!cur.container) {
lua_pop(lstate, 1);
}
}
- kv_destroy(stack);
+ kvi_destroy(stack);
if (ERROR_SET(err)) {
api_free_object(ret);
ret = NIL;
@@ -1257,14 +1238,14 @@ LuaRef nlua_pop_LuaRef(lua_State *const lstate, Error *err)
}
#define GENERATE_INDEX_FUNCTION(type) \
-type nlua_pop_##type(lua_State *lstate, Error *err) \
+ type nlua_pop_##type(lua_State *lstate, Error *err) \
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT \
-{ \
- type ret; \
- ret = (type)lua_tonumber(lstate, -1); \
- lua_pop(lstate, 1); \
- return ret; \
-}
+ { \
+ type ret; \
+ ret = (type)lua_tonumber(lstate, -1); \
+ lua_pop(lstate, 1); \
+ return ret; \
+ }
GENERATE_INDEX_FUNCTION(Buffer)
GENERATE_INDEX_FUNCTION(Window)
diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c
index 4d4286354b..9333d781cd 100644
--- a/src/nvim/lua/executor.c
+++ b/src/nvim/lua/executor.c
@@ -1,58 +1,60 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+#include <lauxlib.h>
#include <lua.h>
#include <lualib.h>
-#include <lauxlib.h>
-#include "nvim/assert.h"
-#include "nvim/version.h"
-#include "nvim/misc1.h"
-#include "nvim/getchar.h"
-#include "nvim/garray.h"
-#include "nvim/func_attr.h"
+#include "luv/luv.h"
+#include "mpack/lmpack.h"
#include "nvim/api/private/defs.h"
#include "nvim/api/private/helpers.h"
-#include "nvim/api/private/handle.h"
#include "nvim/api/vim.h"
-#include "nvim/msgpack_rpc/channel.h"
-#include "nvim/vim.h"
-#include "nvim/extmark.h"
-#include "nvim/ex_getln.h"
-#include "nvim/ex_cmds2.h"
-#include "nvim/map.h"
-#include "nvim/message.h"
-#include "nvim/memline.h"
-#include "nvim/buffer_defs.h"
-#include "nvim/regexp.h"
-#include "nvim/macros.h"
-#include "nvim/screen.h"
-#include "nvim/cursor.h"
-#include "nvim/undo.h"
#include "nvim/ascii.h"
+#include "nvim/assert.h"
+#include "nvim/buffer_defs.h"
#include "nvim/change.h"
+#include "nvim/cursor.h"
#include "nvim/eval/userfunc.h"
-#include "nvim/event/time.h"
#include "nvim/event/loop.h"
-
-#include "nvim/os/os.h"
-
+#include "nvim/event/time.h"
+#include "nvim/ex_cmds2.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/lua/converter.h"
#include "nvim/lua/executor.h"
#include "nvim/lua/treesitter.h"
-
-#include "luv/luv.h"
+#include "nvim/lua/xdiff.h"
+#include "nvim/macros.h"
+#include "nvim/map.h"
+#include "nvim/memline.h"
+#include "nvim/message.h"
+#include "nvim/misc1.h"
+#include "nvim/msgpack_rpc/channel.h"
+#include "nvim/os/os.h"
+#include "nvim/regexp.h"
+#include "nvim/screen.h"
+#include "nvim/undo.h"
+#include "nvim/version.h"
+#include "nvim/vim.h"
+#include "cjson/lua_cjson.h"
static int in_fast_callback = 0;
+// Initialized in nlua_init().
+static lua_State *global_lstate = NULL;
+
typedef struct {
Error err;
String lua_err_str;
} LuaError;
#ifdef INCLUDE_GENERATED_DECLARATIONS
-# include "lua/vim_module.generated.h"
# include "lua/executor.c.generated.h"
+# include "lua/vim_module.generated.h"
#endif
#define PUSH_ALL_TYPVALS(lstate, args, argcount, special) \
@@ -65,7 +67,8 @@ typedef struct {
}
#if __has_feature(address_sanitizer)
- PMap(handle_T) *nlua_ref_markers = NULL;
+static PMap(handle_T) nlua_ref_markers = MAP_INIT;
+static bool nlua_track_refs = false;
# define NLUA_TRACK_REFS
#endif
@@ -85,7 +88,7 @@ static void nlua_error(lua_State *const lstate, const char *const msg)
lua_pop(lstate, 1);
}
-/// Return version of current neovim build
+/// Gets the version of the current Nvim build.
///
/// @param lstate Lua interpreter state.
static int nlua_nvim_version(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
@@ -144,12 +147,12 @@ static int nlua_stricmp(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
return 1;
}
-/// convert byte index to UTF-32 and UTF-16 indicies
+/// convert byte index to UTF-32 and UTF-16 indices
///
/// Expects a string and an optional index. If no index is supplied, the length
/// of the string is returned.
///
-/// Returns two values: the UTF-32 and UTF-16 indicies.
+/// Returns two values: the UTF-32 and UTF-16 indices.
static int nlua_str_utfindex(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
{
size_t s1_len;
@@ -173,7 +176,7 @@ static int nlua_str_utfindex(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
return 2;
}
-/// convert UTF-32 or UTF-16 indicies to byte index.
+/// convert UTF-32 or UTF-16 indices to byte index.
///
/// Expects up to three args: string, index and use_utf16.
/// If use_utf16 is not supplied it defaults to false (use UTF-32)
@@ -211,8 +214,7 @@ static void nlua_luv_error_event(void **argv)
xfree(error);
}
-static int nlua_luv_cfpcall(lua_State *lstate, int nargs, int nresult,
- int flags)
+static int nlua_luv_cfpcall(lua_State *lstate, int nargs, int nresult, int flags)
FUNC_ATTR_NONNULL_ALL
{
int retval;
@@ -234,7 +236,7 @@ static int nlua_luv_cfpcall(lua_State *lstate, int nargs, int nresult,
multiqueue_put(main_loop.events, nlua_luv_error_event,
1, xstrdup(error));
- lua_pop(lstate, 1); // error mesage
+ lua_pop(lstate, 1); // error message
retval = -status;
} else { // LUA_OK
if (nresult == LUA_MULTRET) {
@@ -250,7 +252,7 @@ static int nlua_luv_cfpcall(lua_State *lstate, int nargs, int nresult,
static void nlua_schedule_event(void **argv)
{
LuaRef cb = (LuaRef)(ptrdiff_t)argv[0];
- lua_State *const lstate = nlua_enter();
+ lua_State *const lstate = global_lstate;
nlua_pushref(lstate, cb);
nlua_unref(lstate, cb);
if (lua_pcall(lstate, 0, 0, 0)) {
@@ -295,8 +297,7 @@ static void dummy_timer_close_cb(TimeWatcher *tw, void *data)
xfree(tw);
}
-static bool nlua_wait_condition(lua_State *lstate, int *status,
- bool *callback_result)
+static bool nlua_wait_condition(lua_State *lstate, int *status, bool *callback_result)
{
lua_pushvalue(lstate, 2);
*status = lua_pcall(lstate, 0, 1, 0);
@@ -331,9 +332,8 @@ static int nlua_wait(lua_State *lstate)
}
if (!is_function) {
- lua_pushliteral(
- lstate,
- "vim.wait: if passed, condition must be a function");
+ lua_pushliteral(lstate,
+ "vim.wait: if passed, condition must be a function");
return lua_error(lstate);
}
}
@@ -360,23 +360,20 @@ static int nlua_wait(lua_State *lstate)
time_watcher_init(&main_loop, tw, NULL);
tw->events = loop_events;
tw->blockable = true;
- time_watcher_start(
- tw,
- dummy_timer_due_cb,
- (uint64_t)interval,
- (uint64_t)interval);
+ time_watcher_start(tw,
+ dummy_timer_due_cb,
+ (uint64_t)interval,
+ (uint64_t)interval);
int pcall_status = 0;
bool callback_result = false;
- LOOP_PROCESS_EVENTS_UNTIL(
- &main_loop,
- loop_events,
- (int)timeout,
- is_function ? nlua_wait_condition(
- lstate,
- &pcall_status,
- &callback_result) : false || got_int);
+ LOOP_PROCESS_EVENTS_UNTIL(&main_loop,
+ loop_events,
+ (int)timeout,
+ is_function ? nlua_wait_condition(lstate,
+ &pcall_status,
+ &callback_result) : false || got_int);
// Stop dummy timer
time_watcher_stop(tw);
@@ -502,6 +499,8 @@ static int nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
lua_setfield(lstate, -2, "__tostring");
lua_setmetatable(lstate, -2);
nlua_nil_ref = nlua_ref(lstate, -1);
+ lua_pushvalue(lstate, -1);
+ lua_setfield(lstate, LUA_REGISTRYINDEX, "mpack.NIL");
lua_setfield(lstate, -2, "NIL");
// vim._empty_dict_mt
@@ -509,11 +508,33 @@ static int nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
lua_pushcfunction(lstate, &nlua_empty_dict_tostring);
lua_setfield(lstate, -2, "__tostring");
nlua_empty_dict_ref = nlua_ref(lstate, -1);
+ lua_pushvalue(lstate, -1);
+ lua_setfield(lstate, LUA_REGISTRYINDEX, "mpack.empty_dict");
lua_setfield(lstate, -2, "_empty_dict_mt");
+ // vim.mpack
+ luaopen_mpack(lstate);
+ lua_pushvalue(lstate, -1);
+ lua_setfield(lstate, -3, "mpack");
+
+ // package.loaded.mpack = vim.mpack
+ // otherwise luv will be reinitialized when require'mpack'
+ lua_getglobal(lstate, "package");
+ lua_getfield(lstate, -1, "loaded");
+ lua_pushvalue(lstate, -3);
+ lua_setfield(lstate, -2, "mpack");
+ lua_pop(lstate, 3);
+
// internal vim._treesitter... API
nlua_add_treesitter(lstate);
+ // vim.diff
+ lua_pushcfunction(lstate, &nlua_xdl_diff);
+ lua_setfield(lstate, -2, "diff");
+
+ lua_cjson_new(lstate);
+ lua_setfield(lstate, -2, "json");
+
lua_setglobal(lstate, "vim");
{
@@ -536,8 +557,17 @@ static int nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
return 1;
}
// [package, loaded, inspect]
-
lua_setfield(lstate, -2, "vim.inspect"); // [package, loaded]
+
+ code = (char *)&lua_F_module[0];
+ if (luaL_loadbuffer(lstate, code, strlen(code), "@vim/F.lua")
+ || lua_pcall(lstate, 0, 1, 0)) {
+ nlua_error(lstate, _("E5106: Error while creating vim.F module: %.*s"));
+ return 1;
+ }
+ // [package, loaded, module]
+ lua_setfield(lstate, -2, "vim.F"); // [package, loaded]
+
lua_pop(lstate, 2); // []
}
@@ -550,22 +580,34 @@ static int nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
}
}
+ {
+ lua_getglobal(lstate, "package"); // [package]
+ lua_getfield(lstate, -1, "loaded"); // [package, loaded]
+
+ const char *code = (char *)&lua_meta_module[0];
+ if (luaL_loadbuffer(lstate, code, strlen(code), "@vim/_meta.lua")
+ || lua_pcall(lstate, 0, 1, 0)) {
+ nlua_error(lstate, _("E5106: Error while creating vim._meta module: %.*s"));
+ return 1;
+ }
+ // [package, loaded, module]
+ lua_setfield(lstate, -2, "vim._meta"); // [package, loaded]
+
+ lua_pop(lstate, 2); // []
+ }
+
return 0;
}
-/// Initialize lua interpreter
-///
-/// Crashes Nvim if initialization fails. Should be called once per lua
-/// interpreter instance.
+/// Initialize global lua interpreter
///
-/// @return New lua interpreter instance.
-static lua_State *nlua_init(void)
- FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT
+/// Crashes Nvim if initialization fails.
+void nlua_init(void)
{
#ifdef NLUA_TRACK_REFS
const char *env = os_getenv("NVIM_LUA_NOTRACK");
if (!env || !*env) {
- nlua_ref_markers = pmap_new(handle_T)();
+ nlua_track_refs = true;
}
#endif
@@ -577,28 +619,9 @@ static lua_State *nlua_init(void)
luaL_openlibs(lstate);
nlua_state_init(lstate);
- return lstate;
+ global_lstate = lstate;
}
-// only to be used by nlua_enter and nlua_free_all_mem!
-static lua_State *global_lstate = NULL;
-
-/// Enter lua interpreter
-///
-/// Calls nlua_init() if needed. Is responsible for pre-lua call initalization
-/// like updating `package.[c]path` with directories derived from &runtimepath.
-///
-/// @return Interpreter instance to use. Will either be initialized now or
-/// taken from previous initialization.
-static lua_State *nlua_enter(void)
- FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT
-{
- if (global_lstate == NULL) {
- global_lstate = nlua_init();
- }
- lua_State *const lstate = global_lstate;
- return lstate;
-}
void nlua_free_all_mem(void)
{
@@ -615,10 +638,10 @@ void nlua_free_all_mem(void)
fprintf(stderr, "%d lua references were leaked!", nlua_refcount);
}
- if (nlua_ref_markers) {
+ if (nlua_track_refs) {
// in case there are leaked luarefs, leak the associated memory
// to get LeakSanitizer stacktraces on exit
- pmap_free(handle_T)(nlua_ref_markers);
+ pmap_destroy(handle_T)(&nlua_ref_markers);
}
#endif
@@ -635,22 +658,19 @@ static void nlua_print_event(void **argv)
const size_t start = i;
while (i < len) {
switch (str[i]) {
- case NUL: {
- str[i] = NL;
- i++;
- continue;
- }
- case NL: {
- // TODO(bfredl): use proper multiline msg? Probably should implement
- // print() in lua in terms of nvim_message(), when it is available.
- str[i] = NUL;
- i++;
- break;
- }
- default: {
- i++;
- continue;
- }
+ case NUL:
+ str[i] = NL;
+ i++;
+ continue;
+ case NL:
+ // TODO(bfredl): use proper multiline msg? Probably should implement
+ // print() in lua in terms of nvim_message(), when it is available.
+ str[i] = NUL;
+ i++;
+ break;
+ default:
+ i++;
+ continue;
}
break;
}
@@ -691,8 +711,7 @@ static int nlua_print(lua_State *const lstate)
size_t len;
const char *const s = lua_tolstring(lstate, -1, &len);
if (s == NULL) {
- PRINT_ERROR(
- "<Unknown error: lua_tolstring returned NULL for tostring result>");
+ PRINT_ERROR("<Unknown error: lua_tolstring returned NULL for tostring result>");
}
ga_concat_len(&msg_ga, s, len);
if (curargidx < nargs) {
@@ -800,13 +819,13 @@ int nlua_call(lua_State *lstate)
try_start();
typval_T rettv;
- int dummy;
+ funcexe_T funcexe = FUNCEXE_INIT;
+ funcexe.firstline = curwin->w_cursor.lnum;
+ funcexe.lastline = curwin->w_cursor.lnum;
+ funcexe.evaluate = true;
// call_func() retval is deceptive, ignore it. Instead we set `msg_list`
// (TRY_WRAP) to capture abort-causing non-exception errors.
- (void)call_func(name, (int)name_len, &rettv, nargs,
- vim_args, NULL,
- curwin->w_cursor.lnum, curwin->w_cursor.lnum,
- &dummy, true, NULL, NULL);
+ (void)call_func(name, (int)name_len, &rettv, nargs, vim_args, &funcexe);
if (!try_end(&err)) {
nlua_push_typval(lstate, &rettv, false);
}
@@ -865,7 +884,7 @@ static int nlua_rpc(lua_State *lstate, bool request)
} else {
if (!rpc_send_event(chan_id, name, args)) {
api_set_error(&err, kErrorTypeValidation,
- "Invalid channel: %"PRIu64, chan_id);
+ "Invalid channel: %" PRIu64, chan_id);
}
}
@@ -1017,10 +1036,10 @@ LuaRef nlua_ref(lua_State *lstate, int index)
if (ref > 0) {
nlua_refcount++;
#ifdef NLUA_TRACK_REFS
- if (nlua_ref_markers) {
- // dummy allocation to make LeakSanitizer track our luarefs
- pmap_put(handle_T)(nlua_ref_markers, ref, xmalloc(3));
- }
+ if (nlua_track_refs) {
+ // dummy allocation to make LeakSanitizer track our luarefs
+ pmap_put(handle_T)(&nlua_ref_markers, ref, xmalloc(3));
+ }
#endif
}
return ref;
@@ -1033,8 +1052,8 @@ void nlua_unref(lua_State *lstate, LuaRef ref)
nlua_refcount--;
#ifdef NLUA_TRACK_REFS
// NB: don't remove entry from map to track double-unref
- if (nlua_ref_markers) {
- xfree(pmap_get(handle_T)(nlua_ref_markers, ref));
+ if (nlua_track_refs) {
+ xfree(pmap_get(handle_T)(&nlua_ref_markers, ref));
}
#endif
luaL_unref(lstate, LUA_REGISTRYINDEX, ref);
@@ -1043,8 +1062,7 @@ void nlua_unref(lua_State *lstate, LuaRef ref)
void api_free_luaref(LuaRef ref)
{
- lua_State *const lstate = nlua_enter();
- nlua_unref(lstate, ref);
+ nlua_unref(global_lstate, ref);
}
/// push a value referenced in the registry
@@ -1064,7 +1082,7 @@ LuaRef api_new_luaref(LuaRef original_ref)
return LUA_NOREF;
}
- lua_State *const lstate = nlua_enter();
+ lua_State *const lstate = global_lstate;
nlua_pushref(lstate, original_ref);
LuaRef new_ref = nlua_ref(lstate, -1);
lua_pop(lstate, 1);
@@ -1081,8 +1099,7 @@ LuaRef api_new_luaref(LuaRef original_ref)
/// @param[out] ret_tv Location where result will be saved.
///
/// @return Result of the execution.
-void nlua_typval_eval(const String str, typval_T *const arg,
- typval_T *const ret_tv)
+void nlua_typval_eval(const String str, typval_T *const arg, typval_T *const ret_tv)
FUNC_ATTR_NONNULL_ALL
{
#define EVALHEADER "local _A=select(1,...) return ("
@@ -1104,8 +1121,8 @@ void nlua_typval_eval(const String str, typval_T *const arg,
}
}
-void nlua_typval_call(const char *str, size_t len, typval_T *const args,
- int argcount, typval_T *ret_tv)
+void nlua_typval_call(const char *str, size_t len, typval_T *const args, int argcount,
+ typval_T *ret_tv)
FUNC_ATTR_NONNULL_ALL
{
#define CALLHEADER "return "
@@ -1131,9 +1148,8 @@ void nlua_typval_call(const char *str, size_t len, typval_T *const args,
}
}
-static void nlua_typval_exec(const char *lcmd, size_t lcmd_len,
- const char *name, typval_T *const args,
- int argcount, bool special, typval_T *ret_tv)
+static void nlua_typval_exec(const char *lcmd, size_t lcmd_len, const char *name,
+ typval_T *const args, int argcount, bool special, typval_T *ret_tv)
{
if (check_secure()) {
if (ret_tv) {
@@ -1143,7 +1159,7 @@ static void nlua_typval_exec(const char *lcmd, size_t lcmd_len,
return;
}
- lua_State *const lstate = nlua_enter();
+ lua_State *const lstate = global_lstate;
if (luaL_loadbuffer(lstate, lcmd, lcmd_len, name)) {
nlua_error(lstate, _("E5107: Error loading lua %.*s"));
return;
@@ -1161,8 +1177,7 @@ static void nlua_typval_exec(const char *lcmd, size_t lcmd_len,
}
}
-int nlua_source_using_linegetter(LineGetter fgetline,
- void *cookie, char *name)
+int nlua_source_using_linegetter(LineGetter fgetline, void *cookie, char *name)
{
const linenr_T save_sourcing_lnum = sourcing_lnum;
const sctx_T save_current_sctx = current_sctx;
@@ -1198,13 +1213,8 @@ int nlua_source_using_linegetter(LineGetter fgetline,
/// @param[in] argcount Count of typval arguments
/// @param[in] argvars Typval Arguments
/// @param[out] rettv The return value from the called function.
-int typval_exec_lua_callable(
- lua_State *lstate,
- LuaCallable lua_cb,
- int argcount,
- typval_T *argvars,
- typval_T *rettv
-)
+int typval_exec_lua_callable(lua_State *lstate, LuaCallable lua_cb, int argcount, typval_T *argvars,
+ typval_T *rettv)
{
LuaRef cb = lua_cb.func_ref;
@@ -1233,7 +1243,7 @@ int typval_exec_lua_callable(
/// @return Return value of the execution.
Object nlua_exec(const String str, const Array args, Error *err)
{
- lua_State *const lstate = nlua_enter();
+ lua_State *const lstate = global_lstate;
if (luaL_loadbuffer(lstate, str.data, str.size, "<nvim>")) {
size_t len;
@@ -1267,10 +1277,9 @@ Object nlua_exec(const String str, const Array args, Error *err)
/// if false, discard return value
/// @param err Error details, if any (if NULL, errors are echoed)
/// @return Return value of function, if retval was set. Otherwise NIL.
-Object nlua_call_ref(LuaRef ref, const char *name, Array args,
- bool retval, Error *err)
+Object nlua_call_ref(LuaRef ref, const char *name, Array args, bool retval, Error *err)
{
- lua_State *const lstate = nlua_enter();
+ lua_State *const lstate = global_lstate;
nlua_pushref(lstate, ref);
int nargs = (int)args.size;
if (name != NULL) {
@@ -1346,7 +1355,7 @@ void ex_luado(exarg_T *const eap)
const char *const cmd = (const char *)eap->arg;
const size_t cmd_len = strlen(cmd);
- lua_State *const lstate = nlua_enter();
+ lua_State *const lstate = global_lstate;
#define DOSTART "return function(line, linenr) "
#define DOEND " end"
@@ -1431,7 +1440,7 @@ void ex_luafile(exarg_T *const eap)
bool nlua_exec_file(const char *path)
FUNC_ATTR_NONNULL_ALL
{
- lua_State *const lstate = nlua_enter();
+ lua_State *const lstate = global_lstate;
if (luaL_loadfile(lstate, path)) {
nlua_error(lstate, _("E5112: Error while creating lua chunk: %.*s"));
@@ -1475,12 +1484,9 @@ static void nlua_add_treesitter(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
lua_setfield(lstate, -2, "_ts_get_language_version");
}
-int nlua_expand_pat(expand_T *xp,
- char_u *pat,
- int *num_results,
- char_u ***results)
+int nlua_expand_pat(expand_T *xp, char_u *pat, int *num_results, char_u ***results)
{
- lua_State *const lstate = nlua_enter();
+ lua_State *const lstate = global_lstate;
int ret = OK;
// [ vim ]
@@ -1490,13 +1496,12 @@ int nlua_expand_pat(expand_T *xp,
lua_getfield(lstate, -1, "_expand_pat");
luaL_checktype(lstate, -1, LUA_TFUNCTION);
- // [ vim, vim._log_keystroke, buf ]
+ // [ vim, vim._on_key, buf ]
lua_pushlstring(lstate, (const char *)pat, STRLEN(pat));
if (lua_pcall(lstate, 1, 2, 0) != 0) {
- nlua_error(
- lstate,
- _("Error executing vim._expand_pat: %.*s"));
+ nlua_error(lstate,
+ _("Error executing vim._expand_pat: %.*s"));
return FAIL;
}
@@ -1527,10 +1532,9 @@ int nlua_expand_pat(expand_T *xp,
goto cleanup_array;
}
- GA_APPEND(
- char_u *,
- &result_array,
- vim_strsave((char_u *)v.data.string.data));
+ GA_APPEND(char_u *,
+ &result_array,
+ vim_strsave((char_u *)v.data.string.data));
}
xp->xp_pattern += prefix_len;
@@ -1684,26 +1688,22 @@ static int regex_match_line(lua_State *lstate)
// Required functions for lua c functions as VimL callbacks
-int nlua_CFunction_func_call(
- int argcount,
- typval_T *argvars,
- typval_T *rettv,
- void *state)
+int nlua_CFunction_func_call(int argcount, typval_T *argvars, typval_T *rettv, void *state)
{
- lua_State *const lstate = nlua_enter();
- LuaCFunctionState *funcstate = (LuaCFunctionState *)state;
+ lua_State *const lstate = global_lstate;
+ LuaCFunctionState *funcstate = (LuaCFunctionState *)state;
- return typval_exec_lua_callable(lstate, funcstate->lua_callable,
- argcount, argvars, rettv);
+ return typval_exec_lua_callable(lstate, funcstate->lua_callable,
+ argcount, argvars, rettv);
}
void nlua_CFunction_func_free(void *state)
{
- lua_State *const lstate = nlua_enter();
- LuaCFunctionState *funcstate = (LuaCFunctionState *)state;
+ lua_State *const lstate = global_lstate;
+ LuaCFunctionState *funcstate = (LuaCFunctionState *)state;
- nlua_unref(lstate, funcstate->lua_callable.func_ref);
- xfree(funcstate);
+ nlua_unref(lstate, funcstate->lua_callable.func_ref);
+ xfree(funcstate);
}
bool nlua_is_table_from_lua(typval_T *const arg)
@@ -1730,7 +1730,7 @@ char_u *nlua_register_table_as_callable(typval_T *const arg)
return NULL;
}
- lua_State *const lstate = nlua_enter();
+ lua_State *const lstate = global_lstate;
#ifndef NDEBUG
int top = lua_gettop(lstate);
@@ -1764,12 +1764,12 @@ char_u *nlua_register_table_as_callable(typval_T *const arg)
return name;
}
-void nlua_execute_log_keystroke(int c)
+void nlua_execute_on_key(int c)
{
char_u buf[NUMBUFLEN];
size_t buf_len = special_to_buf(c, mod_mask, false, buf);
- lua_State *const lstate = nlua_enter();
+ lua_State *const lstate = global_lstate;
#ifndef NDEBUG
int top = lua_gettop(lstate);
@@ -1778,17 +1778,16 @@ void nlua_execute_log_keystroke(int c)
// [ vim ]
lua_getglobal(lstate, "vim");
- // [ vim, vim._log_keystroke ]
- lua_getfield(lstate, -1, "_log_keystroke");
+ // [ vim, vim._on_key]
+ lua_getfield(lstate, -1, "_on_key");
luaL_checktype(lstate, -1, LUA_TFUNCTION);
- // [ vim, vim._log_keystroke, buf ]
+ // [ vim, vim._on_key, buf ]
lua_pushlstring(lstate, (const char *)buf, buf_len);
if (lua_pcall(lstate, 1, 0, 0)) {
- nlua_error(
- lstate,
- _("Error executing vim.log_keystroke lua callback: %.*s"));
+ nlua_error(lstate,
+ _("Error executing vim.on_key Lua callback: %.*s"));
}
// [ vim ]
diff --git a/src/nvim/lua/treesitter.c b/src/nvim/lua/treesitter.c
index e3fa48f530..37929093e3 100644
--- a/src/nvim/lua/treesitter.c
+++ b/src/nvim/lua/treesitter.c
@@ -5,22 +5,20 @@
// NB: this file mostly contains a generic lua interface for tree-sitter
// trees and nodes, and could be broken out as a reusable lua package
-#include <stdbool.h>
-#include <stdlib.h>
-#include <string.h>
-#include <inttypes.h>
#include <assert.h>
-
+#include <inttypes.h>
+#include <lauxlib.h>
#include <lua.h>
#include <lualib.h>
-#include <lauxlib.h>
-
-#include "tree_sitter/api.h"
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include "nvim/api/private/helpers.h"
+#include "nvim/buffer.h"
#include "nvim/lua/treesitter.h"
-#include "nvim/api/private/handle.h"
#include "nvim/memline.h"
-#include "nvim/buffer.h"
+#include "tree_sitter/api.h"
#define TS_META_PARSER "treesitter_parser"
#define TS_META_TREE "treesitter_tree"
@@ -80,6 +78,10 @@ static struct luaL_Reg node_meta[] = {
{ "parent", node_parent },
{ "iter_children", node_iter_children },
{ "_rawquery", node_rawquery },
+ { "next_sibling", node_next_sibling },
+ { "prev_sibling", node_prev_sibling },
+ { "next_named_sibling", node_next_named_sibling },
+ { "prev_named_sibling", node_prev_named_sibling },
{ NULL, NULL }
};
@@ -101,7 +103,7 @@ static struct luaL_Reg treecursor_meta[] = {
{ NULL, NULL }
};
-static PMap(cstr_t) *langs;
+static PMap(cstr_t) langs = MAP_INIT;
static void build_meta(lua_State *L, const char *tname, const luaL_Reg *meta)
{
@@ -119,8 +121,6 @@ static void build_meta(lua_State *L, const char *tname, const luaL_Reg *meta)
/// all global state is stored in the regirstry of the lua_State
void tslua_init(lua_State *L)
{
- langs = pmap_new(cstr_t)();
-
// type metatables
build_meta(L, TS_META_PARSER, parser_meta);
build_meta(L, TS_META_TREE, tree_meta);
@@ -133,7 +133,7 @@ void tslua_init(lua_State *L)
int tslua_has_language(lua_State *L)
{
const char *lang_name = luaL_checkstring(L, 1);
- lua_pushboolean(L, pmap_has(cstr_t)(langs, lang_name));
+ lua_pushboolean(L, pmap_has(cstr_t)(&langs, lang_name));
return 1;
}
@@ -142,7 +142,7 @@ int tslua_add_language(lua_State *L)
const char *path = luaL_checkstring(L, 1);
const char *lang_name = luaL_checkstring(L, 2);
- if (pmap_has(cstr_t)(langs, lang_name)) {
+ if (pmap_has(cstr_t)(&langs, lang_name)) {
return 0;
}
@@ -177,15 +177,14 @@ int tslua_add_language(lua_State *L)
uint32_t lang_version = ts_language_version(lang);
if (lang_version < TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION
|| lang_version > TREE_SITTER_LANGUAGE_VERSION) {
- return luaL_error(
- L,
- "ABI version mismatch for %s: supported between %d and %d, found %d",
- path,
- TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION,
- TREE_SITTER_LANGUAGE_VERSION, lang_version);
+ return luaL_error(L,
+ "ABI version mismatch for %s: supported between %d and %d, found %d",
+ path,
+ TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION,
+ TREE_SITTER_LANGUAGE_VERSION, lang_version);
}
- pmap_put(cstr_t)(langs, xstrdup(lang_name), lang);
+ pmap_put(cstr_t)(&langs, xstrdup(lang_name), lang);
lua_pushboolean(L, true);
return 1;
@@ -195,7 +194,7 @@ int tslua_inspect_lang(lua_State *L)
{
const char *lang_name = luaL_checkstring(L, 1);
- TSLanguage *lang = pmap_get(cstr_t)(langs, lang_name);
+ TSLanguage *lang = pmap_get(cstr_t)(&langs, lang_name);
if (!lang) {
return luaL_error(L, "no such language: %s", lang_name);
}
@@ -243,7 +242,7 @@ int tslua_push_parser(lua_State *L)
// Gather language name
const char *lang_name = luaL_checkstring(L, 1);
- TSLanguage *lang = pmap_get(cstr_t)(langs, lang_name);
+ TSLanguage *lang = pmap_get(cstr_t)(&langs, lang_name);
if (!lang) {
return luaL_error(L, "no such language: %s", lang_name);
}
@@ -261,7 +260,7 @@ int tslua_push_parser(lua_State *L)
return 1;
}
-static TSParser ** parser_check(lua_State *L, uint16_t index)
+static TSParser **parser_check(lua_State *L, uint16_t index)
{
return luaL_checkudata(L, index, TS_META_PARSER);
}
@@ -283,8 +282,8 @@ static int parser_tostring(lua_State *L)
return 1;
}
-static const char *input_cb(void *payload, uint32_t byte_index,
- TSPoint position, uint32_t *bytes_read)
+static const char *input_cb(void *payload, uint32_t byte_index, TSPoint position,
+ uint32_t *bytes_read)
{
buf_T *bp = payload;
#define BUFSIZE 256
@@ -316,9 +315,7 @@ static const char *input_cb(void *payload, uint32_t byte_index,
#undef BUFSIZE
}
-static void push_ranges(lua_State *L,
- const TSRange *ranges,
- const unsigned int length)
+static void push_ranges(lua_State *L, const TSRange *ranges, const unsigned int length)
{
lua_createtable(L, length, 0);
for (size_t i = 0; i < length; i++) {
@@ -359,40 +356,39 @@ static int parser_parse(lua_State *L)
// This switch is necessary because of the behavior of lua_isstring, that
// consider numbers as strings...
switch (lua_type(L, 3)) {
- case LUA_TSTRING:
- str = lua_tolstring(L, 3, &len);
- new_tree = ts_parser_parse_string(*p, old_tree, str, len);
- break;
+ case LUA_TSTRING:
+ str = lua_tolstring(L, 3, &len);
+ new_tree = ts_parser_parse_string(*p, old_tree, str, len);
+ break;
- case LUA_TNUMBER:
- bufnr = lua_tointeger(L, 3);
- buf = handle_get_buffer(bufnr);
+ case LUA_TNUMBER:
+ bufnr = lua_tointeger(L, 3);
+ buf = handle_get_buffer(bufnr);
- if (!buf) {
- return luaL_error(L, "invalid buffer handle: %d", bufnr);
- }
+ if (!buf) {
+ return luaL_error(L, "invalid buffer handle: %d", bufnr);
+ }
- input = (TSInput){ (void *)buf, input_cb, TSInputEncodingUTF8 };
- new_tree = ts_parser_parse(*p, old_tree, input);
+ input = (TSInput){ (void *)buf, input_cb, TSInputEncodingUTF8 };
+ new_tree = ts_parser_parse(*p, old_tree, input);
- break;
+ break;
- default:
- return luaL_error(L, "invalid argument to parser:parse()");
+ default:
+ return luaL_error(L, "invalid argument to parser:parse()");
}
// Sometimes parsing fails (timeout, or wrong parser ABI)
// In those case, just return an error.
if (!new_tree) {
- return luaL_error(L, "An error occured when parsing.");
+ return luaL_error(L, "An error occurred when parsing.");
}
// The new tree will be pushed to the stack, without copy, owwership is now to
// the lua GC.
// Old tree is still owned by the lua GC.
uint32_t n_ranges = 0;
- TSRange *changed = old_tree ? ts_tree_get_changed_ranges(
- old_tree, new_tree, &n_ranges) : NULL;
+ TSRange *changed = old_tree ? ts_tree_get_changed_ranges(old_tree, new_tree, &n_ranges) : NULL;
push_tree(L, new_tree, false); // [tree]
@@ -502,17 +498,15 @@ static void range_from_lua(lua_State *L, TSRange *range)
}
return;
error:
- luaL_error(
- L,
- "Ranges can only be made from 6 element long tables or nodes.");
+ luaL_error(L,
+ "Ranges can only be made from 6 element long tables or nodes.");
}
static int parser_set_ranges(lua_State *L)
{
if (lua_gettop(L) < 2) {
- return luaL_error(
- L,
- "not enough args to parser:set_included_ranges()");
+ return luaL_error(L,
+ "not enough args to parser:set_included_ranges()");
}
TSParser **p = parser_check(L, 1);
@@ -521,9 +515,8 @@ static int parser_set_ranges(lua_State *L)
}
if (!lua_istable(L, 2)) {
- return luaL_error(
- L,
- "argument for parser:set_included_ranges() should be a table.");
+ return luaL_error(L,
+ "argument for parser:set_included_ranges() should be a table.");
}
size_t tbl_len = lua_objlen(L, 2);
@@ -888,9 +881,9 @@ static int node_descendant_for_range(lua_State *L)
return 0;
}
TSPoint start = { (uint32_t)lua_tointeger(L, 2),
- (uint32_t)lua_tointeger(L, 3) };
+ (uint32_t)lua_tointeger(L, 3) };
TSPoint end = { (uint32_t)lua_tointeger(L, 4),
- (uint32_t)lua_tointeger(L, 5) };
+ (uint32_t)lua_tointeger(L, 5) };
TSNode child = ts_node_descendant_for_point_range(node, start, end);
push_node(L, child, 1);
@@ -904,9 +897,9 @@ static int node_named_descendant_for_range(lua_State *L)
return 0;
}
TSPoint start = { (uint32_t)lua_tointeger(L, 2),
- (uint32_t)lua_tointeger(L, 3) };
+ (uint32_t)lua_tointeger(L, 3) };
TSPoint end = { (uint32_t)lua_tointeger(L, 4),
- (uint32_t)lua_tointeger(L, 5) };
+ (uint32_t)lua_tointeger(L, 5) };
TSNode child = ts_node_named_descendant_for_point_range(node, start, end);
push_node(L, child, 1);
@@ -915,8 +908,7 @@ static int node_named_descendant_for_range(lua_State *L)
static int node_next_child(lua_State *L)
{
- TSTreeCursor *ud = luaL_checkudata(
- L, lua_upvalueindex(1), TS_META_TREECURSOR);
+ TSTreeCursor *ud = luaL_checkudata(L, lua_upvalueindex(1), TS_META_TREECURSOR);
if (!ud) {
return 0;
}
@@ -937,19 +929,18 @@ static int node_next_child(lua_State *L)
if (ts_tree_cursor_goto_next_sibling(ud)) {
push:
- push_node(
- L,
- ts_tree_cursor_current_node(ud),
- lua_upvalueindex(2)); // [node]
+ push_node(L,
+ ts_tree_cursor_current_node(ud),
+ lua_upvalueindex(2)); // [node]
- const char * field = ts_tree_cursor_current_field_name(ud);
+ const char * field = ts_tree_cursor_current_field_name(ud);
- if (field != NULL) {
- lua_pushstring(L, ts_tree_cursor_current_field_name(ud));
- } else {
- lua_pushnil(L);
- } // [node, field_name_or_nil]
- return 2;
+ if (field != NULL) {
+ lua_pushstring(L, ts_tree_cursor_current_field_name(ud));
+ } else {
+ lua_pushnil(L);
+ } // [node, field_name_or_nil]
+ return 2;
}
end:
@@ -992,6 +983,50 @@ static int node_parent(lua_State *L)
return 1;
}
+static int node_next_sibling(lua_State *L)
+{
+ TSNode node;
+ if (!node_check(L, 1, &node)) {
+ return 0;
+ }
+ TSNode sibling = ts_node_next_sibling(node);
+ push_node(L, sibling, 1);
+ return 1;
+}
+
+static int node_prev_sibling(lua_State *L)
+{
+ TSNode node;
+ if (!node_check(L, 1, &node)) {
+ return 0;
+ }
+ TSNode sibling = ts_node_prev_sibling(node);
+ push_node(L, sibling, 1);
+ return 1;
+}
+
+static int node_next_named_sibling(lua_State *L)
+{
+ TSNode node;
+ if (!node_check(L, 1, &node)) {
+ return 0;
+ }
+ TSNode sibling = ts_node_next_named_sibling(node);
+ push_node(L, sibling, 1);
+ return 1;
+}
+
+static int node_prev_named_sibling(lua_State *L)
+{
+ TSNode node;
+ if (!node_check(L, 1, &node)) {
+ return 0;
+ }
+ TSNode sibling = ts_node_prev_named_sibling(node);
+ push_node(L, sibling, 1);
+ return 1;
+}
+
/// assumes the match table being on top of the stack
static void set_match(lua_State *L, TSQueryMatch *match, int nodeidx)
{
@@ -1127,7 +1162,7 @@ int tslua_parse_query(lua_State *L)
}
const char *lang_name = lua_tostring(L, 1);
- TSLanguage *lang = pmap_get(cstr_t)(langs, lang_name);
+ TSLanguage *lang = pmap_get(cstr_t)(&langs, lang_name);
if (!lang) {
return luaL_error(L, "no such language: %s", lang_name);
}
@@ -1154,11 +1189,16 @@ int tslua_parse_query(lua_State *L)
static const char *query_err_string(TSQueryError err) {
switch (err) {
- case TSQueryErrorSyntax: return "invalid syntax";
- case TSQueryErrorNodeType: return "invalid node type";
- case TSQueryErrorField: return "invalid field";
- case TSQueryErrorCapture: return "invalid capture";
- default: return "error";
+ case TSQueryErrorSyntax:
+ return "invalid syntax";
+ case TSQueryErrorNodeType:
+ return "invalid node type";
+ case TSQueryErrorField:
+ return "invalid field";
+ case TSQueryErrorCapture:
+ return "invalid capture";
+ default:
+ return "error";
}
}
diff --git a/src/nvim/lua/vim.lua b/src/nvim/lua/vim.lua
index 8cecaa51dd..7a209f2d79 100644
--- a/src/nvim/lua/vim.lua
+++ b/src/nvim/lua/vim.lua
@@ -4,6 +4,7 @@
-- 1. runtime/lua/vim/ (the runtime): For "nice to have" features, e.g. the
-- `inspect` and `lpeg` modules.
-- 2. runtime/lua/vim/shared.lua: Code shared between Nvim and tests.
+-- (This will go away if we migrate to nvim as the test-runner.)
-- 3. src/nvim/lua/: Compiled-into Nvim itself.
--
-- Guideline: "If in doubt, put it in the runtime".
@@ -104,6 +105,12 @@ setmetatable(vim, {
elseif key == 'highlight' then
t.highlight = require('vim.highlight')
return t.highlight
+ elseif key == 'diagnostic' then
+ t.diagnostic = require('vim.diagnostic')
+ return t.diagnostic
+ elseif key == 'ui' then
+ t.ui = require('vim.ui')
+ return t.ui
end
end
})
@@ -178,8 +185,8 @@ end
--- Return a human-readable representation of the given object.
---
---@see https://github.com/kikito/inspect.lua
---@see https://github.com/mpeterv/vinspect
+---@see https://github.com/kikito/inspect.lua
+---@see https://github.com/mpeterv/vinspect
local function inspect(object, options) -- luacheck: no unused
error(object, options) -- Stub for gen_vimdoc.py
end
@@ -203,15 +210,15 @@ do
--- end)(vim.paste)
--- </pre>
---
- --@see |paste|
+ ---@see |paste|
---
- --@param lines |readfile()|-style list of lines to paste. |channel-lines|
- --@param phase -1: "non-streaming" paste: the call contains all lines.
+ ---@param lines |readfile()|-style list of lines to paste. |channel-lines|
+ ---@param phase -1: "non-streaming" paste: the call contains all lines.
--- If paste is "streamed", `phase` indicates the stream state:
--- - 1: starts the paste (exactly once)
--- - 2: continues the paste (zero or more times)
--- - 3: ends the paste (exactly once)
- --@returns false if client should cancel the paste.
+ ---@returns false if client should cancel the paste.
function vim.paste(lines, phase)
local call = vim.api.nvim_call_function
local now = vim.loop.now()
@@ -273,13 +280,13 @@ end
---@see |vim.in_fast_event()|
function vim.schedule_wrap(cb)
return (function (...)
- local args = {...}
- vim.schedule(function() cb(unpack(args)) end)
+ local args = vim.F.pack_len(...)
+ vim.schedule(function() cb(vim.F.unpack_len(args)) end)
end)
end
--- <Docs described in |vim.empty_dict()| >
---@private
+---@private
function vim.empty_dict()
return setmetatable({}, vim._empty_dict_mt)
end
@@ -338,12 +345,12 @@ end
--- Get a table of lines with start, end columns for a region marked by two points
---
---@param bufnr number of buffer
---@param pos1 (line, column) tuple marking beginning of region
---@param pos2 (line, column) tuple marking end of region
---@param regtype type of selection (:help setreg)
---@param inclusive boolean indicating whether the selection is end-inclusive
---@return region lua table of the form {linenr = {startcol,endcol}}
+---@param bufnr number of buffer
+---@param pos1 (line, column) tuple marking beginning of region
+---@param pos2 (line, column) tuple marking end of region
+---@param regtype type of selection (:help setreg)
+---@param inclusive boolean indicating whether the selection is end-inclusive
+---@return region lua table of the form {linenr = {startcol,endcol}}
function vim.region(bufnr, pos1, pos2, regtype, inclusive)
if not vim.api.nvim_buf_is_loaded(bufnr) then
vim.fn.bufload(bufnr)
@@ -390,9 +397,9 @@ end
--- Use to do a one-shot timer that calls `fn`
--- Note: The {fn} is |schedule_wrap|ped automatically, so API functions are
--- safe to call.
---@param fn Callback to call once `timeout` expires
---@param timeout Number of milliseconds to wait before calling `fn`
---@return timer luv timer object
+---@param fn Callback to call once `timeout` expires
+---@param timeout Number of milliseconds to wait before calling `fn`
+---@return timer luv timer object
function vim.defer_fn(fn, timeout)
vim.validate { fn = { fn, 'c', true}; }
local timer = vim.loop.new_timer()
@@ -408,11 +415,12 @@ end
--- Notification provider
---- without a runtime, writes to :Messages
--- see :help nvim_notify
---@param msg Content of the notification to show to the user
---@param log_level Optional log level
---@param opts Dictionary with optional options (timeout, etc)
+---
+--- Without a runtime, writes to :Messages
+---@see :help nvim_notify
+---@param msg Content of the notification to show to the user
+---@param log_level Optional log level
+---@param opts Dictionary with optional options (timeout, etc)
function vim.notify(msg, log_level, _opts)
if log_level == vim.log.levels.ERROR then
@@ -425,26 +433,35 @@ function vim.notify(msg, log_level, _opts)
end
-local on_keystroke_callbacks = {}
+function vim.register_keystroke_callback()
+ error('vim.register_keystroke_callback is deprecated, instead use: vim.on_key')
+end
+
+local on_key_cbs = {}
---- Register a lua {fn} with an {id} to be run after every keystroke.
+--- Adds Lua function {fn} with namespace id {ns_id} as a listener to every,
+--- yes every, input key.
---
---@param fn function: Function to call. It should take one argument, which is a string.
---- The string will contain the literal keys typed.
---- See |i_CTRL-V|
+--- The Nvim command-line option |-w| is related but does not support callbacks
+--- and cannot be toggled dynamically.
---
+---@param fn function: Callback function. It should take one string argument.
+--- On each key press, Nvim passes the key char to fn(). |i_CTRL-V|
--- If {fn} is nil, it removes the callback for the associated {ns_id}
---@param ns_id number? Namespace ID. If not passed or 0, will generate and return a new
---- namespace ID from |nvim_create_namesapce()|
+---@param ns_id number? Namespace ID. If nil or 0, generates and returns a new
+--- |nvim_create_namesapce()| id.
---
---@return number Namespace ID associated with {fn}
+---@return number Namespace id associated with {fn}. Or count of all callbacks
+---if on_key() is called without arguments.
---
---@note {fn} will be automatically removed if an error occurs while calling.
---- This is to prevent the annoying situation of every keystroke erroring
---- while trying to remove a broken callback.
---@note {fn} will not be cleared from |nvim_buf_clear_namespace()|
---@note {fn} will receive the keystrokes after mappings have been evaluated
-function vim.register_keystroke_callback(fn, ns_id)
+---@note {fn} will be removed if an error occurs while calling.
+---@note {fn} will not be cleared by |nvim_buf_clear_namespace()|
+---@note {fn} will receive the keys after mappings have been evaluated
+function vim.on_key(fn, ns_id)
+ if fn == nil and ns_id == nil then
+ return #on_key_cbs
+ end
+
vim.validate {
fn = { fn, 'c', true},
ns_id = { ns_id, 'n', true }
@@ -454,20 +471,19 @@ function vim.register_keystroke_callback(fn, ns_id)
ns_id = vim.api.nvim_create_namespace('')
end
- on_keystroke_callbacks[ns_id] = fn
+ on_key_cbs[ns_id] = fn
return ns_id
end
---- Function that executes the keystroke callbacks.
---@private
-function vim._log_keystroke(char)
+--- Executes the on_key callbacks.
+---@private
+function vim._on_key(char)
local failed_ns_ids = {}
local failed_messages = {}
- for k, v in pairs(on_keystroke_callbacks) do
+ for k, v in pairs(on_key_cbs) do
local ok, err_msg = pcall(v, char)
if not ok then
- vim.register_keystroke_callback(nil, k)
-
+ vim.on_key(nil, k)
table.insert(failed_ns_ids, k)
table.insert(failed_messages, err_msg)
end
@@ -475,7 +491,7 @@ function vim._log_keystroke(char)
if failed_ns_ids[1] then
error(string.format(
- "Error executing 'on_keystroke' with ns_ids of '%s'\n With messages: %s",
+ "Error executing 'on_key' with ns_ids '%s'\n Messages: %s",
table.concat(failed_ns_ids, ", "),
table.concat(failed_messages, "\n")))
end
@@ -641,6 +657,4 @@ vim._expand_pat_get_parts = function(lua_string)
return parts, search_index
end
-pcall(require, 'vim._meta')
-
return module
diff --git a/src/nvim/lua/xdiff.c b/src/nvim/lua/xdiff.c
new file mode 100644
index 0000000000..3955fbe72c
--- /dev/null
+++ b/src/nvim/lua/xdiff.c
@@ -0,0 +1,332 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
+#include <errno.h>
+#include <lauxlib.h>
+#include <lua.h>
+#include <lualib.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "nvim/api/private/helpers.h"
+#include "nvim/lua/converter.h"
+#include "nvim/lua/executor.h"
+#include "nvim/lua/xdiff.h"
+#include "nvim/vim.h"
+#include "xdiff/xdiff.h"
+
+typedef enum {
+ kNluaXdiffModeUnified = 0,
+ kNluaXdiffModeOnHunkCB,
+ kNluaXdiffModeLocations,
+} NluaXdiffMode;
+
+typedef struct {
+ lua_State *lstate;
+ Error *err;
+} hunkpriv_t;
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "lua/xdiff.c.generated.h"
+#endif
+
+static int write_string(void *priv, mmbuffer_t *mb, int nbuf)
+{
+ luaL_Buffer *buf = (luaL_Buffer *)priv;
+ for (int i = 0; i < nbuf; i++) {
+ const long size = mb[i].size;
+ for (long total = 0; total < size; total += LUAL_BUFFERSIZE) {
+ const int tocopy = MIN((int)(size - total), LUAL_BUFFERSIZE);
+ char *p = luaL_prepbuffer(buf);
+ if (!p) {
+ return -1;
+ }
+ memcpy(p, mb[i].ptr + total, (unsigned)tocopy);
+ luaL_addsize(buf, (unsigned)tocopy);
+ }
+ }
+ return 0;
+}
+
+// hunk_func callback used when opts.hunk_lines = true
+static int hunk_locations_cb(long start_a, long count_a, long start_b, long count_b, void *cb_data)
+{
+ // Mimic extra offsets done by xdiff, see:
+ // src/xdiff/xemit.c:284
+ // src/xdiff/xutils.c:(356,368)
+ if (count_a > 0) {
+ start_a += 1;
+ }
+ if (count_b > 0) {
+ start_b += 1;
+ }
+
+ lua_State * lstate = (lua_State *)cb_data;
+ lua_createtable(lstate, 0, 0);
+
+ lua_pushinteger(lstate, start_a);
+ lua_rawseti(lstate, -2, 1);
+ lua_pushinteger(lstate, count_a);
+ lua_rawseti(lstate, -2, 2);
+ lua_pushinteger(lstate, start_b);
+ lua_rawseti(lstate, -2, 3);
+ lua_pushinteger(lstate, count_b);
+ lua_rawseti(lstate, -2, 4);
+
+ lua_rawseti(lstate, -2, (signed)lua_objlen(lstate, -2)+1);
+
+ return 0;
+}
+
+// hunk_func callback used when opts.on_hunk is given
+static int call_on_hunk_cb(long start_a, long count_a, long start_b, long count_b, void *cb_data)
+{
+ // Mimic extra offsets done by xdiff, see:
+ // src/xdiff/xemit.c:284
+ // src/xdiff/xutils.c:(356,368)
+ if (count_a > 0) {
+ start_a += 1;
+ }
+ if (count_b > 0) {
+ start_b += 1;
+ }
+
+ hunkpriv_t *priv = (hunkpriv_t *)cb_data;
+ lua_State * lstate = priv->lstate;
+ Error *err = priv->err;
+ const int fidx = lua_gettop(lstate);
+ lua_pushvalue(lstate, fidx);
+ lua_pushinteger(lstate, start_a);
+ lua_pushinteger(lstate, count_a);
+ lua_pushinteger(lstate, start_b);
+ lua_pushinteger(lstate, count_b);
+
+ if (lua_pcall(lstate, 4, 1, 0) != 0) {
+ api_set_error(err, kErrorTypeException,
+ "error running function on_hunk: %s",
+ lua_tostring(lstate, -1));
+ return -1;
+ }
+
+ int r = 0;
+ if (lua_isnumber(lstate, -1)) {
+ r = (int)lua_tonumber(lstate, -1);
+ }
+
+ lua_pop(lstate, 1);
+ lua_settop(lstate, fidx);
+ return r;
+}
+
+static mmfile_t get_string_arg(lua_State *lstate, int idx)
+{
+ if (lua_type(lstate, idx) != LUA_TSTRING) {
+ luaL_argerror(lstate, idx, "expected string");
+ }
+ mmfile_t mf;
+ mf.ptr = (char *)lua_tolstring(lstate, idx, (size_t *)&mf.size);
+ return mf;
+}
+
+// Helper function for validating option types
+static bool check_xdiff_opt(ObjectType actType, ObjectType expType, const char *name, Error *err)
+{
+ if (actType != expType) {
+ const char * type_str =
+ expType == kObjectTypeString ? "string" :
+ expType == kObjectTypeInteger ? "integer" :
+ expType == kObjectTypeBoolean ? "boolean" :
+ expType == kObjectTypeLuaRef ? "function" :
+ "NA";
+
+ api_set_error(err, kErrorTypeValidation, "%s is not a %s", name,
+ type_str);
+ return true;
+ }
+
+ return false;
+}
+
+static NluaXdiffMode process_xdl_diff_opts(lua_State *lstate, xdemitconf_t *cfg, xpparam_t *params,
+ Error *err)
+{
+ const DictionaryOf(LuaRef) opts = nlua_pop_Dictionary(lstate, true, err);
+
+ NluaXdiffMode mode = kNluaXdiffModeUnified;
+
+ bool had_on_hunk = false;
+ bool had_result_type_indices = false;
+ for (size_t i = 0; i < opts.size; i++) {
+ String k = opts.items[i].key;
+ Object *v = &opts.items[i].value;
+ if (strequal("on_hunk", k.data)) {
+ if (check_xdiff_opt(v->type, kObjectTypeLuaRef, "on_hunk", err)) {
+ goto exit_1;
+ }
+ had_on_hunk = true;
+ nlua_pushref(lstate, v->data.luaref);
+ } else if (strequal("result_type", k.data)) {
+ if (check_xdiff_opt(v->type, kObjectTypeString, "result_type", err)) {
+ goto exit_1;
+ }
+ if (strequal("unified", v->data.string.data)) {
+ } else if (strequal("indices", v->data.string.data)) {
+ had_result_type_indices = true;
+ } else {
+ api_set_error(err, kErrorTypeValidation, "not a valid result_type");
+ goto exit_1;
+ }
+ } else if (strequal("algorithm", k.data)) {
+ if (check_xdiff_opt(v->type, kObjectTypeString, "algorithm", err)) {
+ goto exit_1;
+ }
+ if (strequal("myers", v->data.string.data)) {
+ // default
+ } else if (strequal("minimal", v->data.string.data)) {
+ cfg->flags |= XDF_NEED_MINIMAL;
+ } else if (strequal("patience", v->data.string.data)) {
+ cfg->flags |= XDF_PATIENCE_DIFF;
+ } else if (strequal("histogram", v->data.string.data)) {
+ cfg->flags |= XDF_HISTOGRAM_DIFF;
+ } else {
+ api_set_error(err, kErrorTypeValidation, "not a valid algorithm");
+ goto exit_1;
+ }
+ } else if (strequal("ctxlen", k.data)) {
+ if (check_xdiff_opt(v->type, kObjectTypeInteger, "ctxlen", err)) {
+ goto exit_1;
+ }
+ cfg->ctxlen = v->data.integer;
+ } else if (strequal("interhunkctxlen", k.data)) {
+ if (check_xdiff_opt(v->type, kObjectTypeInteger, "interhunkctxlen",
+ err)) {
+ goto exit_1;
+ }
+ cfg->interhunkctxlen = v->data.integer;
+ } else {
+ struct {
+ const char *name;
+ unsigned long value;
+ } flags[] = {
+ { "ignore_whitespace", XDF_IGNORE_WHITESPACE },
+ { "ignore_whitespace_change", XDF_IGNORE_WHITESPACE_CHANGE },
+ { "ignore_whitespace_change_at_eol", XDF_IGNORE_WHITESPACE_AT_EOL },
+ { "ignore_cr_at_eol", XDF_IGNORE_CR_AT_EOL },
+ { "ignore_blank_lines", XDF_IGNORE_BLANK_LINES },
+ { "indent_heuristic", XDF_INDENT_HEURISTIC },
+ { NULL, 0 },
+ };
+ bool key_used = false;
+ for (size_t j = 0; flags[j].name; j++) {
+ if (strequal(flags[j].name, k.data)) {
+ if (check_xdiff_opt(v->type, kObjectTypeBoolean, flags[j].name,
+ err)) {
+ goto exit_1;
+ }
+ if (v->data.boolean) {
+ params->flags |= flags[j].value;
+ }
+ key_used = true;
+ break;
+ }
+ }
+
+ if (key_used) {
+ continue;
+ }
+
+ api_set_error(err, kErrorTypeValidation, "unexpected key: %s", k.data);
+ goto exit_1;
+ }
+ }
+
+ if (had_on_hunk) {
+ mode = kNluaXdiffModeOnHunkCB;
+ cfg->hunk_func = call_on_hunk_cb;
+ } else if (had_result_type_indices) {
+ mode = kNluaXdiffModeLocations;
+ cfg->hunk_func = hunk_locations_cb;
+ }
+
+exit_1:
+ api_free_dictionary(opts);
+ return mode;
+}
+
+int nlua_xdl_diff(lua_State *lstate)
+{
+ if (lua_gettop(lstate) < 2) {
+ return luaL_error(lstate, "Expected at least 2 arguments");
+ }
+ mmfile_t ma = get_string_arg(lstate, 1);
+ mmfile_t mb = get_string_arg(lstate, 2);
+
+ Error err = ERROR_INIT;
+
+ xdemitconf_t cfg;
+ xpparam_t params;
+ xdemitcb_t ecb;
+
+ memset(&cfg, 0, sizeof(cfg));
+ memset(&params, 0, sizeof(params));
+ memset(&ecb, 0, sizeof(ecb));
+
+ NluaXdiffMode mode = kNluaXdiffModeUnified;
+
+ if (lua_gettop(lstate) == 3) {
+ if (lua_type(lstate, 3) != LUA_TTABLE) {
+ return luaL_argerror(lstate, 3, "expected table");
+ }
+
+ mode = process_xdl_diff_opts(lstate, &cfg, &params, &err);
+
+ if (ERROR_SET(&err)) {
+ goto exit_0;
+ }
+ }
+
+ luaL_Buffer buf;
+ hunkpriv_t *priv = NULL;
+ switch (mode) {
+ case kNluaXdiffModeUnified:
+ luaL_buffinit(lstate, &buf);
+ ecb.priv = &buf;
+ ecb.out_line = write_string;
+ break;
+ case kNluaXdiffModeOnHunkCB:
+ priv = xmalloc(sizeof(*priv));
+ priv->lstate = lstate;
+ priv->err = &err;
+ ecb.priv = priv;
+ break;
+ case kNluaXdiffModeLocations:
+ lua_createtable(lstate, 0, 0);
+ ecb.priv = lstate;
+ break;
+ }
+
+ if (xdl_diff(&ma, &mb, &params, &cfg, &ecb) == -1) {
+ if (!ERROR_SET(&err)) {
+ api_set_error(&err, kErrorTypeException,
+ "Error while performing diff operation");
+ }
+ }
+
+ XFREE_CLEAR(priv);
+
+exit_0:
+ if (ERROR_SET(&err)) {
+ luaL_where(lstate, 1);
+ lua_pushstring(lstate, err.msg);
+ api_clear_error(&err);
+ lua_concat(lstate, 2);
+ return lua_error(lstate);
+ } else if (mode == kNluaXdiffModeUnified) {
+ luaL_pushresult(&buf);
+ return 1;
+ } else if (mode == kNluaXdiffModeLocations) {
+ return 1;
+ }
+ return 0;
+}
diff --git a/src/nvim/lua/xdiff.h b/src/nvim/lua/xdiff.h
new file mode 100644
index 0000000000..cae7c98e81
--- /dev/null
+++ b/src/nvim/lua/xdiff.h
@@ -0,0 +1,12 @@
+#ifndef NVIM_LUA_XDIFF_H
+#define NVIM_LUA_XDIFF_H
+
+#include <lua.h>
+#include <lualib.h>
+#include <lauxlib.h>
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "lua/xdiff.h.generated.h"
+#endif
+
+#endif // NVIM_LUA_XDIFF_H
diff --git a/src/nvim/macros.h b/src/nvim/macros.h
index e718254fb9..e1aa1b7704 100644
--- a/src/nvim/macros.h
+++ b/src/nvim/macros.h
@@ -34,10 +34,6 @@
/// LINEEMPTY() - return TRUE if the line is empty
#define LINEEMPTY(p) (*ml_get(p) == NUL)
-/// BUFEMPTY() - return TRUE if the current buffer is empty
-#define BUFEMPTY() (curbuf->b_ml.ml_line_count == 1 && *ml_get((linenr_T)1) == \
- NUL)
-
// toupper() and tolower() that use the current locale.
// Careful: Only call TOUPPER_LOC() and TOLOWER_LOC() with a character in the
// range 0 - 255. toupper()/tolower() on some systems can't handle others.
@@ -133,6 +129,8 @@
/// error. A mechanism to detect many (though not all) of those errors at
/// compile time is implemented. It works by the second division producing
/// a division by zero in those cases (-Wdiv-by-zero in GCC).
+///
+/// -V:ARRAY_SIZE:1063
#define ARRAY_SIZE(arr) \
((sizeof(arr)/sizeof((arr)[0])) \
/ ((size_t)(!(sizeof(arr) % sizeof((arr)[0])))))
diff --git a/src/nvim/main.c b/src/nvim/main.c
index 7d7eba2105..d977589ad7 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -3,27 +3,22 @@
#define EXTERN
#include <assert.h>
+#include <msgpack.h>
+#include <stdbool.h>
#include <stdint.h>
#include <string.h>
-#include <stdbool.h>
-
-#include <lua.h>
-#include <lauxlib.h>
-#include <msgpack.h>
#include "nvim/ascii.h"
-#include "nvim/channel.h"
-#include "nvim/vim.h"
-#include "nvim/main.h"
#include "nvim/aucmd.h"
#include "nvim/buffer.h"
+#include "nvim/channel.h"
#include "nvim/charset.h"
+#include "nvim/decoration.h"
#include "nvim/diff.h"
#include "nvim/eval.h"
#include "nvim/ex_cmds.h"
#include "nvim/ex_cmds2.h"
#include "nvim/ex_docmd.h"
-#include "nvim/decoration.h"
#include "nvim/fileio.h"
#include "nvim/fold.h"
#include "nvim/getchar.h"
@@ -32,29 +27,36 @@
#include "nvim/iconv.h"
#include "nvim/if_cscope.h"
#include "nvim/lua/executor.h"
+#include "nvim/main.h"
+#include "nvim/vim.h"
#ifdef HAVE_LOCALE_H
# include <locale.h>
#endif
+#include "nvim/garray.h"
+#include "nvim/log.h"
#include "nvim/mark.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
+#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/garray.h"
-#include "nvim/log.h"
-#include "nvim/memory.h"
-#include "nvim/move.h"
#include "nvim/mouse.h"
+#include "nvim/move.h"
#include "nvim/normal.h"
#include "nvim/ops.h"
#include "nvim/option.h"
-#include "nvim/os_unix.h"
+#include "nvim/os/fileio.h"
+#include "nvim/os/input.h"
+#include "nvim/os/os.h"
#include "nvim/os/os_defs.h"
+#include "nvim/os/time.h"
+#include "nvim/os_unix.h"
#include "nvim/path.h"
-#include "nvim/profile.h"
#include "nvim/popupmnu.h"
+#include "nvim/profile.h"
#include "nvim/quickfix.h"
#include "nvim/screen.h"
+#include "nvim/shada.h"
#include "nvim/sign.h"
#include "nvim/state.h"
#include "nvim/strings.h"
@@ -63,25 +65,19 @@
#include "nvim/ui_compositor.h"
#include "nvim/version.h"
#include "nvim/window.h"
-#include "nvim/shada.h"
-#include "nvim/os/input.h"
-#include "nvim/os/os.h"
-#include "nvim/os/time.h"
-#include "nvim/os/fileio.h"
#ifdef WIN32
# include "nvim/os/os_win_console.h"
#endif
+#include "nvim/api/private/defs.h"
+#include "nvim/api/private/dispatch.h"
+#include "nvim/api/private/helpers.h"
+#include "nvim/api/ui.h"
#include "nvim/event/loop.h"
-#include "nvim/os/signal.h"
#include "nvim/event/process.h"
+#include "nvim/msgpack_rpc/channel.h"
#include "nvim/msgpack_rpc/helpers.h"
#include "nvim/msgpack_rpc/server.h"
-#include "nvim/msgpack_rpc/channel.h"
-#include "nvim/api/ui.h"
-#include "nvim/api/private/defs.h"
-#include "nvim/api/private/helpers.h"
-#include "nvim/api/private/handle.h"
-#include "nvim/api/private/dispatch.h"
+#include "nvim/os/signal.h"
#ifndef WIN32
# include "nvim/os/pty_process_unix.h"
#endif
@@ -128,8 +124,6 @@ void event_init(void)
signal_init();
// finish mspgack-rpc initialization
channel_init();
- remote_ui_init();
- api_vim_init();
terminal_init();
ui_init();
}
@@ -162,8 +156,6 @@ void early_init(mparm_T *paramp)
{
env_init();
fs_init();
- handle_init();
- decor_init();
eval_init(); // init global variables
init_path(argv0 ? argv0 : "nvim");
init_normal_cmds(); // Init the table of Normal mode commands.
@@ -258,6 +250,8 @@ int main(int argc, char **argv)
// Check if we have an interactive window.
check_and_set_isatty(&params);
+ nlua_init();
+
// Process the command line arguments. File names are put in the global
// argument list "global_alist".
command_line_scan(&params);
@@ -283,9 +277,9 @@ int main(int argc, char **argv)
TIME_MSG("expanding arguments");
- if (params.diff_mode && params.window_count == -1)
- params.window_count = 0; /* open up to 3 windows */
-
+ if (params.diff_mode && params.window_count == -1) {
+ params.window_count = 0; // open up to 3 windows
+ }
// Don't redraw until much later.
RedrawingDisabled++;
@@ -318,7 +312,8 @@ int main(int argc, char **argv)
debug_break_level = params.use_debug_break_level;
// Read ex-commands if invoked with "-es".
- if (!params.input_isatty && silent_mode && exmode_active == EXMODE_NORMAL) {
+ if (!params.input_isatty && !params.input_neverscript
+ && silent_mode && exmode_active) {
input_start(STDIN_FILENO);
}
@@ -338,25 +333,14 @@ int main(int argc, char **argv)
// prepare screen now, so external UIs can display messages
starting = NO_BUFFERS;
screenclear();
- TIME_MSG("initialized screen early for UI");
- }
-
-
- // open terminals when opening files that start with term://
-#define PROTO "term://"
- do_cmdline_cmd("augroup nvim_terminal");
- do_cmdline_cmd("autocmd!");
- do_cmdline_cmd("autocmd BufReadCmd " PROTO "* nested "
- ":if !exists('b:term_title')|call termopen( "
- // Capture the command string
- "matchstr(expand(\"<amatch>\"), "
- "'\\c\\m" PROTO "\\%(.\\{-}//\\%(\\d\\+:\\)\\?\\)\\?\\zs.*'), "
- // capture the working directory
- "{'cwd': expand(get(matchlist(expand(\"<amatch>\"), "
- "'\\c\\m" PROTO "\\(.\\{-}\\)//'), 1, ''))})"
- "|endif");
- do_cmdline_cmd("augroup END");
-#undef PROTO
+ TIME_MSG("init screen for UI");
+ }
+
+ init_default_mappings(); // Default mappings.
+ TIME_MSG("init default mappings");
+
+ init_default_autocmds();
+ TIME_MSG("init default autocommands");
// Reset 'loadplugins' for "-u NONE" before "--cmd" arguments.
// Allows for setting 'loadplugins' there.
@@ -474,7 +458,7 @@ int main(int argc, char **argv)
curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
}
- apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf);
+ apply_autocmds(EVENT_BUFENTER, NULL, NULL, false, curbuf);
TIME_MSG("BufEnter autocommands");
setpcmark();
@@ -601,15 +585,16 @@ void getout(int exitval)
/* When running in Ex mode an error causes us to exit with a non-zero exit
* code. POSIX requires this, although it's not 100% clear from the
* standard. */
- if (exmode_active)
+ if (exmode_active) {
exitval += ex_exitval;
+ }
set_vim_var_nr(VV_EXITING, exitval);
// Position the cursor on the last screen line, below all the text
ui_cursor_goto(Rows - 1, 0);
- /* Optionally print hashtable efficiency. */
+ // Optionally print hashtable efficiency.
hash_debug_results();
if (v_dying <= 1) {
@@ -620,7 +605,7 @@ void getout(int exitval)
next_tp = tp->tp_next;
FOR_ALL_WINDOWS_IN_TAB(wp, tp) {
if (wp->w_buffer == NULL) {
- /* Autocmd must have close the buffer already, skip. */
+ // Autocmd must have close the buffer already, skip.
continue;
}
@@ -641,7 +626,7 @@ void getout(int exitval)
}
}
- /* Trigger BufUnload for buffers that are loaded */
+ // Trigger BufUnload for buffers that are loaded
FOR_ALL_BUFFERS(buf) {
if (buf->b_ml.ml_mfp != NULL) {
bufref_T bufref;
@@ -689,8 +674,8 @@ void getout(int exitval)
profile_dump();
if (did_emsg
- ) {
- /* give the user a chance to read the (error) message */
+ ) {
+ // give the user a chance to read the (error) message
no_wait_return = FALSE;
wait_return(FALSE);
}
@@ -742,7 +727,7 @@ static void init_locale(void)
setlocale(LC_ALL, "");
# ifdef LC_NUMERIC
- /* Make sure strtod() uses a decimal point, not a comma. */
+ // Make sure strtod() uses a decimal point, not a comma.
setlocale(LC_NUMERIC, "C");
# endif
@@ -764,10 +749,10 @@ static void init_locale(void)
static bool edit_stdin(bool explicit, mparm_T *parmp)
{
bool implicit = !headless_mode
- && !embedded_mode
- && exmode_active != EXMODE_NORMAL // -E/-Es but not -e/-es.
- && !parmp->input_isatty
- && scriptin[0] == NULL; // `-s -` was not given.
+ && !embedded_mode
+ && (!exmode_active || parmp->input_neverscript)
+ && !parmp->input_isatty
+ && scriptin[0] == NULL; // `-s -` was not given.
return explicit || implicit;
}
@@ -799,269 +784,242 @@ static void command_line_scan(mparm_T *parmp)
parmp->commands[parmp->n_commands++] = &(argv[0][1]);
}
- // Optional argument.
+ // Optional argument.
} else if (argv[0][0] == '-' && !had_minmin) {
want_argument = false;
c = argv[0][argv_idx++];
switch (c) {
- case NUL: { // "nvim -" read from stdin
- if (exmode_active) {
- // "nvim -e -" silent mode
- silent_mode = true;
- parmp->no_swap_file = true;
- } else {
- if (parmp->edit_type != EDIT_NONE
- && parmp->edit_type != EDIT_FILE
- && parmp->edit_type != EDIT_STDIN) {
- mainerr(err_too_many_args, argv[0]);
- }
- had_stdin_file = true;
- parmp->edit_type = EDIT_STDIN;
+ case NUL: // "nvim -" read from stdin
+ if (exmode_active) {
+ // "nvim -e -" silent mode
+ silent_mode = true;
+ parmp->no_swap_file = true;
+ } else {
+ if (parmp->edit_type != EDIT_NONE
+ && parmp->edit_type != EDIT_FILE
+ && parmp->edit_type != EDIT_STDIN) {
+ mainerr(err_too_many_args, argv[0]);
}
- argv_idx = -1; // skip to next argument
- break;
+ had_stdin_file = true;
+ parmp->edit_type = EDIT_STDIN;
}
- case '-': { // "--" don't take any more option arguments
- // "--help" give help message
- // "--version" give version message
- // "--noplugin[s]" skip plugins
- // "--cmd <cmd>" execute cmd before vimrc
- if (STRICMP(argv[0] + argv_idx, "help") == 0) {
- usage();
- os_exit(0);
- } else if (STRICMP(argv[0] + argv_idx, "version") == 0) {
- version();
- os_exit(0);
- } else if (STRICMP(argv[0] + argv_idx, "api-info") == 0) {
- FileDescriptor fp;
- const int fof_ret = file_open_fd(&fp, STDOUT_FILENO,
- kFileWriteOnly);
- msgpack_packer *p = msgpack_packer_new(&fp, msgpack_file_write);
-
- if (fof_ret != 0) {
- emsgf(_("E5421: Failed to open stdin: %s"), os_strerror(fof_ret));
- }
+ argv_idx = -1; // skip to next argument
+ break;
+ case '-': // "--" don't take any more option arguments
+ // "--help" give help message
+ // "--version" give version message
+ // "--noplugin[s]" skip plugins
+ // "--cmd <cmd>" execute cmd before vimrc
+ if (STRICMP(argv[0] + argv_idx, "help") == 0) {
+ usage();
+ os_exit(0);
+ } else if (STRICMP(argv[0] + argv_idx, "version") == 0) {
+ version();
+ os_exit(0);
+ } else if (STRICMP(argv[0] + argv_idx, "api-info") == 0) {
+ FileDescriptor fp;
+ const int fof_ret = file_open_fd(&fp, STDOUT_FILENO,
+ kFileWriteOnly);
+ msgpack_packer *p = msgpack_packer_new(&fp, msgpack_file_write);
+
+ if (fof_ret != 0) {
+ emsgf(_("E5421: Failed to open stdin: %s"), os_strerror(fof_ret));
+ }
- if (p == NULL) {
- EMSG(_(e_outofmem));
- }
+ if (p == NULL) {
+ EMSG(_(e_outofmem));
+ }
- Object md = DICTIONARY_OBJ(api_metadata());
- msgpack_rpc_from_object(md, p);
+ Object md = DICTIONARY_OBJ(api_metadata());
+ msgpack_rpc_from_object(md, p);
- msgpack_packer_free(p);
- const int ff_ret = file_flush(&fp);
- if (ff_ret < 0) {
- msgpack_file_write_error(ff_ret);
- }
- os_exit(0);
- } else if (STRICMP(argv[0] + argv_idx, "headless") == 0) {
- headless_mode = true;
- } else if (STRICMP(argv[0] + argv_idx, "embed") == 0) {
- embedded_mode = true;
- } else if (STRNICMP(argv[0] + argv_idx, "listen", 6) == 0) {
- want_argument = true;
- argv_idx += 6;
- } else if (STRNICMP(argv[0] + argv_idx, "literal", 7) == 0) {
- // Do nothing: file args are always literal. #7679
- } else if (STRNICMP(argv[0] + argv_idx, "noplugin", 8) == 0) {
- p_lpl = false;
- } else if (STRNICMP(argv[0] + argv_idx, "cmd", 3) == 0) {
- want_argument = true;
- argv_idx += 3;
- } else if (STRNICMP(argv[0] + argv_idx, "startuptime", 11) == 0) {
- want_argument = true;
- argv_idx += 11;
- } else if (STRNICMP(argv[0] + argv_idx, "clean", 5) == 0) {
- parmp->use_vimrc = "NONE";
- parmp->clean = true;
- set_option_value("shadafile", 0L, "NONE", 0);
- } else {
- if (argv[0][argv_idx])
- mainerr(err_opt_unknown, argv[0]);
- had_minmin = true;
+ msgpack_packer_free(p);
+ const int ff_ret = file_flush(&fp);
+ if (ff_ret < 0) {
+ msgpack_file_write_error(ff_ret);
}
- if (!want_argument) {
- argv_idx = -1; // skip to next argument
+ os_exit(0);
+ } else if (STRICMP(argv[0] + argv_idx, "headless") == 0) {
+ headless_mode = true;
+ } else if (STRICMP(argv[0] + argv_idx, "embed") == 0) {
+ embedded_mode = true;
+ } else if (STRNICMP(argv[0] + argv_idx, "listen", 6) == 0) {
+ want_argument = true;
+ argv_idx += 6;
+ } else if (STRNICMP(argv[0] + argv_idx, "literal", 7) == 0) {
+ // Do nothing: file args are always literal. #7679
+ } else if (STRNICMP(argv[0] + argv_idx, "noplugin", 8) == 0) {
+ p_lpl = false;
+ } else if (STRNICMP(argv[0] + argv_idx, "cmd", 3) == 0) {
+ want_argument = true;
+ argv_idx += 3;
+ } else if (STRNICMP(argv[0] + argv_idx, "startuptime", 11) == 0) {
+ want_argument = true;
+ argv_idx += 11;
+ } else if (STRNICMP(argv[0] + argv_idx, "clean", 5) == 0) {
+ parmp->use_vimrc = "NONE";
+ parmp->clean = true;
+ set_option_value("shadafile", 0L, "NONE", 0);
+ } else {
+ if (argv[0][argv_idx]) {
+ mainerr(err_opt_unknown, argv[0]);
}
- break;
+ had_minmin = true;
}
- case 'A': { // "-A" start in Arabic mode.
- set_option_value("arabic", 1L, NULL, 0);
- break;
- }
- case 'b': { // "-b" binary mode.
- // Needs to be effective before expanding file names, because
- // for Win32 this makes us edit a shortcut file itself,
- // instead of the file it links to.
- set_options_bin(curbuf->b_p_bin, 1, 0);
- curbuf->b_p_bin = 1; // Binary file I/O.
- break;
+ if (!want_argument) {
+ argv_idx = -1; // skip to next argument
}
+ break;
+ case 'A': // "-A" start in Arabic mode.
+ set_option_value("arabic", 1L, NULL, 0);
+ break;
+ case 'b': // "-b" binary mode.
+ // Needs to be effective before expanding file names, because
+ // for Win32 this makes us edit a shortcut file itself,
+ // instead of the file it links to.
+ set_options_bin(curbuf->b_p_bin, 1, 0);
+ curbuf->b_p_bin = 1; // Binary file I/O.
+ break;
- case 'D': { // "-D" Debugging
- parmp->use_debug_break_level = 9999;
- break;
- }
- case 'd': { // "-d" 'diff'
- parmp->diff_mode = true;
- break;
- }
- case 'e': { // "-e" Ex mode
- exmode_active = EXMODE_NORMAL;
- break;
- }
- case 'E': { // "-E" Ex mode
- exmode_active = EXMODE_VIM;
- break;
- }
- case 'f': { // "-f" GUI: run in foreground.
- break;
- }
- case '?': // "-?" give help message (for MS-Windows)
- case 'h': { // "-h" give help message
- usage();
- os_exit(0);
- }
- case 'H': { // "-H" start in Hebrew mode: rl + hkmap set.
- p_hkmap = true;
- set_option_value("rl", 1L, NULL, 0);
- break;
- }
- case 'l': { // "-l" lisp mode, 'lisp' and 'showmatch' on.
- set_option_value("lisp", 1L, NULL, 0);
- p_sm = true;
- break;
- }
- case 'M': { // "-M" no changes or writing of files
- reset_modifiable();
- FALLTHROUGH;
- }
- case 'm': { // "-m" no writing of files
- p_write = false;
- break;
- }
+ case 'D': // "-D" Debugging
+ parmp->use_debug_break_level = 9999;
+ break;
+ case 'd': // "-d" 'diff'
+ parmp->diff_mode = true;
+ break;
+ case 'e': // "-e" Ex mode
+ exmode_active = true;
+ break;
+ case 'E': // "-E" Ex mode
+ exmode_active = true;
+ parmp->input_neverscript = true;
+ break;
+ case 'f': // "-f" GUI: run in foreground.
+ break;
+ case '?': // "-?" give help message (for MS-Windows)
+ case 'h': // "-h" give help message
+ usage();
+ os_exit(0);
+ case 'H': // "-H" start in Hebrew mode: rl + hkmap set.
+ p_hkmap = true;
+ set_option_value("rl", 1L, NULL, 0);
+ break;
+ case 'l': // "-l" lisp mode, 'lisp' and 'showmatch' on.
+ set_option_value("lisp", 1L, NULL, 0);
+ p_sm = true;
+ break;
+ case 'M': // "-M" no changes or writing of files
+ reset_modifiable();
+ FALLTHROUGH;
+ case 'm': // "-m" no writing of files
+ p_write = false;
+ break;
- case 'N': // "-N" Nocompatible
- case 'X': // "-X" Do not connect to X server
- // No-op
- break;
+ case 'N': // "-N" Nocompatible
+ case 'X': // "-X" Do not connect to X server
+ // No-op
+ break;
- case 'n': { // "-n" no swap file
- parmp->no_swap_file = true;
- break;
- }
- case 'p': { // "-p[N]" open N tab pages
- // default is 0: open window for each file
- parmp->window_count = get_number_arg(argv[0], &argv_idx, 0);
- parmp->window_layout = WIN_TABS;
- break;
- }
- case 'o': { // "-o[N]" open N horizontal split windows
- // default is 0: open window for each file
- parmp->window_count = get_number_arg(argv[0], &argv_idx, 0);
- parmp->window_layout = WIN_HOR;
- break;
- }
- case 'O': { // "-O[N]" open N vertical split windows
- // default is 0: open window for each file
- parmp->window_count = get_number_arg(argv[0], &argv_idx, 0);
- parmp->window_layout = WIN_VER;
- break;
- }
- case 'q': { // "-q" QuickFix mode
- if (parmp->edit_type != EDIT_NONE) {
- mainerr(err_too_many_args, argv[0]);
- }
- parmp->edit_type = EDIT_QF;
- if (argv[0][argv_idx]) { // "-q{errorfile}"
- parmp->use_ef = (char_u *)argv[0] + argv_idx;
- argv_idx = -1;
- } else if (argc > 1) { // "-q {errorfile}"
- want_argument = true;
- }
- break;
- }
- case 'R': { // "-R" readonly mode
- readonlymode = true;
- curbuf->b_p_ro = true;
- p_uc = 10000; // don't update very often
- break;
+ case 'n': // "-n" no swap file
+ parmp->no_swap_file = true;
+ break;
+ case 'p': // "-p[N]" open N tab pages
+ // default is 0: open window for each file
+ parmp->window_count = get_number_arg(argv[0], &argv_idx, 0);
+ parmp->window_layout = WIN_TABS;
+ break;
+ case 'o': // "-o[N]" open N horizontal split windows
+ // default is 0: open window for each file
+ parmp->window_count = get_number_arg(argv[0], &argv_idx, 0);
+ parmp->window_layout = WIN_HOR;
+ break;
+ case 'O': // "-O[N]" open N vertical split windows
+ // default is 0: open window for each file
+ parmp->window_count = get_number_arg(argv[0], &argv_idx, 0);
+ parmp->window_layout = WIN_VER;
+ break;
+ case 'q': // "-q" QuickFix mode
+ if (parmp->edit_type != EDIT_NONE) {
+ mainerr(err_too_many_args, argv[0]);
}
- case 'r': // "-r" recovery mode
- case 'L': { // "-L" recovery mode
- recoverymode = 1;
- break;
+ parmp->edit_type = EDIT_QF;
+ if (argv[0][argv_idx]) { // "-q{errorfile}"
+ parmp->use_ef = (char_u *)argv[0] + argv_idx;
+ argv_idx = -1;
+ } else if (argc > 1) { // "-q {errorfile}"
+ want_argument = true;
}
- case 's': {
- if (exmode_active) { // "-es" silent (batch) Ex-mode
- silent_mode = true;
- parmp->no_swap_file = true;
- } else { // "-s {scriptin}" read from script file
- want_argument = true;
- }
- break;
+ break;
+ case 'R': // "-R" readonly mode
+ readonlymode = true;
+ curbuf->b_p_ro = true;
+ p_uc = 10000; // don't update very often
+ break;
+ case 'r': // "-r" recovery mode
+ case 'L': // "-L" recovery mode
+ recoverymode = 1;
+ break;
+ case 's':
+ if (exmode_active) { // "-es" silent (batch) Ex-mode
+ silent_mode = true;
+ parmp->no_swap_file = true;
+ } else { // "-s {scriptin}" read from script file
+ want_argument = true;
}
- case 't': { // "-t {tag}" or "-t{tag}" jump to tag
- if (parmp->edit_type != EDIT_NONE) {
- mainerr(err_too_many_args, argv[0]);
- }
- parmp->edit_type = EDIT_TAG;
- if (argv[0][argv_idx]) { // "-t{tag}"
- parmp->tagname = (char_u *)argv[0] + argv_idx;
- argv_idx = -1;
- } else { // "-t {tag}"
- want_argument = true;
- }
- break;
+ break;
+ case 't': // "-t {tag}" or "-t{tag}" jump to tag
+ if (parmp->edit_type != EDIT_NONE) {
+ mainerr(err_too_many_args, argv[0]);
}
- case 'v': {
- version();
- os_exit(0);
+ parmp->edit_type = EDIT_TAG;
+ if (argv[0][argv_idx]) { // "-t{tag}"
+ parmp->tagname = (char_u *)argv[0] + argv_idx;
+ argv_idx = -1;
+ } else { // "-t {tag}"
+ want_argument = true;
}
- case 'V': { // "-V{N}" Verbose level
- // default is 10: a little bit verbose
- p_verbose = get_number_arg(argv[0], &argv_idx, 10);
- if (argv[0][argv_idx] != NUL) {
- set_option_value("verbosefile", 0L, argv[0] + argv_idx, 0);
- argv_idx = (int)STRLEN(argv[0]);
- }
- break;
+ break;
+ case 'v':
+ version();
+ os_exit(0);
+ case 'V': // "-V{N}" Verbose level
+ // default is 10: a little bit verbose
+ p_verbose = get_number_arg(argv[0], &argv_idx, 10);
+ if (argv[0][argv_idx] != NUL) {
+ set_option_value("verbosefile", 0L, argv[0] + argv_idx, 0);
+ argv_idx = (int)STRLEN(argv[0]);
}
- case 'w': { // "-w{number}" set window height
- // "-w {scriptout}" write to script
- if (ascii_isdigit(((char_u *)argv[0])[argv_idx])) {
- n = get_number_arg(argv[0], &argv_idx, 10);
- set_option_value("window", n, NULL, 0);
- break;
- }
- want_argument = true;
+ break;
+ case 'w': // "-w{number}" set window height
+ // "-w {scriptout}" write to script
+ if (ascii_isdigit(((char_u *)argv[0])[argv_idx])) {
+ n = get_number_arg(argv[0], &argv_idx, 10);
+ set_option_value("window", n, NULL, 0);
break;
}
+ want_argument = true;
+ break;
- case 'c': { // "-c{command}" or "-c {command}" exec command
- if (argv[0][argv_idx] != NUL) {
- if (parmp->n_commands >= MAX_ARG_CMDS) {
- mainerr(err_extra_cmd, NULL);
- }
- parmp->commands[parmp->n_commands++] = argv[0] + argv_idx;
- argv_idx = -1;
- break;
+ case 'c': // "-c{command}" or "-c {command}" exec command
+ if (argv[0][argv_idx] != NUL) {
+ if (parmp->n_commands >= MAX_ARG_CMDS) {
+ mainerr(err_extra_cmd, NULL);
}
- FALLTHROUGH;
- }
- case 'S': // "-S {file}" execute Vim script
- case 'i': // "-i {shada}" use for ShaDa file
- case 'u': // "-u {vimrc}" vim inits file
- case 'U': // "-U {gvimrc}" gvim inits file
- case 'W': { // "-W {scriptout}" overwrite
- want_argument = true;
+ parmp->commands[parmp->n_commands++] = argv[0] + argv_idx;
+ argv_idx = -1;
break;
}
+ FALLTHROUGH;
+ case 'S': // "-S {file}" execute Vim script
+ case 'i': // "-i {shada}" use for ShaDa file
+ case 'u': // "-u {vimrc}" vim inits file
+ case 'U': // "-U {gvimrc}" gvim inits file
+ case 'W': // "-W {scriptout}" overwrite
+ want_argument = true;
+ break;
- default: {
- mainerr(err_opt_unknown, argv[0]);
- }
+ default:
+ mainerr(err_opt_unknown, argv[0]);
}
// Handle option arguments with argument.
@@ -1079,130 +1037,122 @@ static void command_line_scan(mparm_T *parmp)
argv_idx = -1;
switch (c) {
- case 'c': // "-c {command}" execute command
- case 'S': { // "-S {file}" execute Vim script
- if (parmp->n_commands >= MAX_ARG_CMDS) {
- mainerr(err_extra_cmd, NULL);
- }
- if (c == 'S') {
- char *a;
-
- if (argc < 1) {
- // "-S" without argument: use default session file name.
- a = SESSION_FILE;
- } else if (argv[0][0] == '-') {
- // "-S" followed by another option: use default session file.
- a = SESSION_FILE;
- ++argc;
- --argv;
- } else {
- a = argv[0];
- }
-
- size_t s_size = STRLEN(a) + 9;
- char *s = xmalloc(s_size);
- snprintf(s, s_size, "so %s", a);
- parmp->cmds_tofree[parmp->n_commands] = true;
- parmp->commands[parmp->n_commands++] = s;
+ case 'c': // "-c {command}" execute command
+ case 'S': // "-S {file}" execute Vim script
+ if (parmp->n_commands >= MAX_ARG_CMDS) {
+ mainerr(err_extra_cmd, NULL);
+ }
+ if (c == 'S') {
+ char *a;
+
+ if (argc < 1) {
+ // "-S" without argument: use default session file name.
+ a = SESSION_FILE;
+ } else if (argv[0][0] == '-') {
+ // "-S" followed by another option: use default session file.
+ a = SESSION_FILE;
+ ++argc;
+ --argv;
} else {
- parmp->commands[parmp->n_commands++] = argv[0];
+ a = argv[0];
}
- break;
+
+ size_t s_size = STRLEN(a) + 9;
+ char *s = xmalloc(s_size);
+ snprintf(s, s_size, "so %s", a);
+ parmp->cmds_tofree[parmp->n_commands] = true;
+ parmp->commands[parmp->n_commands++] = s;
+ } else {
+ parmp->commands[parmp->n_commands++] = argv[0];
}
+ break;
- case '-': {
- if (strequal(argv[-1], "--cmd")) {
- // "--cmd {command}" execute command
- if (parmp->n_pre_commands >= MAX_ARG_CMDS) {
- mainerr(err_extra_cmd, NULL);
- }
- parmp->pre_commands[parmp->n_pre_commands++] = argv[0];
- } else if (strequal(argv[-1], "--listen")) {
- // "--listen {address}"
- parmp->listen_addr = argv[0];
+ case '-':
+ if (strequal(argv[-1], "--cmd")) {
+ // "--cmd {command}" execute command
+ if (parmp->n_pre_commands >= MAX_ARG_CMDS) {
+ mainerr(err_extra_cmd, NULL);
}
- // "--startuptime <file>" already handled
- break;
+ parmp->pre_commands[parmp->n_pre_commands++] = argv[0];
+ } else if (strequal(argv[-1], "--listen")) {
+ // "--listen {address}"
+ parmp->listen_addr = argv[0];
}
+ // "--startuptime <file>" already handled
+ break;
- case 'q': { // "-q {errorfile}" QuickFix mode
- parmp->use_ef = (char_u *)argv[0];
- break;
- }
+ case 'q': // "-q {errorfile}" QuickFix mode
+ parmp->use_ef = (char_u *)argv[0];
+ break;
- case 'i': { // "-i {shada}" use for shada
- set_option_value("shadafile", 0L, argv[0], 0);
- break;
- }
+ case 'i': // "-i {shada}" use for shada
+ set_option_value("shadafile", 0L, argv[0], 0);
+ break;
- case 's': { // "-s {scriptin}" read from script file
- if (scriptin[0] != NULL) {
+ case 's': { // "-s {scriptin}" read from script file
+ if (scriptin[0] != NULL) {
scripterror:
- vim_snprintf((char *)IObuff, IOSIZE,
- _("Attempt to open script file again: \"%s %s\"\n"),
- argv[-1], argv[0]);
- mch_errmsg((const char *)IObuff);
- os_exit(2);
- }
- int error;
- if (strequal(argv[0], "-")) {
- const int stdin_dup_fd = os_dup(STDIN_FILENO);
+ vim_snprintf((char *)IObuff, IOSIZE,
+ _("Attempt to open script file again: \"%s %s\"\n"),
+ argv[-1], argv[0]);
+ mch_errmsg((const char *)IObuff);
+ os_exit(2);
+ }
+ int error;
+ if (strequal(argv[0], "-")) {
+ const int stdin_dup_fd = os_dup(STDIN_FILENO);
#ifdef WIN32
- // Replace the original stdin with the console input handle.
- os_replace_stdin_to_conin();
+ // Replace the original stdin with the console input handle.
+ os_replace_stdin_to_conin();
#endif
- FileDescriptor *const stdin_dup = file_open_fd_new(
- &error, stdin_dup_fd, kFileReadOnly|kFileNonBlocking);
- assert(stdin_dup != NULL);
- scriptin[0] = stdin_dup;
- } else if ((scriptin[0] = file_open_new(
- &error, argv[0], kFileReadOnly|kFileNonBlocking, 0)) == NULL) {
- vim_snprintf((char *)IObuff, IOSIZE,
- _("Cannot open for reading: \"%s\": %s\n"),
- argv[0], os_strerror(error));
- mch_errmsg((const char *)IObuff);
- os_exit(2);
- }
- save_typebuf();
- break;
+ FileDescriptor *const stdin_dup = file_open_fd_new(&error, stdin_dup_fd,
+ kFileReadOnly|kFileNonBlocking);
+ assert(stdin_dup != NULL);
+ scriptin[0] = stdin_dup;
+ } else if ((scriptin[0] =
+ file_open_new(&error, argv[0], kFileReadOnly|kFileNonBlocking,
+ 0)) == NULL) {
+ vim_snprintf((char *)IObuff, IOSIZE,
+ _("Cannot open for reading: \"%s\": %s\n"),
+ argv[0], os_strerror(error));
+ mch_errmsg((const char *)IObuff);
+ os_exit(2);
}
+ save_typebuf();
+ break;
+ }
- case 't': { // "-t {tag}"
- parmp->tagname = (char_u *)argv[0];
- break;
- }
- case 'u': { // "-u {vimrc}" vim inits file
- parmp->use_vimrc = argv[0];
- break;
- }
- case 'U': { // "-U {gvimrc}" gvim inits file
+ case 't': // "-t {tag}"
+ parmp->tagname = (char_u *)argv[0];
+ break;
+ case 'u': // "-u {vimrc}" vim inits file
+ parmp->use_vimrc = argv[0];
+ break;
+ case 'U': // "-U {gvimrc}" gvim inits file
+ break;
+
+ case 'w': // "-w {nr}" 'window' value
+ // "-w {scriptout}" append to script file
+ if (ascii_isdigit(*((char_u *)argv[0]))) {
+ argv_idx = 0;
+ n = get_number_arg(argv[0], &argv_idx, 10);
+ set_option_value("window", n, NULL, 0);
+ argv_idx = -1;
break;
}
-
- case 'w': { // "-w {nr}" 'window' value
- // "-w {scriptout}" append to script file
- if (ascii_isdigit(*((char_u *)argv[0]))) {
- argv_idx = 0;
- n = get_number_arg(argv[0], &argv_idx, 10);
- set_option_value("window", n, NULL, 0);
- argv_idx = -1;
- break;
- }
- FALLTHROUGH;
+ FALLTHROUGH;
+ case 'W': // "-W {scriptout}" overwrite script file
+ if (scriptout != NULL) {
+ goto scripterror;
}
- case 'W': { // "-W {scriptout}" overwrite script file
- if (scriptout != NULL) {
- goto scripterror;
- }
- if ((scriptout = os_fopen(argv[0], c == 'w' ? APPENDBIN : WRITEBIN))
- == NULL) {
- mch_errmsg(_("Cannot open for script output: \""));
- mch_errmsg(argv[0]);
- mch_errmsg("\"\n");
- os_exit(2);
- }
- break;
+ if ((scriptout = os_fopen(argv[0], c == 'w' ? APPENDBIN : WRITEBIN))
+ == NULL) {
+ mch_errmsg(_("Cannot open for script output: \""));
+ mch_errmsg(argv[0]);
+ mch_errmsg("\"\n");
+ os_exit(2);
}
+ break;
}
}
} else { // File name argument.
@@ -1223,7 +1173,7 @@ scripterror:
if (parmp->diff_mode && os_isdir(p) && GARGCOUNT > 0
&& !os_isdir(alist_name(&GARGLIST[0]))) {
char_u *r = (char_u *)concat_fnames((char *)p,
- (char *)path_tail(alist_name(&GARGLIST[0])), true);
+ (char *)path_tail(alist_name(&GARGLIST[0])), true);
xfree(p);
p = r;
}
@@ -1348,10 +1298,11 @@ static char_u *get_fname(mparm_T *parmp, char_u *cwd)
static void set_window_layout(mparm_T *paramp)
{
if (paramp->diff_mode && paramp->window_layout == 0) {
- if (diffopt_horizontal())
- paramp->window_layout = WIN_HOR; /* use horizontal split */
- else
- paramp->window_layout = WIN_VER; /* use vertical split */
+ if (diffopt_horizontal()) {
+ paramp->window_layout = WIN_HOR; // use horizontal split
+ } else {
+ paramp->window_layout = WIN_VER; // use vertical split
+ }
}
}
@@ -1366,23 +1317,10 @@ static void load_plugins(void)
char_u *const plugin_pattern_vim = (char_u *)"plugin/**/*.vim"; // NOLINT
char_u *const plugin_pattern_lua = (char_u *)"plugin/**/*.lua"; // NOLINT
- // First add all package directories to 'runtimepath', so that their
- // autoload directories can be found. Only if not done already with a
- // :packloadall command.
- // Make a copy of 'runtimepath', so that source_runtime does not use the
- // pack directories.
- if (!did_source_packages) {
- rtp_copy = vim_strsave(p_rtp);
- add_pack_start_dirs();
- }
-
- source_in_path(rtp_copy == NULL ? p_rtp : rtp_copy,
- plugin_pattern_vim,
- DIP_ALL | DIP_NOAFTER);
- source_in_path(rtp_copy == NULL ? p_rtp : rtp_copy,
- plugin_pattern_lua,
- DIP_ALL | DIP_NOAFTER);
- TIME_MSG("loading plugins");
+ // don't use source_runtime() yet so we can check for :packloadall below
+ source_in_path(p_rtp, plugin_pattern_vim, DIP_ALL | DIP_NOAFTER);
+ source_in_path(p_rtp, plugin_pattern_lua, DIP_ALL | DIP_NOAFTER);
+ TIME_MSG("loading rtp plugins");
xfree(rtp_copy);
// Only source "start" packages if not done already with a :packloadall
@@ -1424,15 +1362,16 @@ static void handle_quickfix(mparm_T *paramp)
static void handle_tag(char_u *tagname)
{
if (tagname != NULL) {
- swap_exists_did_quit = FALSE;
+ swap_exists_did_quit = false;
vim_snprintf((char *)IObuff, IOSIZE, "ta %s", tagname);
do_cmdline_cmd((char *)IObuff);
TIME_MSG("jumping to tag");
- /* If the user doesn't want to edit the file then we quit here. */
- if (swap_exists_did_quit)
+ // If the user doesn't want to edit the file then we quit here.
+ if (swap_exists_did_quit) {
getout(1);
+ }
}
}
@@ -1442,13 +1381,11 @@ static void read_stdin(void)
// When getting the ATTENTION prompt here, use a dialog.
swap_exists_action = SEA_DIALOG;
no_wait_return = true;
- int save_msg_didany = msg_didany;
+ bool save_msg_didany = msg_didany;
set_buflisted(true);
-
// Create memfile and read from stdin.
(void)open_buffer(true, NULL, 0);
-
- if (BUFEMPTY() && curbuf->b_next != NULL) {
+ if (buf_is_empty(curbuf) && curbuf->b_next != NULL) {
// stdin was empty, go to buffer 2 (e.g. "echo file1 | xargs nvim"). #8561
do_cmdline_cmd("silent! bnext");
// Delete the empty stdin buffer.
@@ -1472,26 +1409,31 @@ static void create_windows(mparm_T *parmp)
/*
* Create the number of windows that was requested.
*/
- if (parmp->window_count == -1) /* was not set */
+ if (parmp->window_count == -1) { // was not set
parmp->window_count = 1;
- if (parmp->window_count == 0)
+ }
+ if (parmp->window_count == 0) {
parmp->window_count = GARGCOUNT;
+ }
if (parmp->window_count > 1) {
// Don't change the windows if there was a command in vimrc that
// already split some windows
- if (parmp->window_layout == 0)
+ if (parmp->window_layout == 0) {
parmp->window_layout = WIN_HOR;
+ }
if (parmp->window_layout == WIN_TABS) {
parmp->window_count = make_tabpages(parmp->window_count);
TIME_MSG("making tab pages");
} else if (firstwin->w_next == NULL) {
parmp->window_count = make_windows(parmp->window_count,
- parmp->window_layout == WIN_VER);
+ parmp->window_layout == WIN_VER);
TIME_MSG("making windows");
- } else
+ } else {
parmp->window_count = win_count();
- } else
+ }
+ } else {
parmp->window_count = 1;
+ }
if (recoverymode) { // do recover
msg_scroll = true; // scroll message up
@@ -1511,17 +1453,20 @@ static void create_windows(mparm_T *parmp)
dorewind = TRUE;
while (done++ < 1000) {
if (dorewind) {
- if (parmp->window_layout == WIN_TABS)
+ if (parmp->window_layout == WIN_TABS) {
goto_tabpage(1);
- else
+ } else {
curwin = firstwin;
+ }
} else if (parmp->window_layout == WIN_TABS) {
- if (curtab->tp_next == NULL)
+ if (curtab->tp_next == NULL) {
break;
+ }
goto_tabpage(0);
} else {
- if (curwin->w_next == NULL)
+ if (curwin->w_next == NULL) {
break;
+ }
curwin = curwin->w_next;
}
dorewind = FALSE;
@@ -1535,13 +1480,13 @@ static void create_windows(mparm_T *parmp)
swap_exists_action = SEA_DIALOG;
set_buflisted(TRUE);
- /* create memfile, read file */
+ // create memfile, read file
(void)open_buffer(FALSE, NULL, 0);
if (swap_exists_action == SEA_QUIT) {
if (got_int || only_one_window()) {
- /* abort selected or quit and only one window */
- did_emsg = FALSE; /* avoid hit-enter prompt */
+ // abort selected or quit and only one window
+ did_emsg = FALSE; // avoid hit-enter prompt
getout(1);
}
/* We can't close the window, it would disturb what
@@ -1550,20 +1495,22 @@ static void create_windows(mparm_T *parmp)
setfname(curbuf, NULL, NULL, false);
curwin->w_arg_idx = -1;
swap_exists_action = SEA_NONE;
- } else
+ } else {
handle_swap_exists(NULL);
- dorewind = TRUE; /* start again */
+ }
+ dorewind = TRUE; // start again
}
os_breakcheck();
if (got_int) {
- (void)vgetc(); /* only break the file loading, not the rest */
+ (void)vgetc(); // only break the file loading, not the rest
break;
}
}
- if (parmp->window_layout == WIN_TABS)
+ if (parmp->window_layout == WIN_TABS) {
goto_tabpage(1);
- else
+ } else {
curwin = firstwin;
+ }
curbuf = curwin->w_buffer;
--autocmd_no_enter;
--autocmd_no_leave;
@@ -1574,10 +1521,10 @@ static void create_windows(mparm_T *parmp)
/// windows. make_windows() has already opened the windows.
static void edit_buffers(mparm_T *parmp, char_u *cwd)
{
- int arg_idx; /* index in argument list */
+ int arg_idx; // index in argument list
int i;
bool advance = true;
- win_T *win;
+ win_T *win;
char *p_shm_save = NULL;
/*
@@ -1586,7 +1533,7 @@ static void edit_buffers(mparm_T *parmp, char_u *cwd)
++autocmd_no_enter;
++autocmd_no_leave;
- /* When w_arg_idx is -1 remove the window (see create_windows()). */
+ // When w_arg_idx is -1 remove the window (see create_windows()).
if (curwin->w_arg_idx == -1) {
win_close(curwin, true);
advance = false;
@@ -1607,8 +1554,9 @@ static void edit_buffers(mparm_T *parmp, char_u *cwd)
if (advance) {
if (parmp->window_layout == WIN_TABS) {
- if (curtab->tp_next == NULL) /* just checking */
+ if (curtab->tp_next == NULL) { // just checking
break;
+ }
goto_tabpage(0);
// Temporarily reset 'shm' option to not print fileinfo when
// loading the other buffers. This would overwrite the already
@@ -1621,8 +1569,9 @@ static void edit_buffers(mparm_T *parmp, char_u *cwd)
set_option_value("shm", 0L, buf, 0);
}
} else {
- if (curwin->w_next == NULL) /* just checking */
+ if (curwin->w_next == NULL) { // just checking
break;
+ }
win_enter(curwin->w_next, false);
}
}
@@ -1634,15 +1583,15 @@ static void edit_buffers(mparm_T *parmp, char_u *cwd)
curwin->w_arg_idx = arg_idx;
/* Edit file from arg list, if there is one. When "Quit" selected
* at the ATTENTION prompt close the window. */
- swap_exists_did_quit = FALSE;
+ swap_exists_did_quit = false;
(void)do_ecmd(0, arg_idx < GARGCOUNT
? alist_name(&GARGLIST[arg_idx]) : NULL,
- NULL, NULL, ECMD_LASTL, ECMD_HIDE, curwin);
+ NULL, NULL, ECMD_LASTL, ECMD_HIDE, curwin);
if (swap_exists_did_quit) {
- /* abort or quit selected */
+ // abort or quit selected
if (got_int || only_one_window()) {
- /* abort selected and only one window */
- did_emsg = FALSE; /* avoid hit-enter prompt */
+ // abort selected and only one window
+ did_emsg = FALSE; // avoid hit-enter prompt
getout(1);
}
win_close(curwin, true);
@@ -1655,7 +1604,7 @@ static void edit_buffers(mparm_T *parmp, char_u *cwd)
}
os_breakcheck();
if (got_int) {
- (void)vgetc(); /* only break the file loading, not the rest */
+ (void)vgetc(); // only break the file loading, not the rest
break;
}
}
@@ -1665,13 +1614,14 @@ static void edit_buffers(mparm_T *parmp, char_u *cwd)
xfree(p_shm_save);
}
- if (parmp->window_layout == WIN_TABS)
+ if (parmp->window_layout == WIN_TABS) {
goto_tabpage(1);
+ }
--autocmd_no_enter;
- /* make the first window the current window */
+ // make the first window the current window
win = firstwin;
- /* Avoid making a preview window the current window. */
+ // Avoid making a preview window the current window.
while (win->w_p_pvw) {
win = win->w_next;
if (win == NULL) {
@@ -1683,8 +1633,9 @@ static void edit_buffers(mparm_T *parmp, char_u *cwd)
--autocmd_no_leave;
TIME_MSG("editing files in windows");
- if (parmp->window_count > 1 && parmp->window_layout != WIN_TABS)
- win_equal(curwin, false, 'b'); /* adjust heights */
+ if (parmp->window_count > 1 && parmp->window_layout != WIN_TABS) {
+ win_equal(curwin, false, 'b'); // adjust heights
+ }
}
/*
@@ -1697,7 +1648,7 @@ static void exe_pre_commands(mparm_T *parmp)
int i;
if (cnt > 0) {
- curwin->w_cursor.lnum = 0; /* just in case.. */
+ curwin->w_cursor.lnum = 0; // just in case..
sourcing_name = (char_u *)_("pre-vimrc command line");
current_sctx.sc_sid = SID_CMDARG;
for (i = 0; i < cnt; i++) {
@@ -1722,15 +1673,17 @@ static void exe_commands(mparm_T *parmp)
* with g`" was used.
*/
msg_scroll = TRUE;
- if (parmp->tagname == NULL && curwin->w_cursor.lnum <= 1)
+ if (parmp->tagname == NULL && curwin->w_cursor.lnum <= 1) {
curwin->w_cursor.lnum = 0;
+ }
sourcing_name = (char_u *)"command line";
current_sctx.sc_sid = SID_CARG;
current_sctx.sc_seq = 0;
for (i = 0; i < parmp->n_commands; i++) {
do_cmdline_cmd(parmp->commands[i]);
- if (parmp->cmds_tofree[i])
+ if (parmp->cmds_tofree[i]) {
xfree(parmp->commands[i]);
+ }
}
sourcing_name = NULL;
current_sctx.sc_sid = 0;
@@ -1738,12 +1691,14 @@ static void exe_commands(mparm_T *parmp)
curwin->w_cursor.lnum = 1;
}
- if (!exmode_active)
+ if (!exmode_active) {
msg_scroll = FALSE;
+ }
- /* When started with "-q errorfile" jump to first error again. */
- if (parmp->edit_type == EDIT_QF)
+ // When started with "-q errorfile" jump to first error again.
+ if (parmp->edit_type == EDIT_QF) {
qf_jump(NULL, 0, 0, FALSE);
+ }
TIME_MSG("executing command arguments");
}
@@ -1773,7 +1728,7 @@ static void do_system_initialization(void)
memcpy(vimrc, dir, dir_len);
vimrc[dir_len] = PATHSEP;
memcpy(vimrc + dir_len + 1, path_tail, sizeof(path_tail));
- if (do_source((char_u *)vimrc, false, DOSO_NONE) != FAIL) {
+ if (do_source((char_u *)vimrc, false, DOSO_NONE) != FAIL) {
xfree(vimrc);
xfree(config_dirs);
return;
@@ -1810,22 +1765,23 @@ static bool do_user_initialization(void)
}
char_u *init_lua_path = (char_u *)stdpaths_user_conf_subpath("init.lua");
+ char_u *user_vimrc = (char_u *)stdpaths_user_conf_subpath("init.vim");
+
+ // init.lua
if (os_path_exists(init_lua_path)
&& do_source(init_lua_path, true, DOSO_VIMRC)) {
- os_setenv("MYVIMRC", (const char *)init_lua_path, 1);
- char_u *vimrc_path = (char_u *)stdpaths_user_conf_subpath("init.vim");
-
- if (os_path_exists(vimrc_path)) {
- EMSG3(_("Conflicting configs: \"%s\" \"%s\""), init_lua_path, vimrc_path);
+ if (os_path_exists(user_vimrc)) {
+ EMSG3(_("E5422: Conflicting configs: \"%s\" \"%s\""), init_lua_path,
+ user_vimrc);
}
- xfree(vimrc_path);
+ xfree(user_vimrc);
xfree(init_lua_path);
return false;
}
xfree(init_lua_path);
- char_u *user_vimrc = (char_u *)stdpaths_user_conf_subpath("init.vim");
+ // init.vim
if (do_source(user_vimrc, true, DOSO_VIMRC) != FAIL) {
do_exrc = p_exrc;
if (do_exrc) {
@@ -1837,6 +1793,7 @@ static bool do_user_initialization(void)
return do_exrc;
}
xfree(user_vimrc);
+
char *const config_dirs = stdpaths_get_xdg_var(kXDGConfigDirs);
if (config_dirs != NULL) {
const void *iter = NULL;
@@ -1853,7 +1810,7 @@ static bool do_user_initialization(void)
memmove(vimrc, dir, dir_len);
vimrc[dir_len] = PATHSEP;
memmove(vimrc + dir_len + 1, path_tail, sizeof(path_tail));
- if (do_source((char_u *) vimrc, true, DOSO_VIMRC) != FAIL) {
+ if (do_source((char_u *)vimrc, true, DOSO_VIMRC) != FAIL) {
do_exrc = p_exrc;
if (do_exrc) {
do_exrc = (path_full_compare((char_u *)VIMRC_FILE, (char_u *)vimrc,
@@ -1867,6 +1824,7 @@ static bool do_user_initialization(void)
} while (iter != NULL);
xfree(config_dirs);
}
+
if (execute_env("EXINIT") == OK) {
do_exrc = p_exrc;
return do_exrc;
@@ -1903,7 +1861,7 @@ static void source_startup_scripts(const mparm_T *const parmp)
// If vimrc file is not owned by user, set 'secure' mode.
if (!file_owned(VIMRC_FILE))
#endif
- secure = p_secure;
+ secure = p_secure;
if (do_source((char_u *)VIMRC_FILE, true, DOSO_VIMRC) == FAIL) {
#if defined(UNIX)
@@ -2000,10 +1958,10 @@ static void mainerr(const char *errstr, const char *str)
/// Prints version information for "nvim -v" or "nvim --version".
static void version(void)
{
- info_message = TRUE; // use mch_msg(), not mch_errmsg()
+ info_message = true; // use mch_msg(), not mch_errmsg()
list_version();
msg_putchar('\n');
- msg_didout = FALSE;
+ msg_didout = false;
}
/// Prints help message for "nvim -h" or "nvim --help".
@@ -2059,7 +2017,8 @@ static void usage(void)
*/
static void check_swap_exists_action(void)
{
- if (swap_exists_action == SEA_QUIT)
+ if (swap_exists_action == SEA_QUIT) {
getout(1);
+ }
handle_swap_exists(NULL);
}
diff --git a/src/nvim/main.h b/src/nvim/main.h
index 61252f2bce..d387e6d668 100644
--- a/src/nvim/main.h
+++ b/src/nvim/main.h
@@ -30,6 +30,7 @@ typedef struct {
bool input_isatty; // stdin is a terminal
bool output_isatty; // stdout is a terminal
bool err_isatty; // stderr is a terminal
+ bool input_neverscript; // never treat stdin as script (-E/-Es)
int no_swap_file; // "-n" argument used
int use_debug_break_level;
int window_count; // number of windows to use
diff --git a/src/nvim/map.c b/src/nvim/map.c
index 7d97b7f13d..20d5570e8c 100644
--- a/src/nvim/map.c
+++ b/src/nvim/map.c
@@ -8,20 +8,18 @@
// khash.h does not make its own copy of the key or value.
//
-#include <stdlib.h>
+#include <lauxlib.h>
+#include <lua.h>
#include <stdbool.h>
+#include <stdlib.h>
#include <string.h>
-#include <lua.h>
-#include <lauxlib.h>
-
+#include "nvim/api/private/dispatch.h"
+#include "nvim/lib/khash.h"
#include "nvim/map.h"
#include "nvim/map_defs.h"
-#include "nvim/vim.h"
#include "nvim/memory.h"
-#include "nvim/api/private/dispatch.h"
-
-#include "nvim/lib/khash.h"
+#include "nvim/vim.h"
#define cstr_t_hash kh_str_hash_func
#define cstr_t_eq kh_str_hash_equal
@@ -38,11 +36,11 @@
#if defined(ARCH_64)
-#define ptr_t_hash(key) uint64_t_hash((uint64_t)key)
-#define ptr_t_eq(a, b) uint64_t_eq((uint64_t)a, (uint64_t)b)
+# define ptr_t_hash(key) uint64_t_hash((uint64_t)key)
+# define ptr_t_eq(a, b) uint64_t_eq((uint64_t)a, (uint64_t)b)
#elif defined(ARCH_32)
-#define ptr_t_hash(key) uint32_t_hash((uint32_t)key)
-#define ptr_t_eq(a, b) uint32_t_eq((uint32_t)a, (uint32_t)b)
+# define ptr_t_hash(key) uint32_t_hash((uint32_t)key)
+# define ptr_t_eq(a, b) uint32_t_eq((uint32_t)a, (uint32_t)b)
#endif
#define INITIALIZER(T, U) T##_##U##_initializer
@@ -52,58 +50,50 @@
#define MAP_IMPL(T, U, ...) \
INITIALIZER_DECLARE(T, U, __VA_ARGS__); \
- __KHASH_IMPL(T##_##U##_map,, T, U, 1, T##_hash, T##_eq) \
- \
- Map(T, U) *map_##T##_##U##_new() \
- { \
- Map(T, U) *rv = xmalloc(sizeof(Map(T, U))); \
- rv->table = kh_init(T##_##U##_map); \
- return rv; \
- } \
+ __KHASH_IMPL(T##_##U##_map, , T, U, 1, T##_hash, T##_eq) \
\
- void map_##T##_##U##_free(Map(T, U) *map) \
+ void map_##T##_##U##_destroy(Map(T, U) *map) \
{ \
- kh_destroy(T##_##U##_map, map->table); \
- xfree(map); \
+ kh_dealloc(T##_##U##_map, &map->table); \
} \
\
U map_##T##_##U##_get(Map(T, U) *map, T key) \
{ \
khiter_t k; \
\
- if ((k = kh_get(T##_##U##_map, map->table, key)) == kh_end(map->table)) { \
+ if ((k = kh_get(T##_##U##_map, &map->table, key)) == kh_end(&map->table)) { \
return INITIALIZER(T, U); \
} \
\
- return kh_val(map->table, k); \
+ return kh_val(&map->table, k); \
} \
\
bool map_##T##_##U##_has(Map(T, U) *map, T key) \
{ \
- return kh_get(T##_##U##_map, map->table, key) != kh_end(map->table); \
+ return kh_get(T##_##U##_map, &map->table, key) != kh_end(&map->table); \
} \
\
T map_##T##_##U##_key(Map(T, U) *map, T key) \
{ \
khiter_t k; \
\
- if ((k = kh_get(T##_##U##_map, map->table, key)) == kh_end(map->table)) { \
+ if ((k = kh_get(T##_##U##_map, &map->table, key)) == kh_end(&map->table)) { \
abort(); /* Caller must check map_has(). */ \
} \
\
- return kh_key(map->table, k); \
+ return kh_key(&map->table, k); \
} \
U map_##T##_##U##_put(Map(T, U) *map, T key, U value) \
{ \
int ret; \
U rv = INITIALIZER(T, U); \
- khiter_t k = kh_put(T##_##U##_map, map->table, key, &ret); \
+ khiter_t k = kh_put(T##_##U##_map, &map->table, key, &ret); \
\
if (!ret) { \
- rv = kh_val(map->table, k); \
+ rv = kh_val(&map->table, k); \
} \
\
- kh_val(map->table, k) = value; \
+ kh_val(&map->table, k) = value; \
return rv; \
} \
\
@@ -112,18 +102,18 @@
int ret; \
khiter_t k; \
if (put) { \
- k = kh_put(T##_##U##_map, map->table, key, &ret); \
+ k = kh_put(T##_##U##_map, &map->table, key, &ret); \
if (ret) { \
- kh_val(map->table, k) = INITIALIZER(T, U); \
+ kh_val(&map->table, k) = INITIALIZER(T, U); \
} \
} else { \
- k = kh_get(T##_##U##_map, map->table, key); \
- if (k == kh_end(map->table)) { \
+ k = kh_get(T##_##U##_map, &map->table, key); \
+ if (k == kh_end(&map->table)) { \
return NULL; \
} \
} \
\
- return &kh_val(map->table, k); \
+ return &kh_val(&map->table, k); \
} \
\
U map_##T##_##U##_del(Map(T, U) *map, T key) \
@@ -131,9 +121,9 @@
U rv = INITIALIZER(T, U); \
khiter_t k; \
\
- if ((k = kh_get(T##_##U##_map, map->table, key)) != kh_end(map->table)) { \
- rv = kh_val(map->table, k); \
- kh_del(T##_##U##_map, map->table, k); \
+ if ((k = kh_get(T##_##U##_map, &map->table, key)) != kh_end(&map->table)) { \
+ rv = kh_val(&map->table, k); \
+ kh_del(T##_##U##_map, &map->table, k); \
} \
\
return rv; \
@@ -141,7 +131,7 @@
\
void map_##T##_##U##_clear(Map(T, U) *map) \
{ \
- kh_clear(T##_##U##_map, map->table); \
+ kh_clear(T##_##U##_map, &map->table); \
}
static inline khint_t String_hash(String s)
@@ -194,11 +184,12 @@ static inline bool ColorKey_eq(ColorKey ae1, ColorKey ae2)
MAP_IMPL(int, int, DEFAULT_INITIALIZER)
MAP_IMPL(cstr_t, ptr_t, DEFAULT_INITIALIZER)
+MAP_IMPL(cstr_t, int, DEFAULT_INITIALIZER)
MAP_IMPL(ptr_t, ptr_t, DEFAULT_INITIALIZER)
MAP_IMPL(uint64_t, ptr_t, DEFAULT_INITIALIZER)
MAP_IMPL(uint64_t, ssize_t, SSIZE_INITIALIZER)
MAP_IMPL(uint64_t, uint64_t, DEFAULT_INITIALIZER)
-#define EXTMARK_NS_INITIALIZER { 0, 0 }
+#define EXTMARK_NS_INITIALIZER { { MAP_INIT }, 1 }
MAP_IMPL(uint64_t, ExtmarkNs, EXTMARK_NS_INITIALIZER)
#define EXTMARK_ITEM_INITIALIZER { 0, 0, NULL }
MAP_IMPL(uint64_t, ExtmarkItem, EXTMARK_ITEM_INITIALIZER)
diff --git a/src/nvim/map.h b/src/nvim/map.h
index 7bd3d31330..d6515878a2 100644
--- a/src/nvim/map.h
+++ b/src/nvim/map.h
@@ -18,11 +18,12 @@
KHASH_DECLARE(T##_##U##_map, T, U) \
\
typedef struct { \
- khash_t(T##_##U##_map) *table; \
+ khash_t(T##_##U##_map) table; \
} Map(T, U); \
\
Map(T, U) *map_##T##_##U##_new(void); \
void map_##T##_##U##_free(Map(T, U) *map); \
+ void map_##T##_##U##_destroy(Map(T, U) *map); \
U map_##T##_##U##_get(Map(T, U) *map, T key); \
bool map_##T##_##U##_has(Map(T, U) *map, T key); \
T map_##T##_##U##_key(Map(T, U) *map, T key); \
@@ -36,6 +37,7 @@
//
MAP_DECLS(int, int)
MAP_DECLS(cstr_t, ptr_t)
+MAP_DECLS(cstr_t, int)
MAP_DECLS(ptr_t, ptr_t)
MAP_DECLS(uint64_t, ptr_t)
MAP_DECLS(uint64_t, ssize_t)
@@ -44,7 +46,7 @@ MAP_DECLS(uint64_t, uint64_t)
// NB: this is the only way to define a struct both containing and contained
// in a map...
typedef struct ExtmarkNs { // For namespacing extmarks
- Map(uint64_t, uint64_t) *map; // For fast lookup
+ Map(uint64_t, uint64_t) map[1]; // For fast lookup
uint64_t free_id; // For automatically assigning id's
} ExtmarkNs;
@@ -57,8 +59,10 @@ MAP_DECLS(String, handle_T)
MAP_DECLS(ColorKey, ColorItem)
-#define map_new(T, U) map_##T##_##U##_new
-#define map_free(T, U) map_##T##_##U##_free
+#define MAP_INIT { { 0, 0, 0, 0, NULL, NULL, NULL } }
+#define map_init(k, v, map) do { *(map) = (Map(k, v))MAP_INIT; } while (false)
+
+#define map_destroy(T, U) map_##T##_##U##_destroy
#define map_get(T, U) map_##T##_##U##_get
#define map_has(T, U) map_##T##_##U##_has
#define map_key(T, U) map_##T##_##U##_key
@@ -67,10 +71,9 @@ MAP_DECLS(ColorKey, ColorItem)
#define map_del(T, U) map_##T##_##U##_del
#define map_clear(T, U) map_##T##_##U##_clear
-#define map_size(map) ((map)->table->size)
+#define map_size(map) ((map)->table.size)
-#define pmap_new(T) map_new(T, ptr_t)
-#define pmap_free(T) map_free(T, ptr_t)
+#define pmap_destroy(T) map_destroy(T, ptr_t)
#define pmap_get(T) map_get(T, ptr_t)
#define pmap_has(T) map_has(T, ptr_t)
#define pmap_key(T) map_key(T, ptr_t)
@@ -79,12 +82,13 @@ MAP_DECLS(ColorKey, ColorItem)
/// @see pmap_del2
#define pmap_del(T) map_del(T, ptr_t)
#define pmap_clear(T) map_clear(T, ptr_t)
+#define pmap_init(k, map) map_init(k, ptr_t, map)
#define map_foreach(map, key, value, block) \
- kh_foreach(map->table, key, value, block)
+ kh_foreach(&(map)->table, key, value, block)
#define map_foreach_value(map, value, block) \
- kh_foreach_value(map->table, value, block)
+ kh_foreach_value(&(map)->table, value, block)
void pmap_del2(PMap(cstr_t) *map, const char *key);
diff --git a/src/nvim/mark.c b/src/nvim/mark.c
index 73a9c1d1d7..b296bf39cf 100644
--- a/src/nvim/mark.c
+++ b/src/nvim/mark.c
@@ -7,35 +7,35 @@
#include <assert.h>
#include <inttypes.h>
-#include <string.h>
#include <limits.h>
+#include <string.h>
-#include "nvim/vim.h"
#include "nvim/ascii.h"
-#include "nvim/mark.h"
#include "nvim/buffer.h"
#include "nvim/charset.h"
#include "nvim/diff.h"
#include "nvim/eval.h"
#include "nvim/ex_cmds.h"
+#include "nvim/extmark.h"
#include "nvim/fileio.h"
#include "nvim/fold.h"
-#include "nvim/extmark.h"
+#include "nvim/mark.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/normal.h"
#include "nvim/option.h"
+#include "nvim/os/input.h"
+#include "nvim/os/os.h"
+#include "nvim/os/time.h"
#include "nvim/path.h"
#include "nvim/quickfix.h"
#include "nvim/search.h"
#include "nvim/sign.h"
#include "nvim/strings.h"
#include "nvim/ui.h"
-#include "nvim/os/os.h"
-#include "nvim/os/time.h"
-#include "nvim/os/input.h"
+#include "nvim/vim.h"
/*
* This file contains routines to maintain and manipulate marks.
@@ -94,21 +94,23 @@ int setmark_pos(int c, pos_T *pos, int fnum)
{
int i;
- /* Check for a special key (may cause islower() to crash). */
- if (c < 0)
+ // Check for a special key (may cause islower() to crash).
+ if (c < 0) {
return FAIL;
+ }
if (c == '\'' || c == '`') {
if (pos == &curwin->w_cursor) {
setpcmark();
- /* keep it even when the cursor doesn't move */
+ // keep it even when the cursor doesn't move
curwin->w_prev_pcmark = curwin->w_pcmark;
- } else
+ } else {
curwin->w_pcmark = *pos;
+ }
return OK;
}
- // Can't set a mark in a non-existant buffer.
+ // Can't set a mark in a non-existent buffer.
buf_T *buf = buflist_findnr(fnum);
if (buf == NULL) {
return FAIL;
@@ -166,11 +168,12 @@ int setmark_pos(int c, pos_T *pos, int fnum)
*/
void setpcmark(void)
{
- xfmark_T *fm;
+ xfmark_T *fm;
- /* for :global the mark is set only once */
- if (global_busy || listcmd_busy || cmdmod.keepjumps)
+ // for :global the mark is set only once
+ if (global_busy || listcmd_busy || cmdmod.keepjumps) {
return;
+ }
curwin->w_prev_pcmark = curwin->w_pcmark;
curwin->w_pcmark = curwin->w_cursor;
@@ -189,7 +192,7 @@ void setpcmark(void)
}
}
- /* If jumplist is full: remove oldest entry */
+ // If jumplist is full: remove oldest entry
if (++curwin->w_jumplistlen > JUMPLISTSIZE) {
curwin->w_jumplistlen = JUMPLISTSIZE;
free_xfmark(curwin->w_jumplist[0]);
@@ -214,7 +217,7 @@ void checkpcmark(void)
&& (equalpos(curwin->w_pcmark, curwin->w_cursor)
|| curwin->w_pcmark.lnum == 0)) {
curwin->w_pcmark = curwin->w_prev_pcmark;
- curwin->w_prev_pcmark.lnum = 0; /* Show it has been checked */
+ curwin->w_prev_pcmark.lnum = 0; // Show it has been checked
}
}
@@ -223,18 +226,20 @@ void checkpcmark(void)
*/
pos_T *movemark(int count)
{
- pos_T *pos;
- xfmark_T *jmp;
+ pos_T *pos;
+ xfmark_T *jmp;
cleanup_jumplist(curwin, true);
- if (curwin->w_jumplistlen == 0) /* nothing to jump to */
+ if (curwin->w_jumplistlen == 0) { // nothing to jump to
return (pos_T *)NULL;
+ }
for (;; ) {
if (curwin->w_jumplistidx + count < 0
- || curwin->w_jumplistidx + count >= curwin->w_jumplistlen)
+ || curwin->w_jumplistidx + count >= curwin->w_jumplistlen) {
return (pos_T *)NULL;
+ }
/*
* if first CTRL-O or CTRL-I command after a jump, add cursor position
@@ -243,30 +248,34 @@ pos_T *movemark(int count)
*/
if (curwin->w_jumplistidx == curwin->w_jumplistlen) {
setpcmark();
- --curwin->w_jumplistidx; /* skip the new entry */
- if (curwin->w_jumplistidx + count < 0)
+ --curwin->w_jumplistidx; // skip the new entry
+ if (curwin->w_jumplistidx + count < 0) {
return (pos_T *)NULL;
+ }
}
curwin->w_jumplistidx += count;
jmp = curwin->w_jumplist + curwin->w_jumplistidx;
- if (jmp->fmark.fnum == 0)
+ if (jmp->fmark.fnum == 0) {
fname2fnum(jmp);
+ }
if (jmp->fmark.fnum != curbuf->b_fnum) {
- /* jump to other file */
- if (buflist_findnr(jmp->fmark.fnum) == NULL) { /* Skip this one .. */
+ // jump to other file
+ if (buflist_findnr(jmp->fmark.fnum) == NULL) { // Skip this one ..
count += count < 0 ? -1 : 1;
continue;
}
if (buflist_getfile(jmp->fmark.fnum, jmp->fmark.mark.lnum,
- 0, FALSE) == FAIL)
+ 0, FALSE) == FAIL) {
return (pos_T *)NULL;
- /* Set lnum again, autocommands my have changed it */
+ }
+ // Set lnum again, autocommands my have changed it
curwin->w_cursor = jmp->fmark.mark;
pos = (pos_T *)-1;
- } else
+ } else {
pos = &(jmp->fmark.mark);
+ }
return pos;
}
}
@@ -278,20 +287,24 @@ pos_T *movechangelist(int count)
{
int n;
- if (curbuf->b_changelistlen == 0) /* nothing to jump to */
+ if (curbuf->b_changelistlen == 0) { // nothing to jump to
return (pos_T *)NULL;
+ }
n = curwin->w_changelistidx;
if (n + count < 0) {
- if (n == 0)
+ if (n == 0) {
return (pos_T *)NULL;
+ }
n = 0;
} else if (n + count >= curbuf->b_changelistlen) {
- if (n == curbuf->b_changelistlen - 1)
+ if (n == curbuf->b_changelistlen - 1) {
return (pos_T *)NULL;
+ }
n = curbuf->b_changelistlen - 1;
- } else
+ } else {
n += count;
+ }
curwin->w_changelistidx = n;
return &(curbuf->b_changelist[n].mark);
}
@@ -319,16 +332,17 @@ pos_T *getmark(int c, bool changefile)
pos_T *getmark_buf_fnum(buf_T *buf, int c, bool changefile, int *fnum)
{
- pos_T *posp;
- pos_T *startp, *endp;
+ pos_T *posp;
+ pos_T *startp, *endp;
static pos_T pos_copy;
posp = NULL;
/* Check for special key, can't be a mark name and might cause islower()
* to crash. */
- if (c < 0)
+ if (c < 0) {
return posp;
+ }
if (c > '~') { // check for islower()/isupper()
} else if (c == '\'' || c == '`') { // previous context mark
pos_copy = curwin->w_pcmark; // need to make a copy because
@@ -346,30 +360,30 @@ pos_T *getmark_buf_fnum(buf_T *buf, int c, bool changefile, int *fnum)
} else if (c == '{' || c == '}') { // to previous/next paragraph
pos_T pos;
oparg_T oa;
- int slcb = listcmd_busy;
+ bool slcb = listcmd_busy;
pos = curwin->w_cursor;
- listcmd_busy = TRUE; /* avoid that '' is changed */
+ listcmd_busy = true; // avoid that '' is changed
if (findpar(&oa.inclusive,
- c == '}' ? FORWARD : BACKWARD, 1L, NUL, FALSE)) {
+ c == '}' ? FORWARD : BACKWARD, 1L, NUL, FALSE)) {
pos_copy = curwin->w_cursor;
posp = &pos_copy;
}
curwin->w_cursor = pos;
listcmd_busy = slcb;
- } else if (c == '(' || c == ')') { /* to previous/next sentence */
+ } else if (c == '(' || c == ')') { // to previous/next sentence
pos_T pos;
- int slcb = listcmd_busy;
+ bool slcb = listcmd_busy;
pos = curwin->w_cursor;
- listcmd_busy = TRUE; /* avoid that '' is changed */
+ listcmd_busy = true; // avoid that '' is changed
if (findsent(c == ')' ? FORWARD : BACKWARD, 1L)) {
pos_copy = curwin->w_cursor;
posp = &pos_copy;
}
curwin->w_cursor = pos;
listcmd_busy = slcb;
- } else if (c == '<' || c == '>') { /* start/end of visual area */
+ } else if (c == '<' || c == '>') { // start/end of visual area
startp = &buf->b_visual.vi_start;
endp = &buf->b_visual.vi_end;
if (((c == '<') == lt(*startp, *endp) || endp->lnum == 0)
@@ -383,63 +397,62 @@ pos_T *getmark_buf_fnum(buf_T *buf, int c, bool changefile, int *fnum)
if (buf->b_visual.vi_mode == 'V') {
pos_copy = *posp;
posp = &pos_copy;
- if (c == '<')
+ if (c == '<') {
pos_copy.col = 0;
- else
+ } else {
pos_copy.col = MAXCOL;
+ }
pos_copy.coladd = 0;
}
- } else if (ASCII_ISLOWER(c)) { /* normal named mark */
+ } else if (ASCII_ISLOWER(c)) { // normal named mark
posp = &(buf->b_namedm[c - 'a'].mark);
- } else if (ASCII_ISUPPER(c) || ascii_isdigit(c)) { /* named file mark */
- if (ascii_isdigit(c))
+ } else if (ASCII_ISUPPER(c) || ascii_isdigit(c)) { // named file mark
+ if (ascii_isdigit(c)) {
c = c - '0' + NMARKS;
- else
+ } else {
c -= 'A';
+ }
posp = &(namedfm[c].fmark.mark);
if (namedfm[c].fmark.fnum == 0) {
fname2fnum(&namedfm[c]);
}
- if (fnum != NULL)
+ if (fnum != NULL) {
*fnum = namedfm[c].fmark.fnum;
- else if (namedfm[c].fmark.fnum != buf->b_fnum) {
- /* mark is in another file */
+ } else if (namedfm[c].fmark.fnum != buf->b_fnum) {
+ // mark is in another file
posp = &pos_copy;
if (namedfm[c].fmark.mark.lnum != 0
&& changefile && namedfm[c].fmark.fnum) {
if (buflist_getfile(namedfm[c].fmark.fnum,
- (linenr_T)1, GETF_SETMARK, FALSE) == OK) {
- /* Set the lnum now, autocommands could have changed it */
+ (linenr_T)1, GETF_SETMARK, FALSE) == OK) {
+ // Set the lnum now, autocommands could have changed it
curwin->w_cursor = namedfm[c].fmark.mark;
return (pos_T *)-1;
}
- pos_copy.lnum = -1; /* can't get file */
- } else
+ pos_copy.lnum = -1; // can't get file
+ } else {
pos_copy.lnum = 0; /* mark exists, but is not valid in
current buffer */
+ }
}
}
return posp;
}
-/*
- * Search for the next named mark in the current file.
- *
- * Returns pointer to pos_T of the next mark or NULL if no mark is found.
- */
-pos_T *
-getnextmark (
- pos_T *startpos, /* where to start */
- int dir, /* direction for search */
- int begin_line
-)
+/// Search for the next named mark in the current file.
+///
+/// @param startpos where to start
+/// @param dir direction for search
+///
+/// @return pointer to pos_T of the next mark or NULL if no mark is found.
+pos_T *getnextmark(pos_T *startpos, int dir, int begin_line)
{
int i;
- pos_T *result = NULL;
+ pos_T *result = NULL;
pos_T pos;
pos = *startpos;
@@ -448,21 +461,24 @@ getnextmark (
* position must be in a previous line.
* When searching forward and leaving the cursor on the first non-blank,
* position must be in a next line. */
- if (dir == BACKWARD && begin_line)
+ if (dir == BACKWARD && begin_line) {
pos.col = 0;
- else if (dir == FORWARD && begin_line)
+ } else if (dir == FORWARD && begin_line) {
pos.col = MAXCOL;
+ }
for (i = 0; i < NMARKS; i++) {
if (curbuf->b_namedm[i].mark.lnum > 0) {
if (dir == FORWARD) {
if ((result == NULL || lt(curbuf->b_namedm[i].mark, *result))
- && lt(pos, curbuf->b_namedm[i].mark))
+ && lt(pos, curbuf->b_namedm[i].mark)) {
result = &curbuf->b_namedm[i].mark;
+ }
} else {
if ((result == NULL || lt(*result, curbuf->b_namedm[i].mark))
- && lt(curbuf->b_namedm[i].mark, pos))
+ && lt(curbuf->b_namedm[i].mark, pos)) {
result = &curbuf->b_namedm[i].mark;
+ }
}
}
}
@@ -494,10 +510,11 @@ static void fname2fnum(xfmark_T *fm)
expand_env((char_u *)"~/", NameBuff, MAXPATHL);
len = (int)STRLEN(NameBuff);
STRLCPY(NameBuff + len, fm->fname + 2, MAXPATHL - len);
- } else
+ } else {
STRLCPY(NameBuff, fm->fname, MAXPATHL);
+ }
- /* Try to shorten the file name. */
+ // Try to shorten the file name.
os_dirname(IObuff, IOSIZE);
p = path_shorten_fname(NameBuff, IObuff);
@@ -513,14 +530,16 @@ static void fname2fnum(xfmark_T *fm)
*/
void fmarks_check_names(buf_T *buf)
{
- char_u *name = buf->b_ffname;
+ char_u *name = buf->b_ffname;
int i;
- if (buf->b_ffname == NULL)
+ if (buf->b_ffname == NULL) {
return;
+ }
- for (i = 0; i < NGLOBALMARKS; ++i)
+ for (i = 0; i < NGLOBALMARKS; ++i) {
fmarks_check_one(&namedfm[i], name, buf);
+ }
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
for (i = 0; i < wp->w_jumplistlen; ++i) {
@@ -552,8 +571,9 @@ int check_mark(pos_T *pos)
if (pos->lnum <= 0) {
/* lnum is negative if mark is in another file can can't get that
* file, error message already give then. */
- if (pos->lnum == 0)
+ if (pos->lnum == 0) {
EMSG(_(e_marknotset));
+ }
return FAIL;
}
if (pos->lnum > curbuf->b_ml.ml_line_count) {
@@ -593,8 +613,9 @@ void clrallmarks(buf_T *const buf)
*/
char_u *fm_getname(fmark_T *fmark, int lead_len)
{
- if (fmark->fnum == curbuf->b_fnum) /* current buffer */
+ if (fmark->fnum == curbuf->b_fnum) { // current buffer
return mark_line(&(fmark->mark), lead_len);
+ }
return buflist_nr2name(fmark->fnum, FALSE, TRUE);
}
@@ -604,11 +625,12 @@ char_u *fm_getname(fmark_T *fmark, int lead_len)
*/
static char_u *mark_line(pos_T *mp, int lead_len)
{
- char_u *s, *p;
+ char_u *s, *p;
int len;
- if (mp->lnum == 0 || mp->lnum > curbuf->b_ml.ml_line_count)
+ if (mp->lnum == 0 || mp->lnum > curbuf->b_ml.ml_line_count) {
return vim_strsave((char_u *)"-invalid-");
+ }
assert(Columns >= 0 && (size_t)Columns <= SIZE_MAX);
// Allow for up to 5 bytes per character.
s = vim_strnsave(skipwhite(ml_get(mp->lnum)), (size_t)Columns * 5);
@@ -617,8 +639,9 @@ static char_u *mark_line(pos_T *mp, int lead_len)
len = 0;
for (p = s; *p != NUL; MB_PTR_ADV(p)) {
len += ptr2cells(p);
- if (len >= Columns - lead_len)
+ if (len >= Columns - lead_len) {
break;
+ }
}
*p = NUL;
return s;
@@ -629,28 +652,32 @@ static char_u *mark_line(pos_T *mp, int lead_len)
*/
void ex_marks(exarg_T *eap)
{
- char_u *arg = eap->arg;
+ char_u *arg = eap->arg;
int i;
- char_u *name;
- pos_T *posp, *startp, *endp;
+ char_u *name;
+ pos_T *posp, *startp, *endp;
- if (arg != NULL && *arg == NUL)
+ if (arg != NULL && *arg == NUL) {
arg = NULL;
+ }
show_one_mark('\'', arg, &curwin->w_pcmark, NULL, true);
- for (i = 0; i < NMARKS; ++i)
+ for (i = 0; i < NMARKS; ++i) {
show_one_mark(i + 'a', arg, &curbuf->b_namedm[i].mark, NULL, true);
+ }
for (i = 0; i < NGLOBALMARKS; ++i) {
- if (namedfm[i].fmark.fnum != 0)
+ if (namedfm[i].fmark.fnum != 0) {
name = fm_getname(&namedfm[i].fmark, 15);
- else
+ } else {
name = namedfm[i].fname;
+ }
if (name != NULL) {
show_one_mark(i >= NMARKS ? i - NMARKS + '0' : i + 'A',
- arg, &namedfm[i].fmark.mark, name,
- namedfm[i].fmark.fnum == curbuf->b_fnum);
- if (namedfm[i].fmark.fnum != 0)
+ arg, &namedfm[i].fmark.mark, name,
+ namedfm[i].fmark.fnum == curbuf->b_fnum);
+ if (namedfm[i].fmark.fnum != 0) {
xfree(name);
+ }
}
}
show_one_mark('"', arg, &curbuf->b_last_cursor.mark, NULL, true);
@@ -673,14 +700,8 @@ void ex_marks(exarg_T *eap)
show_one_mark(-1, arg, NULL, NULL, false);
}
-static void
-show_one_mark(
- int c,
- char_u *arg,
- pos_T *p,
- char_u *name_arg,
- int current // in current file
-)
+/// @param current in current file
+static void show_one_mark(int c, char_u *arg, pos_T *p, char_u *name_arg, int current)
{
static bool did_title = false;
bool mustfree = false;
@@ -731,41 +752,42 @@ show_one_mark(
*/
void ex_delmarks(exarg_T *eap)
{
- char_u *p;
+ char_u *p;
int from, to;
int i;
int lower;
int digit;
int n;
- if (*eap->arg == NUL && eap->forceit)
- /* clear all marks */
+ if (*eap->arg == NUL && eap->forceit) {
+ // clear all marks
clrallmarks(curbuf);
- else if (eap->forceit)
+ } else if (eap->forceit) {
EMSG(_(e_invarg));
- else if (*eap->arg == NUL)
+ } else if (*eap->arg == NUL) {
EMSG(_(e_argreq));
- else {
- /* clear specified marks only */
+ } else {
+ // clear specified marks only
for (p = eap->arg; *p != NUL; ++p) {
lower = ASCII_ISLOWER(*p);
digit = ascii_isdigit(*p);
if (lower || digit || ASCII_ISUPPER(*p)) {
if (p[1] == '-') {
- /* clear range of marks */
+ // clear range of marks
from = *p;
to = p[2];
if (!(lower ? ASCII_ISLOWER(p[2])
- : (digit ? ascii_isdigit(p[2])
- : ASCII_ISUPPER(p[2])))
+ : (digit ? ascii_isdigit(p[2])
+ : ASCII_ISUPPER(p[2])))
|| to < from) {
EMSG2(_(e_invarg2), p);
return;
}
p += 2;
- } else
- /* clear one lower case mark */
+ } else {
+ // clear one lower case mark
from = to = *p;
+ }
for (i = from; i <= to; ++i) {
if (lower) {
@@ -781,19 +803,29 @@ void ex_delmarks(exarg_T *eap)
XFREE_CLEAR(namedfm[n].fname);
}
}
- } else
+ } else {
switch (*p) {
- case '"': CLEAR_FMARK(&curbuf->b_last_cursor); break;
- case '^': CLEAR_FMARK(&curbuf->b_last_insert); break;
- case '.': CLEAR_FMARK(&curbuf->b_last_change); break;
- case '[': curbuf->b_op_start.lnum = 0; break;
- case ']': curbuf->b_op_end.lnum = 0; break;
- case '<': curbuf->b_visual.vi_start.lnum = 0; break;
- case '>': curbuf->b_visual.vi_end.lnum = 0; break;
- case ' ': break;
- default: EMSG2(_(e_invarg2), p);
+ case '"':
+ CLEAR_FMARK(&curbuf->b_last_cursor); break;
+ case '^':
+ CLEAR_FMARK(&curbuf->b_last_insert); break;
+ case '.':
+ CLEAR_FMARK(&curbuf->b_last_change); break;
+ case '[':
+ curbuf->b_op_start.lnum = 0; break;
+ case ']':
+ curbuf->b_op_end.lnum = 0; break;
+ case '<':
+ curbuf->b_visual.vi_start.lnum = 0; break;
+ case '>':
+ curbuf->b_visual.vi_end.lnum = 0; break;
+ case ' ':
+ break;
+ default:
+ EMSG2(_(e_invarg2), p);
return;
}
+ }
}
}
}
@@ -804,7 +836,7 @@ void ex_delmarks(exarg_T *eap)
void ex_jumps(exarg_T *eap)
{
int i;
- char_u *name;
+ char_u *name;
cleanup_jumplist(curwin, true);
// Highlight title
@@ -825,11 +857,11 @@ void ex_jumps(exarg_T *eap)
break;
}
sprintf((char *)IObuff, "%c %2d %5ld %4d ",
- i == curwin->w_jumplistidx ? '>' : ' ',
- i > curwin->w_jumplistidx ? i - curwin->w_jumplistidx
- : curwin->w_jumplistidx - i,
- curwin->w_jumplist[i].fmark.mark.lnum,
- curwin->w_jumplist[i].fmark.mark.col);
+ i == curwin->w_jumplistidx ? '>' : ' ',
+ i > curwin->w_jumplistidx ? i - curwin->w_jumplistidx
+ : curwin->w_jumplistidx - i,
+ curwin->w_jumplist[i].fmark.mark.lnum,
+ curwin->w_jumplist[i].fmark.mark.col);
msg_outtrans(IObuff);
msg_outtrans_attr(name,
curwin->w_jumplist[i].fmark.fnum == curbuf->b_fnum
@@ -839,8 +871,9 @@ void ex_jumps(exarg_T *eap)
}
ui_flush();
}
- if (curwin->w_jumplistidx == curwin->w_jumplistlen)
+ if (curwin->w_jumplistidx == curwin->w_jumplistlen) {
MSG_PUTS("\n>");
+ }
}
void ex_clearjumps(exarg_T *eap)
@@ -856,7 +889,7 @@ void ex_clearjumps(exarg_T *eap)
void ex_changes(exarg_T *eap)
{
int i;
- char_u *name;
+ char_u *name;
// Highlight title
MSG_PUTS_TITLE(_("\nchange line col text"));
@@ -864,14 +897,15 @@ void ex_changes(exarg_T *eap)
for (i = 0; i < curbuf->b_changelistlen && !got_int; ++i) {
if (curbuf->b_changelist[i].mark.lnum != 0) {
msg_putchar('\n');
- if (got_int)
+ if (got_int) {
break;
+ }
sprintf((char *)IObuff, "%c %3d %5ld %4d ",
- i == curwin->w_changelistidx ? '>' : ' ',
- i > curwin->w_changelistidx ? i - curwin->w_changelistidx
- : curwin->w_changelistidx - i,
- (long)curbuf->b_changelist[i].mark.lnum,
- curbuf->b_changelist[i].mark.col);
+ i == curwin->w_changelistidx ? '>' : ' ',
+ i > curwin->w_changelistidx ? i - curwin->w_changelistidx
+ : curwin->w_changelistidx - i,
+ (long)curbuf->b_changelist[i].mark.lnum,
+ curbuf->b_changelist[i].mark.col);
msg_outtrans(IObuff);
name = mark_line(&curbuf->b_changelist[i].mark, 17);
msg_outtrans_attr(name, HL_ATTR(HLF_D));
@@ -880,8 +914,9 @@ void ex_changes(exarg_T *eap)
}
ui_flush();
}
- if (curwin->w_changelistidx == curbuf->b_changelistlen)
+ if (curwin->w_changelistidx == curbuf->b_changelistlen) {
MSG_PUTS("\n>");
+ }
}
#define one_adjust(add) \
@@ -890,27 +925,27 @@ void ex_changes(exarg_T *eap)
if (*lp >= line1 && *lp <= line2) \
{ \
if (amount == MAXLNUM) \
- *lp = 0; \
+ *lp = 0; \
else \
- *lp += amount; \
+ *lp += amount; \
} \
else if (amount_after && *lp > line2) \
- *lp += amount_after; \
+ *lp += amount_after; \
}
-/* don't delete the line, just put at first deleted line */
+// don't delete the line, just put at first deleted line
#define one_adjust_nodel(add) \
{ \
lp = add; \
if (*lp >= line1 && *lp <= line2) \
{ \
if (amount == MAXLNUM) \
- *lp = line1; \
+ *lp = line1; \
else \
- *lp += amount; \
+ *lp += amount; \
} \
else if (amount_after && *lp > line2) \
- *lp += amount_after; \
+ *lp += amount_after; \
}
/*
@@ -922,13 +957,9 @@ void ex_changes(exarg_T *eap)
* If 'amount_after' is non-zero adjust marks after line2.
* Example: Delete lines 34 and 35: mark_adjust(34, 35, MAXLNUM, -2);
* Example: Insert two lines below 55: mark_adjust(56, MAXLNUM, 2, 0);
- * or: mark_adjust(56, 55, MAXLNUM, 2);
+ * or: mark_adjust(56, 55, MAXLNUM, 2);
*/
-void mark_adjust(linenr_T line1,
- linenr_T line2,
- long amount,
- long amount_after,
- ExtmarkOp op)
+void mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after, ExtmarkOp op)
{
mark_adjust_internal(line1, line2, amount, amount_after, true, op);
}
@@ -938,54 +969,56 @@ void mark_adjust(linenr_T line1,
// This is only useful when folds need to be moved in a way different to
// calling foldMarkAdjust() with arguments line1, line2, amount, amount_after,
// for an example of why this may be necessary, see do_move().
-void mark_adjust_nofold(linenr_T line1, linenr_T line2, long amount,
- long amount_after,
+void mark_adjust_nofold(linenr_T line1, linenr_T line2, long amount, long amount_after,
ExtmarkOp op)
{
mark_adjust_internal(line1, line2, amount, amount_after, false, op);
}
-static void mark_adjust_internal(linenr_T line1, linenr_T line2,
- long amount, long amount_after,
- bool adjust_folds,
- ExtmarkOp op)
+static void mark_adjust_internal(linenr_T line1, linenr_T line2, long amount, long amount_after,
+ bool adjust_folds, ExtmarkOp op)
{
int i;
int fnum = curbuf->b_fnum;
- linenr_T *lp;
+ linenr_T *lp;
static pos_T initpos = { 1, 0, 0 };
- if (line2 < line1 && amount_after == 0L) /* nothing to do */
+ if (line2 < line1 && amount_after == 0L) { // nothing to do
return;
+ }
if (!cmdmod.lockmarks) {
- /* named marks, lower case and upper case */
+ // named marks, lower case and upper case
for (i = 0; i < NMARKS; i++) {
one_adjust(&(curbuf->b_namedm[i].mark.lnum));
- if (namedfm[i].fmark.fnum == fnum)
+ if (namedfm[i].fmark.fnum == fnum) {
one_adjust_nodel(&(namedfm[i].fmark.mark.lnum));
+ }
}
for (i = NMARKS; i < NGLOBALMARKS; i++) {
- if (namedfm[i].fmark.fnum == fnum)
+ if (namedfm[i].fmark.fnum == fnum) {
one_adjust_nodel(&(namedfm[i].fmark.mark.lnum));
+ }
}
- /* last Insert position */
+ // last Insert position
one_adjust(&(curbuf->b_last_insert.mark.lnum));
- /* last change position */
+ // last change position
one_adjust(&(curbuf->b_last_change.mark.lnum));
- /* last cursor position, if it was set */
- if (!equalpos(curbuf->b_last_cursor.mark, initpos))
+ // last cursor position, if it was set
+ if (!equalpos(curbuf->b_last_cursor.mark, initpos)) {
one_adjust(&(curbuf->b_last_cursor.mark.lnum));
+ }
- /* list of change positions */
- for (i = 0; i < curbuf->b_changelistlen; ++i)
+ // list of change positions
+ for (i = 0; i < curbuf->b_changelistlen; ++i) {
one_adjust_nodel(&(curbuf->b_changelist[i].mark.lnum));
+ }
- /* Visual area */
+ // Visual area
one_adjust_nodel(&(curbuf->b_visual.vi_start.lnum));
one_adjust_nodel(&(curbuf->b_visual.vi_end.lnum));
@@ -1008,15 +1041,16 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2,
}
}
- /* previous context mark */
+ // previous context mark
one_adjust(&(curwin->w_pcmark.lnum));
- /* previous pcmark */
+ // previous pcmark
one_adjust(&(curwin->w_prev_pcmark.lnum));
- /* saved cursor for formatting */
- if (saved_cursor.lnum != 0)
+ // saved cursor for formatting
+ if (saved_cursor.lnum != 0) {
one_adjust_nodel(&(saved_cursor.lnum));
+ }
/*
* Adjust items in all windows related to the current buffer.
@@ -1034,7 +1068,7 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2,
if (win->w_buffer == curbuf) {
if (!cmdmod.lockmarks) {
- /* marks in the tag stack */
+ // marks in the tag stack
for (i = 0; i < win->w_tagstacklen; i++) {
if (win->w_tagstack[i].fmark.fnum == fnum) {
one_adjust_nodel(&(win->w_tagstack[i].fmark.mark.lnum));
@@ -1042,7 +1076,7 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2,
}
}
- /* the displayed Visual area */
+ // the displayed Visual area
if (win->w_old_cursor_lnum != 0) {
one_adjust_nodel(&(win->w_old_cursor_lnum));
one_adjust_nodel(&(win->w_old_visual_lnum));
@@ -1052,13 +1086,13 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2,
* other than the current window */
if (win != curwin) {
if (win->w_topline >= line1 && win->w_topline <= line2) {
- if (amount == MAXLNUM) { /* topline is deleted */
+ if (amount == MAXLNUM) { // topline is deleted
if (line1 <= 1) {
win->w_topline = 1;
} else {
win->w_topline = line1 - 1;
}
- } else { /* keep topline on the same line */
+ } else { // keep topline on the same line
win->w_topline += amount;
}
win->w_topfill = 0;
@@ -1067,14 +1101,14 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2,
win->w_topfill = 0;
}
if (win->w_cursor.lnum >= line1 && win->w_cursor.lnum <= line2) {
- if (amount == MAXLNUM) { /* line with cursor is deleted */
+ if (amount == MAXLNUM) { // line with cursor is deleted
if (line1 <= 1) {
win->w_cursor.lnum = 1;
} else {
win->w_cursor.lnum = line1 - 1;
}
win->w_cursor.col = 0;
- } else { /* keep cursor on the same line */
+ } else { // keep cursor on the same line
win->w_cursor.lnum += amount;
}
} else if (amount_after && win->w_cursor.lnum > line2) {
@@ -1088,11 +1122,11 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2,
}
}
- /* adjust diffs */
+ // adjust diffs
diff_mark_adjust(line1, line2, amount, amount_after);
}
-/* This code is used often, needs to be fast. */
+// This code is used often, needs to be fast.
#define col_adjust(pp) \
{ \
posp = pp; \
@@ -1115,56 +1149,58 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2,
// position.
// "spaces_removed" is the number of spaces that were removed, matters when the
// cursor is inside them.
-void mark_col_adjust(
- linenr_T lnum, colnr_T mincol, long lnum_amount, long col_amount,
- int spaces_removed)
+void mark_col_adjust(linenr_T lnum, colnr_T mincol, long lnum_amount, long col_amount,
+ int spaces_removed)
{
int i;
int fnum = curbuf->b_fnum;
- pos_T *posp;
+ pos_T *posp;
- if ((col_amount == 0L && lnum_amount == 0L) || cmdmod.lockmarks)
- return; /* nothing to do */
-
- /* named marks, lower case and upper case */
+ if ((col_amount == 0L && lnum_amount == 0L) || cmdmod.lockmarks) {
+ return; // nothing to do
+ }
+ // named marks, lower case and upper case
for (i = 0; i < NMARKS; i++) {
col_adjust(&(curbuf->b_namedm[i].mark));
- if (namedfm[i].fmark.fnum == fnum)
+ if (namedfm[i].fmark.fnum == fnum) {
col_adjust(&(namedfm[i].fmark.mark));
+ }
}
for (i = NMARKS; i < NGLOBALMARKS; i++) {
- if (namedfm[i].fmark.fnum == fnum)
+ if (namedfm[i].fmark.fnum == fnum) {
col_adjust(&(namedfm[i].fmark.mark));
+ }
}
- /* last Insert position */
+ // last Insert position
col_adjust(&(curbuf->b_last_insert.mark));
- /* last change position */
+ // last change position
col_adjust(&(curbuf->b_last_change.mark));
- /* list of change positions */
- for (i = 0; i < curbuf->b_changelistlen; ++i)
+ // list of change positions
+ for (i = 0; i < curbuf->b_changelistlen; ++i) {
col_adjust(&(curbuf->b_changelist[i].mark));
+ }
- /* Visual area */
+ // Visual area
col_adjust(&(curbuf->b_visual.vi_start));
col_adjust(&(curbuf->b_visual.vi_end));
- /* previous context mark */
+ // previous context mark
col_adjust(&(curwin->w_pcmark));
- /* previous pcmark */
+ // previous pcmark
col_adjust(&(curwin->w_prev_pcmark));
- /* saved cursor for formatting */
+ // saved cursor for formatting
col_adjust(&saved_cursor);
/*
* Adjust items in all windows related to the current buffer.
*/
FOR_ALL_WINDOWS_IN_TAB(win, curtab) {
- /* marks in the jumplist */
+ // marks in the jumplist
for (i = 0; i < win->w_jumplistlen; ++i) {
if (win->w_jumplist[i].fmark.fnum == fnum) {
col_adjust(&(win->w_jumplist[i].fmark.mark));
@@ -1172,14 +1208,14 @@ void mark_col_adjust(
}
if (win->w_buffer == curbuf) {
- /* marks in the tag stack */
+ // marks in the tag stack
for (i = 0; i < win->w_tagstacklen; i++) {
if (win->w_tagstack[i].fmark.fnum == fnum) {
col_adjust(&(win->w_tagstack[i].fmark.mark));
}
}
- /* cursor position for other windows with the same buffer */
+ // cursor position for other windows with the same buffer
if (win != curwin) {
col_adjust(&win->w_cursor);
}
@@ -1269,8 +1305,9 @@ void copy_jumplist(win_T *from, win_T *to)
for (i = 0; i < from->w_jumplistlen; ++i) {
to->w_jumplist[i] = from->w_jumplist[i];
- if (from->w_jumplist[i].fname != NULL)
+ if (from->w_jumplist[i].fname != NULL) {
to->w_jumplist[i].fname = vim_strsave(from->w_jumplist[i].fname);
+ }
}
to->w_jumplistlen = from->w_jumplistlen;
to->w_jumplistidx = from->w_jumplistidx;
@@ -1287,18 +1324,17 @@ void copy_jumplist(win_T *from, win_T *to)
///
/// @return Pointer that needs to be passed to next `mark_jumplist_iter` call or
/// NULL if iteration is over.
-const void *mark_jumplist_iter(const void *const iter, const win_T *const win,
- xfmark_T *const fm)
+const void *mark_jumplist_iter(const void *const iter, const win_T *const win, xfmark_T *const fm)
FUNC_ATTR_NONNULL_ARG(2, 3) FUNC_ATTR_WARN_UNUSED_RESULT
{
if (iter == NULL && win->w_jumplistlen == 0) {
- *fm = (xfmark_T) {{{0, 0, 0}, 0, 0, NULL}, NULL};
+ *fm = (xfmark_T) { { { 0, 0, 0 }, 0, 0, NULL }, NULL };
return NULL;
}
const xfmark_T *const iter_mark =
- (iter == NULL
+ (iter == NULL
? &(win->w_jumplist[0])
- : (const xfmark_T *const) iter);
+ : (const xfmark_T *const)iter);
*fm = *iter_mark;
if (iter_mark == &(win->w_jumplist[win->w_jumplistlen - 1])) {
return NULL;
@@ -1318,30 +1354,29 @@ const void *mark_jumplist_iter(const void *const iter, const win_T *const win,
///
/// @return Pointer that needs to be passed to next `mark_global_iter` call or
/// NULL if iteration is over.
-const void *mark_global_iter(const void *const iter, char *const name,
- xfmark_T *const fm)
+const void *mark_global_iter(const void *const iter, char *const name, xfmark_T *const fm)
FUNC_ATTR_NONNULL_ARG(2, 3) FUNC_ATTR_WARN_UNUSED_RESULT
{
*name = NUL;
const xfmark_T *iter_mark = (iter == NULL
? &(namedfm[0])
- : (const xfmark_T *const) iter);
- while ((size_t) (iter_mark - &(namedfm[0])) < ARRAY_SIZE(namedfm)
+ : (const xfmark_T *const)iter);
+ while ((size_t)(iter_mark - &(namedfm[0])) < ARRAY_SIZE(namedfm)
&& !iter_mark->fmark.mark.lnum) {
iter_mark++;
}
- if ((size_t) (iter_mark - &(namedfm[0])) == ARRAY_SIZE(namedfm)
+ if ((size_t)(iter_mark - &(namedfm[0])) == ARRAY_SIZE(namedfm)
|| !iter_mark->fmark.mark.lnum) {
return NULL;
}
- size_t iter_off = (size_t) (iter_mark - &(namedfm[0]));
- *name = (char) (iter_off < NMARKS
- ? 'A' + (char) iter_off
- : '0' + (char) (iter_off - NMARKS));
+ size_t iter_off = (size_t)(iter_mark - &(namedfm[0]));
+ *name = (char)(iter_off < NMARKS
+ ? 'A' + (char)iter_off
+ : '0' + (char)(iter_off - NMARKS));
*fm = *iter_mark;
- while ((size_t) (++iter_mark - &(namedfm[0])) < ARRAY_SIZE(namedfm)) {
+ while ((size_t)(++iter_mark - &(namedfm[0])) < ARRAY_SIZE(namedfm)) {
if (iter_mark->fmark.mark.lnum) {
- return (const void *) iter_mark;
+ return (const void *)iter_mark;
}
}
return NULL;
@@ -1358,34 +1393,27 @@ const void *mark_global_iter(const void *const iter, char *const name,
/// behaviour is undefined.
///
/// @return Pointer to the next mark or NULL.
-static inline const fmark_T *next_buffer_mark(const buf_T *const buf,
- char *const mark_name)
+static inline const fmark_T *next_buffer_mark(const buf_T *const buf, char *const mark_name)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
switch (*mark_name) {
- case NUL: {
- *mark_name = '"';
- return &(buf->b_last_cursor);
- }
- case '"': {
- *mark_name = '^';
- return &(buf->b_last_insert);
- }
- case '^': {
- *mark_name = '.';
- return &(buf->b_last_change);
- }
- case '.': {
- *mark_name = 'a';
- return &(buf->b_namedm[0]);
- }
- case 'z': {
- return NULL;
- }
- default: {
- (*mark_name)++;
- return &(buf->b_namedm[*mark_name - 'a']);
- }
+ case NUL:
+ *mark_name = '"';
+ return &(buf->b_last_cursor);
+ case '"':
+ *mark_name = '^';
+ return &(buf->b_last_insert);
+ case '^':
+ *mark_name = '.';
+ return &(buf->b_last_change);
+ case '.':
+ *mark_name = 'a';
+ return &(buf->b_namedm[0]);
+ case 'z':
+ return NULL;
+ default:
+ (*mark_name)++;
+ return &(buf->b_namedm[*mark_name - 'a']);
}
}
@@ -1401,12 +1429,12 @@ static inline const fmark_T *next_buffer_mark(const buf_T *const buf,
///
/// @return Pointer that needs to be passed to next `mark_buffer_iter` call or
/// NULL if iteration is over.
-const void *mark_buffer_iter(const void *const iter, const buf_T *const buf,
- char *const name, fmark_T *const fm)
+const void *mark_buffer_iter(const void *const iter, const buf_T *const buf, char *const name,
+ fmark_T *const fm)
FUNC_ATTR_NONNULL_ARG(2, 3, 4) FUNC_ATTR_WARN_UNUSED_RESULT
{
*name = NUL;
- char mark_name = (char) (iter == NULL
+ char mark_name = (char)(iter == NULL
? NUL
: (iter == &(buf->b_last_cursor)
? '"'
@@ -1414,8 +1442,8 @@ const void *mark_buffer_iter(const void *const iter, const buf_T *const buf,
? '^'
: (iter == &(buf->b_last_change)
? '.'
- : 'a' + (char) ((const fmark_T *)iter
- - &(buf->b_namedm[0]))))));
+ : 'a' + (char)((const fmark_T *)iter
+ - &(buf->b_namedm[0]))))));
const fmark_T *iter_mark = next_buffer_mark(buf, &mark_name);
while (iter_mark != NULL && iter_mark->mark.lnum == 0) {
iter_mark = next_buffer_mark(buf, &mark_name);
@@ -1423,14 +1451,14 @@ const void *mark_buffer_iter(const void *const iter, const buf_T *const buf,
if (iter_mark == NULL) {
return NULL;
}
- size_t iter_off = (size_t) (iter_mark - &(buf->b_namedm[0]));
+ size_t iter_off = (size_t)(iter_mark - &(buf->b_namedm[0]));
if (mark_name) {
*name = mark_name;
} else {
- *name = (char) ('a' + (char) iter_off);
+ *name = (char)('a' + (char)iter_off);
}
*fm = *iter_mark;
- return (const void *) iter_mark;
+ return (const void *)iter_mark;
}
/// Set global mark
@@ -1467,8 +1495,7 @@ bool mark_set_global(const char name, const xfmark_T fm, const bool update)
/// later then existing one.
///
/// @return true on success, false on failure.
-bool mark_set_local(const char name, buf_T *const buf,
- const fmark_T fm, const bool update)
+bool mark_set_local(const char name, buf_T *const buf, const fmark_T fm, const bool update)
FUNC_ATTR_NONNULL_ALL
{
fmark_T *fm_tgt = NULL;
@@ -1556,8 +1583,7 @@ void mark_mb_adjustpos(buf_T *buf, pos_T *lp)
// Add information about mark 'mname' to list 'l'
-static int add_mark(list_T *l, const char *mname, const pos_T *pos, int bufnr,
- const char *fname)
+static int add_mark(list_T *l, const char *mname, const pos_T *pos, int bufnr, const char *fname)
FUNC_ATTR_NONNULL_ARG(1, 2, 3)
{
if (pos->lnum <= 0) {
diff --git a/src/nvim/marktree.c b/src/nvim/marktree.c
index feb54eae4a..ebe4478bc8 100644
--- a/src/nvim/marktree.c
+++ b/src/nvim/marktree.c
@@ -49,9 +49,9 @@
#include <assert.h>
-#include "nvim/marktree.h"
-#include "nvim/lib/kvec.h"
#include "nvim/garray.h"
+#include "nvim/lib/kvec.h"
+#include "nvim/marktree.h"
#define T MT_BRANCH_FACTOR
#define ILEN (sizeof(mtnode_t)+(2 * T) * sizeof(void *))
@@ -137,7 +137,9 @@ static inline int marktree_getp_aux(const mtnode_t *x, mtkey_t k, int *r)
end = mid;
}
}
- if (begin == x->n) { *rr = 1; return x->n - 1; }
+ if (begin == x->n) {
+ *rr = 1; return x->n - 1;
+ }
if ((*rr = key_cmp(k, x->key[begin])) < 0) {
begin--;
}
@@ -232,9 +234,8 @@ uint64_t marktree_put(MarkTree *b, int row, int col, bool right_gravity)
return id;
}
-uint64_t marktree_put_pair(MarkTree *b,
- int start_row, int start_col, bool start_right,
- int end_row, int end_col, bool end_right)
+uint64_t marktree_put_pair(MarkTree *b, int start_row, int start_col, bool start_right, int end_row,
+ int end_col, bool end_right)
{
uint64_t id = (b->next_id+=ID_INCR)|PAIRED;
uint64_t start_id = id|(start_right?RIGHT_GRAVITY:0);
@@ -250,7 +251,6 @@ void marktree_put_key(MarkTree *b, int row, int col, uint64_t id)
if (!b->root) {
b->root = (mtnode_t *)xcalloc(1, ILEN);
- b->id2node = pmap_new(uint64_t)();
b->n_nodes++;
}
mtnode_t *r, *s;
@@ -547,9 +547,9 @@ void marktree_clear(MarkTree *b)
marktree_free_node(b->root);
b->root = NULL;
}
- if (b->id2node) {
- pmap_free(uint64_t)(b->id2node);
- b->id2node = NULL;
+ if (b->id2node->table.keys) {
+ pmap_destroy(uint64_t)(b->id2node);
+ pmap_init(uint64_t, b->id2node);
}
b->n_keys = 0;
b->n_nodes = 0;
@@ -595,8 +595,8 @@ bool marktree_itr_get(MarkTree *b, int row, int col, MarkTreeIter *itr)
itr, false, false, NULL);
}
-bool marktree_itr_get_ext(MarkTree *b, mtpos_t p, MarkTreeIter *itr,
- bool last, bool gravity, mtpos_t *oldbase)
+bool marktree_itr_get_ext(MarkTree *b, mtpos_t p, MarkTreeIter *itr, bool last, bool gravity,
+ mtpos_t *oldbase)
{
mtkey_t k = { .pos = p, .id = gravity ? RIGHT_GRAVITY : 0 };
if (last && !gravity) {
@@ -696,8 +696,7 @@ bool marktree_itr_next(MarkTree *b, MarkTreeIter *itr)
return marktree_itr_next_skip(b, itr, false, NULL);
}
-static bool marktree_itr_next_skip(MarkTree *b, MarkTreeIter *itr, bool skip,
- mtpos_t oldbase[])
+static bool marktree_itr_next_skip(MarkTree *b, MarkTreeIter *itr, bool skip, mtpos_t oldbase[])
{
if (!itr->node) {
return false;
@@ -820,8 +819,8 @@ mtmark_t marktree_itr_current(MarkTreeIter *itr)
mtpos_t pos = marktree_itr_pos(itr);
mtmark_t mark = { .row = pos.row,
.col = pos.col,
- .id = ANTIGRAVITY(keyid),
- .right_gravity = keyid & RIGHT_GRAVITY };
+ .id = ANTIGRAVITY(keyid),
+ .right_gravity = keyid & RIGHT_GRAVITY };
return mark;
}
return (mtmark_t){ -1, -1, 0, false };
@@ -834,10 +833,8 @@ static void swap_id(uint64_t *id1, uint64_t *id2)
*id2 = temp;
}
-bool marktree_splice(MarkTree *b,
- int start_line, int start_col,
- int old_extent_line, int old_extent_col,
- int new_extent_line, int new_extent_col)
+bool marktree_splice(MarkTree *b, int start_line, int start_col, int old_extent_line,
+ int old_extent_col, int new_extent_line, int new_extent_col)
{
mtpos_t start = { start_line, start_col };
mtpos_t old_extent = { (int)old_extent_line, old_extent_col };
@@ -904,7 +901,8 @@ continue_same_node:
refkey(b, itr->node, itr->i);
refkey(b, enditr->node, enditr->i);
} else {
- past_right = true; // NOLINT
+ past_right = true; // NOLINT
+ (void)past_right;
break;
}
}
@@ -994,10 +992,8 @@ past_continue_same_node:
return moved;
}
-void marktree_move_region(MarkTree *b,
- int start_row, colnr_T start_col,
- int extent_row, colnr_T extent_col,
- int new_row, colnr_T new_col)
+void marktree_move_region(MarkTree *b, int start_row, colnr_T start_col, int extent_row,
+ colnr_T extent_col, int new_row, colnr_T new_col)
{
mtpos_t start = { start_row, start_col }, size = { extent_row, extent_col };
mtpos_t end = size;
@@ -1114,8 +1110,7 @@ void marktree_check(MarkTree *b)
}
#ifndef NDEBUG
-static size_t check_node(MarkTree *b, mtnode_t *x,
- mtpos_t *last, bool *last_right)
+static size_t check_node(MarkTree *b, mtnode_t *x, mtpos_t *last, bool *last_right)
{
assert(x->n <= 2 * T - 1);
// TODO(bfredl): too strict if checking "in repair" post-delete tree.
diff --git a/src/nvim/marktree.h b/src/nvim/marktree.h
index 8a1c564a6d..7af23765c3 100644
--- a/src/nvim/marktree.h
+++ b/src/nvim/marktree.h
@@ -49,7 +49,7 @@ struct mtnode_s {
int32_t n;
int32_t level;
// TODO(bfredl): we could consider having a only-sometimes-valid
- // index into parent for faster "chached" lookup.
+ // index into parent for faster "cached" lookup.
mtnode_t *parent;
mtkey_t key[2 * MT_BRANCH_FACTOR - 1];
mtnode_t *ptr[];
@@ -63,7 +63,7 @@ typedef struct {
uint64_t next_id;
// TODO(bfredl): the pointer to node could be part of the larger
// Map(uint64_t, ExtmarkItem) essentially;
- PMap(uint64_t) *id2node;
+ PMap(uint64_t) id2node[1];
} MarkTree;
diff --git a/src/nvim/math.c b/src/nvim/math.c
index b51f335ed7..791f1f9373 100644
--- a/src/nvim/math.c
+++ b/src/nvim/math.c
@@ -3,40 +3,38 @@
#include <math.h>
+#include <stdint.h>
+#include <string.h>
+
#include "nvim/math.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "math.c.generated.h"
#endif
-#if defined(__clang__) && __clang__ == 1 && __clang_major__ >= 6
-// Workaround glibc + Clang 6+ bug. #8274
-// https://bugzilla.redhat.com/show_bug.cgi?id=1472437
-# pragma clang diagnostic push
-# pragma clang diagnostic ignored "-Wconversion"
-#endif
int xfpclassify(double d)
{
-#if defined(__MINGW32__)
- // Workaround mingw warning. #7863
- return __fpclassify(d);
-#else
- return fpclassify(d);
-#endif
+ uint64_t m;
+ int e;
+
+ memcpy(&m, &d, sizeof(m));
+ e = 0x7ff & (m >> 52);
+ m = 0xfffffffffffffULL & m;
+
+ switch (e) {
+ default:
+ return FP_NORMAL;
+ case 0x000:
+ return m ? FP_SUBNORMAL : FP_ZERO;
+ case 0x7ff:
+ return m ? FP_NAN : FP_INFINITE;
+ }
}
int xisinf(double d)
{
- return isinf(d);
+ return FP_INFINITE == xfpclassify(d);
}
int xisnan(double d)
{
-#if defined(__MINGW32__)
- // Workaround mingw warning. #7863
- return _isnan(d);
-#else
- return isnan(d);
-#endif
+ return FP_NAN == xfpclassify(d);
}
-#if defined(__clang__) && __clang__ == 1 && __clang_major__ >= 6
-# pragma clang diagnostic pop
-#endif
diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c
index 73e3ba53a5..253ddfc253 100644
--- a/src/nvim/mbyte.c
+++ b/src/nvim/mbyte.c
@@ -31,30 +31,30 @@
#include <wchar.h>
#include <wctype.h>
-#include "nvim/vim.h"
#include "nvim/ascii.h"
+#include "nvim/vim.h"
#ifdef HAVE_LOCALE_H
# include <locale.h>
#endif
-#include "nvim/eval.h"
-#include "nvim/path.h"
-#include "nvim/iconv.h"
-#include "nvim/mbyte.h"
+#include "nvim/arabic.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
+#include "nvim/eval.h"
#include "nvim/fileio.h"
#include "nvim/func_attr.h"
+#include "nvim/iconv.h"
+#include "nvim/mark.h"
+#include "nvim/mbyte.h"
#include "nvim/memline.h"
+#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/memory.h"
#include "nvim/option.h"
+#include "nvim/os/os.h"
+#include "nvim/path.h"
#include "nvim/screen.h"
#include "nvim/spell.h"
#include "nvim/strings.h"
-#include "nvim/os/os.h"
-#include "nvim/arabic.h"
-#include "nvim/mark.h"
typedef struct {
int rangeStart;
@@ -70,12 +70,10 @@ struct interval {
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "mbyte.c.generated.h"
+
# include "unicode_tables.generated.h"
#endif
-char_u e_loadlib[] = "E370: Could not load library %s";
-char_u e_loadfunc[] = "E448: Could not load library function %s";
-
// To speed up BYTELEN(); keep a lookup table to quickly get the length in
// bytes of a UTF-8 character from the first byte of a UTF-8 string. Bytes
// which are illegal when used as the first byte have a 1. The NUL byte has
@@ -130,131 +128,131 @@ static struct
enc_canon_table[] =
{
#define IDX_LATIN_1 0
- {"latin1", ENC_8BIT + ENC_LATIN1, 1252},
+ { "latin1", ENC_8BIT + ENC_LATIN1, 1252 },
#define IDX_ISO_2 1
- {"iso-8859-2", ENC_8BIT, 0},
+ { "iso-8859-2", ENC_8BIT, 0 },
#define IDX_ISO_3 2
- {"iso-8859-3", ENC_8BIT, 0},
+ { "iso-8859-3", ENC_8BIT, 0 },
#define IDX_ISO_4 3
- {"iso-8859-4", ENC_8BIT, 0},
+ { "iso-8859-4", ENC_8BIT, 0 },
#define IDX_ISO_5 4
- {"iso-8859-5", ENC_8BIT, 0},
+ { "iso-8859-5", ENC_8BIT, 0 },
#define IDX_ISO_6 5
- {"iso-8859-6", ENC_8BIT, 0},
+ { "iso-8859-6", ENC_8BIT, 0 },
#define IDX_ISO_7 6
- {"iso-8859-7", ENC_8BIT, 0},
+ { "iso-8859-7", ENC_8BIT, 0 },
#define IDX_ISO_8 7
- {"iso-8859-8", ENC_8BIT, 0},
+ { "iso-8859-8", ENC_8BIT, 0 },
#define IDX_ISO_9 8
- {"iso-8859-9", ENC_8BIT, 0},
+ { "iso-8859-9", ENC_8BIT, 0 },
#define IDX_ISO_10 9
- {"iso-8859-10", ENC_8BIT, 0},
+ { "iso-8859-10", ENC_8BIT, 0 },
#define IDX_ISO_11 10
- {"iso-8859-11", ENC_8BIT, 0},
+ { "iso-8859-11", ENC_8BIT, 0 },
#define IDX_ISO_13 11
- {"iso-8859-13", ENC_8BIT, 0},
+ { "iso-8859-13", ENC_8BIT, 0 },
#define IDX_ISO_14 12
- {"iso-8859-14", ENC_8BIT, 0},
+ { "iso-8859-14", ENC_8BIT, 0 },
#define IDX_ISO_15 13
- {"iso-8859-15", ENC_8BIT + ENC_LATIN9, 0},
+ { "iso-8859-15", ENC_8BIT + ENC_LATIN9, 0 },
#define IDX_KOI8_R 14
- {"koi8-r", ENC_8BIT, 0},
+ { "koi8-r", ENC_8BIT, 0 },
#define IDX_KOI8_U 15
- {"koi8-u", ENC_8BIT, 0},
+ { "koi8-u", ENC_8BIT, 0 },
#define IDX_UTF8 16
- {"utf-8", ENC_UNICODE, 0},
+ { "utf-8", ENC_UNICODE, 0 },
#define IDX_UCS2 17
- {"ucs-2", ENC_UNICODE + ENC_ENDIAN_B + ENC_2BYTE, 0},
+ { "ucs-2", ENC_UNICODE + ENC_ENDIAN_B + ENC_2BYTE, 0 },
#define IDX_UCS2LE 18
- {"ucs-2le", ENC_UNICODE + ENC_ENDIAN_L + ENC_2BYTE, 0},
+ { "ucs-2le", ENC_UNICODE + ENC_ENDIAN_L + ENC_2BYTE, 0 },
#define IDX_UTF16 19
- {"utf-16", ENC_UNICODE + ENC_ENDIAN_B + ENC_2WORD, 0},
+ { "utf-16", ENC_UNICODE + ENC_ENDIAN_B + ENC_2WORD, 0 },
#define IDX_UTF16LE 20
- {"utf-16le", ENC_UNICODE + ENC_ENDIAN_L + ENC_2WORD, 0},
+ { "utf-16le", ENC_UNICODE + ENC_ENDIAN_L + ENC_2WORD, 0 },
#define IDX_UCS4 21
- {"ucs-4", ENC_UNICODE + ENC_ENDIAN_B + ENC_4BYTE, 0},
+ { "ucs-4", ENC_UNICODE + ENC_ENDIAN_B + ENC_4BYTE, 0 },
#define IDX_UCS4LE 22
- {"ucs-4le", ENC_UNICODE + ENC_ENDIAN_L + ENC_4BYTE, 0},
+ { "ucs-4le", ENC_UNICODE + ENC_ENDIAN_L + ENC_4BYTE, 0 },
- /* For debugging DBCS encoding on Unix. */
+ // For debugging DBCS encoding on Unix.
#define IDX_DEBUG 23
- {"debug", ENC_DBCS, DBCS_DEBUG},
+ { "debug", ENC_DBCS, DBCS_DEBUG },
#define IDX_EUC_JP 24
- {"euc-jp", ENC_DBCS, DBCS_JPNU},
+ { "euc-jp", ENC_DBCS, DBCS_JPNU },
#define IDX_SJIS 25
- {"sjis", ENC_DBCS, DBCS_JPN},
+ { "sjis", ENC_DBCS, DBCS_JPN },
#define IDX_EUC_KR 26
- {"euc-kr", ENC_DBCS, DBCS_KORU},
+ { "euc-kr", ENC_DBCS, DBCS_KORU },
#define IDX_EUC_CN 27
- {"euc-cn", ENC_DBCS, DBCS_CHSU},
+ { "euc-cn", ENC_DBCS, DBCS_CHSU },
#define IDX_EUC_TW 28
- {"euc-tw", ENC_DBCS, DBCS_CHTU},
+ { "euc-tw", ENC_DBCS, DBCS_CHTU },
#define IDX_BIG5 29
- {"big5", ENC_DBCS, DBCS_CHT},
+ { "big5", ENC_DBCS, DBCS_CHT },
/* MS-DOS and MS-Windows codepages are included here, so that they can be
* used on Unix too. Most of them are similar to ISO-8859 encodings, but
* not exactly the same. */
#define IDX_CP437 30
- {"cp437", ENC_8BIT, 437}, /* like iso-8859-1 */
+ { "cp437", ENC_8BIT, 437 }, // like iso-8859-1
#define IDX_CP737 31
- {"cp737", ENC_8BIT, 737}, /* like iso-8859-7 */
+ { "cp737", ENC_8BIT, 737 }, // like iso-8859-7
#define IDX_CP775 32
- {"cp775", ENC_8BIT, 775}, /* Baltic */
+ { "cp775", ENC_8BIT, 775 }, // Baltic
#define IDX_CP850 33
- {"cp850", ENC_8BIT, 850}, /* like iso-8859-4 */
+ { "cp850", ENC_8BIT, 850 }, // like iso-8859-4
#define IDX_CP852 34
- {"cp852", ENC_8BIT, 852}, /* like iso-8859-1 */
+ { "cp852", ENC_8BIT, 852 }, // like iso-8859-1
#define IDX_CP855 35
- {"cp855", ENC_8BIT, 855}, /* like iso-8859-2 */
+ { "cp855", ENC_8BIT, 855 }, // like iso-8859-2
#define IDX_CP857 36
- {"cp857", ENC_8BIT, 857}, /* like iso-8859-5 */
+ { "cp857", ENC_8BIT, 857 }, // like iso-8859-5
#define IDX_CP860 37
- {"cp860", ENC_8BIT, 860}, /* like iso-8859-9 */
+ { "cp860", ENC_8BIT, 860 }, // like iso-8859-9
#define IDX_CP861 38
- {"cp861", ENC_8BIT, 861}, /* like iso-8859-1 */
+ { "cp861", ENC_8BIT, 861 }, // like iso-8859-1
#define IDX_CP862 39
- {"cp862", ENC_8BIT, 862}, /* like iso-8859-1 */
+ { "cp862", ENC_8BIT, 862 }, // like iso-8859-1
#define IDX_CP863 40
- {"cp863", ENC_8BIT, 863}, /* like iso-8859-8 */
+ { "cp863", ENC_8BIT, 863 }, // like iso-8859-8
#define IDX_CP865 41
- {"cp865", ENC_8BIT, 865}, /* like iso-8859-1 */
+ { "cp865", ENC_8BIT, 865 }, // like iso-8859-1
#define IDX_CP866 42
- {"cp866", ENC_8BIT, 866}, /* like iso-8859-5 */
+ { "cp866", ENC_8BIT, 866 }, // like iso-8859-5
#define IDX_CP869 43
- {"cp869", ENC_8BIT, 869}, /* like iso-8859-7 */
+ { "cp869", ENC_8BIT, 869 }, // like iso-8859-7
#define IDX_CP874 44
- {"cp874", ENC_8BIT, 874}, /* Thai */
+ { "cp874", ENC_8BIT, 874 }, // Thai
#define IDX_CP932 45
- {"cp932", ENC_DBCS, DBCS_JPN},
+ { "cp932", ENC_DBCS, DBCS_JPN },
#define IDX_CP936 46
- {"cp936", ENC_DBCS, DBCS_CHS},
+ { "cp936", ENC_DBCS, DBCS_CHS },
#define IDX_CP949 47
- {"cp949", ENC_DBCS, DBCS_KOR},
+ { "cp949", ENC_DBCS, DBCS_KOR },
#define IDX_CP950 48
- {"cp950", ENC_DBCS, DBCS_CHT},
+ { "cp950", ENC_DBCS, DBCS_CHT },
#define IDX_CP1250 49
- {"cp1250", ENC_8BIT, 1250}, /* Czech, Polish, etc. */
+ { "cp1250", ENC_8BIT, 1250 }, // Czech, Polish, etc.
#define IDX_CP1251 50
- {"cp1251", ENC_8BIT, 1251}, /* Cyrillic */
- /* cp1252 is considered to be equal to latin1 */
+ { "cp1251", ENC_8BIT, 1251 }, // Cyrillic
+ // cp1252 is considered to be equal to latin1
#define IDX_CP1253 51
- {"cp1253", ENC_8BIT, 1253}, /* Greek */
+ { "cp1253", ENC_8BIT, 1253 }, // Greek
#define IDX_CP1254 52
- {"cp1254", ENC_8BIT, 1254}, /* Turkish */
+ { "cp1254", ENC_8BIT, 1254 }, // Turkish
#define IDX_CP1255 53
- {"cp1255", ENC_8BIT, 1255}, /* Hebrew */
+ { "cp1255", ENC_8BIT, 1255 }, // Hebrew
#define IDX_CP1256 54
- {"cp1256", ENC_8BIT, 1256}, /* Arabic */
+ { "cp1256", ENC_8BIT, 1256 }, // Arabic
#define IDX_CP1257 55
- {"cp1257", ENC_8BIT, 1257}, /* Baltic */
+ { "cp1257", ENC_8BIT, 1257 }, // Baltic
#define IDX_CP1258 56
- {"cp1258", ENC_8BIT, 1258}, /* Vietnamese */
+ { "cp1258", ENC_8BIT, 1258 }, // Vietnamese
#define IDX_MACROMAN 57
- {"macroman", ENC_8BIT + ENC_MACROMAN, 0}, /* Mac OS */
+ { "macroman", ENC_8BIT + ENC_MACROMAN, 0 }, // Mac OS
#define IDX_HPROMAN8 58
- {"hp-roman8", ENC_8BIT, 0}, /* HP Roman8 */
+ { "hp-roman8", ENC_8BIT, 0 }, // HP Roman8
#define IDX_COUNT 59
};
@@ -339,9 +337,11 @@ static int enc_canon_search(const char_u *name)
{
int i;
- for (i = 0; i < IDX_COUNT; ++i)
- if (STRCMP(name, enc_canon_table[i].name) == 0)
+ for (i = 0; i < IDX_COUNT; ++i) {
+ if (STRCMP(name, enc_canon_table[i].name) == 0) {
return i;
+ }
+ }
return -1;
}
@@ -356,12 +356,13 @@ int enc_canon_props(const char_u *name)
int i;
i = enc_canon_search(name);
- if (i >= 0)
+ if (i >= 0) {
return enc_canon_table[i].prop;
- if (STRNCMP(name, "2byte-", 6) == 0)
+ } else if (STRNCMP(name, "2byte-", 6) == 0) {
return ENC_DBCS;
- if (STRNCMP(name, "8bit-", 5) == 0 || STRNCMP(name, "iso-8859-", 9) == 0)
+ } else if (STRNCMP(name, "8bit-", 5) == 0 || STRNCMP(name, "iso-8859-", 9) == 0) {
return ENC_8BIT;
+ }
return 0;
}
@@ -439,21 +440,23 @@ static bool intable(const struct interval *table, size_t n_items, int c)
{
int mid, bot, top;
- /* first quick check for Latin1 etc. characters */
- if (c < table[0].first)
+ // first quick check for Latin1 etc. characters
+ if (c < table[0].first) {
return false;
+ }
- /* binary search in table */
+ // binary search in table
bot = 0;
top = (int)(n_items - 1);
while (top >= bot) {
mid = (bot + top) / 2;
- if (table[mid].last < c)
+ if (table[mid].last < c) {
bot = mid + 1;
- else if (table[mid].first > c)
+ } else if (table[mid].first > c) {
top = mid - 1;
- else
+ } else {
return true;
+ }
}
return false;
}
@@ -515,12 +518,14 @@ int utf_ptr2cells(const char_u *p)
// Need to convert to a character number.
if (*p >= 0x80) {
c = utf_ptr2char(p);
- /* An illegal byte is displayed as <xx>. */
- if (utf_ptr2len(p) == 1 || c == NUL)
+ // An illegal byte is displayed as <xx>.
+ if (utf_ptr2len(p) == 1 || c == NUL) {
return 4;
- /* If the char is ASCII it must be an overlong sequence. */
- if (c < 0x80)
+ }
+ // If the char is ASCII it must be an overlong sequence.
+ if (c < 0x80) {
return char2cells(c);
+ }
return utf_char2cells(c);
}
return 1;
@@ -532,17 +537,20 @@ int utf_ptr2cells_len(const char_u *p, int size)
{
int c;
- /* Need to convert to a wide character. */
+ // Need to convert to a wide character.
if (size > 0 && *p >= 0x80) {
- if (utf_ptr2len_len(p, size) < utf8len_tab[*p])
- return 1; /* truncated */
+ if (utf_ptr2len_len(p, size) < utf8len_tab[*p]) {
+ return 1; // truncated
+ }
c = utf_ptr2char(p);
- /* An illegal byte is displayed as <xx>. */
- if (utf_ptr2len(p) == 1 || c == NUL)
+ // An illegal byte is displayed as <xx>.
+ if (utf_ptr2len(p) == 1 || c == NUL) {
return 4;
- /* If the char is ASCII it must be an overlong sequence. */
- if (c < 0x80)
+ }
+ // If the char is ASCII it must be an overlong sequence.
+ if (c < 0x80) {
return char2cells(c);
+ }
return utf_char2cells(c);
}
return 1;
@@ -654,13 +662,14 @@ static int utf_safe_read_char_adv(const char_u **s, size_t *n)
{
int c;
- if (*n == 0) /* end of buffer */
+ if (*n == 0) { // end of buffer
return 0;
+ }
uint8_t k = utf8len_tab_zero[**s];
if (k == 1) {
- /* ASCII character or NUL */
+ // ASCII character or NUL
(*n)--;
return *(*s)++;
}
@@ -677,14 +686,14 @@ static int utf_safe_read_char_adv(const char_u **s, size_t *n)
* U+00C3 (UTF-8: 0xC3 0x83), so need to check that special case too.
* It's safe even if n=1, else we would have k=2 > n. */
if (c != (int)(**s) || (c == 0xC3 && (*s)[1] == 0x83)) {
- /* byte sequence was successfully decoded */
+ // byte sequence was successfully decoded
*s += k;
*n -= k;
return c;
}
}
- /* byte sequence is incomplete or illegal */
+ // byte sequence is incomplete or illegal
return -1;
}
@@ -724,10 +733,12 @@ bool utf_composinglike(const char_u *p1, const char_u *p2)
int c2;
c2 = utf_ptr2char(p2);
- if (utf_iscomposing(c2))
+ if (utf_iscomposing(c2)) {
return true;
- if (!arabic_maycombine(c2))
+ }
+ if (!arabic_maycombine(c2)) {
return false;
+ }
return arabic_combine(utf_ptr2char(p1), c2);
}
@@ -749,23 +760,26 @@ int utfc_ptr2char(const char_u *p, int *pcc)
c = utf_ptr2char(p);
len = utf_ptr2len(p);
- /* Only accept a composing char when the first char isn't illegal. */
+ // Only accept a composing char when the first char isn't illegal.
if ((len > 1 || *p < 0x80)
&& p[len] >= 0x80
&& UTF_COMPOSINGLIKE(p, p + len)) {
cc = utf_ptr2char(p + len);
for (;; ) {
pcc[i++] = cc;
- if (i == MAX_MCO)
+ if (i == MAX_MCO) {
break;
+ }
len += utf_ptr2len(p + len);
- if (p[len] < 0x80 || !utf_iscomposing(cc = utf_ptr2char(p + len)))
+ if (p[len] < 0x80 || !utf_iscomposing(cc = utf_ptr2char(p + len))) {
break;
+ }
}
}
- if (i < MAX_MCO) /* last composing char must be 0 */
+ if (i < MAX_MCO) { // last composing char must be 0
pcc[i] = 0;
+ }
return c;
}
@@ -858,15 +872,19 @@ int utf_ptr2len_len(const char_u *p, int size)
int m;
len = utf8len_tab[*p];
- if (len == 1)
- return 1; /* NUL, ascii or illegal lead byte */
- if (len > size)
- m = size; /* incomplete byte sequence. */
- else
+ if (len == 1) {
+ return 1; // NUL, ascii or illegal lead byte
+ }
+ if (len > size) {
+ m = size; // incomplete byte sequence.
+ } else {
m = len;
- for (i = 1; i < m; ++i)
- if ((p[i] & 0xc0) != 0x80)
+ }
+ for (i = 1; i < m; ++i) {
+ if ((p[i] & 0xc0) != 0x80) {
return 1;
+ }
+ }
return len;
}
@@ -918,17 +936,20 @@ int utfc_ptr2len_len(const char_u *p, int size)
int len;
int prevlen;
- if (size < 1 || *p == NUL)
+ if (size < 1 || *p == NUL) {
return 0;
- if (p[0] < 0x80 && (size == 1 || p[1] < 0x80)) /* be quick for ASCII */
+ }
+ if (p[0] < 0x80 && (size == 1 || p[1] < 0x80)) { // be quick for ASCII
return 1;
+ }
- /* Skip over first UTF-8 char, stopping at a NUL byte. */
+ // Skip over first UTF-8 char, stopping at a NUL byte.
len = utf_ptr2len_len(p, size);
- /* Check for illegal byte and incomplete byte sequence. */
- if ((len == 1 && p[0] >= 0x80) || len > size)
+ // Check for illegal byte and incomplete byte sequence.
+ if ((len == 1 && p[0] >= 0x80) || len > size) {
return 1;
+ }
/*
* Check for composing characters. We can handle only the first six, but
@@ -938,21 +959,24 @@ int utfc_ptr2len_len(const char_u *p, int size)
while (len < size) {
int len_next_char;
- if (p[len] < 0x80)
+ if (p[len] < 0x80) {
break;
+ }
/*
* Next character length should not go beyond size to ensure that
* UTF_COMPOSINGLIKE(...) does not read beyond size.
*/
len_next_char = utf_ptr2len_len(p + len, size - len);
- if (len_next_char > size - len)
+ if (len_next_char > size - len) {
break;
+ }
- if (!UTF_COMPOSINGLIKE(p + prevlen, p + len))
+ if (!UTF_COMPOSINGLIKE(p + prevlen, p + len)) {
break;
+ }
- /* Skip over composing char */
+ // Skip over composing char
prevlen = len;
len += len_next_char;
}
@@ -1046,9 +1070,9 @@ bool utf_printable(int c)
* 0xd800-0xdfff is reserved for UTF-16, actually illegal. */
static struct interval nonprint[] =
{
- {0x070f, 0x070f}, {0x180b, 0x180e}, {0x200b, 0x200f}, {0x202a, 0x202e},
- {0x206a, 0x206f}, {0xd800, 0xdfff}, {0xfeff, 0xfeff}, {0xfff9, 0xfffb},
- {0xfffe, 0xffff}
+ { 0x070f, 0x070f }, { 0x180b, 0x180e }, { 0x200b, 0x200f }, { 0x202a, 0x202e },
+ { 0x206a, 0x206f }, { 0xd800, 0xdfff }, { 0xfeff, 0xfeff }, { 0xfff9, 0xfffb },
+ { 0xfffe, 0xffff }
};
return !intable(nonprint, ARRAY_SIZE(nonprint), c);
@@ -1068,7 +1092,7 @@ int utf_class(const int c)
int utf_class_tab(const int c, const uint64_t *const chartab)
{
- /* sorted list of non-overlapping intervals */
+ // sorted list of non-overlapping intervals
static struct clinterval {
unsigned int first;
unsigned int last;
@@ -1150,7 +1174,7 @@ int utf_class_tab(const int c, const uint64_t *const chartab)
int top = ARRAY_SIZE(classes) - 1;
int mid;
- /* First quick check for Latin1 characters, use 'iskeyword'. */
+ // First quick check for Latin1 characters, use 'iskeyword'.
if (c < 0x100) {
if (c == ' ' || c == '\t' || c == NUL || c == 0xa0) {
return 0; // blank
@@ -1161,15 +1185,16 @@ int utf_class_tab(const int c, const uint64_t *const chartab)
return 1; // punctuation
}
- /* binary search in table */
+ // binary search in table
while (top >= bot) {
mid = (bot + top) / 2;
- if (classes[mid].last < (unsigned int)c)
+ if (classes[mid].last < (unsigned int)c) {
bot = mid + 1;
- else if (classes[mid].first > (unsigned int)c)
+ } else if (classes[mid].first > (unsigned int)c) {
top = mid - 1;
- else
+ } else {
return (int)classes[mid].class;
+ }
}
// emoji
@@ -1177,7 +1202,7 @@ int utf_class_tab(const int c, const uint64_t *const chartab)
return 3;
}
- /* most other characters are "word" characters */
+ // most other characters are "word" characters
return 2;
}
@@ -1194,25 +1219,27 @@ bool utf_ambiguous_width(int c)
*/
static int utf_convert(int a, const convertStruct *const table, size_t n_items)
{
- size_t start, mid, end; /* indices into table */
+ size_t start, mid, end; // indices into table
start = 0;
end = n_items;
while (start < end) {
- /* need to search further */
+ // need to search further
mid = (end + start) / 2;
- if (table[mid].rangeEnd < a)
+ if (table[mid].rangeEnd < a) {
start = mid + 1;
- else
+ } else {
end = mid;
+ }
}
if (start < n_items
&& table[start].rangeStart <= a
&& a <= table[start].rangeEnd
- && (a - table[start].rangeStart) % table[start].step == 0)
+ && (a - table[start].rangeStart) % table[start].step == 0) {
return a + table[start].offset;
- else
+ } else {
return a;
+ }
}
/*
@@ -1237,21 +1264,24 @@ int utf_fold(int a)
/// simple case folding.
int mb_toupper(int a)
{
- /* If 'casemap' contains "keepascii" use ASCII style toupper(). */
- if (a < 128 && (cmp_flags & CMP_KEEPASCII))
+ // If 'casemap' contains "keepascii" use ASCII style toupper().
+ if (a < 128 && (cmp_flags & CMP_KEEPASCII)) {
return TOUPPER_ASC(a);
+ }
#if defined(__STDC_ISO_10646__)
- /* If towupper() is available and handles Unicode, use it. */
- if (!(cmp_flags & CMP_INTERNAL))
+ // If towupper() is available and handles Unicode, use it.
+ if (!(cmp_flags & CMP_INTERNAL)) {
return towupper(a);
+ }
#endif
- /* For characters below 128 use locale sensitive toupper(). */
- if (a < 128)
+ // For characters below 128 use locale sensitive toupper().
+ if (a < 128) {
return TOUPPER_LOC(a);
+ }
- /* For any other characters use the above mapping table. */
+ // For any other characters use the above mapping table.
return utf_convert(a, toUpper, ARRAY_SIZE(toUpper));
}
@@ -1265,21 +1295,24 @@ bool mb_islower(int a)
/// simple case folding.
int mb_tolower(int a)
{
- /* If 'casemap' contains "keepascii" use ASCII style tolower(). */
- if (a < 128 && (cmp_flags & CMP_KEEPASCII))
+ // If 'casemap' contains "keepascii" use ASCII style tolower().
+ if (a < 128 && (cmp_flags & CMP_KEEPASCII)) {
return TOLOWER_ASC(a);
+ }
#if defined(__STDC_ISO_10646__)
- /* If towlower() is available and handles Unicode, use it. */
- if (!(cmp_flags & CMP_INTERNAL))
+ // If towlower() is available and handles Unicode, use it.
+ if (!(cmp_flags & CMP_INTERNAL)) {
return towlower(a);
+ }
#endif
- /* For characters below 128 use locale sensitive tolower(). */
- if (a < 128)
+ // For characters below 128 use locale sensitive tolower().
+ if (a < 128) {
return TOLOWER_LOC(a);
+ }
- /* For any other characters use the above mapping table. */
+ // For any other characters use the above mapping table.
return utf_convert(a, toLower, ARRAY_SIZE(toLower));
}
@@ -1288,8 +1321,7 @@ bool mb_isupper(int a)
return mb_tolower(a) != a;
}
-static int utf_strnicmp(const char_u *s1, const char_u *s2, size_t n1,
- size_t n2)
+static int utf_strnicmp(const char_u *s1, const char_u *s2, size_t n1, size_t n2)
{
int c1, c2, cdiff;
char_u buffer[6];
@@ -1298,23 +1330,27 @@ static int utf_strnicmp(const char_u *s1, const char_u *s2, size_t n1,
c1 = utf_safe_read_char_adv(&s1, &n1);
c2 = utf_safe_read_char_adv(&s2, &n2);
- if (c1 <= 0 || c2 <= 0)
+ if (c1 <= 0 || c2 <= 0) {
break;
+ }
- if (c1 == c2)
+ if (c1 == c2) {
continue;
+ }
cdiff = utf_fold(c1) - utf_fold(c2);
- if (cdiff != 0)
+ if (cdiff != 0) {
return cdiff;
+ }
}
- /* some string ended or has an incomplete/illegal character sequence */
+ // some string ended or has an incomplete/illegal character sequence
if (c1 == 0 || c2 == 0) {
- /* some string ended. shorter string is smaller */
- if (c1 == 0 && c2 == 0)
+ // some string ended. shorter string is smaller
+ if (c1 == 0 && c2 == 0) {
return 0;
+ }
return c1 == 0 ? -1 : 1;
}
@@ -1335,8 +1371,9 @@ static int utf_strnicmp(const char_u *s1, const char_u *s2, size_t n1,
while (n1 > 0 && n2 > 0 && *s1 != NUL && *s2 != NUL) {
cdiff = (int)(*s1) - (int)(*s2);
- if (cdiff != 0)
+ if (cdiff != 0) {
return cdiff;
+ }
s1++;
s2++;
@@ -1344,20 +1381,23 @@ static int utf_strnicmp(const char_u *s1, const char_u *s2, size_t n1,
n2--;
}
- if (n1 > 0 && *s1 == NUL)
+ if (n1 > 0 && *s1 == NUL) {
n1 = 0;
- if (n2 > 0 && *s2 == NUL)
+ }
+ if (n2 > 0 && *s2 == NUL) {
n2 = 0;
+ }
- if (n1 == 0 && n2 == 0)
+ if (n1 == 0 && n2 == 0) {
return 0;
+ }
return n1 == 0 ? -1 : 1;
}
#ifdef WIN32
-#ifndef CP_UTF8
-# define CP_UTF8 65001 /* magic number from winnls.h */
-#endif
+# ifndef CP_UTF8
+# define CP_UTF8 65001 // magic number from winnls.h
+# endif
/// Converts string from UTF-8 to UTF-16.
///
@@ -1456,8 +1496,7 @@ int utf16_to_utf8(const wchar_t *utf16, int utf16len, char **utf8)
/// @param len maximum length (an earlier NUL terminates)
/// @param[out] codepoints incremented with UTF-32 code point size
/// @param[out] codeunits incremented with UTF-16 code unit size
-void mb_utflen(const char_u *s, size_t len, size_t *codepoints,
- size_t *codeunits)
+void mb_utflen(const char_u *s, size_t len, size_t *codepoints, size_t *codeunits)
FUNC_ATTR_NONNULL_ALL
{
size_t count = 0, extra = 0;
@@ -1476,8 +1515,7 @@ void mb_utflen(const char_u *s, size_t len, size_t *codepoints,
*codeunits += count + extra;
}
-ssize_t mb_utf_index_to_bytes(const char_u *s, size_t len,
- size_t index, bool use_utf16_units)
+ssize_t mb_utf_index_to_bytes(const char_u *s, size_t len, size_t index, bool use_utf16_units)
FUNC_ATTR_NONNULL_ALL
{
size_t count = 0;
@@ -1540,7 +1578,7 @@ void show_utf8(void)
{
int len;
int rlen = 0;
- char_u *line;
+ char_u *line;
int clen;
int i;
@@ -1556,7 +1594,7 @@ void show_utf8(void)
clen = 0;
for (i = 0; i < len; ++i) {
if (clen == 0) {
- /* start of (composing) character, get its length */
+ // start of (composing) character, get its length
if (i > 0) {
STRCPY(IObuff + rlen, "+ ");
rlen += 2;
@@ -1564,11 +1602,12 @@ void show_utf8(void)
clen = utf_ptr2len(line + i);
}
sprintf((char *)IObuff + rlen, "%02x ",
- (line[i] == NL) ? NUL : line[i]); /* NUL is stored as NL */
+ (line[i] == NL) ? NUL : line[i]); // NUL is stored as NL
--clen;
rlen += (int)STRLEN(IObuff + rlen);
- if (rlen > IOSIZE - 20)
+ if (rlen > IOSIZE - 20) {
break;
+ }
}
msg(IObuff);
@@ -1582,42 +1621,49 @@ int utf_head_off(const char_u *base, const char_u *p)
int c;
int len;
- if (*p < 0x80) /* be quick for ASCII */
+ if (*p < 0x80) { // be quick for ASCII
return 0;
+ }
/* Skip backwards over trailing bytes: 10xx.xxxx
* Skip backwards again if on a composing char. */
const char_u *q;
for (q = p;; --q) {
- /* Move s to the last byte of this char. */
+ // Move s to the last byte of this char.
const char_u *s;
for (s = q; (s[1] & 0xc0) == 0x80; ++s) {}
- /* Move q to the first byte of this char. */
- while (q > base && (*q & 0xc0) == 0x80)
+ // Move q to the first byte of this char.
+ while (q > base && (*q & 0xc0) == 0x80) {
--q;
+ }
/* Check for illegal sequence. Do allow an illegal byte after where we
* started. */
len = utf8len_tab[*q];
- if (len != (int)(s - q + 1) && len != (int)(p - q + 1))
+ if (len != (int)(s - q + 1) && len != (int)(p - q + 1)) {
return 0;
+ }
- if (q <= base)
+ if (q <= base) {
break;
+ }
c = utf_ptr2char(q);
- if (utf_iscomposing(c))
+ if (utf_iscomposing(c)) {
continue;
+ }
if (arabic_maycombine(c)) {
- /* Advance to get a sneak-peak at the next char */
+ // Advance to get a sneak-peak at the next char
const char_u *j = q;
--j;
- /* Move j to the first byte of this char. */
- while (j > base && (*j & 0xc0) == 0x80)
+ // Move j to the first byte of this char.
+ while (j > base && (*j & 0xc0) == 0x80) {
--j;
- if (arabic_combine(utf_ptr2char(j), c))
+ }
+ if (arabic_combine(utf_ptr2char(j), c)) {
continue;
+ }
}
break;
}
@@ -1630,12 +1676,12 @@ bool utf_eat_space(int cc)
FUNC_ATTR_CONST FUNC_ATTR_WARN_UNUSED_RESULT
{
return (cc >= 0x2000 && cc <= 0x206F) // General punctuations
- || (cc >= 0x2e00 && cc <= 0x2e7f) // Supplemental punctuations
- || (cc >= 0x3000 && cc <= 0x303f) // CJK symbols and punctuations
- || (cc >= 0xff01 && cc <= 0xff0f) // Full width ASCII punctuations
- || (cc >= 0xff1a && cc <= 0xff20) // ..
- || (cc >= 0xff3b && cc <= 0xff40) // ..
- || (cc >= 0xff5b && cc <= 0xff65); // ..
+ || (cc >= 0x2e00 && cc <= 0x2e7f) // Supplemental punctuations
+ || (cc >= 0x3000 && cc <= 0x303f) // CJK symbols and punctuations
+ || (cc >= 0xff01 && cc <= 0xff0f) // Full width ASCII punctuations
+ || (cc >= 0xff1a && cc <= 0xff20) // ..
+ || (cc >= 0xff3b && cc <= 0xff40) // ..
+ || (cc >= 0xff5b && cc <= 0xff65); // ..
}
// Whether line break is allowed before "cc".
@@ -1817,8 +1863,9 @@ int mb_tail_off(char_u *base, char_u *p)
int i;
int j;
- if (*p == NUL)
+ if (*p == NUL) {
return 0;
+ }
// Find the last character that is 10xx.xxxx
for (i = 0; (p[i + 1] & 0xc0) == 0x80; i++) {}
@@ -1842,10 +1889,10 @@ int mb_tail_off(char_u *base, char_u *p)
void utf_find_illegal(void)
{
pos_T pos = curwin->w_cursor;
- char_u *p;
+ char_u *p;
int len;
vimconv_T vimconv;
- char_u *tofree = NULL;
+ char_u *tofree = NULL;
vimconv.vc_type = CONV_NONE;
if (enc_canon_props(curbuf->b_p_fenc) & ENC_8BIT) {
@@ -1861,8 +1908,9 @@ void utf_find_illegal(void)
if (vimconv.vc_type != CONV_NONE) {
xfree(tofree);
tofree = string_convert(&vimconv, p, NULL);
- if (tofree == NULL)
+ if (tofree == NULL) {
break;
+ }
p = tofree;
}
@@ -1871,10 +1919,10 @@ void utf_find_illegal(void)
* utf_ptr2len()) or too many of them (overlong sequence). */
len = utf_ptr2len(p);
if (*p >= 0x80 && (len == 1
- || utf_char2len(utf_ptr2char(p)) != len)) {
- if (vimconv.vc_type == CONV_NONE)
+ || utf_char2len(utf_ptr2char(p)) != len)) {
+ if (vimconv.vc_type == CONV_NONE) {
curwin->w_cursor.col += (colnr_T)(p - get_cursor_pos_ptr());
- else {
+ } else {
int l;
len = (int)(p - tofree);
@@ -1887,13 +1935,14 @@ void utf_find_illegal(void)
}
p += len;
}
- if (curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count)
+ if (curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count) {
break;
+ }
++curwin->w_cursor.lnum;
curwin->w_cursor.col = 0;
}
- /* didn't find it: don't move and beep */
+ // didn't find it: don't move and beep
curwin->w_cursor = pos;
beep_flush();
@@ -1947,13 +1996,10 @@ void mb_check_adjust_col(void *win_)
}
}
-/*
- * Return a pointer to the character before "*p", if there is one.
- */
-char_u * mb_prevptr(
- char_u *line, /* start of the string */
- char_u *p
- )
+/// @param line start of the string
+///
+/// @return a pointer to the character before "*p", if there is one.
+char_u *mb_prevptr(char_u *line, char_u *p)
{
if (p > line) {
MB_PTR_BACK(line, p);
@@ -1967,14 +2013,16 @@ char_u * mb_prevptr(
*/
int mb_charlen(char_u *str)
{
- char_u *p = str;
+ char_u *p = str;
int count;
- if (p == NULL)
+ if (p == NULL) {
return 0;
+ }
- for (count = 0; *p != NUL; count++)
+ for (count = 0; *p != NUL; count++) {
p += (*mb_ptr2len)(p);
+ }
return count;
}
@@ -1984,11 +2032,12 @@ int mb_charlen(char_u *str)
*/
int mb_charlen_len(char_u *str, int len)
{
- char_u *p = str;
+ char_u *p = str;
int count;
- for (count = 0; *p != NUL && p < str + len; count++)
+ for (count = 0; *p != NUL && p < str + len; count++) {
p += (*mb_ptr2len)(p);
+ }
return count;
}
@@ -2050,12 +2099,14 @@ const char *mb_unescape(const char **const pp)
/*
* Skip the Vim specific head of a 'encoding' name.
*/
-char_u * enc_skip(char_u *p)
+char_u *enc_skip(char_u *p)
{
- if (STRNCMP(p, "2byte-", 6) == 0)
+ if (STRNCMP(p, "2byte-", 6) == 0) {
return p + 6;
- if (STRNCMP(p, "8bit-", 5) == 0)
+ }
+ if (STRNCMP(p, "8bit-", 5) == 0) {
return p + 5;
+ }
return p;
}
@@ -2067,7 +2118,7 @@ char_u * enc_skip(char_u *p)
*/
char_u *enc_canonize(char_u *enc) FUNC_ATTR_NONNULL_RET
{
- char_u *p, *s;
+ char_u *p, *s;
int i;
if (STRCMP(enc, "default") == 0) {
@@ -2075,47 +2126,51 @@ char_u *enc_canonize(char_u *enc) FUNC_ATTR_NONNULL_RET
return vim_strsave(fenc_default);
}
- /* copy "enc" to allocated memory, with room for two '-' */
+ // copy "enc" to allocated memory, with room for two '-'
char_u *r = xmalloc(STRLEN(enc) + 3);
- /* Make it all lower case and replace '_' with '-'. */
+ // Make it all lower case and replace '_' with '-'.
p = r;
for (s = enc; *s != NUL; ++s) {
- if (*s == '_')
+ if (*s == '_') {
*p++ = '-';
- else
+ } else {
*p++ = TOLOWER_ASC(*s);
+ }
}
*p = NUL;
- /* Skip "2byte-" and "8bit-". */
+ // Skip "2byte-" and "8bit-".
p = enc_skip(r);
- /* Change "microsoft-cp" to "cp". Used in some spell files. */
- if (STRNCMP(p, "microsoft-cp", 12) == 0)
+ // Change "microsoft-cp" to "cp". Used in some spell files.
+ if (STRNCMP(p, "microsoft-cp", 12) == 0) {
STRMOVE(p, p + 10);
+ }
- /* "iso8859" -> "iso-8859" */
+ // "iso8859" -> "iso-8859"
if (STRNCMP(p, "iso8859", 7) == 0) {
STRMOVE(p + 4, p + 3);
p[3] = '-';
}
- /* "iso-8859n" -> "iso-8859-n" */
+ // "iso-8859n" -> "iso-8859-n"
if (STRNCMP(p, "iso-8859", 8) == 0 && p[8] != '-') {
STRMOVE(p + 9, p + 8);
p[8] = '-';
}
- /* "latin-N" -> "latinN" */
- if (STRNCMP(p, "latin-", 6) == 0)
+ // "latin-N" -> "latinN"
+ if (STRNCMP(p, "latin-", 6) == 0) {
STRMOVE(p + 5, p + 6);
+ }
if (enc_canon_search(p) >= 0) {
- /* canonical name can be used unmodified */
- if (p != r)
+ // canonical name can be used unmodified
+ if (p != r) {
STRMOVE(r, p);
+ }
} else if ((i = enc_alias_search(p)) >= 0) {
- /* alias recognized, get canonical name */
+ // alias recognized, get canonical name
xfree(r);
r = vim_strsave((char_u *)enc_canon_table[i].name);
}
@@ -2130,9 +2185,11 @@ static int enc_alias_search(char_u *name)
{
int i;
- for (i = 0; enc_alias_table[i].name != NULL; ++i)
- if (STRCMP(name, enc_alias_table[i].name) == 0)
+ for (i = 0; enc_alias_table[i].name != NULL; ++i) {
+ if (STRCMP(name, enc_alias_table[i].name) == 0) {
return enc_alias_table[i].canon;
+ }
+ }
return -1;
}
@@ -2145,19 +2202,19 @@ static int enc_alias_search(char_u *name)
* Get the canonicalized encoding of the current locale.
* Returns an allocated string when successful, NULL when not.
*/
-char_u * enc_locale(void)
+char_u *enc_locale(void)
{
int i;
char buf[50];
const char *s;
-# ifdef HAVE_NL_LANGINFO_CODESET
+#ifdef HAVE_NL_LANGINFO_CODESET
if (!(s = nl_langinfo(CODESET)) || *s == NUL)
-# endif
+#endif
{
-# if defined(HAVE_LOCALE_H)
+#if defined(HAVE_LOCALE_H)
if (!(s = setlocale(LC_CTYPE, NULL)) || *s == NUL)
-# endif
+#endif
{
if ((s = os_getenv("LC_ALL"))) {
if ((s = os_getenv("LC_CTYPE"))) {
@@ -2208,7 +2265,7 @@ enc_locale_copy_enc:
return enc_canonize((char_u *)buf);
}
-# if defined(HAVE_ICONV)
+#if defined(HAVE_ICONV)
/*
@@ -2217,18 +2274,18 @@ enc_locale_copy_enc:
* Returns (void *)-1 if failed.
* (should return iconv_t, but that causes problems with prototypes).
*/
-void * my_iconv_open(char_u *to, char_u *from)
+void *my_iconv_open(char_u *to, char_u *from)
{
iconv_t fd;
-#define ICONV_TESTLEN 400
+# define ICONV_TESTLEN 400
char_u tobuf[ICONV_TESTLEN];
- char *p;
+ char *p;
size_t tolen;
static WorkingStatus iconv_working = kUnknown;
- if (iconv_working == kBroken)
- return (void *)-1; /* detected a broken iconv() previously */
-
+ if (iconv_working == kBroken) {
+ return (void *)-1; // detected a broken iconv() previously
+ }
fd = iconv_open((char *)enc_skip(to), (char *)enc_skip(from));
if (fd != (iconv_t)-1 && iconv_working == kUnknown) {
@@ -2246,8 +2303,9 @@ void * my_iconv_open(char_u *to, char_u *from)
iconv_working = kBroken;
iconv_close(fd);
fd = (iconv_t)-1;
- } else
+ } else {
iconv_working = kWorking;
+ }
}
return (void *)fd;
@@ -2260,17 +2318,17 @@ void * my_iconv_open(char_u *to, char_u *from)
* Returns the converted string in allocated memory. NULL for an error.
* If resultlenp is not NULL, sets it to the result length in bytes.
*/
-static char_u *iconv_string(const vimconv_T *const vcp, char_u *str,
- size_t slen, size_t *unconvlenp, size_t *resultlenp)
+static char_u *iconv_string(const vimconv_T *const vcp, char_u *str, size_t slen,
+ size_t *unconvlenp, size_t *resultlenp)
{
- const char *from;
+ const char *from;
size_t fromlen;
- char *to;
+ char *to;
size_t tolen;
size_t len = 0;
size_t done = 0;
- char_u *result = NULL;
- char_u *p;
+ char_u *result = NULL;
+ char_u *p;
int l;
from = (char *)str;
@@ -2281,8 +2339,9 @@ static char_u *iconv_string(const vimconv_T *const vcp, char_u *str,
* increase the buffer size. */
len = len + fromlen * 2 + 40;
p = xmalloc(len);
- if (done > 0)
+ if (done > 0) {
memmove(p, result, done);
+ }
xfree(result);
result = p;
}
@@ -2330,12 +2389,13 @@ static char_u *iconv_string(const vimconv_T *const vcp, char_u *str,
done = to - (char *)result;
}
- if (resultlenp != NULL && result != NULL)
+ if (resultlenp != NULL && result != NULL) {
*resultlenp = (size_t)(to - (char *)result);
+ }
return result;
}
-# endif // HAVE_ICONV
+#endif // HAVE_ICONV
@@ -2354,12 +2414,10 @@ int convert_setup(vimconv_T *vcp, char_u *from, char_u *to)
return convert_setup_ext(vcp, from, true, to, true);
}
-/*
- * As convert_setup(), but only when from_unicode_is_utf8 is TRUE will all
- * "from" unicode charsets be considered utf-8. Same for "to".
- */
-int convert_setup_ext(vimconv_T *vcp, char_u *from, bool from_unicode_is_utf8,
- char_u *to, bool to_unicode_is_utf8)
+/// As convert_setup(), but only when from_unicode_is_utf8 is true will all
+/// "from" unicode charsets be considered utf-8. Same for "to".
+int convert_setup_ext(vimconv_T *vcp, char_u *from, bool from_unicode_is_utf8, char_u *to,
+ bool to_unicode_is_utf8)
{
int from_prop;
int to_prop;
@@ -2367,58 +2425,61 @@ int convert_setup_ext(vimconv_T *vcp, char_u *from, bool from_unicode_is_utf8,
int to_is_utf8;
// Reset to no conversion.
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
if (vcp->vc_type == CONV_ICONV && vcp->vc_fd != (iconv_t)-1) {
iconv_close(vcp->vc_fd);
}
-# endif
+#endif
*vcp = (vimconv_T)MBYTE_NONE_CONV;
- /* No conversion when one of the names is empty or they are equal. */
+ // No conversion when one of the names is empty or they are equal.
if (from == NULL || *from == NUL || to == NULL || *to == NUL
- || STRCMP(from, to) == 0)
+ || STRCMP(from, to) == 0) {
return OK;
+ }
from_prop = enc_canon_props(from);
to_prop = enc_canon_props(to);
- if (from_unicode_is_utf8)
+ if (from_unicode_is_utf8) {
from_is_utf8 = from_prop & ENC_UNICODE;
- else
+ } else {
from_is_utf8 = from_prop == ENC_UNICODE;
- if (to_unicode_is_utf8)
+ }
+ if (to_unicode_is_utf8) {
to_is_utf8 = to_prop & ENC_UNICODE;
- else
+ } else {
to_is_utf8 = to_prop == ENC_UNICODE;
+ }
if ((from_prop & ENC_LATIN1) && to_is_utf8) {
- /* Internal latin1 -> utf-8 conversion. */
+ // Internal latin1 -> utf-8 conversion.
vcp->vc_type = CONV_TO_UTF8;
- vcp->vc_factor = 2; /* up to twice as long */
+ vcp->vc_factor = 2; // up to twice as long
} else if ((from_prop & ENC_LATIN9) && to_is_utf8) {
- /* Internal latin9 -> utf-8 conversion. */
+ // Internal latin9 -> utf-8 conversion.
vcp->vc_type = CONV_9_TO_UTF8;
- vcp->vc_factor = 3; /* up to three as long (euro sign) */
+ vcp->vc_factor = 3; // up to three as long (euro sign)
} else if (from_is_utf8 && (to_prop & ENC_LATIN1)) {
- /* Internal utf-8 -> latin1 conversion. */
+ // Internal utf-8 -> latin1 conversion.
vcp->vc_type = CONV_TO_LATIN1;
} else if (from_is_utf8 && (to_prop & ENC_LATIN9)) {
- /* Internal utf-8 -> latin9 conversion. */
+ // Internal utf-8 -> latin9 conversion.
vcp->vc_type = CONV_TO_LATIN9;
}
-# ifdef HAVE_ICONV
+#ifdef HAVE_ICONV
else { // NOLINT(readability/braces)
// Use iconv() for conversion.
- vcp->vc_fd = (iconv_t)my_iconv_open(
- to_is_utf8 ? (char_u *)"utf-8" : to,
- from_is_utf8 ? (char_u *)"utf-8" : from);
+ vcp->vc_fd = (iconv_t)my_iconv_open(to_is_utf8 ? (char_u *)"utf-8" : to,
+ from_is_utf8 ? (char_u *)"utf-8" : from);
if (vcp->vc_fd != (iconv_t)-1) {
vcp->vc_type = CONV_ICONV;
- vcp->vc_factor = 4; /* could be longer too... */
+ vcp->vc_factor = 4; // could be longer too...
}
}
-# endif
- if (vcp->vc_type == CONV_NONE)
+#endif
+ if (vcp->vc_type == CONV_NONE) {
return FAIL;
+ }
return OK;
}
@@ -2440,130 +2501,154 @@ char_u *string_convert(const vimconv_T *const vcp, char_u *ptr, size_t *lenp)
* an incomplete sequence at the end it is not converted and "*unconvlenp" is
* set to the number of remaining bytes.
*/
-char_u * string_convert_ext(const vimconv_T *const vcp, char_u *ptr,
- size_t *lenp, size_t *unconvlenp)
+char_u *string_convert_ext(const vimconv_T *const vcp, char_u *ptr, size_t *lenp,
+ size_t *unconvlenp)
{
- char_u *retval = NULL;
- char_u *d;
+ char_u *retval = NULL;
+ char_u *d;
int l;
int c;
size_t len;
- if (lenp == NULL)
+ if (lenp == NULL) {
len = STRLEN(ptr);
- else
+ } else {
len = *lenp;
- if (len == 0)
+ }
+ if (len == 0) {
return vim_strsave((char_u *)"");
+ }
switch (vcp->vc_type) {
- case CONV_TO_UTF8: /* latin1 to utf-8 conversion */
- retval = xmalloc(len * 2 + 1);
- d = retval;
- for (size_t i = 0; i < len; ++i) {
- c = ptr[i];
- if (c < 0x80)
- *d++ = c;
- else {
- *d++ = 0xc0 + ((unsigned)c >> 6);
- *d++ = 0x80 + (c & 0x3f);
- }
+ case CONV_TO_UTF8: // latin1 to utf-8 conversion
+ retval = xmalloc(len * 2 + 1);
+ d = retval;
+ for (size_t i = 0; i < len; ++i) {
+ c = ptr[i];
+ if (c < 0x80) {
+ *d++ = c;
+ } else {
+ *d++ = 0xc0 + ((unsigned)c >> 6);
+ *d++ = 0x80 + (c & 0x3f);
}
- *d = NUL;
- if (lenp != NULL)
- *lenp = (size_t)(d - retval);
- break;
+ }
+ *d = NUL;
+ if (lenp != NULL) {
+ *lenp = (size_t)(d - retval);
+ }
+ break;
- case CONV_9_TO_UTF8: /* latin9 to utf-8 conversion */
- retval = xmalloc(len * 3 + 1);
- d = retval;
- for (size_t i = 0; i < len; ++i) {
- c = ptr[i];
- switch (c) {
- case 0xa4: c = 0x20ac; break; /* euro */
- case 0xa6: c = 0x0160; break; /* S hat */
- case 0xa8: c = 0x0161; break; /* S -hat */
- case 0xb4: c = 0x017d; break; /* Z hat */
- case 0xb8: c = 0x017e; break; /* Z -hat */
- case 0xbc: c = 0x0152; break; /* OE */
- case 0xbd: c = 0x0153; break; /* oe */
- case 0xbe: c = 0x0178; break; /* Y */
- }
- d += utf_char2bytes(c, d);
+ case CONV_9_TO_UTF8: // latin9 to utf-8 conversion
+ retval = xmalloc(len * 3 + 1);
+ d = retval;
+ for (size_t i = 0; i < len; ++i) {
+ c = ptr[i];
+ switch (c) {
+ case 0xa4:
+ c = 0x20ac; break; // euro
+ case 0xa6:
+ c = 0x0160; break; // S hat
+ case 0xa8:
+ c = 0x0161; break; // S -hat
+ case 0xb4:
+ c = 0x017d; break; // Z hat
+ case 0xb8:
+ c = 0x017e; break; // Z -hat
+ case 0xbc:
+ c = 0x0152; break; // OE
+ case 0xbd:
+ c = 0x0153; break; // oe
+ case 0xbe:
+ c = 0x0178; break; // Y
}
- *d = NUL;
- if (lenp != NULL)
- *lenp = (size_t)(d - retval);
- break;
+ d += utf_char2bytes(c, d);
+ }
+ *d = NUL;
+ if (lenp != NULL) {
+ *lenp = (size_t)(d - retval);
+ }
+ break;
- case CONV_TO_LATIN1: /* utf-8 to latin1 conversion */
- case CONV_TO_LATIN9: /* utf-8 to latin9 conversion */
- retval = xmalloc(len + 1);
- d = retval;
- for (size_t i = 0; i < len; ++i) {
- l = utf_ptr2len_len(ptr + i, len - i);
- if (l == 0)
- *d++ = NUL;
- else if (l == 1) {
- uint8_t l_w = utf8len_tab_zero[ptr[i]];
-
- if (l_w == 0) {
- /* Illegal utf-8 byte cannot be converted */
+ case CONV_TO_LATIN1: // utf-8 to latin1 conversion
+ case CONV_TO_LATIN9: // utf-8 to latin9 conversion
+ retval = xmalloc(len + 1);
+ d = retval;
+ for (size_t i = 0; i < len; ++i) {
+ l = utf_ptr2len_len(ptr + i, len - i);
+ if (l == 0) {
+ *d++ = NUL;
+ } else if (l == 1) {
+ uint8_t l_w = utf8len_tab_zero[ptr[i]];
+
+ if (l_w == 0) {
+ // Illegal utf-8 byte cannot be converted
+ xfree(retval);
+ return NULL;
+ }
+ if (unconvlenp != NULL && l_w > len - i) {
+ // Incomplete sequence at the end.
+ *unconvlenp = len - i;
+ break;
+ }
+ *d++ = ptr[i];
+ } else {
+ c = utf_ptr2char(ptr + i);
+ if (vcp->vc_type == CONV_TO_LATIN9) {
+ switch (c) {
+ case 0x20ac:
+ c = 0xa4; break; // euro
+ case 0x0160:
+ c = 0xa6; break; // S hat
+ case 0x0161:
+ c = 0xa8; break; // S -hat
+ case 0x017d:
+ c = 0xb4; break; // Z hat
+ case 0x017e:
+ c = 0xb8; break; // Z -hat
+ case 0x0152:
+ c = 0xbc; break; // OE
+ case 0x0153:
+ c = 0xbd; break; // oe
+ case 0x0178:
+ c = 0xbe; break; // Y
+ case 0xa4:
+ case 0xa6:
+ case 0xa8:
+ case 0xb4:
+ case 0xb8:
+ case 0xbc:
+ case 0xbd:
+ case 0xbe:
+ c = 0x100; break; // not in latin9
+ }
+ }
+ if (!utf_iscomposing(c)) { // skip composing chars
+ if (c < 0x100) {
+ *d++ = c;
+ } else if (vcp->vc_fail) {
xfree(retval);
return NULL;
- }
- if (unconvlenp != NULL && l_w > len - i) {
- /* Incomplete sequence at the end. */
- *unconvlenp = len - i;
- break;
- }
- *d++ = ptr[i];
- } else {
- c = utf_ptr2char(ptr + i);
- if (vcp->vc_type == CONV_TO_LATIN9)
- switch (c) {
- case 0x20ac: c = 0xa4; break; /* euro */
- case 0x0160: c = 0xa6; break; /* S hat */
- case 0x0161: c = 0xa8; break; /* S -hat */
- case 0x017d: c = 0xb4; break; /* Z hat */
- case 0x017e: c = 0xb8; break; /* Z -hat */
- case 0x0152: c = 0xbc; break; /* OE */
- case 0x0153: c = 0xbd; break; /* oe */
- case 0x0178: c = 0xbe; break; /* Y */
- case 0xa4:
- case 0xa6:
- case 0xa8:
- case 0xb4:
- case 0xb8:
- case 0xbc:
- case 0xbd:
- case 0xbe: c = 0x100; break; /* not in latin9 */
- }
- if (!utf_iscomposing(c)) { /* skip composing chars */
- if (c < 0x100)
- *d++ = c;
- else if (vcp->vc_fail) {
- xfree(retval);
- return NULL;
- } else {
- *d++ = 0xbf;
- if (utf_char2cells(c) > 1)
- *d++ = '?';
+ } else {
+ *d++ = 0xbf;
+ if (utf_char2cells(c) > 1) {
+ *d++ = '?';
}
}
- i += l - 1;
}
+ i += l - 1;
}
- *d = NUL;
- if (lenp != NULL)
- *lenp = (size_t)(d - retval);
- break;
+ }
+ *d = NUL;
+ if (lenp != NULL) {
+ *lenp = (size_t)(d - retval);
+ }
+ break;
-# ifdef HAVE_ICONV
- case CONV_ICONV: // conversion with vcp->vc_fd
- retval = iconv_string(vcp, ptr, len, unconvlenp, lenp);
- break;
-# endif
+#ifdef HAVE_ICONV
+ case CONV_ICONV: // conversion with vcp->vc_fd
+ retval = iconv_string(vcp, ptr, len, unconvlenp, lenp);
+ break;
+#endif
}
return retval;
diff --git a/src/nvim/memfile.c b/src/nvim/memfile.c
index 7bed644da3..438340e0c4 100644
--- a/src/nvim/memfile.c
+++ b/src/nvim/memfile.c
@@ -39,24 +39,24 @@
/// mf_fullname() make file name full path (use before first :cd)
#include <assert.h>
+#include <fcntl.h>
#include <inttypes.h>
#include <limits.h>
-#include <string.h>
#include <stdbool.h>
-#include <fcntl.h>
+#include <string.h>
-#include "nvim/vim.h"
#include "nvim/ascii.h"
-#include "nvim/memfile.h"
+#include "nvim/assert.h"
#include "nvim/fileio.h"
+#include "nvim/memfile.h"
#include "nvim/memline.h"
-#include "nvim/message.h"
#include "nvim/memory.h"
+#include "nvim/message.h"
+#include "nvim/os/input.h"
+#include "nvim/os/os.h"
#include "nvim/os_unix.h"
#include "nvim/path.h"
-#include "nvim/assert.h"
-#include "nvim/os/os.h"
-#include "nvim/os/input.h"
+#include "nvim/vim.h"
#define MEMFILE_PAGE_SIZE 4096 /// default page size
@@ -168,7 +168,7 @@ void mf_close(memfile_T *mfp, bool del_file)
return;
}
if (mfp->mf_fd >= 0 && close(mfp->mf_fd) < 0) {
- EMSG(_(e_swapclose));
+ EMSG(_(e_swapclose));
}
if (del_file && mfp->mf_fname != NULL) {
os_remove((char *)mfp->mf_fname);
@@ -282,14 +282,16 @@ bhdr_T *mf_new(memfile_T *mfp, bool negative, unsigned page_count)
bhdr_T *mf_get(memfile_T *mfp, blocknr_T nr, unsigned page_count)
{
// check block number exists
- if (nr >= mfp->mf_blocknr_max || nr <= mfp->mf_blocknr_min)
+ if (nr >= mfp->mf_blocknr_max || nr <= mfp->mf_blocknr_min) {
return NULL;
+ }
// see if it is in the cache
bhdr_T *hp = mf_find_hash(mfp, nr);
if (hp == NULL) { // not in the hash list
- if (nr < 0 || nr >= mfp->mf_infile_count) // can't be in the file
+ if (nr < 0 || nr >= mfp->mf_infile_count) { // can't be in the file
return NULL;
+ }
// could check here if the block is in the free list
@@ -331,8 +333,9 @@ void mf_put(memfile_T *mfp, bhdr_T *hp, bool dirty, bool infile)
mfp->mf_dirty = true;
}
hp->bh_flags = flags;
- if (infile)
+ if (infile) {
mf_trans_add(mfp, hp); // may translate negative in positive nr
+ }
}
/// Signal block as no longer used (may put it in the free list).
@@ -381,32 +384,38 @@ int mf_sync(memfile_T *mfp, int flags)
// fails then we give up.
int status = OK;
bhdr_T *hp;
- for (hp = mfp->mf_used_last; hp != NULL; hp = hp->bh_prev)
+ for (hp = mfp->mf_used_last; hp != NULL; hp = hp->bh_prev) {
if (((flags & MFS_ALL) || hp->bh_bnum >= 0)
&& (hp->bh_flags & BH_DIRTY)
&& (status == OK || (hp->bh_bnum >= 0
&& hp->bh_bnum < mfp->mf_infile_count))) {
- if ((flags & MFS_ZERO) && hp->bh_bnum != 0)
+ if ((flags & MFS_ZERO) && hp->bh_bnum != 0) {
continue;
+ }
if (mf_write(mfp, hp) == FAIL) {
- if (status == FAIL) // double error: quit syncing
+ if (status == FAIL) { // double error: quit syncing
break;
+ }
status = FAIL;
}
if (flags & MFS_STOP) { // Stop when char available now.
- if (os_char_avail())
+ if (os_char_avail()) {
break;
+ }
} else {
os_breakcheck();
}
- if (got_int)
+ if (got_int) {
break;
+ }
}
+ }
// If the whole list is flushed, the memfile is not dirty anymore.
// In case of an error, dirty flag is also set, to avoid trying all the time.
- if (hp == NULL || status == FAIL)
+ if (hp == NULL || status == FAIL) {
mfp->mf_dirty = false;
+ }
if (flags & MFS_FLUSH) {
if (os_fsync(mfp->mf_fd)) {
@@ -465,15 +474,17 @@ static void mf_ins_used(memfile_T *mfp, bhdr_T *hp)
/// Remove block from memfile's used list.
static void mf_rem_used(memfile_T *mfp, bhdr_T *hp)
{
- if (hp->bh_next == NULL) // last block in used list
+ if (hp->bh_next == NULL) { // last block in used list
mfp->mf_used_last = hp->bh_prev;
- else
+ } else {
hp->bh_next->bh_prev = hp->bh_prev;
+ }
- if (hp->bh_prev == NULL) // first block in used list
+ if (hp->bh_prev == NULL) { // first block in used list
mfp->mf_used_first = hp->bh_next;
- else
+ } else {
hp->bh_prev->bh_next = hp->bh_next;
+ }
}
/// Release as many blocks as possible.
@@ -554,8 +565,9 @@ static bhdr_T *mf_rem_free(memfile_T *mfp)
/// - Error reading file.
static int mf_read(memfile_T *mfp, bhdr_T *hp)
{
- if (mfp->mf_fd < 0) // there is no file, can't read
+ if (mfp->mf_fd < 0) { // there is no file, can't read
return FAIL;
+ }
unsigned page_size = mfp->mf_page_size;
// TODO(elmart): Check (page_size * hp->bh_bnum) within off_T bounds.
@@ -592,12 +604,15 @@ static int mf_write(memfile_T *mfp, bhdr_T *hp)
unsigned page_count; // number of pages written
unsigned size; // number of bytes written
- if (mfp->mf_fd < 0) // there is no file, can't write
+ if (mfp->mf_fd < 0) { // there is no file, can't write
return FAIL;
+ }
- if (hp->bh_bnum < 0) // must assign file block number
- if (mf_trans_add(mfp, hp) == FAIL)
+ if (hp->bh_bnum < 0) { // must assign file block number
+ if (mf_trans_add(mfp, hp) == FAIL) {
return FAIL;
+ }
+ }
page_size = mfp->mf_page_size;
@@ -620,10 +635,11 @@ static int mf_write(memfile_T *mfp, bhdr_T *hp)
PERROR(_("E296: Seek error in swap file write"));
return FAIL;
}
- if (hp2 == NULL) // freed block, fill with dummy data
+ if (hp2 == NULL) { // freed block, fill with dummy data
page_count = 1;
- else
+ } else {
page_count = hp2->bh_page_count;
+ }
size = page_size * page_count;
void *data = (hp2 == NULL) ? hp->bh_data : hp2->bh_data;
if ((unsigned)write_eintr(mfp->mf_fd, data, size) != size) {
@@ -631,18 +647,22 @@ static int mf_write(memfile_T *mfp, bhdr_T *hp)
/// disk is full. We give the message again only after a successful
/// write or when hitting a key. We keep on trying, in case some
/// space becomes available.
- if (!did_swapwrite_msg)
+ if (!did_swapwrite_msg) {
EMSG(_("E297: Write error in swap file"));
+ }
did_swapwrite_msg = true;
return FAIL;
}
did_swapwrite_msg = false;
- if (hp2 != NULL) // written a non-dummy block
+ if (hp2 != NULL) { // written a non-dummy block
hp2->bh_flags &= ~BH_DIRTY;
- if (nr + (blocknr_T)page_count > mfp->mf_infile_count) // appended to file
+ }
+ if (nr + (blocknr_T)page_count > mfp->mf_infile_count) { // appended to file
mfp->mf_infile_count = nr + page_count;
- if (nr == hp->bh_bnum) // written the desired block
+ }
+ if (nr == hp->bh_bnum) { // written the desired block
break;
+ }
}
return OK;
}
@@ -653,8 +673,9 @@ static int mf_write(memfile_T *mfp, bhdr_T *hp)
/// FAIL On failure.
static int mf_trans_add(memfile_T *mfp, bhdr_T *hp)
{
- if (hp->bh_bnum >= 0) // it's already positive
+ if (hp->bh_bnum >= 0) { // it's already positive
return OK;
+ }
mf_blocknr_trans_item_T *np = xmalloc(sizeof(mf_blocknr_trans_item_T));
@@ -702,8 +723,9 @@ blocknr_T mf_trans_del(memfile_T *mfp, blocknr_T old_nr)
mf_blocknr_trans_item_T *np =
(mf_blocknr_trans_item_T *)mf_hash_find(&mfp->mf_trans, old_nr);
- if (np == NULL) // not found
+ if (np == NULL) { // not found
return old_nr;
+ }
mfp->mf_neg_count--;
blocknr_T new_bnum = np->nt_new_bnum;
@@ -834,8 +856,9 @@ static void mf_hash_free_all(mf_hashtab_T *mht)
static mf_hashitem_T *mf_hash_find(mf_hashtab_T *mht, blocknr_T key)
{
mf_hashitem_T *mhi = mht->mht_buckets[(size_t)key & mht->mht_mask];
- while (mhi != NULL && mhi->mhi_key != key)
+ while (mhi != NULL && mhi->mhi_key != key) {
mhi = mhi->mhi_next;
+ }
return mhi;
}
@@ -845,8 +868,9 @@ static void mf_hash_add_item(mf_hashtab_T *mht, mf_hashitem_T *mhi)
size_t idx = (size_t)mhi->mhi_key & mht->mht_mask;
mhi->mhi_next = mht->mht_buckets[idx];
mhi->mhi_prev = NULL;
- if (mhi->mhi_next != NULL)
+ if (mhi->mhi_next != NULL) {
mhi->mhi_next->mhi_prev = mhi;
+ }
mht->mht_buckets[idx] = mhi;
mht->mht_count++;
@@ -861,14 +885,16 @@ static void mf_hash_add_item(mf_hashtab_T *mht, mf_hashitem_T *mhi)
/// Remove item from hashtable. Item must be non NULL and within hashtable.
static void mf_hash_rem_item(mf_hashtab_T *mht, mf_hashitem_T *mhi)
{
- if (mhi->mhi_prev == NULL)
+ if (mhi->mhi_prev == NULL) {
mht->mht_buckets[(size_t)mhi->mhi_key & mht->mht_mask] =
mhi->mhi_next;
- else
+ } else {
mhi->mhi_prev->mhi_next = mhi->mhi_next;
+ }
- if (mhi->mhi_next != NULL)
+ if (mhi->mhi_next != NULL) {
mhi->mhi_next->mhi_prev = mhi->mhi_prev;
+ }
mht->mht_count--;
@@ -884,8 +910,9 @@ static void mf_hash_grow(mf_hashtab_T *mht)
mf_hashitem_T **buckets = xcalloc(1, size);
int shift = 0;
- while ((mht->mht_mask >> shift) != 0)
+ while ((mht->mht_mask >> shift) != 0) {
shift++;
+ }
for (size_t i = 0; i <= mht->mht_mask; i++) {
/// Traverse the items in the i-th original bucket and move them into
@@ -914,13 +941,16 @@ static void mf_hash_grow(mf_hashtab_T *mht)
}
}
- for (size_t j = 0; j < MHT_GROWTH_FACTOR; j++)
- if (tails[j] != NULL)
+ for (size_t j = 0; j < MHT_GROWTH_FACTOR; j++) {
+ if (tails[j] != NULL) {
tails[j]->mhi_next = NULL;
+ }
+ }
}
- if (mht->mht_buckets != mht->mht_small_buckets)
+ if (mht->mht_buckets != mht->mht_small_buckets) {
xfree(mht->mht_buckets);
+ }
mht->mht_buckets = buckets;
mht->mht_mask = (mht->mht_mask + 1) * MHT_GROWTH_FACTOR - 1;
diff --git a/src/nvim/memfile_defs.h b/src/nvim/memfile_defs.h
index 2402d2147d..3eaa7d83e0 100644
--- a/src/nvim/memfile_defs.h
+++ b/src/nvim/memfile_defs.h
@@ -101,7 +101,7 @@ typedef struct memfile {
blocknr_T mf_neg_count; /// number of negative blocks numbers
blocknr_T mf_infile_count; /// number of pages in the file
unsigned mf_page_size; /// number of bytes in a page
- bool mf_dirty; /// TRUE if there are dirty blocks
+ bool mf_dirty; /// true if there are dirty blocks
} memfile_T;
#endif // NVIM_MEMFILE_DEFS_H
diff --git a/src/nvim/memline.c b/src/nvim/memline.c
index cb2437b2b3..69598bbdda 100644
--- a/src/nvim/memline.c
+++ b/src/nvim/memline.c
@@ -38,29 +38,31 @@
#include <assert.h>
#include <errno.h>
+#include <fcntl.h>
#include <inttypes.h>
-#include <string.h>
#include <stdbool.h>
-#include <fcntl.h>
+#include <string.h>
#include "nvim/ascii.h"
-#include "nvim/vim.h"
-#include "nvim/memline.h"
#include "nvim/buffer.h"
#include "nvim/change.h"
#include "nvim/cursor.h"
#include "nvim/eval.h"
-#include "nvim/getchar.h"
#include "nvim/fileio.h"
#include "nvim/func_attr.h"
+#include "nvim/getchar.h"
#include "nvim/main.h"
#include "nvim/mark.h"
#include "nvim/mbyte.h"
#include "nvim/memfile.h"
+#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
#include "nvim/option.h"
+#include "nvim/os/input.h"
+#include "nvim/os/os.h"
+#include "nvim/os/process.h"
#include "nvim/os_unix.h"
#include "nvim/path.h"
#include "nvim/screen.h"
@@ -68,44 +70,42 @@
#include "nvim/spell.h"
#include "nvim/strings.h"
#include "nvim/ui.h"
-#include "nvim/version.h"
#include "nvim/undo.h"
+#include "nvim/version.h"
+#include "nvim/vim.h"
#include "nvim/window.h"
-#include "nvim/os/os.h"
-#include "nvim/os/process.h"
-#include "nvim/os/input.h"
-#ifndef UNIX /* it's in os/unix_defs.h for Unix */
+#ifndef UNIX // it's in os/unix_defs.h for Unix
# include <time.h>
#endif
-typedef struct block0 ZERO_BL; /* contents of the first block */
-typedef struct pointer_block PTR_BL; /* contents of a pointer block */
-typedef struct data_block DATA_BL; /* contents of a data block */
-typedef struct pointer_entry PTR_EN; /* block/line-count pair */
+typedef struct block0 ZERO_BL; // contents of the first block
+typedef struct pointer_block PTR_BL; // contents of a pointer block
+typedef struct data_block DATA_BL; // contents of a data block
+typedef struct pointer_entry PTR_EN; // block/line-count pair
-#define DATA_ID (('d' << 8) + 'a') /* data block id */
-#define PTR_ID (('p' << 8) + 't') /* pointer block id */
-#define BLOCK0_ID0 'b' /* block 0 id 0 */
-#define BLOCK0_ID1 '0' /* block 0 id 1 */
+#define DATA_ID (('d' << 8) + 'a') // data block id
+#define PTR_ID (('p' << 8) + 't') // pointer block id
+#define BLOCK0_ID0 'b' // block 0 id 0
+#define BLOCK0_ID1 '0' // block 0 id 1
/*
* pointer to a block, used in a pointer block
*/
struct pointer_entry {
- blocknr_T pe_bnum; /* block number */
- linenr_T pe_line_count; /* number of lines in this branch */
- linenr_T pe_old_lnum; /* lnum for this block (for recovery) */
- int pe_page_count; /* number of pages in block pe_bnum */
+ blocknr_T pe_bnum; // block number
+ linenr_T pe_line_count; // number of lines in this branch
+ linenr_T pe_old_lnum; // lnum for this block (for recovery)
+ int pe_page_count; // number of pages in block pe_bnum
};
/*
* A pointer block contains a list of branches in the tree.
*/
struct pointer_block {
- uint16_t pb_id; /* ID for pointer block: PTR_ID */
- uint16_t pb_count; /* number of pointers in this block */
- uint16_t pb_count_max; /* maximum value for pb_count */
+ uint16_t pb_id; // ID for pointer block: PTR_ID
+ uint16_t pb_count; // number of pointers in this block
+ uint16_t pb_count_max; // maximum value for pb_count
PTR_EN pb_pointer[1]; /* list of pointers to blocks (actually longer)
* followed by empty space until end of page */
};
@@ -118,15 +118,15 @@ struct pointer_block {
* etc. Thus the order of the lines is the opposite of the line number.
*/
struct data_block {
- uint16_t db_id; /* ID for data block: DATA_ID */
- unsigned db_free; /* free space available */
- unsigned db_txt_start; /* byte where text starts */
- unsigned db_txt_end; /* byte just after data block */
- linenr_T db_line_count; /* number of lines in this block */
- unsigned db_index[1]; /* index for start of line (actually bigger)
- * followed by empty space upto db_txt_start
- * followed by the text in the lines until
- * end of page */
+ uint16_t db_id; // ID for data block: DATA_ID
+ unsigned db_free; // free space available
+ unsigned db_txt_start; // byte where text starts
+ unsigned db_txt_end; // byte just after data block
+ linenr_T db_line_count; // number of lines in this block
+ unsigned db_index[1]; // index for start of line (actually bigger)
+ // followed by empty space up to db_txt_start
+ // followed by the text in the lines until
+ // end of page
};
/*
@@ -140,12 +140,12 @@ struct data_block {
#define DB_MARKED ((unsigned)1 << ((sizeof(unsigned) * 8) - 1))
#define DB_INDEX_MASK (~DB_MARKED)
-#define INDEX_SIZE (sizeof(unsigned)) /* size of one db_index entry */
-#define HEADER_SIZE (sizeof(DATA_BL) - INDEX_SIZE) /* size of data block header */
+#define INDEX_SIZE (sizeof(unsigned)) // size of one db_index entry
+#define HEADER_SIZE (sizeof(DATA_BL) - INDEX_SIZE) // size of data block header
-#define B0_FNAME_SIZE_ORG 900 /* what it was in older versions */
-#define B0_FNAME_SIZE_NOCRYPT 898 /* 2 bytes used for other things */
-#define B0_FNAME_SIZE_CRYPT 890 /* 10 bytes used for other things */
+#define B0_FNAME_SIZE_ORG 900 // what it was in older versions
+#define B0_FNAME_SIZE_NOCRYPT 898 // 2 bytes used for other things
+#define B0_FNAME_SIZE_CRYPT 890 // 10 bytes used for other things
#define B0_UNAME_SIZE 40
#define B0_HNAME_SIZE 40
/*
@@ -172,18 +172,18 @@ struct data_block {
*/
struct block0 {
char_u b0_id[2]; ///< ID for block 0: BLOCK0_ID0 and BLOCK0_ID1.
- char_u b0_version[10]; /* Vim version string */
- char_u b0_page_size[4]; /* number of bytes per page */
- char_u b0_mtime[4]; /* last modification time of file */
- char_u b0_ino[4]; /* inode of b0_fname */
- char_u b0_pid[4]; /* process id of creator (or 0) */
- char_u b0_uname[B0_UNAME_SIZE]; /* name of user (uid if no name) */
- char_u b0_hname[B0_HNAME_SIZE]; /* host name (if it has a name) */
- char_u b0_fname[B0_FNAME_SIZE_ORG]; /* name of file being edited */
- long b0_magic_long; /* check for byte order of long */
- int b0_magic_int; /* check for byte order of int */
- short b0_magic_short; /* check for byte order of short */
- char_u b0_magic_char; /* check for last char */
+ char_u b0_version[10]; // Vim version string
+ char_u b0_page_size[4]; // number of bytes per page
+ char_u b0_mtime[4]; // last modification time of file
+ char_u b0_ino[4]; // inode of b0_fname
+ char_u b0_pid[4]; // process id of creator (or 0)
+ char_u b0_uname[B0_UNAME_SIZE]; // name of user (uid if no name)
+ char_u b0_hname[B0_HNAME_SIZE]; // host name (if it has a name)
+ char_u b0_fname[B0_FNAME_SIZE_ORG]; // name of file being edited
+ long b0_magic_long; // check for byte order of long
+ int b0_magic_int; // check for byte order of int
+ short b0_magic_short; // check for byte order of short
+ char_u b0_magic_char; // check for last char
};
/*
@@ -213,7 +213,7 @@ struct block0 {
* When empty there is only the NUL. */
#define B0_HAS_FENC 8
-#define STACK_INCR 5 /* nr of entries added to ml_stack at a time */
+#define STACK_INCR 5 // nr of entries added to ml_stack at a time
/*
* The line number where the first mark may be is remembered.
@@ -226,16 +226,16 @@ static linenr_T lowest_marked = 0;
/*
* arguments for ml_find_line()
*/
-#define ML_DELETE 0x11 /* delete line */
-#define ML_INSERT 0x12 /* insert line */
-#define ML_FIND 0x13 /* just find the line */
-#define ML_FLUSH 0x02 /* flush locked block */
-#define ML_SIMPLE(x) (x & 0x10) /* DEL, INS or FIND */
+#define ML_DELETE 0x11 // delete line
+#define ML_INSERT 0x12 // insert line
+#define ML_FIND 0x13 // just find the line
+#define ML_FLUSH 0x02 // flush locked block
+#define ML_SIMPLE(x) (x & 0x10) // DEL, INS or FIND
-/* argument for ml_upd_block0() */
+// argument for ml_upd_block0()
typedef enum {
- UB_FNAME = 0 /* update timestamp and filename */
- , UB_SAME_DIR /* update the B0_SAME_DIR flag */
+ UB_FNAME = 0 // update timestamp and filename
+ , UB_SAME_DIR // update the B0_SAME_DIR flag
} upd_block0_T;
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -249,10 +249,10 @@ typedef enum {
*/
int ml_open(buf_T *buf)
{
- bhdr_T *hp = NULL;
- ZERO_BL *b0p;
- PTR_BL *pp;
- DATA_BL *dp;
+ bhdr_T *hp = NULL;
+ ZERO_BL *b0p;
+ PTR_BL *pp;
+ DATA_BL *dp;
/*
* init fields in memline struct
@@ -264,6 +264,7 @@ int ml_open(buf_T *buf)
buf->b_ml.ml_line_lnum = 0; // no cached line
buf->b_ml.ml_line_offset = 0;
buf->b_ml.ml_chunksize = NULL;
+ buf->b_ml.ml_usedchunks = 0;
if (cmdmod.noswapfile) {
buf->b_p_swf = false;
@@ -306,7 +307,7 @@ int ml_open(buf_T *buf)
b0p->b0_magic_int = (int)B0_MAGIC_INT;
b0p->b0_magic_short = (short)B0_MAGIC_SHORT;
b0p->b0_magic_char = B0_MAGIC_CHAR;
- xstrlcpy(xstpcpy((char *) b0p->b0_version, "VIM "), Version, 6);
+ xstrlcpy(xstpcpy((char *)b0p->b0_version, "VIM "), Version, 6);
long_to_char((long)mfp->mf_page_size, b0p->b0_page_size);
if (!buf->b_spell) {
@@ -328,14 +329,16 @@ int ml_open(buf_T *buf)
* is created.
*/
mf_put(mfp, hp, true, false);
- if (!buf->b_help && !B_SPELL(buf))
+ if (!buf->b_help && !B_SPELL(buf)) {
(void)mf_sync(mfp, 0);
+ }
/*
* Fill in root pointer block and write page 1.
*/
- if ((hp = ml_new_ptr(mfp)) == NULL)
+ if ((hp = ml_new_ptr(mfp)) == NULL) {
goto error;
+ }
if (hp->bh_bnum != 1) {
IEMSG(_("E298: Didn't get block nr 1?"));
goto error;
@@ -345,7 +348,7 @@ int ml_open(buf_T *buf)
pp->pb_pointer[0].pe_bnum = 2;
pp->pb_pointer[0].pe_page_count = 1;
pp->pb_pointer[0].pe_old_lnum = 1;
- pp->pb_pointer[0].pe_line_count = 1; /* line count after insertion */
+ pp->pb_pointer[0].pe_line_count = 1; // line count after insertion
mf_put(mfp, hp, true, false);
/*
@@ -358,10 +361,10 @@ int ml_open(buf_T *buf)
}
dp = hp->bh_data;
- dp->db_index[0] = --dp->db_txt_start; /* at end of block */
+ dp->db_index[0] = --dp->db_txt_start; // at end of block
dp->db_free -= 1 + INDEX_SIZE;
dp->db_line_count = 1;
- *((char_u *)dp + dp->db_txt_start) = NUL; /* empty line */
+ *((char_u *)dp + dp->db_txt_start) = NUL; // empty line
return OK;
@@ -382,19 +385,19 @@ error:
*/
void ml_setname(buf_T *buf)
{
- int success = FALSE;
- memfile_T *mfp;
- char_u *fname;
- char_u *dirp;
+ bool success = false;
+ memfile_T *mfp;
+ char_u *fname;
+ char_u *dirp;
mfp = buf->b_ml.ml_mfp;
- if (mfp->mf_fd < 0) { /* there is no swap file yet */
+ if (mfp->mf_fd < 0) { // there is no swap file yet
/*
* When 'updatecount' is 0 and 'noswapfile' there is no swap file.
* For help files we will make a swap file now.
*/
if (p_uc != 0 && !cmdmod.noswapfile) {
- ml_open_file(buf); /* create a swap file */
+ ml_open_file(buf); // create a swap file
}
return;
}
@@ -405,50 +408,54 @@ void ml_setname(buf_T *buf)
dirp = p_dir;
bool found_existing_dir = false;
for (;; ) {
- if (*dirp == NUL) /* tried all directories, fail */
+ if (*dirp == NUL) { // tried all directories, fail
break;
+ }
fname = (char_u *)findswapname(buf, (char **)&dirp, (char *)mfp->mf_fname,
&found_existing_dir);
- /* alloc's fname */
- if (dirp == NULL) /* out of memory */
+ // alloc's fname
+ if (dirp == NULL) { // out of memory
break;
- if (fname == NULL) /* no file name found for this dir */
+ }
+ if (fname == NULL) { // no file name found for this dir
continue;
+ }
- /* if the file name is the same we don't have to do anything */
+ // if the file name is the same we don't have to do anything
if (fnamecmp(fname, mfp->mf_fname) == 0) {
xfree(fname);
- success = TRUE;
+ success = true;
break;
}
- /* need to close the swap file before renaming */
+ // need to close the swap file before renaming
if (mfp->mf_fd >= 0) {
close(mfp->mf_fd);
mfp->mf_fd = -1;
}
- /* try to rename the swap file */
+ // try to rename the swap file
if (vim_rename(mfp->mf_fname, fname) == 0) {
- success = TRUE;
+ success = true;
mf_free_fnames(mfp);
mf_set_fnames(mfp, fname);
ml_upd_block0(buf, UB_SAME_DIR);
break;
}
- xfree(fname); /* this fname didn't work, try another */
+ xfree(fname); // this fname didn't work, try another
}
- if (mfp->mf_fd == -1) { /* need to (re)open the swap file */
+ if (mfp->mf_fd == -1) { // need to (re)open the swap file
mfp->mf_fd = os_open((char *)mfp->mf_fname, O_RDWR, 0);
if (mfp->mf_fd < 0) {
- /* could not (re)open the swap file, what can we do???? */
+ // could not (re)open the swap file, what can we do????
EMSG(_("E301: Oops, lost the swap file!!!"));
return;
}
(void)os_set_cloexec(mfp->mf_fd);
}
- if (!success)
+ if (!success) {
EMSG(_("E302: Could not rename swap file"));
+ }
}
/*
@@ -472,21 +479,22 @@ void ml_open_files(void)
*/
void ml_open_file(buf_T *buf)
{
- memfile_T *mfp;
- char_u *fname;
- char_u *dirp;
+ memfile_T *mfp;
+ char_u *fname;
+ char_u *dirp;
mfp = buf->b_ml.ml_mfp;
if (mfp == NULL || mfp->mf_fd >= 0 || !buf->b_p_swf || cmdmod.noswapfile
|| buf->terminal) {
- return; /* nothing to do */
+ return; // nothing to do
}
- /* For a spell buffer use a temp file name. */
+ // For a spell buffer use a temp file name.
if (buf->b_spell) {
fname = vim_tempname();
- if (fname != NULL)
- (void)mf_open_file(mfp, fname); /* consumes fname! */
+ if (fname != NULL) {
+ (void)mf_open_file(mfp, fname); // consumes fname!
+ }
buf->b_may_swap = false;
return;
}
@@ -497,21 +505,24 @@ void ml_open_file(buf_T *buf)
dirp = p_dir;
bool found_existing_dir = false;
for (;; ) {
- if (*dirp == NUL)
+ if (*dirp == NUL) {
break;
+ }
// There is a small chance that between choosing the swap file name
// and creating it, another Vim creates the file. In that case the
// creation will fail and we will use another directory.
fname = (char_u *)findswapname(buf, (char **)&dirp, NULL,
&found_existing_dir);
- if (dirp == NULL)
- break; /* out of memory */
- if (fname == NULL)
+ if (dirp == NULL) {
+ break; // out of memory
+ }
+ if (fname == NULL) {
continue;
- if (mf_open_file(mfp, fname) == OK) { /* consumes fname! */
+ }
+ if (mf_open_file(mfp, fname) == OK) { // consumes fname!
ml_upd_block0(buf, UB_SAME_DIR);
- /* Flush block zero, so others can read it */
+ // Flush block zero, so others can read it
if (mf_sync(mfp, MFS_ZERO) == OK) {
/* Mark all blocks that should be in the swapfile as dirty.
* Needed for when the 'swapfile' option was reset, so that
@@ -519,7 +530,7 @@ void ml_open_file(buf_T *buf)
mf_set_dirty(mfp);
break;
}
- /* Writing block 0 failed: close the file and try another dir */
+ // Writing block 0 failed: close the file and try another dir
mf_close_file(buf, false);
}
}
@@ -527,13 +538,12 @@ void ml_open_file(buf_T *buf)
if (*p_dir != NUL && mfp->mf_fname == NULL) {
need_wait_return = true; // call wait_return later
no_wait_return++;
- (void)EMSG2(_(
- "E303: Unable to open swap file for \"%s\", recovery impossible"),
- buf_spname(buf) != NULL ? buf_spname(buf) : buf->b_fname);
+ (void)EMSG2(_("E303: Unable to open swap file for \"%s\", recovery impossible"),
+ buf_spname(buf) != NULL ? buf_spname(buf) : buf->b_fname);
--no_wait_return;
}
- /* don't try to open a swap file again */
+ // don't try to open a swap file again
buf->b_may_swap = false;
}
@@ -559,11 +569,13 @@ void check_need_swap(bool newfile)
*/
void ml_close(buf_T *buf, int del_file)
{
- if (buf->b_ml.ml_mfp == NULL) /* not open */
+ if (buf->b_ml.ml_mfp == NULL) { // not open
return;
- mf_close(buf->b_ml.ml_mfp, del_file); /* close the .swp file */
- if (buf->b_ml.ml_line_lnum != 0 && (buf->b_ml.ml_flags & ML_LINE_DIRTY))
+ }
+ mf_close(buf->b_ml.ml_mfp, del_file); // close the .swp file
+ if (buf->b_ml.ml_line_lnum != 0 && (buf->b_ml.ml_flags & ML_LINE_DIRTY)) {
xfree(buf->b_ml.ml_line_ptr);
+ }
xfree(buf->b_ml.ml_stack);
XFREE_CLEAR(buf->b_ml.ml_chunksize);
buf->b_ml.ml_mfp = NULL;
@@ -584,8 +596,8 @@ void ml_close_all(int del_file)
FOR_ALL_BUFFERS(buf) {
ml_close(buf, del_file && ((buf->b_flags & BF_PRESERVED) == 0));
}
- spell_delete_wordlist(); /* delete the internal wordlist */
- vim_deltempdir(); /* delete created temp directory */
+ spell_delete_wordlist(); // delete the internal wordlist
+ vim_deltempdir(); // delete created temp directory
}
/*
@@ -596,7 +608,7 @@ void ml_close_notmod(void)
{
FOR_ALL_BUFFERS(buf) {
if (!bufIsChanged(buf)) {
- ml_close(buf, TRUE); /* close all not-modified buffers */
+ ml_close(buf, TRUE); // close all not-modified buffers
}
}
}
@@ -632,13 +644,14 @@ static bool ml_check_b0_strings(ZERO_BL *b0p)
*/
static void ml_upd_block0(buf_T *buf, upd_block0_T what)
{
- memfile_T *mfp;
- bhdr_T *hp;
- ZERO_BL *b0p;
+ memfile_T *mfp;
+ bhdr_T *hp;
+ ZERO_BL *b0p;
mfp = buf->b_ml.ml_mfp;
- if (mfp == NULL || (hp = mf_get(mfp, 0, 1)) == NULL)
+ if (mfp == NULL || (hp = mf_get(mfp, 0, 1)) == NULL) {
return;
+ }
b0p = hp->bh_data;
if (ml_check_b0_id(b0p) == FAIL) {
IEMSG(_("E304: ml_upd_block0(): Didn't get block 0??"));
@@ -659,9 +672,9 @@ static void ml_upd_block0(buf_T *buf, upd_block0_T what)
*/
static void set_b0_fname(ZERO_BL *b0p, buf_T *buf)
{
- if (buf->b_ffname == NULL)
+ if (buf->b_ffname == NULL) {
b0p->b0_fname[0] = NUL;
- else {
+ } else {
char uname[B0_UNAME_SIZE];
/*
@@ -672,9 +685,9 @@ static void set_b0_fname(ZERO_BL *b0p, buf_T *buf)
* Then insert the user name to get "~user/".
*/
home_replace(NULL, buf->b_ffname, b0p->b0_fname,
- B0_FNAME_SIZE_CRYPT, TRUE);
+ B0_FNAME_SIZE_CRYPT, TRUE);
if (b0p->b0_fname[0] == '~') {
- /* If there is no user name or it is too long, don't use "~/" */
+ // If there is no user name or it is too long, don't use "~/"
int retval = os_get_user_name(uname, B0_UNAME_SIZE);
size_t ulen = STRLEN(uname);
size_t flen = STRLEN(b0p->b0_fname);
@@ -701,7 +714,7 @@ static void set_b0_fname(ZERO_BL *b0p, buf_T *buf)
}
}
- /* Also add the 'fileencoding' if there is room. */
+ // Also add the 'fileencoding' if there is room.
add_b0_fenc(b0p, curbuf);
}
@@ -713,10 +726,11 @@ static void set_b0_fname(ZERO_BL *b0p, buf_T *buf)
*/
static void set_b0_dir_flag(ZERO_BL *b0p, buf_T *buf)
{
- if (same_directory(buf->b_ml.ml_mfp->mf_fname, buf->b_ffname))
+ if (same_directory(buf->b_ml.ml_mfp->mf_fname, buf->b_ffname)) {
b0p->b0_flags |= B0_SAME_DIR;
- else
+ } else {
b0p->b0_flags &= ~B0_SAME_DIR;
+ }
}
/*
@@ -728,11 +742,11 @@ static void add_b0_fenc(ZERO_BL *b0p, buf_T *buf)
int size = B0_FNAME_SIZE_NOCRYPT;
n = (int)STRLEN(buf->b_p_fenc);
- if ((int)STRLEN(b0p->b0_fname) + n + 1 > size)
+ if ((int)STRLEN(b0p->b0_fname) + n + 1 > size) {
b0p->b0_flags &= ~B0_HAS_FENC;
- else {
+ } else {
memmove((char *)b0p->b0_fname + size - n,
- (char *)buf->b_p_fenc, (size_t)n);
+ (char *)buf->b_p_fenc, (size_t)n);
*(b0p->b0_fname + size - n - 1) = NUL;
b0p->b0_flags |= B0_HAS_FENC;
}
@@ -744,26 +758,26 @@ static void add_b0_fenc(ZERO_BL *b0p, buf_T *buf)
/// swap file.
void ml_recover(bool checkext)
{
- buf_T *buf = NULL;
- memfile_T *mfp = NULL;
- char_u *fname;
- char_u *fname_used = NULL;
- bhdr_T *hp = NULL;
- ZERO_BL *b0p;
+ buf_T *buf = NULL;
+ memfile_T *mfp = NULL;
+ char_u *fname;
+ char_u *fname_used = NULL;
+ bhdr_T *hp = NULL;
+ ZERO_BL *b0p;
int b0_ff;
- char_u *b0_fenc = NULL;
- PTR_BL *pp;
- DATA_BL *dp;
- infoptr_T *ip;
+ char_u *b0_fenc = NULL;
+ PTR_BL *pp;
+ DATA_BL *dp;
+ infoptr_T *ip;
blocknr_T bnum;
int page_count;
int len;
- int directly;
+ bool directly;
linenr_T lnum;
- char_u *p;
+ char_u *p;
int i;
long error;
- int cannot_open;
+ bool cannot_open;
linenr_T line_count;
bool has_error;
int idx;
@@ -771,7 +785,7 @@ void ml_recover(bool checkext)
int txt_start;
off_T size;
int called_from_main;
- int serious_error = TRUE;
+ bool serious_error = true;
long mtime;
int attr;
int orig_file_status = NOTDONE;
@@ -783,45 +797,48 @@ void ml_recover(bool checkext)
// If the file name ends in ".s[a-w][a-z]" we assume this is the swap file.
// Otherwise a search is done to find the swap file(s).
fname = curbuf->b_fname;
- if (fname == NULL) /* When there is no file name */
+ if (fname == NULL) { // When there is no file name
fname = (char_u *)"";
+ }
len = (int)STRLEN(fname);
if (checkext && len >= 4
&& STRNICMP(fname + len - 4, ".s", 2) == 0
&& vim_strchr((char_u *)"abcdefghijklmnopqrstuvw",
TOLOWER_ASC(fname[len - 2])) != NULL
&& ASCII_ISALPHA(fname[len - 1])) {
- directly = TRUE;
- fname_used = vim_strsave(fname); /* make a copy for mf_open() */
+ directly = true;
+ fname_used = vim_strsave(fname); // make a copy for mf_open()
} else {
- directly = FALSE;
+ directly = false;
- /* count the number of matching swap files */
+ // count the number of matching swap files
len = recover_names(fname, FALSE, 0, NULL);
- if (len == 0) { /* no swap files found */
+ if (len == 0) { // no swap files found
EMSG2(_("E305: No swap file found for %s"), fname);
goto theend;
}
- if (len == 1) /* one swap file found, use it */
+ if (len == 1) { // one swap file found, use it
i = 1;
- else { /* several swap files found, choose */
- /* list the names of the swap files */
+ } else { // several swap files found, choose
+ // list the names of the swap files
(void)recover_names(fname, TRUE, 0, NULL);
msg_putchar('\n');
MSG_PUTS(_("Enter number of swap file to use (0 to quit): "));
i = get_number(FALSE, NULL);
- if (i < 1 || i > len)
+ if (i < 1 || i > len) {
goto theend;
+ }
}
- /* get the swap file name that will be used */
+ // get the swap file name that will be used
(void)recover_names(fname, FALSE, i, &fname_used);
}
- if (fname_used == NULL)
+ if (fname_used == NULL) {
goto theend; // user chose invalid number.
-
- /* When called from main() still need to initialize storage structure */
- if (called_from_main && ml_open(curbuf) == FAIL)
+ }
+ // When called from main() still need to initialize storage structure
+ if (called_from_main && ml_open(curbuf) == FAIL) {
getout(1);
+ }
/*
* Allocate a buffer structure for the swap file that is used for recovery.
@@ -868,9 +885,8 @@ void ml_recover(bool checkext)
msg_start();
MSG_PUTS_ATTR(_("Unable to read block 0 from "), attr | MSG_HIST);
msg_outtrans_attr(mfp->mf_fname, attr | MSG_HIST);
- MSG_PUTS_ATTR(_(
- "\nMaybe no changes were made or Vim did not update the swap file."),
- attr | MSG_HIST);
+ MSG_PUTS_ATTR(_("\nMaybe no changes were made or Vim did not update the swap file."),
+ attr | MSG_HIST);
msg_end();
goto theend;
}
@@ -879,7 +895,7 @@ void ml_recover(bool checkext)
msg_start();
msg_outtrans_attr(mfp->mf_fname, MSG_HIST);
MSG_PUTS_ATTR(_(" cannot be used with this version of Vim.\n"),
- MSG_HIST);
+ MSG_HIST);
MSG_PUTS_ATTR(_("Use Vim version 3.0.\n"), MSG_HIST);
msg_end();
goto theend;
@@ -892,9 +908,9 @@ void ml_recover(bool checkext)
msg_start();
msg_outtrans_attr(mfp->mf_fname, attr | MSG_HIST);
MSG_PUTS_ATTR(_(" cannot be used on this computer.\n"),
- attr | MSG_HIST);
+ attr | MSG_HIST);
MSG_PUTS_ATTR(_("The file was created on "), attr | MSG_HIST);
- /* avoid going past the end of a corrupted hostname */
+ // avoid going past the end of a corrupted hostname
b0p->b0_fname[0] = NUL;
MSG_PUTS_ATTR(b0p->b0_hname, attr | MSG_HIST);
MSG_PUTS_ATTR(_(",\nor the file has been damaged."), attr | MSG_HIST);
@@ -913,9 +929,8 @@ void ml_recover(bool checkext)
if (mfp->mf_page_size < previous_page_size) {
msg_start();
msg_outtrans_attr(mfp->mf_fname, attr | MSG_HIST);
- MSG_PUTS_ATTR(_(
- " has been damaged (page size is smaller than minimum value).\n"),
- attr | MSG_HIST);
+ MSG_PUTS_ATTR(_(" has been damaged (page size is smaller than minimum value).\n"),
+ attr | MSG_HIST);
msg_end();
goto theend;
}
@@ -926,7 +941,7 @@ void ml_recover(bool checkext)
}
mfp->mf_infile_count = mfp->mf_blocknr_max;
- /* need to reallocate the memory used to store the data */
+ // need to reallocate the memory used to store the data
p = xmalloc(mfp->mf_page_size);
memmove(p, hp->bh_data, previous_page_size);
xfree(hp->bh_data);
@@ -947,10 +962,11 @@ void ml_recover(bool checkext)
home_replace(NULL, mfp->mf_fname, NameBuff, MAXPATHL, TRUE);
smsg(_("Using swap file \"%s\""), NameBuff);
- if (buf_spname(curbuf) != NULL)
+ if (buf_spname(curbuf) != NULL) {
STRLCPY(NameBuff, buf_spname(curbuf), MAXPATHL);
- else
+ } else {
home_replace(NULL, curbuf->b_ffname, NameBuff, MAXPATHL, TRUE);
+ }
smsg(_("Original file \"%s\""), NameBuff);
msg_putchar('\n');
@@ -964,13 +980,13 @@ void ml_recover(bool checkext)
&& os_fileinfo((char *)curbuf->b_ffname, &org_file_info)
&& ((os_fileinfo((char *)mfp->mf_fname, &swp_file_info)
&& org_file_info.stat.st_mtim.tv_sec
- > swp_file_info.stat.st_mtim.tv_sec)
+ > swp_file_info.stat.st_mtim.tv_sec)
|| org_file_info.stat.st_mtim.tv_sec != mtime)) {
EMSG(_("E308: Warning: Original file may have been changed"));
}
ui_flush();
- /* Get the 'fileformat' and 'fileencoding' from block zero. */
+ // Get the 'fileformat' and 'fileencoding' from block zero.
b0_ff = (b0p->b0_flags & B0_FF_MASK);
if (b0p->b0_flags & B0_HAS_FENC) {
int fnsize = B0_FNAME_SIZE_NOCRYPT;
@@ -980,7 +996,7 @@ void ml_recover(bool checkext)
b0_fenc = vim_strnsave(p, b0p->b0_fname + fnsize - p);
}
- mf_put(mfp, hp, false, false); /* release block 0 */
+ mf_put(mfp, hp, false, false); // release block 0
hp = NULL;
/*
@@ -995,39 +1011,42 @@ void ml_recover(bool checkext)
* Try reading the original file to obtain the values of 'fileformat',
* 'fileencoding', etc. Ignore errors. The text itself is not used.
*/
- if (curbuf->b_ffname != NULL)
+ if (curbuf->b_ffname != NULL) {
orig_file_status = readfile(curbuf->b_ffname, NULL, (linenr_T)0,
- (linenr_T)0, (linenr_T)MAXLNUM, NULL, READ_NEW);
+ (linenr_T)0, (linenr_T)MAXLNUM, NULL, READ_NEW);
+ }
- /* Use the 'fileformat' and 'fileencoding' as stored in the swap file. */
- if (b0_ff != 0)
+ // Use the 'fileformat' and 'fileencoding' as stored in the swap file.
+ if (b0_ff != 0) {
set_fileformat(b0_ff - 1, OPT_LOCAL);
+ }
if (b0_fenc != NULL) {
set_option_value("fenc", 0L, (char *)b0_fenc, OPT_LOCAL);
xfree(b0_fenc);
}
unchanged(curbuf, true, true);
- bnum = 1; /* start with block 1 */
- page_count = 1; /* which is 1 page */
- lnum = 0; /* append after line 0 in curbuf */
+ bnum = 1; // start with block 1
+ page_count = 1; // which is 1 page
+ lnum = 0; // append after line 0 in curbuf
line_count = 0;
- idx = 0; /* start with first index in block 1 */
+ idx = 0; // start with first index in block 1
error = 0;
buf->b_ml.ml_stack_top = 0;
buf->b_ml.ml_stack = NULL;
- buf->b_ml.ml_stack_size = 0; /* no stack yet */
+ buf->b_ml.ml_stack_size = 0; // no stack yet
- if (curbuf->b_ffname == NULL)
- cannot_open = TRUE;
- else
- cannot_open = FALSE;
+ if (curbuf->b_ffname == NULL) {
+ cannot_open = true;
+ } else {
+ cannot_open = false;
+ }
- serious_error = FALSE;
+ serious_error = false;
for (; !got_int; line_breakcheck()) {
- if (hp != NULL)
- mf_put(mfp, hp, false, false); /* release previous block */
-
+ if (hp != NULL) {
+ mf_put(mfp, hp, false, false); // release previous block
+ }
/*
* get block
*/
@@ -1041,11 +1060,12 @@ void ml_recover(bool checkext)
(colnr_T)0, true);
} else { // there is a block
pp = hp->bh_data;
- if (pp->pb_id == PTR_ID) { /* it is a pointer block */
- /* check line count when using pointer block first time */
+ if (pp->pb_id == PTR_ID) { // it is a pointer block
+ // check line count when using pointer block first time
if (idx == 0 && line_count != 0) {
- for (i = 0; i < (int)pp->pb_count; ++i)
+ for (i = 0; i < (int)pp->pb_count; ++i) {
line_count -= pp->pb_pointer[i].pe_line_count;
+ }
if (line_count != 0) {
++error;
ml_append(lnum++, (char_u *)_("???LINE COUNT WRONG"),
@@ -1079,7 +1099,7 @@ void ml_recover(bool checkext)
ml_append(lnum++, (char_u *)_("???LINES MISSING"),
(colnr_T)0, true);
}
- ++idx; /* get same block again for next index */
+ ++idx; // get same block again for next index
continue;
}
@@ -1097,12 +1117,12 @@ void ml_recover(bool checkext)
idx = 0;
continue;
}
- } else { /* not a pointer block */
+ } else { // not a pointer block
dp = hp->bh_data;
- if (dp->db_id != DATA_ID) { /* block id wrong */
+ if (dp->db_id != DATA_ID) { // block id wrong
if (bnum == 1) {
EMSG2(_("E310: Block 1 ID wrong (%s not a .swp file?)"),
- mfp->mf_fname);
+ mfp->mf_fname);
goto theend;
}
++error;
@@ -1115,17 +1135,16 @@ void ml_recover(bool checkext)
// check length of block
// if wrong, use length in pointer block
if (page_count * mfp->mf_page_size != dp->db_txt_end) {
- ml_append(
- lnum++,
- (char_u *)_("??? from here until ???END lines"
- " may be messed up"),
- (colnr_T)0, true);
+ ml_append(lnum++,
+ (char_u *)_("??? from here until ???END lines"
+ " may be messed up"),
+ (colnr_T)0, true);
error++;
has_error = true;
dp->db_txt_end = page_count * mfp->mf_page_size;
}
- /* make sure there is a NUL at the end of the block */
+ // make sure there is a NUL at the end of the block
*((char_u *)dp + dp->db_txt_end - 1) = NUL;
/*
@@ -1133,11 +1152,10 @@ void ml_recover(bool checkext)
* if wrong, use count in data block
*/
if (line_count != dp->db_line_count) {
- ml_append(
- lnum++,
- (char_u *)_("??? from here until ???END lines"
- " may have been inserted/deleted"),
- (colnr_T)0, true);
+ ml_append(lnum++,
+ (char_u *)_("??? from here until ???END lines"
+ " may have been inserted/deleted"),
+ (colnr_T)0, true);
error++;
has_error = true;
}
@@ -1148,8 +1166,9 @@ void ml_recover(bool checkext)
|| txt_start >= (int)dp->db_txt_end) {
p = (char_u *)"???";
++error;
- } else
+ } else {
p = (char_u *)dp + txt_start;
+ }
ml_append(lnum++, p, (colnr_T)0, true);
}
if (has_error) {
@@ -1159,15 +1178,16 @@ void ml_recover(bool checkext)
}
}
- if (buf->b_ml.ml_stack_top == 0) /* finished */
+ if (buf->b_ml.ml_stack_top == 0) { // finished
break;
+ }
/*
* go one block up in the tree
*/
ip = &(buf->b_ml.ml_stack[--(buf->b_ml.ml_stack_top)]);
bnum = ip->ip_bnum;
- idx = ip->ip_index + 1; /* go to next index */
+ idx = ip->ip_index + 1; // go to next index
page_count = 1;
}
@@ -1187,7 +1207,7 @@ void ml_recover(bool checkext)
}
} else {
for (idx = 1; idx <= lnum; ++idx) {
- /* Need to copy one line, fetching the other one may flush it. */
+ // Need to copy one line, fetching the other one may flush it.
p = vim_strsave(ml_get(idx));
i = STRCMP(p, ml_get(idx + lnum));
xfree(p);
@@ -1204,30 +1224,30 @@ void ml_recover(bool checkext)
* empty buffer. These will now be after the last line in the buffer.
*/
while (curbuf->b_ml.ml_line_count > lnum
- && !(curbuf->b_ml.ml_flags & ML_EMPTY))
+ && !(curbuf->b_ml.ml_flags & ML_EMPTY)) {
ml_delete(curbuf->b_ml.ml_line_count, false);
+ }
curbuf->b_flags |= BF_RECOVERED;
check_cursor();
recoverymode = FALSE;
- if (got_int)
+ if (got_int) {
EMSG(_("E311: Recovery Interrupted"));
- else if (error) {
+ } else if (error) {
++no_wait_return;
MSG(">>>>>>>>>>>>>");
- EMSG(_(
- "E312: Errors detected while recovering; look for lines starting with ???"));
+ EMSG(_( "E312: Errors detected while recovering; look for lines starting with ???"));
--no_wait_return;
MSG(_("See \":help E312\" for more information."));
MSG(">>>>>>>>>>>>>");
} else {
if (curbuf->b_changed) {
MSG(_("Recovery completed. You should check if everything is OK."));
- MSG_PUTS(_(
- "\n(You might want to write out this file under another name\n"));
+ MSG_PUTS(_("\n(You might want to write out this file under another name\n"));
MSG_PUTS(_("and run diff with the original file to check for changes)"));
- } else
+ } else {
MSG(_("Recovery completed. Buffer contents equals file contents."));
+ }
MSG_PUTS(_("\nYou may want to delete the .swp file now.\n\n"));
cmdline_row = msg_row;
}
@@ -1237,51 +1257,49 @@ theend:
xfree(fname_used);
recoverymode = FALSE;
if (mfp != NULL) {
- if (hp != NULL)
+ if (hp != NULL) {
mf_put(mfp, hp, false, false);
- mf_close(mfp, false); /* will also xfree(mfp->mf_fname) */
+ }
+ mf_close(mfp, false); // will also xfree(mfp->mf_fname)
}
if (buf != NULL) { //may be NULL if swap file not found.
xfree(buf->b_ml.ml_stack);
xfree(buf);
}
- if (serious_error && called_from_main)
+ if (serious_error && called_from_main) {
ml_close(curbuf, TRUE);
- else {
+ } else {
apply_autocmds(EVENT_BUFREADPOST, NULL, curbuf->b_fname, FALSE, curbuf);
apply_autocmds(EVENT_BUFWINENTER, NULL, curbuf->b_fname, FALSE, curbuf);
}
return;
}
-/*
- * Find the names of swap files in current directory and the directory given
- * with the 'directory' option.
- *
- * Used to:
- * - list the swap files for "vim -r"
- * - count the number of swap files when recovering
- * - list the swap files when recovering
- * - find the name of the n'th swap file when recovering
- */
-int
-recover_names (
- char_u *fname, /* base for swap file name */
- int list, /* when TRUE, list the swap file names */
- int nr, /* when non-zero, return nr'th swap file name */
- char_u **fname_out /* result when "nr" > 0 */
-)
+/// Find the names of swap files in current directory and the directory given
+/// with the 'directory' option.
+///
+/// Used to:
+/// - list the swap files for "vim -r"
+/// - count the number of swap files when recovering
+/// - list the swap files when recovering
+/// - find the name of the n'th swap file when recovering
+///
+/// @param fname base for swap file name
+/// @param list when TRUE, list the swap file names
+/// @param nr when non-zero, return nr'th swap file name
+/// @param fname_out result when "nr" > 0
+int recover_names(char_u *fname, int list, int nr, char_u **fname_out)
{
int num_names;
- char_u *(names[6]);
- char_u *tail;
- char_u *p;
+ char_u *(names[6]);
+ char_u *tail;
+ char_u *p;
int num_files;
int file_count = 0;
- char_u **files;
- char_u *dirp;
- char_u *dir_name;
- char_u *fname_res = NULL;
+ char_u **files;
+ char_u *dirp;
+ char_u *dir_name;
+ char_u *fname_res = NULL;
#ifdef HAVE_READLINK
char_u fname_buf[MAXPATHL];
#endif
@@ -1290,15 +1308,15 @@ recover_names (
#ifdef HAVE_READLINK
/* Expand symlink in the file name, because the swap file is created
* with the actual file instead of with the symlink. */
- if (resolve_symlink(fname, fname_buf) == OK)
+ if (resolve_symlink(fname, fname_buf) == OK) {
fname_res = fname_buf;
- else
+ } else
#endif
fname_res = fname;
}
if (list) {
- /* use msg() to start the scrolling properly */
+ // use msg() to start the scrolling properly
msg((char_u *)_("Swap files found:"));
msg_putchar('\n');
}
@@ -1313,7 +1331,7 @@ recover_names (
// Advance dirp to next directory name.
(void)copy_option_part(&dirp, dir_name, 31000, ",");
- if (dir_name[0] == '.' && dir_name[1] == NUL) { /* check current dir */
+ if (dir_name[0] == '.' && dir_name[1] == NUL) { // check current dir
if (fname == NULL) {
names[0] = vim_strsave((char_u *)"*.sw?");
/* For Unix names starting with a dot are special. MS-Windows
@@ -1321,9 +1339,10 @@ recover_names (
names[1] = vim_strsave((char_u *)".*.sw?");
names[2] = vim_strsave((char_u *)".sw?");
num_names = 3;
- } else
+ } else {
num_names = recov_file_names(names, fname_res, TRUE);
- } else { /* check directory dir_name */
+ }
+ } else { // check directory dir_name
if (fname == NULL) {
names[0] = (char_u *)concat_fnames((char *)dir_name, "*.sw?", TRUE);
/* For Unix names starting with a dot are special. MS-Windows
@@ -1349,11 +1368,12 @@ recover_names (
}
}
- if (num_names == 0)
+ if (num_names == 0) {
num_files = 0;
- else if (expand_wildcards(num_names, names, &num_files, &files,
- EW_KEEPALL|EW_FILE|EW_SILENT) == FAIL)
+ } else if (expand_wildcards(num_names, names, &num_files, &files,
+ EW_KEEPALL|EW_FILE|EW_SILENT) == FAIL) {
num_files = 0;
+ }
/*
* When no swap file found, wildcard expansion might have failed (e.g.
@@ -1386,27 +1406,29 @@ recover_names (
// down. When the array becomes empty free it here, since
// FreeWild() won't be called below.
xfree(files[i]);
- if (--num_files == 0)
+ if (--num_files == 0) {
xfree(files);
- else
- for (; i < num_files; ++i)
+ } else {
+ for (; i < num_files; ++i) {
files[i] = files[i + 1];
+ }
+ }
}
}
}
if (nr > 0) {
file_count += num_files;
if (nr <= file_count) {
- *fname_out = vim_strsave(
- files[nr - 1 + num_files - file_count]);
- dirp = (char_u *)""; /* stop searching */
+ *fname_out = vim_strsave(files[nr - 1 + num_files - file_count]);
+ dirp = (char_u *)""; // stop searching
}
} else if (list) {
if (dir_name[0] == '.' && dir_name[1] == NUL) {
- if (fname == NULL)
+ if (fname == NULL) {
MSG_PUTS(_(" In current directory:\n"));
- else
+ } else {
MSG_PUTS(_(" Using specified name:\n"));
+ }
} else {
MSG_PUTS(_(" In directory "));
msg_home_replace(dir_name);
@@ -1415,23 +1437,27 @@ recover_names (
if (num_files) {
for (int i = 0; i < num_files; ++i) {
- /* print the swap file name */
+ // print the swap file name
msg_outnum((long)++file_count);
msg_puts(". ");
msg_puts((const char *)path_tail(files[i]));
msg_putchar('\n');
(void)swapfile_info(files[i]);
}
- } else
+ } else {
MSG_PUTS(_(" -- none --\n"));
+ }
ui_flush();
- } else
+ } else {
file_count += num_files;
+ }
- for (int i = 0; i < num_names; ++i)
+ for (int i = 0; i < num_names; ++i) {
xfree(names[i]);
- if (num_files > 0)
+ }
+ if (num_files > 0) {
FreeWild(num_files, files);
+ }
}
xfree(dir_name);
return file_count;
@@ -1441,7 +1467,7 @@ recover_names (
* Append the full path to name with path separators made into percent
* signs, to dir. An unnamed buffer is handled as "" (<currentdir>/"")
*/
-char *make_percent_swname(const char *dir, char *name)
+char *make_percent_swname(const char *dir, const char *name)
FUNC_ATTR_NONNULL_ARG(1)
{
char *d = NULL;
@@ -1542,10 +1568,11 @@ static time_t swapfile_info(char_u *fname)
MSG_PUTS(_(" [garbled strings (not nul terminated)]"));
} else {
MSG_PUTS(_(" file name: "));
- if (b0.b0_fname[0] == NUL)
+ if (b0.b0_fname[0] == NUL) {
MSG_PUTS(_("[No Name]"));
- else
+ } else {
msg_outtrans(b0.b0_fname);
+ }
MSG_PUTS(_("\n modified: "));
MSG_PUTS(b0.b0_dirty ? _("YES") : _("no"));
@@ -1556,10 +1583,11 @@ static time_t swapfile_info(char_u *fname)
}
if (*(b0.b0_hname) != NUL) {
- if (*(b0.b0_uname) != NUL)
+ if (*(b0.b0_uname) != NUL) {
MSG_PUTS(_(" host name: "));
- else
+ } else {
MSG_PUTS(_("\n host name: "));
+ }
msg_outtrans(b0.b0_hname);
}
@@ -1576,11 +1604,13 @@ static time_t swapfile_info(char_u *fname)
MSG_PUTS(_("\n [not usable on this computer]"));
}
}
- } else
+ } else {
MSG_PUTS(_(" [cannot be read]"));
+ }
close(fd);
- } else
+ } else {
MSG_PUTS(_(" [cannot be opened]"));
+ }
msg_putchar('\n');
return x;
@@ -1648,18 +1678,20 @@ static int recov_file_names(char_u **names, char_u *path, int prepend_dot)
// Form the normal swap file name pattern by appending ".sw?".
names[num_names] = (char_u *)concat_fnames((char *)path, ".sw?", FALSE);
- if (num_names >= 1) { /* check if we have the same name twice */
+ if (num_names >= 1) { // check if we have the same name twice
char_u *p = names[num_names - 1];
int i = (int)STRLEN(names[num_names - 1]) - (int)STRLEN(names[num_names]);
- if (i > 0)
- p += i; /* file name has been expanded to full path */
-
- if (STRCMP(p, names[num_names]) != 0)
+ if (i > 0) {
+ p += i; // file name has been expanded to full path
+ }
+ if (STRCMP(p, names[num_names]) != 0) {
++num_names;
- else
+ } else {
xfree(names[num_names]);
- } else
+ }
+ } else {
++num_names;
+ }
return num_names;
}
@@ -1674,11 +1706,11 @@ static int recov_file_names(char_u **names, char_u *path, int prepend_dot)
void ml_sync_all(int check_file, int check_char, bool do_fsync)
{
FOR_ALL_BUFFERS(buf) {
- if (buf->b_ml.ml_mfp == NULL || buf->b_ml.ml_mfp->mf_fname == NULL)
- continue; /* no file */
-
- ml_flush_line(buf); /* flush buffered line */
- /* flush locked block */
+ if (buf->b_ml.ml_mfp == NULL || buf->b_ml.ml_mfp->mf_fname == NULL) {
+ continue; // no file
+ }
+ ml_flush_line(buf); // flush buffered line
+ // flush locked block
(void)ml_find_line(buf, (linenr_T)0, ML_FLUSH);
if (bufIsChanged(buf) && check_file && mf_need_trans(buf->b_ml.ml_mfp)
&& buf->b_ffname != NULL) {
@@ -1717,15 +1749,16 @@ void ml_sync_all(int check_file, int check_char, bool do_fsync)
*/
void ml_preserve(buf_T *buf, int message, bool do_fsync)
{
- bhdr_T *hp;
+ bhdr_T *hp;
linenr_T lnum;
- memfile_T *mfp = buf->b_ml.ml_mfp;
+ memfile_T *mfp = buf->b_ml.ml_mfp;
int status;
int got_int_save = got_int;
if (mfp == NULL || mfp->mf_fname == NULL) {
- if (message)
+ if (message) {
EMSG(_("E313: Cannot preserve, there is no swap file"));
+ }
return;
}
@@ -1737,7 +1770,7 @@ void ml_preserve(buf_T *buf, int message, bool do_fsync)
(void)ml_find_line(buf, (linenr_T)0, ML_FLUSH); // flush locked block
status = mf_sync(mfp, MFS_ALL | (do_fsync ? MFS_FLUSH : 0));
- /* stack is invalid after mf_sync(.., MFS_ALL) */
+ // stack is invalid after mf_sync(.., MFS_ALL)
buf->b_ml.ml_stack_top = 0;
/*
@@ -1774,10 +1807,11 @@ theend:
got_int |= got_int_save;
if (message) {
- if (status == OK)
+ if (status == OK) {
MSG(_("File preserved"));
- else
+ } else {
EMSG(_("E314: Preserve failed"));
+ }
}
}
@@ -1785,7 +1819,7 @@ theend:
* NOTE: The pointer returned by the ml_get_*() functions only remains valid
* until the next call!
* line1 = ml_get(1);
- * line2 = ml_get(2); // line1 is now invalid!
+ * line2 = ml_get(2); // line1 is now invalid!
* Make a copy of the line if necessary.
*/
/*
@@ -1796,7 +1830,7 @@ theend:
*/
char_u *ml_get(linenr_T lnum)
{
- return ml_get_buf(curbuf, lnum, FALSE);
+ return ml_get_buf(curbuf, lnum, false);
}
/*
@@ -1808,26 +1842,18 @@ char_u *ml_get_pos(const pos_T *pos)
return ml_get_buf(curbuf, pos->lnum, false) + pos->col;
}
-/*
- * Return a pointer to a line in a specific buffer
- *
- * "will_change": if TRUE mark the buffer dirty (chars in the line will be
- * changed)
- */
-char_u *
-ml_get_buf (
- buf_T *buf,
- linenr_T lnum,
- bool will_change // line will be changed
-)
+/// Return a pointer to a line in a specific buffer
+///
+/// @param will_change true mark the buffer dirty (chars in the line will be changed)
+char_u *ml_get_buf(buf_T *buf, linenr_T lnum, bool will_change)
FUNC_ATTR_NONNULL_ALL
{
- bhdr_T *hp;
- DATA_BL *dp;
- char_u *ptr;
+ bhdr_T *hp;
+ DATA_BL *dp;
+ char_u *ptr;
static int recursive = 0;
- if (lnum > buf->b_ml.ml_line_count) { /* invalid line number */
+ if (lnum > buf->b_ml.ml_line_count) { // invalid line number
if (recursive == 0) {
// Avoid giving this message for a recursive call, may happen when
// the GUI redraws part of the text.
@@ -1839,11 +1865,13 @@ errorret:
STRCPY(IObuff, "???");
return IObuff;
}
- if (lnum <= 0) /* pretend line 0 is line 1 */
+ if (lnum <= 0) { // pretend line 0 is line 1
lnum = 1;
+ }
- if (buf->b_ml.ml_mfp == NULL) /* there are no lines */
+ if (buf->b_ml.ml_mfp == NULL) { // there are no lines
return (char_u *)"";
+ }
/*
* See if it is the same line as requested last time.
@@ -1898,88 +1926,89 @@ int ml_line_alloced(void)
return curbuf->b_ml.ml_flags & ML_LINE_DIRTY;
}
-/*
- * Append a line after lnum (may be 0 to insert a line in front of the file).
- * "line" does not need to be allocated, but can't be another line in a
- * buffer, unlocking may make it invalid.
- *
- * newfile: TRUE when starting to edit a new file, meaning that pe_old_lnum
- * will be set for recovery
- * Check: The caller of this function should probably also call
- * appended_lines().
- *
- * return FAIL for failure, OK otherwise
- */
-int ml_append(
- linenr_T lnum, // append after this line (can be 0)
- char_u *line, // text of the new line
- colnr_T len, // length of new line, including NUL, or 0
- bool newfile // flag, see above
-)
+/// Append a line after lnum (may be 0 to insert a line in front of the file).
+/// "line" does not need to be allocated, but can't be another line in a
+/// buffer, unlocking may make it invalid.
+///
+/// newfile: TRUE when starting to edit a new file, meaning that pe_old_lnum
+/// will be set for recovery
+/// Check: The caller of this function should probably also call
+/// appended_lines().
+///
+/// @param lnum append after this line (can be 0)
+/// @param line text of the new line
+/// @param len length of new line, including NUL, or 0
+/// @param newfile flag, see above
+///
+/// @return FAIL for failure, OK otherwise
+int ml_append(linenr_T lnum, char_u *line, colnr_T len, bool newfile)
{
- /* When starting up, we might still need to create the memfile */
- if (curbuf->b_ml.ml_mfp == NULL && open_buffer(FALSE, NULL, 0) == FAIL)
+ // When starting up, we might still need to create the memfile
+ if (curbuf->b_ml.ml_mfp == NULL && open_buffer(FALSE, NULL, 0) == FAIL) {
return FAIL;
+ }
- if (curbuf->b_ml.ml_line_lnum != 0)
+ if (curbuf->b_ml.ml_line_lnum != 0) {
ml_flush_line(curbuf);
+ }
return ml_append_int(curbuf, lnum, line, len, newfile, FALSE);
}
-/*
- * Like ml_append() but for an arbitrary buffer. The buffer must already have
- * a memline.
- */
-int ml_append_buf(
- buf_T *buf,
- linenr_T lnum, // append after this line (can be 0)
- char_u *line, // text of the new line
- colnr_T len, // length of new line, including NUL, or 0
- bool newfile // flag, see above
-)
+/// Like ml_append() but for an arbitrary buffer. The buffer must already have
+/// a memline.
+///
+/// @param lnum append after this line (can be 0)
+/// @param line text of the new line
+/// @param len length of new line, including NUL, or 0
+/// @param newfile flag, see above
+int ml_append_buf(buf_T *buf, linenr_T lnum, char_u *line, colnr_T len, bool newfile)
FUNC_ATTR_NONNULL_ARG(1)
{
- if (buf->b_ml.ml_mfp == NULL)
+ if (buf->b_ml.ml_mfp == NULL) {
return FAIL;
+ }
- if (buf->b_ml.ml_line_lnum != 0)
+ if (buf->b_ml.ml_line_lnum != 0) {
ml_flush_line(buf);
+ }
return ml_append_int(buf, lnum, line, len, newfile, FALSE);
}
-static int ml_append_int(
- buf_T *buf,
- linenr_T lnum, // append after this line (can be 0)
- char_u *line, // text of the new line
- colnr_T len, // length of line, including NUL, or 0
- bool newfile, // flag, see above
- int mark // mark the new line
-)
+/// @param lnum append after this line (can be 0)
+/// @param line text of the new line
+/// @param len length of line, including NUL, or 0
+/// @param newfile flag, see above
+/// @param mark mark the new line
+static int ml_append_int(buf_T *buf, linenr_T lnum, char_u *line, colnr_T len, bool newfile,
+ int mark)
{
int i;
- int line_count; /* number of indexes in current block */
+ int line_count; // number of indexes in current block
int offset;
int from, to;
- int space_needed; /* space needed for new line */
+ int space_needed; // space needed for new line
int page_size;
int page_count;
- int db_idx; /* index for lnum in data block */
- bhdr_T *hp;
- memfile_T *mfp;
- DATA_BL *dp;
- PTR_BL *pp;
- infoptr_T *ip;
-
- /* lnum out of range */
- if (lnum > buf->b_ml.ml_line_count || buf->b_ml.ml_mfp == NULL)
+ int db_idx; // index for lnum in data block
+ bhdr_T *hp;
+ memfile_T *mfp;
+ DATA_BL *dp;
+ PTR_BL *pp;
+ infoptr_T *ip;
+
+ // lnum out of range
+ if (lnum > buf->b_ml.ml_line_count || buf->b_ml.ml_mfp == NULL) {
return FAIL;
+ }
- if (lowest_marked && lowest_marked > lnum)
+ if (lowest_marked && lowest_marked > lnum) {
lowest_marked = lnum + 1;
+ }
- if (len == 0)
- len = (colnr_T)STRLEN(line) + 1; /* space needed for the text */
- space_needed = len + INDEX_SIZE; /* space needed for text + index */
+ if (len == 0) {
+ len = (colnr_T)STRLEN(line) + 1; // space needed for the text
+ }
+ space_needed = len + INDEX_SIZE; // space needed for text + index
mfp = buf->b_ml.ml_mfp;
page_size = mfp->mf_page_size;
@@ -1990,16 +2019,18 @@ static int ml_append_int(
* This also releases any locked block.
*/
if ((hp = ml_find_line(buf, lnum == 0 ? (linenr_T)1 : lnum,
- ML_INSERT)) == NULL)
+ ML_INSERT)) == NULL) {
return FAIL;
+ }
buf->b_ml.ml_flags &= ~ML_EMPTY;
- if (lnum == 0) /* got line one instead, correct db_idx */
- db_idx = -1; /* careful, it is negative! */
- else
+ if (lnum == 0) { // got line one instead, correct db_idx
+ db_idx = -1; // careful, it is negative!
+ } else {
db_idx = lnum - buf->b_ml.ml_locked_low;
- /* get line count before the insertion */
+ }
+ // get line count before the insertion
line_count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low;
dp = hp->bh_data;
@@ -2020,11 +2051,12 @@ static int ml_append_int(
*/
--(buf->b_ml.ml_locked_lineadd);
--(buf->b_ml.ml_locked_high);
- if ((hp = ml_find_line(buf, lnum + 1, ML_INSERT)) == NULL)
+ if ((hp = ml_find_line(buf, lnum + 1, ML_INSERT)) == NULL) {
return FAIL;
+ }
- db_idx = -1; /* careful, it is negative! */
- /* get line count before the insertion */
+ db_idx = -1; // careful, it is negative!
+ // get line count before the insertion
line_count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low;
CHECK(buf->b_ml.ml_locked_low != lnum + 1, "locked_low != lnum + 1");
@@ -2033,7 +2065,7 @@ static int ml_append_int(
++buf->b_ml.ml_line_count;
- if ((int)dp->db_free >= space_needed) { /* enough room in data block */
+ if ((int)dp->db_free >= space_needed) { // enough room in data block
/*
* Insert new line in existing data block, or in data block allocated above.
*/
@@ -2045,38 +2077,43 @@ static int ml_append_int(
* move the text of the lines that follow to the front
* adjust the indexes of the lines that follow
*/
- if (line_count > db_idx + 1) { /* if there are following lines */
+ if (line_count > db_idx + 1) { // if there are following lines
/*
* Offset is the start of the previous line.
* This will become the character just after the new line.
*/
- if (db_idx < 0)
+ if (db_idx < 0) {
offset = dp->db_txt_end;
- else
+ } else {
offset = ((dp->db_index[db_idx]) & DB_INDEX_MASK);
+ }
memmove((char *)dp + dp->db_txt_start,
- (char *)dp + dp->db_txt_start + len,
- (size_t)(offset - (dp->db_txt_start + len)));
- for (i = line_count - 1; i > db_idx; --i)
+ (char *)dp + dp->db_txt_start + len,
+ (size_t)(offset - (dp->db_txt_start + len)));
+ for (i = line_count - 1; i > db_idx; --i) {
dp->db_index[i + 1] = dp->db_index[i] - len;
+ }
dp->db_index[db_idx + 1] = offset - len;
- } else /* add line at the end */
+ } else { // add line at the end
dp->db_index[db_idx + 1] = dp->db_txt_start;
+ }
/*
* copy the text into the block
*/
memmove((char *)dp + dp->db_index[db_idx + 1], line, (size_t)len);
- if (mark)
+ if (mark) {
dp->db_index[db_idx + 1] |= DB_MARKED;
+ }
/*
* Mark the block dirty.
*/
buf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
- if (!newfile)
+ if (!newfile) {
buf->b_ml.ml_flags |= ML_LOCKED_POS;
- } else { /* not enough space in data block */
+ }
+ } else { // not enough space in data block
/*
* If there is not enough room we have to create a new data block and copy some
* lines into it.
@@ -2088,20 +2125,20 @@ static int ml_append_int(
*/
long line_count_left, line_count_right;
int page_count_left, page_count_right;
- bhdr_T *hp_left;
- bhdr_T *hp_right;
- bhdr_T *hp_new;
+ bhdr_T *hp_left;
+ bhdr_T *hp_right;
+ bhdr_T *hp_new;
int lines_moved;
- int data_moved = 0; /* init to shut up gcc */
- int total_moved = 0; /* init to shut up gcc */
- DATA_BL *dp_right, *dp_left;
+ int data_moved = 0; // init to shut up gcc
+ int total_moved = 0; // init to shut up gcc
+ DATA_BL *dp_right, *dp_left;
int stack_idx;
- int in_left;
+ bool in_left;
int lineadd;
blocknr_T bnum_left, bnum_right;
linenr_T lnum_left, lnum_right;
int pb_idx;
- PTR_BL *pp_new;
+ PTR_BL *pp_new;
/*
* We are going to allocate a new data block. Depending on the
@@ -2111,24 +2148,24 @@ static int ml_append_int(
* also put in the right block. This method is more efficient when
* inserting a lot of lines at one place.
*/
- if (db_idx < 0) { /* left block is new, right block is existing */
+ if (db_idx < 0) { // left block is new, right block is existing
lines_moved = 0;
- in_left = TRUE;
- /* space_needed does not change */
- } else { /* left block is existing, right block is new */
+ in_left = true;
+ // space_needed does not change
+ } else { // left block is existing, right block is new
lines_moved = line_count - db_idx - 1;
- if (lines_moved == 0)
- in_left = FALSE; /* put new line in right block */
- /* space_needed does not change */
- else {
+ if (lines_moved == 0) {
+ in_left = false; // put new line in right block
+ // space_needed does not change
+ } else {
data_moved = ((dp->db_index[db_idx]) & DB_INDEX_MASK) -
dp->db_txt_start;
total_moved = data_moved + lines_moved * INDEX_SIZE;
if ((int)dp->db_free + total_moved >= space_needed) {
- in_left = TRUE; /* put new line in left block */
+ in_left = true; // put new line in left block
space_needed = total_moved;
} else {
- in_left = FALSE; /* put new line in right block */
+ in_left = false; // put new line in right block
space_needed += total_moved;
}
}
@@ -2136,12 +2173,12 @@ static int ml_append_int(
page_count = ((space_needed + HEADER_SIZE) + page_size - 1) / page_size;
hp_new = ml_new_data(mfp, newfile, page_count);
- if (db_idx < 0) { /* left block is new */
+ if (db_idx < 0) { // left block is new
hp_left = hp_new;
hp_right = hp;
line_count_left = 0;
line_count_right = line_count;
- } else { /* right block is new */
+ } else { // right block is new
hp_left = hp;
hp_right = hp_new;
line_count_left = line_count;
@@ -2161,11 +2198,12 @@ static int ml_append_int(
dp_right->db_txt_start -= len;
dp_right->db_free -= len + INDEX_SIZE;
dp_right->db_index[0] = dp_right->db_txt_start;
- if (mark)
+ if (mark) {
dp_right->db_index[0] |= DB_MARKED;
+ }
memmove((char *)dp_right + dp_right->db_txt_start,
- line, (size_t)len);
+ line, (size_t)len);
++line_count_right;
}
/*
@@ -2177,8 +2215,8 @@ static int ml_append_int(
dp_right->db_txt_start -= data_moved;
dp_right->db_free -= total_moved;
memmove((char *)dp_right + dp_right->db_txt_start,
- (char *)dp_left + dp_left->db_txt_start,
- (size_t)data_moved);
+ (char *)dp_left + dp_left->db_txt_start,
+ (size_t)data_moved);
offset = dp_right->db_txt_start - dp_left->db_txt_start;
dp_left->db_txt_start += data_moved;
dp_left->db_free += total_moved;
@@ -2187,8 +2225,9 @@ static int ml_append_int(
* update indexes in the new block
*/
for (to = line_count_right, from = db_idx + 1;
- from < line_count_left; ++from, ++to)
+ from < line_count_left; ++from, ++to) {
dp_right->db_index[to] = dp->db_index[from] + offset;
+ }
line_count_right += lines_moved;
line_count_left -= lines_moved;
}
@@ -2200,22 +2239,24 @@ static int ml_append_int(
dp_left->db_txt_start -= len;
dp_left->db_free -= len + INDEX_SIZE;
dp_left->db_index[line_count_left] = dp_left->db_txt_start;
- if (mark)
+ if (mark) {
dp_left->db_index[line_count_left] |= DB_MARKED;
+ }
memmove((char *)dp_left + dp_left->db_txt_start,
- line, (size_t)len);
+ line, (size_t)len);
++line_count_left;
}
- if (db_idx < 0) { /* left block is new */
+ if (db_idx < 0) { // left block is new
lnum_left = lnum + 1;
lnum_right = 0;
- } else { /* right block is new */
+ } else { // right block is new
lnum_left = 0;
- if (in_left)
+ if (in_left) {
lnum_right = lnum + 2;
- else
+ } else {
lnum_right = lnum + 1;
+ }
}
dp_left->db_line_count = line_count_left;
dp_right->db_line_count = line_count_right;
@@ -2226,10 +2267,12 @@ static int ml_append_int(
* The old one (hp, in ml_locked) gets a positive blocknumber if
* we changed it and we are not editing a new file.
*/
- if (lines_moved || in_left)
+ if (lines_moved || in_left) {
buf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
- if (!newfile && db_idx >= 0 && in_left)
+ }
+ if (!newfile && db_idx >= 0 && in_left) {
buf->b_ml.ml_flags |= ML_LOCKED_POS;
+ }
mf_put(mfp, hp_new, true, false);
/*
@@ -2248,9 +2291,10 @@ static int ml_append_int(
--stack_idx) {
ip = &(buf->b_ml.ml_stack[stack_idx]);
pb_idx = ip->ip_index;
- if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL)
+ if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL) {
return FAIL;
- pp = hp->bh_data; /* must be pointer block */
+ }
+ pp = hp->bh_data; // must be pointer block
if (pp->pb_id != PTR_ID) {
IEMSG(_("E317: pointer block id wrong 3"));
mf_put(mfp, hp, false, false);
@@ -2260,12 +2304,13 @@ static int ml_append_int(
* TODO: If the pointer block is full and we are adding at the end
* try to insert in front of the next block
*/
- /* block not full, add one entry */
+ // block not full, add one entry
if (pp->pb_count < pp->pb_count_max) {
- if (pb_idx + 1 < (int)pp->pb_count)
+ if (pb_idx + 1 < (int)pp->pb_count) {
memmove(&pp->pb_pointer[pb_idx + 2],
- &pp->pb_pointer[pb_idx + 1],
- (size_t)(pp->pb_count - pb_idx - 1) * sizeof(PTR_EN));
+ &pp->pb_pointer[pb_idx + 1],
+ (size_t)(pp->pb_count - pb_idx - 1) * sizeof(PTR_EN));
+ }
++pp->pb_count;
pp->pb_pointer[pb_idx].pe_line_count = line_count_left;
pp->pb_pointer[pb_idx].pe_bnum = bnum_left;
@@ -2274,19 +2319,21 @@ static int ml_append_int(
pp->pb_pointer[pb_idx + 1].pe_bnum = bnum_right;
pp->pb_pointer[pb_idx + 1].pe_page_count = page_count_right;
- if (lnum_left != 0)
+ if (lnum_left != 0) {
pp->pb_pointer[pb_idx].pe_old_lnum = lnum_left;
- if (lnum_right != 0)
+ }
+ if (lnum_right != 0) {
pp->pb_pointer[pb_idx + 1].pe_old_lnum = lnum_right;
+ }
mf_put(mfp, hp, true, false);
- buf->b_ml.ml_stack_top = stack_idx + 1; /* truncate stack */
+ buf->b_ml.ml_stack_top = stack_idx + 1; // truncate stack
if (lineadd) {
--(buf->b_ml.ml_stack_top);
- /* fix line count for rest of blocks in the stack */
+ // fix line count for rest of blocks in the stack
ml_lineadd(buf, lineadd);
- /* fix stack itself */
+ // fix stack itself
buf->b_ml.ml_stack[buf->b_ml.ml_stack_top].ip_high +=
lineadd;
++(buf->b_ml.ml_stack_top);
@@ -2296,21 +2343,23 @@ static int ml_append_int(
* We are finished, break the loop here.
*/
break;
- } else { /* pointer block full */
+ } else { // pointer block full
/*
* split the pointer block
* allocate a new pointer block
* move some of the pointer into the new block
* prepare for updating the parent block
*/
- for (;; ) { /* do this twice when splitting block 1 */
+ for (;; ) { // do this twice when splitting block 1
hp_new = ml_new_ptr(mfp);
- if (hp_new == NULL) /* TODO: try to fix tree */
+ if (hp_new == NULL) { // TODO: try to fix tree
return FAIL;
+ }
pp_new = hp_new->bh_data;
- if (hp->bh_bnum != 1)
+ if (hp->bh_bnum != 1) {
break;
+ }
/*
* if block 1 becomes full the tree is given an extra level
@@ -2324,12 +2373,12 @@ static int ml_append_int(
pp->pb_pointer[0].pe_line_count = buf->b_ml.ml_line_count;
pp->pb_pointer[0].pe_old_lnum = 1;
pp->pb_pointer[0].pe_page_count = 1;
- mf_put(mfp, hp, true, false); /* release block 1 */
- hp = hp_new; /* new block is to be split */
+ mf_put(mfp, hp, true, false); // release block 1
+ hp = hp_new; // new block is to be split
pp = pp_new;
CHECK(stack_idx != 0, _("stack_idx should be 0"));
ip->ip_index = 0;
- ++stack_idx; /* do block 1 again later */
+ ++stack_idx; // do block 1 again later
}
/*
* move the pointers after the current one to the new block
@@ -2338,15 +2387,16 @@ static int ml_append_int(
total_moved = pp->pb_count - pb_idx - 1;
if (total_moved) {
memmove(&pp_new->pb_pointer[0],
- &pp->pb_pointer[pb_idx + 1],
- (size_t)(total_moved) * sizeof(PTR_EN));
+ &pp->pb_pointer[pb_idx + 1],
+ (size_t)(total_moved) * sizeof(PTR_EN));
pp_new->pb_count = total_moved;
pp->pb_count -= total_moved - 1;
pp->pb_pointer[pb_idx + 1].pe_bnum = bnum_right;
pp->pb_pointer[pb_idx + 1].pe_line_count = line_count_right;
pp->pb_pointer[pb_idx + 1].pe_page_count = page_count_right;
- if (lnum_right)
+ if (lnum_right) {
pp->pb_pointer[pb_idx + 1].pe_old_lnum = lnum_right;
+ }
} else {
pp_new->pb_count = 1;
pp_new->pb_pointer[0].pe_bnum = bnum_right;
@@ -2357,8 +2407,9 @@ static int ml_append_int(
pp->pb_pointer[pb_idx].pe_bnum = bnum_left;
pp->pb_pointer[pb_idx].pe_line_count = line_count_left;
pp->pb_pointer[pb_idx].pe_page_count = page_count_left;
- if (lnum_left)
+ if (lnum_left) {
pp->pb_pointer[pb_idx].pe_old_lnum = lnum_left;
+ }
lnum_left = 0;
lnum_right = 0;
@@ -2366,11 +2417,13 @@ static int ml_append_int(
* recompute line counts
*/
line_count_right = 0;
- for (i = 0; i < (int)pp_new->pb_count; ++i)
+ for (i = 0; i < (int)pp_new->pb_count; ++i) {
line_count_right += pp_new->pb_pointer[i].pe_line_count;
+ }
line_count_left = 0;
- for (i = 0; i < (int)pp->pb_count; ++i)
+ for (i = 0; i < (int)pp->pb_count; ++i) {
line_count_left += pp->pb_pointer[i].pe_line_count;
+ }
bnum_left = hp->bh_bnum;
bnum_right = hp_new->bh_bnum;
@@ -2390,7 +2443,7 @@ static int ml_append_int(
}
}
- /* The line was inserted below 'lnum' */
+ // The line was inserted below 'lnum'
ml_updatechunk(buf, lnum + 1, (long)len, ML_CHNK_ADDLINE);
return OK;
}
@@ -2437,8 +2490,9 @@ int ml_replace(linenr_T lnum, char_u *line, bool copy)
// return FAIL for failure, OK otherwise
int ml_replace_buf(buf_T *buf, linenr_T lnum, char_u *line, bool copy)
{
- if (line == NULL) /* just checking... */
+ if (line == NULL) { // just checking...
return FAIL;
+ }
// When starting up, we might still need to create the memfile
if (buf->b_ml.ml_mfp == NULL && open_buffer(false, NULL, 0) == FAIL) {
@@ -2485,12 +2539,12 @@ int ml_delete(linenr_T lnum, bool message)
static int ml_delete_int(buf_T *buf, linenr_T lnum, bool message)
{
- bhdr_T *hp;
- memfile_T *mfp;
- DATA_BL *dp;
- PTR_BL *pp;
- infoptr_T *ip;
- int count; /* number of entries in block */
+ bhdr_T *hp;
+ memfile_T *mfp;
+ DATA_BL *dp;
+ PTR_BL *pp;
+ infoptr_T *ip;
+ int count; // number of entries in block
int idx;
int stack_idx;
int text_start;
@@ -2498,19 +2552,22 @@ static int ml_delete_int(buf_T *buf, linenr_T lnum, bool message)
long line_size;
int i;
- if (lnum < 1 || lnum > buf->b_ml.ml_line_count)
+ if (lnum < 1 || lnum > buf->b_ml.ml_line_count) {
return FAIL;
+ }
- if (lowest_marked && lowest_marked > lnum)
+ if (lowest_marked && lowest_marked > lnum) {
lowest_marked--;
+ }
/*
* If the file becomes empty the last line is replaced by an empty line.
*/
- if (buf->b_ml.ml_line_count == 1) { /* file becomes empty */
+ if (buf->b_ml.ml_line_count == 1) { // file becomes empty
if (message
- )
+ ) {
set_keep_msg((char_u *)_(no_lines_msg), 0);
+ }
i = ml_replace((linenr_T)1, (char_u *)"", true);
buf->b_ml.ml_flags |= ML_EMPTY;
@@ -2524,14 +2581,16 @@ static int ml_delete_int(buf_T *buf, linenr_T lnum, bool message)
* This also releases any locked block.
*/
mfp = buf->b_ml.ml_mfp;
- if (mfp == NULL)
+ if (mfp == NULL) {
return FAIL;
+ }
- if ((hp = ml_find_line(buf, lnum, ML_DELETE)) == NULL)
+ if ((hp = ml_find_line(buf, lnum, ML_DELETE)) == NULL) {
return FAIL;
+ }
dp = hp->bh_data;
- /* compute line count before the delete */
+ // compute line count before the delete
count = (long)(buf->b_ml.ml_locked_high)
- (long)(buf->b_ml.ml_locked_low) + 2;
idx = lnum - buf->b_ml.ml_locked_low;
@@ -2539,10 +2598,11 @@ static int ml_delete_int(buf_T *buf, linenr_T lnum, bool message)
--buf->b_ml.ml_line_count;
line_start = ((dp->db_index[idx]) & DB_INDEX_MASK);
- if (idx == 0) /* first line in block, text at the end */
+ if (idx == 0) { // first line in block, text at the end
line_size = dp->db_txt_end - line_start;
- else
+ } else {
line_size = ((dp->db_index[idx - 1]) & DB_INDEX_MASK) - line_start;
+ }
// Line should always have an NL char internally (represented as NUL),
// even if 'noeol' is set.
@@ -2558,33 +2618,35 @@ static int ml_delete_int(buf_T *buf, linenr_T lnum, bool message)
* ml_find_line().
*/
if (count == 1) {
- mf_free(mfp, hp); /* free the data block */
+ mf_free(mfp, hp); // free the data block
buf->b_ml.ml_locked = NULL;
for (stack_idx = buf->b_ml.ml_stack_top - 1; stack_idx >= 0;
--stack_idx) {
- buf->b_ml.ml_stack_top = 0; /* stack is invalid when failing */
+ buf->b_ml.ml_stack_top = 0; // stack is invalid when failing
ip = &(buf->b_ml.ml_stack[stack_idx]);
idx = ip->ip_index;
- if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL)
+ if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL) {
return FAIL;
- pp = hp->bh_data; /* must be pointer block */
+ }
+ pp = hp->bh_data; // must be pointer block
if (pp->pb_id != PTR_ID) {
IEMSG(_("E317: pointer block id wrong 4"));
mf_put(mfp, hp, false, false);
return FAIL;
}
count = --(pp->pb_count);
- if (count == 0) /* the pointer block becomes empty! */
+ if (count == 0) { // the pointer block becomes empty!
mf_free(mfp, hp);
- else {
- if (count != idx) /* move entries after the deleted one */
+ } else {
+ if (count != idx) { // move entries after the deleted one
memmove(&pp->pb_pointer[idx], &pp->pb_pointer[idx + 1],
- (size_t)(count - idx) * sizeof(PTR_EN));
+ (size_t)(count - idx) * sizeof(PTR_EN));
+ }
mf_put(mfp, hp, true, false);
- buf->b_ml.ml_stack_top = stack_idx; /* truncate stack */
- /* fix line count for rest of blocks in the stack */
+ buf->b_ml.ml_stack_top = stack_idx; // truncate stack
+ // fix line count for rest of blocks in the stack
if (buf->b_ml.ml_locked_lineadd != 0) {
ml_lineadd(buf, buf->b_ml.ml_locked_lineadd);
buf->b_ml.ml_stack[buf->b_ml.ml_stack_top].ip_high +=
@@ -2602,14 +2664,15 @@ static int ml_delete_int(buf_T *buf, linenr_T lnum, bool message)
*/
text_start = dp->db_txt_start;
memmove((char *)dp + text_start + line_size,
- (char *)dp + text_start, (size_t)(line_start - text_start));
+ (char *)dp + text_start, (size_t)(line_start - text_start));
/*
* delete the index by moving the next indexes backwards
* Adjust the indexes for the text movement.
*/
- for (i = idx; i < count - 1; ++i)
+ for (i = idx; i < count - 1; ++i) {
dp->db_index[i] = dp->db_index[i + 1] + line_size;
+ }
dp->db_free += line_size + INDEX_SIZE;
dp->db_txt_start += line_size;
@@ -2630,24 +2693,25 @@ static int ml_delete_int(buf_T *buf, linenr_T lnum, bool message)
*/
void ml_setmarked(linenr_T lnum)
{
- bhdr_T *hp;
+ bhdr_T *hp;
DATA_BL *dp;
- /* invalid line number */
+ // invalid line number
if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count
- || curbuf->b_ml.ml_mfp == NULL)
- return; /* give error message? */
-
- if (lowest_marked == 0 || lowest_marked > lnum)
+ || curbuf->b_ml.ml_mfp == NULL) {
+ return; // give error message?
+ }
+ if (lowest_marked == 0 || lowest_marked > lnum) {
lowest_marked = lnum;
+ }
/*
* find the data block containing the line
* This also fills the stack with the blocks from the root to the data block
* This also releases any locked block.
*/
- if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL)
- return; /* give error message? */
-
+ if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL) {
+ return; // give error message?
+ }
dp = hp->bh_data;
dp->db_index[lnum - curbuf->b_ml.ml_locked_low] |= DB_MARKED;
curbuf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
@@ -2658,13 +2722,14 @@ void ml_setmarked(linenr_T lnum)
*/
linenr_T ml_firstmarked(void)
{
- bhdr_T *hp;
- DATA_BL *dp;
+ bhdr_T *hp;
+ DATA_BL *dp;
linenr_T lnum;
int i;
- if (curbuf->b_ml.ml_mfp == NULL)
- return (linenr_T) 0;
+ if (curbuf->b_ml.ml_mfp == NULL) {
+ return (linenr_T)0;
+ }
/*
* The search starts with lowest_marked line. This is the last line where
@@ -2676,22 +2741,23 @@ linenr_T ml_firstmarked(void)
* This also fills the stack with the blocks from the root to the data
* block This also releases any locked block.
*/
- if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL)
- return (linenr_T)0; /* give error message? */
-
+ if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL) {
+ return (linenr_T)0; // give error message?
+ }
dp = hp->bh_data;
for (i = lnum - curbuf->b_ml.ml_locked_low;
- lnum <= curbuf->b_ml.ml_locked_high; ++i, ++lnum)
+ lnum <= curbuf->b_ml.ml_locked_high; ++i, ++lnum) {
if ((dp->db_index[i]) & DB_MARKED) {
(dp->db_index[i]) &= DB_INDEX_MASK;
curbuf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
lowest_marked = lnum + 1;
return lnum;
}
+ }
}
- return (linenr_T) 0;
+ return (linenr_T)0;
}
/*
@@ -2699,13 +2765,14 @@ linenr_T ml_firstmarked(void)
*/
void ml_clearmarked(void)
{
- bhdr_T *hp;
- DATA_BL *dp;
+ bhdr_T *hp;
+ DATA_BL *dp;
linenr_T lnum;
int i;
- if (curbuf->b_ml.ml_mfp == NULL) /* nothing to do */
+ if (curbuf->b_ml.ml_mfp == NULL) { // nothing to do
return;
+ }
/*
* The search starts with line lowest_marked.
@@ -2716,17 +2783,18 @@ void ml_clearmarked(void)
* This also fills the stack with the blocks from the root to the data
* block and releases any locked block.
*/
- if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL)
- return; /* give error message? */
-
+ if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL) {
+ return; // give error message?
+ }
dp = hp->bh_data;
for (i = lnum - curbuf->b_ml.ml_locked_low;
- lnum <= curbuf->b_ml.ml_locked_high; ++i, ++lnum)
+ lnum <= curbuf->b_ml.ml_locked_high; ++i, ++lnum) {
if ((dp->db_index[i]) & DB_MARKED) {
(dp->db_index[i]) &= DB_INDEX_MASK;
curbuf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
}
+ }
}
lowest_marked = 0;
@@ -2749,11 +2817,11 @@ size_t ml_flush_deleted_bytes(buf_T *buf, size_t *codepoints, size_t *codeunits)
*/
static void ml_flush_line(buf_T *buf)
{
- bhdr_T *hp;
- DATA_BL *dp;
+ bhdr_T *hp;
+ DATA_BL *dp;
linenr_T lnum;
- char_u *new_line;
- char_u *old_line;
+ char_u *new_line;
+ char_u *old_line;
colnr_T new_len;
int old_len;
int extra;
@@ -2761,16 +2829,17 @@ static void ml_flush_line(buf_T *buf)
int start;
int count;
int i;
- static int entered = FALSE;
-
- if (buf->b_ml.ml_line_lnum == 0 || buf->b_ml.ml_mfp == NULL)
- return; /* nothing to do */
+ static bool entered = false;
+ if (buf->b_ml.ml_line_lnum == 0 || buf->b_ml.ml_mfp == NULL) {
+ return; // nothing to do
+ }
if (buf->b_ml.ml_flags & ML_LINE_DIRTY) {
- /* This code doesn't work recursively. */
- if (entered)
+ // This code doesn't work recursively.
+ if (entered) {
return;
- entered = TRUE;
+ }
+ entered = true;
buf->flush_count++;
@@ -2785,39 +2854,41 @@ static void ml_flush_line(buf_T *buf)
idx = lnum - buf->b_ml.ml_locked_low;
start = ((dp->db_index[idx]) & DB_INDEX_MASK);
old_line = (char_u *)dp + start;
- if (idx == 0) /* line is last in block */
+ if (idx == 0) { // line is last in block
old_len = dp->db_txt_end - start;
- else /* text of previous line follows */
+ } else { // text of previous line follows
old_len = (dp->db_index[idx - 1] & DB_INDEX_MASK) - start;
+ }
new_len = (colnr_T)STRLEN(new_line) + 1;
- extra = new_len - old_len; /* negative if lines gets smaller */
+ extra = new_len - old_len; // negative if lines gets smaller
/*
* if new line fits in data block, replace directly
*/
if ((int)dp->db_free >= extra) {
- /* if the length changes and there are following lines */
+ // if the length changes and there are following lines
count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low + 1;
if (extra != 0 && idx < count - 1) {
- /* move text of following lines */
+ // move text of following lines
memmove((char *)dp + dp->db_txt_start - extra,
- (char *)dp + dp->db_txt_start,
- (size_t)(start - dp->db_txt_start));
+ (char *)dp + dp->db_txt_start,
+ (size_t)(start - dp->db_txt_start));
- /* adjust pointers of this and following lines */
- for (i = idx + 1; i < count; ++i)
+ // adjust pointers of this and following lines
+ for (i = idx + 1; i < count; ++i) {
dp->db_index[i] -= extra;
+ }
}
dp->db_index[idx] -= extra;
- /* adjust free space */
+ // adjust free space
dp->db_free -= extra;
dp->db_txt_start -= extra;
- /* copy new line into the data block */
+ // copy new line into the data block
memmove(old_line - extra, new_line, (size_t)new_len);
buf->b_ml.ml_flags |= (ML_LOCKED_DIRTY | ML_LOCKED_POS);
- /* The else case is already covered by the insert and delete */
+ // The else case is already covered by the insert and delete
ml_updatechunk(buf, lnum, (long)extra, ML_CHNK_UPDLINE);
} else {
// Cannot do it in one data block: Delete and append.
@@ -2833,7 +2904,7 @@ static void ml_flush_line(buf_T *buf)
}
xfree(new_line);
- entered = FALSE;
+ entered = false;
}
buf->b_ml.ml_line_lnum = 0;
@@ -2874,8 +2945,8 @@ static bhdr_T *ml_new_ptr(memfile_T *mfp)
* lookup line 'lnum' in a memline
*
* action: if ML_DELETE or ML_INSERT the line count is updated while searching
- * if ML_FLUSH only flush a locked block
- * if ML_FIND just find the line
+ * if ML_FLUSH only flush a locked block
+ * if ML_FIND just find the line
*
* If the block was found it is locked and put in ml_locked.
* The stack is updated to lead to the locked block. The ip_high field in
@@ -2887,11 +2958,11 @@ static bhdr_T *ml_new_ptr(memfile_T *mfp)
*/
static bhdr_T *ml_find_line(buf_T *buf, linenr_T lnum, int action)
{
- DATA_BL *dp;
- PTR_BL *pp;
- infoptr_T *ip;
- bhdr_T *hp;
- memfile_T *mfp;
+ DATA_BL *dp;
+ PTR_BL *pp;
+ infoptr_T *ip;
+ bhdr_T *hp;
+ memfile_T *mfp;
linenr_T t;
blocknr_T bnum, bnum2;
int dirty;
@@ -2925,58 +2996,63 @@ static bhdr_T *ml_find_line(buf_T *buf, linenr_T lnum, int action)
}
mf_put(mfp, buf->b_ml.ml_locked, buf->b_ml.ml_flags & ML_LOCKED_DIRTY,
- buf->b_ml.ml_flags & ML_LOCKED_POS);
+ buf->b_ml.ml_flags & ML_LOCKED_POS);
buf->b_ml.ml_locked = NULL;
/*
* If lines have been added or deleted in the locked block, need to
* update the line count in pointer blocks.
*/
- if (buf->b_ml.ml_locked_lineadd != 0)
+ if (buf->b_ml.ml_locked_lineadd != 0) {
ml_lineadd(buf, buf->b_ml.ml_locked_lineadd);
+ }
}
- if (action == ML_FLUSH) /* nothing else to do */
+ if (action == ML_FLUSH) { // nothing else to do
return NULL;
+ }
- bnum = 1; /* start at the root of the tree */
+ bnum = 1; // start at the root of the tree
page_count = 1;
low = 1;
high = buf->b_ml.ml_line_count;
- if (action == ML_FIND) { /* first try stack entries */
+ if (action == ML_FIND) { // first try stack entries
for (top = buf->b_ml.ml_stack_top - 1; top >= 0; --top) {
ip = &(buf->b_ml.ml_stack[top]);
if (ip->ip_low <= lnum && ip->ip_high >= lnum) {
bnum = ip->ip_bnum;
low = ip->ip_low;
high = ip->ip_high;
- buf->b_ml.ml_stack_top = top; /* truncate stack at prev entry */
+ buf->b_ml.ml_stack_top = top; // truncate stack at prev entry
break;
}
}
- if (top < 0)
- buf->b_ml.ml_stack_top = 0; /* not found, start at the root */
- } else /* ML_DELETE or ML_INSERT */
- buf->b_ml.ml_stack_top = 0; /* start at the root */
-
+ if (top < 0) {
+ buf->b_ml.ml_stack_top = 0; // not found, start at the root
+ }
+ } else { // ML_DELETE or ML_INSERT
+ buf->b_ml.ml_stack_top = 0; // start at the root
+ }
/*
* search downwards in the tree until a data block is found
*/
for (;; ) {
- if ((hp = mf_get(mfp, bnum, page_count)) == NULL)
+ if ((hp = mf_get(mfp, bnum, page_count)) == NULL) {
goto error_noblock;
+ }
/*
* update high for insert/delete
*/
- if (action == ML_INSERT)
+ if (action == ML_INSERT) {
++high;
- else if (action == ML_DELETE)
+ } else if (action == ML_DELETE) {
--high;
+ }
dp = hp->bh_data;
- if (dp->db_id == DATA_ID) { /* data block */
+ if (dp->db_id == DATA_ID) { // data block
buf->b_ml.ml_locked = hp;
buf->b_ml.ml_locked_low = low;
buf->b_ml.ml_locked_high = high;
@@ -2985,7 +3061,7 @@ static bhdr_T *ml_find_line(buf_T *buf, linenr_T lnum, int action)
return hp;
}
- pp = (PTR_BL *)(dp); /* must be pointer block */
+ pp = (PTR_BL *)(dp); // must be pointer block
if (pp->pb_id != PTR_ID) {
IEMSG(_("E317: pointer block id wrong"));
goto error_block;
@@ -2996,7 +3072,7 @@ static bhdr_T *ml_find_line(buf_T *buf, linenr_T lnum, int action)
ip->ip_bnum = bnum;
ip->ip_low = low;
ip->ip_high = high;
- ip->ip_index = -1; /* index not known yet */
+ ip->ip_index = -1; // index not known yet
dirty = FALSE;
for (idx = 0; idx < (int)pp->pb_count; ++idx) {
@@ -3028,7 +3104,6 @@ static bhdr_T *ml_find_line(buf_T *buf, linenr_T lnum, int action)
if (lnum > buf->b_ml.ml_line_count) {
IEMSGN(_("E322: line number out of range: %" PRId64 " past the end"),
lnum - buf->b_ml.ml_line_count);
-
} else {
IEMSGN(_("E323: line count wrong in block %" PRId64), bnum);
}
@@ -3052,10 +3127,11 @@ error_noblock:
* the incremented/decremented line counts, because there won't be a line
* inserted/deleted after all.
*/
- if (action == ML_DELETE)
+ if (action == ML_DELETE) {
ml_lineadd(buf, 1);
- else if (action == ML_INSERT)
+ } else if (action == ML_INSERT) {
ml_lineadd(buf, -1);
+ }
buf->b_ml.ml_stack_top = 0;
return NULL;
}
@@ -3069,9 +3145,9 @@ static int ml_add_stack(buf_T *buf)
{
int top = buf->b_ml.ml_stack_top;
- /* may have to increase the stack size */
+ // may have to increase the stack size
if (top == buf->b_ml.ml_stack_size) {
- CHECK(top > 0, _("Stack size increases")); /* more than 5 levels??? */
+ CHECK(top > 0, _("Stack size increases")); // more than 5 levels???
buf->b_ml.ml_stack_size += STACK_INCR;
size_t new_size = sizeof(infoptr_T) * buf->b_ml.ml_stack_size;
@@ -3095,16 +3171,17 @@ static int ml_add_stack(buf_T *buf)
static void ml_lineadd(buf_T *buf, int count)
{
int idx;
- infoptr_T *ip;
- PTR_BL *pp;
- memfile_T *mfp = buf->b_ml.ml_mfp;
- bhdr_T *hp;
+ infoptr_T *ip;
+ PTR_BL *pp;
+ memfile_T *mfp = buf->b_ml.ml_mfp;
+ bhdr_T *hp;
for (idx = buf->b_ml.ml_stack_top - 1; idx >= 0; --idx) {
ip = &(buf->b_ml.ml_stack[idx]);
- if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL)
+ if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL) {
break;
- pp = hp->bh_data; /* must be pointer block */
+ }
+ pp = hp->bh_data; // must be pointer block
if (pp->pb_id != PTR_ID) {
mf_put(mfp, hp, false, false);
IEMSG(_("E317: pointer block id wrong 2"));
@@ -3130,14 +3207,15 @@ int resolve_symlink(const char_u *fname, char_u *buf)
int ret;
int depth = 0;
- if (fname == NULL)
+ if (fname == NULL) {
return FAIL;
+ }
- /* Put the result so far in tmp[], starting with the original name. */
+ // Put the result so far in tmp[], starting with the original name.
STRLCPY(tmp, fname, MAXPATHL);
for (;; ) {
- /* Limit symlink depth to 100, catch recursive loops. */
+ // Limit symlink depth to 100, catch recursive loops.
if (++depth == 100) {
EMSG2(_("E773: Symlink loop for \"%s\""), fname);
return FAIL;
@@ -3149,14 +3227,15 @@ int resolve_symlink(const char_u *fname, char_u *buf)
/* Found non-symlink or not existing file, stop here.
* When at the first level use the unmodified name, skip the
* call to vim_FullName(). */
- if (depth == 1)
+ if (depth == 1) {
return FAIL;
+ }
- /* Use the resolved name in tmp[]. */
+ // Use the resolved name in tmp[].
break;
}
- /* There must be some error reading links, use original name. */
+ // There must be some error reading links, use original name.
return FAIL;
}
buf[ret] = NUL;
@@ -3191,8 +3270,8 @@ int resolve_symlink(const char_u *fname, char_u *buf)
*/
char_u *makeswapname(char_u *fname, char_u *ffname, buf_T *buf, char_u *dir_name)
{
- char_u *r, *s;
- char_u *fname_res = fname;
+ char_u *r, *s;
+ char_u *fname_res = fname;
#ifdef HAVE_READLINK
char_u fname_buf[MAXPATHL];
@@ -3219,46 +3298,43 @@ char_u *makeswapname(char_u *fname, char_u *ffname, buf_T *buf, char_u *dir_name
// Prepend a '.' to the swap file name for the current directory.
r = (char_u *)modname((char *)fname_res, ".swp",
- dir_name[0] == '.' && dir_name[1] == NUL);
- if (r == NULL) /* out of memory */
+ dir_name[0] == '.' && dir_name[1] == NUL);
+ if (r == NULL) { // out of memory
return NULL;
+ }
s = get_file_in_dir(r, dir_name);
xfree(r);
return s;
}
-/*
- * Get file name to use for swap file or backup file.
- * Use the name of the edited file "fname" and an entry in the 'dir' or 'bdir'
- * option "dname".
- * - If "dname" is ".", return "fname" (swap file in dir of file).
- * - If "dname" starts with "./", insert "dname" in "fname" (swap file
- * relative to dir of file).
- * - Otherwise, prepend "dname" to the tail of "fname" (swap file in specific
- * dir).
- *
- * The return value is an allocated string and can be NULL.
- */
-char_u *
-get_file_in_dir (
- char_u *fname,
- char_u *dname /* don't use "dirname", it is a global for Alpha */
-)
+/// Get file name to use for swap file or backup file.
+/// Use the name of the edited file "fname" and an entry in the 'dir' or 'bdir'
+/// option "dname".
+/// - If "dname" is ".", return "fname" (swap file in dir of file).
+/// - If "dname" starts with "./", insert "dname" in "fname" (swap file
+/// relative to dir of file).
+/// - Otherwise, prepend "dname" to the tail of "fname" (swap file in specific
+/// dir).
+///
+/// The return value is an allocated string and can be NULL.
+///
+/// @param dname don't use "dirname", it is a global for Alpha
+char_u *get_file_in_dir(char_u *fname, char_u *dname)
{
- char_u *t;
- char_u *tail;
- char_u *retval;
+ char_u *t;
+ char_u *tail;
+ char_u *retval;
int save_char;
tail = path_tail(fname);
- if (dname[0] == '.' && dname[1] == NUL)
+ if (dname[0] == '.' && dname[1] == NUL) {
retval = vim_strsave(fname);
- else if (dname[0] == '.' && vim_ispathsep(dname[1])) {
- if (tail == fname) /* no path before file name */
+ } else if (dname[0] == '.' && vim_ispathsep(dname[1])) {
+ if (tail == fname) { // no path before file name
retval = (char_u *)concat_fnames((char *)dname + 2, (char *)tail, TRUE);
- else {
+ } else {
save_char = *tail;
*tail = NUL;
t = (char_u *)concat_fnames((char *)fname, (char *)dname + 2, TRUE);
@@ -3274,14 +3350,11 @@ get_file_in_dir (
}
-/*
- * Print the ATTENTION message: info about an existing swap file.
- */
-static void
-attention_message (
- buf_T *buf, /* buffer being edited */
- char_u *fname /* swap file name */
-)
+/// Print the ATTENTION message: info about an existing swap file.
+///
+/// @param buf buffer being edited
+/// @param fname swap file name
+static void attention_message(buf_T *buf, char_u *fname)
{
assert(buf->b_fname != NULL);
@@ -3337,24 +3410,30 @@ attention_message (
*/
static int do_swapexists(buf_T *buf, char_u *fname)
{
- set_vim_var_string(VV_SWAPNAME, (char *) fname, -1);
+ set_vim_var_string(VV_SWAPNAME, (char *)fname, -1);
set_vim_var_string(VV_SWAPCHOICE, NULL, -1);
- /* Trigger SwapExists autocommands with <afile> set to the file being
- * edited. Disallow changing directory here. */
- ++allbuf_lock;
- apply_autocmds(EVENT_SWAPEXISTS, buf->b_fname, NULL, FALSE, NULL);
- --allbuf_lock;
+ // Trigger SwapExists autocommands with <afile> set to the file being
+ // edited. Disallow changing directory here.
+ allbuf_lock++;
+ apply_autocmds(EVENT_SWAPEXISTS, buf->b_fname, NULL, false, NULL);
+ allbuf_lock--;
set_vim_var_string(VV_SWAPNAME, NULL, -1);
switch (*get_vim_var_str(VV_SWAPCHOICE)) {
- case 'o': return 1;
- case 'e': return 2;
- case 'r': return 3;
- case 'd': return 4;
- case 'q': return 5;
- case 'a': return 6;
+ case 'o':
+ return 1;
+ case 'e':
+ return 2;
+ case 'r':
+ return 3;
+ case 'd':
+ return 4;
+ case 'q':
+ return 5;
+ case 'a':
+ return 6;
}
return 0;
@@ -3383,14 +3462,13 @@ static int do_swapexists(buf_T *buf, char_u *fname)
/// never set to false.
///
/// @return [allocated] Name of the swap file.
-static char *findswapname(buf_T *buf, char **dirp, char *old_fname,
- bool *found_existing_dir)
+static char *findswapname(buf_T *buf, char **dirp, char *old_fname, bool *found_existing_dir)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ARG(1, 2, 4)
{
char *fname;
size_t n;
char *dir_name;
- char *buf_fname = (char *) buf->b_fname;
+ char *buf_fname = (char *)buf->b_fname;
/*
* Isolate a directory name from *dirp and put it in dir_name.
@@ -3398,7 +3476,7 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname,
*/
const size_t dir_len = strlen(*dirp) + 1;
dir_name = xmalloc(dir_len);
- (void)copy_option_part((char_u **) dirp, (char_u *) dir_name, dir_len, ",");
+ (void)copy_option_part((char_u **)dirp, (char_u *)dir_name, dir_len, ",");
/*
* we try different names until we find one that does not exist yet
@@ -3457,7 +3535,7 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname,
// inode too.
expand_env(b0.b0_fname, NameBuff, MAXPATHL);
if (fnamecmp_ino(buf->b_ffname, NameBuff,
- char_to_long(b0.b0_ino))) {
+ char_to_long(b0.b0_ino))) {
differ = TRUE;
}
}
@@ -3466,7 +3544,7 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname,
// "~user/path/file". Expand it first.
expand_env(b0.b0_fname, NameBuff, MAXPATHL);
if (fnamecmp_ino(buf->b_ffname, NameBuff,
- char_to_long(b0.b0_ino))) {
+ char_to_long(b0.b0_ino))) {
differ = TRUE;
}
}
@@ -3530,12 +3608,10 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname,
choice = do_dialog(VIM_WARNING, (char_u *)_("VIM - ATTENTION"),
(char_u *)name,
process_still_running
- ? (char_u *)_(
- "&Open Read-Only\n&Edit anyway\n&Recover"
- "\n&Quit\n&Abort") :
- (char_u *)_(
- "&Open Read-Only\n&Edit anyway\n&Recover"
- "\n&Delete it\n&Quit\n&Abort"),
+ ? (char_u *)_("&Open Read-Only\n&Edit anyway\n&Recover"
+ "\n&Quit\n&Abort") :
+ (char_u *)_("&Open Read-Only\n&Edit anyway\n&Recover"
+ "\n&Delete it\n&Quit\n&Abort"),
1, NULL, false);
if (process_still_running && choice >= 4) {
@@ -3575,11 +3651,11 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname,
}
} else {
MSG_PUTS("\n");
- if (msg_silent == 0)
- /* call wait_return() later */
- need_wait_return = TRUE;
+ if (msg_silent == 0) {
+ // call wait_return() later
+ need_wait_return = true;
+ }
}
-
}
}
}
@@ -3590,19 +3666,19 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname,
* If that still isn't enough decrement the last but one char: ".svz"
* Can happen when editing many "No Name" buffers.
*/
- if (fname[n - 1] == 'a') { /* ".s?a" */
- if (fname[n - 2] == 'a') { /* ".saa": tried enough, give up */
+ if (fname[n - 1] == 'a') { // ".s?a"
+ if (fname[n - 2] == 'a') { // ".saa": tried enough, give up
EMSG(_("E326: Too many swap files found"));
XFREE_CLEAR(fname);
break;
}
- --fname[n - 2]; /* ".svz", ".suz", etc. */
+ --fname[n - 2]; // ".svz", ".suz", etc.
fname[n - 1] = 'z' + 1;
}
- --fname[n - 1]; /* ".swo", ".swn", etc. */
+ --fname[n - 1]; // ".swo", ".swn", etc.
}
- if (os_isdir((char_u *) dir_name)) {
+ if (os_isdir((char_u *)dir_name)) {
*found_existing_dir = true;
} else if (!*found_existing_dir && **dirp == NUL) {
int ret;
@@ -3627,66 +3703,62 @@ static int b0_magic_wrong(ZERO_BL *b0p)
|| b0p->b0_magic_char != B0_MAGIC_CHAR;
}
-/*
- * Compare current file name with file name from swap file.
- * Try to use inode numbers when possible.
- * Return non-zero when files are different.
- *
- * When comparing file names a few things have to be taken into consideration:
- * - When working over a network the full path of a file depends on the host.
- * We check the inode number if possible. It is not 100% reliable though,
- * because the device number cannot be used over a network.
- * - When a file does not exist yet (editing a new file) there is no inode
- * number.
- * - The file name in a swap file may not be valid on the current host. The
- * "~user" form is used whenever possible to avoid this.
- *
- * This is getting complicated, let's make a table:
- *
- * ino_c ino_s fname_c fname_s differ =
- *
- * both files exist -> compare inode numbers:
- * != 0 != 0 X X ino_c != ino_s
- *
- * inode number(s) unknown, file names available -> compare file names
- * == 0 X OK OK fname_c != fname_s
- * X == 0 OK OK fname_c != fname_s
- *
- * current file doesn't exist, file for swap file exist, file name(s) not
- * available -> probably different
- * == 0 != 0 FAIL X TRUE
- * == 0 != 0 X FAIL TRUE
- *
- * current file exists, inode for swap unknown, file name(s) not
- * available -> probably different
- * != 0 == 0 FAIL X TRUE
- * != 0 == 0 X FAIL TRUE
- *
- * current file doesn't exist, inode for swap unknown, one file name not
- * available -> probably different
- * == 0 == 0 FAIL OK TRUE
- * == 0 == 0 OK FAIL TRUE
- *
- * current file doesn't exist, inode for swap unknown, both file names not
- * available -> compare file names
- * == 0 == 0 FAIL FAIL fname_c != fname_s
- *
- * Only the last 32 bits of the inode will be used. This can't be changed
- * without making the block 0 incompatible with 32 bit versions.
- */
-
-static bool fnamecmp_ino(
- char_u *fname_c, // current file name
- char_u *fname_s, // file name from swap file
- long ino_block0
-)
+/// Compare current file name with file name from swap file.
+/// Try to use inode numbers when possible.
+/// Return non-zero when files are different.
+///
+/// When comparing file names a few things have to be taken into consideration:
+/// - When working over a network the full path of a file depends on the host.
+/// We check the inode number if possible. It is not 100% reliable though,
+/// because the device number cannot be used over a network.
+/// - When a file does not exist yet (editing a new file) there is no inode
+/// number.
+/// - The file name in a swap file may not be valid on the current host. The
+/// "~user" form is used whenever possible to avoid this.
+///
+/// This is getting complicated, let's make a table:
+///
+/// ino_c ino_s fname_c fname_s differ =
+///
+/// both files exist -> compare inode numbers:
+/// != 0 != 0 X X ino_c != ino_s
+///
+/// inode number(s) unknown, file names available -> compare file names
+/// == 0 X OK OK fname_c != fname_s
+/// X == 0 OK OK fname_c != fname_s
+///
+/// current file doesn't exist, file for swap file exist, file name(s) not
+/// available -> probably different
+/// == 0 != 0 FAIL X TRUE
+/// == 0 != 0 X FAIL TRUE
+///
+/// current file exists, inode for swap unknown, file name(s) not
+/// available -> probably different
+/// != 0 == 0 FAIL X TRUE
+/// != 0 == 0 X FAIL TRUE
+///
+/// current file doesn't exist, inode for swap unknown, one file name not
+/// available -> probably different
+/// == 0 == 0 FAIL OK TRUE
+/// == 0 == 0 OK FAIL TRUE
+///
+/// current file doesn't exist, inode for swap unknown, both file names not
+/// available -> compare file names
+/// == 0 == 0 FAIL FAIL fname_c != fname_s
+///
+/// Only the last 32 bits of the inode will be used. This can't be changed
+/// without making the block 0 incompatible with 32 bit versions.
+///
+/// @param fname_c current file name
+/// @param fname_s file name from swap file
+static bool fnamecmp_ino(char_u *fname_c, char_u *fname_s, long ino_block0)
{
- uint64_t ino_c = 0; /* ino of current file */
- uint64_t ino_s; /* ino of file from swap file */
- char_u buf_c[MAXPATHL]; /* full path of fname_c */
- char_u buf_s[MAXPATHL]; /* full path of fname_s */
- int retval_c; /* flag: buf_c valid */
- int retval_s; /* flag: buf_s valid */
+ uint64_t ino_c = 0; // ino of current file
+ uint64_t ino_s; // ino of file from swap file
+ char_u buf_c[MAXPATHL]; // full path of fname_c
+ char_u buf_s[MAXPATHL]; // full path of fname_s
+ int retval_c; // flag: buf_c valid
+ int retval_s; // flag: buf_s valid
FileInfo file_info;
if (os_fileinfo((char *)fname_c, &file_info)) {
@@ -3704,8 +3776,9 @@ static bool fnamecmp_ino(
ino_s = (uint64_t)ino_block0;
}
- if (ino_c && ino_s)
+ if (ino_c && ino_s) {
return ino_c != ino_s;
+ }
/*
* One of the inode numbers is unknown, try a forced vim_FullName() and
@@ -3713,8 +3786,9 @@ static bool fnamecmp_ino(
*/
retval_c = vim_FullName((char *)fname_c, (char *)buf_c, MAXPATHL, TRUE);
retval_s = vim_FullName((char *)fname_s, (char *)buf_s, MAXPATHL, TRUE);
- if (retval_c == OK && retval_s == OK)
+ if (retval_c == OK && retval_s == OK) {
return STRCMP(buf_c, buf_s) != 0;
+ }
/*
* Can't compare inodes or file names, guess that the files are different,
@@ -3765,11 +3839,12 @@ static long char_to_long(char_u *s)
*/
void ml_setflags(buf_T *buf)
{
- bhdr_T *hp;
- ZERO_BL *b0p;
+ bhdr_T *hp;
+ ZERO_BL *b0p;
- if (!buf->b_ml.ml_mfp)
+ if (!buf->b_ml.ml_mfp) {
return;
+ }
for (hp = buf->b_ml.ml_mfp->mf_used_last; hp != NULL; hp = hp->bh_prev) {
if (hp->bh_bnum == 0) {
b0p = hp->bh_data;
@@ -3784,19 +3859,19 @@ void ml_setflags(buf_T *buf)
}
}
-#define MLCS_MAXL 800 /* max no of lines in chunk */
-#define MLCS_MINL 400 /* should be half of MLCS_MAXL */
+#define MLCS_MAXL 800 // max no of lines in chunk
+#define MLCS_MINL 400 // should be half of MLCS_MAXL
/*
* Keep information for finding byte offset of a line, updtype may be one of:
* ML_CHNK_ADDLINE: Add len to parent chunk, possibly splitting it
- * Careful: ML_CHNK_ADDLINE may cause ml_find_line() to be called.
+ * Careful: ML_CHNK_ADDLINE may cause ml_find_line() to be called.
* ML_CHNK_DELLINE: Subtract len from parent chunk, possibly deleting it
* ML_CHNK_UPDLINE: Add len to parent chunk, as a signed entity.
*/
static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype)
{
- static buf_T *ml_upd_lastbuf = NULL;
+ static buf_T *ml_upd_lastbuf = NULL;
static linenr_T ml_upd_lastline;
static linenr_T ml_upd_lastcurline;
static int ml_upd_lastcurix;
@@ -3804,13 +3879,14 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype)
linenr_T curline = ml_upd_lastcurline;
int curix = ml_upd_lastcurix;
long size;
- chunksize_T *curchnk;
+ chunksize_T *curchnk;
int rest;
- bhdr_T *hp;
- DATA_BL *dp;
+ bhdr_T *hp;
+ DATA_BL *dp;
- if (buf->b_ml.ml_usedchunks == -1 || len == 0)
+ if (buf->b_ml.ml_usedchunks == -1 || len == 0) {
return;
+ }
if (buf->b_ml.ml_chunksize == NULL) {
buf->b_ml.ml_chunksize = xmalloc(sizeof(chunksize_T) * 100);
buf->b_ml.ml_numchunks = 100;
@@ -3838,8 +3914,8 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype)
|| updtype != ML_CHNK_ADDLINE) {
for (curline = 1, curix = 0;
curix < buf->b_ml.ml_usedchunks - 1
- && line >= curline +
- buf->b_ml.ml_chunksize[curix].mlcs_numlines;
+ && line >= curline +
+ buf->b_ml.ml_chunksize[curix].mlcs_numlines;
curix++) {
curline += buf->b_ml.ml_chunksize[curix].mlcs_numlines;
}
@@ -3851,31 +3927,31 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype)
}
curchnk = buf->b_ml.ml_chunksize + curix;
- if (updtype == ML_CHNK_DELLINE)
+ if (updtype == ML_CHNK_DELLINE) {
len = -len;
+ }
curchnk->mlcs_totalsize += len;
if (updtype == ML_CHNK_ADDLINE) {
curchnk->mlcs_numlines++;
- /* May resize here so we don't have to do it in both cases below */
+ // May resize here so we don't have to do it in both cases below
if (buf->b_ml.ml_usedchunks + 1 >= buf->b_ml.ml_numchunks) {
buf->b_ml.ml_numchunks = buf->b_ml.ml_numchunks * 3 / 2;
- buf->b_ml.ml_chunksize = xrealloc(
- buf->b_ml.ml_chunksize,
- sizeof(chunksize_T) * buf->b_ml.ml_numchunks);
+ buf->b_ml.ml_chunksize = xrealloc(buf->b_ml.ml_chunksize,
+ sizeof(chunksize_T) * buf->b_ml.ml_numchunks);
}
if (buf->b_ml.ml_chunksize[curix].mlcs_numlines >= MLCS_MAXL) {
- int count; /* number of entries in block */
+ int count; // number of entries in block
int idx;
int text_end;
int linecnt;
memmove(buf->b_ml.ml_chunksize + curix + 1,
- buf->b_ml.ml_chunksize + curix,
- (buf->b_ml.ml_usedchunks - curix) *
- sizeof(chunksize_T));
- /* Compute length of first half of lines in the split chunk */
+ buf->b_ml.ml_chunksize + curix,
+ (buf->b_ml.ml_usedchunks - curix) *
+ sizeof(chunksize_T));
+ // Compute length of first half of lines in the split chunk
size = 0;
linecnt = 0;
while (curline < buf->b_ml.ml_line_count
@@ -3889,11 +3965,12 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype)
(long)(buf->b_ml.ml_locked_low) + 1;
idx = curline - buf->b_ml.ml_locked_low;
curline = buf->b_ml.ml_locked_high + 1;
- if (idx == 0) /* first line in block, text at the end */
+ if (idx == 0) { // first line in block, text at the end
text_end = dp->db_txt_end;
- else
+ } else {
text_end = ((dp->db_index[idx - 1]) & DB_INDEX_MASK);
- /* Compute index of last line to use in this MEMLINE */
+ }
+ // Compute index of last line to use in this MEMLINE
rest = count - idx;
if (linecnt + rest > MLCS_MINL) {
idx += MLCS_MINL - linecnt - 1;
@@ -3909,7 +3986,7 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype)
buf->b_ml.ml_chunksize[curix].mlcs_totalsize = size;
buf->b_ml.ml_chunksize[curix + 1].mlcs_totalsize -= size;
buf->b_ml.ml_usedchunks++;
- ml_upd_lastbuf = NULL; /* Force recalc of curix & curline */
+ ml_upd_lastbuf = NULL; // Force recalc of curix & curline
return;
} else if (buf->b_ml.ml_chunksize[curix].mlcs_numlines >= MLCS_MINL
&& curix == buf->b_ml.ml_usedchunks - 1
@@ -3934,12 +4011,13 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype)
return;
}
dp = hp->bh_data;
- if (dp->db_line_count == 1)
+ if (dp->db_line_count == 1) {
rest = dp->db_txt_end - dp->db_txt_start;
- else
+ } else {
rest =
((dp->db_index[dp->db_line_count - 2]) & DB_INDEX_MASK)
- dp->db_txt_start;
+ }
curchnk->mlcs_totalsize = rest;
curchnk->mlcs_numlines = 1;
curchnk[-1].mlcs_totalsize -= rest;
@@ -3948,7 +4026,7 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype)
}
} else if (updtype == ML_CHNK_DELLINE) {
curchnk->mlcs_numlines--;
- ml_upd_lastbuf = NULL; /* Force recalc of curix & curline */
+ ml_upd_lastbuf = NULL; // Force recalc of curix & curline
if (curix < (buf->b_ml.ml_usedchunks - 1)
&& (curchnk->mlcs_numlines + curchnk[1].mlcs_numlines)
<= MLCS_MINL) {
@@ -3957,7 +4035,7 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype)
} else if (curix == 0 && curchnk->mlcs_numlines <= 0) {
buf->b_ml.ml_usedchunks--;
memmove(buf->b_ml.ml_chunksize, buf->b_ml.ml_chunksize + 1,
- buf->b_ml.ml_usedchunks * sizeof(chunksize_T));
+ buf->b_ml.ml_usedchunks * sizeof(chunksize_T));
return;
} else if (curix == 0 || (curchnk->mlcs_numlines > 10
&& (curchnk->mlcs_numlines +
@@ -3966,15 +4044,15 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype)
return;
}
- /* Collapse chunks */
+ // Collapse chunks
curchnk[-1].mlcs_numlines += curchnk->mlcs_numlines;
curchnk[-1].mlcs_totalsize += curchnk->mlcs_totalsize;
buf->b_ml.ml_usedchunks--;
if (curix < buf->b_ml.ml_usedchunks) {
memmove(buf->b_ml.ml_chunksize + curix,
- buf->b_ml.ml_chunksize + curix + 1,
- (buf->b_ml.ml_usedchunks - curix) *
- sizeof(chunksize_T));
+ buf->b_ml.ml_chunksize + curix + 1,
+ (buf->b_ml.ml_usedchunks - curix) *
+ sizeof(chunksize_T));
}
return;
}
@@ -3999,9 +4077,9 @@ long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp, bool no_ff)
linenr_T curline;
int curix;
long size;
- bhdr_T *hp;
- DATA_BL *dp;
- int count; /* number of entries in block */
+ bhdr_T *hp;
+ DATA_BL *dp;
+ int count; // number of entries in block
int idx;
int start_idx;
int text_end;
@@ -4029,15 +4107,18 @@ long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp, bool no_ff)
if (buf->b_ml.ml_usedchunks == -1
|| buf->b_ml.ml_chunksize == NULL
- || lnum < 0)
+ || lnum < 0) {
return -1;
+ }
- if (offp == NULL)
+ if (offp == NULL) {
offset = 0;
- else
+ } else {
offset = *offp;
- if (lnum == 0 && offset <= 0)
- return 1; /* Not a "find offset" and offset 0 _must_ be in line 1 */
+ }
+ if (lnum == 0 && offset <= 0) {
+ return 1; // Not a "find offset" and offset 0 _must_ be in line 1
+ }
/*
* Find the last chunk before the one containing our line. Last chunk is
* special because it will never qualify
@@ -4053,36 +4134,41 @@ long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp, bool no_ff)
+ ffdos * buf->b_ml.ml_chunksize[curix].mlcs_numlines))) {
curline += buf->b_ml.ml_chunksize[curix].mlcs_numlines;
size += buf->b_ml.ml_chunksize[curix].mlcs_totalsize;
- if (offset && ffdos)
+ if (offset && ffdos) {
size += buf->b_ml.ml_chunksize[curix].mlcs_numlines;
+ }
curix++;
}
while ((lnum != 0 && curline < lnum) || (offset != 0 && size < offset)) {
if (curline > buf->b_ml.ml_line_count
- || (hp = ml_find_line(buf, curline, ML_FIND)) == NULL)
+ || (hp = ml_find_line(buf, curline, ML_FIND)) == NULL) {
return -1;
+ }
dp = hp->bh_data;
count = (long)(buf->b_ml.ml_locked_high) -
(long)(buf->b_ml.ml_locked_low) + 1;
start_idx = idx = curline - buf->b_ml.ml_locked_low;
- if (idx == 0) /* first line in block, text at the end */
+ if (idx == 0) { // first line in block, text at the end
text_end = dp->db_txt_end;
- else
+ } else {
text_end = ((dp->db_index[idx - 1]) & DB_INDEX_MASK);
- /* Compute index of last line to use in this MEMLINE */
+ }
+ // Compute index of last line to use in this MEMLINE
if (lnum != 0) {
- if (curline + (count - idx) >= lnum)
+ if (curline + (count - idx) >= lnum) {
idx += lnum - curline - 1;
- else
+ } else {
idx = count - 1;
+ }
} else {
extra = 0;
while (offset >= size
+ text_end - (int)((dp->db_index[idx]) & DB_INDEX_MASK)
+ ffdos) {
- if (ffdos)
+ if (ffdos) {
size++;
+ }
if (idx == count - 1) {
extra = 1;
break;
@@ -4093,25 +4179,28 @@ long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp, bool no_ff)
len = text_end - ((dp->db_index[idx]) & DB_INDEX_MASK);
size += len;
if (offset != 0 && size >= offset) {
- if (size + ffdos == offset)
+ if (size + ffdos == offset) {
*offp = 0;
- else if (idx == start_idx)
+ } else if (idx == start_idx) {
*offp = offset - size + len;
- else
+ } else {
*offp = offset - size + len
- (text_end - ((dp->db_index[idx - 1]) & DB_INDEX_MASK));
+ }
curline += idx - start_idx + extra;
- if (curline > buf->b_ml.ml_line_count)
- return -1; /* exactly one byte beyond the end */
+ if (curline > buf->b_ml.ml_line_count) {
+ return -1; // exactly one byte beyond the end
+ }
return curline;
}
curline = buf->b_ml.ml_locked_high + 1;
}
if (lnum != 0) {
- /* Count extra CR characters. */
- if (ffdos)
+ // Count extra CR characters.
+ if (ffdos) {
size += lnum - 1;
+ }
/* Don't count the last line break if 'noeol' and ('bin' or
* 'nofixeol'). */
diff --git a/src/nvim/memory.c b/src/nvim/memory.c
index 7a8fc4da75..5e6c6a8189 100644
--- a/src/nvim/memory.c
+++ b/src/nvim/memory.c
@@ -1,26 +1,26 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
- // Various routines dealing with allocation and deallocation of memory.
+// Various routines dealing with allocation and deallocation of memory.
#include <assert.h>
#include <inttypes.h>
-#include <string.h>
#include <stdbool.h>
+#include <string.h>
-#include "nvim/vim.h"
+#include "nvim/api/vim.h"
#include "nvim/context.h"
+#include "nvim/decoration.h"
#include "nvim/eval.h"
#include "nvim/highlight.h"
+#include "nvim/lua/executor.h"
#include "nvim/memfile.h"
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/ui.h"
#include "nvim/sign.h"
-#include "nvim/api/vim.h"
-#include "nvim/lua/executor.h"
-#include "nvim/decoration.h"
+#include "nvim/ui.h"
+#include "nvim/vim.h"
#ifdef UNIT_TESTING
# define malloc(size) mem_malloc(size)
@@ -47,8 +47,9 @@ void try_to_free_memory(void)
{
static bool trying_to_free = false;
// avoid recursive calls
- if (trying_to_free)
+ if (trying_to_free) {
return;
+ }
trying_to_free = true;
// free any scrollback text
@@ -169,6 +170,8 @@ void *xrealloc(void *ptr, size_t size)
/// xmalloc() wrapper that allocates size + 1 bytes and zeroes the last byte
///
+/// Commonly used to allocate strings, e.g. `char *s = xmallocz(len)`.
+///
/// @see {xmalloc}
/// @param size
/// @return pointer to allocated space. Never NULL
@@ -182,7 +185,7 @@ void *xmallocz(size_t size)
}
void *ret = xmalloc(total_size);
- ((char*)ret)[size] = 0;
+ ((char *)ret)[size] = 0;
return ret;
}
@@ -339,16 +342,16 @@ char *xstpcpy(char *restrict dst, const char *restrict src)
char *xstpncpy(char *restrict dst, const char *restrict src, size_t maxlen)
FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
- const char *p = memchr(src, '\0', maxlen);
- if (p) {
- size_t srclen = (size_t)(p - src);
- memcpy(dst, src, srclen);
- memset(dst + srclen, 0, maxlen - srclen);
- return dst + srclen;
- } else {
- memcpy(dst, src, maxlen);
- return dst + maxlen;
- }
+ const char *p = memchr(src, '\0', maxlen);
+ if (p) {
+ size_t srclen = (size_t)(p - src);
+ memcpy(dst, src, srclen);
+ memset(dst + srclen, 0, maxlen - srclen);
+ return dst + srclen;
+ } else {
+ memcpy(dst, src, maxlen);
+ return dst + maxlen;
+ }
}
/// xstrlcpy - Copy a NUL-terminated string into a sized buffer
@@ -447,7 +450,7 @@ void *xmemrchr(const void *src, uint8_t c, size_t len)
{
while (len--) {
if (((uint8_t *)src)[len] == c) {
- return (uint8_t *) src + len;
+ return (uint8_t *)src + len;
}
}
return NULL;
@@ -500,7 +503,7 @@ bool striequal(const char *a, const char *b)
void do_outofmem_msg(size_t size)
{
if (!did_outofmem_msg) {
- /* Don't hide this message */
+ // Don't hide this message
emsg_silent = 0;
/* Must come first to avoid coming back here when printing the error
@@ -523,35 +526,35 @@ void time_to_bytes(time_t time_, uint8_t buf[8])
#if defined(EXITFREE)
-#include "nvim/file_search.h"
-#include "nvim/buffer.h"
-#include "nvim/charset.h"
-#include "nvim/diff.h"
-#include "nvim/edit.h"
-#include "nvim/ex_cmds.h"
-#include "nvim/ex_docmd.h"
-#include "nvim/ex_getln.h"
-#include "nvim/fileio.h"
-#include "nvim/fold.h"
-#include "nvim/getchar.h"
-#include "nvim/mark.h"
-#include "nvim/mbyte.h"
-#include "nvim/memline.h"
-#include "nvim/move.h"
-#include "nvim/option.h"
-#include "nvim/ops.h"
-#include "nvim/os_unix.h"
-#include "nvim/path.h"
-#include "nvim/quickfix.h"
-#include "nvim/regexp.h"
-#include "nvim/screen.h"
-#include "nvim/search.h"
-#include "nvim/spell.h"
-#include "nvim/syntax.h"
-#include "nvim/tag.h"
-#include "nvim/window.h"
-#include "nvim/os/os.h"
-#include "nvim/eval/typval.h"
+# include "nvim/buffer.h"
+# include "nvim/charset.h"
+# include "nvim/diff.h"
+# include "nvim/edit.h"
+# include "nvim/eval/typval.h"
+# include "nvim/ex_cmds.h"
+# include "nvim/ex_docmd.h"
+# include "nvim/ex_getln.h"
+# include "nvim/file_search.h"
+# include "nvim/fileio.h"
+# include "nvim/fold.h"
+# include "nvim/getchar.h"
+# include "nvim/mark.h"
+# include "nvim/mbyte.h"
+# include "nvim/memline.h"
+# include "nvim/move.h"
+# include "nvim/ops.h"
+# include "nvim/option.h"
+# include "nvim/os/os.h"
+# include "nvim/os_unix.h"
+# include "nvim/path.h"
+# include "nvim/quickfix.h"
+# include "nvim/regexp.h"
+# include "nvim/screen.h"
+# include "nvim/search.h"
+# include "nvim/spell.h"
+# include "nvim/syntax.h"
+# include "nvim/tag.h"
+# include "nvim/window.h"
/*
* Free everything that we allocated.
@@ -562,7 +565,7 @@ void time_to_bytes(time_t time_, uint8_t buf[8])
*/
void free_all_mem(void)
{
- buf_T *buf, *nextbuf;
+ buf_T *buf, *nextbuf;
// When we cause a crash here it is caught and Vim tries to exit cleanly.
// Don't try freeing everything again.
@@ -574,10 +577,11 @@ void free_all_mem(void)
// Don't want to trigger autocommands from here on.
block_autocmds();
- /* Close all tabs and windows. Reset 'equalalways' to avoid redraws. */
+ // Close all tabs and windows. Reset 'equalalways' to avoid redraws.
p_ea = false;
- if (first_tabpage->tp_next != NULL)
+ if (first_tabpage->tp_next != NULL) {
do_cmdline_cmd("tabonly!");
+ }
if (!ONE_WINDOW) {
// to keep things simple, don't perform this
@@ -586,17 +590,17 @@ void free_all_mem(void)
do_cmdline_cmd("only!");
}
- /* Free all spell info. */
+ // Free all spell info.
spell_free_all();
- /* Clear user commands (before deleting buffers). */
+ // Clear user commands (before deleting buffers).
ex_comclear(NULL);
- /* Clear menus. */
+ // Clear menus.
do_cmdline_cmd("aunmenu *");
do_cmdline_cmd("menutranslate clear");
- /* Clear mappings, abbreviations, breakpoints. */
+ // Clear mappings, abbreviations, breakpoints.
do_cmdline_cmd("lmapclear");
do_cmdline_cmd("xmapclear");
do_cmdline_cmd("mapclear");
@@ -609,7 +613,7 @@ void free_all_mem(void)
free_titles();
free_findfile();
- /* Obviously named calls. */
+ // Obviously named calls.
free_all_autocmds();
free_all_marks();
alist_clear(&global_alist);
@@ -627,25 +631,25 @@ void free_all_mem(void)
diff_clear(curtab);
clear_sb_text(true); // free any scrollback text
- /* Free some global vars. */
+ // Free some global vars.
xfree(last_cmdline);
xfree(new_last_cmdline);
set_keep_msg(NULL, 0);
- /* Clear cmdline history. */
+ // Clear cmdline history.
p_hi = 0;
init_history();
qf_free_all(NULL);
- /* Free all location lists */
+ // Free all location lists
FOR_ALL_TAB_WINDOWS(tab, win) {
qf_free_all(win);
}
- /* Close all script inputs. */
+ // Close all script inputs.
close_all_scripts();
- /* Destroy all windows. Must come before freeing buffers. */
+ // Destroy all windows. Must come before freeing buffers.
win_free_all();
// Free all option values. Must come after closing windows.
@@ -653,13 +657,13 @@ void free_all_mem(void)
free_arshape_buf();
- /* Clear registers. */
+ // Clear registers.
clear_registers();
ResetRedobuff();
ResetRedobuff();
- /* highlight info */
+ // highlight info
free_highlight();
reset_last_sourcing();
@@ -667,10 +671,12 @@ void free_all_mem(void)
free_tabpage(first_tabpage);
first_tabpage = NULL;
- /* message history */
- for (;; )
- if (delete_first_msg() == FAIL)
+ // message history
+ for (;; ) {
+ if (delete_first_msg() == FAIL) {
break;
+ }
+ }
eval_clear();
api_vim_free_all_mem();
diff --git a/src/nvim/menu.c b/src/nvim/menu.c
index 112f51fc64..2b1a250604 100644
--- a/src/nvim/menu.c
+++ b/src/nvim/menu.c
@@ -10,27 +10,27 @@
#include <inttypes.h>
#include <string.h>
-#include "nvim/vim.h"
#include "nvim/ascii.h"
-#include "nvim/menu.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
#include "nvim/eval.h"
+#include "nvim/eval/typval.h"
#include "nvim/ex_docmd.h"
+#include "nvim/garray.h"
#include "nvim/getchar.h"
+#include "nvim/keymap.h"
#include "nvim/memory.h"
+#include "nvim/menu.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/keymap.h"
-#include "nvim/garray.h"
+#include "nvim/screen.h"
#include "nvim/state.h"
#include "nvim/strings.h"
#include "nvim/ui.h"
-#include "nvim/eval/typval.h"
-#include "nvim/screen.h"
+#include "nvim/vim.h"
#include "nvim/window.h"
-#define MENUDEPTH 10 /* maximum depth of menus */
+#define MENUDEPTH 10 // maximum depth of menus
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -43,8 +43,7 @@
/// The character for each menu mode
static char_u menu_mode_chars[] = { 'n', 'v', 's', 'o', 'i', 'c', 't' };
-static char_u e_notsubmenu[] = N_(
- "E327: Part of menu-item path is not sub-menu");
+static char_u e_notsubmenu[] = N_("E327: Part of menu-item path is not sub-menu");
static char_u e_othermode[] = N_("E328: Menu only exists in another mode");
static char_u e_nomenu[] = N_("E329: No menu \"%s\"");
@@ -63,18 +62,17 @@ static vimmenu_T **get_root_menu(const char_u *const name)
/// Do the :menu command and relatives.
/// @param eap Ex command arguments
-void
-ex_menu(exarg_T *eap)
+void ex_menu(exarg_T *eap)
{
- char_u *menu_path;
+ char_u *menu_path;
int modes;
- char_u *map_to; // command mapped to the menu entry
+ char_u *map_to; // command mapped to the menu entry
int noremap;
bool silent = false;
int unmenu;
- char_u *map_buf;
- char_u *arg;
- char_u *p;
+ char_u *map_buf;
+ char_u *arg;
+ char_u *p;
int i;
long pri_tab[MENUDEPTH + 1];
TriState enable = kNone; // kTrue for "menu enable",
@@ -109,8 +107,9 @@ ex_menu(exarg_T *eap)
if (STRNCMP(arg, "icon=", 5) == 0) {
arg += 5;
while (*arg != NUL && *arg != ' ') {
- if (*arg == '\\')
+ if (*arg == '\\') {
STRMOVE(arg, arg + 1);
+ }
MB_PTR_ADV(arg);
}
if (*arg != NUL) {
@@ -139,11 +138,13 @@ ex_menu(exarg_T *eap)
} else if (eap->addr_count && eap->line2 != 0) {
pri_tab[0] = eap->line2;
i = 1;
- } else
+ } else {
i = 0;
- while (i < MENUDEPTH)
+ }
+ while (i < MENUDEPTH) {
pri_tab[i++] = 500;
- pri_tab[MENUDEPTH] = -1; /* mark end of the table */
+ }
+ pri_tab[MENUDEPTH] = -1; // mark end of the table
/*
* Check for "disable" or "enable" argument.
@@ -195,31 +196,34 @@ ex_menu(exarg_T *eap)
}
if (menu_is_popup(menu_path)) {
- for (i = 0; i < MENU_INDEX_TIP; ++i)
+ for (i = 0; i < MENU_INDEX_TIP; ++i) {
if (modes & (1 << i)) {
p = popup_mode_name(menu_path, i);
menu_enable_recurse(*root_menu_ptr, p, MENU_ALL_MODES, enable);
xfree(p);
}
+ }
}
menu_enable_recurse(*root_menu_ptr, menu_path, modes, enable);
} else if (unmenu) {
/*
* Delete menu(s).
*/
- if (STRCMP(menu_path, "*") == 0) /* meaning: remove all menus */
+ if (STRCMP(menu_path, "*") == 0) { // meaning: remove all menus
menu_path = (char_u *)"";
+ }
/*
* For the PopUp menu, remove a menu for each mode separately.
*/
if (menu_is_popup(menu_path)) {
- for (i = 0; i < MENU_INDEX_TIP; ++i)
+ for (i = 0; i < MENU_INDEX_TIP; ++i) {
if (modes & (1 << i)) {
p = popup_mode_name(menu_path, i);
remove_menu(root_menu_ptr, p, MENU_ALL_MODES, true);
xfree(p);
}
+ }
}
// Careful: remove_menu() changes menu_path
@@ -229,7 +233,7 @@ ex_menu(exarg_T *eap)
* Add menu(s).
* Replace special key codes.
*/
- if (STRICMP(map_to, "<nop>") == 0) { /* "<Nop>" means nothing */
+ if (STRICMP(map_to, "<nop>") == 0) { // "<Nop>" means nothing
map_to = (char_u *)"";
map_buf = NULL;
} else if (modes & MENU_TIP_MODE) {
@@ -247,7 +251,7 @@ ex_menu(exarg_T *eap)
* For the PopUp menu, add a menu for each mode separately.
*/
if (menu_is_popup(menu_path)) {
- for (i = 0; i < MENU_INDEX_TIP; ++i)
+ for (i = 0; i < MENU_INDEX_TIP; ++i) {
if (modes & (1 << i)) {
p = popup_mode_name(menu_path, i);
// Include all modes, to make ":amenu" work
@@ -255,6 +259,7 @@ ex_menu(exarg_T *eap)
add_menu_path(p, &menuarg, pri_tab, map_to);
xfree(p);
}
+ }
}
xfree(map_buf);
@@ -272,33 +277,28 @@ theend:
/// @param[out] menuarg menu entry
/// @param[] pri_tab priority table
/// @param[in] call_data Right hand side command
-static int
-add_menu_path(
- const char_u *const menu_path,
- vimmenu_T *menuarg,
- const long *const pri_tab,
- const char_u *const call_data
-)
+static int add_menu_path(const char_u *const menu_path, vimmenu_T *menuarg,
+ const long *const pri_tab, const char_u *const call_data)
{
- char_u *path_name;
+ char_u *path_name;
int modes = menuarg->modes;
- vimmenu_T *menu = NULL;
- vimmenu_T *parent;
- vimmenu_T **lower_pri;
- char_u *p;
- char_u *name;
- char_u *dname;
- char_u *next_name;
+ vimmenu_T *menu = NULL;
+ vimmenu_T *parent;
+ vimmenu_T **lower_pri;
+ char_u *p;
+ char_u *name;
+ char_u *dname;
+ char_u *next_name;
char_u c;
char_u d;
int i;
int pri_idx = 0;
int old_modes = 0;
int amenu;
- char_u *en_name;
- char_u *map_to = NULL;
+ char_u *en_name;
+ char_u *map_to = NULL;
- /* Make a copy so we can stuff around with it, since it could be const */
+ // Make a copy so we can stuff around with it, since it could be const
path_name = vim_strsave(menu_path);
vimmenu_T **root_menu_ptr = get_root_menu(menu_path);
vimmenu_T **menup = root_menu_ptr;
@@ -317,12 +317,12 @@ add_menu_path(
}
dname = menu_text(name, NULL, NULL);
if (*dname == NUL) {
- /* Only a mnemonic or accelerator is not valid. */
+ // Only a mnemonic or accelerator is not valid.
EMSG(_("E792: Empty menu name"));
goto erret;
}
- /* See if it's already there */
+ // See if it's already there
lower_pri = menup;
menu = *menup;
while (menu != NULL) {
@@ -364,7 +364,7 @@ add_menu_path(
goto erret;
}
- /* Not already there, so lets add it */
+ // Not already there, so lets add it
menu = xcalloc(1, sizeof(vimmenu_T));
menu->modes = modes;
@@ -387,7 +387,6 @@ add_menu_path(
*lower_pri = menu;
old_modes = 0;
-
} else {
old_modes = menu->modes;
@@ -419,16 +418,17 @@ add_menu_path(
*/
amenu = ((modes & (MENU_NORMAL_MODE | MENU_INSERT_MODE)) ==
(MENU_NORMAL_MODE | MENU_INSERT_MODE));
- if (sys_menu)
+ if (sys_menu) {
modes &= ~old_modes;
+ }
if (menu != NULL && modes) {
p = (call_data == NULL) ? NULL : vim_strsave(call_data);
- /* loop over all modes, may add more than one */
+ // loop over all modes, may add more than one
for (i = 0; i < MENU_MODES; ++i) {
if (modes & (1 << i)) {
- /* free any old menu */
+ // free any old menu
free_menu_string(menu, i);
// For "amenu", may insert an extra character.
@@ -462,7 +462,7 @@ add_menu_path(
if (c == Ctrl_C) {
int len = (int)STRLEN(menu->strings[i]);
- /* Append CTRL-\ CTRL-G to obey 'insertmode'. */
+ // Append CTRL-\ CTRL-G to obey 'insertmode'.
menu->strings[i][len] = Ctrl_BSL;
menu->strings[i][len + 1] = Ctrl_G;
menu->strings[i][len + 2] = NUL;
@@ -504,20 +504,17 @@ erret:
* Set the (sub)menu with the given name to enabled or disabled.
* Called recursively.
*/
-static int menu_enable_recurse(vimmenu_T *menu,
- char_u *name,
- int modes,
- int enable)
+static int menu_enable_recurse(vimmenu_T *menu, char_u *name, int modes, int enable)
{
- char_u *p;
-
- if (menu == NULL)
- return OK; /* Got to bottom of hierarchy */
+ char_u *p;
- /* Get name of this element in the menu hierarchy */
+ if (menu == NULL) {
+ return OK; // Got to bottom of hierarchy
+ }
+ // Get name of this element in the menu hierarchy
p = menu_name_skip(name);
- /* Find the menu */
+ // Find the menu
while (menu != NULL) {
if (*name == NUL || *name == '*' || menu_name_equal(name, menu)) {
if (*p != NUL) {
@@ -539,8 +536,9 @@ static int menu_enable_recurse(vimmenu_T *menu,
* modes, so keep looping, otherwise we are just doing the named
* menu item (which has been found) so break here.
*/
- if (*name != NUL && *name != '*')
+ if (*name != NUL && *name != '*') {
break;
+ }
}
menu = menu->next;
}
@@ -553,42 +551,39 @@ static int menu_enable_recurse(vimmenu_T *menu,
return OK;
}
-/*
- * Remove the (sub)menu with the given name from the menu hierarchy
- * Called recursively.
- */
-static int
-remove_menu (
- vimmenu_T **menup,
- char_u *name,
- int modes,
- bool silent /* don't give error messages */
-)
+/// Remove the (sub)menu with the given name from the menu hierarchy
+/// Called recursively.
+///
+/// @param silent don't give error messages
+static int remove_menu(vimmenu_T **menup, char_u *name, int modes, bool silent)
{
- vimmenu_T *menu;
- vimmenu_T *child;
- char_u *p;
-
- if (*menup == NULL)
- return OK; /* Got to bottom of hierarchy */
+ vimmenu_T *menu;
+ vimmenu_T *child;
+ char_u *p;
- /* Get name of this element in the menu hierarchy */
+ if (*menup == NULL) {
+ return OK; // Got to bottom of hierarchy
+ }
+ // Get name of this element in the menu hierarchy
p = menu_name_skip(name);
- /* Find the menu */
+ // Find the menu
while ((menu = *menup) != NULL) {
if (*name == NUL || menu_name_equal(name, menu)) {
if (*p != NUL && menu->children == NULL) {
- if (!silent)
+ if (!silent) {
EMSG(_(e_notsubmenu));
+ }
return FAIL;
}
if ((menu->modes & modes) != 0x0) {
- if (remove_menu(&menu->children, p, modes, silent) == FAIL)
+ if (remove_menu(&menu->children, p, modes, silent) == FAIL) {
return FAIL;
+ }
} else if (*name != NUL) {
- if (!silent)
+ if (!silent) {
EMSG(_(e_othermode));
+ }
return FAIL;
}
@@ -597,39 +592,45 @@ remove_menu (
* modes, so keep looping, otherwise we are just removing the named
* menu item (which has been found) so break here.
*/
- if (*name != NUL)
+ if (*name != NUL) {
break;
+ }
/* Remove the menu item for the given mode[s]. If the menu item
* is no longer valid in ANY mode, delete it */
menu->modes &= ~modes;
- if (modes & MENU_TIP_MODE)
+ if (modes & MENU_TIP_MODE) {
free_menu_string(menu, MENU_INDEX_TIP);
- if ((menu->modes & MENU_ALL_MODES) == 0)
+ }
+ if ((menu->modes & MENU_ALL_MODES) == 0) {
free_menu(menup);
- else
+ } else {
menup = &menu->next;
- } else
+ }
+ } else {
menup = &menu->next;
+ }
}
if (*name != NUL) {
if (menu == NULL) {
- if (!silent)
+ if (!silent) {
EMSG2(_(e_nomenu), name);
+ }
return FAIL;
}
- /* Recalculate modes for menu based on the new updated children */
+ // Recalculate modes for menu based on the new updated children
menu->modes &= ~modes;
child = menu->children;
- for (; child != NULL; child = child->next)
+ for (; child != NULL; child = child->next) {
menu->modes |= child->modes;
+ }
if (modes & MENU_TIP_MODE) {
free_menu_string(menu, MENU_INDEX_TIP);
}
if ((menu->modes & MENU_ALL_MODES) == 0) {
- /* The menu item is no longer valid in ANY mode, so delete it */
+ // The menu item is no longer valid in ANY mode, so delete it
*menup = menu;
free_menu(menup);
}
@@ -644,7 +645,7 @@ remove_menu (
static void free_menu(vimmenu_T **menup)
{
int i;
- vimmenu_T *menu;
+ vimmenu_T *menu;
menu = *menup;
@@ -657,10 +658,10 @@ static void free_menu(vimmenu_T **menup)
xfree(menu->en_name);
xfree(menu->en_dname);
xfree(menu->actext);
- for (i = 0; i < MENU_MODES; i++)
+ for (i = 0; i < MENU_MODES; i++) {
free_menu_string(menu, i);
+ }
xfree(menu);
-
}
/*
@@ -671,11 +672,14 @@ static void free_menu_string(vimmenu_T *menu, int idx)
int count = 0;
int i;
- for (i = 0; i < MENU_MODES; i++)
- if (menu->strings[i] == menu->strings[idx])
+ for (i = 0; i < MENU_MODES; i++) {
+ if (menu->strings[i] == menu->strings[idx]) {
count++;
- if (count == 1)
+ }
+ }
+ if (count == 1) {
xfree(menu->strings[idx]);
+ }
menu->strings[idx] = NULL;
}
@@ -793,8 +797,8 @@ static vimmenu_T *find_menu(vimmenu_T *menu, char_u *name, int modes)
if (menu_name_equal(name, menu)) {
// Found menu
if (*p != NUL && menu->children == NULL) {
- EMSG(_(e_notsubmenu));
- return NULL;
+ EMSG(_(e_notsubmenu));
+ return NULL;
} else if ((menu->modes & modes) == 0x0) {
EMSG(_(e_othermode));
return NULL;
@@ -826,8 +830,8 @@ static int show_menus(char_u *const path_name, int modes)
return FAIL;
}
- /* Now we have found the matching menu, and we list the mappings */
- /* Highlight title */
+ // Now we have found the matching menu, and we list the mappings
+ // Highlight title
MSG_PUTS_TITLE(_("\n--- Menus ---"));
show_menus_recursive(menu->parent, modes, 0);
@@ -840,15 +844,18 @@ static void show_menus_recursive(vimmenu_T *menu, int modes, int depth)
int i;
int bit;
- if (menu != NULL && (menu->modes & modes) == 0x0)
+ if (menu != NULL && (menu->modes & modes) == 0x0) {
return;
+ }
if (menu != NULL) {
msg_putchar('\n');
- if (got_int) /* "q" hit for "--more--" */
+ if (got_int) { // "q" hit for "--more--"
return;
- for (i = 0; i < depth; i++)
+ }
+ for (i = 0; i < depth; i++) {
MSG_PUTS(" ");
+ }
if (menu->priority) {
msg_outnum((long)menu->priority);
MSG_PUTS(" ");
@@ -858,28 +865,33 @@ static void show_menus_recursive(vimmenu_T *menu, int modes, int depth)
}
if (menu != NULL && menu->children == NULL) {
- for (bit = 0; bit < MENU_MODES; bit++)
+ for (bit = 0; bit < MENU_MODES; bit++) {
if ((menu->modes & modes & (1 << bit)) != 0) {
msg_putchar('\n');
- if (got_int) /* "q" hit for "--more--" */
+ if (got_int) { // "q" hit for "--more--"
return;
- for (i = 0; i < depth + 2; i++)
+ }
+ for (i = 0; i < depth + 2; i++) {
MSG_PUTS(" ");
+ }
msg_putchar(menu_mode_chars[bit]);
- if (menu->noremap[bit] == REMAP_NONE)
+ if (menu->noremap[bit] == REMAP_NONE) {
msg_putchar('*');
- else if (menu->noremap[bit] == REMAP_SCRIPT)
+ } else if (menu->noremap[bit] == REMAP_SCRIPT) {
msg_putchar('&');
- else
+ } else {
msg_putchar(' ');
- if (menu->silent[bit])
+ }
+ if (menu->silent[bit]) {
msg_putchar('s');
- else
+ } else {
msg_putchar(' ');
- if ((menu->modes & menu->enabled & (1 << bit)) == 0)
+ }
+ if ((menu->modes & menu->enabled & (1 << bit)) == 0) {
msg_putchar('-');
- else
+ } else {
msg_putchar(' ');
+ }
MSG_PUTS(" ");
if (*menu->strings[bit] == NUL) {
msg_puts_attr("<Nop>", HL_ATTR(HLF_8));
@@ -887,17 +899,21 @@ static void show_menus_recursive(vimmenu_T *menu, int modes, int depth)
msg_outtrans_special(menu->strings[bit], false, 0);
}
}
+ }
} else {
if (menu == NULL) {
menu = root_menu;
depth--;
- } else
+ } else {
menu = menu->children;
+ }
- /* recursively show all children. Skip PopUp[nvoci]. */
- for (; menu != NULL && !got_int; menu = menu->next)
- if (!menu_is_hidden(menu->dname))
+ // recursively show all children. Skip PopUp[nvoci].
+ for (; menu != NULL && !got_int; menu = menu->next) {
+ if (!menu_is_hidden(menu->dname)) {
show_menus_recursive(menu, modes, depth + 1);
+ }
+ }
}
}
@@ -905,57 +921,61 @@ static void show_menus_recursive(vimmenu_T *menu, int modes, int depth)
/*
* Used when expanding menu names.
*/
-static vimmenu_T *expand_menu = NULL;
+static vimmenu_T *expand_menu = NULL;
static int expand_modes = 0x0;
-static int expand_emenu; /* TRUE for ":emenu" command */
+static int expand_emenu; // TRUE for ":emenu" command
/*
* Work out what to complete when doing command line completion of menu names.
*/
-char_u *set_context_in_menu_cmd(expand_T *xp, const char *cmd, char_u *arg,
- bool forceit)
+char_u *set_context_in_menu_cmd(expand_T *xp, const char *cmd, char_u *arg, bool forceit)
FUNC_ATTR_NONNULL_ALL
{
- char_u *after_dot;
- char_u *p;
- char_u *path_name = NULL;
- char_u *name;
+ char_u *after_dot;
+ char_u *p;
+ char_u *path_name = NULL;
+ char_u *name;
int unmenu;
- vimmenu_T *menu;
+ vimmenu_T *menu;
int expand_menus;
xp->xp_context = EXPAND_UNSUCCESSFUL;
- /* Check for priority numbers, enable and disable */
- for (p = arg; *p; ++p)
- if (!ascii_isdigit(*p) && *p != '.')
+ // Check for priority numbers, enable and disable
+ for (p = arg; *p; ++p) {
+ if (!ascii_isdigit(*p) && *p != '.') {
break;
+ }
+ }
if (!ascii_iswhite(*p)) {
if (STRNCMP(arg, "enable", 6) == 0
- && (arg[6] == NUL || ascii_iswhite(arg[6])))
+ && (arg[6] == NUL || ascii_iswhite(arg[6]))) {
p = arg + 6;
- else if (STRNCMP(arg, "disable", 7) == 0
- && (arg[7] == NUL || ascii_iswhite(arg[7])))
+ } else if (STRNCMP(arg, "disable", 7) == 0
+ && (arg[7] == NUL || ascii_iswhite(arg[7]))) {
p = arg + 7;
- else
+ } else {
p = arg;
+ }
}
- while (*p != NUL && ascii_iswhite(*p))
+ while (*p != NUL && ascii_iswhite(*p)) {
++p;
+ }
arg = after_dot = p;
for (; *p && !ascii_iswhite(*p); ++p) {
- if ((*p == '\\' || *p == Ctrl_V) && p[1] != NUL)
+ if ((*p == '\\' || *p == Ctrl_V) && p[1] != NUL) {
p++;
- else if (*p == '.')
+ } else if (*p == '.') {
after_dot = p + 1;
+ }
}
- // ":popup" only uses menues, not entries
+ // ":popup" only uses menus, not entries
expand_menus = !((*cmd == 't' && cmd[1] == 'e') || *cmd == 'p');
expand_emenu = (*cmd == 'e');
if (expand_menus && ascii_iswhite(*p)) {
@@ -966,12 +986,13 @@ char_u *set_context_in_menu_cmd(expand_T *xp, const char *cmd, char_u *arg,
// With :menu though you might want to add a menu with the same name as
// one in another mode, so match menus from other modes too.
expand_modes = get_menu_cmd_modes(cmd, forceit, NULL, &unmenu);
- if (!unmenu)
+ if (!unmenu) {
expand_modes = MENU_ALL_MODES;
+ }
menu = root_menu;
if (after_dot > arg) {
- size_t path_len = (size_t) (after_dot - arg);
+ size_t path_len = (size_t)(after_dot - arg);
path_name = xmalloc(path_len);
STRLCPY(path_name, arg, path_len);
}
@@ -980,7 +1001,7 @@ char_u *set_context_in_menu_cmd(expand_T *xp, const char *cmd, char_u *arg,
p = menu_name_skip(name);
while (menu != NULL) {
if (menu_name_equal(name, menu)) {
- /* Found menu */
+ // Found menu
if ((*p != NUL && menu->children == NULL)
|| ((menu->modes & expand_modes) == 0x0)) {
/*
@@ -995,7 +1016,7 @@ char_u *set_context_in_menu_cmd(expand_T *xp, const char *cmd, char_u *arg,
menu = menu->next;
}
if (menu == NULL) {
- /* No menu found with the name we were looking for */
+ // No menu found with the name we were looking for
xfree(path_name);
return NULL;
}
@@ -1019,35 +1040,38 @@ char_u *set_context_in_menu_cmd(expand_T *xp, const char *cmd, char_u *arg,
*/
char_u *get_menu_name(expand_T *xp, int idx)
{
- static vimmenu_T *menu = NULL;
- char_u *str;
+ static vimmenu_T *menu = NULL;
+ char_u *str;
static int should_advance = FALSE;
- if (idx == 0) { /* first call: start at first item */
+ if (idx == 0) { // first call: start at first item
menu = expand_menu;
should_advance = false;
}
- /* Skip PopUp[nvoci]. */
+ // Skip PopUp[nvoci].
while (menu != NULL && (menu_is_hidden(menu->dname)
|| menu_is_separator(menu->dname)
|| menu->children == NULL)) {
menu = menu->next;
}
- if (menu == NULL) /* at end of linked list */
+ if (menu == NULL) { // at end of linked list
return NULL;
+ }
- if (menu->modes & expand_modes)
- if (should_advance)
+ if (menu->modes & expand_modes) {
+ if (should_advance) {
str = menu->en_dname;
- else {
+ } else {
str = menu->dname;
- if (menu->en_dname == NULL)
+ if (menu->en_dname == NULL) {
should_advance = TRUE;
+ }
}
- else
+ } else {
str = (char_u *)"";
+ }
if (should_advance) {
// Advance to next menu entry.
@@ -1065,18 +1089,18 @@ char_u *get_menu_name(expand_T *xp, int idx)
*/
char_u *get_menu_names(expand_T *xp, int idx)
{
- static vimmenu_T *menu = NULL;
+ static vimmenu_T *menu = NULL;
#define TBUFFER_LEN 256
- static char_u tbuffer[TBUFFER_LEN]; /*hack*/
- char_u *str;
+ static char_u tbuffer[TBUFFER_LEN]; //hack
+ char_u *str;
static bool should_advance = false;
- if (idx == 0) { /* first call: start at first item */
+ if (idx == 0) { // first call: start at first item
menu = expand_menu;
should_advance = false;
}
- /* Skip Browse-style entries, popup menus and separators. */
+ // Skip Browse-style entries, popup menus and separators.
while (menu != NULL
&& (menu_is_hidden(menu->dname)
|| (expand_emenu && menu_is_separator(menu->dname))
@@ -1084,8 +1108,9 @@ char_u *get_menu_names(expand_T *xp, int idx)
menu = menu->next;
}
- if (menu == NULL) /* at end of linked list */
+ if (menu == NULL) { // at end of linked list
return NULL;
+ }
if (menu->modes & expand_modes) {
if (menu->children != NULL) {
@@ -1102,17 +1127,18 @@ char_u *get_menu_names(expand_T *xp, int idx)
STRCAT(tbuffer, "\001");
str = tbuffer;
} else {
- if (should_advance)
+ if (should_advance) {
str = menu->en_dname;
- else {
+ } else {
str = menu->dname;
if (menu->en_dname == NULL) {
should_advance = true;
}
}
}
- } else
+ } else {
str = (char_u *)"";
+ }
if (should_advance) {
// Advance to next menu entry.
@@ -1132,17 +1158,19 @@ char_u *get_menu_names(expand_T *xp, int idx)
/// @return start of the next element
char_u *menu_name_skip(char_u *const name)
{
- char_u *p;
+ char_u *p;
for (p = name; *p && *p != '.'; MB_PTR_ADV(p)) {
if (*p == '\\' || *p == Ctrl_V) {
STRMOVE(p, p + 1);
- if (*p == NUL)
+ if (*p == NUL) {
break;
+ }
}
}
- if (*p)
+ if (*p) {
*p++ = NUL;
+ }
return p;
}
@@ -1154,8 +1182,9 @@ static bool menu_name_equal(const char_u *const name, vimmenu_T *const menu)
{
if (menu->en_name != NULL
&& (menu_namecmp(name, menu->en_name)
- || menu_namecmp(name, menu->en_dname)))
+ || menu_namecmp(name, menu->en_dname))) {
return true;
+ }
return menu_namecmp(name, menu->name) || menu_namecmp(name, menu->dname);
}
@@ -1163,9 +1192,11 @@ static bool menu_namecmp(const char_u *const name, const char_u *const mname)
{
int i;
- for (i = 0; name[i] != NUL && name[i] != TAB; ++i)
- if (name[i] != mname[i])
+ for (i = 0; name[i] != NUL && name[i] != TAB; ++i) {
+ if (name[i] != mname[i]) {
break;
+ }
+ }
return (name[i] == NUL || name[i] == TAB)
&& (mname[i] == NUL || mname[i] == TAB);
}
@@ -1180,45 +1211,39 @@ static bool menu_namecmp(const char_u *const name, const char_u *const mname)
/// to whether the command is a "nore" command.
/// @param[out] unmenu If not NULL, the flag it points to is set according
/// to whether the command is an "unmenu" command.
-int
-get_menu_cmd_modes(
- const char *cmd,
- bool forceit,
- int *noremap,
- int *unmenu
-)
+int get_menu_cmd_modes(const char *cmd, bool forceit, int *noremap, int *unmenu)
{
int modes;
switch (*cmd++) {
- case 'v': /* vmenu, vunmenu, vnoremenu */
+ case 'v': // vmenu, vunmenu, vnoremenu
modes = MENU_VISUAL_MODE | MENU_SELECT_MODE;
break;
- case 'x': /* xmenu, xunmenu, xnoremenu */
+ case 'x': // xmenu, xunmenu, xnoremenu
modes = MENU_VISUAL_MODE;
break;
- case 's': /* smenu, sunmenu, snoremenu */
+ case 's': // smenu, sunmenu, snoremenu
modes = MENU_SELECT_MODE;
break;
- case 'o': /* omenu */
+ case 'o': // omenu
modes = MENU_OP_PENDING_MODE;
break;
- case 'i': /* imenu */
+ case 'i': // imenu
modes = MENU_INSERT_MODE;
break;
case 't':
- modes = MENU_TIP_MODE; /* tmenu */
+ modes = MENU_TIP_MODE; // tmenu
break;
- case 'c': /* cmenu */
+ case 'c': // cmenu
modes = MENU_CMDLINE_MODE;
break;
- case 'a': /* amenu */
+ case 'a': // amenu
modes = MENU_INSERT_MODE | MENU_CMDLINE_MODE | MENU_NORMAL_MODE
| MENU_VISUAL_MODE | MENU_SELECT_MODE
| MENU_OP_PENDING_MODE;
break;
case 'n':
- if (*cmd != 'o') { /* nmenu, not noremenu */
+ if (*cmd != 'o') { // nmenu, not noremenu
modes = MENU_NORMAL_MODE;
break;
}
@@ -1235,10 +1260,12 @@ get_menu_cmd_modes(
}
}
- if (noremap != NULL)
+ if (noremap != NULL) {
*noremap = (*cmd == 'n' ? REMAP_NONE : REMAP_YES);
- if (unmenu != NULL)
+ }
+ if (unmenu != NULL) {
*unmenu = (*cmd == 'u');
+ }
return modes;
}
@@ -1274,27 +1301,31 @@ static char_u *menu_text(const char_u *str, int *mnemonic, char_u **actext)
FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT
FUNC_ATTR_NONNULL_ARG(1)
{
- char_u *p;
- char_u *text;
+ char_u *p;
+ char_u *text;
- /* Locate accelerator text, after the first TAB */
+ // Locate accelerator text, after the first TAB
p = vim_strchr(str, TAB);
if (p != NULL) {
- if (actext != NULL)
+ if (actext != NULL) {
*actext = vim_strsave(p + 1);
+ }
assert(p >= str);
text = vim_strnsave(str, (size_t)(p - str));
- } else
+ } else {
text = vim_strsave(str);
+ }
- /* Find mnemonic characters "&a" and reduce "&&" to "&". */
+ // Find mnemonic characters "&a" and reduce "&&" to "&".
for (p = text; p != NULL; ) {
p = vim_strchr(p, '&');
if (p != NULL) {
- if (p[1] == NUL) /* trailing "&" */
+ if (p[1] == NUL) { // trailing "&"
break;
- if (mnemonic != NULL && p[1] != '&')
+ }
+ if (mnemonic != NULL && p[1] != '&') {
*mnemonic = p[1];
+ }
STRMOVE(p, p + 1);
p = p + 1;
}
@@ -1343,7 +1374,7 @@ int menu_is_separator(char_u *name)
static int menu_is_hidden(char_u *name)
{
return (name[0] == MNU_HIDDEN_CHAR)
- || (menu_is_popup(name) && name[5] != NUL);
+ || (menu_is_popup(name) && name[5] != NUL);
}
// Execute "menu". Use by ":emenu" and the window toolbar.
@@ -1359,8 +1390,8 @@ static void execute_menu(const exarg_T *eap, vimmenu_T *menu)
mode = (char_u *)"Insert";
idx = MENU_INDEX_INSERT;
} else if (State & CMDLINE) {
- mode = (char_u *)"Command";
- idx = MENU_INDEX_CMDLINE;
+ mode = (char_u *)"Command";
+ idx = MENU_INDEX_CMDLINE;
} else if (get_real_state() & VISUAL) {
/* Detect real visual mode -- if we are really in visual mode we
* don't need to do any guesswork to figure out what the selection
@@ -1379,13 +1410,13 @@ static void execute_menu(const exarg_T *eap, vimmenu_T *menu)
* select start and end. */
if ((curbuf->b_visual.vi_start.lnum == eap->line1)
&& (curbuf->b_visual.vi_end.lnum) == eap->line2) {
- /* Set it up for visual mode - equivalent to gv. */
+ // Set it up for visual mode - equivalent to gv.
VIsual_mode = curbuf->b_visual.vi_mode;
tpos = curbuf->b_visual.vi_end;
curwin->w_cursor = curbuf->b_visual.vi_start;
curwin->w_curswant = curbuf->b_visual.vi_curswant;
} else {
- /* Set it up for line-wise visual mode */
+ // Set it up for line-wise visual mode
VIsual_mode = 'V';
curwin->w_cursor.lnum = eap->line1;
curwin->w_cursor.col = 1;
@@ -1394,7 +1425,7 @@ static void execute_menu(const exarg_T *eap, vimmenu_T *menu)
tpos.coladd = 0;
}
- /* Activate visual mode */
+ // Activate visual mode
VIsual_active = TRUE;
VIsual_reselect = TRUE;
check_cursor();
@@ -1484,15 +1515,15 @@ void ex_emenu(exarg_T *eap)
*/
typedef struct {
- char_u *from; /* English name */
- char_u *from_noamp; /* same, without '&' */
- char_u *to; /* translated name */
+ char_u *from; // English name
+ char_u *from_noamp; // same, without '&'
+ char_u *to; // translated name
} menutrans_T;
static garray_T menutrans_ga = GA_EMPTY_INIT_VALUE;
#define FREE_MENUTRANS(mt) \
- menutrans_T* _mt = (mt); \
+ menutrans_T * _mt = (mt); \
xfree(_mt->from); \
xfree(_mt->from_noamp); \
xfree(_mt->to)
@@ -1504,11 +1535,12 @@ static garray_T menutrans_ga = GA_EMPTY_INIT_VALUE;
*/
void ex_menutranslate(exarg_T *eap)
{
- char_u *arg = eap->arg;
- char_u *from, *from_noamp, *to;
+ char_u *arg = eap->arg;
+ char_u *from, *from_noamp, *to;
- if (menutrans_ga.ga_itemsize == 0)
+ if (menutrans_ga.ga_itemsize == 0) {
ga_init(&menutrans_ga, (int)sizeof(menutrans_T), 5);
+ }
/*
* ":menutrans clear": clear all translations.
@@ -1516,18 +1548,18 @@ void ex_menutranslate(exarg_T *eap)
if (STRNCMP(arg, "clear", 5) == 0 && ends_excmd(*skipwhite(arg + 5))) {
GA_DEEP_CLEAR(&menutrans_ga, menutrans_T, FREE_MENUTRANS);
- /* Delete all "menutrans_" global variables. */
+ // Delete all "menutrans_" global variables.
del_menutrans_vars();
} else {
- /* ":menutrans from to": add translation */
+ // ":menutrans from to": add translation
from = arg;
arg = menu_skip_part(arg);
to = skipwhite(arg);
*arg = NUL;
arg = menu_skip_part(to);
- if (arg == to)
+ if (arg == to) {
EMSG(_(e_invarg));
- else {
+ } else {
from = vim_strsave(from);
from_noamp = menu_text(from, NULL, NULL);
assert(arg >= to);
@@ -1536,7 +1568,7 @@ void ex_menutranslate(exarg_T *eap)
menu_translate_tab_and_shift(to);
menu_unescape_name(from);
menu_unescape_name(to);
- menutrans_T* tp = GA_APPEND_VIA_PTR(menutrans_T, &menutrans_ga);
+ menutrans_T * tp = GA_APPEND_VIA_PTR(menutrans_T, &menutrans_ga);
tp->from = from;
tp->from_noamp = from_noamp;
tp->to = to;
@@ -1550,8 +1582,9 @@ void ex_menutranslate(exarg_T *eap)
static char_u *menu_skip_part(char_u *p)
{
while (*p != NUL && *p != '.' && !ascii_iswhite(*p)) {
- if ((*p == '\\' || *p == Ctrl_V) && p[1] != NUL)
+ if ((*p == '\\' || *p == Ctrl_V) && p[1] != NUL) {
++p;
+ }
++p;
}
return p;
@@ -1563,8 +1596,8 @@ static char_u *menu_skip_part(char_u *p)
*/
static char_u *menutrans_lookup(char_u *name, int len)
{
- menutrans_T *tp = (menutrans_T *)menutrans_ga.ga_data;
- char_u *dname;
+ menutrans_T *tp = (menutrans_T *)menutrans_ga.ga_data;
+ char_u *dname;
for (int i = 0; i < menutrans_ga.ga_len; i++) {
if (STRNICMP(name, tp[i].from, len) == 0 && tp[i].from[len] == NUL) {
@@ -1572,7 +1605,7 @@ static char_u *menutrans_lookup(char_u *name, int len)
}
}
- /* Now try again while ignoring '&' characters. */
+ // Now try again while ignoring '&' characters.
char_u c = name[len];
name[len] = NUL;
dname = menu_text(name, NULL, NULL);
@@ -1593,7 +1626,7 @@ static char_u *menutrans_lookup(char_u *name, int len)
*/
static void menu_unescape_name(char_u *name)
{
- char_u *p;
+ char_u *p;
for (p = name; *p && *p != '.'; MB_PTR_ADV(p)) {
if (*p == '\\') {
@@ -1608,19 +1641,20 @@ static void menu_unescape_name(char_u *name)
*/
static char_u *menu_translate_tab_and_shift(char_u *arg_start)
{
- char_u *arg = arg_start;
+ char_u *arg = arg_start;
while (*arg && !ascii_iswhite(*arg)) {
- if ((*arg == '\\' || *arg == Ctrl_V) && arg[1] != NUL)
+ if ((*arg == '\\' || *arg == Ctrl_V) && arg[1] != NUL) {
arg++;
- else if (STRNICMP(arg, "<TAB>", 5) == 0) {
+ } else if (STRNICMP(arg, "<TAB>", 5) == 0) {
*arg = TAB;
STRMOVE(arg + 1, arg + 5);
}
arg++;
}
- if (*arg != NUL)
+ if (*arg != NUL) {
*arg++ = NUL;
+ }
arg = skipwhite(arg);
return arg;
diff --git a/src/nvim/message.c b/src/nvim/message.c
index ec5dabbbc0..ed673b52d3 100644
--- a/src/nvim/message.c
+++ b/src/nvim/message.c
@@ -7,42 +7,42 @@
#include <assert.h>
#include <inttypes.h>
-#include <stdbool.h>
#include <stdarg.h>
+#include <stdbool.h>
#include <string.h>
-#include "nvim/vim.h"
+#include "nvim/api/private/helpers.h"
#include "nvim/ascii.h"
#include "nvim/assert.h"
-#include "nvim/message.h"
#include "nvim/charset.h"
#include "nvim/eval.h"
-#include "nvim/ex_eval.h"
#include "nvim/ex_docmd.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/highlight.h"
+#include "nvim/keymap.h"
#include "nvim/main.h"
#include "nvim/mbyte.h"
#include "nvim/memory.h"
+#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/keymap.h"
-#include "nvim/garray.h"
+#include "nvim/mouse.h"
+#include "nvim/normal.h"
#include "nvim/ops.h"
#include "nvim/option.h"
-#include "nvim/normal.h"
+#include "nvim/os/input.h"
+#include "nvim/os/os.h"
+#include "nvim/os/time.h"
#include "nvim/regexp.h"
#include "nvim/screen.h"
#include "nvim/strings.h"
#include "nvim/syntax.h"
-#include "nvim/highlight.h"
#include "nvim/ui.h"
#include "nvim/ui_compositor.h"
-#include "nvim/mouse.h"
-#include "nvim/os/os.h"
-#include "nvim/os/input.h"
-#include "nvim/os/time.h"
-#include "nvim/api/private/helpers.h"
+#include "nvim/vim.h"
/*
* To be able to scroll back at the "more" and "hit-enter" prompts we need to
@@ -50,24 +50,24 @@
*/
typedef struct msgchunk_S msgchunk_T;
struct msgchunk_S {
- msgchunk_T *sb_next;
- msgchunk_T *sb_prev;
- char sb_eol; /* TRUE when line ends after this text */
- int sb_msg_col; /* column in which text starts */
- int sb_attr; /* text attributes */
- char_u sb_text[1]; /* text to be displayed, actually longer */
+ msgchunk_T *sb_next;
+ msgchunk_T *sb_prev;
+ char sb_eol; // TRUE when line ends after this text
+ int sb_msg_col; // column in which text starts
+ int sb_attr; // text attributes
+ char_u sb_text[1]; // text to be displayed, actually longer
};
-/* Magic chars used in confirm dialog strings */
+// Magic chars used in confirm dialog strings
#define DLG_BUTTON_SEP '\n'
#define DLG_HOTKEY_CHAR '&'
-static int confirm_msg_used = FALSE; /* displaying confirm_msg */
+static int confirm_msg_used = FALSE; // displaying confirm_msg
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "message.c.generated.h"
#endif
-static char_u *confirm_msg = NULL; /* ":confirm" message */
-static char_u *confirm_msg_tail; /* tail of confirm_msg */
+static char_u *confirm_msg = NULL; // ":confirm" message
+static char_u *confirm_msg_tail; // tail of confirm_msg
MessageHistoryEntry *first_msg_hist = NULL;
MessageHistoryEntry *last_msg_hist = NULL;
@@ -79,37 +79,37 @@ static int verbose_did_open = FALSE;
/*
* When writing messages to the screen, there are many different situations.
* A number of variables is used to remember the current state:
- * msg_didany TRUE when messages were written since the last time the
- * user reacted to a prompt.
- * Reset: After hitting a key for the hit-return prompt,
- * hitting <CR> for the command line or input().
- * Set: When any message is written to the screen.
- * msg_didout TRUE when something was written to the current line.
- * Reset: When advancing to the next line, when the current
- * text can be overwritten.
- * Set: When any message is written to the screen.
- * msg_nowait No extra delay for the last drawn message.
- * Used in normal_cmd() before the mode message is drawn.
+ * msg_didany true when messages were written since the last time the
+ * user reacted to a prompt.
+ * Reset: After hitting a key for the hit-return prompt,
+ * hitting <CR> for the command line or input().
+ * Set: When any message is written to the screen.
+ * msg_didout true when something was written to the current line.
+ * Reset: When advancing to the next line, when the current
+ * text can be overwritten.
+ * Set: When any message is written to the screen.
+ * msg_nowait No extra delay for the last drawn message.
+ * Used in normal_cmd() before the mode message is drawn.
* emsg_on_display There was an error message recently. Indicates that there
- * should be a delay before redrawing.
- * msg_scroll The next message should not overwrite the current one.
- * msg_scrolled How many lines the screen has been scrolled (because of
- * messages). Used in update_screen() to scroll the screen
- * back. Incremented each time the screen scrolls a line.
+ * should be a delay before redrawing.
+ * msg_scroll The next message should not overwrite the current one.
+ * msg_scrolled How many lines the screen has been scrolled (because of
+ * messages). Used in update_screen() to scroll the screen
+ * back. Incremented each time the screen scrolls a line.
* msg_scrolled_ign TRUE when msg_scrolled is non-zero and msg_puts_attr()
- * writes something without scrolling should not make
- * need_wait_return to be set. This is a hack to make ":ts"
- * work without an extra prompt.
- * lines_left Number of lines available for messages before the
- * more-prompt is to be given. -1 when not set.
- * need_wait_return TRUE when the hit-return prompt is needed.
- * Reset: After giving the hit-return prompt, when the user
- * has answered some other prompt.
- * Set: When the ruler or typeahead display is overwritten,
- * scrolling the screen for some message.
- * keep_msg Message to be displayed after redrawing the screen, in
- * main_loop().
- * This is an allocated string or NULL when not used.
+ * writes something without scrolling should not make
+ * need_wait_return to be set. This is a hack to make ":ts"
+ * work without an extra prompt.
+ * lines_left Number of lines available for messages before the
+ * more-prompt is to be given. -1 when not set.
+ * need_wait_return true when the hit-return prompt is needed.
+ * Reset: After giving the hit-return prompt, when the user
+ * has answered some other prompt.
+ * Set: When the ruler or typeahead display is overwritten,
+ * scrolling the screen for some message.
+ * keep_msg Message to be displayed after redrawing the screen, in
+ * main_loop().
+ * This is an allocated string or NULL when not used.
*/
@@ -231,8 +231,7 @@ int msg_attr(const char *s, const int attr)
}
/// similar to msg_outtrans_attr, but support newlines and tabs.
-void msg_multiline_attr(const char *s, int attr,
- bool check_int, bool *need_clear)
+void msg_multiline_attr(const char *s, int attr, bool check_int, bool *need_clear)
FUNC_ATTR_NONNULL_ALL
{
const char *next_spec = s;
@@ -287,16 +286,17 @@ bool msg_attr_keep(char_u *s, int attr, bool keep, bool multiline)
}
if (attr == 0) {
- set_vim_var_string(VV_STATUSMSG, (char *) s, -1);
+ set_vim_var_string(VV_STATUSMSG, (char *)s, -1);
}
/*
* It is possible that displaying a messages causes a problem (e.g.,
- * when redrawing the window), which causes another message, etc.. To
+ * when redrawing the window), which causes another message, etc.. To
* break this loop, limit the recursiveness to 3 levels.
*/
- if (entered >= 3)
+ if (entered >= 3) {
return TRUE;
+ }
++entered;
/* Add message to history (unless it's a repeated kept message or a
@@ -309,11 +309,12 @@ bool msg_attr_keep(char_u *s, int attr, bool keep, bool multiline)
add_msg_hist((const char *)s, -1, attr, multiline);
}
- /* Truncate the message if needed. */
+ // Truncate the message if needed.
msg_start();
buf = msg_strtrunc(s, FALSE);
- if (buf != NULL)
+ if (buf != NULL) {
s = buf;
+ }
bool need_clear = true;
if (multiline) {
@@ -336,31 +337,28 @@ bool msg_attr_keep(char_u *s, int attr, bool keep, bool multiline)
return retval;
}
-/*
- * Truncate a string such that it can be printed without causing a scroll.
- * Returns an allocated string or NULL when no truncating is done.
- */
-char_u *
-msg_strtrunc (
- char_u *s,
- int force /* always truncate */
-)
+/// Truncate a string such that it can be printed without causing a scroll.
+/// Returns an allocated string or NULL when no truncating is done.
+///
+/// @param force always truncate
+char_u *msg_strtrunc(char_u *s, int force)
{
- char_u *buf = NULL;
+ char_u *buf = NULL;
int len;
int room;
- /* May truncate message to avoid a hit-return prompt */
+ // May truncate message to avoid a hit-return prompt
if ((!msg_scroll && !need_wait_return && shortmess(SHM_TRUNCALL)
&& !exmode_active && msg_silent == 0 && !ui_has(kUIMessages))
|| force) {
len = vim_strsize(s);
- if (msg_scrolled != 0)
- /* Use all the columns. */
+ if (msg_scrolled != 0) {
+ // Use all the columns.
room = (int)(Rows - msg_row) * Columns - 1;
- else
- /* Use up to 'showcmd' column. */
+ } else {
+ // Use up to 'showcmd' column.
room = (int)(Rows - msg_row - 1) * Columns + sc_col - 1;
+ }
if (len > room && room > 0) {
// may have up to 18 bytes per cell (6 per char, up to two
// composing chars)
@@ -390,10 +388,10 @@ void trunc_string(char_u *s, char_u *buf, int room_in, int buflen)
}
half = room / 2;
- /* First part: Start of the string. */
+ // First part: Start of the string.
for (e = 0; len < half && e < buflen; ++e) {
if (s[e] == NUL) {
- /* text fits without truncating! */
+ // text fits without truncating!
buf[e] = NUL;
return;
}
@@ -497,7 +495,7 @@ int smsg_attr_keep(int attr, char *s, ...)
* isn't printed each time when it didn't change.
*/
static int last_sourcing_lnum = 0;
-static char_u *last_sourcing_name = NULL;
+static char_u *last_sourcing_name = NULL;
/*
* Reset the last used sourcing name/lnum. Makes sure it is displayed again
@@ -515,8 +513,9 @@ void reset_last_sourcing(void)
static int other_sourcing_name(void)
{
if (sourcing_name != NULL) {
- if (last_sourcing_name != NULL)
+ if (last_sourcing_name != NULL) {
return STRCMP(sourcing_name, last_sourcing_name) != 0;
+ }
return TRUE;
}
return FALSE;
@@ -577,16 +576,17 @@ void msg_source(int attr)
if (p != NULL) {
msg_attr(p, HL_ATTR(HLF_N));
xfree(p);
- last_sourcing_lnum = sourcing_lnum; /* only once for each line */
+ last_sourcing_lnum = sourcing_lnum; // only once for each line
}
- /* remember the last sourcing name printed, also when it's empty */
+ // remember the last sourcing name printed, also when it's empty
if (sourcing_name == NULL || other_sourcing_name()) {
xfree(last_sourcing_name);
- if (sourcing_name == NULL)
+ if (sourcing_name == NULL) {
last_sourcing_name = NULL;
- else
+ } else {
last_sourcing_name = vim_strsave(sourcing_name);
+ }
}
--no_wait_return;
}
@@ -601,9 +601,9 @@ int emsg_not_now(void)
{
if ((emsg_off > 0 && vim_strchr(p_debug, 'm') == NULL
&& vim_strchr(p_debug, 't') == NULL)
- || emsg_skip > 0
- )
+ || emsg_skip > 0) {
return TRUE;
+ }
return FALSE;
}
@@ -762,7 +762,7 @@ bool emsgf_multiline(const char *const fmt, ...)
va_list ap;
- static char errbuf[MULTILINE_BUFSIZE];
+ static char errbuf[MULTILINE_BUFSIZE];
if (emsg_not_now()) {
return true;
}
@@ -794,9 +794,9 @@ static bool emsgfv(const char *fmt, va_list ap)
/// detected when fuzzing vim.
void iemsg(const char *s)
{
- emsg((char_u *)s);
+ emsg((char_u *)s);
#ifdef ABORT_ON_INTERNAL_ERROR
- abort();
+ abort();
#endif
}
@@ -805,19 +805,19 @@ void iemsg(const char *s)
/// detected when fuzzing vim.
void iemsgf(const char *s, ...)
{
- va_list ap;
- va_start(ap, s);
- (void)emsgfv(s, ap);
- va_end(ap);
+ va_list ap;
+ va_start(ap, s);
+ (void)emsgfv(s, ap);
+ va_end(ap);
#ifdef ABORT_ON_INTERNAL_ERROR
- abort();
+ abort();
#endif
}
/// Give an "Internal error" message.
void internal_error(char *where)
{
- IEMSG2(_(e_intern2), where);
+ IEMSG2(_(e_intern2), where);
}
static void msg_emsgf_event(void **argv)
@@ -858,8 +858,9 @@ char_u *msg_trunc_attr(char_u *s, int force, int attr)
n = msg_attr((const char *)s, attr);
msg_hist_off = false;
- if (n)
+ if (n) {
return s;
+ }
return NULL;
}
@@ -930,18 +931,21 @@ void add_hl_msg_hist(HlMessage hl_msg)
/// @param[in] len Length of s or -1.
static void add_msg_hist(const char *s, int len, int attr, bool multiline)
{
- if (msg_hist_off || msg_silent != 0)
+ if (msg_hist_off || msg_silent != 0) {
return;
+ }
- /* Don't let the message history get too big */
- while (msg_hist_len > MAX_MSG_HIST_LEN)
+ // Don't let the message history get too big
+ while (msg_hist_len > MAX_MSG_HIST_LEN) {
(void)delete_first_msg();
+ }
- /* allocate an entry and add the message at the end of the history */
+ // allocate an entry and add the message at the end of the history
struct msg_hist *p = xmalloc(sizeof(struct msg_hist));
- if (len < 0)
+ if (len < 0) {
len = (int)STRLEN(s);
- /* remove leading and trailing newlines */
+ }
+ // remove leading and trailing newlines
while (len > 0 && *s == '\n') {
++s;
--len;
@@ -972,11 +976,12 @@ int delete_first_msg(void)
{
struct msg_hist *p;
- if (msg_hist_len <= 0)
+ if (msg_hist_len <= 0) {
return FAIL;
+ }
p = first_msg_hist;
first_msg_hist = p->next;
- if (first_msg_hist == NULL) { /* history is becoming empty */
+ if (first_msg_hist == NULL) { // history is becoming empty
assert(msg_hist_len == 1);
last_msg_hist = NULL;
}
@@ -1078,7 +1083,7 @@ void wait_return(int redraw)
int oldState;
int tmpState;
int had_got_int;
- FILE *save_scriptout;
+ FILE *save_scriptout;
if (redraw == true) {
redraw_all_later(NOT_VALID);
@@ -1086,8 +1091,9 @@ void wait_return(int redraw)
/* If using ":silent cmd", don't wait for a return. Also don't set
* need_wait_return to do it later. */
- if (msg_silent != 0)
+ if (msg_silent != 0) {
return;
+ }
/*
* When inside vgetc(), we can't wait for a typed character at all.
@@ -1095,24 +1101,26 @@ void wait_return(int redraw)
* the end. Adjust cmdline_row to avoid the next message overwriting the
* last one.
*/
- if (vgetc_busy > 0)
+ if (vgetc_busy > 0) {
return;
- need_wait_return = TRUE;
+ }
+ need_wait_return = true;
if (no_wait_return) {
- if (!exmode_active)
+ if (!exmode_active) {
cmdline_row = msg_row;
+ }
return;
}
- redir_off = TRUE; /* don't redirect this message */
+ redir_off = true; // don't redirect this message
oldState = State;
if (quit_more) {
- c = CAR; /* just pretend CR was hit */
+ c = CAR; // just pretend CR was hit
quit_more = FALSE;
got_int = FALSE;
} else if (exmode_active) {
- MSG_PUTS(" "); /* make sure the cursor is on the right line */
- c = CAR; /* no need for a return in ex mode */
+ MSG_PUTS(" "); // make sure the cursor is on the right line
+ c = CAR; // no need for a return in ex mode
got_int = FALSE;
} else {
// Make sure the hit-return prompt is on screen when 'guioptions' was
@@ -1165,18 +1173,18 @@ void wait_return(int redraw)
if (p_more) {
if (c == 'b' || c == 'k' || c == 'u' || c == 'g'
|| c == K_UP || c == K_PAGEUP) {
- if (msg_scrolled > Rows)
- /* scroll back to show older messages */
+ if (msg_scrolled > Rows) {
+ // scroll back to show older messages
do_more_prompt(c);
- else {
- msg_didout = FALSE;
+ } else {
+ msg_didout = false;
c = K_IGNORE;
msg_col =
cmdmsg_rl ? Columns - 1 :
0;
}
if (quit_more) {
- c = CAR; /* just pretend CR was hit */
+ c = CAR; // just pretend CR was hit
quit_more = FALSE;
got_int = FALSE;
} else if (c != K_IGNORE) {
@@ -1185,8 +1193,9 @@ void wait_return(int redraw)
}
} else if (msg_scrolled > Rows - 2
&& (c == 'j' || c == 'd' || c == 'f'
- || c == K_DOWN || c == K_PAGEDOWN))
+ || c == K_DOWN || c == K_PAGEDOWN)) {
c = K_IGNORE;
+ }
}
} while ((had_got_int && c == Ctrl_C)
|| c == K_IGNORE
@@ -1201,9 +1210,9 @@ void wait_return(int redraw)
* Avoid that the mouse-up event causes visual mode to start.
*/
if (c == K_LEFTMOUSE || c == K_MIDDLEMOUSE || c == K_RIGHTMOUSE
- || c == K_X1MOUSE || c == K_X2MOUSE)
+ || c == K_X1MOUSE || c == K_X2MOUSE) {
(void)jump_to_mouse(MOUSE_SETPOS, NULL, 0);
- else if (vim_strchr((char_u *)"\r\n ", c) == NULL && c != Ctrl_C) {
+ } else if (vim_strchr((char_u *)"\r\n ", c) == NULL && c != Ctrl_C) {
/* Put the character back in the typeahead buffer. Don't use the
* stuff buffer, because lmaps wouldn't work. */
ins_char_typebuf(c);
@@ -1216,8 +1225,9 @@ void wait_return(int redraw)
// If the user hits ':', '?' or '/' we get a command line from the next
// line.
if (c == ':' || c == '?' || c == '/') {
- if (!exmode_active)
+ if (!exmode_active) {
cmdline_row = msg_row;
+ }
skip_redraw = true; // skip redraw once
do_redraw = false;
msg_ext_keep_after_cmdline = true;
@@ -1240,7 +1250,7 @@ void wait_return(int redraw)
XFREE_CLEAR(keep_msg); // don't redisplay message, it's too long
}
- if (tmpState == SETWSIZE) { /* got resize event while in vgetc() */
+ if (tmpState == SETWSIZE) { // got resize event while in vgetc()
ui_refresh();
} else if (!skip_redraw) {
if (redraw == true || (msg_scrolled != 0 && redraw != -1)) {
@@ -1259,9 +1269,10 @@ static void hit_return_msg(void)
{
int save_p_more = p_more;
- p_more = FALSE; /* don't want see this message when scrolling back */
- if (msg_didout) /* start on a new line */
+ p_more = FALSE; // don't want see this message when scrolling back
+ if (msg_didout) { // start on a new line
msg_putchar('\n');
+ }
msg_ext_set_kind("return_prompt");
if (got_int) {
MSG_PUTS(_("Interrupt: "));
@@ -1280,11 +1291,12 @@ static void hit_return_msg(void)
void set_keep_msg(char_u *s, int attr)
{
xfree(keep_msg);
- if (s != NULL && msg_silent == 0)
+ if (s != NULL && msg_silent == 0) {
keep_msg = vim_strsave(s);
- else
+ } else {
keep_msg = NULL;
- keep_msg_more = FALSE;
+ }
+ keep_msg_more = false;
keep_msg_attr = attr;
}
@@ -1324,12 +1336,12 @@ void msg_start(void)
0;
} else if (msg_didout) { // start message on next line
msg_putchar('\n');
- did_return = TRUE;
- if (exmode_active != EXMODE_NORMAL)
- cmdline_row = msg_row;
+ did_return = true;
+ cmdline_row = msg_row;
}
- if (!msg_didany || lines_left < 0)
+ if (!msg_didany || lines_left < 0) {
msg_starthere();
+ }
if (msg_silent == 0) {
msg_didout = false; // no output on current line yet
}
@@ -1354,7 +1366,7 @@ void msg_start(void)
void msg_starthere(void)
{
lines_left = cmdline_row;
- msg_didany = FALSE;
+ msg_didany = false;
}
void msg_putchar(int c)
@@ -1397,7 +1409,7 @@ void msg_home_replace_hl(char_u *fname)
static void msg_home_replace_attr(char_u *fname, int attr)
{
- char_u *name;
+ char_u *name;
name = home_replace_save(NULL, fname);
msg_outtrans_attr(name, attr);
@@ -1450,7 +1462,7 @@ int msg_outtrans_len_attr(const char_u *msgstr, int len, int attr)
int mb_l;
int c;
- /* if MSG_HIST flag set, add message to history */
+ // if MSG_HIST flag set, add message to history
if (attr & MSG_HIST) {
add_msg_hist(str, len, attr, false);
attr &= ~MSG_HIST;
@@ -1519,13 +1531,16 @@ void msg_make(char_u *arg)
static char_u *str = (char_u *)"eeffoc", *rs = (char_u *)"Plon#dqg#vxjduB";
arg = skipwhite(arg);
- for (i = 5; *arg && i >= 0; --i)
- if (*arg++ != str[i])
+ for (i = 5; *arg && i >= 0; --i) {
+ if (*arg++ != str[i]) {
break;
+ }
+ }
if (i < 0) {
msg_putchar('\n');
- for (i = 0; rs[i]; ++i)
+ for (i = 0; rs[i]; ++i) {
msg_putchar(rs[i] - 3);
+ }
}
}
@@ -1541,11 +1556,10 @@ void msg_make(char_u *arg)
/// Otherwise characters are not highlighted.
/// This function is used to show mappings, where we want to see how to type
/// the character/string -- webb
-int msg_outtrans_special(
- const char_u *strstart,
- bool from, ///< true for LHS of a mapping
- int maxlen ///< screen columns, 0 for unlimeted
-)
+///
+/// @param from true for LHS of a mapping
+/// @param maxlen screen columns, 0 for unlimeted
+int msg_outtrans_special(const char_u *strstart, bool from, int maxlen)
{
if (strstart == NULL) {
return 0; // Do nothing.
@@ -1586,8 +1600,7 @@ int msg_outtrans_special(
/// @param[in] replace_lt Convert `<` into `<lt>`.
///
/// @return [allocated] Converted string.
-char *str2special_save(const char *const str, const bool replace_spaces,
- const bool replace_lt)
+char *str2special_save(const char *const str, const bool replace_spaces, const bool replace_lt)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_MALLOC
FUNC_ATTR_NONNULL_RET
{
@@ -1612,8 +1625,7 @@ char *str2special_save(const char *const str, const bool replace_spaces,
/// @return Converted key code, in a static buffer. Buffer is always one and the
/// same, so save converted string somewhere before running str2special
/// for the second time.
-const char *str2special(const char **const sp, const bool replace_spaces,
- const bool replace_lt)
+const char *str2special(const char **const sp, const bool replace_spaces, const bool replace_lt)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_RET
{
static char buf[7];
@@ -1708,6 +1720,8 @@ void msg_prt_line(char_u *s, int list)
int n;
int attr = 0;
char_u *lead = NULL;
+ bool in_multispace = false;
+ int multispace_pos = 0;
char_u *trail = NULL;
int l;
@@ -1772,6 +1786,10 @@ void msg_prt_line(char_u *s, int list)
} else {
attr = 0;
c = *s++;
+ in_multispace = c == ' ' && ((col > 0 && s[-2] == ' ') || *s == ' ');
+ if (!in_multispace) {
+ multispace_pos = 0;
+ }
if (c == TAB && (!list || curwin->w_p_lcs_chars.tab1)) {
// tab amount depends on current column
n_extra = tabstop_padding(col,
@@ -1787,11 +1805,11 @@ void msg_prt_line(char_u *s, int list)
: curwin->w_p_lcs_chars.tab1;
c_extra = curwin->w_p_lcs_chars.tab2;
c_final = curwin->w_p_lcs_chars.tab3;
- attr = HL_ATTR(HLF_8);
+ attr = HL_ATTR(HLF_0);
}
} else if (c == 160 && list && curwin->w_p_lcs_chars.nbsp != NUL) {
c = curwin->w_p_lcs_chars.nbsp;
- attr = HL_ATTR(HLF_8);
+ attr = HL_ATTR(HLF_0);
} else if (c == NUL && list && curwin->w_p_lcs_chars.eol != NUL) {
p_extra = (char_u *)"";
c_extra = NUL;
@@ -1808,21 +1826,30 @@ void msg_prt_line(char_u *s, int list)
c = *p_extra++;
/* Use special coloring to be able to distinguish <hex> from
* the same in plain text. */
- attr = HL_ATTR(HLF_8);
- } else if (c == ' ' && lead != NULL && s <= lead) {
- c = curwin->w_p_lcs_chars.lead;
- attr = HL_ATTR(HLF_8);
- } else if (c == ' ' && trail != NULL && s > trail) {
- c = curwin->w_p_lcs_chars.trail;
- attr = HL_ATTR(HLF_8);
- } else if (c == ' ' && list && curwin->w_p_lcs_chars.space != NUL) {
- c = curwin->w_p_lcs_chars.space;
- attr = HL_ATTR(HLF_8);
+ attr = HL_ATTR(HLF_0);
+ } else if (c == ' ') {
+ if (lead != NULL && s <= lead) {
+ c = curwin->w_p_lcs_chars.lead;
+ attr = HL_ATTR(HLF_0);
+ } else if (trail != NULL && s > trail) {
+ c = curwin->w_p_lcs_chars.trail;
+ attr = HL_ATTR(HLF_0);
+ } else if (list && in_multispace && curwin->w_p_lcs_chars.multispace != NULL) {
+ c = curwin->w_p_lcs_chars.multispace[multispace_pos++];
+ if (curwin->w_p_lcs_chars.multispace[multispace_pos] == NUL) {
+ multispace_pos = 0;
+ }
+ attr = HL_ATTR(HLF_0);
+ } else if (list && curwin->w_p_lcs_chars.space != NUL) {
+ c = curwin->w_p_lcs_chars.space;
+ attr = HL_ATTR(HLF_0);
+ }
}
}
- if (c == NUL)
+ if (c == NUL) {
break;
+ }
msg_putchar_attr(c, attr);
col++;
@@ -2009,8 +2036,7 @@ static void msg_ext_emit_chunk(void)
* The display part of msg_puts_attr_len().
* May be called recursively to display scroll-back text.
*/
-static void msg_puts_display(const char_u *str, int maxlen, int attr,
- int recurse)
+static void msg_puts_display(const char_u *str, int maxlen, int attr, int recurse)
{
const char_u *s = str;
const char_u *t_s = str; // String from "t_s" to "s" is still todo.
@@ -2063,17 +2089,19 @@ static void msg_puts_display(const char_u *str, int maxlen, int attr,
t_puts(&t_col, t_s, s, attr);
}
- /* When no more prompt and no more room, truncate here */
- if (msg_no_more && lines_left == 0)
+ // When no more prompt and no more room, truncate here
+ if (msg_no_more && lines_left == 0) {
break;
+ }
// Scroll the screen up one line.
bool has_last_char = (*s >= ' ' && !cmdmsg_rl);
msg_scroll_up(!has_last_char);
msg_row = Rows - 2;
- if (msg_col >= Columns) /* can happen after screen resize */
+ if (msg_col >= Columns) { // can happen after screen resize
msg_col = Columns - 1;
+ }
// Display char in last column before showing more-prompt.
if (has_last_char) {
@@ -2114,20 +2142,24 @@ static void msg_puts_display(const char_u *str, int maxlen, int attr,
* If screen is completely filled and 'more' is set then wait
* for a character.
*/
- if (lines_left > 0)
+ if (lines_left > 0) {
--lines_left;
+ }
if (p_more && lines_left == 0 && State != HITRETURN
&& !msg_no_more && !exmode_active) {
- if (do_more_prompt(NUL))
+ if (do_more_prompt(NUL)) {
s = confirm_msg_tail;
- if (quit_more)
+ }
+ if (quit_more) {
return;
+ }
}
/* When we displayed a char in last column need to check if there
* is still more. */
- if (did_last_char)
+ if (did_last_char) {
continue;
+ }
}
wrap = *s == '\n'
@@ -2146,20 +2178,23 @@ static void msg_puts_display(const char_u *str, int maxlen, int attr,
store_sb_text((char_u **)&sb_str, (char_u *)s, attr, &sb_col, true);
}
- if (*s == '\n') { /* go to next line */
- msg_didout = FALSE; /* remember that line is empty */
- if (cmdmsg_rl)
+ if (*s == '\n') { // go to next line
+ msg_didout = false; // remember that line is empty
+ if (cmdmsg_rl) {
msg_col = Columns - 1;
- else
+ } else {
msg_col = 0;
- if (++msg_row >= Rows) /* safety check */
+ }
+ if (++msg_row >= Rows) { // safety check
msg_row = Rows - 1;
- } else if (*s == '\r') { /* go to column 0 */
+ }
+ } else if (*s == '\r') { // go to column 0
msg_col = 0;
- } else if (*s == '\b') { /* go to previous char */
- if (msg_col)
+ } else if (*s == '\b') { // go to previous char
+ if (msg_col) {
--msg_col;
- } else if (*s == TAB) { /* translate Tab into spaces */
+ }
+ } else if (*s == TAB) { // translate Tab into spaces
do {
msg_screen_putchar(' ', attr);
} while (msg_col & 7);
@@ -2183,9 +2218,10 @@ static void msg_puts_display(const char_u *str, int maxlen, int attr,
msg_screen_putchar(*s, attr);
}
} else {
- /* postpone this character until later */
- if (t_col == 0)
+ // postpone this character until later
+ if (t_col == 0) {
t_s = s;
+ }
t_col += cw;
s += l - 1;
}
@@ -2343,7 +2379,7 @@ void msg_reset_scroll(void)
static void inc_msg_scrolled(void)
{
if (*get_vim_var_str(VV_SCROLLSTART) == NUL) {
- char *p = (char *) sourcing_name;
+ char *p = (char *)sourcing_name;
char *tofree = NULL;
// v:scrollstart is empty, set it to the script/function name and line
@@ -2354,7 +2390,7 @@ static void inc_msg_scrolled(void)
size_t len = strlen(p) + 40;
tofree = xmalloc(len);
vim_snprintf(tofree, len, _("%s line %" PRId64),
- p, (int64_t) sourcing_lnum);
+ p, (int64_t)sourcing_lnum);
p = tofree;
}
set_vim_var_string(VV_SCROLLSTART, p, -1);
@@ -2379,15 +2415,13 @@ typedef enum {
static sb_clear_T do_clear_sb_text = SB_CLEAR_NONE;
/// Store part of a printed message for displaying when scrolling back.
-static void store_sb_text(
- char_u **sb_str, // start of string
- char_u *s, // just after string
- int attr,
- int *sb_col,
- int finish // line ends
-)
+///
+/// @param sb_str start of string
+/// @param s just after string
+/// @param finish line ends
+static void store_sb_text(char_u **sb_str, char_u *s, int attr, int *sb_col, int finish)
{
- msgchunk_T *mp;
+ msgchunk_T *mp;
if (do_clear_sb_text == SB_CLEAR_ALL
|| do_clear_sb_text == SB_CLEAR_CMDLINE_DONE) {
@@ -2412,8 +2446,9 @@ static void store_sb_text(
last_msgchunk = mp;
}
mp->sb_next = NULL;
- } else if (finish && last_msgchunk != NULL)
+ } else if (finish && last_msgchunk != NULL) {
last_msgchunk->sb_eol = TRUE;
+ }
*sb_str = s;
*sb_col = 0;
@@ -2445,8 +2480,8 @@ void sb_text_end_cmdline(void)
/// Called when redrawing the screen.
void clear_sb_text(int all)
{
- msgchunk_T *mp;
- msgchunk_T **lastp;
+ msgchunk_T *mp;
+ msgchunk_T **lastp;
if (all) {
lastp = &last_msgchunk;
@@ -2469,7 +2504,7 @@ void clear_sb_text(int all)
*/
void show_sb_text(void)
{
- msgchunk_T *mp;
+ msgchunk_T *mp;
/* Only show something if there is more than one line, otherwise it looks
* weird, typing a command without output results in one line. */
@@ -2489,8 +2524,9 @@ static msgchunk_T *msg_sb_start(msgchunk_T *mps)
{
msgchunk_T *mp = mps;
- while (mp != NULL && mp->sb_prev != NULL && !mp->sb_prev->sb_eol)
+ while (mp != NULL && mp->sb_prev != NULL && !mp->sb_prev->sb_eol) {
mp = mp->sb_prev;
+ }
return mp;
}
@@ -2499,8 +2535,9 @@ static msgchunk_T *msg_sb_start(msgchunk_T *mps)
*/
void msg_sb_eol(void)
{
- if (last_msgchunk != NULL)
+ if (last_msgchunk != NULL) {
last_msgchunk->sb_eol = TRUE;
+ }
}
/*
@@ -2509,18 +2546,20 @@ void msg_sb_eol(void)
*/
static msgchunk_T *disp_sb_line(int row, msgchunk_T *smp)
{
- msgchunk_T *mp = smp;
- char_u *p;
+ msgchunk_T *mp = smp;
+ char_u *p;
for (;; ) {
msg_row = row;
msg_col = mp->sb_msg_col;
p = mp->sb_text;
- if (*p == '\n') /* don't display the line break */
+ if (*p == '\n') { // don't display the line break
++p;
+ }
msg_puts_display(p, -1, mp->sb_attr, TRUE);
- if (mp->sb_eol || mp->sb_next == NULL)
+ if (mp->sb_eol || mp->sb_next == NULL) {
break;
+ }
mp = mp->sb_next;
}
@@ -2618,8 +2657,8 @@ static int do_more_prompt(int typed_char)
int retval = FALSE;
int toscroll;
bool to_redraw = false;
- msgchunk_T *mp_last = NULL;
- msgchunk_T *mp;
+ msgchunk_T *mp_last = NULL;
+ msgchunk_T *mp;
int i;
// If headless mode is enabled and no input is required, this variable
@@ -2636,23 +2675,25 @@ static int do_more_prompt(int typed_char)
entered = true;
if (typed_char == 'G') {
- /* "g<": Find first line on the last page. */
+ // "g<": Find first line on the last page.
mp_last = msg_sb_start(last_msgchunk);
for (i = 0; i < Rows - 2 && mp_last != NULL
- && mp_last->sb_prev != NULL; ++i)
+ && mp_last->sb_prev != NULL; ++i) {
mp_last = msg_sb_start(mp_last->sb_prev);
+ }
}
State = ASKMORE;
setmouse();
- if (typed_char == NUL)
+ if (typed_char == NUL) {
msg_moremsg(FALSE);
+ }
for (;; ) {
/*
* Get a typed character directly from the user.
*/
if (used_typed_char != NUL) {
- c = used_typed_char; /* was typed at hit-enter prompt */
+ c = used_typed_char; // was typed at hit-enter prompt
used_typed_char = NUL;
} else {
c = get_keystroke(resize_events);
@@ -2661,64 +2702,64 @@ static int do_more_prompt(int typed_char)
toscroll = 0;
switch (c) {
- case BS: /* scroll one line back */
+ case BS: // scroll one line back
case K_BS:
case 'k':
case K_UP:
toscroll = -1;
break;
- case CAR: /* one extra line */
+ case CAR: // one extra line
case NL:
case 'j':
case K_DOWN:
toscroll = 1;
break;
- case 'u': /* Up half a page */
+ case 'u': // Up half a page
toscroll = -(Rows / 2);
break;
- case 'd': /* Down half a page */
+ case 'd': // Down half a page
toscroll = Rows / 2;
break;
- case 'b': /* one page back */
+ case 'b': // one page back
case K_PAGEUP:
toscroll = -(Rows - 1);
break;
- case ' ': /* one extra page */
+ case ' ': // one extra page
case 'f':
case K_PAGEDOWN:
case K_LEFTMOUSE:
toscroll = Rows - 1;
break;
- case 'g': /* all the way back to the start */
+ case 'g': // all the way back to the start
toscroll = -999999;
break;
- case 'G': /* all the way to the end */
+ case 'G': // all the way to the end
toscroll = 999999;
lines_left = 999999;
break;
- case ':': /* start new command line */
+ case ':': // start new command line
if (!confirm_msg_used) {
/* Since got_int is set all typeahead will be flushed, but we
* want to keep this ':', remember that in a special way. */
typeahead_noflush(':');
- cmdline_row = Rows - 1; /* put ':' on this line */
- skip_redraw = TRUE; /* skip redraw once */
- need_wait_return = FALSE; /* don't wait in main() */
+ cmdline_row = Rows - 1; // put ':' on this line
+ skip_redraw = true; // skip redraw once
+ need_wait_return = false; // don't wait in main()
}
FALLTHROUGH;
case 'q': // quit
case Ctrl_C:
case ESC:
if (confirm_msg_used) {
- /* Jump to the choices of the dialog. */
+ // Jump to the choices of the dialog.
retval = TRUE;
} else {
got_int = TRUE;
@@ -2737,7 +2778,7 @@ static int do_more_prompt(int typed_char)
to_redraw = true;
break;
- default: /* no valid response */
+ default: // no valid response
msg_moremsg(TRUE);
continue;
}
@@ -2756,10 +2797,11 @@ static int do_more_prompt(int typed_char)
mp = NULL;
}
- /* go to start of line at top of the screen */
+ // go to start of line at top of the screen
for (i = 0; i < Rows - 2 && mp != NULL && mp->sb_prev != NULL;
- ++i)
+ ++i) {
mp = msg_sb_start(mp->sb_prev);
+ }
if (mp != NULL && (mp->sb_prev != NULL || to_redraw)) {
// Find line to be displayed at top
@@ -2768,10 +2810,11 @@ static int do_more_prompt(int typed_char)
break;
}
mp = msg_sb_start(mp->sb_prev);
- if (mp_last == NULL)
+ if (mp_last == NULL) {
mp_last = msg_sb_start(last_msgchunk);
- else
+ } else {
mp_last = msg_sb_start(mp_last->sb_prev);
+ }
}
if (toscroll == -1 && !to_redraw) {
@@ -2795,7 +2838,7 @@ static int do_more_prompt(int typed_char)
toscroll = 0;
}
} else {
- /* First display any text that we scrolled back. */
+ // First display any text that we scrolled back.
while (toscroll > 0 && mp_last != NULL) {
if (msg_do_throttle() && !msg_grid.throttled) {
// Tricky: we redraw at one line higher than usual. Therefore
@@ -2821,7 +2864,7 @@ static int do_more_prompt(int typed_char)
continue;
}
- /* display more text, return to caller */
+ // display more text, return to caller
lines_left = toscroll;
}
@@ -2902,7 +2945,7 @@ static void msg_screen_putchar(int c, int attr)
void msg_moremsg(int full)
{
int attr;
- char_u *s = (char_u *)_("-- More --");
+ char_u *s = (char_u *)_("-- More --");
attr = hl_combine_attr(HL_ATTR(HLF_MSG), HL_ATTR(HLF_M));
grid_puts(&msg_grid_adj, s, Rows - 1, 0, attr);
@@ -2920,19 +2963,19 @@ void msg_moremsg(int full)
void repeat_message(void)
{
if (State == ASKMORE) {
- msg_moremsg(TRUE); /* display --more-- message again */
+ msg_moremsg(TRUE); // display --more-- message again
msg_row = Rows - 1;
} else if (State == CONFIRM) {
- display_confirm_msg(); /* display ":confirm" message again */
+ display_confirm_msg(); // display ":confirm" message again
msg_row = Rows - 1;
} else if (State == EXTERNCMD) {
- ui_cursor_goto(msg_row, msg_col); /* put cursor back */
+ ui_cursor_goto(msg_row, msg_col); // put cursor back
} else if (State == HITRETURN || State == SETWSIZE) {
if (msg_row == Rows - 1) {
/* Avoid drawing the "hit-enter" prompt below the previous one,
* overwrite it. Esp. useful when regaining focus and a
* FocusGained autocmd exists but didn't draw anything. */
- msg_didout = FALSE;
+ msg_didout = false;
msg_col = 0;
msg_clr_eos();
}
@@ -2947,8 +2990,9 @@ void repeat_message(void)
*/
void msg_clr_eos(void)
{
- if (msg_silent == 0)
+ if (msg_silent == 0) {
msg_clr_eos_force();
+ }
}
/*
@@ -3096,8 +3140,8 @@ void msg_check(void)
return;
}
if (msg_row == Rows - 1 && msg_col >= sc_col) {
- need_wait_return = TRUE;
- redraw_cmdline = TRUE;
+ need_wait_return = true;
+ redraw_cmdline = true;
}
}
@@ -3114,16 +3158,18 @@ static void redir_write(const char *const str, const ptrdiff_t maxlen)
return;
}
- /* Don't do anything for displaying prompts and the like. */
- if (redir_off)
+ // Don't do anything for displaying prompts and the like.
+ if (redir_off) {
return;
+ }
- /* If 'verbosefile' is set prepare for writing in that file. */
- if (*p_vfile != NUL && verbose_fd == NULL)
+ // If 'verbosefile' is set prepare for writing in that file.
+ if (*p_vfile != NUL && verbose_fd == NULL) {
verbose_open();
+ }
if (redirecting()) {
- /* If the string doesn't start with CR or NL, go to msg_col */
+ // If the string doesn't start with CR or NL, go to msg_col
if (*s != '\n' && *s != '\r') {
while (cur_col < msg_col) {
if (capture_ga) {
@@ -3175,8 +3221,9 @@ static void redir_write(const char *const str, const ptrdiff_t maxlen)
s++;
}
- if (msg_silent != 0) /* should update msg_col */
+ if (msg_silent != 0) { // should update msg_col
msg_col = cur_col;
+ }
}
}
@@ -3192,8 +3239,9 @@ int redirecting(void)
*/
void verbose_enter(void)
{
- if (*p_vfile != NUL)
+ if (*p_vfile != NUL) {
++msg_silent;
+ }
}
/*
@@ -3202,9 +3250,11 @@ void verbose_enter(void)
*/
void verbose_leave(void)
{
- if (*p_vfile != NUL)
- if (--msg_silent < 0)
+ if (*p_vfile != NUL) {
+ if (--msg_silent < 0) {
msg_silent = 0;
+ }
+ }
}
/*
@@ -3212,11 +3262,12 @@ void verbose_leave(void)
*/
void verbose_enter_scroll(void)
{
- if (*p_vfile != NUL)
+ if (*p_vfile != NUL) {
++msg_silent;
- else
- /* always scroll up, don't overwrite */
+ } else {
+ // always scroll up, don't overwrite
msg_scroll = TRUE;
+ }
}
/*
@@ -3225,10 +3276,12 @@ void verbose_enter_scroll(void)
void verbose_leave_scroll(void)
{
if (*p_vfile != NUL) {
- if (--msg_silent < 0)
+ if (--msg_silent < 0) {
msg_silent = 0;
- } else
+ }
+ } else {
cmdline_row = msg_row;
+ }
}
/*
@@ -3250,7 +3303,7 @@ void verbose_stop(void)
int verbose_open(void)
{
if (verbose_fd == NULL && !verbose_did_open) {
- /* Only give the error message once. */
+ // Only give the error message once.
verbose_did_open = TRUE;
verbose_fd = os_fopen((char *)p_vfile, "a");
@@ -3309,8 +3362,8 @@ void give_warning2(char_u *const message, char_u *const a1, bool hl)
*/
void msg_advance(int col)
{
- if (msg_silent != 0) { /* nothing to advance to */
- msg_col = col; /* for redirection, may fill it up later */
+ if (msg_silent != 0) { // nothing to advance to
+ msg_col = col; // for redirection, may fill it up later
return;
}
if (ui_has(kUIMessages)) {
@@ -3321,49 +3374,44 @@ void msg_advance(int col)
}
return;
}
- if (col >= Columns) /* not enough room */
+ if (col >= Columns) { // not enough room
col = Columns - 1;
- if (cmdmsg_rl)
- while (msg_col > Columns - col)
+ }
+ if (cmdmsg_rl) {
+ while (msg_col > Columns - col) {
msg_putchar(' ');
- else
- while (msg_col < col)
+ }
+ } else {
+ while (msg_col < col) {
msg_putchar(' ');
+ }
+ }
}
-/*
- * Used for "confirm()" function, and the :confirm command prefix.
- * Versions which haven't got flexible dialogs yet, and console
- * versions, get this generic handler which uses the command line.
- *
- * type = one of:
- * VIM_QUESTION, VIM_INFO, VIM_WARNING, VIM_ERROR or VIM_GENERIC
- * title = title string (can be NULL for default)
- * (neither used in console dialogs at the moment)
- *
- * Format of the "buttons" string:
- * "Button1Name\nButton2Name\nButton3Name"
- * The first button should normally be the default/accept
- * The second button should be the 'Cancel' button
- * Other buttons- use your imagination!
- * A '&' in a button name becomes a shortcut, so each '&' should be before a
- * different letter.
- */
-int
-do_dialog (
- int type,
- char_u *title,
- char_u *message,
- char_u *buttons,
- int dfltbutton,
- char_u *textfield, /* IObuff for inputdialog(), NULL
- otherwise */
- int ex_cmd /* when TRUE pressing : accepts default and starts
- Ex command */
-)
+/// Used for "confirm()" function, and the :confirm command prefix.
+/// Versions which haven't got flexible dialogs yet, and console
+/// versions, get this generic handler which uses the command line.
+///
+/// type = one of:
+/// VIM_QUESTION, VIM_INFO, VIM_WARNING, VIM_ERROR or VIM_GENERIC
+/// title = title string (can be NULL for default)
+/// (neither used in console dialogs at the moment)
+///
+/// Format of the "buttons" string:
+/// "Button1Name\nButton2Name\nButton3Name"
+/// The first button should normally be the default/accept
+/// The second button should be the 'Cancel' button
+/// Other buttons- use your imagination!
+/// A '&' in a button name becomes a shortcut, so each '&' should be before a
+/// different letter.
+///
+/// @param textfiel IObuff for inputdialog(), NULL otherwise
+/// @param ex_cmd when TRUE pressing : accepts default and starts Ex command
+int do_dialog(int type, char_u *title, char_u *message, char_u *buttons, int dfltbutton,
+ char_u *textfield, int ex_cmd)
{
int retval = 0;
- char_u *hotkeys;
+ char_u *hotkeys;
int c;
int i;
@@ -3392,16 +3440,16 @@ do_dialog (
// Get a typed character directly from the user.
c = get_keystroke(NULL);
switch (c) {
- case CAR: /* User accepts default option */
+ case CAR: // User accepts default option
case NL:
retval = dfltbutton;
break;
- case Ctrl_C: /* User aborts/cancels */
+ case Ctrl_C: // User aborts/cancels
case ESC:
retval = 0;
break;
- default: /* Could be a hotkey? */
- if (c < 0) { /* special keys are ignored here */
+ default: // Could be a hotkey?
+ if (c < 0) { // special keys are ignored here
continue;
}
if (c == ':' && ex_cmd) {
@@ -3420,9 +3468,10 @@ do_dialog (
i += utfc_ptr2len(hotkeys + i) - 1;
retval++;
}
- if (hotkeys[i])
+ if (hotkeys[i]) {
break;
- /* No hotkey match, so keep waiting */
+ }
+ // No hotkey match, so keep waiting
continue;
}
break;
@@ -3440,15 +3489,11 @@ do_dialog (
}
-/*
- * Copy one character from "*from" to "*to", taking care of multi-byte
- * characters. Return the length of the character in bytes.
- */
-static int copy_char(
- const char_u *from,
- char_u *to,
- bool lowercase // make character lower case
-)
+/// Copy one character from "*from" to "*to", taking care of multi-byte
+/// characters. Return the length of the character in bytes.
+///
+/// @param lowercase make character lower case
+static int copy_char(const char_u *from, char_u *to, bool lowercase)
FUNC_ATTR_NONNULL_ALL
{
if (lowercase) {
@@ -3475,9 +3520,7 @@ static int copy_char(
/// corresponding button has a hotkey
///
/// @return Pointer to memory allocated for storing hotkeys
-static char_u * console_dialog_alloc(const char_u *message,
- char_u *buttons,
- bool has_hotkey[])
+static char_u *console_dialog_alloc(const char_u *message, char_u *buttons, bool has_hotkey[])
{
int lenhotkey = HOTK_LEN; // count first button
has_hotkey[0] = false;
@@ -3506,9 +3549,9 @@ static char_u * console_dialog_alloc(const char_u *message,
}
len += (int)(STRLEN(message)
- + 2 // for the NL's
- + STRLEN(buttons)
- + 3); // for the ": " and NUL
+ + 2 // for the NL's
+ + STRLEN(buttons)
+ + 3); // for the ": " and NUL
lenhotkey++; // for the NUL
// If no hotkey is specified, first char is used.
@@ -3537,7 +3580,7 @@ static char_u * console_dialog_alloc(const char_u *message,
static char_u *msg_show_console_dialog(char_u *message, char_u *buttons, int dfltbutton)
FUNC_ATTR_NONNULL_RET
{
- bool has_hotkey[HAS_HOTKEY_LEN] = {false};
+ bool has_hotkey[HAS_HOTKEY_LEN] = { false };
char_u *hotk = console_dialog_alloc(message, buttons, has_hotkey);
copy_hotkeys_and_msg(message, buttons, dfltbutton, has_hotkey, hotk);
@@ -3554,9 +3597,8 @@ static char_u *msg_show_console_dialog(char_u *message, char_u *buttons, int dfl
/// @param has_hotkey An element in this array is true if corresponding button
/// has a hotkey
/// @param[out] hotkeys_ptr Pointer to the memory location where hotkeys will be copied
-static void copy_hotkeys_and_msg(const char_u *message, char_u *buttons,
- int default_button_idx, const bool has_hotkey[],
- char_u *hotkeys_ptr)
+static void copy_hotkeys_and_msg(const char_u *message, char_u *buttons, int default_button_idx,
+ const bool has_hotkey[], char_u *hotkeys_ptr)
{
*confirm_msg = '\n';
STRCPY(confirm_msg + 1, message);
@@ -3596,7 +3638,6 @@ static void copy_hotkeys_and_msg(const char_u *message, char_u *buttons,
if (idx < HAS_HOTKEY_LEN - 1 && !has_hotkey[++idx]) {
first_hotkey = true;
}
-
} else if (*r == DLG_HOTKEY_CHAR || first_hotkey) {
if (*r == DLG_HOTKEY_CHAR) {
++r;
@@ -3645,21 +3686,24 @@ void display_confirm_msg(void)
int vim_dialog_yesno(int type, char_u *title, char_u *message, int dflt)
{
if (do_dialog(type,
- title == NULL ? (char_u *)_("Question") : title,
- message,
- (char_u *)_("&Yes\n&No"), dflt, NULL, FALSE) == 1)
+ title == NULL ? (char_u *)_("Question") : title,
+ message,
+ (char_u *)_("&Yes\n&No"), dflt, NULL, FALSE) == 1) {
return VIM_YES;
+ }
return VIM_NO;
}
int vim_dialog_yesnocancel(int type, char_u *title, char_u *message, int dflt)
{
switch (do_dialog(type,
- title == NULL ? (char_u *)_("Question") : title,
- message,
- (char_u *)_("&Yes\n&No\n&Cancel"), dflt, NULL, FALSE)) {
- case 1: return VIM_YES;
- case 2: return VIM_NO;
+ title == NULL ? (char_u *)_("Question") : title,
+ message,
+ (char_u *)_("&Yes\n&No\n&Cancel"), dflt, NULL, FALSE)) {
+ case 1:
+ return VIM_YES;
+ case 2:
+ return VIM_NO;
}
return VIM_CANCEL;
}
@@ -3667,14 +3711,18 @@ int vim_dialog_yesnocancel(int type, char_u *title, char_u *message, int dflt)
int vim_dialog_yesnoallcancel(int type, char_u *title, char_u *message, int dflt)
{
switch (do_dialog(type,
- title == NULL ? (char_u *)"Question" : title,
- message,
- (char_u *)_("&Yes\n&No\nSave &All\n&Discard All\n&Cancel"),
- dflt, NULL, FALSE)) {
- case 1: return VIM_YES;
- case 2: return VIM_NO;
- case 3: return VIM_ALL;
- case 4: return VIM_DISCARDALL;
+ title == NULL ? (char_u *)"Question" : title,
+ message,
+ (char_u *)_("&Yes\n&No\nSave &All\n&Discard All\n&Cancel"),
+ dflt, NULL, FALSE)) {
+ case 1:
+ return VIM_YES;
+ case 2:
+ return VIM_NO;
+ case 3:
+ return VIM_ALL;
+ case 4:
+ return VIM_DISCARDALL;
}
return VIM_CANCEL;
}
diff --git a/src/nvim/misc1.c b/src/nvim/misc1.c
index 38d0a7dadf..2dfe5df325 100644
--- a/src/nvim/misc1.c
+++ b/src/nvim/misc1.c
@@ -7,37 +7,43 @@
#include <assert.h>
#include <inttypes.h>
+#include <limits.h>
#include <stdbool.h>
#include <string.h>
-#include <limits.h>
-#include "nvim/vim.h"
#include "nvim/ascii.h"
-#include "nvim/misc1.h"
+#include "nvim/buffer.h"
+#include "nvim/buffer_updates.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
#include "nvim/diff.h"
#include "nvim/edit.h"
#include "nvim/eval.h"
+#include "nvim/event/stream.h"
#include "nvim/ex_cmds.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_getln.h"
#include "nvim/fileio.h"
-#include "nvim/func_attr.h"
#include "nvim/fold.h"
+#include "nvim/func_attr.h"
+#include "nvim/garray.h"
#include "nvim/getchar.h"
#include "nvim/indent.h"
#include "nvim/indent_c.h"
-#include "nvim/buffer_updates.h"
#include "nvim/main.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/message.h"
-#include "nvim/garray.h"
-#include "nvim/move.h"
+#include "nvim/misc1.h"
#include "nvim/mouse.h"
+#include "nvim/move.h"
#include "nvim/option.h"
+#include "nvim/os/input.h"
+#include "nvim/os/os.h"
+#include "nvim/os/shell.h"
+#include "nvim/os/signal.h"
+#include "nvim/os/time.h"
#include "nvim/os_unix.h"
#include "nvim/quickfix.h"
#include "nvim/regexp.h"
@@ -48,14 +54,8 @@
#include "nvim/tag.h"
#include "nvim/ui.h"
#include "nvim/undo.h"
+#include "nvim/vim.h"
#include "nvim/window.h"
-#include "nvim/os/os.h"
-#include "nvim/os/shell.h"
-#include "nvim/os/signal.h"
-#include "nvim/os/input.h"
-#include "nvim/os/time.h"
-#include "nvim/event/stream.h"
-#include "nvim/buffer.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "misc1.c.generated.h"
@@ -73,23 +73,23 @@ static garray_T ga_users = GA_EMPTY_INIT_VALUE;
* If "include_space" is set, include trailing whitespace while calculating the
* length.
*/
-int get_leader_len(char_u *line, char_u **flags,
- bool backward, bool include_space)
+int get_leader_len(char_u *line, char_u **flags, bool backward, bool include_space)
{
int i, j;
int result;
int got_com = FALSE;
int found_one;
- char_u part_buf[COM_MAX_LEN]; /* buffer for one option part */
- char_u *string; /* pointer to comment string */
- char_u *list;
+ char_u part_buf[COM_MAX_LEN]; // buffer for one option part
+ char_u *string; // pointer to comment string
+ char_u *list;
int middle_match_len = 0;
- char_u *prev_list;
- char_u *saved_flags = NULL;
+ char_u *prev_list;
+ char_u *saved_flags = NULL;
result = i = 0;
- while (ascii_iswhite(line[i])) /* leading white space is ignored */
+ while (ascii_iswhite(line[i])) { // leading white space is ignored
++i;
+ }
/*
* Repeat to match several nested comment strings.
@@ -102,51 +102,60 @@ int get_leader_len(char_u *line, char_u **flags,
for (list = curbuf->b_p_com; *list; ) {
/* Get one option part into part_buf[]. Advance "list" to next
* one. Put "string" at start of string. */
- if (!got_com && flags != NULL)
- *flags = list; /* remember where flags started */
+ if (!got_com && flags != NULL) {
+ *flags = list; // remember where flags started
+ }
prev_list = list;
(void)copy_option_part(&list, part_buf, COM_MAX_LEN, ",");
string = vim_strchr(part_buf, ':');
- if (string == NULL) /* missing ':', ignore this part */
+ if (string == NULL) { // missing ':', ignore this part
continue;
- *string++ = NUL; /* isolate flags from string */
+ }
+ *string++ = NUL; // isolate flags from string
/* If we found a middle match previously, use that match when this
* is not a middle or end. */
if (middle_match_len != 0
&& vim_strchr(part_buf, COM_MIDDLE) == NULL
- && vim_strchr(part_buf, COM_END) == NULL)
+ && vim_strchr(part_buf, COM_END) == NULL) {
break;
+ }
/* When we already found a nested comment, only accept further
* nested comments. */
- if (got_com && vim_strchr(part_buf, COM_NEST) == NULL)
+ if (got_com && vim_strchr(part_buf, COM_NEST) == NULL) {
continue;
+ }
- /* When 'O' flag present and using "O" command skip this one. */
- if (backward && vim_strchr(part_buf, COM_NOBACK) != NULL)
+ // When 'O' flag present and using "O" command skip this one.
+ if (backward && vim_strchr(part_buf, COM_NOBACK) != NULL) {
continue;
+ }
/* Line contents and string must match.
* When string starts with white space, must have some white space
* (but the amount does not need to match, there might be a mix of
* TABs and spaces). */
if (ascii_iswhite(string[0])) {
- if (i == 0 || !ascii_iswhite(line[i - 1]))
- continue; /* missing white space */
- while (ascii_iswhite(string[0]))
+ if (i == 0 || !ascii_iswhite(line[i - 1])) {
+ continue; // missing white space
+ }
+ while (ascii_iswhite(string[0])) {
++string;
+ }
}
- for (j = 0; string[j] != NUL && string[j] == line[i + j]; ++j)
+ for (j = 0; string[j] != NUL && string[j] == line[i + j]; ++j) {
;
- if (string[j] != NUL)
- continue; /* string doesn't match */
-
+ }
+ if (string[j] != NUL) {
+ continue; // string doesn't match
+ }
/* When 'b' flag used, there must be white space or an
* end-of-line after the string in the line. */
if (vim_strchr(part_buf, COM_BLANK) != NULL
- && !ascii_iswhite(line[i + j]) && line[i + j] != NUL)
+ && !ascii_iswhite(line[i + j]) && line[i + j] != NUL) {
continue;
+ }
/* We have found a match, stop searching unless this is a middle
* comment. The middle comment can be a substring of the end
@@ -160,13 +169,15 @@ int get_leader_len(char_u *line, char_u **flags,
}
continue;
}
- if (middle_match_len != 0 && j > middle_match_len)
+ if (middle_match_len != 0 && j > middle_match_len) {
/* Use this match instead of the middle match, since it's a
* longer thus better match. */
middle_match_len = 0;
+ }
- if (middle_match_len == 0)
+ if (middle_match_len == 0) {
i += j;
+ }
found_one = TRUE;
break;
}
@@ -174,29 +185,34 @@ int get_leader_len(char_u *line, char_u **flags,
if (middle_match_len != 0) {
/* Use the previously found middle match after failing to find a
* match with an end. */
- if (!got_com && flags != NULL)
+ if (!got_com && flags != NULL) {
*flags = saved_flags;
+ }
i += middle_match_len;
found_one = TRUE;
}
- /* No match found, stop scanning. */
- if (!found_one)
+ // No match found, stop scanning.
+ if (!found_one) {
break;
+ }
result = i;
- /* Include any trailing white space. */
- while (ascii_iswhite(line[i]))
+ // Include any trailing white space.
+ while (ascii_iswhite(line[i])) {
++i;
+ }
- if (include_space)
+ if (include_space) {
result = i;
+ }
- /* If this comment doesn't nest, stop here. */
+ // If this comment doesn't nest, stop here.
got_com = TRUE;
- if (vim_strchr(part_buf, COM_NEST) == NULL)
+ if (vim_strchr(part_buf, COM_NEST) == NULL) {
break;
+ }
}
return result;
}
@@ -213,12 +229,12 @@ int get_last_leader_offset(char_u *line, char_u **flags)
int result = -1;
int i, j;
int lower_check_bound = 0;
- char_u *string;
- char_u *com_leader;
- char_u *com_flags;
- char_u *list;
+ char_u *string;
+ char_u *com_leader;
+ char_u *com_flags;
+ char_u *list;
int found_one;
- char_u part_buf[COM_MAX_LEN]; /* buffer for one option part */
+ char_u part_buf[COM_MAX_LEN]; // buffer for one option part
/*
* Repeat to match several nested comment strings.
@@ -242,7 +258,7 @@ int get_last_leader_offset(char_u *line, char_u **flags)
* happen. */
continue;
}
- *string++ = NUL; /* Isolate flags from string. */
+ *string++ = NUL; // Isolate flags from string.
com_leader = string;
/*
@@ -252,16 +268,19 @@ int get_last_leader_offset(char_u *line, char_u **flags)
* TABs and spaces).
*/
if (ascii_iswhite(string[0])) {
- if (i == 0 || !ascii_iswhite(line[i - 1]))
+ if (i == 0 || !ascii_iswhite(line[i - 1])) {
continue;
+ }
while (ascii_iswhite(*string)) {
string++;
}
}
- for (j = 0; string[j] != NUL && string[j] == line[i + j]; ++j)
+ for (j = 0; string[j] != NUL && string[j] == line[i + j]; ++j) {
/* do nothing */;
- if (string[j] != NUL)
+ }
+ if (string[j] != NUL) {
continue;
+ }
/*
* When 'b' flag used, there must be white space or an
@@ -290,23 +309,25 @@ int get_last_leader_offset(char_u *line, char_u **flags)
*/
found_one = TRUE;
- if (flags)
+ if (flags) {
*flags = flags_save;
+ }
com_flags = flags_save;
break;
}
if (found_one) {
- char_u part_buf2[COM_MAX_LEN]; /* buffer for one option part */
+ char_u part_buf2[COM_MAX_LEN]; // buffer for one option part
int len1, len2, off;
result = i;
/*
* If this comment nests, continue searching.
*/
- if (vim_strchr(part_buf, COM_NEST) != NULL)
+ if (vim_strchr(part_buf, COM_NEST) != NULL) {
continue;
+ }
lower_check_bound = i;
@@ -316,31 +337,36 @@ int get_last_leader_offset(char_u *line, char_u **flags)
* the comment leader correctly.
*/
- while (ascii_iswhite(*com_leader))
+ while (ascii_iswhite(*com_leader)) {
++com_leader;
+ }
len1 = (int)STRLEN(com_leader);
for (list = curbuf->b_p_com; *list; ) {
char_u *flags_save = list;
(void)copy_option_part(&list, part_buf2, COM_MAX_LEN, ",");
- if (flags_save == com_flags)
+ if (flags_save == com_flags) {
continue;
+ }
string = vim_strchr(part_buf2, ':');
++string;
- while (ascii_iswhite(*string))
+ while (ascii_iswhite(*string)) {
++string;
+ }
len2 = (int)STRLEN(string);
- if (len2 == 0)
+ if (len2 == 0) {
continue;
+ }
/* Now we have to verify whether string ends with a substring
* beginning the com_leader. */
for (off = (len2 > i ? i : len2); off > 0 && off + len1 > len2; ) {
--off;
if (!STRNCMP(string + off, com_leader, len2 - off)) {
- if (i - off < lower_check_bound)
+ if (i - off < lower_check_bound) {
lower_check_bound = i - off;
+ }
}
}
}
@@ -349,178 +375,6 @@ int get_last_leader_offset(char_u *line, char_u **flags)
return result;
}
-/*
- * Return the number of window lines occupied by buffer line "lnum".
- */
-int plines(const linenr_T lnum)
-{
- return plines_win(curwin, lnum, true);
-}
-
-int plines_win(
- win_T *const wp,
- const linenr_T lnum,
- const bool winheight // when true limit to window height
-)
-{
- /* Check for filler lines above this buffer line. When folded the result
- * is one line anyway. */
- return plines_win_nofill(wp, lnum, winheight) + diff_check_fill(wp, lnum);
-}
-
-int plines_nofill(const linenr_T lnum)
-{
- return plines_win_nofill(curwin, lnum, true);
-}
-
-int plines_win_nofill(
- win_T *const wp,
- const linenr_T lnum,
- const bool winheight // when true limit to window height
-)
-{
- if (!wp->w_p_wrap) {
- return 1;
- }
-
- if (wp->w_width_inner == 0) {
- return 1;
- }
-
- // A folded lines is handled just like an empty line.
- if (lineFolded(wp, lnum)) {
- return 1;
- }
-
- const int lines = plines_win_nofold(wp, lnum);
- if (winheight && lines > wp->w_height_inner) {
- return wp->w_height_inner;
- }
- return lines;
-}
-
-/*
- * Return number of window lines physical line "lnum" will occupy in window
- * "wp". Does not care about folding, 'wrap' or 'diff'.
- */
-int plines_win_nofold(win_T *wp, linenr_T lnum)
-{
- char_u *s;
- unsigned int col;
- int width;
-
- s = ml_get_buf(wp->w_buffer, lnum, FALSE);
- if (*s == NUL) /* empty line */
- return 1;
- col = win_linetabsize(wp, s, MAXCOL);
-
- // If list mode is on, then the '$' at the end of the line may take up one
- // extra column.
- if (wp->w_p_list && wp->w_p_lcs_chars.eol != NUL) {
- col += 1;
- }
-
- /*
- * Add column offset for 'number', 'relativenumber' and 'foldcolumn'.
- */
- width = wp->w_width_inner - win_col_off(wp);
- if (width <= 0 || col > 32000) {
- return 32000; // bigger than the number of screen columns
- }
- if (col <= (unsigned int)width) {
- return 1;
- }
- col -= (unsigned int)width;
- width += win_col_off2(wp);
- assert(col <= INT_MAX && (int)col < INT_MAX - (width -1));
- return ((int)col + (width - 1)) / width + 1;
-}
-
-/*
- * Like plines_win(), but only reports the number of physical screen lines
- * used from the start of the line to the given column number.
- */
-int plines_win_col(win_T *wp, linenr_T lnum, long column)
-{
- // Check for filler lines above this buffer line. When folded the result
- // is one line anyway.
- int lines = diff_check_fill(wp, lnum);
-
- if (!wp->w_p_wrap)
- return lines + 1;
-
- if (wp->w_width_inner == 0) {
- return lines + 1;
- }
-
- char_u *line = ml_get_buf(wp->w_buffer, lnum, false);
- char_u *s = line;
-
- colnr_T col = 0;
- while (*s != NUL && --column >= 0) {
- col += win_lbr_chartabsize(wp, line, s, col, NULL);
- MB_PTR_ADV(s);
- }
-
- // If *s is a TAB, and the TAB is not displayed as ^I, and we're not in
- // INSERT mode, then col must be adjusted so that it represents the last
- // screen position of the TAB. This only fixes an error when the TAB wraps
- // from one screen line to the next (when 'columns' is not a multiple of
- // 'ts') -- webb.
- if (*s == TAB && (State & NORMAL)
- && (!wp->w_p_list || wp->w_p_lcs_chars.tab1)) {
- col += win_lbr_chartabsize(wp, line, s, col, NULL) - 1;
- }
-
- // Add column offset for 'number', 'relativenumber', 'foldcolumn', etc.
- int width = wp->w_width_inner - win_col_off(wp);
- if (width <= 0) {
- return 9999;
- }
-
- lines += 1;
- if (col > width)
- lines += (col - width) / (width + win_col_off2(wp)) + 1;
- return lines;
-}
-
-/// Get the number of screen lines lnum takes up. This takes care of
-/// both folds and topfill, and limits to the current window height.
-///
-/// @param[in] wp window line is in
-/// @param[in] lnum line number
-/// @param[out] nextp if not NULL, the line after a fold
-/// @param[out] foldedp if not NULL, whether lnum is on a fold
-/// @param[in] cache whether to use the window's cache for folds
-///
-/// @return the total number of screen lines
-int plines_win_full(win_T *wp, linenr_T lnum, linenr_T *const nextp,
- bool *const foldedp, const bool cache)
-{
- bool folded = hasFoldingWin(wp, lnum, NULL, nextp, cache, NULL);
- if (foldedp) {
- *foldedp = folded;
- }
- if (folded) {
- return 1;
- } else if (lnum == wp->w_topline) {
- return plines_win_nofill(wp, lnum, true) + wp->w_topfill;
- }
- return plines_win(wp, lnum, true);
-}
-
-int plines_m_win(win_T *wp, linenr_T first, linenr_T last)
-{
- int count = 0;
-
- while (first <= last) {
- linenr_T next = first;
- count += plines_win_full(wp, first, &next, NULL, false);
- first = next + 1;
- }
- return count;
-}
-
int gchar_pos(pos_T *pos)
FUNC_ATTR_NONNULL_ARG(1)
{
@@ -533,7 +387,7 @@ int gchar_pos(pos_T *pos)
/*
* check_status: called when the status bars for the buffer 'buf'
- * need to be updated
+ * need to be updated
*/
void check_status(buf_T *buf)
{
@@ -631,7 +485,7 @@ int is_mouse_key(int c)
*/
int get_keystroke(MultiQueue *events)
{
- char_u *buf = NULL;
+ char_u *buf = NULL;
int buflen = 150;
int maxlen;
int len = 0;
@@ -665,9 +519,9 @@ int get_keystroke(MultiQueue *events)
n = fix_input_buffer(buf + len, n);
len += n;
waited = 0;
- } else if (len > 0)
- ++waited; /* keep track of the waiting time */
-
+ } else if (len > 0) {
+ ++waited; // keep track of the waiting time
+ }
if (n > 0) { // found a termcode: adjust length
len = n;
}
@@ -675,19 +529,20 @@ int get_keystroke(MultiQueue *events)
continue;
}
- /* Handle modifier and/or special key code. */
+ // Handle modifier and/or special key code.
n = buf[0];
if (n == K_SPECIAL) {
n = TO_SPECIAL(buf[1], buf[2]);
if (buf[1] == KS_MODIFIER
|| n == K_IGNORE
- || (is_mouse_key(n) && n != K_LEFTMOUSE)
- ) {
- if (buf[1] == KS_MODIFIER)
+ || (is_mouse_key(n) && n != K_LEFTMOUSE)) {
+ if (buf[1] == KS_MODIFIER) {
mod_mask = buf[2];
+ }
len -= 3;
- if (len > 0)
+ if (len > 0) {
memmove(buf, buf + 3, (size_t)len);
+ }
continue;
}
break;
@@ -706,27 +561,25 @@ int get_keystroke(MultiQueue *events)
return n;
}
-/*
- * Get a number from the user.
- * When "mouse_used" is not NULL allow using the mouse.
- */
-int
-get_number (
- int colon, /* allow colon to abort */
- int *mouse_used
-)
+/// Get a number from the user.
+/// When "mouse_used" is not NULL allow using the mouse.
+///
+/// @param colon allow colon to abort
+int get_number(int colon, int *mouse_used)
{
int n = 0;
int c;
int typed = 0;
- if (mouse_used != NULL)
+ if (mouse_used != NULL) {
*mouse_used = FALSE;
+ }
/* When not printing messages, the user won't know what to type, return a
* zero (as if CR was hit). */
- if (msg_silent != 0)
+ if (msg_silent != 0) {
return 0;
+ }
no_mapping++;
for (;; ) {
@@ -748,10 +601,11 @@ get_number (
break;
} else if (n == 0 && c == ':' && colon) {
stuffcharReadbuff(':');
- if (!exmode_active)
+ if (!exmode_active) {
cmdline_row = msg_row;
- skip_redraw = TRUE; /* skip redraw once */
- do_redraw = FALSE;
+ }
+ skip_redraw = true; // skip redraw once
+ do_redraw = false;
break;
} else if (c == Ctrl_C || c == ESC || c == 'q') {
n = 0;
@@ -815,41 +669,46 @@ void msgmore(long n)
{
long pn;
- if (global_busy /* no messages now, wait until global is finished */
- || !messaging()) /* 'lazyredraw' set, don't do messages now */
+ if (global_busy // no messages now, wait until global is finished
+ || !messaging()) { // 'lazyredraw' set, don't do messages now
return;
+ }
/* We don't want to overwrite another important message, but do overwrite
* a previous "more lines" or "fewer lines" message, so that "5dd" and
* then "put" reports the last action. */
- if (keep_msg != NULL && !keep_msg_more)
+ if (keep_msg != NULL && !keep_msg_more) {
return;
+ }
- if (n > 0)
+ if (n > 0) {
pn = n;
- else
+ } else {
pn = -n;
+ }
if (pn > p_report) {
if (pn == 1) {
- if (n > 0)
+ if (n > 0) {
STRLCPY(msg_buf, _("1 more line"), MSG_BUF_LEN);
- else
+ } else {
STRLCPY(msg_buf, _("1 line less"), MSG_BUF_LEN);
+ }
} else {
- if (n > 0)
+ if (n > 0) {
vim_snprintf((char *)msg_buf, MSG_BUF_LEN,
- _("%" PRId64 " more lines"), (int64_t)pn);
- else
+ _("%" PRId64 " more lines"), (int64_t)pn);
+ } else {
vim_snprintf((char *)msg_buf, MSG_BUF_LEN,
- _("%" PRId64 " fewer lines"), (int64_t)pn);
+ _("%" PRId64 " fewer lines"), (int64_t)pn);
+ }
}
if (got_int) {
xstrlcat((char *)msg_buf, _(" (Interrupted)"), MSG_BUF_LEN);
}
if (msg(msg_buf)) {
set_keep_msg(msg_buf, 0);
- keep_msg_more = TRUE;
+ keep_msg_more = true;
}
}
}
@@ -924,7 +783,7 @@ static void init_users(void)
}
lazy_init_done = TRUE;
-
+
os_get_usernames(&ga_users);
}
@@ -934,8 +793,9 @@ static void init_users(void)
char_u *get_users(expand_T *xp, int idx)
{
init_users();
- if (idx < ga_users.ga_len)
+ if (idx < ga_users.ga_len) {
return ((char_u **)ga_users.ga_data)[idx];
+ }
return NULL;
}
@@ -952,10 +812,12 @@ int match_user(char_u *name)
init_users();
for (int i = 0; i < ga_users.ga_len; i++) {
- if (STRCMP(((char_u **)ga_users.ga_data)[i], name) == 0)
- return 2; /* full match */
- if (STRNCMP(((char_u **)ga_users.ga_data)[i], name, n) == 0)
- result = 1; /* partial match */
+ if (STRCMP(((char_u **)ga_users.ga_data)[i], name) == 0) {
+ return 2; // full match
+ }
+ if (STRNCMP(((char_u **)ga_users.ga_data)[i], name, n) == 0) {
+ result = 1; // partial match
+ }
}
return result;
}
@@ -1012,7 +874,7 @@ void preserve_exit(void)
*/
#ifndef BREAKCHECK_SKIP
-# define BREAKCHECK_SKIP 1000
+# define BREAKCHECK_SKIP 1000
#endif
static int breakcheck_count = 0;
@@ -1093,8 +955,7 @@ int call_shell(char_u *cmd, ShellOpts opts, char_u *extra_shell_arg)
/// @param ret_len length of the stdout
///
/// @return an allocated string, or NULL for error.
-char_u *get_cmd_output(char_u *cmd, char_u *infile, ShellOpts flags,
- size_t *ret_len)
+char_u *get_cmd_output(char_u *cmd, char_u *infile, ShellOpts flags, size_t *ret_len)
{
char_u *buffer = NULL;
@@ -1142,12 +1003,14 @@ char_u *get_cmd_output(char_u *cmd, char_u *infile, ShellOpts flags,
EMSG2(_(e_notread), tempname);
XFREE_CLEAR(buffer);
} else if (ret_len == NULL) {
- /* Change NUL into SOH, otherwise the string is truncated. */
- for (i = 0; i < len; ++i)
- if (buffer[i] == NUL)
+ // Change NUL into SOH, otherwise the string is truncated.
+ for (i = 0; i < len; ++i) {
+ if (buffer[i] == NUL) {
buffer[i] = 1;
+ }
+ }
- buffer[len] = NUL; /* make sure the buffer is terminated */
+ buffer[len] = NUL; // make sure the buffer is terminated
} else {
*ret_len = len;
}
@@ -1163,10 +1026,12 @@ done:
*/
void FreeWild(int count, char_u **files)
{
- if (count <= 0 || files == NULL)
+ if (count <= 0 || files == NULL) {
return;
- while (count--)
+ }
+ while (count--) {
xfree(files[count]);
+ }
xfree(files);
}
diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c
index 4c0339e5f4..cf463fd40a 100644
--- a/src/nvim/mouse.c
+++ b/src/nvim/mouse.c
@@ -3,25 +3,26 @@
#include <stdbool.h>
-#include "nvim/mouse.h"
-#include "nvim/vim.h"
#include "nvim/ascii.h"
-#include "nvim/window.h"
+#include "nvim/buffer_defs.h"
+#include "nvim/charset.h"
+#include "nvim/cursor.h"
+#include "nvim/diff.h"
+#include "nvim/fold.h"
+#include "nvim/memline.h"
+#include "nvim/misc1.h"
+#include "nvim/mouse.h"
+#include "nvim/move.h"
+#include "nvim/os_unix.h"
+#include "nvim/plines.h"
+#include "nvim/screen.h"
#include "nvim/state.h"
#include "nvim/strings.h"
-#include "nvim/screen.h"
#include "nvim/syntax.h"
#include "nvim/ui.h"
#include "nvim/ui_compositor.h"
-#include "nvim/os_unix.h"
-#include "nvim/fold.h"
-#include "nvim/diff.h"
-#include "nvim/move.h"
-#include "nvim/misc1.h"
-#include "nvim/cursor.h"
-#include "nvim/buffer_defs.h"
-#include "nvim/memline.h"
-#include "nvim/charset.h"
+#include "nvim/vim.h"
+#include "nvim/window.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "mouse.c.generated.h"
@@ -30,33 +31,34 @@
static linenr_T orig_topline = 0;
static int orig_topfill = 0;
-// Move the cursor to the specified row and column on the screen.
-// Change current window if necessary. Returns an integer with the
-// CURSOR_MOVED bit set if the cursor has moved or unset otherwise.
-//
-// The MOUSE_FOLD_CLOSE bit is set when clicked on the '-' in a fold column.
-// The MOUSE_FOLD_OPEN bit is set when clicked on the '+' in a fold column.
-//
-// If flags has MOUSE_FOCUS, then the current window will not be changed, and
-// if the mouse is outside the window then the text will scroll, or if the
-// mouse was previously on a status line, then the status line may be dragged.
-//
-// If flags has MOUSE_MAY_VIS, then VIsual mode will be started before the
-// cursor is moved unless the cursor was on a status line.
-// This function returns one of IN_UNKNOWN, IN_BUFFER, IN_STATUS_LINE or
-// IN_SEP_LINE depending on where the cursor was clicked.
-//
-// If flags has MOUSE_MAY_STOP_VIS, then Visual mode will be stopped, unless
-// the mouse is on the status line of the same window.
-//
-// If flags has MOUSE_DID_MOVE, nothing is done if the mouse didn't move since
-// the last call.
-//
-// If flags has MOUSE_SETPOS, nothing is done, only the current position is
-// remembered.
-int jump_to_mouse(int flags,
- bool *inclusive, // used for inclusive operator, can be NULL
- int which_button) // MOUSE_LEFT, MOUSE_RIGHT, MOUSE_MIDDLE
+/// Move the cursor to the specified row and column on the screen.
+/// Change current window if necessary. Returns an integer with the
+/// CURSOR_MOVED bit set if the cursor has moved or unset otherwise.
+///
+/// The MOUSE_FOLD_CLOSE bit is set when clicked on the '-' in a fold column.
+/// The MOUSE_FOLD_OPEN bit is set when clicked on the '+' in a fold column.
+///
+/// If flags has MOUSE_FOCUS, then the current window will not be changed, and
+/// if the mouse is outside the window then the text will scroll, or if the
+/// mouse was previously on a status line, then the status line may be dragged.
+///
+/// If flags has MOUSE_MAY_VIS, then VIsual mode will be started before the
+/// cursor is moved unless the cursor was on a status line.
+/// This function returns one of IN_UNKNOWN, IN_BUFFER, IN_STATUS_LINE or
+/// IN_SEP_LINE depending on where the cursor was clicked.
+///
+/// If flags has MOUSE_MAY_STOP_VIS, then Visual mode will be stopped, unless
+/// the mouse is on the status line of the same window.
+///
+/// If flags has MOUSE_DID_MOVE, nothing is done if the mouse didn't move since
+/// the last call.
+///
+/// If flags has MOUSE_SETPOS, nothing is done, only the current position is
+/// remembered.
+///
+/// @param inclusive used for inclusive operator, can be NULL
+/// @param which_button MOUSE_LEFT, MOUSE_RIGHT, MOUSE_MIDDLE
+int jump_to_mouse(int flags, bool *inclusive, int which_button)
{
static int on_status_line = 0; // #lines below bottom of window
static int on_sep_line = 0; // on separator right of window
@@ -65,7 +67,7 @@ int jump_to_mouse(int flags,
static win_T *dragwin = NULL; // window being dragged
static int did_drag = false; // drag was noticed
- win_T *wp, *old_curwin;
+ win_T *wp, *old_curwin;
pos_T old_cursor;
int count;
bool first;
@@ -80,8 +82,9 @@ int jump_to_mouse(int flags,
if (flags & MOUSE_RELEASED) {
// On button release we may change window focus if positioned on a
// status line and no dragging happened.
- if (dragwin != NULL && !did_drag)
+ if (dragwin != NULL && !did_drag) {
flags &= ~(MOUSE_FOCUS | MOUSE_DID_MOVE);
+ }
dragwin = NULL;
did_drag = false;
}
@@ -108,15 +111,16 @@ retnomove:
prev_row = mouse_row;
prev_col = mouse_col;
- if (flags & MOUSE_SETPOS)
+ if (flags & MOUSE_SETPOS) {
goto retnomove; // ugly goto...
-
+ }
old_curwin = curwin;
old_cursor = curwin->w_cursor;
if (!(flags & MOUSE_FOCUS)) {
- if (row < 0 || col < 0) // check if it makes sense
+ if (row < 0 || col < 0) { // check if it makes sense
return IN_UNKNOWN;
+ }
// find the window where the row is in
wp = mouse_find_win(&grid, &row, &col);
@@ -150,10 +154,11 @@ retnomove:
// The rightmost character of the status line might be a vertical
// separator character if there is no connecting window to the right.
if (on_status_line && on_sep_line) {
- if (stl_connected(wp))
+ if (stl_connected(wp)) {
on_sep_line = 0;
- else
+ } else {
on_status_line = 0;
+ }
}
// Before jumping to another buffer, or moving the cursor for a left
@@ -180,28 +185,32 @@ retnomove:
// Only change window focus when not clicking on or dragging the
// status line. Do change focus when releasing the mouse button
// (MOUSE_FOCUS was set above if we dragged first).
- if (dragwin == NULL || (flags & MOUSE_RELEASED))
+ if (dragwin == NULL || (flags & MOUSE_RELEASED)) {
win_enter(wp, true); // can make wp invalid!
+ }
// set topline, to be able to check for double click ourselves
- if (curwin != old_curwin)
+ if (curwin != old_curwin) {
set_mouse_topline(curwin);
+ }
if (on_status_line) { // In (or below) status line
// Don't use start_arrow() if we're in the same window
- if (curwin == old_curwin)
+ if (curwin == old_curwin) {
return IN_STATUS_LINE;
- else
+ } else {
return IN_STATUS_LINE | CURSOR_MOVED;
+ }
}
if (on_sep_line) { // In (or below) status line
// Don't use start_arrow() if we're in the same window
- if (curwin == old_curwin)
+ if (curwin == old_curwin) {
return IN_SEP_LINE;
- else
+ } else {
return IN_SEP_LINE | CURSOR_MOVED;
+ }
}
curwin->w_cursor.lnum = curwin->w_topline;
- } else if (on_status_line && which_button == MOUSE_LEFT) {
+ } else if (on_status_line && which_button == MOUSE_LEFT) {
if (dragwin != NULL) {
// Drag the status line
count = row - dragwin->w_winrow - dragwin->w_height + 1
@@ -210,7 +219,7 @@ retnomove:
did_drag |= count;
}
return IN_STATUS_LINE; // Cursor didn't move
- } else if (on_sep_line && which_button == MOUSE_LEFT) {
+ } else if (on_sep_line && which_button == MOUSE_LEFT) {
if (dragwin != NULL) {
// Drag the separator column
count = col - dragwin->w_wincol - dragwin->w_width + 1
@@ -227,25 +236,23 @@ retnomove:
redraw_curbuf_later(INVERTED); // delete the inversion
}
-
- row -= curwin->w_winrow;
- col -= curwin->w_wincol;
-
// When clicking beyond the end of the window, scroll the screen.
// Scroll by however many rows outside the window we are.
if (row < 0) {
count = 0;
for (first = true; curwin->w_topline > 1; ) {
- if (curwin->w_topfill < diff_check(curwin, curwin->w_topline))
- ++count;
- else
- count += plines(curwin->w_topline - 1);
- if (!first && count > -row)
+ if (curwin->w_topfill < win_get_fill(curwin, curwin->w_topline)) {
+ count++;
+ } else {
+ count += plines_win(curwin, curwin->w_topline - 1, true);
+ }
+ if (!first && count > -row) {
break;
+ }
first = false;
(void)hasFolding(curwin->w_topline, &curwin->w_topline, NULL);
- if (curwin->w_topfill < diff_check(curwin, curwin->w_topline)) {
- ++curwin->w_topfill;
+ if (curwin->w_topfill < win_get_fill(curwin, curwin->w_topline)) {
+ curwin->w_topfill++;
} else {
--curwin->w_topline;
curwin->w_topfill = 0;
@@ -256,13 +263,13 @@ retnomove:
~(VALID_WROW|VALID_CROW|VALID_BOTLINE|VALID_BOTLINE_AP);
redraw_later(curwin, VALID);
row = 0;
- } else if (row >= curwin->w_height_inner) {
+ } else if (row >= curwin->w_height_inner) {
count = 0;
for (first = true; curwin->w_topline < curbuf->b_ml.ml_line_count; ) {
if (curwin->w_topfill > 0) {
++count;
} else {
- count += plines(curwin->w_topline);
+ count += plines_win(curwin, curwin->w_topline, true);
}
if (!first && count > row - curwin->w_height_inner + 1) {
@@ -276,11 +283,10 @@ retnomove:
}
if (curwin->w_topfill > 0) {
- --curwin->w_topfill;
+ curwin->w_topfill--;
} else {
- ++curwin->w_topline;
- curwin->w_topfill =
- diff_check_fill(curwin, curwin->w_topline);
+ curwin->w_topline++;
+ curwin->w_topfill = win_get_fill(curwin, curwin->w_topline);
}
}
check_topfill(curwin, false);
@@ -288,7 +294,7 @@ retnomove:
curwin->w_valid &=
~(VALID_WROW|VALID_CROW|VALID_BOTLINE|VALID_BOTLINE_AP);
row = curwin->w_height_inner - 1;
- } else if (row == 0) {
+ } else if (row == 0) {
// When dragging the mouse, while the text has been scrolled up as
// far as it goes, moving the mouse in the top line should scroll
// the text down (done later when recomputing w_topline).
@@ -366,12 +372,12 @@ bool mouse_comp_pos(win_T *win, int *rowp, int *colp, linenr_T *lnump)
while (row > 0) {
// Don't include filler lines in "count"
- if (win->w_p_diff
+ if (win_may_fill(win)
&& !hasFoldingWin(win, lnum, NULL, NULL, true, NULL)) {
if (lnum == win->w_topline) {
row -= win->w_topfill;
} else {
- row -= diff_check_fill(win, lnum);
+ row -= win_get_fill(win, lnum);
}
count = plines_win_nofill(win, lnum, true);
} else {
@@ -395,8 +401,9 @@ bool mouse_comp_pos(win_T *win, int *rowp, int *colp, linenr_T *lnump)
if (!retval) {
// Compute the column without wrapping.
off = win_col_off(win) - win_col_off2(win);
- if (col < off)
+ if (col < off) {
col = off;
+ }
col += row * (win->w_width_inner - off);
// add skip column (for long wrapping line)
col += win->w_skipcol;
@@ -432,23 +439,26 @@ win_T *mouse_find_win(int *gridp, int *rowp, int *colp)
}
- frame_T *fp;
+ frame_T *fp;
fp = topframe;
*rowp -= firstwin->w_winrow;
for (;; ) {
- if (fp->fr_layout == FR_LEAF)
+ if (fp->fr_layout == FR_LEAF) {
break;
+ }
if (fp->fr_layout == FR_ROW) {
for (fp = fp->fr_child; fp->fr_next != NULL; fp = fp->fr_next) {
- if (*colp < fp->fr_width)
+ if (*colp < fp->fr_width) {
break;
+ }
*colp -= fp->fr_width;
}
} else { // fr_layout == FR_COL
for (fp = fp->fr_child; fp->fr_next != NULL; fp = fp->fr_next) {
- if (*rowp < fp->fr_height)
+ if (*rowp < fp->fr_height) {
break;
+ }
*rowp -= fp->fr_height;
}
}
@@ -522,7 +532,7 @@ static colnr_T scroll_line_len(linenr_T lnum)
char_u *line = ml_get(lnum);
if (*line != NUL) {
for (;;) {
- int numchar = chartabsize(line, col);
+ int numchar = win_chartabsize(curwin, line, col);
MB_PTR_ADV(line);
if (*line == NUL) { // don't count the last character
break;
@@ -570,27 +580,26 @@ static linenr_T find_longest_lnum(void)
return ret;
}
-///
-/// Do a horizontal scroll. Return TRUE if the cursor moved, FALSE otherwise.
-///
+/// Do a horizontal scroll.
+/// @return true if the cursor moved, false otherwise.
bool mouse_scroll_horiz(int dir)
{
if (curwin->w_p_wrap) {
- return false;
+ return false;
}
int step = 6;
if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) {
- step = curwin->w_width_inner;
+ step = curwin->w_width_inner;
}
int leftcol = curwin->w_leftcol + (dir == MSCR_RIGHT ? -step : +step);
if (leftcol < 0) {
- leftcol = 0;
+ leftcol = 0;
}
if (curwin->w_leftcol == leftcol) {
- return false;
+ return false;
}
curwin->w_leftcol = (colnr_T)leftcol;
@@ -599,8 +608,8 @@ bool mouse_scroll_horiz(int dir)
// longest visible line.
if (!virtual_active()
&& (colnr_T)leftcol > scroll_line_len(curwin->w_cursor.lnum)) {
- curwin->w_cursor.lnum = find_longest_lnum();
- curwin->w_cursor.col = 0;
+ curwin->w_cursor.lnum = find_longest_lnum();
+ curwin->w_cursor.col = 0;
}
return leftcol_changed();
@@ -619,10 +628,10 @@ static int mouse_adjust_click(win_T *wp, int row, int col)
// scanned *up to* `col`, nudging it left or right when concealed characters
// are encountered.
//
- // chartabsize() is used to keep track of the virtual column position relative
- // to the line's bytes. For example: if col == 9 and the line starts with a
- // tab that's 8 columns wide, we would want the cursor to be highlighting the
- // second byte, not the ninth.
+ // win_chartabsize() is used to keep track of the virtual column position
+ // relative to the line's bytes. For example: if col == 9 and the line
+ // starts with a tab that's 8 columns wide, we would want the cursor to be
+ // highlighting the second byte, not the ninth.
linenr_T lnum = wp->w_cursor.lnum;
char_u *line = ml_get(lnum);
@@ -646,7 +655,7 @@ static int mouse_adjust_click(win_T *wp, int row, int col)
// checked for concealed characters.
vcol = 0;
while (vcol < offset && *ptr != NUL) {
- vcol += chartabsize(ptr, vcol);
+ vcol += win_chartabsize(curwin, ptr, vcol);
ptr += utfc_ptr2len(ptr);
}
@@ -657,7 +666,7 @@ static int mouse_adjust_click(win_T *wp, int row, int col)
vcol = offset;
ptr_end = ptr_row_offset;
while (vcol < col && *ptr_end != NUL) {
- vcol += chartabsize(ptr_end, vcol);
+ vcol += win_chartabsize(curwin, ptr_end, vcol);
ptr_end += utfc_ptr2len(ptr_end);
}
@@ -672,7 +681,7 @@ static int mouse_adjust_click(win_T *wp, int row, int col)
#define decr() nudge--; ptr_end -= utfc_ptr2len(ptr_end)
while (ptr < ptr_end && *ptr != NUL) {
- cwidth = chartabsize(ptr, vcol);
+ cwidth = win_chartabsize(curwin, ptr, vcol);
vcol += cwidth;
if (cwidth > 1 && *ptr == '\t' && nudge > 0) {
// A tab will "absorb" any previous adjustments.
@@ -721,14 +730,20 @@ int mouse_check_fold(void)
int click_row = mouse_row;
int click_col = mouse_col;
int mouse_char = ' ';
+ int max_row = Rows;
+ int max_col = Columns;
+ int multigrid = ui_has(kUIMultigrid);
win_T *wp;
wp = mouse_find_win(&click_grid, &click_row, &click_col);
+ if (wp && multigrid) {
+ max_row = wp->w_grid_alloc.Rows;
+ max_col = wp->w_grid_alloc.Columns;
+ }
- if (wp && mouse_row >= 0 && mouse_row < Rows
- && mouse_col >= 0 && mouse_col <= Columns) {
- int multigrid = ui_has(kUIMultigrid);
+ if (wp && mouse_row >= 0 && mouse_row < max_row
+ && mouse_col >= 0 && mouse_col < max_col) {
ScreenGrid *gp = multigrid ? &wp->w_grid_alloc : &default_grid;
int fdc = win_fdccol_count(wp);
int row = multigrid && mouse_grid == 0 ? click_row : mouse_row;
diff --git a/src/nvim/move.c b/src/nvim/move.c
index 1210a3365a..ca3dd34204 100644
--- a/src/nvim/move.c
+++ b/src/nvim/move.c
@@ -17,7 +17,7 @@
#include <stdbool.h>
#include "nvim/ascii.h"
-#include "nvim/move.h"
+#include "nvim/buffer.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
#include "nvim/diff.h"
@@ -26,16 +26,18 @@
#include "nvim/mbyte.h"
#include "nvim/memline.h"
#include "nvim/misc1.h"
+#include "nvim/move.h"
#include "nvim/option.h"
+#include "nvim/plines.h"
#include "nvim/popupmnu.h"
#include "nvim/screen.h"
#include "nvim/strings.h"
#include "nvim/window.h"
typedef struct {
- linenr_T lnum; /* line number */
- int fill; /* filler lines */
- int height; /* height of added line */
+ linenr_T lnum; // line number
+ int fill; // filler lines
+ int height; // height of added line
} lineoff_T;
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -83,7 +85,7 @@ static void comp_botline(win_T *wp)
lnum = last;
}
- /* wp->w_botline is the line that is just below the window */
+ // wp->w_botline is the line that is just below the window
wp->w_botline = lnum;
wp->w_valid |= VALID_BOTLINE|VALID_BOTLINE_AP;
wp->w_viewport_invalid = true;
@@ -172,7 +174,7 @@ void update_topline(win_T *wp)
old_topfill = wp->w_topfill;
// If the buffer is empty, always set topline to 1.
- if (BUFEMPTY()) { // special case - file is empty
+ if (buf_is_empty(curbuf)) { // special case - file is empty
if (wp->w_topline != 1) {
redraw_later(wp, NOT_VALID);
}
@@ -195,7 +197,7 @@ void update_topline(win_T *wp)
}
}
// Check if there are more filler lines than allowed.
- if (!check_topline && wp->w_topfill > diff_check_fill(wp, wp->w_topline)) {
+ if (!check_topline && wp->w_topfill > win_get_fill(wp, wp->w_topline)) {
check_topline = true;
}
@@ -272,8 +274,7 @@ void update_topline(win_T *wp)
n += wp->w_filler_rows;
loff.height = 0;
while (loff.lnum < wp->w_botline
- && (loff.lnum + 1 < wp->w_botline || loff.fill == 0)
- ) {
+ && (loff.lnum + 1 < wp->w_botline || loff.fill == 0)) {
n += loff.height;
if (n >= *so_ptr) {
break;
@@ -285,7 +286,7 @@ void update_topline(win_T *wp)
check_botline = false;
}
} else {
- /* sufficient context, no need to scroll */
+ // sufficient context, no need to scroll
check_botline = false;
}
}
@@ -323,8 +324,7 @@ void update_topline(win_T *wp)
* Need to redraw when topline changed.
*/
if (wp->w_topline != old_topline
- || wp->w_topfill != old_topfill
- ) {
+ || wp->w_topfill != old_topfill) {
dollar_vcol = -1;
if (wp->w_skipcol != 0) {
wp->w_skipcol = 0;
@@ -344,7 +344,7 @@ void update_topline(win_T *wp)
/*
* Update win->w_topline to move the cursor onto the screen.
*/
-void update_topline_win(win_T* win)
+void update_topline_win(win_T * win)
{
win_T *save_curwin;
switch_win(&save_curwin, NULL, win, NULL, true);
@@ -372,8 +372,7 @@ static bool check_top_offset(void)
{
long so = get_scrolloff_value(curwin);
if (curwin->w_cursor.lnum < curwin->w_topline + so
- || hasAnyFolding(curwin)
- ) {
+ || hasAnyFolding(curwin)) {
lineoff_T loff;
loff.lnum = curwin->w_cursor.lnum;
loff.fill = 0;
@@ -383,8 +382,8 @@ static bool check_top_offset(void)
topline_back(curwin, &loff);
// Stop when included a line above the window.
if (loff.lnum < curwin->w_topline
- || (loff.lnum == curwin->w_topline && loff.fill > 0)
- ) {
+ || (loff.lnum == curwin->w_topline &&
+ loff.fill > 0)) {
break;
}
n += loff.height;
@@ -418,8 +417,8 @@ void check_cursor_moved(win_T *wp)
wp->w_viewport_invalid = true;
} else if (wp->w_cursor.col != wp->w_valid_cursor.col
|| wp->w_leftcol != wp->w_valid_leftcol
- || wp->w_cursor.coladd != wp->w_valid_cursor.coladd
- ) {
+ || wp->w_cursor.coladd !=
+ wp->w_valid_cursor.coladd) {
wp->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL);
wp->w_valid_cursor.col = wp->w_cursor.col;
wp->w_valid_leftcol = wp->w_leftcol;
@@ -451,13 +450,18 @@ void changed_window_setting_win(win_T *wp)
*/
void set_topline(win_T *wp, linenr_T lnum)
{
- /* go to first of folded lines */
+ linenr_T prev_topline = wp->w_topline;
+
+ // go to first of folded lines
(void)hasFoldingWin(wp, lnum, &lnum, NULL, true, NULL);
- /* Approximate the value of w_botline */
+ // Approximate the value of w_botline
wp->w_botline += lnum - wp->w_topline;
wp->w_topline = lnum;
wp->w_topline_was_set = true;
- wp->w_topfill = 0;
+ if (lnum != prev_topline) {
+ // Keep the filler lines when the topline didn't change.
+ wp->w_topfill = 0;
+ }
wp->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE|VALID_TOPLINE);
// Don't set VALID_TOPLINE here, 'scrolloff' needs to be checked.
redraw_later(wp, VALID);
@@ -553,7 +557,7 @@ void validate_cursor(void)
*/
static void curs_rows(win_T *wp)
{
- /* Check if wp->w_lines[].wl_size is invalid */
+ // Check if wp->w_lines[].wl_size is invalid
int all_invalid = (!redrawing()
|| wp->w_lines_valid == 0
|| wp->w_lines[0].wl_lnum > wp->w_topline);
@@ -562,27 +566,28 @@ static void curs_rows(win_T *wp)
for (linenr_T lnum = wp->w_topline; lnum < wp->w_cursor.lnum; ++i) {
bool valid = false;
if (!all_invalid && i < wp->w_lines_valid) {
- if (wp->w_lines[i].wl_lnum < lnum || !wp->w_lines[i].wl_valid)
- continue; /* skip changed or deleted lines */
+ if (wp->w_lines[i].wl_lnum < lnum || !wp->w_lines[i].wl_valid) {
+ continue; // skip changed or deleted lines
+ }
if (wp->w_lines[i].wl_lnum == lnum) {
/* Check for newly inserted lines below this row, in which
* case we need to check for folded lines. */
if (!wp->w_buffer->b_mod_set
|| wp->w_lines[i].wl_lastlnum < wp->w_cursor.lnum
- || wp->w_buffer->b_mod_top
- > wp->w_lines[i].wl_lastlnum + 1)
+ || wp->w_buffer->b_mod_top
+ > wp->w_lines[i].wl_lastlnum + 1) {
valid = true;
+ }
} else if (wp->w_lines[i].wl_lnum > lnum) {
- --i; /* hold at inserted lines */
+ --i; // hold at inserted lines
}
}
- if (valid
- && (lnum != wp->w_topline || !wp->w_p_diff)
- ) {
+ if (valid && (lnum != wp->w_topline || !win_may_fill(wp))) {
lnum = wp->w_lines[i].wl_lastlnum + 1;
- /* Cursor inside folded lines, don't count this row */
- if (lnum > wp->w_cursor.lnum)
+ // Cursor inside folded lines, don't count this row
+ if (lnum > wp->w_cursor.lnum) {
break;
+ }
wp->w_cline_row += wp->w_lines[i].wl_size;
} else {
linenr_T last = lnum;
@@ -606,7 +611,7 @@ static void curs_rows(win_T *wp)
wp->w_cline_height = plines_win_full(wp, wp->w_cursor.lnum, NULL,
&wp->w_cline_folded, true);
} else if (i > wp->w_lines_valid) {
- /* a line that is too long to fit on the last screen line */
+ // a line that is too long to fit on the last screen line
wp->w_cline_height = 0;
wp->w_cline_folded = hasFoldingWin(wp, wp->w_cursor.lnum, NULL,
NULL, true, NULL);
@@ -638,9 +643,9 @@ void validate_virtcol_win(win_T *wp)
getvvcol(wp, &wp->w_cursor, NULL, &(wp->w_virtcol), NULL);
wp->w_valid |= VALID_VIRTCOL;
if (wp->w_p_cuc
- && !pum_visible()
- )
+ && !pum_visible()) {
redraw_later(wp, SOME_VALID);
+ }
}
}
@@ -711,8 +716,9 @@ int curwin_col_off(void)
*/
int win_col_off2(win_T *wp)
{
- if ((wp->w_p_nu || wp->w_p_rnu) && vim_strchr(p_cpo, CPO_NUMCOL) != NULL)
+ if ((wp->w_p_nu || wp->w_p_rnu) && vim_strchr(p_cpo, CPO_NUMCOL) != NULL) {
return number_width(wp) + 1;
+ }
return 0;
}
@@ -725,10 +731,7 @@ int curwin_col_off2(void)
// Also updates curwin->w_wrow and curwin->w_cline_row.
// Also updates curwin->w_leftcol.
// @param may_scroll when true, may scroll horizontally
-void curs_columns(
- win_T *wp,
- int may_scroll
-)
+void curs_columns(win_T *wp, int may_scroll)
{
int n;
int width = 0;
@@ -758,9 +761,10 @@ void curs_columns(
getvvcol(wp, &wp->w_cursor, &startcol, &(wp->w_virtcol), &endcol);
}
- /* remove '$' from change command when cursor moves onto it */
- if (startcol > dollar_vcol)
+ // remove '$' from change command when cursor moves onto it
+ if (startcol > dollar_vcol) {
dollar_vcol = -1;
+ }
int extra = win_col_off(wp);
wp->w_wcol = wp->w_virtcol + extra;
@@ -775,8 +779,7 @@ void curs_columns(
wp->w_wcol = wp->w_width_inner - 1;
wp->w_wrow = wp->w_height_inner - 1;
} else if (wp->w_p_wrap
- && wp->w_width_inner != 0
- ) {
+ && wp->w_width_inner != 0) {
width = textwidth + win_col_off2(wp);
// long line wrapping, adjust wp->w_wrow
@@ -786,17 +789,17 @@ void curs_columns(
wp->w_wcol -= n * width;
wp->w_wrow += n;
- /* When cursor wraps to first char of next line in Insert
- * mode, the 'showbreak' string isn't shown, backup to first
- * column */
- if (*p_sbr && *get_cursor_pos_ptr() == NUL
- && wp->w_wcol == (int)vim_strsize(p_sbr)) {
+ // When cursor wraps to first char of next line in Insert
+ // mode, the 'showbreak' string isn't shown, backup to first
+ // column
+ char_u *const sbr = get_showbreak_value(wp);
+ if (*sbr && *get_cursor_pos_ptr() == NUL
+ && wp->w_wcol == (int)vim_strsize(sbr)) {
wp->w_wcol = 0;
}
}
} else if (may_scroll
- && !wp->w_cline_folded
- ) {
+ && !wp->w_cline_folded) {
// No line wrapping: compute wp->w_leftcol if scrolling is on and line
// is not folded.
// If scrolling is off, wp->w_leftcol is assumed to be 0
@@ -808,7 +811,7 @@ void curs_columns(
assert(siso <= INT_MAX);
int off_left = startcol - wp->w_leftcol - (int)siso;
int off_right =
- endcol - wp->w_leftcol - wp->w_width_inner + (int)siso + 1;
+ endcol - wp->w_leftcol - wp->w_width_inner + (int)siso + 1;
if (off_left < 0 || off_right > 0) {
int diff = (off_left < 0) ? -off_left: off_right;
@@ -828,8 +831,9 @@ void curs_columns(
new_leftcol = wp->w_leftcol + diff;
}
}
- if (new_leftcol < 0)
+ if (new_leftcol < 0) {
new_leftcol = 0;
+ }
if (new_leftcol != (int)wp->w_leftcol) {
wp->w_leftcol = new_leftcol;
win_check_anchored_floats(wp);
@@ -849,7 +853,7 @@ void curs_columns(
if (wp->w_cursor.lnum == wp->w_topline) {
wp->w_wrow += wp->w_topfill;
} else {
- wp->w_wrow += diff_check_fill(wp, wp->w_cursor.lnum);
+ wp->w_wrow += win_get_fill(wp, wp->w_cursor.lnum);
}
prev_skipcol = wp->w_skipcol;
@@ -859,13 +863,12 @@ void curs_columns(
|| ((prev_skipcol > 0
|| wp->w_wrow + so >= wp->w_height_inner)
&& (plines =
- plines_win_nofill(wp, wp->w_cursor.lnum, false)) - 1
+ plines_win_nofill(wp, wp->w_cursor.lnum, false)) - 1
>= wp->w_height_inner))
&& wp->w_height_inner != 0
&& wp->w_cursor.lnum == wp->w_topline
&& width > 0
- && wp->w_width_inner != 0
- ) {
+ && wp->w_width_inner != 0) {
/* Cursor past end of screen. Happens with a single line that does
* not fit on screen. Find a skipcol to show the text around the
* cursor. Avoid scrolling all the time. compute value of "extra":
@@ -964,8 +967,8 @@ void curs_columns(
/// @param[out] scolp start screen column
/// @param[out] ccolp cursor screen column
/// @param[out] ecolp end screen column
-void textpos2screenpos(win_T *wp, pos_T *pos, int *rowp, int *scolp,
- int *ccolp, int *ecolp, bool local)
+void textpos2screenpos(win_T *wp, pos_T *pos, int *rowp, int *scolp, int *ccolp, int *ecolp,
+ bool local)
{
colnr_T scol = 0, ccol = 0, ecol = 0;
int row = 0;
@@ -988,7 +991,7 @@ void textpos2screenpos(win_T *wp, pos_T *pos, int *rowp, int *scolp,
if ((local && existing_row) || visible_row) {
colnr_T off;
colnr_T col;
- int width;
+ int width;
getvcol(wp, pos, &scol, &ccol, &ecol);
@@ -1033,38 +1036,42 @@ bool scrolldown(long line_count, int byfold)
{
int done = 0; // total # of physical lines done
- /* Make sure w_topline is at the first of a sequence of folded lines. */
+ // Make sure w_topline is at the first of a sequence of folded lines.
(void)hasFolding(curwin->w_topline, &curwin->w_topline, NULL);
- validate_cursor(); /* w_wrow needs to be valid */
+ validate_cursor(); // w_wrow needs to be valid
while (line_count-- > 0) {
- if (curwin->w_topfill < diff_check(curwin, curwin->w_topline)
+ if (curwin->w_topfill < win_get_fill(curwin, curwin->w_topline)
&& curwin->w_topfill < curwin->w_height_inner - 1) {
curwin->w_topfill++;
done++;
} else {
- if (curwin->w_topline == 1)
+ if (curwin->w_topline == 1) {
break;
+ }
--curwin->w_topline;
curwin->w_topfill = 0;
- /* A sequence of folded lines only counts for one logical line */
+ // A sequence of folded lines only counts for one logical line
linenr_T first;
if (hasFolding(curwin->w_topline, &first, NULL)) {
++done;
- if (!byfold)
+ if (!byfold) {
line_count -= curwin->w_topline - first - 1;
+ }
curwin->w_botline -= curwin->w_topline - first;
curwin->w_topline = first;
- } else
- done += plines_nofill(curwin->w_topline);
+ } else {
+ done += plines_win_nofill(curwin, curwin->w_topline, true);
+ }
}
- --curwin->w_botline; /* approximate w_botline */
+ --curwin->w_botline; // approximate w_botline
invalidate_botline();
}
- curwin->w_wrow += done; /* keep w_wrow updated */
- curwin->w_cline_row += done; /* keep w_cline_row updated */
+ curwin->w_wrow += done; // keep w_wrow updated
+ curwin->w_cline_row += done; // keep w_cline_row updated
- if (curwin->w_cursor.lnum == curwin->w_topline)
+ if (curwin->w_cursor.lnum == curwin->w_topline) {
curwin->w_cline_row = 0;
+ }
check_topfill(curwin, true);
/*
@@ -1073,8 +1080,7 @@ bool scrolldown(long line_count, int byfold)
*/
int wrow = curwin->w_wrow;
if (curwin->w_p_wrap
- && curwin->w_width_inner != 0
- ) {
+ && curwin->w_width_inner != 0) {
validate_virtcol();
validate_cheight();
wrow += curwin->w_cline_height - 1 -
@@ -1085,18 +1091,20 @@ bool scrolldown(long line_count, int byfold)
linenr_T first;
if (hasFolding(curwin->w_cursor.lnum, &first, NULL)) {
--wrow;
- if (first == 1)
+ if (first == 1) {
curwin->w_cursor.lnum = 1;
- else
+ } else {
curwin->w_cursor.lnum = first - 1;
- } else
- wrow -= plines(curwin->w_cursor.lnum--);
+ }
+ } else {
+ wrow -= plines_win(curwin, curwin->w_cursor.lnum--, true);
+ }
curwin->w_valid &=
~(VALID_WROW|VALID_WCOL|VALID_CHEIGHT|VALID_CROW|VALID_VIRTCOL);
moved = true;
}
if (moved) {
- /* Move cursor to first line of closed fold. */
+ // Move cursor to first line of closed fold.
foldAdjustCursor();
coladvance(curwin->w_curswant);
}
@@ -1113,39 +1121,44 @@ bool scrollup(long line_count, int byfold)
linenr_T botline = curwin->w_botline;
if ((byfold && hasAnyFolding(curwin))
- || curwin->w_p_diff) {
+ || win_may_fill(curwin)) {
// count each sequence of folded lines as one logical line
linenr_T lnum = curwin->w_topline;
while (line_count--) {
- if (curwin->w_topfill > 0)
+ if (curwin->w_topfill > 0) {
--curwin->w_topfill;
- else {
- if (byfold)
+ } else {
+ if (byfold) {
(void)hasFolding(lnum, NULL, &lnum);
- if (lnum >= curbuf->b_ml.ml_line_count)
+ }
+ if (lnum >= curbuf->b_ml.ml_line_count) {
break;
- ++lnum;
- curwin->w_topfill = diff_check_fill(curwin, lnum);
+ }
+ lnum++;
+ curwin->w_topfill = win_get_fill(curwin, lnum);
}
}
- /* approximate w_botline */
+ // approximate w_botline
curwin->w_botline += lnum - curwin->w_topline;
curwin->w_topline = lnum;
} else {
curwin->w_topline += line_count;
- curwin->w_botline += line_count; /* approximate w_botline */
+ curwin->w_botline += line_count; // approximate w_botline
}
- if (curwin->w_topline > curbuf->b_ml.ml_line_count)
+ if (curwin->w_topline > curbuf->b_ml.ml_line_count) {
curwin->w_topline = curbuf->b_ml.ml_line_count;
- if (curwin->w_botline > curbuf->b_ml.ml_line_count + 1)
+ }
+ if (curwin->w_botline > curbuf->b_ml.ml_line_count + 1) {
curwin->w_botline = curbuf->b_ml.ml_line_count + 1;
+ }
check_topfill(curwin, false);
- if (hasAnyFolding(curwin))
- /* Make sure w_topline is at the first of a sequence of folded lines. */
+ if (hasAnyFolding(curwin)) {
+ // Make sure w_topline is at the first of a sequence of folded lines.
(void)hasFolding(curwin->w_topline, &curwin->w_topline, NULL);
+ }
curwin->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE);
if (curwin->w_cursor.lnum < curwin->w_topline) {
@@ -1156,19 +1169,15 @@ bool scrollup(long line_count, int byfold)
}
bool moved = topline != curwin->w_topline
- || botline != curwin->w_botline;
+ || botline != curwin->w_botline;
return moved;
}
-/*
- * Don't end up with too many filler lines in the window.
- */
-void
-check_topfill (
- win_T *wp,
- bool down /* when true scroll down when not enough space */
-)
+/// Don't end up with too many filler lines in the window.
+///
+/// @param down when true scroll down when not enough space
+void check_topfill(win_T *wp, bool down)
{
if (wp->w_topfill > 0) {
int n = plines_win_nofill(wp, wp->w_topline, true);
@@ -1193,11 +1202,11 @@ check_topfill (
*/
static void max_topfill(void)
{
- int n = plines_nofill(curwin->w_topline);
+ int n = plines_win_nofill(curwin, curwin->w_topline, true);
if (n >= curwin->w_height_inner) {
curwin->w_topfill = 0;
} else {
- curwin->w_topfill = diff_check_fill(curwin, curwin->w_topline);
+ curwin->w_topfill = win_get_fill(curwin, curwin->w_topline);
if (curwin->w_topfill + n > curwin->w_height_inner) {
curwin->w_topfill = curwin->w_height_inner - n;
}
@@ -1210,29 +1219,25 @@ static void max_topfill(void)
*/
void scrolldown_clamp(void)
{
- int can_fill = (curwin->w_topfill
- < diff_check_fill(curwin, curwin->w_topline));
+ int can_fill = (curwin->w_topfill < win_get_fill(curwin, curwin->w_topline));
if (curwin->w_topline <= 1
- && !can_fill
- )
+ && !can_fill) {
return;
+ }
- validate_cursor(); /* w_wrow needs to be valid */
+ validate_cursor(); // w_wrow needs to be valid
- /*
- * Compute the row number of the last row of the cursor line
- * and make sure it doesn't go off the screen. Make sure the cursor
- * doesn't go past 'scrolloff' lines from the screen end.
- */
+ // Compute the row number of the last row of the cursor line
+ // and make sure it doesn't go off the screen. Make sure the cursor
+ // doesn't go past 'scrolloff' lines from the screen end.
int end_row = curwin->w_wrow;
- if (can_fill)
- ++end_row;
- else
- end_row += plines_nofill(curwin->w_topline - 1);
- if (curwin->w_p_wrap
- && curwin->w_width_inner != 0
- ) {
+ if (can_fill) {
+ end_row++;
+ } else {
+ end_row += plines_win_nofill(curwin, curwin->w_topline - 1, true);
+ }
+ if (curwin->w_p_wrap && curwin->w_width_inner != 0) {
validate_cheight();
validate_virtcol();
end_row += curwin->w_cline_height - 1 -
@@ -1247,7 +1252,7 @@ void scrolldown_clamp(void)
curwin->w_topfill = 0;
}
(void)hasFolding(curwin->w_topline, &curwin->w_topline, NULL);
- --curwin->w_botline; /* approximate w_botline */
+ --curwin->w_botline; // approximate w_botline
curwin->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE);
}
}
@@ -1259,22 +1264,19 @@ void scrolldown_clamp(void)
void scrollup_clamp(void)
{
if (curwin->w_topline == curbuf->b_ml.ml_line_count
- && curwin->w_topfill == 0
- )
+ && curwin->w_topfill == 0) {
return;
+ }
- validate_cursor(); /* w_wrow needs to be valid */
+ validate_cursor(); // w_wrow needs to be valid
- /*
- * Compute the row number of the first row of the cursor line
- * and make sure it doesn't go off the screen. Make sure the cursor
- * doesn't go before 'scrolloff' lines from the screen start.
- */
- int start_row = curwin->w_wrow - plines_nofill(curwin->w_topline)
- - curwin->w_topfill;
- if (curwin->w_p_wrap
- && curwin->w_width_inner != 0
- ) {
+ // Compute the row number of the first row of the cursor line
+ // and make sure it doesn't go off the screen. Make sure the cursor
+ // doesn't go before 'scrolloff' lines from the screen start.
+ int start_row = (curwin->w_wrow
+ - plines_win_nofill(curwin, curwin->w_topline, true)
+ - curwin->w_topfill);
+ if (curwin->w_p_wrap && curwin->w_width_inner != 0) {
validate_virtcol();
start_row -= curwin->w_virtcol / curwin->w_width_inner;
}
@@ -1298,7 +1300,7 @@ void scrollup_clamp(void)
*/
static void topline_back(win_T *wp, lineoff_T *lp)
{
- if (lp->fill < diff_check_fill(wp, lp->lnum)) {
+ if (lp->fill < win_get_fill(wp, lp->lnum)) {
// Add a filler line
lp->fill++;
lp->height = 1;
@@ -1324,7 +1326,7 @@ static void topline_back(win_T *wp, lineoff_T *lp)
*/
static void botline_forw(win_T *wp, lineoff_T *lp)
{
- if (lp->fill < diff_check_fill(wp, lp->lnum + 1)) {
+ if (lp->fill < win_get_fill(wp, lp->lnum + 1)) {
// Add a filler line.
lp->fill++;
lp->height = 1;
@@ -1351,8 +1353,8 @@ static void botline_forw(win_T *wp, lineoff_T *lp)
static void botline_topline(lineoff_T *lp)
{
if (lp->fill > 0) {
- ++lp->lnum;
- lp->fill = diff_check_fill(curwin, lp->lnum) - lp->fill + 1;
+ lp->lnum++;
+ lp->fill = win_get_fill(curwin, lp->lnum) - lp->fill + 1;
}
}
@@ -1364,8 +1366,8 @@ static void botline_topline(lineoff_T *lp)
static void topline_botline(lineoff_T *lp)
{
if (lp->fill > 0) {
- lp->fill = diff_check_fill(curwin, lp->lnum) - lp->fill + 1;
- --lp->lnum;
+ lp->fill = win_get_fill(curwin, lp->lnum) - lp->fill + 1;
+ lp->lnum--;
}
}
@@ -1377,15 +1379,16 @@ static void topline_botline(lineoff_T *lp)
void scroll_cursor_top(int min_scroll, int always)
{
int scrolled = 0;
- linenr_T top; /* just above displayed lines */
- linenr_T bot; /* just below displayed lines */
+ linenr_T top; // just above displayed lines
+ linenr_T bot; // just below displayed lines
linenr_T old_topline = curwin->w_topline;
linenr_T old_topfill = curwin->w_topfill;
linenr_T new_topline;
int off = (int)get_scrolloff_value(curwin);
- if (mouse_dragging > 0)
+ if (mouse_dragging > 0) {
off = mouse_dragging - 1;
+ }
/*
* Decrease topline until:
@@ -1412,7 +1415,7 @@ void scroll_cursor_top(int min_scroll, int always)
// "used" already contains the number of filler lines above, don't add it
// again.
// Hide filler lines above cursor line by adding them to "extra".
- int extra = diff_check_fill(curwin, curwin->w_cursor.lnum);
+ int extra = win_get_fill(curwin, curwin->w_cursor.lnum);
/*
* Check if the lines from "top" to "bot" fit in the window. If they do,
@@ -1421,14 +1424,15 @@ void scroll_cursor_top(int min_scroll, int always)
while (top > 0) {
int i = hasFolding(top, &top, NULL)
? 1 // count one logical line for a sequence of folded lines
- : plines_nofill(top);
+ : plines_win_nofill(curwin, top, true);
used += i;
if (extra + i <= off && bot < curbuf->b_ml.ml_line_count) {
- if (hasFolding(bot, NULL, &bot))
- /* count one logical line for a sequence of folded lines */
- ++used;
- else
- used += plines(bot);
+ if (hasFolding(bot, NULL, &bot)) {
+ // count one logical line for a sequence of folded lines
+ used++;
+ } else {
+ used += plines_win(curwin, bot, true);
+ }
}
if (used > curwin->w_height_inner) {
break;
@@ -1441,8 +1445,9 @@ void scroll_cursor_top(int min_scroll, int always)
* If scrolling is needed, scroll at least 'sj' lines.
*/
if ((new_topline >= curwin->w_topline || scrolled > min_scroll)
- && extra >= off)
+ && extra >= off) {
break;
+ }
extra += i;
new_topline = top;
@@ -1462,22 +1467,25 @@ void scroll_cursor_top(int min_scroll, int always)
* If "always" is false, only adjust topline to a lower value, higher
* value may happen with wrapping lines
*/
- if (new_topline < curwin->w_topline || always)
+ if (new_topline < curwin->w_topline || always) {
curwin->w_topline = new_topline;
- if (curwin->w_topline > curwin->w_cursor.lnum)
+ }
+ if (curwin->w_topline > curwin->w_cursor.lnum) {
curwin->w_topline = curwin->w_cursor.lnum;
- curwin->w_topfill = diff_check_fill(curwin, curwin->w_topline);
+ }
+ curwin->w_topfill = win_get_fill(curwin, curwin->w_topline);
if (curwin->w_topfill > 0 && extra > off) {
curwin->w_topfill -= extra - off;
- if (curwin->w_topfill < 0)
+ if (curwin->w_topfill < 0) {
curwin->w_topfill = 0;
+ }
}
check_topfill(curwin, false);
if (curwin->w_topline != old_topline
- || curwin->w_topfill != old_topfill
- )
+ || curwin->w_topfill != old_topfill) {
curwin->w_valid &=
~(VALID_WROW|VALID_CROW|VALID_BOTLINE|VALID_BOTLINE_AP);
+ }
curwin->w_valid |= VALID_TOPLINE;
curwin->w_viewport_invalid = true;
}
@@ -1495,10 +1503,10 @@ void set_empty_rows(win_T *wp, int used)
} else {
wp->w_empty_rows = wp->w_height_inner - used;
if (wp->w_botline <= wp->w_buffer->b_ml.ml_line_count) {
- wp->w_filler_rows = diff_check_fill(wp, wp->w_botline);
- if (wp->w_empty_rows > wp->w_filler_rows)
+ wp->w_filler_rows = win_get_fill(wp, wp->w_botline);
+ if (wp->w_empty_rows > wp->w_filler_rows) {
wp->w_empty_rows -= wp->w_filler_rows;
- else {
+ } else {
wp->w_filler_rows = wp->w_empty_rows;
wp->w_empty_rows = 0;
}
@@ -1521,10 +1529,10 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
lineoff_T boff;
int fill_below_window;
linenr_T old_topline = curwin->w_topline;
- int old_topfill = curwin->w_topfill;
+ int old_topfill = curwin->w_topfill;
linenr_T old_botline = curwin->w_botline;
- int old_valid = curwin->w_valid;
- int old_empty_rows = curwin->w_empty_rows;
+ int old_valid = curwin->w_valid;
+ int old_empty_rows = curwin->w_empty_rows;
linenr_T cln = curwin->w_cursor.lnum; // Cursor Line Number
long so = get_scrolloff_value(curwin);
@@ -1547,23 +1555,24 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
set_empty_rows(curwin, used);
curwin->w_valid |= VALID_BOTLINE|VALID_BOTLINE_AP;
if (curwin->w_topline != old_topline
- || curwin->w_topfill != old_topfill
- )
+ || curwin->w_topfill != old_topfill) {
curwin->w_valid &= ~(VALID_WROW|VALID_CROW);
+ }
} else {
validate_botline(curwin);
}
- /* The lines of the cursor line itself are always used. */
- used = plines_nofill(cln);
+ // The lines of the cursor line itself are always used.
+ used = plines_win_nofill(curwin, cln, true);
- /* If the cursor is below botline, we will at least scroll by the height
- * of the cursor line. Correct for empty lines, which are really part of
- * botline. */
+ // If the cursor is below botline, we will at least scroll by the height
+ // of the cursor line. Correct for empty lines, which are really part of
+ // botline.
if (cln >= curwin->w_botline) {
scrolled = used;
- if (cln == curwin->w_botline)
+ if (cln == curwin->w_botline) {
scrolled -= curwin->w_empty_rows;
+ }
}
/*
@@ -1579,7 +1588,7 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
}
loff.fill = 0;
boff.fill = 0;
- fill_below_window = diff_check_fill(curwin, curwin->w_botline)
+ fill_below_window = win_get_fill(curwin, curwin->w_botline)
- curwin->w_filler_rows;
while (loff.lnum > 1) {
@@ -1590,8 +1599,7 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
|| boff.lnum + 1 > curbuf->b_ml.ml_line_count)
&& loff.lnum <= curwin->w_botline
&& (loff.lnum < curwin->w_botline
- || loff.fill >= fill_below_window)
- ) {
+ || loff.fill >= fill_below_window)) {
break;
}
@@ -1607,9 +1615,8 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
}
if (loff.lnum >= curwin->w_botline
&& (loff.lnum > curwin->w_botline
- || loff.fill <= fill_below_window)
- ) {
- /* Count screen lines that are below the window. */
+ || loff.fill <= fill_below_window)) {
+ // Count screen lines that are below the window.
scrolled += loff.height;
if (loff.lnum == curwin->w_botline
&& loff.fill == 0) {
@@ -1629,14 +1636,13 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
extra += boff.height;
if (boff.lnum >= curwin->w_botline
|| (boff.lnum + 1 == curwin->w_botline
- && boff.fill > curwin->w_filler_rows)
- ) {
- /* Count screen lines that are below the window. */
+ && boff.fill > curwin->w_filler_rows)) {
+ // Count screen lines that are below the window.
scrolled += boff.height;
if (boff.lnum == curwin->w_botline
- && boff.fill == 0
- )
+ && boff.fill == 0) {
scrolled -= curwin->w_empty_rows;
+ }
}
}
}
@@ -1646,10 +1652,10 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
// curwin->w_empty_rows is larger, no need to scroll
if (scrolled <= 0) {
line_count = 0;
- // more than a screenfull, don't scroll but redraw
+ // more than a screenfull, don't scroll but redraw
} else if (used > curwin->w_height_inner) {
line_count = used;
- // scroll minimal number of lines
+ // scroll minimal number of lines
} else {
line_count = 0;
boff.fill = curwin->w_topfill;
@@ -1660,8 +1666,9 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
i += boff.height;
++line_count;
}
- if (i < scrolled) /* below curwin->w_botline, don't scroll */
+ if (i < scrolled) { // below curwin->w_botline, don't scroll
line_count = 9999;
+ }
}
/*
@@ -1703,12 +1710,12 @@ void scroll_cursor_halfway(int atend)
loff.lnum = boff.lnum = curwin->w_cursor.lnum;
(void)hasFolding(loff.lnum, &loff.lnum, &boff.lnum);
- int used = plines_nofill(loff.lnum);
+ int used = plines_win_nofill(curwin, loff.lnum, true);
loff.fill = 0;
boff.fill = 0;
linenr_T topline = loff.lnum;
while (topline > 1) {
- if (below <= above) { /* add a line below the cursor first */
+ if (below <= above) { // add a line below the cursor first
if (boff.lnum < curbuf->b_ml.ml_line_count) {
botline_forw(curwin, &boff);
used += boff.height;
@@ -1717,9 +1724,10 @@ void scroll_cursor_halfway(int atend)
}
below += boff.height;
} else {
- ++below; /* count a "~" line */
- if (atend)
+ ++below; // count a "~" line
+ if (atend) {
++used;
+ }
}
}
@@ -1738,8 +1746,9 @@ void scroll_cursor_halfway(int atend)
topfill = loff.fill;
}
}
- if (!hasFolding(topline, &curwin->w_topline, NULL))
+ if (!hasFolding(topline, &curwin->w_topline, NULL)) {
curwin->w_topline = topline;
+ }
curwin->w_topfill = topfill;
if (old_topline > curwin->w_topline + curwin->w_height_inner) {
curwin->w_botfill = false;
@@ -1788,12 +1797,12 @@ void cursor_correct(void)
* If there are sufficient file-lines above and below the cursor, we can
* return now.
*/
- linenr_T cln = curwin->w_cursor.lnum; /* Cursor Line Number */
+ linenr_T cln = curwin->w_cursor.lnum; // Cursor Line Number
if (cln >= curwin->w_topline + above_wanted
&& cln < curwin->w_botline - below_wanted
- && !hasAnyFolding(curwin)
- )
+ && !hasAnyFolding(curwin)) {
return;
+ }
/*
* Narrow down the area where the cursor can be put by taking lines from
@@ -1803,34 +1812,37 @@ void cursor_correct(void)
*/
linenr_T topline = curwin->w_topline;
linenr_T botline = curwin->w_botline - 1;
- /* count filler lines as context */
- int above = curwin->w_topfill; /* screen lines above topline */
- int below = curwin->w_filler_rows; /* screen lines below botline */
+ // count filler lines as context
+ int above = curwin->w_topfill; // screen lines above topline
+ int below = curwin->w_filler_rows; // screen lines below botline
while ((above < above_wanted || below < below_wanted) && topline < botline) {
if (below < below_wanted && (below <= above || above >= above_wanted)) {
- if (hasFolding(botline, &botline, NULL))
- ++below;
- else
- below += plines(botline);
- --botline;
+ if (hasFolding(botline, &botline, NULL)) {
+ below++;
+ } else {
+ below += plines_win(curwin, botline, true);
+ }
+ botline--;
}
if (above < above_wanted && (above < below || below >= below_wanted)) {
- if (hasFolding(topline, NULL, &topline))
- ++above;
- else
- above += plines_nofill(topline);
-
- /* Count filler lines below this line as context. */
- if (topline < botline)
- above += diff_check_fill(curwin, topline + 1);
+ if (hasFolding(topline, NULL, &topline)) {
+ above++;
+ } else {
+ above += plines_win_nofill(curwin, topline, true);
+ }
+
+ // Count filler lines below this line as context.
+ if (topline < botline) {
+ above += win_get_fill(curwin, topline + 1);
+ }
++topline;
}
}
- if (topline == botline || botline == 0)
+ if (topline == botline || botline == 0) {
curwin->w_cursor.lnum = topline;
- else if (topline > botline)
+ } else if (topline > botline) {
curwin->w_cursor.lnum = botline;
- else {
+ } else {
if (cln < topline && curwin->w_topline > 1) {
curwin->w_cursor.lnum = topline;
curwin->w_valid &=
@@ -1860,7 +1872,7 @@ int onepage(Direction dir, long count)
linenr_T old_topline = curwin->w_topline;
long so = get_scrolloff_value(curwin);
- if (curbuf->b_ml.ml_line_count == 1) { /* nothing to do */
+ if (curbuf->b_ml.ml_line_count == 1) { // nothing to do
beep_flush();
return FAIL;
}
@@ -1875,9 +1887,7 @@ int onepage(Direction dir, long count)
? ((curwin->w_topline >= curbuf->b_ml.ml_line_count - so)
&& curwin->w_botline > curbuf->b_ml.ml_line_count)
: (curwin->w_topline == 1
- && curwin->w_topfill ==
- diff_check_fill(curwin, curwin->w_topline)
- )) {
+ && curwin->w_topfill == win_get_fill(curwin, curwin->w_topline))) {
beep_flush();
retval = FAIL;
break;
@@ -1886,16 +1896,18 @@ int onepage(Direction dir, long count)
loff.fill = 0;
if (dir == FORWARD) {
if (ONE_WINDOW && p_window > 0 && p_window < Rows - 1) {
- /* Vi compatible scrolling */
- if (p_window <= 2)
+ // Vi compatible scrolling
+ if (p_window <= 2) {
++curwin->w_topline;
- else
+ } else {
curwin->w_topline += p_window - 2;
- if (curwin->w_topline > curbuf->b_ml.ml_line_count)
+ }
+ if (curwin->w_topline > curbuf->b_ml.ml_line_count) {
curwin->w_topline = curbuf->b_ml.ml_line_count;
+ }
curwin->w_cursor.lnum = curwin->w_topline;
} else if (curwin->w_botline > curbuf->b_ml.ml_line_count) {
- /* at end of file */
+ // at end of file
curwin->w_topline = curbuf->b_ml.ml_line_count;
curwin->w_topfill = 0;
curwin->w_valid &= ~(VALID_WROW|VALID_CROW);
@@ -1903,7 +1915,7 @@ int onepage(Direction dir, long count)
/* For the overlap, start with the line just below the window
* and go upwards. */
loff.lnum = curwin->w_botline;
- loff.fill = diff_check_fill(curwin, loff.lnum)
+ loff.fill = win_get_fill(curwin, loff.lnum)
- curwin->w_filler_rows;
get_scroll_overlap(&loff, -1);
curwin->w_topline = loff.lnum;
@@ -1913,23 +1925,26 @@ int onepage(Direction dir, long count)
curwin->w_valid &= ~(VALID_WCOL|VALID_CHEIGHT|VALID_WROW|
VALID_CROW|VALID_BOTLINE|VALID_BOTLINE_AP);
}
- } else { /* dir == BACKWARDS */
+ } else { // dir == BACKWARDS
if (curwin->w_topline == 1) {
- /* Include max number of filler lines */
+ // Include max number of filler lines
max_topfill();
continue;
}
if (ONE_WINDOW && p_window > 0 && p_window < Rows - 1) {
- /* Vi compatible scrolling (sort of) */
- if (p_window <= 2)
+ // Vi compatible scrolling (sort of)
+ if (p_window <= 2) {
--curwin->w_topline;
- else
+ } else {
curwin->w_topline -= p_window - 2;
- if (curwin->w_topline < 1)
+ }
+ if (curwin->w_topline < 1) {
curwin->w_topline = 1;
+ }
curwin->w_cursor.lnum = curwin->w_topline + p_window - 1;
- if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
+ if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count) {
curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+ }
continue;
}
@@ -1937,8 +1952,7 @@ int onepage(Direction dir, long count)
* line at the bottom of the window. Make sure this results in
* the same line as before doing CTRL-F. */
loff.lnum = curwin->w_topline - 1;
- loff.fill = diff_check_fill(curwin, loff.lnum + 1)
- - curwin->w_topfill;
+ loff.fill = win_get_fill(curwin, loff.lnum + 1) - curwin->w_topfill;
get_scroll_overlap(&loff, 1);
if (loff.lnum >= curbuf->b_ml.ml_line_count) {
@@ -1960,12 +1974,12 @@ int onepage(Direction dir, long count)
n += loff.height;
}
}
- if (loff.lnum < 1) { /* at begin of file */
+ if (loff.lnum < 1) { // at begin of file
curwin->w_topline = 1;
max_topfill();
curwin->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE);
} else {
- /* Go two lines forward again. */
+ // Go two lines forward again.
topline_botline(&loff);
botline_forw(curwin, &loff);
botline_forw(curwin, &loff);
@@ -1977,14 +1991,13 @@ int onepage(Direction dir, long count)
* very long lines. */
if (loff.lnum >= curwin->w_topline
&& (loff.lnum > curwin->w_topline
- || loff.fill >= curwin->w_topfill)
- ) {
+ || loff.fill >= curwin->w_topfill)) {
/* First try using the maximum number of filler lines. If
* that's not enough, backup one line. */
loff.fill = curwin->w_topfill;
- if (curwin->w_topfill < diff_check_fill(curwin,
- curwin->w_topline))
+ if (curwin->w_topfill < win_get_fill(curwin, curwin->w_topline)) {
max_topfill();
+ }
if (curwin->w_topfill == loff.fill) {
--curwin->w_topline;
curwin->w_topfill = 0;
@@ -2035,25 +2048,26 @@ int onepage(Direction dir, long count)
* This is symmetric, so that doing both keeps the same lines displayed.
* Three lines are examined:
*
- * before CTRL-F after CTRL-F / before CTRL-B
- * etc. l1
- * l1 last but one line ------------
- * l2 last text line l2 top text line
- * ------------- l3 second text line
- * l3 etc.
+ * before CTRL-F after CTRL-F / before CTRL-B
+ * etc. l1
+ * l1 last but one line ------------
+ * l2 last text line l2 top text line
+ * ------------- l3 second text line
+ * l3 etc.
*/
static void get_scroll_overlap(lineoff_T *lp, int dir)
{
int min_height = curwin->w_height_inner - 2;
- if (lp->fill > 0)
+ if (lp->fill > 0) {
lp->height = 1;
- else
- lp->height = plines_nofill(lp->lnum);
+ } else {
+ lp->height = plines_win_nofill(curwin, lp->lnum, true);
+ }
int h1 = lp->height;
- if (h1 > min_height)
- return; /* no overlap */
-
+ if (h1 > min_height) {
+ return; // no overlap
+ }
lineoff_T loff0 = *lp;
if (dir > 0) {
botline_forw(curwin, lp);
@@ -2062,7 +2076,7 @@ static void get_scroll_overlap(lineoff_T *lp, int dir)
}
int h2 = lp->height;
if (h2 == MAXCOL || h2 + h1 > min_height) {
- *lp = loff0; /* no overlap */
+ *lp = loff0; // no overlap
return;
}
@@ -2074,7 +2088,7 @@ static void get_scroll_overlap(lineoff_T *lp, int dir)
}
int h3 = lp->height;
if (h3 == MAXCOL || h3 + h2 > min_height) {
- *lp = loff0; /* no overlap */
+ *lp = loff0; // no overlap
return;
}
@@ -2085,10 +2099,11 @@ static void get_scroll_overlap(lineoff_T *lp, int dir)
topline_back(curwin, lp);
}
int h4 = lp->height;
- if (h4 == MAXCOL || h4 + h3 + h2 > min_height || h3 + h2 + h1 > min_height)
- *lp = loff1; /* 1 line overlap */
- else
- *lp = loff2; /* 2 lines overlap */
+ if (h4 == MAXCOL || h4 + h3 + h2 > min_height || h3 + h2 + h1 > min_height) {
+ *lp = loff1; // 1 line overlap
+ } else {
+ *lp = loff2; // 2 lines overlap
+ }
return;
}
@@ -2100,11 +2115,11 @@ void halfpage(bool flag, linenr_T Prenum)
if (Prenum) {
curwin->w_p_scr = (Prenum > curwin->w_height_inner) ? curwin->w_height_inner
- : Prenum;
+ : Prenum;
}
assert(curwin->w_p_scr <= INT_MAX);
int n = curwin->w_p_scr <= curwin->w_height_inner ? (int)curwin->w_p_scr
- : curwin->w_height_inner;
+ : curwin->w_height_inner;
update_topline(curwin);
validate_botline(curwin);
@@ -2119,13 +2134,14 @@ void halfpage(bool flag, linenr_T Prenum)
n--;
curwin->w_topfill--;
} else {
- i = plines_nofill(curwin->w_topline);
+ i = plines_win_nofill(curwin, curwin->w_topline, true);
n -= i;
- if (n < 0 && scrolled > 0)
+ if (n < 0 && scrolled > 0) {
break;
+ }
(void)hasFolding(curwin->w_topline, NULL, &curwin->w_topline);
- ++curwin->w_topline;
- curwin->w_topfill = diff_check_fill(curwin, curwin->w_topline);
+ curwin->w_topline++;
+ curwin->w_topfill = win_get_fill(curwin, curwin->w_topline);
if (curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) {
++curwin->w_cursor.lnum;
@@ -2136,21 +2152,19 @@ void halfpage(bool flag, linenr_T Prenum)
curwin->w_valid &= ~(VALID_CROW|VALID_WROW);
scrolled += i;
- /*
- * Correct w_botline for changed w_topline.
- * Won't work when there are filler lines.
- */
- if (curwin->w_p_diff)
+ // Correct w_botline for changed w_topline.
+ // Won't work when there are filler lines.
+ if (win_may_fill(curwin)) {
curwin->w_valid &= ~(VALID_BOTLINE|VALID_BOTLINE_AP);
- else {
+ } else {
room += i;
do {
- i = plines(curwin->w_botline);
- if (i > room)
+ i = plines_win(curwin, curwin->w_botline, true);
+ if (i > room) {
break;
- (void)hasFolding(curwin->w_botline, NULL,
- &curwin->w_botline);
- ++curwin->w_botline;
+ }
+ (void)hasFolding(curwin->w_botline, NULL, &curwin->w_botline);
+ curwin->w_botline++;
room -= i;
} while (curwin->w_botline <= curbuf->b_ml.ml_line_count);
}
@@ -2162,11 +2176,12 @@ void halfpage(bool flag, linenr_T Prenum)
while (--n >= 0
&& curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) {
(void)hasFolding(curwin->w_cursor.lnum, NULL,
- &curwin->w_cursor.lnum);
+ &curwin->w_cursor.lnum);
++curwin->w_cursor.lnum;
}
- } else
+ } else {
curwin->w_cursor.lnum += n;
+ }
check_cursor_lnum();
}
} else {
@@ -2174,15 +2189,16 @@ void halfpage(bool flag, linenr_T Prenum)
* scroll the text down
*/
while (n > 0 && curwin->w_topline > 1) {
- if (curwin->w_topfill < diff_check_fill(curwin, curwin->w_topline)) {
+ if (curwin->w_topfill < win_get_fill(curwin, curwin->w_topline)) {
i = 1;
n--;
curwin->w_topfill++;
} else {
- i = plines_nofill(curwin->w_topline - 1);
+ i = plines_win_nofill(curwin, curwin->w_topline - 1, true);
n -= i;
- if (n < 0 && scrolled > 0)
+ if (n < 0 && scrolled > 0) {
break;
+ }
--curwin->w_topline;
(void)hasFolding(curwin->w_topline, &curwin->w_topline, NULL);
curwin->w_topfill = 0;
@@ -2198,19 +2214,20 @@ void halfpage(bool flag, linenr_T Prenum)
// When hit top of the file: move cursor up.
if (n > 0) {
- if (curwin->w_cursor.lnum <= (linenr_T)n)
+ if (curwin->w_cursor.lnum <= (linenr_T)n) {
curwin->w_cursor.lnum = 1;
- else if (hasAnyFolding(curwin)) {
+ } else if (hasAnyFolding(curwin)) {
while (--n >= 0 && curwin->w_cursor.lnum > 1) {
--curwin->w_cursor.lnum;
(void)hasFolding(curwin->w_cursor.lnum,
- &curwin->w_cursor.lnum, NULL);
+ &curwin->w_cursor.lnum, NULL);
}
- } else
+ } else {
curwin->w_cursor.lnum -= n;
+ }
}
}
- /* Move cursor to first line of closed fold. */
+ // Move cursor to first line of closed fold.
foldAdjustCursor();
check_topfill(curwin, !flag);
cursor_correct();
@@ -2237,7 +2254,7 @@ void do_check_cursorbind(void)
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
curwin = wp;
curbuf = curwin->w_buffer;
- /* skip original window and windows with 'noscrollbind' */
+ // skip original window and windows with 'noscrollbind'
if (curwin != old_curwin && curwin->w_p_crb) {
if (curwin->w_p_diff) {
curwin->w_cursor.lnum =
diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c
index a2d8859c68..a1a1f0f8c0 100644
--- a/src/nvim/msgpack_rpc/channel.c
+++ b/src/nvim/msgpack_rpc/channel.c
@@ -1,44 +1,43 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+#include <inttypes.h>
+#include <msgpack.h>
#include <stdbool.h>
#include <string.h>
-#include <inttypes.h>
-
#include <uv.h>
-#include <msgpack.h>
#include "nvim/api/private/helpers.h"
-#include "nvim/api/vim.h"
#include "nvim/api/ui.h"
+#include "nvim/api/vim.h"
+#include "nvim/ascii.h"
#include "nvim/channel.h"
-#include "nvim/msgpack_rpc/channel.h"
-#include "nvim/event/loop.h"
+#include "nvim/eval.h"
#include "nvim/event/libuv_process.h"
+#include "nvim/event/loop.h"
#include "nvim/event/rstream.h"
-#include "nvim/event/wstream.h"
#include "nvim/event/socket.h"
-#include "nvim/msgpack_rpc/helpers.h"
-#include "nvim/vim.h"
+#include "nvim/event/wstream.h"
+#include "nvim/lib/kvec.h"
+#include "nvim/log.h"
#include "nvim/main.h"
-#include "nvim/ascii.h"
+#include "nvim/map.h"
#include "nvim/memory.h"
-#include "nvim/eval.h"
-#include "nvim/os_unix.h"
#include "nvim/message.h"
-#include "nvim/map.h"
-#include "nvim/log.h"
#include "nvim/misc1.h"
-#include "nvim/lib/kvec.h"
+#include "nvim/msgpack_rpc/channel.h"
+#include "nvim/msgpack_rpc/helpers.h"
#include "nvim/os/input.h"
+#include "nvim/os_unix.h"
#include "nvim/ui.h"
+#include "nvim/vim.h"
#if MIN_LOG_LEVEL > DEBUG_LOG_LEVEL
-#define log_client_msg(...)
-#define log_server_msg(...)
+# define log_client_msg(...)
+# define log_server_msg(...)
#endif
-static PMap(cstr_t) *event_strings = NULL;
+static PMap(cstr_t) event_strings = MAP_INIT;
static msgpack_sbuffer out_buffer;
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -48,7 +47,6 @@ static msgpack_sbuffer out_buffer;
void rpc_init(void)
{
ch_before_blocking_events = multiqueue_new_child(main_loop.events);
- event_strings = pmap_new(cstr_t)();
msgpack_sbuffer_init(&out_buffer);
}
@@ -60,7 +58,6 @@ void rpc_start(Channel *channel)
RpcState *rpc = &channel->rpc;
rpc->closed = false;
rpc->unpacker = msgpack_unpacker_new(MSGPACK_UNPACKER_INIT_BUFFER_SIZE);
- rpc->subscribed_events = pmap_new(cstr_t)();
rpc->next_request_id = 1;
rpc->info = (Dictionary)ARRAY_DICT_INIT;
kv_init(rpc->call_stack);
@@ -104,7 +101,7 @@ bool rpc_send_event(uint64_t id, const char *name, Array args)
if (channel) {
send_event(channel, name, args);
- } else {
+ } else {
broadcast_event(name, args);
}
@@ -118,10 +115,7 @@ bool rpc_send_event(uint64_t id, const char *name, Array args)
/// @param args Array with method arguments
/// @param[out] error True if the return value is an error
/// @return Whatever the remote method returned
-Object rpc_send_call(uint64_t id,
- const char *method_name,
- Array args,
- Error *err)
+Object rpc_send_call(uint64_t id, const char *method_name, Array args, Error *err)
{
Channel *channel = NULL;
@@ -183,11 +177,11 @@ void rpc_subscribe(uint64_t id, char *event)
abort();
}
- char *event_string = pmap_get(cstr_t)(event_strings, event);
+ char *event_string = pmap_get(cstr_t)(&event_strings, event);
if (!event_string) {
event_string = xstrdup(event);
- pmap_put(cstr_t)(event_strings, event_string, event_string);
+ pmap_put(cstr_t)(&event_strings, event_string, event_string);
}
pmap_put(cstr_t)(channel->rpc.subscribed_events, event_string, event_string);
@@ -208,8 +202,7 @@ void rpc_unsubscribe(uint64_t id, char *event)
unsubscribe(channel, event);
}
-static void receive_msgpack(Stream *stream, RBuffer *rbuf, size_t c,
- void *data, bool eof)
+static void receive_msgpack(Stream *stream, RBuffer *rbuf, size_t c, void *data, bool eof)
{
Channel *channel = data;
channel_incref(channel);
@@ -465,10 +458,7 @@ static void send_error(Channel *chan, MessageType type, uint32_t id, char *err)
api_clear_error(&e);
}
-static void send_request(Channel *channel,
- uint32_t id,
- const char *name,
- Array args)
+static void send_request(Channel *channel, uint32_t id, const char *name, Array args)
{
const String method = cstr_as_string((char *)name);
channel_write(channel, serialize_request(channel->id,
@@ -479,9 +469,7 @@ static void send_request(Channel *channel,
1));
}
-static void send_event(Channel *channel,
- const char *name,
- Array args)
+static void send_event(Channel *channel, const char *name, Array args)
{
const String method = cstr_as_string((char *)name);
channel_write(channel, serialize_request(channel->id,
@@ -497,7 +485,7 @@ static void broadcast_event(const char *name, Array args)
kvec_t(Channel *) subscribed = KV_INITIAL_VALUE;
Channel *channel;
- map_foreach_value(channels, channel, {
+ map_foreach_value(&channels, channel, {
if (channel->is_rpc
&& pmap_has(cstr_t)(channel->rpc.subscribed_events, name)) {
kv_push(subscribed, channel);
@@ -528,15 +516,15 @@ end:
static void unsubscribe(Channel *channel, char *event)
{
- char *event_string = pmap_get(cstr_t)(event_strings, event);
+ char *event_string = pmap_get(cstr_t)(&event_strings, event);
if (!event_string) {
- WLOG("RPC: ch %" PRIu64 ": tried to unsubscribe unknown event '%s'",
- channel->id, event);
- return;
+ WLOG("RPC: ch %" PRIu64 ": tried to unsubscribe unknown event '%s'",
+ channel->id, event);
+ return;
}
pmap_del(cstr_t)(channel->rpc.subscribed_events, event_string);
- map_foreach_value(channels, channel, {
+ map_foreach_value(&channels, channel, {
if (channel->is_rpc
&& pmap_has(cstr_t)(channel->rpc.subscribed_events, event_string)) {
return;
@@ -544,7 +532,7 @@ static void unsubscribe(Channel *channel, char *event)
});
// Since the string is no longer used by other channels, release it's memory
- pmap_del(cstr_t)(event_strings, event_string);
+ pmap_del(cstr_t)(&event_strings, event_string);
xfree(event_string);
}
@@ -583,7 +571,7 @@ void rpc_free(Channel *channel)
unsubscribe(channel, event_string);
});
- pmap_free(cstr_t)(channel->rpc.subscribed_events);
+ pmap_destroy(cstr_t)(channel->rpc.subscribed_events);
kv_destroy(channel->rpc.call_stack);
api_free_dictionary(channel->rpc.info);
}
@@ -591,10 +579,10 @@ void rpc_free(Channel *channel)
static bool is_rpc_response(msgpack_object *obj)
{
return obj->type == MSGPACK_OBJECT_ARRAY
- && obj->via.array.size == 4
- && obj->via.array.ptr[0].type == MSGPACK_OBJECT_POSITIVE_INTEGER
- && obj->via.array.ptr[0].via.u64 == 1
- && obj->via.array.ptr[1].type == MSGPACK_OBJECT_POSITIVE_INTEGER;
+ && obj->via.array.size == 4
+ && obj->via.array.ptr[0].type == MSGPACK_OBJECT_POSITIVE_INTEGER
+ && obj->via.array.ptr[0].via.u64 == 1
+ && obj->via.array.ptr[1].type == MSGPACK_OBJECT_POSITIVE_INTEGER;
}
static bool is_valid_rpc_response(msgpack_object *obj, Channel *channel)
@@ -636,12 +624,8 @@ static void call_set_error(Channel *channel, char *msg, int loglevel)
channel_close(channel->id, kChannelPartRpc, NULL);
}
-static WBuffer *serialize_request(uint64_t channel_id,
- uint32_t request_id,
- const String method,
- Array args,
- msgpack_sbuffer *sbuffer,
- size_t refcount)
+static WBuffer *serialize_request(uint64_t channel_id, uint32_t request_id, const String method,
+ Array args, msgpack_sbuffer *sbuffer, size_t refcount)
{
msgpack_packer pac;
msgpack_packer_init(&pac, sbuffer, msgpack_sbuffer_write);
@@ -656,12 +640,8 @@ static WBuffer *serialize_request(uint64_t channel_id,
return rv;
}
-static WBuffer *serialize_response(uint64_t channel_id,
- MessageType type,
- uint32_t response_id,
- Error *err,
- Object arg,
- msgpack_sbuffer *sbuffer)
+static WBuffer *serialize_response(uint64_t channel_id, MessageType type, uint32_t response_id,
+ Error *err, Object arg, msgpack_sbuffer *sbuffer)
{
msgpack_packer pac;
msgpack_packer_init(&pac, sbuffer, msgpack_sbuffer_write);
@@ -719,14 +699,14 @@ const char *rpc_client_name(Channel *chan)
}
#if MIN_LOG_LEVEL <= DEBUG_LOG_LEVEL
-#define REQ "[request] "
-#define RES "[response] "
-#define NOT "[notify] "
-#define ERR "[error] "
+# define REQ "[request] "
+# define RES "[response] "
+# define NOT "[notify] "
+# define ERR "[error] "
// Cannot define array with negative offsets, so this one is needed to be added
// to MSGPACK_UNPACK_\* values.
-#define MUR_OFF 2
+# define MUR_OFF 2
static const char *const msgpack_error_messages[] = {
[MSGPACK_UNPACK_EXTRA_BYTES + MUR_OFF] = "extra bytes found",
@@ -735,47 +715,43 @@ static const char *const msgpack_error_messages[] = {
[MSGPACK_UNPACK_NOMEM_ERROR + MUR_OFF] = "not enough memory",
};
-static void log_server_msg(uint64_t channel_id,
- msgpack_sbuffer *packed)
+static void log_server_msg(uint64_t channel_id, msgpack_sbuffer *packed)
{
msgpack_unpacked unpacked;
msgpack_unpacked_init(&unpacked);
DLOGN("RPC ->ch %" PRIu64 ": ", channel_id);
const msgpack_unpack_return result =
- msgpack_unpack_next(&unpacked, packed->data, packed->size, NULL);
+ msgpack_unpack_next(&unpacked, packed->data, packed->size, NULL);
switch (result) {
- case MSGPACK_UNPACK_SUCCESS: {
- uint64_t type = unpacked.data.via.array.ptr[0].via.u64;
- log_lock();
- FILE *f = open_log_file();
- fprintf(f, type ? (type == 1 ? RES : NOT) : REQ);
- log_msg_close(f, unpacked.data);
- msgpack_unpacked_destroy(&unpacked);
- break;
- }
- case MSGPACK_UNPACK_EXTRA_BYTES:
- case MSGPACK_UNPACK_CONTINUE:
- case MSGPACK_UNPACK_PARSE_ERROR:
- case MSGPACK_UNPACK_NOMEM_ERROR: {
- log_lock();
- FILE *f = open_log_file();
- fprintf(f, ERR);
- log_msg_close(f, (msgpack_object) {
- .type = MSGPACK_OBJECT_STR,
- .via.str = {
- .ptr = (char *)msgpack_error_messages[result + MUR_OFF],
- .size = (uint32_t)strlen(
- msgpack_error_messages[result + MUR_OFF]),
- },
+ case MSGPACK_UNPACK_SUCCESS: {
+ uint64_t type = unpacked.data.via.array.ptr[0].via.u64;
+ log_lock();
+ FILE *f = open_log_file();
+ fprintf(f, type ? (type == 1 ? RES : NOT) : REQ);
+ log_msg_close(f, unpacked.data);
+ msgpack_unpacked_destroy(&unpacked);
+ break;
+ }
+ case MSGPACK_UNPACK_EXTRA_BYTES:
+ case MSGPACK_UNPACK_CONTINUE:
+ case MSGPACK_UNPACK_PARSE_ERROR:
+ case MSGPACK_UNPACK_NOMEM_ERROR: {
+ log_lock();
+ FILE *f = open_log_file();
+ fprintf(f, ERR);
+ log_msg_close(f, (msgpack_object) {
+ .type = MSGPACK_OBJECT_STR,
+ .via.str = {
+ .ptr = (char *)msgpack_error_messages[result + MUR_OFF],
+ .size = (uint32_t)strlen(msgpack_error_messages[result + MUR_OFF]),
+ },
});
- break;
- }
+ break;
+ }
}
}
-static void log_client_msg(uint64_t channel_id,
- bool is_request,
- msgpack_object msg)
+static void log_client_msg(uint64_t channel_id, bool is_request, msgpack_object msg)
{
DLOGN("RPC <-ch %" PRIu64 ": ", channel_id);
log_lock();
diff --git a/src/nvim/msgpack_rpc/channel_defs.h b/src/nvim/msgpack_rpc/channel_defs.h
index 6ef8c027f0..de328af1ce 100644
--- a/src/nvim/msgpack_rpc/channel_defs.h
+++ b/src/nvim/msgpack_rpc/channel_defs.h
@@ -27,7 +27,7 @@ typedef struct {
} RequestEvent;
typedef struct {
- PMap(cstr_t) *subscribed_events;
+ PMap(cstr_t) subscribed_events[1];
bool closed;
msgpack_unpacker *unpacker;
uint32_t next_request_id;
diff --git a/src/nvim/msgpack_rpc/helpers.c b/src/nvim/msgpack_rpc/helpers.c
index a4a36e5ebf..b1b9c77953 100644
--- a/src/nvim/msgpack_rpc/helpers.c
+++ b/src/nvim/msgpack_rpc/helpers.c
@@ -1,19 +1,18 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
-#include <stdbool.h>
#include <inttypes.h>
-
#include <msgpack.h>
+#include <stdbool.h>
#include "nvim/api/private/dispatch.h"
#include "nvim/api/private/helpers.h"
-#include "nvim/msgpack_rpc/helpers.h"
+#include "nvim/assert.h"
#include "nvim/lib/kvec.h"
-#include "nvim/vim.h"
#include "nvim/log.h"
#include "nvim/memory.h"
-#include "nvim/assert.h"
+#include "nvim/msgpack_rpc/helpers.h"
+#include "nvim/vim.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "msgpack_rpc/helpers.c.generated.h"
@@ -86,8 +85,9 @@ bool msgpack_rpc_to_object(const msgpack_object *const obj, Object *const arg)
FUNC_ATTR_NONNULL_ALL
{
bool ret = true;
- kvec_t(MPToAPIObjectStackItem) stack = KV_INITIAL_VALUE;
- kv_push(stack, ((MPToAPIObjectStackItem) {
+ kvec_withinit_t(MPToAPIObjectStackItem, 2) stack = KV_INITIAL_VALUE;
+ kvi_init(stack);
+ kvi_push(stack, ((MPToAPIObjectStackItem) {
.mobj = obj,
.aobj = arg,
.container = false,
@@ -99,178 +99,167 @@ bool msgpack_rpc_to_object(const msgpack_object *const obj, Object *const arg)
*cur.aobj = NIL;
}
switch (cur.mobj->type) {
- case MSGPACK_OBJECT_NIL: {
- break;
- }
- case MSGPACK_OBJECT_BOOLEAN: {
- *cur.aobj = BOOLEAN_OBJ(cur.mobj->via.boolean);
- break;
- }
- case MSGPACK_OBJECT_NEGATIVE_INTEGER: {
- STATIC_ASSERT(sizeof(Integer) == sizeof(cur.mobj->via.i64),
- "Msgpack integer size does not match API integer");
- *cur.aobj = INTEGER_OBJ(cur.mobj->via.i64);
- break;
- }
- case MSGPACK_OBJECT_POSITIVE_INTEGER: {
- STATIC_ASSERT(sizeof(Integer) == sizeof(cur.mobj->via.u64),
- "Msgpack integer size does not match API integer");
- if (cur.mobj->via.u64 > API_INTEGER_MAX) {
- ret = false;
- } else {
- *cur.aobj = INTEGER_OBJ((Integer)cur.mobj->via.u64);
- }
- break;
+ case MSGPACK_OBJECT_NIL:
+ break;
+ case MSGPACK_OBJECT_BOOLEAN:
+ *cur.aobj = BOOLEAN_OBJ(cur.mobj->via.boolean);
+ break;
+ case MSGPACK_OBJECT_NEGATIVE_INTEGER:
+ STATIC_ASSERT(sizeof(Integer) == sizeof(cur.mobj->via.i64),
+ "Msgpack integer size does not match API integer");
+ *cur.aobj = INTEGER_OBJ(cur.mobj->via.i64);
+ break;
+ case MSGPACK_OBJECT_POSITIVE_INTEGER:
+ STATIC_ASSERT(sizeof(Integer) == sizeof(cur.mobj->via.u64),
+ "Msgpack integer size does not match API integer");
+ if (cur.mobj->via.u64 > API_INTEGER_MAX) {
+ ret = false;
+ } else {
+ *cur.aobj = INTEGER_OBJ((Integer)cur.mobj->via.u64);
}
+ break;
#ifdef NVIM_MSGPACK_HAS_FLOAT32
- case MSGPACK_OBJECT_FLOAT32:
- case MSGPACK_OBJECT_FLOAT64:
+ case MSGPACK_OBJECT_FLOAT32:
+ case MSGPACK_OBJECT_FLOAT64:
#else
- case MSGPACK_OBJECT_FLOAT:
+ case MSGPACK_OBJECT_FLOAT:
#endif
- {
- STATIC_ASSERT(sizeof(Float) == sizeof(cur.mobj->via.f64),
- "Msgpack floating-point size does not match API integer");
- *cur.aobj = FLOAT_OBJ(cur.mobj->via.f64);
- break;
- }
+ {
+ STATIC_ASSERT(sizeof(Float) == sizeof(cur.mobj->via.f64),
+ "Msgpack floating-point size does not match API integer");
+ *cur.aobj = FLOAT_OBJ(cur.mobj->via.f64);
+ break;
+ }
#define STR_CASE(type, attr, obj, dest, conv) \
- case type: { \
- dest = conv(((String) { \
- .size = obj->via.attr.size, \
- .data = (obj->via.attr.ptr == NULL || obj->via.attr.size == 0 \
+case type: { \
+ dest = conv(((String) { \
+ .size = obj->via.attr.size, \
+ .data = (obj->via.attr.ptr == NULL || obj->via.attr.size == 0 \
? xmemdupz("", 0) \
: xmemdupz(obj->via.attr.ptr, obj->via.attr.size)), \
- })); \
- break; \
- }
+ })); \
+ break; \
+}
STR_CASE(MSGPACK_OBJECT_STR, str, cur.mobj, *cur.aobj, STRING_OBJ)
STR_CASE(MSGPACK_OBJECT_BIN, bin, cur.mobj, *cur.aobj, STRING_OBJ)
- case MSGPACK_OBJECT_ARRAY: {
- const size_t size = cur.mobj->via.array.size;
- if (cur.container) {
- if (cur.idx >= size) {
- (void)kv_pop(stack);
- } else {
- const size_t idx = cur.idx;
- cur.idx++;
- kv_last(stack) = cur;
- kv_push(stack, ((MPToAPIObjectStackItem) {
+ case MSGPACK_OBJECT_ARRAY: {
+ const size_t size = cur.mobj->via.array.size;
+ if (cur.container) {
+ if (cur.idx >= size) {
+ (void)kv_pop(stack);
+ } else {
+ const size_t idx = cur.idx;
+ cur.idx++;
+ kv_last(stack) = cur;
+ kvi_push(stack, ((MPToAPIObjectStackItem) {
.mobj = &cur.mobj->via.array.ptr[idx],
.aobj = &cur.aobj->data.array.items[idx],
.container = false,
}));
- }
- } else {
- *cur.aobj = ARRAY_OBJ(((Array) {
+ }
+ } else {
+ *cur.aobj = ARRAY_OBJ(((Array) {
.size = size,
.capacity = size,
.items = (size > 0
? xcalloc(size, sizeof(*cur.aobj->data.array.items))
: NULL),
}));
- cur.container = true;
- kv_last(stack) = cur;
- }
- break;
+ cur.container = true;
+ kv_last(stack) = cur;
}
- case MSGPACK_OBJECT_MAP: {
- const size_t size = cur.mobj->via.map.size;
- if (cur.container) {
- if (cur.idx >= size) {
- (void)kv_pop(stack);
- } else {
- const size_t idx = cur.idx;
- cur.idx++;
- kv_last(stack) = cur;
- const msgpack_object *const key = &cur.mobj->via.map.ptr[idx].key;
- switch (key->type) {
+ break;
+ }
+ case MSGPACK_OBJECT_MAP: {
+ const size_t size = cur.mobj->via.map.size;
+ if (cur.container) {
+ if (cur.idx >= size) {
+ (void)kv_pop(stack);
+ } else {
+ const size_t idx = cur.idx;
+ cur.idx++;
+ kv_last(stack) = cur;
+ const msgpack_object *const key = &cur.mobj->via.map.ptr[idx].key;
+ switch (key->type) {
#define ID(x) x
- STR_CASE(MSGPACK_OBJECT_STR, str, key,
- cur.aobj->data.dictionary.items[idx].key, ID)
- STR_CASE(MSGPACK_OBJECT_BIN, bin, key,
- cur.aobj->data.dictionary.items[idx].key, ID)
+ STR_CASE(MSGPACK_OBJECT_STR, str, key,
+ cur.aobj->data.dictionary.items[idx].key, ID)
+ STR_CASE(MSGPACK_OBJECT_BIN, bin, key,
+ cur.aobj->data.dictionary.items[idx].key, ID)
#undef ID
- case MSGPACK_OBJECT_NIL:
- case MSGPACK_OBJECT_BOOLEAN:
- case MSGPACK_OBJECT_POSITIVE_INTEGER:
- case MSGPACK_OBJECT_NEGATIVE_INTEGER:
+ case MSGPACK_OBJECT_NIL:
+ case MSGPACK_OBJECT_BOOLEAN:
+ case MSGPACK_OBJECT_POSITIVE_INTEGER:
+ case MSGPACK_OBJECT_NEGATIVE_INTEGER:
#ifdef NVIM_MSGPACK_HAS_FLOAT32
- case MSGPACK_OBJECT_FLOAT32:
- case MSGPACK_OBJECT_FLOAT64:
+ case MSGPACK_OBJECT_FLOAT32:
+ case MSGPACK_OBJECT_FLOAT64:
#else
- case MSGPACK_OBJECT_FLOAT:
+ case MSGPACK_OBJECT_FLOAT:
#endif
- case MSGPACK_OBJECT_EXT:
- case MSGPACK_OBJECT_MAP:
- case MSGPACK_OBJECT_ARRAY: {
- ret = false;
- break;
- }
- }
- if (ret) {
- kv_push(stack, ((MPToAPIObjectStackItem) {
+ case MSGPACK_OBJECT_EXT:
+ case MSGPACK_OBJECT_MAP:
+ case MSGPACK_OBJECT_ARRAY:
+ ret = false;
+ break;
+ }
+ if (ret) {
+ kvi_push(stack, ((MPToAPIObjectStackItem) {
.mobj = &cur.mobj->via.map.ptr[idx].val,
.aobj = &cur.aobj->data.dictionary.items[idx].value,
.container = false,
}));
- }
}
- } else {
- *cur.aobj = DICTIONARY_OBJ(((Dictionary) {
+ }
+ } else {
+ *cur.aobj = DICTIONARY_OBJ(((Dictionary) {
.size = size,
.capacity = size,
.items = (size > 0
? xcalloc(size, sizeof(*cur.aobj->data.dictionary.items))
: NULL),
}));
- cur.container = true;
- kv_last(stack) = cur;
- }
- break;
+ cur.container = true;
+ kv_last(stack) = cur;
}
- case MSGPACK_OBJECT_EXT: {
- switch ((ObjectType)(cur.mobj->via.ext.type + EXT_OBJECT_TYPE_SHIFT)) {
- case kObjectTypeBuffer: {
- cur.aobj->type = kObjectTypeBuffer;
- ret = msgpack_rpc_to_buffer(cur.mobj, &cur.aobj->data.integer);
- break;
- }
- case kObjectTypeWindow: {
- cur.aobj->type = kObjectTypeWindow;
- ret = msgpack_rpc_to_window(cur.mobj, &cur.aobj->data.integer);
- break;
- }
- case kObjectTypeTabpage: {
- cur.aobj->type = kObjectTypeTabpage;
- ret = msgpack_rpc_to_tabpage(cur.mobj, &cur.aobj->data.integer);
- break;
- }
- case kObjectTypeNil:
- case kObjectTypeBoolean:
- case kObjectTypeInteger:
- case kObjectTypeFloat:
- case kObjectTypeString:
- case kObjectTypeArray:
- case kObjectTypeDictionary:
- case kObjectTypeLuaRef: {
- break;
- }
- }
+ break;
+ }
+ case MSGPACK_OBJECT_EXT:
+ switch ((ObjectType)(cur.mobj->via.ext.type + EXT_OBJECT_TYPE_SHIFT)) {
+ case kObjectTypeBuffer:
+ cur.aobj->type = kObjectTypeBuffer;
+ ret = msgpack_rpc_to_buffer(cur.mobj, &cur.aobj->data.integer);
+ break;
+ case kObjectTypeWindow:
+ cur.aobj->type = kObjectTypeWindow;
+ ret = msgpack_rpc_to_window(cur.mobj, &cur.aobj->data.integer);
+ break;
+ case kObjectTypeTabpage:
+ cur.aobj->type = kObjectTypeTabpage;
+ ret = msgpack_rpc_to_tabpage(cur.mobj, &cur.aobj->data.integer);
+ break;
+ case kObjectTypeNil:
+ case kObjectTypeBoolean:
+ case kObjectTypeInteger:
+ case kObjectTypeFloat:
+ case kObjectTypeString:
+ case kObjectTypeArray:
+ case kObjectTypeDictionary:
+ case kObjectTypeLuaRef:
break;
}
+ break;
#undef STR_CASE
}
if (!cur.container) {
(void)kv_pop(stack);
}
}
- kv_destroy(stack);
+ kvi_destroy(stack);
return ret;
}
-static bool msgpack_rpc_to_string(const msgpack_object *const obj,
- String *const arg)
+static bool msgpack_rpc_to_string(const msgpack_object *const obj, String *const arg)
FUNC_ATTR_NONNULL_ALL
{
if (obj->type == MSGPACK_OBJECT_BIN || obj->type == MSGPACK_OBJECT_STR) {
@@ -302,8 +291,7 @@ bool msgpack_rpc_to_array(const msgpack_object *const obj, Array *const arg)
return true;
}
-bool msgpack_rpc_to_dictionary(const msgpack_object *const obj,
- Dictionary *const arg)
+bool msgpack_rpc_to_dictionary(const msgpack_object *const obj, Dictionary *const arg)
FUNC_ATTR_NONNULL_ALL
{
if (obj->type != MSGPACK_OBJECT_MAP) {
@@ -316,12 +304,12 @@ bool msgpack_rpc_to_dictionary(const msgpack_object *const obj,
for (uint32_t i = 0; i < obj->via.map.size; i++) {
if (!msgpack_rpc_to_string(&obj->via.map.ptr[i].key,
- &arg->items[i].key)) {
+ &arg->items[i].key)) {
return false;
}
if (!msgpack_rpc_to_object(&obj->via.map.ptr[i].val,
- &arg->items[i].value)) {
+ &arg->items[i].value)) {
return false;
}
}
@@ -375,100 +363,93 @@ typedef struct {
void msgpack_rpc_from_object(const Object result, msgpack_packer *const res)
FUNC_ATTR_NONNULL_ARG(2)
{
- kvec_t(APIToMPObjectStackItem) stack = KV_INITIAL_VALUE;
- kv_push(stack, ((APIToMPObjectStackItem) { &result, false, 0 }));
+ kvec_withinit_t(APIToMPObjectStackItem, 2) stack = KV_INITIAL_VALUE;
+ kvi_init(stack);
+ kvi_push(stack, ((APIToMPObjectStackItem) { &result, false, 0 }));
while (kv_size(stack)) {
APIToMPObjectStackItem cur = kv_last(stack);
STATIC_ASSERT(kObjectTypeWindow == kObjectTypeBuffer + 1
&& kObjectTypeTabpage == kObjectTypeWindow + 1,
"Buffer, window and tabpage enum items are in order");
switch (cur.aobj->type) {
- case kObjectTypeNil:
- case kObjectTypeLuaRef: {
- // TODO(bfredl): could also be an error. Though kObjectTypeLuaRef
- // should only appear when the caller has opted in to handle references,
- // see nlua_pop_Object.
- msgpack_pack_nil(res);
- break;
- }
- case kObjectTypeBoolean: {
- msgpack_rpc_from_boolean(cur.aobj->data.boolean, res);
- break;
- }
- case kObjectTypeInteger: {
- msgpack_rpc_from_integer(cur.aobj->data.integer, res);
- break;
- }
- case kObjectTypeFloat: {
- msgpack_rpc_from_float(cur.aobj->data.floating, res);
- break;
- }
- case kObjectTypeString: {
- msgpack_rpc_from_string(cur.aobj->data.string, res);
- break;
- }
- case kObjectTypeBuffer: {
- msgpack_rpc_from_buffer(cur.aobj->data.integer, res);
- break;
- }
- case kObjectTypeWindow: {
- msgpack_rpc_from_window(cur.aobj->data.integer, res);
- break;
- }
- case kObjectTypeTabpage: {
- msgpack_rpc_from_tabpage(cur.aobj->data.integer, res);
- break;
- }
- case kObjectTypeArray: {
- const size_t size = cur.aobj->data.array.size;
- if (cur.container) {
- if (cur.idx >= size) {
- (void)kv_pop(stack);
- } else {
- const size_t idx = cur.idx;
- cur.idx++;
- kv_last(stack) = cur;
- kv_push(stack, ((APIToMPObjectStackItem) {
+ case kObjectTypeNil:
+ case kObjectTypeLuaRef:
+ // TODO(bfredl): could also be an error. Though kObjectTypeLuaRef
+ // should only appear when the caller has opted in to handle references,
+ // see nlua_pop_Object.
+ msgpack_pack_nil(res);
+ break;
+ case kObjectTypeBoolean:
+ msgpack_rpc_from_boolean(cur.aobj->data.boolean, res);
+ break;
+ case kObjectTypeInteger:
+ msgpack_rpc_from_integer(cur.aobj->data.integer, res);
+ break;
+ case kObjectTypeFloat:
+ msgpack_rpc_from_float(cur.aobj->data.floating, res);
+ break;
+ case kObjectTypeString:
+ msgpack_rpc_from_string(cur.aobj->data.string, res);
+ break;
+ case kObjectTypeBuffer:
+ msgpack_rpc_from_buffer(cur.aobj->data.integer, res);
+ break;
+ case kObjectTypeWindow:
+ msgpack_rpc_from_window(cur.aobj->data.integer, res);
+ break;
+ case kObjectTypeTabpage:
+ msgpack_rpc_from_tabpage(cur.aobj->data.integer, res);
+ break;
+ case kObjectTypeArray: {
+ const size_t size = cur.aobj->data.array.size;
+ if (cur.container) {
+ if (cur.idx >= size) {
+ (void)kv_pop(stack);
+ } else {
+ const size_t idx = cur.idx;
+ cur.idx++;
+ kv_last(stack) = cur;
+ kvi_push(stack, ((APIToMPObjectStackItem) {
.aobj = &cur.aobj->data.array.items[idx],
.container = false,
}));
- }
- } else {
- msgpack_pack_array(res, size);
- cur.container = true;
- kv_last(stack) = cur;
}
- break;
+ } else {
+ msgpack_pack_array(res, size);
+ cur.container = true;
+ kv_last(stack) = cur;
}
- case kObjectTypeDictionary: {
- const size_t size = cur.aobj->data.dictionary.size;
- if (cur.container) {
- if (cur.idx >= size) {
- (void)kv_pop(stack);
- } else {
- const size_t idx = cur.idx;
- cur.idx++;
- kv_last(stack) = cur;
- msgpack_rpc_from_string(cur.aobj->data.dictionary.items[idx].key,
- res);
- kv_push(stack, ((APIToMPObjectStackItem) {
+ break;
+ }
+ case kObjectTypeDictionary: {
+ const size_t size = cur.aobj->data.dictionary.size;
+ if (cur.container) {
+ if (cur.idx >= size) {
+ (void)kv_pop(stack);
+ } else {
+ const size_t idx = cur.idx;
+ cur.idx++;
+ kv_last(stack) = cur;
+ msgpack_rpc_from_string(cur.aobj->data.dictionary.items[idx].key,
+ res);
+ kvi_push(stack, ((APIToMPObjectStackItem) {
.aobj = &cur.aobj->data.dictionary.items[idx].value,
.container = false,
}));
- }
- } else {
- msgpack_pack_map(res, size);
- cur.container = true;
- kv_last(stack) = cur;
}
- break;
+ } else {
+ msgpack_pack_map(res, size);
+ cur.container = true;
+ kv_last(stack) = cur;
}
+ break;
+ }
}
if (!cur.container) {
(void)kv_pop(stack);
}
}
- kv_destroy(stack);
+ kvi_destroy(stack);
}
void msgpack_rpc_from_array(Array result, msgpack_packer *res)
@@ -493,9 +474,7 @@ void msgpack_rpc_from_dictionary(Dictionary result, msgpack_packer *res)
}
/// Serializes a msgpack-rpc request or notification(id == 0)
-void msgpack_rpc_serialize_request(uint32_t request_id,
- const String method,
- Array args,
+void msgpack_rpc_serialize_request(uint32_t request_id, const String method, Array args,
msgpack_packer *pac)
FUNC_ATTR_NONNULL_ARG(4)
{
@@ -511,9 +490,7 @@ void msgpack_rpc_serialize_request(uint32_t request_id,
}
/// Serializes a msgpack-rpc response
-void msgpack_rpc_serialize_response(uint32_t response_id,
- Error *err,
- Object arg,
+void msgpack_rpc_serialize_response(uint32_t response_id, Error *err, Object arg,
msgpack_packer *pac)
FUNC_ATTR_NONNULL_ARG(2, 4)
{
@@ -544,15 +521,15 @@ static bool msgpack_rpc_is_notification(msgpack_object *req)
msgpack_object *msgpack_rpc_method(msgpack_object *req)
{
msgpack_object *obj = req->via.array.ptr
- + (msgpack_rpc_is_notification(req) ? 1 : 2);
+ + (msgpack_rpc_is_notification(req) ? 1 : 2);
return obj->type == MSGPACK_OBJECT_STR || obj->type == MSGPACK_OBJECT_BIN ?
- obj : NULL;
+ obj : NULL;
}
msgpack_object *msgpack_rpc_args(msgpack_object *req)
{
msgpack_object *obj = req->via.array.ptr
- + (msgpack_rpc_is_notification(req) ? 2 : 3);
+ + (msgpack_rpc_is_notification(req) ? 2 : 3);
return obj->type == MSGPACK_OBJECT_ARRAY ? obj : NULL;
}
@@ -565,8 +542,7 @@ static msgpack_object *msgpack_rpc_msg_id(msgpack_object *req)
return obj->type == MSGPACK_OBJECT_POSITIVE_INTEGER ? obj : NULL;
}
-MessageType msgpack_rpc_validate(uint32_t *response_id, msgpack_object *req,
- Error *err)
+MessageType msgpack_rpc_validate(uint32_t *response_id, msgpack_object *req, Error *err)
{
*response_id = 0;
// Validate the basic structure of the msgpack-rpc payload
diff --git a/src/nvim/msgpack_rpc/server.c b/src/nvim/msgpack_rpc/server.c
index 062ea784ca..e954e4b3a3 100644
--- a/src/nvim/msgpack_rpc/server.c
+++ b/src/nvim/msgpack_rpc/server.c
@@ -2,24 +2,24 @@
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
#include <assert.h>
+#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
-#include <inttypes.h>
-#include "nvim/msgpack_rpc/channel.h"
-#include "nvim/msgpack_rpc/server.h"
-#include "nvim/os/os.h"
-#include "nvim/event/socket.h"
#include "nvim/ascii.h"
#include "nvim/eval.h"
+#include "nvim/event/socket.h"
+#include "nvim/fileio.h"
#include "nvim/garray.h"
-#include "nvim/vim.h"
+#include "nvim/log.h"
#include "nvim/main.h"
#include "nvim/memory.h"
-#include "nvim/log.h"
-#include "nvim/fileio.h"
+#include "nvim/msgpack_rpc/channel.h"
+#include "nvim/msgpack_rpc/server.h"
+#include "nvim/os/os.h"
#include "nvim/path.h"
#include "nvim/strings.h"
+#include "nvim/vim.h"
#define MAX_CONNECTIONS 32
#define LISTEN_ADDRESS_ENV_VAR "NVIM_LISTEN_ADDRESS"
@@ -90,7 +90,7 @@ char *server_address_new(void)
static uint32_t count = 0;
char template[ADDRESS_MAX_SIZE];
snprintf(template, ADDRESS_MAX_SIZE,
- "\\\\.\\pipe\\nvim-%" PRIu64 "-%" PRIu32, os_get_pid(), count++);
+ "\\\\.\\pipe\\nvim-%" PRIu64 "-%" PRIu32, os_get_pid(), count++);
return xstrdup(template);
#else
return (char *)vim_tempname();
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index 44cdc09c0b..493c704f42 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -9,14 +9,12 @@
#include <assert.h>
#include <inttypes.h>
-#include <string.h>
#include <stdbool.h>
#include <stdlib.h>
+#include <string.h>
-#include "nvim/log.h"
-#include "nvim/vim.h"
+#include "nvim/api/private/helpers.h"
#include "nvim/ascii.h"
-#include "nvim/normal.h"
#include "nvim/buffer.h"
#include "nvim/change.h"
#include "nvim/charset.h"
@@ -25,6 +23,7 @@
#include "nvim/digraph.h"
#include "nvim/edit.h"
#include "nvim/eval/userfunc.h"
+#include "nvim/event/loop.h"
#include "nvim/ex_cmds.h"
#include "nvim/ex_cmds2.h"
#include "nvim/ex_docmd.h"
@@ -34,34 +33,35 @@
#include "nvim/getchar.h"
#include "nvim/indent.h"
#include "nvim/indent_c.h"
+#include "nvim/keymap.h"
+#include "nvim/log.h"
#include "nvim/main.h"
#include "nvim/mark.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/keymap.h"
-#include "nvim/move.h"
#include "nvim/mouse.h"
+#include "nvim/move.h"
+#include "nvim/normal.h"
#include "nvim/ops.h"
#include "nvim/option.h"
+#include "nvim/os/input.h"
+#include "nvim/os/time.h"
+#include "nvim/plines.h"
#include "nvim/quickfix.h"
#include "nvim/screen.h"
#include "nvim/search.h"
#include "nvim/spell.h"
#include "nvim/spellfile.h"
+#include "nvim/state.h"
#include "nvim/strings.h"
#include "nvim/syntax.h"
#include "nvim/tag.h"
#include "nvim/ui.h"
-#include "nvim/mouse.h"
#include "nvim/undo.h"
+#include "nvim/vim.h"
#include "nvim/window.h"
-#include "nvim/state.h"
-#include "nvim/event/loop.h"
-#include "nvim/os/time.h"
-#include "nvim/os/input.h"
-#include "nvim/api/private/helpers.h"
typedef struct normal_state {
VimState state;
@@ -87,12 +87,10 @@ typedef struct normal_state {
/*
* The Visual area is remembered for reselection.
*/
-static int resel_VIsual_mode = NUL; /* 'v', 'V', or Ctrl-V */
-static linenr_T resel_VIsual_line_count; /* number of lines */
-static colnr_T resel_VIsual_vcol; /* nr of cols or end col */
-static int VIsual_mode_orig = NUL; /* saved Visual mode */
-
-static int restart_VIsual_select = 0;
+static int resel_VIsual_mode = NUL; // 'v', 'V', or Ctrl-V
+static linenr_T resel_VIsual_line_count; // number of lines
+static colnr_T resel_VIsual_vcol; // nr of cols or end col
+static int VIsual_mode_orig = NUL; // saved Visual mode
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -120,18 +118,18 @@ static char *e_noident = N_("E349: No identifier under cursor");
*/
typedef void (*nv_func_T)(cmdarg_T *cap);
-/* Values for cmd_flags. */
-#define NV_NCH 0x01 /* may need to get a second char */
-#define NV_NCH_NOP (0x02|NV_NCH) /* get second char when no operator pending */
-#define NV_NCH_ALW (0x04|NV_NCH) /* always get a second char */
-#define NV_LANG 0x08 /* second char needs language adjustment */
+// Values for cmd_flags.
+#define NV_NCH 0x01 // may need to get a second char
+#define NV_NCH_NOP (0x02|NV_NCH) // get second char when no operator pending
+#define NV_NCH_ALW (0x04|NV_NCH) // always get a second char
+#define NV_LANG 0x08 // second char needs language adjustment
-#define NV_SS 0x10 /* may start selection */
-#define NV_SSS 0x20 /* may start selection with shift modifier */
-#define NV_STS 0x40 /* may stop selection without shift modif. */
-#define NV_RL 0x80 /* 'rightleft' modifies command */
-#define NV_KEEPREG 0x100 /* don't clear regname */
-#define NV_NCW 0x200 /* not allowed in command-line window */
+#define NV_SS 0x10 // may start selection
+#define NV_SSS 0x20 // may start selection with shift modifier
+#define NV_STS 0x40 // may stop selection without shift modif.
+#define NV_RL 0x80 // 'rightleft' modifies command
+#define NV_KEEPREG 0x100 // don't clear regname
+#define NV_NCW 0x200 // not allowed in command-line window
/*
* Generally speaking, every Normal mode command should either clear any
@@ -149,10 +147,10 @@ typedef void (*nv_func_T)(cmdarg_T *cap);
* It is faster when all keys from zero to '~' are present.
*/
static const struct nv_cmd {
- int cmd_char; /* (first) command character */
- nv_func_T cmd_func; /* function for this command */
- uint16_t cmd_flags; /* NV_ flags */
- short cmd_arg; /* value for ca.arg */
+ int cmd_char; // (first) command character
+ nv_func_T cmd_func; // function for this command
+ uint16_t cmd_flags; // NV_ flags
+ short cmd_arg; // value for ca.arg
} nv_cmds[] =
{
{ NUL, nv_error, 0, 0 },
@@ -345,10 +343,10 @@ static const struct nv_cmd {
{ K_COMMAND, nv_colon, 0, 0 },
};
-/* Number of commands in nv_cmds[]. */
+// Number of commands in nv_cmds[].
#define NV_CMDS_SIZE ARRAY_SIZE(nv_cmds)
-/* Sorted index of commands in nv_cmds[]. */
+// Sorted index of commands in nv_cmds[].
static short nv_cmd_idx[NV_CMDS_SIZE];
/* The highest index for which
@@ -363,13 +361,15 @@ static int nv_compare(const void *s1, const void *s2)
{
int c1, c2;
- /* The commands are sorted on absolute value. */
+ // The commands are sorted on absolute value.
c1 = nv_cmds[*(const short *)s1].cmd_char;
c2 = nv_cmds[*(const short *)s2].cmd_char;
- if (c1 < 0)
+ if (c1 < 0) {
c1 = -c1;
- if (c2 < 0)
+ }
+ if (c2 < 0) {
c2 = -c2;
+ }
return c1 - c2;
}
@@ -380,15 +380,15 @@ void init_normal_cmds(void)
{
assert(NV_CMDS_SIZE <= SHRT_MAX);
- /* Fill the index table with a one to one relation. */
+ // Fill the index table with a one to one relation.
for (short int i = 0; i < (short int)NV_CMDS_SIZE; ++i) {
nv_cmd_idx[i] = i;
}
- /* Sort the commands by the command character. */
+ // Sort the commands by the command character.
qsort(&nv_cmd_idx, NV_CMDS_SIZE, sizeof(short), nv_compare);
- /* Find the first entry that can't be indexed by the command character. */
+ // Find the first entry that can't be indexed by the command character.
short int i;
for (i = 0; i < (short int)NV_CMDS_SIZE; ++i) {
if (i != nv_cmds[nv_cmd_idx[i]].cmd_char) {
@@ -409,38 +409,43 @@ static int find_command(int cmdchar)
int top, bot;
int c;
- /* A multi-byte character is never a command. */
- if (cmdchar >= 0x100)
+ // A multi-byte character is never a command.
+ if (cmdchar >= 0x100) {
return -1;
+ }
/* We use the absolute value of the character. Special keys have a
* negative value, but are sorted on their absolute value. */
- if (cmdchar < 0)
+ if (cmdchar < 0) {
cmdchar = -cmdchar;
+ }
/* If the character is in the first part: The character is the index into
* nv_cmd_idx[]. */
assert(nv_max_linear < (int)NV_CMDS_SIZE);
- if (cmdchar <= nv_max_linear)
+ if (cmdchar <= nv_max_linear) {
return nv_cmd_idx[cmdchar];
+ }
- /* Perform a binary search. */
+ // Perform a binary search.
bot = nv_max_linear + 1;
top = NV_CMDS_SIZE - 1;
idx = -1;
while (bot <= top) {
i = (top + bot) / 2;
c = nv_cmds[nv_cmd_idx[i]].cmd_char;
- if (c < 0)
+ if (c < 0) {
c = -c;
+ }
if (cmdchar == c) {
idx = nv_cmd_idx[i];
break;
}
- if (cmdchar > c)
+ if (cmdchar > c) {
bot = i + 1;
- else
+ } else {
top = i - 1;
+ }
}
return idx;
}
@@ -545,59 +550,60 @@ static bool normal_need_additional_char(NormalState *s)
int cmdchar = s->ca.cmdchar;
// without NV_NCH we never need to check for an additional char
return flags & NV_NCH && (
- // NV_NCH_NOP is set and no operator is pending, get a second char
- ((flags & NV_NCH_NOP) == NV_NCH_NOP && !pending_op)
- // NV_NCH_ALW is set, always get a second char
- || (flags & NV_NCH_ALW) == NV_NCH_ALW
- // 'q' without a pending operator, recording or executing a register,
- // needs to be followed by a second char, examples:
- // - qc => record using register c
- // - q: => open command-line window
- || (cmdchar == 'q'
- && !pending_op
- && reg_recording == 0
- && reg_executing == 0)
- // 'a' or 'i' after an operator is a text object, examples:
- // - ciw => change inside word
- // - da( => delete parenthesis and everything inside.
- // Also, don't do anything when these keys are received in visual mode
- // so just get another char.
- //
- // TODO(tarruda): Visual state needs to be refactored into a
- // separate state that "inherits" from normal state.
- || ((cmdchar == 'a' || cmdchar == 'i') && (pending_op || VIsual_active)));
+ // NV_NCH_NOP is set and no operator is pending, get a second char
+ ((flags & NV_NCH_NOP) == NV_NCH_NOP && !pending_op)
+ // NV_NCH_ALW is set, always get a second char
+ || (flags & NV_NCH_ALW) == NV_NCH_ALW
+ // 'q' without a pending operator, recording or executing a register,
+ // needs to be followed by a second char, examples:
+ // - qc => record using register c
+ // - q: => open command-line window
+ || (cmdchar == 'q'
+ && !pending_op
+ && reg_recording == 0
+ && reg_executing == 0)
+ // 'a' or 'i' after an operator is a text object, examples:
+ // - ciw => change inside word
+ // - da( => delete parenthesis and everything inside.
+ // Also, don't do anything when these keys are received in visual mode
+ // so just get another char.
+ //
+ // TODO(tarruda): Visual state needs to be refactored into a
+ // separate state that "inherits" from normal state.
+ || ((cmdchar == 'a' || cmdchar == 'i') &&
+ (pending_op || VIsual_active)));
}
static bool normal_need_redraw_mode_message(NormalState *s)
{
return (
- // 'showmode' is set and messages can be printed
- ((p_smd && msg_silent == 0
- // must restart insert mode(ctrl+o or ctrl+l) or we just entered visual
- // mode
- && (restart_edit != 0 || (VIsual_active
- && s->old_pos.lnum == curwin->w_cursor.lnum
- && s->old_pos.col == curwin->w_cursor.col))
- // command-line must be cleared or redrawn
- && (clear_cmdline || redraw_cmdline)
- // some message was printed or scrolled
- && (msg_didout || (msg_didany && msg_scroll))
- // it is fine to remove the current message
- && !msg_nowait
- // the command was the result of direct user input and not a mapping
- && KeyTyped)
- // must restart insert mode, not in visual mode and error message is
- // being shown
- || (restart_edit != 0 && !VIsual_active && msg_scroll
- && emsg_on_display))
- // no register was used
- && s->oa.regname == 0
- && !(s->ca.retval & CA_COMMAND_BUSY)
- && stuff_empty()
- && typebuf_typed()
- && emsg_silent == 0
- && !did_wait_return
- && s->oa.op_type == OP_NOP);
+ // 'showmode' is set and messages can be printed
+ ((p_smd && msg_silent == 0
+ // must restart insert mode(ctrl+o or ctrl+l) or we just entered visual
+ // mode
+ && (restart_edit != 0 || (VIsual_active
+ && s->old_pos.lnum == curwin->w_cursor.lnum
+ && s->old_pos.col == curwin->w_cursor.col))
+ // command-line must be cleared or redrawn
+ && (clear_cmdline || redraw_cmdline)
+ // some message was printed or scrolled
+ && (msg_didout || (msg_didany && msg_scroll))
+ // it is fine to remove the current message
+ && !msg_nowait
+ // the command was the result of direct user input and not a mapping
+ && KeyTyped)
+ // must restart insert mode, not in visual mode and error message is
+ // being shown
+ || (restart_edit != 0 && !VIsual_active && msg_scroll
+ && emsg_on_display))
+ // no register was used
+ && s->oa.regname == 0
+ && !(s->ca.retval & CA_COMMAND_BUSY)
+ && stuff_empty()
+ && typebuf_typed()
+ && emsg_silent == 0
+ && !did_wait_return
+ && s->oa.op_type == OP_NOP);
}
static void normal_redraw_mode_message(NormalState *s)
@@ -612,7 +618,7 @@ static void normal_redraw_mode_message(NormalState *s)
// If need to redraw, and there is a "keep_msg", redraw before the
// delay
if (must_redraw && keep_msg != NULL && !emsg_on_display) {
- char_u *kmsg;
+ char_u *kmsg;
kmsg = keep_msg;
keep_msg = NULL;
@@ -708,7 +714,7 @@ static void normal_get_additional_char(NormalState *s)
if (!lit) {
// Typing CTRL-K gets a digraph.
if (*cp == Ctrl_K && ((nv_cmds[s->idx].cmd_flags & NV_LANG)
- || cp == &s->ca.extra_char)
+ || cp == &s->ca.extra_char)
&& vim_strchr(p_cpo, CPO_DIGRAPH) == NULL) {
s->c = get_digraph(false);
if (s->c > 0) {
@@ -736,7 +742,7 @@ static void normal_get_additional_char(NormalState *s)
s->ca.nchar = s->ca.extra_char;
s->idx = find_command(s->ca.cmdchar);
} else if ((s->ca.nchar == 'n' || s->ca.nchar == 'N')
- && s->ca.cmdchar == 'g') {
+ && s->ca.cmdchar == 'g') {
s->ca.oap->op_type = get_op_type(*cp, NUL);
} else if (*cp == Ctrl_BSL) {
long towait = (p_ttm >= 0 ? p_ttm : p_tm);
@@ -770,7 +776,7 @@ static void normal_get_additional_char(NormalState *s)
&& (s->c >= 0x100 || MB_BYTE2LEN(vpeekc()) > 1)) {
s->c = plain_vgetc();
if (!utf_iscomposing(s->c)) {
- vungetc(s->c); /* it wasn't, put it back */
+ vungetc(s->c); // it wasn't, put it back
break;
} else if (s->ca.ncharC1 == 0) {
s->ca.ncharC1 = s->c;
@@ -786,16 +792,26 @@ static void normal_get_additional_char(NormalState *s)
static void normal_invert_horizontal(NormalState *s)
{
switch (s->ca.cmdchar) {
- case 'l': s->ca.cmdchar = 'h'; break;
- case K_RIGHT: s->ca.cmdchar = K_LEFT; break;
- case K_S_RIGHT: s->ca.cmdchar = K_S_LEFT; break;
- case K_C_RIGHT: s->ca.cmdchar = K_C_LEFT; break;
- case 'h': s->ca.cmdchar = 'l'; break;
- case K_LEFT: s->ca.cmdchar = K_RIGHT; break;
- case K_S_LEFT: s->ca.cmdchar = K_S_RIGHT; break;
- case K_C_LEFT: s->ca.cmdchar = K_C_RIGHT; break;
- case '>': s->ca.cmdchar = '<'; break;
- case '<': s->ca.cmdchar = '>'; break;
+ case 'l':
+ s->ca.cmdchar = 'h'; break;
+ case K_RIGHT:
+ s->ca.cmdchar = K_LEFT; break;
+ case K_S_RIGHT:
+ s->ca.cmdchar = K_S_LEFT; break;
+ case K_C_RIGHT:
+ s->ca.cmdchar = K_C_LEFT; break;
+ case 'h':
+ s->ca.cmdchar = 'l'; break;
+ case K_LEFT:
+ s->ca.cmdchar = K_RIGHT; break;
+ case K_S_LEFT:
+ s->ca.cmdchar = K_S_RIGHT; break;
+ case K_C_LEFT:
+ s->ca.cmdchar = K_C_RIGHT; break;
+ case '>':
+ s->ca.cmdchar = '<'; break;
+ case '<':
+ s->ca.cmdchar = '>'; break;
}
s->idx = find_command(s->ca.cmdchar);
}
@@ -809,7 +825,7 @@ static bool normal_get_command_count(NormalState *s)
// Note that '0' is a command and not the start of a count, but it's
// part of a count after other digits.
while ((s->c >= '1' && s->c <= '9') || (s->ca.count0 != 0
- && (s->c == K_DEL || s->c == K_KDEL || s->c == '0'))) {
+ && (s->c == K_DEL || s->c == K_KDEL || s->c == '0'))) {
if (s->c == K_DEL || s->c == K_KDEL) {
s->ca.count0 /= 10;
del_from_showcmd(4); // delete the digit and ~@%
@@ -942,11 +958,11 @@ normal_end:
// if still inside a mapping that started in Visual mode).
// May switch from Visual to Select mode after CTRL-O command.
if (s->oa.op_type == OP_NOP
- && ((restart_edit != 0 && !VIsual_active && s->old_mapped_len == 0)
- || restart_VIsual_select == 1)
- && !(s->ca.retval & CA_COMMAND_BUSY)
- && stuff_empty()
- && s->oa.regname == 0) {
+ && ((restart_edit != 0 && !VIsual_active && s->old_mapped_len == 0)
+ || restart_VIsual_select == 1)
+ && !(s->ca.retval & CA_COMMAND_BUSY)
+ && stuff_empty()
+ && s->oa.regname == 0) {
if (restart_VIsual_select == 1) {
VIsual_select = true;
showmode();
@@ -969,7 +985,7 @@ static int normal_execute(VimState *state, int key)
{
NormalState *s = (NormalState *)state;
s->command_finished = false;
- s->ctrl_w = false; /* got CTRL-W command */
+ s->ctrl_w = false; // got CTRL-W command
s->old_col = curwin->w_curswant;
s->c = key;
@@ -981,7 +997,7 @@ static int normal_execute(VimState *state, int key)
if (restart_edit == 0) {
s->old_mapped_len = 0;
} else if (s->old_mapped_len || (VIsual_active && s->mapped_len == 0
- && typebuf_maplen() > 0)) {
+ && typebuf_maplen() > 0)) {
s->old_mapped_len = typebuf_maplen();
}
@@ -991,7 +1007,7 @@ static int normal_execute(VimState *state, int key)
// In Select mode, typed text replaces the selection.
if (VIsual_active && VIsual_select && (vim_isprintc(s->c)
- || s->c == NL || s->c == CAR || s->c == K_KENTER)) {
+ || s->c == NL || s->c == CAR || s->c == K_KENTER)) {
// Fake a "c"hange command. When "restart_edit" is set (e.g., because
// 'insertmode' is set) fake a "d"elete command, Insert mode will
// restart automatically.
@@ -1009,14 +1025,14 @@ static int normal_execute(VimState *state, int key)
s->need_flushbuf = add_to_showcmd(s->c);
- while (normal_get_command_count(s)) continue;
+ while (normal_get_command_count(s)) { continue; }
if (s->c == K_EVENT) {
// Save the count values so that ca.opcount and ca.count0 are exactly
// the same when coming back here after handling K_EVENT.
s->oa.prev_opcount = s->ca.opcount;
s->oa.prev_count0 = s->ca.count0;
- } else if (s->ca.opcount != 0) {
+ } else if (s->ca.opcount != 0) {
// If we're in the middle of an operator (including after entering a
// yank buffer with '"') AND we had a count before the operator, then
// that count overrides the current value of ca.count0.
@@ -1188,7 +1204,7 @@ static void normal_check_interrupt(NormalState *s)
&& s->previous_got_int) {
// Typed two CTRL-C in a row: go back to ex mode as if "Q" was
// used and keep "got_int" set, so that it aborts ":g".
- exmode_active = EXMODE_NORMAL;
+ exmode_active = true;
State = NORMAL;
} else if (!global_busy || !exmode_active) {
if (!quit_more) {
@@ -1277,6 +1293,15 @@ static void normal_redraw(NormalState *s)
redrawWinline(curwin, curwin->w_cursor.lnum);
}
+ // Might need to update for 'cursorline'.
+ // When 'cursorlineopt' is "screenline" need to redraw always.
+ if (curwin->w_p_cul
+ && (curwin->w_last_cursorline != curwin->w_cursor.lnum
+ || (curwin->w_p_culopt_flags & CULOPT_SCRLINE))
+ && !char_avail()) {
+ redraw_later(curwin, VALID);
+ }
+
if (VIsual_active) {
update_curbuf(INVERTED); // update inverted part
} else if (must_redraw) {
@@ -1340,7 +1365,7 @@ static int normal_check(VimState *state)
quit_more = false;
// If skip redraw is set (for ":" in wait_return()), don't redraw now.
- // If there is nothing in the stuff_buffer or do_redraw is TRUE,
+ // If there is nothing in the stuff_buffer or do_redraw is true,
// update cursor and redraw.
if (skip_redraw || exmode_active) {
skip_redraw = false;
@@ -1398,7 +1423,7 @@ static int normal_check(VimState *state)
if (s->noexmode) {
return 0;
}
- do_exmode(exmode_active == EXMODE_VIM);
+ do_exmode();
return -1;
}
@@ -1419,18 +1444,19 @@ static void set_vcount_ca(cmdarg_T *cap, bool *set_prevcount)
{
long count = cap->count0;
- /* multiply with cap->opcount the same way as above */
- if (cap->opcount != 0)
+ // multiply with cap->opcount the same way as above
+ if (cap->opcount != 0) {
count = cap->opcount * (count == 0 ? 1 : count);
+ }
set_vcount(count, count == 0 ? 1 : count, *set_prevcount);
- *set_prevcount = false; /* only set v:prevcount once */
+ *set_prevcount = false; // only set v:prevcount once
}
// Handle an operator after Visual mode or when the movement is finished.
// "gui_yank" is true when yanking text for the clipboard.
void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
{
- oparg_T *oap = cap->oap;
+ oparg_T *oap = cap->oap;
pos_T old_cursor;
bool empty_region_error;
int restart_edit_save;
@@ -1500,12 +1526,11 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
&& oap->op_type != OP_FOLDCLOSE
&& oap->op_type != OP_FOLDCLOSEREC
&& oap->op_type != OP_FOLDDEL
- && oap->op_type != OP_FOLDDELREC
- ) {
+ && oap->op_type != OP_FOLDDELREC) {
prep_redo(oap->regname, cap->count0,
- get_op_char(oap->op_type), get_extra_op_char(oap->op_type),
- oap->motion_force, cap->cmdchar, cap->nchar);
- if (cap->cmdchar == '/' || cap->cmdchar == '?') { /* was a search */
+ get_op_char(oap->op_type), get_extra_op_char(oap->op_type),
+ oap->motion_force, cap->cmdchar, cap->nchar);
+ if (cap->cmdchar == '/' || cap->cmdchar == '?') { // was a search
/*
* If 'cpoptions' does not contain 'r', insert the search
* pattern to really repeat the same command.
@@ -1533,8 +1558,9 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
* redo_VIsual_line_count and redo_VIsual_vcol. */
oap->start = curwin->w_cursor;
curwin->w_cursor.lnum += redo_VIsual_line_count - 1;
- if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
+ if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count) {
curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+ }
VIsual_mode = redo_VIsual_mode;
if (redo_VIsual_vcol == MAXCOL || VIsual_mode == 'v') {
if (VIsual_mode == 'v') {
@@ -1542,8 +1568,9 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
validate_virtcol();
curwin->w_curswant =
curwin->w_virtcol + redo_VIsual_vcol - 1;
- } else
+ } else {
curwin->w_curswant = redo_VIsual_vcol;
+ }
} else {
curwin->w_curswant = MAXCOL;
}
@@ -1553,7 +1580,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
cap->count1 = (cap->count0 == 0 ? 1 : cap->count0);
} else if (VIsual_active) {
if (!gui_yank) {
- /* Save the current VIsual area for '< and '> marks, and "gv" */
+ // Save the current VIsual area for '< and '> marks, and "gv"
curbuf->b_visual.vi_start = VIsual;
curbuf->b_visual.vi_end = curwin->w_cursor;
curbuf->b_visual.vi_mode = VIsual_mode;
@@ -1599,10 +1626,11 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
* to the end of the operated text. w_cursor is equal to oap->start.
*/
if (lt(oap->start, curwin->w_cursor)) {
- /* Include folded lines completely. */
+ // Include folded lines completely.
if (!VIsual_active) {
- if (hasFolding(oap->start.lnum, &oap->start.lnum, NULL))
+ if (hasFolding(oap->start.lnum, &oap->start.lnum, NULL)) {
oap->start.col = 0;
+ }
if ((curwin->w_cursor.col > 0
|| oap->inclusive
|| oap->motion_type == kMTLineWise)
@@ -1637,7 +1665,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
check_pos(curwin->w_buffer, &oap->end);
oap->line_count = oap->end.lnum - oap->start.lnum + 1;
- /* Set "virtual_op" before resetting VIsual_active. */
+ // Set "virtual_op" before resetting VIsual_active.
virtual_op = virtual_active();
if (VIsual_active || redo_VIsual_busy) {
@@ -1649,19 +1677,22 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
* size of the Visual text
*/
resel_VIsual_mode = VIsual_mode;
- if (curwin->w_curswant == MAXCOL)
+ if (curwin->w_curswant == MAXCOL) {
resel_VIsual_vcol = MAXCOL;
- else {
- if (VIsual_mode != Ctrl_V)
+ } else {
+ if (VIsual_mode != Ctrl_V) {
getvvcol(curwin, &(oap->end),
- NULL, NULL, &oap->end_vcol);
+ NULL, NULL, &oap->end_vcol);
+ }
if (VIsual_mode == Ctrl_V || oap->line_count <= 1) {
- if (VIsual_mode != Ctrl_V)
+ if (VIsual_mode != Ctrl_V) {
getvvcol(curwin, &(oap->start),
- &oap->start_vcol, NULL, NULL);
+ &oap->start_vcol, NULL, NULL);
+ }
resel_VIsual_vcol = oap->end_vcol - oap->start_vcol + 1;
- } else
+ } else {
resel_VIsual_vcol = oap->end_vcol;
+ }
}
resel_VIsual_line_count = oap->line_count;
}
@@ -1676,8 +1707,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
&& oap->op_type != OP_FOLDCLOSEREC
&& oap->op_type != OP_FOLDDEL
&& oap->op_type != OP_FOLDDELREC
- && oap->motion_force == NUL
- ) {
+ && oap->motion_force == NUL) {
/* Prepare for redoing. Only use the nchar field for "r",
* otherwise it might be the second char of the operator. */
if (cap->cmdchar == 'g' && (cap->nchar == 'n'
@@ -1717,8 +1747,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
} else if (VIsual_mode == 'v') {
oap->motion_type = kMTCharWise;
if (*ml_get_pos(&(oap->end)) == NUL
- && (include_line_break || !virtual_op)
- ) {
+ && (include_line_break || !virtual_op)) {
oap->inclusive = false;
// Try to include the newline, unless it's an operator
// that works on lines only.
@@ -1820,22 +1849,24 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
oap->inclusive = true;
}
}
- } else
+ } else {
oap->end_adjusted = false;
+ }
switch (oap->op_type) {
case OP_LSHIFT:
case OP_RSHIFT:
op_shift(oap, true,
- oap->is_VIsual ? (int)cap->count1 :
- 1);
+ oap->is_VIsual ? (int)cap->count1 :
+ 1);
auto_format(false, true);
break;
case OP_JOIN_NS:
case OP_JOIN:
- if (oap->line_count < 2)
+ if (oap->line_count < 2) {
oap->line_count = 2;
+ }
if (curwin->w_cursor.lnum + oap->line_count - 1 >
curbuf->b_ml.ml_line_count) {
beep_flush();
@@ -1847,7 +1878,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
break;
case OP_DELETE:
- VIsual_reselect = false; /* don't reselect now */
+ VIsual_reselect = false; // don't reselect now
if (empty_region_error) {
vim_beep(BO_OPER);
CancelRedo();
@@ -1877,7 +1908,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
break;
case OP_CHANGE:
- VIsual_reselect = false; /* don't reselect now */
+ VIsual_reselect = false; // don't reselect now
if (empty_region_error) {
vim_beep(BO_OPER);
CancelRedo();
@@ -1886,10 +1917,11 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
* remember it to make 'insertmode' work with mappings for
* Visual mode. But do this only once and not when typed and
* 'insertmode' isn't set. */
- if (p_im || !KeyTyped)
+ if (p_im || !KeyTyped) {
restart_edit_save = restart_edit;
- else
+ } else {
restart_edit_save = 0;
+ }
restart_edit = 0;
// Restore linebreak, so that when the user edits it looks as before.
@@ -1897,10 +1929,12 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
// Reset finish_op now, don't want it set inside edit().
finish_op = false;
- if (op_change(oap)) /* will call edit() */
+ if (op_change(oap)) { // will call edit()
cap->retval |= CA_COMMAND_BUSY;
- if (restart_edit == 0)
+ }
+ if (restart_edit == 0) {
restart_edit = restart_edit_save;
+ }
}
break;
@@ -1924,8 +1958,8 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
break;
}
op_reindent(oap,
- *curbuf->b_p_inde != NUL ? get_expr_indent :
- get_c_indent);
+ *curbuf->b_p_inde != NUL ? get_expr_indent :
+ get_c_indent);
break;
}
@@ -1939,8 +1973,9 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
if (empty_region_error) {
vim_beep(BO_OPER);
CancelRedo();
- } else
+ } else {
op_tilde(oap);
+ }
check_cursor_col();
break;
@@ -1957,7 +1992,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
break;
case OP_FORMAT2:
- op_format(oap, true); /* use internal function */
+ op_format(oap, true); // use internal function
break;
case OP_FUNCTION:
@@ -1969,7 +2004,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
case OP_INSERT:
case OP_APPEND:
- VIsual_reselect = false; /* don't reselect now */
+ VIsual_reselect = false; // don't reselect now
if (empty_region_error) {
vim_beep(BO_OPER);
CancelRedo();
@@ -2001,7 +2036,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
break;
case OP_REPLACE:
- VIsual_reselect = false; /* don't reselect now */
+ VIsual_reselect = false; // don't reselect now
if (empty_region_error) {
vim_beep(BO_OPER);
CancelRedo();
@@ -2133,10 +2168,10 @@ static void op_function(const oparg_T *oap)
{
const TriState save_virtual_op = virtual_op;
- if (*p_opfunc == NUL)
+ if (*p_opfunc == NUL) {
EMSG(_("E774: 'operatorfunc' is empty"));
- else {
- /* Set '[ and '] marks to text to be operated on. */
+ } else {
+ // Set '[ and '] marks to text to be operated on.
curbuf->b_op_start = oap->start;
curbuf->b_op_end = oap->end;
if (oap->motion_type != kMTLineWise && !oap->inclusive) {
@@ -2149,10 +2184,10 @@ static void op_function(const oparg_T *oap)
argv[1].v_type = VAR_UNKNOWN;
argv[0].vval.v_string =
(char_u *)(((const char *const[]) {
- [kMTBlockWise] = "block",
- [kMTLineWise] = "line",
- [kMTCharWise] = "char",
- })[oap->motion_type]);
+ [kMTBlockWise] = "block",
+ [kMTLineWise] = "line",
+ [kMTCharWise] = "char",
+ })[oap->motion_type]);
// Reset virtual_op so that 'virtualedit' can be changed in the
// function.
@@ -2170,73 +2205,69 @@ static void move_tab_to_mouse(void)
{
int tabnr = tab_page_click_defs[mouse_col].tabnr;
if (tabnr <= 0) {
- tabpage_move(9999);
+ tabpage_move(9999);
} else if (tabnr < tabpage_index(curtab)) {
- tabpage_move(tabnr - 1);
+ tabpage_move(tabnr - 1);
} else {
- tabpage_move(tabnr);
- }
-}
-
-/*
- * Do the appropriate action for the current mouse click in the current mode.
- * Not used for Command-line mode.
- *
- * Normal Mode:
- * event modi- position visual change action
- * fier cursor window
- * left press - yes end yes
- * left press C yes end yes "^]" (2)
- * left press S yes end yes "*" (2)
- * left drag - yes start if moved no
- * left relse - yes start if moved no
- * middle press - yes if not active no put register
- * middle press - yes if active no yank and put
- * right press - yes start or extend yes
- * right press S yes no change yes "#" (2)
- * right drag - yes extend no
- * right relse - yes extend no
- *
- * Insert or Replace Mode:
- * event modi- position visual change action
- * fier cursor window
- * left press - yes (cannot be active) yes
- * left press C yes (cannot be active) yes "CTRL-O^]" (2)
- * left press S yes (cannot be active) yes "CTRL-O*" (2)
- * left drag - yes start or extend (1) no CTRL-O (1)
- * left relse - yes start or extend (1) no CTRL-O (1)
- * middle press - no (cannot be active) no put register
- * right press - yes start or extend yes CTRL-O
- * right press S yes (cannot be active) yes "CTRL-O#" (2)
- *
- * (1) only if mouse pointer moved since press
- * (2) only if click is in same buffer
- *
- * Return true if start_arrow() should be called for edit mode.
- */
-bool
-do_mouse (
- oparg_T *oap, /* operator argument, can be NULL */
- int c, /* K_LEFTMOUSE, etc */
- int dir, /* Direction to 'put' if necessary */
- long count,
- bool fixindent /* PUT_FIXINDENT if fixing indent necessary */
-)
-{
- static bool got_click = false; /* got a click some time back */
-
- int which_button; /* MOUSE_LEFT, _MIDDLE or _RIGHT */
- bool is_click; /* If false it's a drag or release event */
- bool is_drag; /* If true it's a drag event */
- int jump_flags = 0; /* flags for jump_to_mouse() */
+ tabpage_move(tabnr);
+ }
+}
+
+/// Do the appropriate action for the current mouse click in the current mode.
+/// Not used for Command-line mode.
+///
+/// Normal Mode:
+/// event modi- position visual change action
+/// fier cursor window
+/// left press - yes end yes
+/// left press C yes end yes "^]" (2)
+/// left press S yes end yes "*" (2)
+/// left drag - yes start if moved no
+/// left relse - yes start if moved no
+/// middle press - yes if not active no put register
+/// middle press - yes if active no yank and put
+/// right press - yes start or extend yes
+/// right press S yes no change yes "#" (2)
+/// right drag - yes extend no
+/// right relse - yes extend no
+///
+/// Insert or Replace Mode:
+/// event modi- position visual change action
+/// fier cursor window
+/// left press - yes (cannot be active) yes
+/// left press C yes (cannot be active) yes "CTRL-O^]" (2)
+/// left press S yes (cannot be active) yes "CTRL-O*" (2)
+/// left drag - yes start or extend (1) no CTRL-O (1)
+/// left relse - yes start or extend (1) no CTRL-O (1)
+/// middle press - no (cannot be active) no put register
+/// right press - yes start or extend yes CTRL-O
+/// right press S yes (cannot be active) yes "CTRL-O#" (2)
+///
+/// (1) only if mouse pointer moved since press
+/// (2) only if click is in same buffer
+///
+/// @param oap operator argument, can be NULL
+/// @param c K_LEFTMOUSE, etc
+/// @param dir Direction to 'put' if necessary
+/// @param fixindent PUT_FIXINDENT if fixing indent necessary
+///
+/// @return true if start_arrow() should be called for edit mode.
+bool do_mouse(oparg_T *oap, int c, int dir, long count, bool fixindent)
+{
+ static bool got_click = false; // got a click some time back
+
+ int which_button; // MOUSE_LEFT, _MIDDLE or _RIGHT
+ bool is_click; // If false it's a drag or release event
+ bool is_drag; // If true it's a drag event
+ int jump_flags = 0; // flags for jump_to_mouse()
pos_T start_visual;
- bool moved; /* Has cursor moved? */
- bool in_status_line; /* mouse in status line */
- static bool in_tab_line = false; /* mouse clicked in tab line */
- bool in_sep_line; /* mouse in vertical separator line */
+ bool moved; // Has cursor moved?
+ bool in_status_line; // mouse in status line
+ static bool in_tab_line = false; // mouse clicked in tab line
+ bool in_sep_line; // mouse in vertical separator line
int c1, c2;
pos_T save_cursor;
- win_T *old_curwin = curwin;
+ win_T *old_curwin = curwin;
static pos_T orig_cursor;
colnr_T leftcol, rightcol;
pos_T end_visual;
@@ -2261,8 +2292,9 @@ do_mouse (
/* Need to get the character, peeking doesn't get the actual
* one. */
nc = safe_vgetc();
- if (c == nc)
+ if (c == nc) {
continue;
+ }
vungetc(nc);
mouse_grid = save_mouse_grid;
mouse_row = save_mouse_row;
@@ -2280,12 +2312,13 @@ do_mouse (
/*
* Ignore drag and release events if we didn't get a click.
*/
- if (is_click)
+ if (is_click) {
got_click = true;
- else {
- if (!got_click) /* didn't get click, ignore */
+ } else {
+ if (!got_click) { // didn't get click, ignore
return false;
- if (!is_drag) { /* release, reset got_click */
+ }
+ if (!is_drag) { // release, reset got_click
got_click = false;
if (in_tab_line) {
in_tab_line = false;
@@ -2299,20 +2332,23 @@ do_mouse (
* CTRL right mouse button does CTRL-T
*/
if (is_click && (mod_mask & MOD_MASK_CTRL) && which_button == MOUSE_RIGHT) {
- if (State & INSERT)
+ if (State & INSERT) {
stuffcharReadbuff(Ctrl_O);
- if (count > 1)
+ }
+ if (count > 1) {
stuffnumReadbuff(count);
+ }
stuffcharReadbuff(Ctrl_T);
- got_click = false; /* ignore drag&release now */
+ got_click = false; // ignore drag&release now
return false;
}
/*
* CTRL only works with left mouse button
*/
- if ((mod_mask & MOD_MASK_CTRL) && which_button != MOUSE_LEFT)
+ if ((mod_mask & MOD_MASK_CTRL) && which_button != MOUSE_LEFT) {
return false;
+ }
/*
* When a modifier is down, ignore drag and release events, as well as
@@ -2329,22 +2365,24 @@ do_mouse (
&& which_button == MOUSE_LEFT)
&& !((mod_mask & MOD_MASK_ALT)
&& !mouse_model_popup()
- && which_button == MOUSE_RIGHT)
- )
+ && which_button == MOUSE_RIGHT)) {
return false;
+ }
/*
* If the button press was used as the movement command for an operator
* (eg "d<MOUSE>"), or it is the middle button that is held down, ignore
* drag/release events.
*/
- if (!is_click && which_button == MOUSE_MIDDLE)
+ if (!is_click && which_button == MOUSE_MIDDLE) {
return false;
+ }
- if (oap != NULL)
+ if (oap != NULL) {
regname = oap->regname;
- else
+ } else {
regname = 0;
+ }
/*
* Middle mouse button does a 'put' of the selected text
@@ -2378,8 +2416,9 @@ do_mouse (
/*
* The rest is below jump_to_mouse()
*/
- } else if ((State & INSERT) == 0)
+ } else if ((State & INSERT) == 0) {
return false;
+ }
/*
* Middle click in insert mode doesn't move the mouse, just insert the
@@ -2401,7 +2440,7 @@ do_mouse (
do_put(regname, NULL, BACKWARD, 1L,
(fixindent ? PUT_FIXINDENT : 0) | PUT_CURSEND);
- /* Repeat it with CTRL-R CTRL-O r or CTRL-R CTRL-P r */
+ // Repeat it with CTRL-R CTRL-O r or CTRL-R CTRL-P r
AppendCharToRedobuff(Ctrl_R);
AppendCharToRedobuff(fixindent ? Ctrl_P : Ctrl_O);
AppendCharToRedobuff(regname == 0 ? '"' : regname);
@@ -2411,9 +2450,10 @@ do_mouse (
}
}
- /* When dragging or button-up stay in the same window. */
- if (!is_click)
+ // When dragging or button-up stay in the same window.
+ if (!is_click) {
jump_flags |= MOUSE_FOCUS | MOUSE_DID_MOVE;
+ }
start_visual.lnum = 0;
@@ -2426,67 +2466,65 @@ do_mouse (
return false;
}
- /* click in a tab selects that tab page */
+ // click in a tab selects that tab page
if (is_click
&& cmdwin_type == 0
&& mouse_col < Columns) {
in_tab_line = true;
c1 = tab_page_click_defs[mouse_col].tabnr;
switch (tab_page_click_defs[mouse_col].type) {
- case kStlClickDisabled: {
- break;
- }
- case kStlClickTabClose: {
- tabpage_T *tp;
+ case kStlClickDisabled:
+ break;
+ case kStlClickTabClose: {
+ tabpage_T *tp;
- // Close the current or specified tab page.
- if (c1 == 999) {
- tp = curtab;
- } else {
- tp = find_tabpage(c1);
- }
- if (tp == curtab) {
- if (first_tabpage->tp_next != NULL) {
- tabpage_close(false);
- }
- } else if (tp != NULL) {
- tabpage_close_other(tp, false);
+ // Close the current or specified tab page.
+ if (c1 == 999) {
+ tp = curtab;
+ } else {
+ tp = find_tabpage(c1);
+ }
+ if (tp == curtab) {
+ if (first_tabpage->tp_next != NULL) {
+ tabpage_close(false);
}
- break;
+ } else if (tp != NULL) {
+ tabpage_close_other(tp, false);
}
- case kStlClickTabSwitch: {
- if ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK) {
- // double click opens new page
- end_visual_mode();
- tabpage_new();
- tabpage_move(c1 == 0 ? 9999 : c1 - 1);
- } else {
- // Go to specified tab page, or next one if not clicking
- // on a label.
- goto_tabpage(c1);
+ break;
+ }
+ case kStlClickTabSwitch:
+ if ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK) {
+ // double click opens new page
+ end_visual_mode();
+ tabpage_new();
+ tabpage_move(c1 == 0 ? 9999 : c1 - 1);
+ } else {
+ // Go to specified tab page, or next one if not clicking
+ // on a label.
+ goto_tabpage(c1);
- // It's like clicking on the status line of a window.
- if (curwin != old_curwin) {
- end_visual_mode();
- }
+ // It's like clicking on the status line of a window.
+ if (curwin != old_curwin) {
+ end_visual_mode();
}
- break;
}
- case kStlClickFuncRun: {
- typval_T argv[] = {
- {
- .v_lock = VAR_FIXED,
- .v_type = VAR_NUMBER,
- .vval = {
- .v_number = (varnumber_T) tab_page_click_defs[mouse_col].tabnr
- },
+ break;
+ case kStlClickFuncRun: {
+ typval_T argv[] = {
+ {
+ .v_lock = VAR_FIXED,
+ .v_type = VAR_NUMBER,
+ .vval = {
+ .v_number = (varnumber_T)tab_page_click_defs[mouse_col].tabnr
},
- {
- .v_lock = VAR_FIXED,
- .v_type = VAR_NUMBER,
- .vval = {
- .v_number = (((mod_mask & MOD_MASK_MULTI_CLICK)
- == MOD_MASK_4CLICK)
+ },
+ {
+ .v_lock = VAR_FIXED,
+ .v_type = VAR_NUMBER,
+ .vval = {
+ .v_number = (((mod_mask & MOD_MASK_MULTI_CLICK)
+ == MOD_MASK_4CLICK)
? 4
: ((mod_mask & MOD_MASK_MULTI_CLICK)
== MOD_MASK_3CLICK)
@@ -2495,43 +2533,43 @@ do_mouse (
== MOD_MASK_2CLICK)
? 2
: 1)
- },
},
- {
- .v_lock = VAR_FIXED,
- .v_type = VAR_STRING,
- .vval = { .v_string = (char_u *) (which_button == MOUSE_LEFT
+ },
+ {
+ .v_lock = VAR_FIXED,
+ .v_type = VAR_STRING,
+ .vval = { .v_string = (char_u *)(which_button == MOUSE_LEFT
? "l"
: which_button == MOUSE_RIGHT
? "r"
: which_button == MOUSE_MIDDLE
? "m"
: "?") },
+ },
+ {
+ .v_lock = VAR_FIXED,
+ .v_type = VAR_STRING,
+ .vval = {
+ .v_string = (char_u[]) {
+ (char_u)(mod_mask & MOD_MASK_SHIFT ? 's' : ' '),
+ (char_u)(mod_mask & MOD_MASK_CTRL ? 'c' : ' '),
+ (char_u)(mod_mask & MOD_MASK_ALT ? 'a' : ' '),
+ (char_u)(mod_mask & MOD_MASK_META ? 'm' : ' '),
+ NUL
+ }
},
- {
- .v_lock = VAR_FIXED,
- .v_type = VAR_STRING,
- .vval = {
- .v_string = (char_u[]) {
- (char_u) (mod_mask & MOD_MASK_SHIFT ? 's' : ' '),
- (char_u) (mod_mask & MOD_MASK_CTRL ? 'c' : ' '),
- (char_u) (mod_mask & MOD_MASK_ALT ? 'a' : ' '),
- (char_u) (mod_mask & MOD_MASK_META ? 'm' : ' '),
- NUL
- }
- },
- }
- };
- typval_T rettv;
- int doesrange;
- (void)call_func((char_u *)tab_page_click_defs[mouse_col].func,
- -1,
- &rettv, ARRAY_SIZE(argv), argv, NULL,
- curwin->w_cursor.lnum, curwin->w_cursor.lnum,
- &doesrange, true, NULL, NULL);
- tv_clear(&rettv);
- break;
- }
+ }
+ };
+ typval_T rettv;
+ funcexe_T funcexe = FUNCEXE_INIT;
+ funcexe.firstline = curwin->w_cursor.lnum;
+ funcexe.lastline = curwin->w_cursor.lnum;
+ funcexe.evaluate = true;
+ (void)call_func((char_u *)tab_page_click_defs[mouse_col].func, -1,
+ &rettv, ARRAY_SIZE(argv), argv, &funcexe);
+ tv_clear(&rettv);
+ break;
+ }
}
}
return true;
@@ -2569,8 +2607,9 @@ do_mouse (
if (is_click) {
/* stop Visual mode for a left click in a window, but not when
* on a status line */
- if (VIsual_active)
+ if (VIsual_active) {
jump_flags |= MOUSE_MAY_STOP_VIS;
+ }
} else {
jump_flags |= MOUSE_MAY_VIS;
}
@@ -2602,9 +2641,10 @@ do_mouse (
oap->motion_type = kMTCharWise;
}
- /* When releasing the button let jump_to_mouse() know. */
- if (!is_click && !is_drag)
+ // When releasing the button let jump_to_mouse() know.
+ if (!is_click && !is_drag) {
jump_flags |= MOUSE_RELEASED;
+ }
/*
* JUMP!
@@ -2620,8 +2660,9 @@ do_mouse (
/* When jumping to another window, clear a pending operator. That's a bit
* friendlier than beeping and not jumping to that window. */
- if (curwin != old_curwin && oap != NULL && oap->op_type != OP_NOP)
+ if (curwin != old_curwin && oap != NULL && oap->op_type != OP_NOP) {
clearop(oap);
+ }
if (mod_mask == 0
&& !is_drag
@@ -2651,16 +2692,17 @@ do_mouse (
}
}
- /* When dragging the mouse above the window, scroll down. */
+ // When dragging the mouse above the window, scroll down.
if (is_drag && mouse_row < 0 && !in_status_line) {
scroll_redraw(false, 1L);
mouse_row = 0;
}
- if (start_visual.lnum) { /* right click in visual mode */
- /* When ALT is pressed make Visual mode blockwise. */
- if (mod_mask & MOD_MASK_ALT)
+ if (start_visual.lnum) { // right click in visual mode
+ // When ALT is pressed make Visual mode blockwise.
+ if (mod_mask & MOD_MASK_ALT) {
VIsual_mode = Ctrl_V;
+ }
/*
* In Visual-block mode, divide the area in four, pick up the corner
@@ -2668,55 +2710,58 @@ do_mouse (
*/
if (VIsual_mode == Ctrl_V) {
getvcols(curwin, &start_visual, &end_visual, &leftcol, &rightcol);
- if (curwin->w_curswant > (leftcol + rightcol) / 2)
+ if (curwin->w_curswant > (leftcol + rightcol) / 2) {
end_visual.col = leftcol;
- else
+ } else {
end_visual.col = rightcol;
+ }
if (curwin->w_cursor.lnum >=
(start_visual.lnum + end_visual.lnum) / 2) {
end_visual.lnum = start_visual.lnum;
}
- /* move VIsual to the right column */
- start_visual = curwin->w_cursor; /* save the cursor pos */
+ // move VIsual to the right column
+ start_visual = curwin->w_cursor; // save the cursor pos
curwin->w_cursor = end_visual;
coladvance(end_visual.col);
VIsual = curwin->w_cursor;
- curwin->w_cursor = start_visual; /* restore the cursor */
+ curwin->w_cursor = start_visual; // restore the cursor
} else {
/*
* If the click is before the start of visual, change the start.
* If the click is after the end of visual, change the end. If
* the click is inside the visual, change the closest side.
*/
- if (lt(curwin->w_cursor, start_visual))
+ if (lt(curwin->w_cursor, start_visual)) {
VIsual = end_visual;
- else if (lt(end_visual, curwin->w_cursor))
+ } else if (lt(end_visual, curwin->w_cursor)) {
VIsual = start_visual;
- else {
- /* In the same line, compare column number */
+ } else {
+ // In the same line, compare column number
if (end_visual.lnum == start_visual.lnum) {
if (curwin->w_cursor.col - start_visual.col >
- end_visual.col - curwin->w_cursor.col)
+ end_visual.col - curwin->w_cursor.col) {
VIsual = start_visual;
- else
+ } else {
VIsual = end_visual;
+ }
}
- /* In different lines, compare line number */
+ // In different lines, compare line number
else {
diff = (curwin->w_cursor.lnum - start_visual.lnum) -
(end_visual.lnum - curwin->w_cursor.lnum);
- if (diff > 0) /* closest to end */
+ if (diff > 0) { // closest to end
VIsual = start_visual;
- else if (diff < 0) /* closest to start */
+ } else if (diff < 0) { // closest to start
VIsual = end_visual;
- else { /* in the middle line */
+ } else { // in the middle line
if (curwin->w_cursor.col <
- (start_visual.col + end_visual.col) / 2)
+ (start_visual.col + end_visual.col) / 2) {
VIsual = end_visual;
- else
+ } else {
VIsual = start_visual;
+ }
}
}
}
@@ -2725,8 +2770,9 @@ do_mouse (
/*
* If Visual mode started in insert mode, execute "CTRL-O"
*/
- else if ((State & INSERT) && VIsual_active)
+ else if ((State & INSERT) && VIsual_active) {
stuffcharReadbuff(Ctrl_O);
+ }
/*
* Middle mouse click: Put text before cursor.
@@ -2736,10 +2782,12 @@ do_mouse (
regname = '*';
}
if (yank_register_mline(regname)) {
- if (mouse_past_bottom)
+ if (mouse_past_bottom) {
dir = FORWARD;
- } else if (mouse_past_eol)
+ }
+ } else if (mouse_past_eol) {
dir = FORWARD;
+ }
if (fixindent) {
c1 = (dir == BACKWARD) ? '[' : ']';
@@ -2754,8 +2802,9 @@ do_mouse (
* Remember where the paste started, so in edit() Insstart can be set
* to this position
*/
- if (restart_edit != 0)
+ if (restart_edit != 0) {
where_paste_started = curwin->w_cursor;
+ }
do_put(regname, NULL, dir, count,
(fixindent ? PUT_FIXINDENT : 0)| PUT_CURSEND);
}
@@ -2781,10 +2830,11 @@ do_mouse (
&& (mod_mask &
MOD_MASK_MULTI_CLICK) ==
MOD_MASK_2CLICK)) {
- if (State & INSERT)
+ if (State & INSERT) {
stuffcharReadbuff(Ctrl_O);
+ }
stuffcharReadbuff(Ctrl_RSB);
- got_click = false; /* ignore drag&release now */
+ got_click = false; // ignore drag&release now
}
/*
* Shift-Mouse click searches for the next occurrence of the word under
@@ -2792,15 +2842,16 @@ do_mouse (
*/
else if ((mod_mask & MOD_MASK_SHIFT)) {
if (State & INSERT
- || (VIsual_active && VIsual_select)
- )
+ || (VIsual_active && VIsual_select)) {
stuffcharReadbuff(Ctrl_O);
- if (which_button == MOUSE_LEFT)
+ }
+ if (which_button == MOUSE_LEFT) {
stuffcharReadbuff('*');
- else /* MOUSE_RIGHT */
+ } else { // MOUSE_RIGHT
stuffcharReadbuff('#');
+ }
}
- /* Handle double clicks, unless on status line */
+ // Handle double clicks, unless on status line
else if (in_status_line) {
} else if (in_sep_line) {
} else if ((mod_mask & MOD_MASK_MULTI_CLICK) && (State & (NORMAL | INSERT))) {
@@ -2812,26 +2863,28 @@ do_mouse (
orig_cursor = VIsual;
VIsual_active = true;
VIsual_reselect = true;
- /* start Select mode if 'selectmode' contains "mouse" */
+ // start Select mode if 'selectmode' contains "mouse"
may_start_select('o');
setmouse();
}
if ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK) {
- /* Double click with ALT pressed makes it blockwise. */
- if (mod_mask & MOD_MASK_ALT)
+ // Double click with ALT pressed makes it blockwise.
+ if (mod_mask & MOD_MASK_ALT) {
VIsual_mode = Ctrl_V;
- else
+ } else {
VIsual_mode = 'v';
- } else if ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_3CLICK)
+ }
+ } else if ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_3CLICK) {
VIsual_mode = 'V';
- else if ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_4CLICK)
+ } else if ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_4CLICK) {
VIsual_mode = Ctrl_V;
+ }
}
/*
* A double click selects a word or a block.
*/
if ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK) {
- pos_T *pos = NULL;
+ pos_T *pos = NULL;
int gc;
if (is_click) {
@@ -2839,8 +2892,9 @@ do_mouse (
* not a word character, try finding a match and select a (),
* {}, [], #if/#endif, etc. block. */
end_visual = curwin->w_cursor;
- while (gc = gchar_pos(&end_visual), ascii_iswhite(gc))
+ while (gc = gchar_pos(&end_visual), ascii_iswhite(gc)) {
inc(&end_visual);
+ }
if (oap != NULL) {
oap->motion_type = kMTCharWise;
}
@@ -2870,28 +2924,32 @@ do_mouse (
find_end_of_word(&VIsual);
} else {
find_start_of_word(&VIsual);
- if (*p_sel == 'e' && *get_cursor_pos_ptr() != NUL)
+ if (*p_sel == 'e' && *get_cursor_pos_ptr() != NUL) {
curwin->w_cursor.col +=
(*mb_ptr2len)(get_cursor_pos_ptr());
+ }
find_end_of_word(&curwin->w_cursor);
}
}
curwin->w_set_curswant = true;
}
- if (is_click)
- redraw_curbuf_later(INVERTED); /* update the inversion */
+ if (is_click) {
+ redraw_curbuf_later(INVERTED); // update the inversion
+ }
} else if (VIsual_active && !old_active) {
- if (mod_mask & MOD_MASK_ALT)
+ if (mod_mask & MOD_MASK_ALT) {
VIsual_mode = Ctrl_V;
- else
+ } else {
VIsual_mode = 'v';
+ }
}
- /* If Visual mode changed show it later. */
+ // If Visual mode changed show it later.
if ((!VIsual_active && old_active && mode_displayed)
|| (VIsual_active && p_smd && msg_silent == 0
- && (!old_active || VIsual_mode != old_mode)))
+ && (!old_active || VIsual_mode != old_mode))) {
redraw_cmdline = true;
+ }
return moved;
}
@@ -2901,7 +2959,7 @@ do_mouse (
*/
static void find_start_of_word(pos_T *pos)
{
- char_u *line;
+ char_u *line;
int cclass;
int col;
@@ -2924,7 +2982,7 @@ static void find_start_of_word(pos_T *pos)
*/
static void find_end_of_word(pos_T *pos)
{
- char_u *line;
+ char_u *line;
int cclass;
int col;
@@ -2937,8 +2995,9 @@ static void find_end_of_word(pos_T *pos)
while (line[pos->col] != NUL) {
col = pos->col + (*mb_ptr2len)(line + pos->col);
if (get_mouse_class(line + col) != cclass) {
- if (*p_sel == 'e')
+ if (*p_sel == 'e') {
pos->col = col;
+ }
break;
}
pos->col = col;
@@ -2972,8 +3031,9 @@ static int get_mouse_class(char_u *p)
* "->", "/ *", "*=", "+=", "&=", "<=", ">=", "!=" etc. Otherwise, each
* character is in its own class.
*/
- if (c != NUL && vim_strchr((char_u *)"-+*/%<>&|^!=", c) != NULL)
+ if (c != NUL && vim_strchr((char_u *)"-+*/%<>&|^!=", c) != NULL) {
return 1;
+ }
return c;
}
@@ -2984,19 +3044,19 @@ static int get_mouse_class(char_u *p)
*/
void end_visual_mode(void)
{
-
VIsual_active = false;
setmouse();
mouse_dragging = 0;
- /* Save the current VIsual area for '< and '> marks, and "gv" */
+ // Save the current VIsual area for '< and '> marks, and "gv"
curbuf->b_visual.vi_mode = VIsual_mode;
curbuf->b_visual.vi_start = VIsual;
curbuf->b_visual.vi_end = curwin->w_cursor;
curbuf->b_visual.vi_curswant = curwin->w_curswant;
curbuf->b_visual_mode_eval = VIsual_mode;
- if (!virtual_active())
+ if (!virtual_active()) {
curwin->w_cursor.coladd = 0;
+ }
may_clear_cmdline();
@@ -3010,7 +3070,7 @@ void reset_VIsual_and_resel(void)
{
if (VIsual_active) {
end_visual_mode();
- redraw_curbuf_later(INVERTED); /* delete the inversion later */
+ redraw_curbuf_later(INVERTED); // delete the inversion later
}
VIsual_reselect = false;
}
@@ -3022,7 +3082,7 @@ void reset_VIsual(void)
{
if (VIsual_active) {
end_visual_mode();
- redraw_curbuf_later(INVERTED); /* delete the inversion later */
+ redraw_curbuf_later(INVERTED); // delete the inversion later
VIsual_reselect = false;
}
}
@@ -3033,11 +3093,8 @@ void reset_VIsual(void)
// "dir" is FORWARD or BACKWARD, the direction of searching.
// "*colp" is in/decremented if "ptr[-dir]" should also be included.
// "bnp" points to a counter for square brackets.
-static bool find_is_eval_item(
- const char_u *const ptr,
- int *const colp,
- int *const bnp,
- const int dir)
+static bool find_is_eval_item(const char_u *const ptr, int *const colp, int *const bnp,
+ const int dir)
{
// Accept everything inside [].
if ((*ptr == ']' && dir == BACKWARD) || (*ptr == '[' && dir == FORWARD)) {
@@ -3090,17 +3147,12 @@ size_t find_ident_under_cursor(char_u **text, int find_type)
curwin->w_cursor.col, text, NULL, find_type);
}
-/*
- * Like find_ident_under_cursor(), but for any window and any position.
- * However: Uses 'iskeyword' from the current window!.
- */
-size_t find_ident_at_pos(
- win_T *wp,
- linenr_T lnum,
- colnr_T startcol,
- char_u **text,
- int *textcol, // column where "text" starts, can be NULL
- int find_type)
+/// Like find_ident_under_cursor(), but for any window and any position.
+/// However: Uses 'iskeyword' from the current window!.
+///
+/// @param textcol column where "text" starts, can be NULL
+size_t find_ident_at_pos(win_T *wp, linenr_T lnum, colnr_T startcol, char_u **text, int *textcol,
+ int find_type)
FUNC_ATTR_NONNULL_ARG(1, 4)
{
int col = 0; // init to shut up GCC
@@ -3206,7 +3258,7 @@ size_t find_ident_at_pos(
static void prep_redo_cmd(cmdarg_T *cap)
{
prep_redo(cap->oap->regname, cap->count0,
- NUL, cap->cmdchar, NUL, NUL, cap->nchar);
+ NUL, cap->cmdchar, NUL, NUL, cap->nchar);
}
/*
@@ -3216,23 +3268,29 @@ static void prep_redo_cmd(cmdarg_T *cap)
static void prep_redo(int regname, long num, int cmd1, int cmd2, int cmd3, int cmd4, int cmd5)
{
ResetRedobuff();
- if (regname != 0) { /* yank from specified buffer */
+ if (regname != 0) { // yank from specified buffer
AppendCharToRedobuff('"');
AppendCharToRedobuff(regname);
}
- if (num)
+ if (num) {
AppendNumberToRedobuff(num);
+ }
- if (cmd1 != NUL)
+ if (cmd1 != NUL) {
AppendCharToRedobuff(cmd1);
- if (cmd2 != NUL)
+ }
+ if (cmd2 != NUL) {
AppendCharToRedobuff(cmd2);
- if (cmd3 != NUL)
+ }
+ if (cmd3 != NUL) {
AppendCharToRedobuff(cmd3);
- if (cmd4 != NUL)
+ }
+ if (cmd4 != NUL) {
AppendCharToRedobuff(cmd4);
- if (cmd5 != NUL)
+ }
+ if (cmd5 != NUL) {
AppendCharToRedobuff(cmd5);
+ }
}
/*
@@ -3242,8 +3300,9 @@ static void prep_redo(int regname, long num, int cmd1, int cmd2, int cmd3, int c
*/
static bool checkclearop(oparg_T *oap)
{
- if (oap->op_type == OP_NOP)
+ if (oap->op_type == OP_NOP) {
return false;
+ }
clearopbeep(oap);
return true;
}
@@ -3256,9 +3315,9 @@ static bool checkclearop(oparg_T *oap)
static bool checkclearopq(oparg_T *oap)
{
if (oap->op_type == OP_NOP
- && !VIsual_active
- )
+ && !VIsual_active) {
return false;
+ }
clearopbeep(oap);
return true;
}
@@ -3269,6 +3328,7 @@ static void clearop(oparg_T *oap)
oap->regname = 0;
oap->motion_force = NUL;
oap->use_reg_one = false;
+ motion_force = NUL;
}
static void clearopbeep(oparg_T *oap)
@@ -3283,12 +3343,18 @@ static void clearopbeep(oparg_T *oap)
static void unshift_special(cmdarg_T *cap)
{
switch (cap->cmdchar) {
- case K_S_RIGHT: cap->cmdchar = K_RIGHT; break;
- case K_S_LEFT: cap->cmdchar = K_LEFT; break;
- case K_S_UP: cap->cmdchar = K_UP; break;
- case K_S_DOWN: cap->cmdchar = K_DOWN; break;
- case K_S_HOME: cap->cmdchar = K_HOME; break;
- case K_S_END: cap->cmdchar = K_END; break;
+ case K_S_RIGHT:
+ cap->cmdchar = K_RIGHT; break;
+ case K_S_LEFT:
+ cap->cmdchar = K_LEFT; break;
+ case K_S_UP:
+ cap->cmdchar = K_UP; break;
+ case K_S_DOWN:
+ cap->cmdchar = K_DOWN; break;
+ case K_S_HOME:
+ cap->cmdchar = K_HOME; break;
+ case K_S_END:
+ cap->cmdchar = K_END; break;
}
cap->cmdchar = simplify_key(cap->cmdchar, &mod_mask);
}
@@ -3306,17 +3372,18 @@ static void may_clear_cmdline(void)
}
// Routines for displaying a partly typed command
-# define SHOWCMD_BUFLEN SHOWCMD_COLS + 1 + 30
+#define SHOWCMD_BUFLEN SHOWCMD_COLS + 1 + 30
static char_u showcmd_buf[SHOWCMD_BUFLEN];
-static char_u old_showcmd_buf[SHOWCMD_BUFLEN]; /* For push_showcmd() */
+static char_u old_showcmd_buf[SHOWCMD_BUFLEN]; // For push_showcmd()
static bool showcmd_is_clear = true;
static bool showcmd_visual = false;
void clear_showcmd(void)
{
- if (!p_sc)
+ if (!p_sc) {
return;
+ }
if (VIsual_active && !char_avail()) {
int cursor_bot = lt(VIsual, curwin->w_cursor);
@@ -3324,7 +3391,7 @@ void clear_showcmd(void)
colnr_T leftcol, rightcol;
linenr_T top, bot;
- /* Show the size of the Visual area. */
+ // Show the size of the Visual area.
if (cursor_bot) {
top = VIsual.lnum;
bot = curwin->w_cursor.lnum;
@@ -3338,18 +3405,21 @@ void clear_showcmd(void)
lines = bot - top + 1;
if (VIsual_mode == Ctrl_V) {
- char_u *saved_sbr = p_sbr;
+ char_u *const saved_sbr = p_sbr;
+ char_u *const saved_w_sbr = curwin->w_p_sbr;
- /* Make 'sbr' empty for a moment to get the correct size. */
+ // Make 'sbr' empty for a moment to get the correct size.
p_sbr = empty_option;
+ curwin->w_p_sbr = empty_option;
getvcols(curwin, &curwin->w_cursor, &VIsual, &leftcol, &rightcol);
p_sbr = saved_sbr;
+ curwin->w_p_sbr = saved_w_sbr;
snprintf((char *)showcmd_buf, SHOWCMD_BUFLEN, "%" PRId64 "x%" PRId64,
(int64_t)lines, (int64_t)rightcol - leftcol + 1);
} else if (VIsual_mode == 'V' || VIsual.lnum != curwin->w_cursor.lnum) {
snprintf((char *)showcmd_buf, SHOWCMD_BUFLEN, "%" PRId64, (int64_t)lines);
} else {
- char_u *s, *e;
+ char_u *s, *e;
int l;
int bytes = 0;
int chars = 0;
@@ -3366,16 +3436,17 @@ void clear_showcmd(void)
if (l == 0) {
++bytes;
++chars;
- break; /* end of line */
+ break; // end of line
}
bytes += l;
++chars;
s += l;
}
- if (bytes == chars)
+ if (bytes == chars) {
sprintf((char *)showcmd_buf, "%d", chars);
- else
+ } else {
sprintf((char *)showcmd_buf, "%d-%d", chars, bytes);
+ }
}
int limit = ui_has(kUIMessages) ? SHOWCMD_BUFLEN-1 : SHOWCMD_COLS;
showcmd_buf[limit] = NUL; // truncate
@@ -3384,9 +3455,10 @@ void clear_showcmd(void)
showcmd_buf[0] = NUL;
showcmd_visual = false;
- /* Don't actually display something if there is nothing to clear. */
- if (showcmd_is_clear)
+ // Don't actually display something if there is nothing to clear.
+ if (showcmd_is_clear) {
return;
+ }
}
display_showcmd();
@@ -3398,7 +3470,7 @@ void clear_showcmd(void)
*/
bool add_to_showcmd(int c)
{
- char_u *p;
+ char_u *p;
int i;
static int ignore[] =
{
@@ -3412,23 +3484,28 @@ bool add_to_showcmd(int c)
0
};
- if (!p_sc || msg_silent != 0)
+ if (!p_sc || msg_silent != 0) {
return false;
+ }
if (showcmd_visual) {
showcmd_buf[0] = NUL;
showcmd_visual = false;
}
- /* Ignore keys that are scrollbar updates and mouse clicks */
- if (IS_SPECIAL(c))
- for (i = 0; ignore[i] != 0; ++i)
- if (ignore[i] == c)
+ // Ignore keys that are scrollbar updates and mouse clicks
+ if (IS_SPECIAL(c)) {
+ for (i = 0; ignore[i] != 0; ++i) {
+ if (ignore[i] == c) {
return false;
+ }
+ }
+ }
p = transchar(c);
- if (*p == ' ')
+ if (*p == ' ') {
STRCPY(p, "<20>");
+ }
size_t old_len = STRLEN(showcmd_buf);
size_t extra_len = STRLEN(p);
size_t limit = ui_has(kUIMessages) ? SHOWCMD_BUFLEN-1 : SHOWCMD_COLS;
@@ -3438,8 +3515,9 @@ bool add_to_showcmd(int c)
}
STRCAT(showcmd_buf, p);
- if (char_avail())
+ if (char_avail()) {
return false;
+ }
display_showcmd();
@@ -3459,16 +3537,19 @@ static void del_from_showcmd(int len)
{
int old_len;
- if (!p_sc)
+ if (!p_sc) {
return;
+ }
old_len = (int)STRLEN(showcmd_buf);
- if (len > old_len)
+ if (len > old_len) {
len = old_len;
+ }
showcmd_buf[old_len - len] = NUL;
- if (!char_avail())
+ if (!char_avail()) {
display_showcmd();
+ }
}
/*
@@ -3477,14 +3558,16 @@ static void del_from_showcmd(int len)
*/
void push_showcmd(void)
{
- if (p_sc)
+ if (p_sc) {
STRCPY(old_showcmd_buf, showcmd_buf);
+ }
}
void pop_showcmd(void)
{
- if (!p_sc)
+ if (!p_sc) {
return;
+ }
STRCPY(showcmd_buf, old_showcmd_buf);
@@ -3533,18 +3616,18 @@ static void display_showcmd(void)
*/
void do_check_scrollbind(bool check)
{
- static win_T *old_curwin = NULL;
+ static win_T *old_curwin = NULL;
static linenr_T old_topline = 0;
static int old_topfill = 0;
- static buf_T *old_buf = NULL;
+ static buf_T *old_buf = NULL;
static colnr_T old_leftcol = 0;
if (check && curwin->w_p_scb) {
/* If a ":syncbind" command was just used, don't scroll, only reset
* the values. */
- if (did_syncbind)
+ if (did_syncbind) {
did_syncbind = false;
- else if (curwin == old_curwin) {
+ } else if (curwin == old_curwin) {
/*
* Synchronize other windows, as necessary according to
* 'scrollbind'. Don't do this after an ":edit" command, except
@@ -3557,9 +3640,9 @@ void do_check_scrollbind(bool check)
|| curwin->w_topfill != old_topfill
|| curwin->w_leftcol != old_leftcol)) {
check_scrollbind(curwin->w_topline - old_topline,
- (long)(curwin->w_leftcol - old_leftcol));
+ (long)(curwin->w_leftcol - old_leftcol));
}
- } else if (vim_strchr(p_sbo, 'j')) { /* jump flag set in 'scrollopt' */
+ } else if (vim_strchr(p_sbo, 'j')) { // jump flag set in 'scrollopt'
/*
* When switching between windows, make sure that the relative
* vertical offset is valid for the new window. The relative
@@ -3591,8 +3674,8 @@ void check_scrollbind(linenr_T topline_diff, long leftcol_diff)
{
bool want_ver;
bool want_hor;
- win_T *old_curwin = curwin;
- buf_T *old_curbuf = curbuf;
+ win_T *old_curwin = curwin;
+ buf_T *old_curbuf = curbuf;
int old_VIsual_select = VIsual_select;
int old_VIsual_active = VIsual_active;
colnr_T tgt_leftcol = curwin->w_leftcol;
@@ -3613,7 +3696,7 @@ void check_scrollbind(linenr_T topline_diff, long leftcol_diff)
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
curwin = wp;
curbuf = curwin->w_buffer;
- /* skip original window and windows with 'noscrollbind' */
+ // skip original window and windows with 'noscrollbind'
if (curwin == old_curwin || !curwin->w_p_scb) {
continue;
}
@@ -3626,16 +3709,19 @@ void check_scrollbind(linenr_T topline_diff, long leftcol_diff)
} else {
curwin->w_scbind_pos += topline_diff;
topline = curwin->w_scbind_pos;
- if (topline > curbuf->b_ml.ml_line_count)
+ if (topline > curbuf->b_ml.ml_line_count) {
topline = curbuf->b_ml.ml_line_count;
- if (topline < 1)
+ }
+ if (topline < 1) {
topline = 1;
+ }
y = topline - curwin->w_topline;
- if (y > 0)
+ if (y > 0) {
scrollup(y, false);
- else
+ } else {
scrolldown(-y, false);
+ }
}
redraw_later(curwin, VALID);
@@ -3668,7 +3754,7 @@ void check_scrollbind(linenr_T topline_diff, long leftcol_diff)
*/
static void nv_ignore(cmdarg_T *cap)
{
- cap->retval |= CA_COMMAND_BUSY; /* don't call edit() now */
+ cap->retval |= CA_COMMAND_BUSY; // don't call edit() now
}
/*
@@ -3692,8 +3778,9 @@ static void nv_error(cmdarg_T *cap)
*/
static void nv_help(cmdarg_T *cap)
{
- if (!checkclearopq(cap->oap))
+ if (!checkclearopq(cap->oap)) {
ex_help(NULL);
+ }
}
/*
@@ -3722,25 +3809,22 @@ static void nv_page(cmdarg_T *cap)
{
if (!checkclearop(cap->oap)) {
if (mod_mask & MOD_MASK_CTRL) {
- /* <C-PageUp>: tab page back; <C-PageDown>: tab page forward */
- if (cap->arg == BACKWARD)
+ // <C-PageUp>: tab page back; <C-PageDown>: tab page forward
+ if (cap->arg == BACKWARD) {
goto_tabpage(-(int)cap->count1);
- else
+ } else {
goto_tabpage((int)cap->count0);
- } else
+ }
+ } else {
(void)onepage(cap->arg, cap->count1);
+ }
}
}
-/*
- * Implementation of "gd" and "gD" command.
- */
-static void
-nv_gd (
- oparg_T *oap,
- int nchar,
- int thisblock /* 1 for "1gd" and "1gD" */
-)
+/// Implementation of "gd" and "gD" command.
+///
+/// @param thisblock 1 for "1gd" and "1gD"
+static void nv_gd(oparg_T *oap, int nchar, int thisblock)
{
size_t len;
char_u *ptr;
@@ -3785,23 +3869,17 @@ static bool is_ident(char_u *line, int offset)
return incomment == false && instring == 0;
}
-/*
- * Search for variable declaration of "ptr[len]".
- * When "locally" is true in the current function ("gd"), otherwise in the
- * current file ("gD").
- * When "thisblock" is true check the {} block scope.
- * Return fail when not found.
- */
-bool
-find_decl (
- char_u *ptr,
- size_t len,
- bool locally,
- bool thisblock,
- int flags_arg // flags passed to searchit()
-)
-{
- char_u *pat;
+/// Search for variable declaration of "ptr[len]".
+/// When "locally" is true in the current function ("gd"), otherwise in the
+/// current file ("gD").
+///
+/// @param thisblock when true check the {} block scope.
+/// @param flags_arg flags passed to searchit()
+///
+/// @return fail when not found.
+bool find_decl(char_u *ptr, size_t len, bool locally, bool thisblock, int flags_arg)
+{
+ char_u *pat;
pos_T old_pos;
pos_T par_pos;
pos_T found_pos;
@@ -3822,8 +3900,8 @@ find_decl (
old_pos = curwin->w_cursor;
save_p_ws = p_ws;
save_p_scs = p_scs;
- p_ws = false; /* don't wrap around end of file now */
- p_scs = false; /* don't switch ignorecase off now */
+ p_ws = false; // don't wrap around end of file now
+ p_scs = false; // don't switch ignorecase off now
/*
* With "gD" go to line 1.
@@ -3831,18 +3909,19 @@ find_decl (
* back until a blank line. If this fails go to line 1.
*/
if (!locally || !findpar(&incll, BACKWARD, 1L, '{', false)) {
- setpcmark(); /* Set in findpar() otherwise */
+ setpcmark(); // Set in findpar() otherwise
curwin->w_cursor.lnum = 1;
par_pos = curwin->w_cursor;
} else {
par_pos = curwin->w_cursor;
while (curwin->w_cursor.lnum > 1
- && *skipwhite(get_cursor_line_ptr()) != NUL)
+ && *skipwhite(get_cursor_line_ptr()) != NUL) {
--curwin->w_cursor.lnum;
+ }
}
curwin->w_cursor.col = 0;
- /* Search forward for the identifier, ignore comment lines. */
+ // Search forward for the identifier, ignore comment lines.
clearpos(&found_pos);
for (;; ) {
t = searchit(curwin, curbuf, &curwin->w_cursor, NULL, FORWARD,
@@ -3866,7 +3945,7 @@ find_decl (
}
if (t == false) {
- /* If we previously found a valid position, use it. */
+ // If we previously found a valid position, use it.
if (found_pos.lnum != 0) {
curwin->w_cursor = found_pos;
t = true;
@@ -3874,7 +3953,7 @@ find_decl (
break;
}
if (get_leader_len(get_cursor_line_ptr(), NULL, false, true) > 0) {
- /* Ignore this line, continue at start of next line. */
+ // Ignore this line, continue at start of next line.
++curwin->w_cursor.lnum;
curwin->w_cursor.col = 0;
continue;
@@ -3916,7 +3995,7 @@ find_decl (
curwin->w_cursor = old_pos;
} else {
curwin->w_set_curswant = true;
- /* "n" searches forward now */
+ // "n" searches forward now
reset_search_dir();
}
@@ -3940,10 +4019,10 @@ static bool nv_screengo(oparg_T *oap, int dir, long dist)
bool retval = true;
bool atend = false;
int n;
- int col_off1; /* margin offset for first screen line */
- int col_off2; /* margin offset for wrapped screen line */
- int width1; /* text width for first screen line */
- int width2; /* test width for wrapped screen line */
+ int col_off1; // margin offset for first screen line
+ int col_off2; // margin offset for wrapped screen line
+ int width1; // text width for first screen line
+ int width2; // test width for wrapped screen line
oap->motion_type = kMTCharWise;
oap->inclusive = (curwin->w_curswant == MAXCOL);
@@ -3963,20 +4042,22 @@ static bool nv_screengo(oparg_T *oap, int dir, long dist)
if (curwin->w_curswant == MAXCOL) {
atend = true;
validate_virtcol();
- if (width1 <= 0)
+ if (width1 <= 0) {
curwin->w_curswant = 0;
- else {
+ } else {
curwin->w_curswant = width1 - 1;
- if (curwin->w_virtcol > curwin->w_curswant)
+ if (curwin->w_virtcol > curwin->w_curswant) {
curwin->w_curswant += ((curwin->w_virtcol
- curwin->w_curswant -
1) / width2 + 1) * width2;
+ }
}
} else {
- if (linelen > width1)
+ if (linelen > width1) {
n = ((linelen - width1 - 1) / width2 + 1) * width2 + width1;
- else
+ } else {
n = width1;
+ }
if (curwin->w_curswant >= n) {
curwin->w_curswant = n - 1;
}
@@ -4012,11 +4093,12 @@ static bool nv_screengo(oparg_T *oap, int dir, long dist)
curwin->w_curswant += w;
}
}
- } else { /* dir == FORWARD */
- if (linelen > width1)
+ } else { // dir == FORWARD
+ if (linelen > width1) {
n = ((linelen - width1 - 1) / width2 + 1) * width2 + width1;
- else
+ } else {
n = width1;
+ }
if (curwin->w_curswant + width2 < (colnr_T)n
&& !hasFolding(curwin->w_cursor.lnum, NULL, NULL)) {
// move forward within line
@@ -4046,10 +4128,11 @@ static bool nv_screengo(oparg_T *oap, int dir, long dist)
}
}
- if (virtual_active() && atend)
+ if (virtual_active() && atend) {
coladvance(MAXCOL);
- else
+ } else {
coladvance(curwin->w_curswant);
+ }
if (curwin->w_cursor.col > 0 && curwin->w_p_wrap) {
/*
@@ -4059,20 +4142,22 @@ static bool nv_screengo(oparg_T *oap, int dir, long dist)
*/
validate_virtcol();
colnr_T virtcol = curwin->w_virtcol;
- if (virtcol > (colnr_T)width1 && *p_sbr != NUL)
- virtcol -= vim_strsize(p_sbr);
+ if (virtcol > (colnr_T)width1 && *get_showbreak_value(curwin) != NUL) {
+ virtcol -= vim_strsize(get_showbreak_value(curwin));
+ }
if (virtcol > curwin->w_curswant
&& (curwin->w_curswant < (colnr_T)width1
? (curwin->w_curswant > (colnr_T)width1 / 2)
: ((curwin->w_curswant - width1) % width2
- > (colnr_T)width2 / 2)))
+ > (colnr_T)width2 / 2))) {
--curwin->w_cursor.col;
+ }
}
- if (atend)
- curwin->w_curswant = MAXCOL; /* stick in the last column */
-
+ if (atend) {
+ curwin->w_curswant = MAXCOL; // stick in the last column
+ }
return retval;
}
@@ -4137,8 +4222,9 @@ static void nv_mouse(cmdarg_T *cap)
*/
static void nv_scroll_line(cmdarg_T *cap)
{
- if (!checkclearop(cap->oap))
+ if (!checkclearop(cap->oap)) {
scroll_redraw(cap->arg, cap->count1);
+ }
}
/*
@@ -4151,8 +4237,8 @@ void scroll_redraw(int up, long count)
linenr_T prev_lnum = curwin->w_cursor.lnum;
bool moved = up ?
- scrollup(count, true) :
- scrolldown(count, true);
+ scrollup(count, true) :
+ scrolldown(count, true);
if (get_scrolloff_value(curwin)) {
// Adjust the cursor position for 'scrolloff'. Mark w_topline as
@@ -4165,17 +4251,18 @@ void scroll_redraw(int up, long count)
* we get stuck at one position. Don't move the cursor up if the
* first line of the buffer is already on the screen */
while (curwin->w_topline == prev_topline
- && curwin->w_topfill == prev_topfill
- ) {
+ && curwin->w_topfill == prev_topfill) {
if (up) {
if (curwin->w_cursor.lnum > prev_lnum
- || cursor_down(1L, false) == false)
+ || cursor_down(1L, false) == false) {
break;
+ }
} else {
if (curwin->w_cursor.lnum < prev_lnum
|| prev_topline == 1L
- || cursor_up(1L, false) == false)
+ || cursor_up(1L, false) == false) {
break;
+ }
}
/* Mark w_topline as valid, otherwise the screen jumps back at the
* end of the file. */
@@ -4211,8 +4298,9 @@ static void nv_zet(cmdarg_T *cap)
/*
* "z123{nchar}": edit the count before obtaining {nchar}
*/
- if (checkclearop(cap->oap))
+ if (checkclearop(cap->oap)) {
return;
+ }
n = nchar - '0';
for (;; ) {
no_mapping++;
@@ -4220,11 +4308,11 @@ static void nv_zet(cmdarg_T *cap)
LANGMAP_ADJUST(nchar, true);
no_mapping--;
(void)add_to_showcmd(nchar);
- if (nchar == K_DEL || nchar == K_KDEL)
+ if (nchar == K_DEL || nchar == K_KDEL) {
n /= 10;
- else if (ascii_isdigit(nchar))
+ } else if (ascii_isdigit(nchar)) {
n = n * 10 + (nchar - '0');
- else if (nchar == CAR) {
+ } else if (nchar == CAR) {
win_setheight(n);
break;
} else if (nchar == 'l'
@@ -4261,15 +4349,16 @@ dozet:
&& cap->count0
&& cap->count0 != curwin->w_cursor.lnum) {
setpcmark();
- if (cap->count0 > curbuf->b_ml.ml_line_count)
+ if (cap->count0 > curbuf->b_ml.ml_line_count) {
curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
- else
+ } else {
curwin->w_cursor.lnum = cap->count0;
+ }
check_cursor_col();
}
switch (nchar) {
- /* "z+", "z<CR>" and "zt": put cursor at top of screen */
+ // "z+", "z<CR>" and "zt": put cursor at top of screen
case '+':
if (cap->count0 == 0) {
// No count given: put cursor at the line below screen
@@ -4287,16 +4376,19 @@ dozet:
beginline(BL_WHITE | BL_FIX);
FALLTHROUGH;
- case 't': scroll_cursor_top(0, true);
+ case 't':
+ scroll_cursor_top(0, true);
redraw_later(curwin, VALID);
set_fraction(curwin);
break;
- /* "z." and "zz": put cursor in middle of screen */
- case '.': beginline(BL_WHITE | BL_FIX);
- FALLTHROUGH;
+ // "z." and "zz": put cursor in middle of screen
+ case '.':
+ beginline(BL_WHITE | BL_FIX);
+ FALLTHROUGH;
- case 'z': scroll_cursor_halfway(true);
+ case 'z':
+ scroll_cursor_halfway(true);
redraw_later(curwin, VALID);
set_fraction(curwin);
break;
@@ -4308,74 +4400,83 @@ dozet:
if (cap->count0 != 0) {
scroll_cursor_bot(0, true);
curwin->w_cursor.lnum = curwin->w_topline;
- } else if (curwin->w_topline == 1)
+ } else if (curwin->w_topline == 1) {
curwin->w_cursor.lnum = 1;
- else
+ } else {
curwin->w_cursor.lnum = curwin->w_topline - 1;
+ }
FALLTHROUGH;
case '-':
beginline(BL_WHITE | BL_FIX);
FALLTHROUGH;
- case 'b': scroll_cursor_bot(0, true);
+ case 'b':
+ scroll_cursor_bot(0, true);
redraw_later(curwin, VALID);
set_fraction(curwin);
break;
- /* "zH" - scroll screen right half-page */
+ // "zH" - scroll screen right half-page
case 'H':
cap->count1 *= curwin->w_width_inner / 2;
FALLTHROUGH;
- /* "zh" - scroll screen to the right */
+ // "zh" - scroll screen to the right
case 'h':
case K_LEFT:
if (!curwin->w_p_wrap) {
- if ((colnr_T)cap->count1 > curwin->w_leftcol)
+ if ((colnr_T)cap->count1 > curwin->w_leftcol) {
curwin->w_leftcol = 0;
- else
+ } else {
curwin->w_leftcol -= (colnr_T)cap->count1;
+ }
leftcol_changed();
}
break;
// "zL" - scroll screen left half-page
- case 'L': cap->count1 *= curwin->w_width_inner / 2;
+ case 'L':
+ cap->count1 *= curwin->w_width_inner / 2;
FALLTHROUGH;
- /* "zl" - scroll screen to the left */
+ // "zl" - scroll screen to the left
case 'l':
case K_RIGHT:
if (!curwin->w_p_wrap) {
- /* scroll the window left */
+ // scroll the window left
curwin->w_leftcol += (colnr_T)cap->count1;
leftcol_changed();
}
break;
- /* "zs" - scroll screen, cursor at the start */
- case 's': if (!curwin->w_p_wrap) {
- if (hasFolding(curwin->w_cursor.lnum, NULL, NULL))
- col = 0; /* like the cursor is in col 0 */
- else
+ // "zs" - scroll screen, cursor at the start
+ case 's':
+ if (!curwin->w_p_wrap) {
+ if (hasFolding(curwin->w_cursor.lnum, NULL, NULL)) {
+ col = 0; // like the cursor is in col 0
+ } else {
getvcol(curwin, &curwin->w_cursor, &col, NULL, NULL);
- if (col > l_p_siso)
+ }
+ if (col > l_p_siso) {
col -= l_p_siso;
- else
+ } else {
col = 0;
+ }
if (curwin->w_leftcol != col) {
curwin->w_leftcol = col;
redraw_later(curwin, NOT_VALID);
}
- }
+ }
break;
- /* "ze" - scroll screen, cursor at the end */
- case 'e': if (!curwin->w_p_wrap) {
- if (hasFolding(curwin->w_cursor.lnum, NULL, NULL))
- col = 0; /* like the cursor is in col 0 */
- else
+ // "ze" - scroll screen, cursor at the end
+ case 'e':
+ if (!curwin->w_p_wrap) {
+ if (hasFolding(curwin->w_cursor.lnum, NULL, NULL)) {
+ col = 0; // like the cursor is in col 0
+ } else {
getvcol(curwin, &curwin->w_cursor, NULL, NULL, &col);
+ }
n = curwin->w_width_inner - curwin_col_off();
if (col + l_p_siso < n) {
col = 0;
@@ -4386,7 +4487,7 @@ dozet:
curwin->w_leftcol = col;
redraw_later(curwin, NOT_VALID);
}
- }
+ }
break;
// "zp", "zP" in block mode put without addind trailing spaces
@@ -4395,41 +4496,46 @@ dozet:
nv_put(cap);
break;
// "zy" Yank without trailing spaces
- case 'y': nv_operator(cap);
- break;
+ case 'y':
+ nv_operator(cap);
+ break;
- /* "zF": create fold command */
- /* "zf": create fold operator */
+ // "zF": create fold command
+ // "zf": create fold operator
case 'F':
- case 'f': if (foldManualAllowed(true)) {
+ case 'f':
+ if (foldManualAllowed(true)) {
cap->nchar = 'f';
nv_operator(cap);
curwin->w_p_fen = true;
- /* "zF" is like "zfzf" */
+ // "zF" is like "zfzf"
if (nchar == 'F' && cap->oap->op_type == OP_FOLD) {
nv_operator(cap);
finish_op = true;
}
- } else
+ } else {
clearopbeep(cap->oap);
+ }
break;
- /* "zd": delete fold at cursor */
- /* "zD": delete fold at cursor recursively */
+ // "zd": delete fold at cursor
+ // "zD": delete fold at cursor recursively
case 'd':
- case 'D': if (foldManualAllowed(false)) {
+ case 'D':
+ if (foldManualAllowed(false)) {
if (VIsual_active) {
nv_operator(cap);
} else {
deleteFold(curwin, curwin->w_cursor.lnum,
curwin->w_cursor.lnum, nchar == 'D', false);
}
- }
+ }
break;
- /* "zE": erase all folds */
- case 'E': if (foldmethodIsManual(curwin)) {
+ // "zE": erase all folds
+ case 'E':
+ if (foldmethodIsManual(curwin)) {
clearFolding(curwin);
changed_window_setting();
} else if (foldmethodIsMarker(curwin)) {
@@ -4439,20 +4545,24 @@ dozet:
}
break;
- /* "zn": fold none: reset 'foldenable' */
- case 'n': curwin->w_p_fen = false;
+ // "zn": fold none: reset 'foldenable'
+ case 'n':
+ curwin->w_p_fen = false;
break;
- /* "zN": fold Normal: set 'foldenable' */
- case 'N': curwin->w_p_fen = true;
+ // "zN": fold Normal: set 'foldenable'
+ case 'N':
+ curwin->w_p_fen = true;
break;
- /* "zi": invert folding: toggle 'foldenable' */
- case 'i': curwin->w_p_fen = !curwin->w_p_fen;
+ // "zi": invert folding: toggle 'foldenable'
+ case 'i':
+ curwin->w_p_fen = !curwin->w_p_fen;
break;
// "za": open closed fold or close open fold at cursor
- case 'a': if (hasFolding(curwin->w_cursor.lnum, NULL, NULL)) {
+ case 'a':
+ if (hasFolding(curwin->w_cursor.lnum, NULL, NULL)) {
openFold(curwin->w_cursor, cap->count1);
} else {
closeFold(curwin->w_cursor, cap->count1);
@@ -4461,7 +4571,8 @@ dozet:
break;
// "zA": open fold at cursor recursively
- case 'A': if (hasFolding(curwin->w_cursor.lnum, NULL, NULL)) {
+ case 'A':
+ if (hasFolding(curwin->w_cursor.lnum, NULL, NULL)) {
openFoldRecurse(curwin->w_cursor);
} else {
closeFoldRecurse(curwin->w_cursor);
@@ -4470,7 +4581,8 @@ dozet:
break;
// "zo": open fold at cursor or Visual area
- case 'o': if (VIsual_active) {
+ case 'o':
+ if (VIsual_active) {
nv_operator(cap);
} else {
openFold(curwin->w_cursor, cap->count1);
@@ -4478,7 +4590,8 @@ dozet:
break;
// "zO": open fold recursively
- case 'O': if (VIsual_active) {
+ case 'O':
+ if (VIsual_active) {
nv_operator(cap);
} else {
openFoldRecurse(curwin->w_cursor);
@@ -4486,16 +4599,18 @@ dozet:
break;
// "zc": close fold at cursor or Visual area
- case 'c': if (VIsual_active) {
+ case 'c':
+ if (VIsual_active) {
nv_operator(cap);
- } else {
+ } else {
closeFold(curwin->w_cursor, cap->count1);
}
curwin->w_p_fen = true;
break;
// "zC": close fold recursively
- case 'C': if (VIsual_active) {
+ case 'C':
+ if (VIsual_active) {
nv_operator(cap);
} else {
closeFoldRecurse(curwin->w_cursor);
@@ -4503,24 +4618,27 @@ dozet:
curwin->w_p_fen = true;
break;
- /* "zv": open folds at the cursor */
- case 'v': foldOpenCursor();
+ // "zv": open folds at the cursor
+ case 'v':
+ foldOpenCursor();
break;
- /* "zx": re-apply 'foldlevel' and open folds at the cursor */
- case 'x': curwin->w_p_fen = true;
- curwin->w_foldinvalid = true; /* recompute folds */
- newFoldLevel(); /* update right now */
+ // "zx": re-apply 'foldlevel' and open folds at the cursor
+ case 'x':
+ curwin->w_p_fen = true;
+ curwin->w_foldinvalid = true; // recompute folds
+ newFoldLevel(); // update right now
foldOpenCursor();
break;
- /* "zX": undo manual opens/closes, re-apply 'foldlevel' */
- case 'X': curwin->w_p_fen = true;
- curwin->w_foldinvalid = true; /* recompute folds */
- old_fdl = -1; /* force an update */
+ // "zX": undo manual opens/closes, re-apply 'foldlevel'
+ case 'X':
+ curwin->w_p_fen = true;
+ curwin->w_foldinvalid = true; // recompute folds
+ old_fdl = -1; // force an update
break;
- /* "zm": fold more */
+ // "zm": fold more
case 'm':
if (curwin->w_p_fdl > 0) {
curwin->w_p_fdl -= cap->count1;
@@ -4528,17 +4646,18 @@ dozet:
curwin->w_p_fdl = 0;
}
}
- old_fdl = -1; /* force an update */
+ old_fdl = -1; // force an update
curwin->w_p_fen = true;
break;
- /* "zM": close all folds */
- case 'M': curwin->w_p_fdl = 0;
- old_fdl = -1; /* force an update */
+ // "zM": close all folds
+ case 'M':
+ curwin->w_p_fdl = 0;
+ old_fdl = -1; // force an update
curwin->w_p_fen = true;
break;
- /* "zr": reduce folding */
+ // "zr": reduce folding
case 'r':
curwin->w_p_fdl += cap->count1;
{
@@ -4554,11 +4673,12 @@ dozet:
old_fdl = -1; // force an update
break;
- case 'j': /* "zj" move to next fold downwards */
- case 'k': /* "zk" move to next fold upwards */
+ case 'j': // "zj" move to next fold downwards
+ case 'k': // "zk" move to next fold upwards
if (foldMoveTo(true, nchar == 'j' ? FORWARD : BACKWARD,
- cap->count1) == false)
+ cap->count1) == false) {
clearopbeep(cap->oap);
+ }
break;
@@ -4575,18 +4695,20 @@ dozet:
undo = true;
FALLTHROUGH;
- case 'g': /* "zg": add good word to word list */
- case 'w': /* "zw": add wrong word to word list */
- case 'G': /* "zG": add good word to temp word list */
- case 'W': /* "zW": add wrong word to temp word list */
+ case 'g': // "zg": add good word to word list
+ case 'w': // "zw": add wrong word to word list
+ case 'G': // "zG": add good word to temp word list
+ case 'W': // "zW": add wrong word to temp word list
{
- char_u *ptr = NULL;
+ char_u *ptr = NULL;
size_t len;
- if (checkclearop(cap->oap))
+ if (checkclearop(cap->oap)) {
break;
- if (VIsual_active && !get_visual_text(cap, &ptr, &len))
+ }
+ if (VIsual_active && !get_visual_text(cap, &ptr, &len)) {
return;
+ }
if (ptr == NULL) {
pos_T pos = curwin->w_cursor;
@@ -4596,13 +4718,15 @@ dozet:
emsg_off++;
len = spell_move_to(curwin, FORWARD, true, true, NULL);
emsg_off--;
- if (len != 0 && curwin->w_cursor.col <= pos.col)
+ if (len != 0 && curwin->w_cursor.col <= pos.col) {
ptr = ml_get_pos(&curwin->w_cursor);
+ }
curwin->w_cursor = pos;
}
- if (ptr == NULL && (len = find_ident_under_cursor(&ptr, FIND_IDENT)) == 0)
+ if (ptr == NULL && (len = find_ident_under_cursor(&ptr, FIND_IDENT)) == 0) {
return;
+ }
assert(len <= INT_MAX);
spell_add_word(ptr, (int)len,
nchar == 'w' || nchar == 'W'
@@ -4612,18 +4736,20 @@ dozet:
}
break;
- case '=': /* "z=": suggestions for a badly spelled word */
- if (!checkclearop(cap->oap))
+ case '=': // "z=": suggestions for a badly spelled word
+ if (!checkclearop(cap->oap)) {
spell_suggest((int)cap->count0);
+ }
break;
- default: clearopbeep(cap->oap);
+ default:
+ clearopbeep(cap->oap);
}
- /* Redraw when 'foldenable' changed */
+ // Redraw when 'foldenable' changed
if (old_fen != curwin->w_p_fen) {
if (foldmethodIsDiff(curwin) && curwin->w_p_scb) {
- /* Adjust 'foldenable' in diff-synced windows. */
+ // Adjust 'foldenable' in diff-synced windows.
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
if (wp != curwin && foldmethodIsDiff(wp) && wp->w_p_scb) {
wp->w_p_fen = curwin->w_p_fen;
@@ -4634,9 +4760,10 @@ dozet:
changed_window_setting();
}
- /* Redraw when 'foldlevel' changed. */
- if (old_fdl != curwin->w_p_fdl)
+ // Redraw when 'foldlevel' changed.
+ if (old_fdl != curwin->w_p_fdl) {
newFoldLevel();
+ }
}
@@ -4652,7 +4779,7 @@ static void nv_exmode(cmdarg_T *cap)
if (VIsual_active) {
vim_beep(BO_EX);
} else if (!checkclearop(cap->oap)) {
- do_exmode(false);
+ do_exmode();
}
}
@@ -4679,9 +4806,10 @@ static void nv_colon(cmdarg_T *cap)
}
}
- /* When typing, don't type below an old message */
- if (KeyTyped)
+ // When typing, don't type below an old message
+ if (KeyTyped) {
compute_cmdrow();
+ }
old_p_im = p_im;
@@ -4689,26 +4817,28 @@ static void nv_colon(cmdarg_T *cap)
cmd_result = do_cmdline(NULL, is_cmdkey ? getcmdkeycmd : getexline, NULL,
cap->oap->op_type != OP_NOP ? DOCMD_KEEPLINE : 0);
- /* If 'insertmode' changed, enter or exit Insert mode */
+ // If 'insertmode' changed, enter or exit Insert mode
if (p_im != old_p_im) {
- if (p_im)
+ if (p_im) {
restart_edit = 'i';
- else
+ } else {
restart_edit = 0;
+ }
}
- if (cmd_result == false)
- /* The Ex command failed, do not execute the operator. */
+ if (cmd_result == false) {
+ // The Ex command failed, do not execute the operator.
clearop(cap->oap);
- else if (cap->oap->op_type != OP_NOP
- && (cap->oap->start.lnum > curbuf->b_ml.ml_line_count
- || cap->oap->start.col >
- (colnr_T)STRLEN(ml_get(cap->oap->start.lnum))
- || did_emsg
- ))
+ } else if (cap->oap->op_type != OP_NOP
+ && (cap->oap->start.lnum > curbuf->b_ml.ml_line_count
+ || cap->oap->start.col >
+ (colnr_T)STRLEN(ml_get(cap->oap->start.lnum))
+ || did_emsg
+ )) {
/* The start of the operator has become invalid by the Ex command.
*/
clearopbeep(cap->oap);
+ }
}
}
@@ -4717,12 +4847,13 @@ static void nv_colon(cmdarg_T *cap)
*/
static void nv_ctrlg(cmdarg_T *cap)
{
- if (VIsual_active) { /* toggle Selection/Visual mode */
+ if (VIsual_active) { // toggle Selection/Visual mode
VIsual_select = !VIsual_select;
showmode();
- } else if (!checkclearop(cap->oap))
- /* print full name if count given or :cd used */
+ } else if (!checkclearop(cap->oap)) {
+ // print full name if count given or :cd used
fileinfo((int)cap->count0, false, true);
+ }
}
/*
@@ -4731,10 +4862,11 @@ static void nv_ctrlg(cmdarg_T *cap)
static void nv_ctrlh(cmdarg_T *cap)
{
if (VIsual_active && VIsual_select) {
- cap->cmdchar = 'x'; /* BS key behaves like 'x' in Select mode */
+ cap->cmdchar = 'x'; // BS key behaves like 'x' in Select mode
v_visop(cap);
- } else
+ } else {
nv_left(cap);
+ }
}
/*
@@ -4743,7 +4875,7 @@ static void nv_ctrlh(cmdarg_T *cap)
static void nv_clear(cmdarg_T *cap)
{
if (!checkclearop(cap->oap)) {
- /* Clear all syntax states to force resyncing. */
+ // Clear all syntax states to force resyncing.
syn_stack_free_all(curwin->w_s);
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
wp->w_s->b_syn_slow = false;
@@ -4761,7 +4893,7 @@ static void nv_ctrlo(cmdarg_T *cap)
if (VIsual_active && VIsual_select) {
VIsual_select = false;
showmode();
- restart_VIsual_select = 2; /* restart Select mode later */
+ restart_VIsual_select = 2; // restart Select mode later
} else {
cap->count1 = -cap->count1;
nv_pcmark(cap);
@@ -4772,9 +4904,10 @@ static void nv_ctrlo(cmdarg_T *cap)
// not named.
static void nv_hat(cmdarg_T *cap)
{
- if (!checkclearopq(cap->oap))
+ if (!checkclearopq(cap->oap)) {
(void)buflist_getfile((int)cap->count0, (linenr_T)0,
- GETF_SETMARK|GETF_ALT, false);
+ GETF_SETMARK|GETF_ALT, false);
+ }
}
/*
@@ -4784,15 +4917,18 @@ static void nv_Zet(cmdarg_T *cap)
{
if (!checkclearopq(cap->oap)) {
switch (cap->nchar) {
- /* "ZZ": equivalent to ":x". */
- case 'Z': do_cmdline_cmd("x");
+ // "ZZ": equivalent to ":x".
+ case 'Z':
+ do_cmdline_cmd("x");
break;
- /* "ZQ": equivalent to ":q!" (Elvis compatible). */
- case 'Q': do_cmdline_cmd("q!");
+ // "ZQ": equivalent to ":q!" (Elvis compatible).
+ case 'Q':
+ do_cmdline_cmd("q!");
break;
- default: clearopbeep(cap->oap);
+ default:
+ clearopbeep(cap->oap);
}
}
}
@@ -4815,23 +4951,23 @@ void do_nv_ident(int c1, int c2)
/*
* Handle the commands that use the word under the cursor.
- * [g] CTRL-] :ta to current identifier
- * [g] 'K' run program for current identifier
- * [g] '*' / to current identifier or string
- * [g] '#' ? to current identifier or string
- * g ']' :tselect for current identifier
+ * [g] CTRL-] :ta to current identifier
+ * [g] 'K' run program for current identifier
+ * [g] '*' / to current identifier or string
+ * [g] '#' ? to current identifier or string
+ * g ']' :tselect for current identifier
*/
static void nv_ident(cmdarg_T *cap)
{
- char_u *ptr = NULL;
- char_u *p;
- size_t n = 0; /* init for GCC */
+ char_u *ptr = NULL;
+ char_u *p;
+ size_t n = 0; // init for GCC
int cmdchar;
- bool g_cmd; /* "g" command */
+ bool g_cmd; // "g" command
bool tag_cmd = false;
- char_u *aux_ptr;
+ char_u *aux_ptr;
- if (cap->cmdchar == 'g') { /* "g*", "g#", "g]" and "gCTRL-]" */
+ if (cap->cmdchar == 'g') { // "g*", "g#", "g]" and "gCTRL-]"
cmdchar = cap->nchar;
g_cmd = true;
} else {
@@ -4839,17 +4975,20 @@ static void nv_ident(cmdarg_T *cap)
g_cmd = false;
}
- if (cmdchar == POUND) /* the pound sign, '#' for English keyboards */
+ if (cmdchar == POUND) { // the pound sign, '#' for English keyboards
cmdchar = '#';
+ }
/*
* The "]", "CTRL-]" and "K" commands accept an argument in Visual mode.
*/
if (cmdchar == ']' || cmdchar == Ctrl_RSB || cmdchar == 'K') {
- if (VIsual_active && get_visual_text(cap, &ptr, &n) == false)
+ if (VIsual_active && get_visual_text(cap, &ptr, &n) == false) {
return;
- if (checkclearopq(cap->oap))
+ }
+ if (checkclearopq(cap->oap)) {
return;
+ }
}
if (ptr == NULL && (n = find_ident_under_cursor(&ptr,
@@ -4886,11 +5025,12 @@ static void nv_ident(cmdarg_T *cap)
* it was.
*/
setpcmark();
- curwin->w_cursor.col = (colnr_T) (ptr - get_cursor_line_ptr());
+ curwin->w_cursor.col = (colnr_T)(ptr - get_cursor_line_ptr());
- if (!g_cmd && vim_iswordp(ptr))
+ if (!g_cmd && vim_iswordp(ptr)) {
STRCPY(buf, "\\<");
- no_smartcase = true; /* don't use 'smartcase' now */
+ }
+ no_smartcase = true; // don't use 'smartcase' now
break;
case 'K':
@@ -4910,7 +5050,7 @@ static void nv_ident(cmdarg_T *cap)
--n;
}
if (n == 0) {
- EMSG(_(e_noident)); /* found dashes only */
+ EMSG(_(e_noident)); // found dashes only
xfree(buf);
return;
}
@@ -4923,7 +5063,8 @@ static void nv_ident(cmdarg_T *cap)
snprintf(buf, buf_size, ".,.+%" PRId64, (int64_t)(cap->count0 - 1));
}
- STRCAT(buf, "! ");
+ do_cmdline_cmd("tabnew");
+ STRCAT(buf, "terminal ");
if (cap->count0 == 0 && isman_s) {
STRCAT(buf, "man");
} else {
@@ -4932,7 +5073,7 @@ static void nv_ident(cmdarg_T *cap)
STRCAT(buf, " ");
if (cap->count0 != 0 && (isman || isman_s)) {
snprintf(buf + STRLEN(buf), buf_size - STRLEN(buf), "%" PRId64,
- (int64_t)cap->count0);
+ (int64_t)cap->count0);
STRCAT(buf, " ");
}
}
@@ -4940,21 +5081,23 @@ static void nv_ident(cmdarg_T *cap)
case ']':
tag_cmd = true;
- if (p_cst)
+ if (p_cst) {
STRCPY(buf, "cstag ");
- else
+ } else {
STRCPY(buf, "ts ");
+ }
break;
default:
tag_cmd = true;
- if (curbuf->b_help)
+ if (curbuf->b_help) {
STRCPY(buf, "he! ");
- else {
- if (g_cmd)
+ } else {
+ if (g_cmd) {
STRCPY(buf, "tj ");
- else
+ } else {
snprintf(buf, buf_size, "%" PRId64 "ta ", (int64_t)cap->count0);
+ }
}
}
@@ -4974,24 +5117,27 @@ static void nv_ident(cmdarg_T *cap)
STRCAT(buf, p);
xfree(p);
} else {
- if (cmdchar == '*')
+ if (cmdchar == '*') {
aux_ptr = (char_u *)(p_magic ? "/.*~[^$\\" : "/^$\\");
- else if (cmdchar == '#')
+ } else if (cmdchar == '#') {
aux_ptr = (char_u *)(p_magic ? "/?.*~[^$\\" : "/?^$\\");
- else if (tag_cmd) {
- if (curbuf->b_help)
- /* ":help" handles unescaped argument */
+ } else if (tag_cmd) {
+ if (curbuf->b_help) {
+ // ":help" handles unescaped argument
aux_ptr = (char_u *)"";
- else
+ } else {
aux_ptr = (char_u *)"\\|\"\n[";
- } else
+ }
+ } else {
aux_ptr = (char_u *)"\\|\"\n*?[";
+ }
p = (char_u *)buf + STRLEN(buf);
while (n-- > 0) {
- /* put a backslash before \ and some others */
- if (vim_strchr(aux_ptr, *ptr) != NULL)
+ // put a backslash before \ and some others
+ if (vim_strchr(aux_ptr, *ptr) != NULL) {
*p++ = '\\';
+ }
/* When current byte is a part of multibyte character, copy all
* bytes of that character. */
const size_t len = (size_t)(utfc_ptr2len(ptr) - 1);
@@ -5020,27 +5166,37 @@ static void nv_ident(cmdarg_T *cap)
g_tag_at_cursor = true;
do_cmdline_cmd(buf);
g_tag_at_cursor = false;
+
+ if (cmdchar == 'K' && !kp_ex && !kp_help) {
+ // Start insert mode in terminal buffer
+ restart_edit = 'i';
+
+ add_map((char_u *)"<buffer> <esc> <Cmd>call jobstop(&channel)<CR>", TERM_FOCUS, true);
+ do_cmdline_cmd("autocmd TermClose <buffer> "
+ " if !v:event.status |"
+ " exec 'bdelete! ' .. expand('<abuf>') |"
+ " endif");
+ }
}
xfree(buf);
}
-/*
- * Get visually selected text, within one line only.
- * Returns false if more than one line selected.
- */
-bool
-get_visual_text (
- cmdarg_T *cap,
- char_u **pp, /* return: start of selected text */
- size_t *lenp /* return: length of selected text */
-)
-{
- if (VIsual_mode != 'V')
+/// Get visually selected text, within one line only.
+///
+/// @param pp return: start of selected text
+/// @param lenp return: length of selected text
+///
+/// @return false if more than one line selected.
+bool get_visual_text(cmdarg_T *cap, char_u **pp, size_t *lenp)
+{
+ if (VIsual_mode != 'V') {
unadjust_for_sel();
+ }
if (VIsual.lnum != curwin->w_cursor.lnum) {
- if (cap != NULL)
+ if (cap != NULL) {
clearopbeep(cap->oap);
+ }
return false;
}
if (VIsual_mode == 'V') {
@@ -5066,8 +5222,9 @@ get_visual_text (
*/
static void nv_tagpop(cmdarg_T *cap)
{
- if (!checkclearopq(cap->oap))
+ if (!checkclearopq(cap->oap)) {
do_tag((char_u *)"", DT_POP, (int)cap->count1, false, true);
+ }
}
/*
@@ -5086,40 +5243,42 @@ static void nv_scroll(cmdarg_T *cap)
if (cap->cmdchar == 'L') {
validate_botline(curwin); // make sure curwin->w_botline is valid
curwin->w_cursor.lnum = curwin->w_botline - 1;
- if (cap->count1 - 1 >= curwin->w_cursor.lnum)
+ if (cap->count1 - 1 >= curwin->w_cursor.lnum) {
curwin->w_cursor.lnum = 1;
- else {
+ } else {
if (hasAnyFolding(curwin)) {
- /* Count a fold for one screen line. */
+ // Count a fold for one screen line.
for (n = cap->count1 - 1; n > 0
&& curwin->w_cursor.lnum > curwin->w_topline; --n) {
(void)hasFolding(curwin->w_cursor.lnum,
- &curwin->w_cursor.lnum, NULL);
+ &curwin->w_cursor.lnum, NULL);
--curwin->w_cursor.lnum;
}
- } else
+ } else {
curwin->w_cursor.lnum -= cap->count1 - 1;
+ }
}
} else {
if (cap->cmdchar == 'M') {
- /* Don't count filler lines above the window. */
- used -= diff_check_fill(curwin, curwin->w_topline)
+ // Don't count filler lines above the window.
+ used -= win_get_fill(curwin, curwin->w_topline)
- curwin->w_topfill;
validate_botline(curwin); // make sure w_empty_rows is valid
half = (curwin->w_height_inner - curwin->w_empty_rows + 1) / 2;
for (n = 0; curwin->w_topline + n < curbuf->b_ml.ml_line_count; n++) {
// Count half he number of filler lines to be "below this
// line" and half to be "above the next line".
- if (n > 0 && used + diff_check_fill(curwin, curwin->w_topline
- + n) / 2 >= half) {
- --n;
+ if (n > 0 && used + win_get_fill(curwin, curwin->w_topline + n) / 2 >= half) {
+ n--;
break;
}
- used += plines(curwin->w_topline + n);
- if (used >= half)
+ used += plines_win(curwin, curwin->w_topline + n, true);
+ if (used >= half) {
break;
- if (hasFolding(curwin->w_topline + n, NULL, &lnum))
+ }
+ if (hasFolding(curwin->w_topline + n, NULL, &lnum)) {
n = lnum - curwin->w_topline;
+ }
}
if (n > 0 && used > curwin->w_height_inner) {
n--;
@@ -5127,7 +5286,7 @@ static void nv_scroll(cmdarg_T *cap)
} else { // (cap->cmdchar == 'H')
n = cap->count1 - 1;
if (hasAnyFolding(curwin)) {
- /* Count a fold for one screen line. */
+ // Count a fold for one screen line.
lnum = curwin->w_topline;
while (n-- > 0 && lnum < curwin->w_botline - 1) {
(void)hasFolding(lnum, NULL, &lnum);
@@ -5137,8 +5296,9 @@ static void nv_scroll(cmdarg_T *cap)
}
}
curwin->w_cursor.lnum = curwin->w_topline + n;
- if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
+ if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count) {
curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+ }
}
// Correct for 'so', except when an operator is pending.
@@ -5157,9 +5317,10 @@ static void nv_right(cmdarg_T *cap)
int PAST_LINE;
if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) {
- /* <C-Right> and <S-Right> move a word or WORD right */
- if (mod_mask & MOD_MASK_CTRL)
+ // <C-Right> and <S-Right> move a word or WORD right
+ if (mod_mask & MOD_MASK_CTRL) {
cap->arg = true;
+ }
nv_wordcmd(cap);
return;
}
@@ -5172,13 +5333,14 @@ static void nv_right(cmdarg_T *cap)
* In virtual mode, there's no such thing as "PAST_LINE", as lines are
* (theoretically) infinitely long.
*/
- if (virtual_active())
+ if (virtual_active()) {
PAST_LINE = 0;
+ }
for (n = cap->count1; n > 0; --n) {
if ((!PAST_LINE && oneright() == false)
- || (PAST_LINE && *get_cursor_pos_ptr() == NUL)
- ) {
+ || (PAST_LINE &&
+ *get_cursor_pos_ptr() == NUL)) {
// <Space> wraps to next line if 'whichwrap' has 's'.
// 'l' wraps to next line if 'whichwrap' has 'l'.
// CURS_RIGHT wraps to next line if 'whichwrap' has '>'.
@@ -5223,8 +5385,9 @@ static void nv_right(cmdarg_T *cap)
}
}
if (n != cap->count1 && (fdo_flags & FDO_HOR) && KeyTyped
- && cap->oap->op_type == OP_NOP)
+ && cap->oap->op_type == OP_NOP) {
foldOpenCursor();
+ }
}
/*
@@ -5237,9 +5400,10 @@ static void nv_left(cmdarg_T *cap)
long n;
if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) {
- /* <C-Left> and <S-Left> move a word or WORD left */
- if (mod_mask & MOD_MASK_CTRL)
+ // <C-Left> and <S-Left> move a word or WORD left
+ if (mod_mask & MOD_MASK_CTRL) {
cap->arg = 1;
+ }
nv_bck_word(cap);
return;
}
@@ -5249,8 +5413,8 @@ static void nv_left(cmdarg_T *cap)
for (n = cap->count1; n > 0; --n) {
if (oneleft() == false) {
/* <BS> and <Del> wrap to previous line if 'whichwrap' has 'b'.
- * 'h' wraps to previous line if 'whichwrap' has 'h'.
- * CURS_LEFT wraps to previous line if 'whichwrap' has '<'.
+ * 'h' wraps to previous line if 'whichwrap' has 'h'.
+ * CURS_LEFT wraps to previous line if 'whichwrap' has '<'.
*/
if ((((cap->cmdchar == K_BS || cap->cmdchar == Ctrl_H)
&& vim_strchr(p_ww, 'b') != NULL)
@@ -5276,15 +5440,17 @@ static void nv_left(cmdarg_T *cap)
}
continue;
}
- /* Only beep and flush if not moved at all */
- else if (cap->oap->op_type == OP_NOP && n == cap->count1)
+ // Only beep and flush if not moved at all
+ else if (cap->oap->op_type == OP_NOP && n == cap->count1) {
beep_flush();
+ }
break;
}
}
if (n != cap->count1 && (fdo_flags & FDO_HOR) && KeyTyped
- && cap->oap->op_type == OP_NOP)
+ && cap->oap->op_type == OP_NOP) {
foldOpenCursor();
+ }
}
/*
@@ -5294,7 +5460,7 @@ static void nv_left(cmdarg_T *cap)
static void nv_up(cmdarg_T *cap)
{
if (mod_mask & MOD_MASK_SHIFT) {
- /* <S-Up> is page up */
+ // <S-Up> is page up
cap->arg = BACKWARD;
nv_page(cap);
} else {
@@ -5314,7 +5480,7 @@ static void nv_up(cmdarg_T *cap)
static void nv_down(cmdarg_T *cap)
{
if (mod_mask & MOD_MASK_SHIFT) {
- /* <S-Down> is page down */
+ // <S-Down> is page down
cap->arg = FORWARD;
nv_page(cap);
} else if (bt_quickfix(curbuf) && cap->cmdchar == CAR) {
@@ -5347,7 +5513,7 @@ static void nv_down(cmdarg_T *cap)
*/
static void nv_gotofile(cmdarg_T *cap)
{
- char_u *ptr;
+ char_u *ptr;
linenr_T lnum = -1;
if (text_locked()) {
@@ -5376,8 +5542,9 @@ static void nv_gotofile(cmdarg_T *cap)
beginline(BL_SOL | BL_FIX);
}
xfree(ptr);
- } else
+ } else {
clearop(cap->oap);
+ }
}
/*
@@ -5385,10 +5552,10 @@ static void nv_gotofile(cmdarg_T *cap)
*/
static void nv_end(cmdarg_T *cap)
{
- if (cap->arg || (mod_mask & MOD_MASK_CTRL)) { /* CTRL-END = goto last line */
+ if (cap->arg || (mod_mask & MOD_MASK_CTRL)) { // CTRL-END = goto last line
cap->arg = true;
nv_goto(cap);
- cap->count1 = 1; /* to end of current line */
+ cap->count1 = 1; // to end of current line
}
nv_dollar(cap);
}
@@ -5404,13 +5571,15 @@ static void nv_dollar(cmdarg_T *cap)
* is pending (whew!) keep the cursor where it is.
* Otherwise, send it to the end of the line. */
if (!virtual_active() || gchar_cursor() != NUL
- || cap->oap->op_type == OP_NOP)
- curwin->w_curswant = MAXCOL; /* so we stay at the end */
+ || cap->oap->op_type == OP_NOP) {
+ curwin->w_curswant = MAXCOL; // so we stay at the end
+ }
if (cursor_down(cap->count1 - 1,
- cap->oap->op_type == OP_NOP) == false)
+ cap->oap->op_type == OP_NOP) == false) {
clearopbeep(cap->oap);
- else if ((fdo_flags & FDO_HOR) && KeyTyped && cap->oap->op_type == OP_NOP)
+ } else if ((fdo_flags & FDO_HOR) && KeyTyped && cap->oap->op_type == OP_NOP) {
foldOpenCursor();
+ }
}
/*
@@ -5419,11 +5588,11 @@ static void nv_dollar(cmdarg_T *cap)
*/
static void nv_search(cmdarg_T *cap)
{
- oparg_T *oap = cap->oap;
+ oparg_T *oap = cap->oap;
pos_T save_cursor = curwin->w_cursor;
if (cap->cmdchar == '?' && cap->oap->op_type == OP_ROT13) {
- /* Translate "g??" to "g?g?" */
+ // Translate "g??" to "g?g?"
cap->cmdchar = 'g';
cap->nchar = '?';
nv_operator(cap);
@@ -5464,18 +5633,13 @@ static void nv_next(cmdarg_T *cap)
}
}
-/*
- * Search for "pat" in direction "dir" ('/' or '?', 0 for repeat).
- * Uses only cap->count1 and cap->oap from "cap".
- * Return 0 for failure, 1 for found, 2 for found and line offset added.
- */
-static int normal_search(
- cmdarg_T *cap,
- int dir,
- char_u *pat,
- int opt, // extra flags for do_search()
- int *wrapped
-)
+/// Search for "pat" in direction "dir" ('/' or '?', 0 for repeat).
+/// Uses only cap->count1 and cap->oap from "cap".
+///
+/// @param opt extra flags for do_search()
+///
+/// @return 0 for failure, 1 for found, 2 for found and line offset added.
+static int normal_search(cmdarg_T *cap, int dir, char_u *pat, int opt, int *wrapped)
{
int i;
searchit_arg_T sia;
@@ -5498,8 +5662,9 @@ static int normal_search(
cap->oap->motion_type = kMTLineWise;
}
curwin->w_cursor.coladd = 0;
- if (cap->oap->op_type == OP_NOP && (fdo_flags & FDO_SEARCH) && KeyTyped)
+ if (cap->oap->op_type == OP_NOP && (fdo_flags & FDO_SEARCH) && KeyTyped) {
foldOpenCursor();
+ }
}
/* "/$" will put the cursor after the end of the line, may need to
@@ -5518,28 +5683,31 @@ static void nv_csearch(cmdarg_T *cap)
{
bool t_cmd;
- if (cap->cmdchar == 't' || cap->cmdchar == 'T')
+ if (cap->cmdchar == 't' || cap->cmdchar == 'T') {
t_cmd = true;
- else
+ } else {
t_cmd = false;
+ }
cap->oap->motion_type = kMTCharWise;
if (IS_SPECIAL(cap->nchar) || searchc(cap, t_cmd) == false) {
clearopbeep(cap->oap);
} else {
curwin->w_set_curswant = true;
- /* Include a Tab for "tx" and for "dfx". */
+ // Include a Tab for "tx" and for "dfx".
if (gchar_cursor() == TAB && virtual_active() && cap->arg == FORWARD
&& (t_cmd || cap->oap->op_type != OP_NOP)) {
colnr_T scol, ecol;
getvcol(curwin, &curwin->w_cursor, &scol, NULL, &ecol);
curwin->w_cursor.coladd = ecol - scol;
- } else
+ } else {
curwin->w_cursor.coladd = 0;
+ }
adjust_for_sel(cap);
- if ((fdo_flags & FDO_HOR) && KeyTyped && cap->oap->op_type == OP_NOP)
+ if ((fdo_flags & FDO_HOR) && KeyTyped && cap->oap->op_type == OP_NOP) {
foldOpenCursor();
+ }
}
}
@@ -5551,8 +5719,8 @@ static void nv_brackets(cmdarg_T *cap)
{
pos_T new_pos = { 0, 0, 0 };
pos_T prev_pos;
- pos_T *pos = NULL; /* init for GCC */
- pos_T old_pos; /* cursor position before command */
+ pos_T *pos = NULL; // init for GCC
+ pos_T old_pos; // cursor position before command
int flag;
long n;
int findc;
@@ -5561,32 +5729,32 @@ static void nv_brackets(cmdarg_T *cap)
cap->oap->motion_type = kMTCharWise;
cap->oap->inclusive = false;
old_pos = curwin->w_cursor;
- curwin->w_cursor.coladd = 0; /* TODO: don't do this for an error. */
+ curwin->w_cursor.coladd = 0; // TODO: don't do this for an error.
/*
* "[f" or "]f" : Edit file under the cursor (same as "gf")
*/
- if (cap->nchar == 'f')
+ if (cap->nchar == 'f') {
nv_gotofile(cap);
- else
+ } else
/*
* Find the occurrence(s) of the identifier or define under cursor
* in current and included files or jump to the first occurrence.
*
- * search list jump
- * fwd bwd fwd bwd fwd bwd
- * identifier "]i" "[i" "]I" "[I" "]^I" "[^I"
- * define "]d" "[d" "]D" "[D" "]^D" "[^D"
+ * search list jump
+ * fwd bwd fwd bwd fwd bwd
+ * identifier "]i" "[i" "]I" "[I" "]^I" "[^I"
+ * define "]d" "[d" "]D" "[D" "]^D" "[^D"
*/
if (vim_strchr((char_u *)
- "iI\011dD\004",
- cap->nchar) != NULL) {
- char_u *ptr;
+ "iI\011dD\004",
+ cap->nchar) != NULL) {
+ char_u *ptr;
size_t len;
- if ((len = find_ident_under_cursor(&ptr, FIND_IDENT)) == 0)
+ if ((len = find_ident_under_cursor(&ptr, FIND_IDENT)) == 0) {
clearop(cap->oap);
- else {
+ } else {
find_pattern_in_path(ptr, 0, len, true,
cap->count0 == 0 ? !isupper(cap->nchar) : false,
(((cap->nchar & 0xf) == ('d' & 0xf))
@@ -5614,14 +5782,16 @@ static void nv_brackets(cmdarg_T *cap)
&& vim_strchr((char_u *)"{(*/#mM", cap->nchar) != NULL)
|| (cap->cmdchar == ']'
&& vim_strchr((char_u *)"})*/#mM", cap->nchar) != NULL)) {
- if (cap->nchar == '*')
+ if (cap->nchar == '*') {
cap->nchar = '/';
+ }
prev_pos.lnum = 0;
if (cap->nchar == 'm' || cap->nchar == 'M') {
- if (cap->cmdchar == '[')
+ if (cap->cmdchar == '[') {
findc = '{';
- else
+ } else {
findc = '}';
+ }
n = 9999;
} else {
findc = cap->nchar;
@@ -5629,12 +5799,14 @@ static void nv_brackets(cmdarg_T *cap)
}
for (; n > 0; --n) {
if ((pos = findmatchlimit(cap->oap, findc,
- (cap->cmdchar == '[') ? FM_BACKWARD : FM_FORWARD, 0)) == NULL) {
- if (new_pos.lnum == 0) { /* nothing found */
- if (cap->nchar != 'm' && cap->nchar != 'M')
+ (cap->cmdchar == '[') ? FM_BACKWARD : FM_FORWARD, 0)) == NULL) {
+ if (new_pos.lnum == 0) { // nothing found
+ if (cap->nchar != 'm' && cap->nchar != 'M') {
clearopbeep(cap->oap);
- } else
- pos = &new_pos; /* use last one found */
+ }
+ } else {
+ pos = &new_pos; // use last one found
+ }
break;
}
prev_pos = new_pos;
@@ -5650,24 +5822,27 @@ static void nv_brackets(cmdarg_T *cap)
* Also repeat for the given count.
*/
if (cap->nchar == 'm' || cap->nchar == 'M') {
- /* norm is true for "]M" and "[m" */
+ // norm is true for "]M" and "[m"
int norm = ((findc == '{') == (cap->nchar == 'm'));
n = cap->count1;
- /* found a match: we were inside a method */
+ // found a match: we were inside a method
if (prev_pos.lnum != 0) {
pos = &prev_pos;
curwin->w_cursor = prev_pos;
- if (norm)
+ if (norm) {
--n;
- } else
+ }
+ } else {
pos = NULL;
+ }
while (n > 0) {
for (;; ) {
if ((findc == '{' ? dec_cursor() : inc_cursor()) < 0) {
- /* if not found anything, that's an error */
- if (pos == NULL)
+ // if not found anything, that's an error
+ if (pos == NULL) {
clearopbeep(cap->oap);
+ }
n = 0;
break;
}
@@ -5686,54 +5861,59 @@ static void nv_brackets(cmdarg_T *cap)
new_pos = curwin->w_cursor;
pos = &new_pos;
}
- /* found start/end of other method: go to match */
+ // found start/end of other method: go to match
else if ((pos = findmatchlimit(cap->oap, findc,
- (cap->cmdchar == '[') ? FM_BACKWARD : FM_FORWARD,
- 0)) == NULL)
+ (cap->cmdchar == '[') ? FM_BACKWARD : FM_FORWARD,
+ 0)) == NULL) {
n = 0;
- else
+ } else {
curwin->w_cursor = *pos;
+ }
break;
}
}
--n;
}
curwin->w_cursor = old_pos;
- if (pos == NULL && new_pos.lnum != 0)
+ if (pos == NULL && new_pos.lnum != 0) {
clearopbeep(cap->oap);
+ }
}
if (pos != NULL) {
setpcmark();
curwin->w_cursor = *pos;
curwin->w_set_curswant = true;
if ((fdo_flags & FDO_BLOCK) && KeyTyped
- && cap->oap->op_type == OP_NOP)
+ && cap->oap->op_type == OP_NOP) {
foldOpenCursor();
+ }
}
}
/*
* "[[", "[]", "]]" and "][": move to start or end of function
*/
else if (cap->nchar == '[' || cap->nchar == ']') {
- if (cap->nchar == cap->cmdchar) /* "]]" or "[[" */
+ if (cap->nchar == cap->cmdchar) { // "]]" or "[["
flag = '{';
- else
- flag = '}'; /* "][" or "[]" */
-
+ } else {
+ flag = '}'; // "][" or "[]"
+ }
curwin->w_set_curswant = true;
/*
* Imitate strange Vi behaviour: When using "]]" with an operator
* we also stop at '}'.
*/
if (!findpar(&cap->oap->inclusive, cap->arg, cap->count1, flag,
- (cap->oap->op_type != OP_NOP
- && cap->arg == FORWARD && flag == '{')))
+ (cap->oap->op_type != OP_NOP
+ && cap->arg == FORWARD && flag == '{'))) {
clearopbeep(cap->oap);
- else {
- if (cap->oap->op_type == OP_NOP)
+ } else {
+ if (cap->oap->op_type == OP_NOP) {
beginline(BL_WHITE | BL_FIX);
- if ((fdo_flags & FDO_BLOCK) && KeyTyped && cap->oap->op_type == OP_NOP)
+ }
+ if ((fdo_flags & FDO_BLOCK) && KeyTyped && cap->oap->op_type == OP_NOP) {
foldOpenCursor();
+ }
}
} else if (cap->nchar == 'p' || cap->nchar == 'P') {
// "[p", "[P", "]P" and "]p": put with indent adjustment
@@ -5747,12 +5927,14 @@ static void nv_brackets(cmdarg_T *cap)
for (n = cap->count1; n > 0; --n) {
prev_pos = *pos;
pos = getnextmark(pos, cap->cmdchar == '[' ? BACKWARD : FORWARD,
- cap->nchar == '\'');
- if (pos == NULL)
+ cap->nchar == '\'');
+ if (pos == NULL) {
break;
+ }
}
- if (pos == NULL)
+ if (pos == NULL) {
pos = &prev_pos;
+ }
nv_cursormark(cap, cap->nchar == '\'', pos);
}
/*
@@ -5761,31 +5943,33 @@ static void nv_brackets(cmdarg_T *cap)
*/
else if (cap->nchar >= K_RIGHTRELEASE && cap->nchar <= K_LEFTMOUSE) {
(void)do_mouse(cap->oap, cap->nchar,
- (cap->cmdchar == ']') ? FORWARD : BACKWARD,
- cap->count1, PUT_FIXINDENT);
+ (cap->cmdchar == ']') ? FORWARD : BACKWARD,
+ cap->count1, PUT_FIXINDENT);
}
/*
* "[z" and "]z": move to start or end of open fold.
*/
else if (cap->nchar == 'z') {
if (foldMoveTo(false, cap->cmdchar == ']' ? FORWARD : BACKWARD,
- cap->count1) == false)
+ cap->count1) == false) {
clearopbeep(cap->oap);
+ }
}
/*
* "[c" and "]c": move to next or previous diff-change.
*/
else if (cap->nchar == 'c') {
if (diff_move_to(cap->cmdchar == ']' ? FORWARD : BACKWARD,
- cap->count1) == false)
+ cap->count1) == false) {
clearopbeep(cap->oap);
+ }
}
/*
* "[s", "[S", "]s" and "]S": move to next spell error.
*/
else if (cap->nchar == 's' || cap->nchar == 'S') {
setpcmark();
- for (n = 0; n < cap->count1; ++n)
+ for (n = 0; n < cap->count1; ++n) {
if (spell_move_to(curwin, cap->cmdchar == ']' ? FORWARD : BACKWARD,
cap->nchar == 's', false, NULL) == 0) {
clearopbeep(cap->oap);
@@ -5793,12 +5977,15 @@ static void nv_brackets(cmdarg_T *cap)
} else {
curwin->w_set_curswant = true;
}
- if (cap->oap->op_type == OP_NOP && (fdo_flags & FDO_SEARCH) && KeyTyped)
+ }
+ if (cap->oap->op_type == OP_NOP && (fdo_flags & FDO_SEARCH) && KeyTyped) {
foldOpenCursor();
+ }
}
- /* Not a valid cap->nchar. */
- else
+ // Not a valid cap->nchar.
+ else {
clearopbeep(cap->oap);
+ }
}
/*
@@ -5806,7 +5993,7 @@ static void nv_brackets(cmdarg_T *cap)
*/
static void nv_percent(cmdarg_T *cap)
{
- pos_T *pos;
+ pos_T *pos;
linenr_T lnum = curwin->w_cursor.lnum;
cap->oap->inclusive = true;
@@ -5838,9 +6025,9 @@ static void nv_percent(cmdarg_T *cap)
} else { // "%" : go to matching paren
cap->oap->motion_type = kMTCharWise;
cap->oap->use_reg_one = true;
- if ((pos = findmatch(cap->oap, NUL)) == NULL)
+ if ((pos = findmatch(cap->oap, NUL)) == NULL) {
clearopbeep(cap->oap);
- else {
+ } else {
setpcmark();
curwin->w_cursor = *pos;
curwin->w_set_curswant = true;
@@ -5851,8 +6038,9 @@ static void nv_percent(cmdarg_T *cap)
if (cap->oap->op_type == OP_NOP
&& lnum != curwin->w_cursor.lnum
&& (fdo_flags & FDO_PERCENT)
- && KeyTyped)
+ && KeyTyped) {
foldOpenCursor();
+ }
}
/*
@@ -5863,18 +6051,19 @@ static void nv_brace(cmdarg_T *cap)
{
cap->oap->motion_type = kMTCharWise;
cap->oap->use_reg_one = true;
- /* The motion used to be inclusive for "(", but that is not what Vi does. */
+ // The motion used to be inclusive for "(", but that is not what Vi does.
cap->oap->inclusive = false;
curwin->w_set_curswant = true;
- if (findsent(cap->arg, cap->count1) == false)
+ if (findsent(cap->arg, cap->count1) == false) {
clearopbeep(cap->oap);
- else {
- /* Don't leave the cursor on the NUL past end of line. */
+ } else {
+ // Don't leave the cursor on the NUL past end of line.
adjust_cursor(cap->oap);
curwin->w_cursor.coladd = 0;
- if ((fdo_flags & FDO_BLOCK) && KeyTyped && cap->oap->op_type == OP_NOP)
+ if ((fdo_flags & FDO_BLOCK) && KeyTyped && cap->oap->op_type == OP_NOP) {
foldOpenCursor();
+ }
}
}
@@ -5884,8 +6073,9 @@ static void nv_brace(cmdarg_T *cap)
static void nv_mark(cmdarg_T *cap)
{
if (!checkclearop(cap->oap)) {
- if (setmark(cap->nchar) == false)
+ if (setmark(cap->nchar) == false) {
clearopbeep(cap->oap);
+ }
}
}
@@ -5899,12 +6089,13 @@ static void nv_findpar(cmdarg_T *cap)
cap->oap->inclusive = false;
cap->oap->use_reg_one = true;
curwin->w_set_curswant = true;
- if (!findpar(&cap->oap->inclusive, cap->arg, cap->count1, NUL, false))
+ if (!findpar(&cap->oap->inclusive, cap->arg, cap->count1, NUL, false)) {
clearopbeep(cap->oap);
- else {
+ } else {
curwin->w_cursor.coladd = 0;
- if ((fdo_flags & FDO_BLOCK) && KeyTyped && cap->oap->op_type == OP_NOP)
+ if ((fdo_flags & FDO_BLOCK) && KeyTyped && cap->oap->op_type == OP_NOP) {
foldOpenCursor();
+ }
}
}
@@ -5914,14 +6105,14 @@ static void nv_findpar(cmdarg_T *cap)
static void nv_undo(cmdarg_T *cap)
{
if (cap->oap->op_type == OP_LOWER
- || VIsual_active
- ) {
- /* translate "<Visual>u" to "<Visual>gu" and "guu" to "gugu" */
+ || VIsual_active) {
+ // translate "<Visual>u" to "<Visual>gu" and "guu" to "gugu"
cap->cmdchar = 'g';
cap->nchar = 'u';
nv_operator(cap);
- } else
+ } else {
nv_kundo(cap);
+ }
}
/*
@@ -5944,7 +6135,7 @@ static void nv_kundo(cmdarg_T *cap)
*/
static void nv_replace(cmdarg_T *cap)
{
- char_u *ptr;
+ char_u *ptr;
int had_ctrl_v;
if (checkclearop(cap->oap)) {
@@ -5955,26 +6146,29 @@ static void nv_replace(cmdarg_T *cap)
return;
}
- /* get another character */
+ // get another character
if (cap->nchar == Ctrl_V) {
had_ctrl_v = Ctrl_V;
cap->nchar = get_literal();
- /* Don't redo a multibyte character with CTRL-V. */
- if (cap->nchar > DEL)
+ // Don't redo a multibyte character with CTRL-V.
+ if (cap->nchar > DEL) {
had_ctrl_v = NUL;
- } else
+ }
+ } else {
had_ctrl_v = NUL;
+ }
- /* Abort if the character is a special key. */
+ // Abort if the character is a special key.
if (IS_SPECIAL(cap->nchar)) {
clearopbeep(cap->oap);
return;
}
- /* Visual mode "r" */
+ // Visual mode "r"
if (VIsual_active) {
- if (got_int)
+ if (got_int) {
reset_VIsual();
+ }
if (had_ctrl_v) {
// Use a special (negative) number to make a difference between a
// literal CR or NL and a line break.
@@ -5988,24 +6182,25 @@ static void nv_replace(cmdarg_T *cap)
return;
}
- /* Break tabs, etc. */
+ // Break tabs, etc.
if (virtual_active()) {
- if (u_save_cursor() == false)
+ if (u_save_cursor() == false) {
return;
+ }
if (gchar_cursor() == NUL) {
- /* Add extra space and put the cursor on the first one. */
+ // Add extra space and put the cursor on the first one.
coladvance_force((colnr_T)(getviscol() + cap->count1));
assert(cap->count1 <= INT_MAX);
curwin->w_cursor.col -= (colnr_T)cap->count1;
- } else if (gchar_cursor() == TAB)
+ } else if (gchar_cursor() == TAB) {
coladvance_force(getviscol());
+ }
}
- /* Abort if not enough characters to replace. */
+ // Abort if not enough characters to replace.
ptr = get_cursor_pos_ptr();
if (STRLEN(ptr) < (unsigned)cap->count1
- || (mb_charlen(ptr) < cap->count1)
- ) {
+ || (mb_charlen(ptr) < cap->count1)) {
clearopbeep(cap->oap);
return;
}
@@ -6022,9 +6217,10 @@ static void nv_replace(cmdarg_T *cap)
return;
}
- /* save line for undo */
- if (u_save_cursor() == false)
+ // save line for undo
+ if (u_save_cursor() == false) {
return;
+ }
if (had_ctrl_v != Ctrl_V && (cap->nchar == '\r' || cap->nchar == '\n')) {
/*
@@ -6032,18 +6228,18 @@ static void nv_replace(cmdarg_T *cap)
* Strange vi behaviour: Only one newline is inserted.
* Delete the characters here.
* Insert the newline with an insert command, takes care of
- * autoindent. The insert command depends on being on the last
+ * autoindent. The insert command depends on being on the last
* character of a line or not.
*/
- (void)del_chars(cap->count1, false); /* delete the characters */
+ (void)del_chars(cap->count1, false); // delete the characters
stuffcharReadbuff('\r');
stuffcharReadbuff(ESC);
- /* Give 'r' to edit(), to get the redo command right. */
+ // Give 'r' to edit(), to get the redo command right.
invoke_edit(cap, true, 'r', false);
} else {
prep_redo(cap->oap->regname, cap->count1,
- NUL, 'r', NUL, had_ctrl_v, cap->nchar);
+ NUL, 'r', NUL, had_ctrl_v, cap->nchar);
curbuf->b_op_start = curwin->w_cursor;
const int old_State = State;
@@ -6080,7 +6276,7 @@ static void nv_replace(cmdarg_T *cap)
ins_char(cap->ncharC2);
}
}
- --curwin->w_cursor.col; /* cursor on the last replaced char */
+ --curwin->w_cursor.col; // cursor on the last replaced char
/* if the character on the left of the current cursor is a multi-byte
* character, move two characters left */
mb_adjust_cursor();
@@ -6112,16 +6308,18 @@ static void v_swap_corners(int cmdchar)
curwin->w_curswant = right;
/* 'selection "exclusive" and cursor at right-bottom corner: move it
* right one column */
- if (old_cursor.lnum >= VIsual.lnum && *p_sel == 'e')
+ if (old_cursor.lnum >= VIsual.lnum && *p_sel == 'e') {
++curwin->w_curswant;
+ }
coladvance(curwin->w_curswant);
if (curwin->w_cursor.col == old_cursor.col
&& (!virtual_active()
- || curwin->w_cursor.coladd == old_cursor.coladd)
- ) {
+ || curwin->w_cursor.coladd ==
+ old_cursor.coladd)) {
curwin->w_cursor.lnum = VIsual.lnum;
- if (old_cursor.lnum <= VIsual.lnum && *p_sel == 'e')
+ if (old_cursor.lnum <= VIsual.lnum && *p_sel == 'e') {
++right;
+ }
coladvance(right);
VIsual = curwin->w_cursor;
@@ -6142,18 +6340,19 @@ static void v_swap_corners(int cmdchar)
*/
static void nv_Replace(cmdarg_T *cap)
{
- if (VIsual_active) { /* "R" is replace lines */
+ if (VIsual_active) { // "R" is replace lines
cap->cmdchar = 'c';
cap->nchar = NUL;
- VIsual_mode_orig = VIsual_mode; /* remember original area for gv */
+ VIsual_mode_orig = VIsual_mode; // remember original area for gv
VIsual_mode = 'V';
nv_operator(cap);
} else if (!checkclearopq(cap->oap)) {
if (!MODIFIABLE(curbuf)) {
EMSG(_(e_modifiable));
} else {
- if (virtual_active())
+ if (virtual_active()) {
coladvance(getviscol());
+ }
invoke_edit(cap, false, cap->arg ? 'V' : 'R', false);
}
}
@@ -6167,17 +6366,19 @@ static void nv_vreplace(cmdarg_T *cap)
if (VIsual_active) {
cap->cmdchar = 'r';
cap->nchar = cap->extra_char;
- nv_replace(cap); /* Do same as "r" in Visual mode for now */
+ nv_replace(cap); // Do same as "r" in Visual mode for now
} else if (!checkclearopq(cap->oap)) {
if (!MODIFIABLE(curbuf)) {
EMSG(_(e_modifiable));
} else {
- if (cap->extra_char == Ctrl_V) /* get another character */
+ if (cap->extra_char == Ctrl_V) { // get another character
cap->extra_char = get_literal();
+ }
stuffcharReadbuff(cap->extra_char);
stuffcharReadbuff(ESC);
- if (virtual_active())
+ if (virtual_active()) {
coladvance(getviscol());
+ }
invoke_edit(cap, true, 'v', false);
}
}
@@ -6203,8 +6404,9 @@ static void n_swapchar(cmdarg_T *cap)
prep_redo_cmd(cap);
- if (u_save_cursor() == false)
+ if (u_save_cursor() == false) {
return;
+ }
startpos = curwin->w_cursor;
for (n = cap->count1; n > 0; --n) {
@@ -6216,12 +6418,14 @@ static void n_swapchar(cmdarg_T *cap)
++curwin->w_cursor.lnum;
curwin->w_cursor.col = 0;
if (n > 1) {
- if (u_savesub(curwin->w_cursor.lnum) == false)
+ if (u_savesub(curwin->w_cursor.lnum) == false) {
break;
+ }
u_clearline();
}
- } else
+ } else {
break;
+ }
}
}
@@ -6233,8 +6437,9 @@ static void n_swapchar(cmdarg_T *cap)
0L, true);
curbuf->b_op_start = startpos;
curbuf->b_op_end = curwin->w_cursor;
- if (curbuf->b_op_end.col > 0)
+ if (curbuf->b_op_end.col > 0) {
--curbuf->b_op_end.col;
+ }
}
}
@@ -6243,19 +6448,21 @@ static void n_swapchar(cmdarg_T *cap)
*/
static void nv_cursormark(cmdarg_T *cap, int flag, pos_T *pos)
{
- if (check_mark(pos) == false)
+ if (check_mark(pos) == false) {
clearop(cap->oap);
- else {
+ } else {
if (cap->cmdchar == '\''
|| cap->cmdchar == '`'
|| cap->cmdchar == '['
- || cap->cmdchar == ']')
+ || cap->cmdchar == ']') {
setpcmark();
+ }
curwin->w_cursor = *pos;
- if (flag)
+ if (flag) {
beginline(BL_WHITE | BL_FIX);
- else
+ } else {
check_cursor();
+ }
}
cap->oap->motion_type = flag ? kMTLineWise : kMTCharWise;
if (cap->cmdchar == '`') {
@@ -6278,8 +6485,9 @@ static void v_visop(cmdarg_T *cap)
if (VIsual_mode != Ctrl_V) {
VIsual_mode_orig = VIsual_mode;
VIsual_mode = 'V';
- } else if (cap->cmdchar == 'C' || cap->cmdchar == 'D')
+ } else if (cap->cmdchar == 'C' || cap->cmdchar == 'D') {
curwin->w_curswant = MAXCOL;
+ }
}
cap->cmdchar = *(vim_strchr(trans, cap->cmdchar) + 1);
nv_operator(cap);
@@ -6301,8 +6509,9 @@ static void nv_subst(cmdarg_T *cap)
}
cap->cmdchar = 'c';
nv_operator(cap);
- } else
+ } else {
nv_optrans(cap);
+ }
}
/*
@@ -6310,14 +6519,15 @@ static void nv_subst(cmdarg_T *cap)
*/
static void nv_abbrev(cmdarg_T *cap)
{
- if (cap->cmdchar == K_DEL || cap->cmdchar == K_KDEL)
- cap->cmdchar = 'x'; /* DEL key behaves like 'x' */
-
- /* in Visual mode these commands are operators */
- if (VIsual_active)
+ if (cap->cmdchar == K_DEL || cap->cmdchar == K_KDEL) {
+ cap->cmdchar = 'x'; // DEL key behaves like 'x'
+ }
+ // in Visual mode these commands are operators
+ if (VIsual_active) {
v_visop(cap);
- else
+ } else {
nv_optrans(cap);
+ }
}
/*
@@ -6344,24 +6554,27 @@ static void nv_optrans(cmdarg_T *cap)
*/
static void nv_gomark(cmdarg_T *cap)
{
- pos_T *pos;
+ pos_T *pos;
int c;
pos_T old_cursor = curwin->w_cursor;
const bool old_KeyTyped = KeyTyped; // getting file may reset it
- if (cap->cmdchar == 'g')
+ if (cap->cmdchar == 'g') {
c = cap->extra_char;
- else
+ } else {
c = cap->nchar;
+ }
pos = getmark(c, (cap->oap->op_type == OP_NOP));
- if (pos == (pos_T *)-1) { /* jumped to other file */
+ if (pos == (pos_T *)-1) { // jumped to other file
if (cap->arg) {
check_cursor_lnum();
beginline(BL_WHITE | BL_FIX);
- } else
+ } else {
check_cursor();
- } else
+ }
+ } else {
nv_cursormark(cap, cap->arg, pos);
+ }
// May need to clear the coladd that a mark includes.
if (!virtual_active()) {
@@ -6380,7 +6593,7 @@ static void nv_gomark(cmdarg_T *cap)
// Handle CTRL-O, CTRL-I, "g;", "g,", and "CTRL-Tab" commands.
static void nv_pcmark(cmdarg_T *cap)
{
- pos_T *pos;
+ pos_T *pos;
linenr_T lnum = curwin->w_cursor.lnum;
const bool old_KeyTyped = KeyTyped; // getting file may reset it
@@ -6397,22 +6610,25 @@ static void nv_pcmark(cmdarg_T *cap)
if (pos == (pos_T *)-1) { // jump to other file
curwin->w_set_curswant = true;
check_cursor();
- } else if (pos != NULL) /* can jump */
+ } else if (pos != NULL) { // can jump
nv_cursormark(cap, false, pos);
- else if (cap->cmdchar == 'g') {
- if (curbuf->b_changelistlen == 0)
+ } else if (cap->cmdchar == 'g') {
+ if (curbuf->b_changelistlen == 0) {
EMSG(_("E664: changelist is empty"));
- else if (cap->count1 < 0)
+ } else if (cap->count1 < 0) {
EMSG(_("E662: At start of changelist"));
- else
+ } else {
EMSG(_("E663: At end of changelist"));
- } else
+ }
+ } else {
clearopbeep(cap->oap);
+ }
if (cap->oap->op_type == OP_NOP
&& (pos == (pos_T *)-1 || lnum != curwin->w_cursor.lnum)
&& (fdo_flags & FDO_MARK)
- && old_KeyTyped)
+ && old_KeyTyped) {
foldOpenCursor();
+ }
}
}
@@ -6421,16 +6637,19 @@ static void nv_pcmark(cmdarg_T *cap)
*/
static void nv_regname(cmdarg_T *cap)
{
- if (checkclearop(cap->oap))
+ if (checkclearop(cap->oap)) {
return;
- if (cap->nchar == '=')
+ }
+ if (cap->nchar == '=') {
cap->nchar = get_expr_register();
+ }
if (cap->nchar != NUL && valid_yank_reg(cap->nchar, false)) {
cap->oap->regname = cap->nchar;
- cap->opcount = cap->count0; /* remember count before '"' */
+ cap->opcount = cap->count0; // remember count before '"'
set_reg_var(cap->oap->regname);
- } else
+ } else {
clearopbeep(cap->oap);
+ }
}
/*
@@ -6441,8 +6660,9 @@ static void nv_regname(cmdarg_T *cap)
*/
static void nv_visual(cmdarg_T *cap)
{
- if (cap->cmdchar == Ctrl_Q)
+ if (cap->cmdchar == Ctrl_Q) {
cap->cmdchar = Ctrl_V;
+ }
// 'v', 'V' and CTRL-V can be used while an operator is pending to make it
// charwise, linewise, or blockwise.
@@ -6453,28 +6673,30 @@ static void nv_visual(cmdarg_T *cap)
}
VIsual_select = cap->arg;
- if (VIsual_active) { /* change Visual mode */
- if (VIsual_mode == cap->cmdchar) /* stop visual mode */
+ if (VIsual_active) { // change Visual mode
+ if (VIsual_mode == cap->cmdchar) { // stop visual mode
end_visual_mode();
- else { /* toggle char/block mode */
- /* or char/line mode */
+ } else { // toggle char/block mode
+ // or char/line mode
VIsual_mode = cap->cmdchar;
showmode();
}
redraw_curbuf_later(INVERTED); // update the inversion
} else { // start Visual mode
if (cap->count0 > 0 && resel_VIsual_mode != NUL) {
- /* use previously selected part */
+ // use previously selected part
VIsual = curwin->w_cursor;
VIsual_active = true;
VIsual_reselect = true;
- if (!cap->arg)
- /* start Select mode when 'selectmode' contains "cmd" */
+ if (!cap->arg) {
+ // start Select mode when 'selectmode' contains "cmd"
may_start_select('c');
+ }
setmouse();
- if (p_smd && msg_silent == 0)
- redraw_cmdline = true; /* show visual mode later */
+ if (p_smd && msg_silent == 0) {
+ redraw_cmdline = true; // show visual mode later
+ }
/*
* For V and ^V, we multiply the number of lines even if there
* was only one -- webb
@@ -6482,8 +6704,9 @@ static void nv_visual(cmdarg_T *cap)
if (resel_VIsual_mode != 'v' || resel_VIsual_line_count > 1) {
curwin->w_cursor.lnum +=
resel_VIsual_line_count * cap->count0 - 1;
- if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
+ if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count) {
curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+ }
}
VIsual_mode = resel_VIsual_mode;
if (VIsual_mode == 'v') {
@@ -6492,8 +6715,9 @@ static void nv_visual(cmdarg_T *cap)
assert(cap->count0 >= INT_MIN && cap->count0 <= INT_MAX);
curwin->w_curswant = (curwin->w_virtcol
+ resel_VIsual_vcol * (int)cap->count0 - 1);
- } else
+ } else {
curwin->w_curswant = resel_VIsual_vcol;
+ }
coladvance(curwin->w_curswant);
}
if (resel_VIsual_vcol == MAXCOL) {
@@ -6505,22 +6729,26 @@ static void nv_visual(cmdarg_T *cap)
curwin->w_curswant = (curwin->w_virtcol
+ resel_VIsual_vcol * (int)cap->count0 - 1);
coladvance(curwin->w_curswant);
- } else
+ } else {
curwin->w_set_curswant = true;
- redraw_curbuf_later(INVERTED); /* show the inversion */
+ }
+ redraw_curbuf_later(INVERTED); // show the inversion
} else {
- if (!cap->arg)
- /* start Select mode when 'selectmode' contains "cmd" */
+ if (!cap->arg) {
+ // start Select mode when 'selectmode' contains "cmd"
may_start_select('c');
+ }
n_start_visual_mode(cap->cmdchar);
- if (VIsual_mode != 'V' && *p_sel == 'e')
- ++cap->count1; /* include one more char */
+ if (VIsual_mode != 'V' && *p_sel == 'e') {
+ ++cap->count1; // include one more char
+ }
if (cap->count0 > 0 && --cap->count1 > 0) {
- /* With a count select that many characters or lines. */
- if (VIsual_mode == 'v' || VIsual_mode == Ctrl_V)
+ // With a count select that many characters or lines.
+ if (VIsual_mode == 'v' || VIsual_mode == Ctrl_V) {
nv_right(cap);
- else if (VIsual_mode == 'V')
+ } else if (VIsual_mode == 'V') {
nv_down(cap);
+ }
}
}
}
@@ -6531,7 +6759,7 @@ static void nv_visual(cmdarg_T *cap)
*/
void start_selection(void)
{
- /* if 'selectmode' contains "key", start Select mode */
+ // if 'selectmode' contains "key", start Select mode
may_start_select('k');
n_start_visual_mode('v');
}
@@ -6554,9 +6782,9 @@ static void n_start_visual_mode(int c)
VIsual_mode = c;
VIsual_active = true;
VIsual_reselect = true;
- /* Corner case: the 0 position in a tab may change when going into
- * virtualedit. Recalculate curwin->w_cursor to avoid bad hilighting.
- */
+ // Corner case: the 0 position in a tab may change when going into
+ // virtualedit. Recalculate curwin->w_cursor to avoid bad highlighting.
+ //
if (c == Ctrl_V && (ve_flags & VE_BLOCK) && gchar_cursor() == TAB) {
validate_virtcol();
coladvance(curwin->w_virtcol);
@@ -6569,9 +6797,9 @@ static void n_start_visual_mode(int c)
// Check for redraw after changing the state.
conceal_check_cursor_line();
- if (p_smd && msg_silent == 0)
- redraw_cmdline = true; /* show visual mode later */
-
+ if (p_smd && msg_silent == 0) {
+ redraw_cmdline = true; // show visual mode later
+ }
/* Only need to redraw this line, unless still need to redraw an old
* Visual area (when 'lazyredraw' is set). */
if (curwin->w_redr_type < INVERTED) {
@@ -6602,8 +6830,9 @@ static void nv_window(cmdarg_T *cap)
static void nv_suspend(cmdarg_T *cap)
{
clearop(cap->oap);
- if (VIsual_active)
- end_visual_mode(); /* stop Visual mode */
+ if (VIsual_active) {
+ end_visual_mode(); // stop Visual mode
+ }
do_cmdline_cmd("st");
}
@@ -6612,7 +6841,7 @@ static void nv_suspend(cmdarg_T *cap)
*/
static void nv_g_cmd(cmdarg_T *cap)
{
- oparg_T *oap = cap->oap;
+ oparg_T *oap = cap->oap;
pos_T tpos;
int i;
bool flag = false;
@@ -6647,18 +6876,19 @@ static void nv_g_cmd(cmdarg_T *cap)
/*
* "gv": Reselect the previous Visual area. If Visual already active,
- * exchange previous and current Visual area.
+ * exchange previous and current Visual area.
*/
case 'v':
- if (checkclearop(oap))
+ if (checkclearop(oap)) {
break;
+ }
- if ( curbuf->b_visual.vi_start.lnum == 0
- || curbuf->b_visual.vi_start.lnum > curbuf->b_ml.ml_line_count
- || curbuf->b_visual.vi_end.lnum == 0)
+ if (curbuf->b_visual.vi_start.lnum == 0
+ || curbuf->b_visual.vi_start.lnum > curbuf->b_ml.ml_line_count
+ || curbuf->b_visual.vi_end.lnum == 0) {
beep_flush();
- else {
- /* set w_cursor to the start of the Visual area, tpos to the end */
+ } else {
+ // set w_cursor to the start of the Visual area, tpos to the end
if (VIsual_active) {
i = VIsual_mode;
VIsual_mode = curbuf->b_visual.vi_mode;
@@ -6704,7 +6934,7 @@ static void nv_g_cmd(cmdarg_T *cap)
break;
/*
* "gV": Don't reselect the previous Visual area after a Select mode
- * mapping of menu.
+ * mapping of menu.
*/
case 'V':
VIsual_reselect = false;
@@ -6732,8 +6962,9 @@ static void nv_g_cmd(cmdarg_T *cap)
*/
case 'N':
case 'n':
- if (!current_search(cap->count1, cap->nchar == 'n'))
+ if (!current_search(cap->count1, cap->nchar == 'n')) {
clearopbeep(oap);
+ }
break;
/*
@@ -6746,10 +6977,12 @@ static void nv_g_cmd(cmdarg_T *cap)
if (!curwin->w_p_wrap) {
oap->motion_type = kMTLineWise;
i = cursor_down(cap->count1, oap->op_type == OP_NOP);
- } else
+ } else {
i = nv_screengo(oap, FORWARD, cap->count1);
- if (!i)
+ }
+ if (!i) {
clearopbeep(oap);
+ }
break;
case 'k':
@@ -6758,10 +6991,12 @@ static void nv_g_cmd(cmdarg_T *cap)
if (!curwin->w_p_wrap) {
oap->motion_type = kMTLineWise;
i = cursor_up(cap->count1, oap->op_type == OP_NOP);
- } else
+ } else {
i = nv_screengo(oap, BACKWARD, cap->count1);
- if (!i)
+ }
+ if (!i) {
clearopbeep(oap);
+ }
break;
/*
@@ -6786,17 +7021,18 @@ static void nv_g_cmd(cmdarg_T *cap)
oap->motion_type = kMTCharWise;
oap->inclusive = false;
if (curwin->w_p_wrap
- && curwin->w_width_inner != 0
- ) {
+ && curwin->w_width_inner != 0) {
int width1 = curwin->w_width_inner - curwin_col_off();
int width2 = width1 + curwin_col_off2();
validate_virtcol();
i = 0;
- if (curwin->w_virtcol >= (colnr_T)width1 && width2 > 0)
+ if (curwin->w_virtcol >= (colnr_T)width1 && width2 > 0) {
i = (curwin->w_virtcol - width1) / width2 * width2 + width1;
- } else
+ }
+ } else {
i = curwin->w_leftcol;
+ }
/* Go to the middle of the screen line. When 'number' or
* 'relativenumber' is on and lines are wrapping the middle can be more
* to the left. */
@@ -6815,21 +7051,20 @@ static void nv_g_cmd(cmdarg_T *cap)
curwin->w_set_curswant = true;
break;
- case 'M':
- {
- const char_u *const ptr = get_cursor_line_ptr();
+ case 'M': {
+ const char_u *const ptr = get_cursor_line_ptr();
- oap->motion_type = kMTCharWise;
- oap->inclusive = false;
- i = (int)mb_string2cells_len(ptr, STRLEN(ptr));
- if (cap->count0 > 0 && cap->count0 <= 100) {
- coladvance((colnr_T)(i * cap->count0 / 100));
- } else {
- coladvance((colnr_T)(i / 2));
- }
- curwin->w_set_curswant = true;
+ oap->motion_type = kMTCharWise;
+ oap->inclusive = false;
+ i = (int)mb_string2cells_len(ptr, STRLEN(ptr));
+ if (cap->count0 > 0 && cap->count0 <= 100) {
+ coladvance((colnr_T)(i * cap->count0 / 100));
+ } else {
+ coladvance((colnr_T)(i / 2));
}
- break;
+ curwin->w_set_curswant = true;
+ }
+ break;
case '_':
/* "g_": to the last non-blank character in the line or <count> lines
@@ -6838,19 +7073,21 @@ static void nv_g_cmd(cmdarg_T *cap)
cap->oap->inclusive = true;
curwin->w_curswant = MAXCOL;
if (cursor_down(cap->count1 - 1,
- cap->oap->op_type == OP_NOP) == false)
+ cap->oap->op_type == OP_NOP) == false) {
clearopbeep(cap->oap);
- else {
- char_u *ptr = get_cursor_line_ptr();
+ } else {
+ char_u *ptr = get_cursor_line_ptr();
- /* In Visual mode we may end up after the line. */
- if (curwin->w_cursor.col > 0 && ptr[curwin->w_cursor.col] == NUL)
+ // In Visual mode we may end up after the line.
+ if (curwin->w_cursor.col > 0 && ptr[curwin->w_cursor.col] == NUL) {
--curwin->w_cursor.col;
+ }
- /* Decrease the cursor column until it's on a non-blank. */
+ // Decrease the cursor column until it's on a non-blank.
while (curwin->w_cursor.col > 0
- && ascii_iswhite(ptr[curwin->w_cursor.col]))
+ && ascii_iswhite(ptr[curwin->w_cursor.col])) {
--curwin->w_cursor.col;
+ }
curwin->w_set_curswant = true;
adjust_for_sel(cap);
}
@@ -6858,28 +7095,27 @@ static void nv_g_cmd(cmdarg_T *cap)
case '$':
case K_END:
- case K_KEND:
- {
+ case K_KEND: {
int col_off = curwin_col_off();
oap->motion_type = kMTCharWise;
oap->inclusive = true;
if (curwin->w_p_wrap
- && curwin->w_width_inner != 0
- ) {
- curwin->w_curswant = MAXCOL; /* so we stay at the end */
+ && curwin->w_width_inner != 0) {
+ curwin->w_curswant = MAXCOL; // so we stay at the end
if (cap->count1 == 1) {
int width1 = curwin->w_width_inner - col_off;
int width2 = width1 + curwin_col_off2();
validate_virtcol();
i = width1 - 1;
- if (curwin->w_virtcol >= (colnr_T)width1)
+ if (curwin->w_virtcol >= (colnr_T)width1) {
i += ((curwin->w_virtcol - width1) / width2 + 1)
* width2;
+ }
coladvance((colnr_T)i);
- /* Make sure we stick in this column. */
+ // Make sure we stick in this column.
validate_virtcol();
curwin->w_curswant = curwin->w_virtcol;
curwin->w_set_curswant = false;
@@ -6889,11 +7125,13 @@ static void nv_g_cmd(cmdarg_T *cap)
* the end of the line. We do not want to advance to
* the next screen line.
*/
- if (curwin->w_virtcol > (colnr_T)i)
+ if (curwin->w_virtcol > (colnr_T)i) {
--curwin->w_cursor.col;
+ }
}
- } else if (nv_screengo(oap, FORWARD, cap->count1 - 1) == false)
+ } else if (nv_screengo(oap, FORWARD, cap->count1 - 1) == false) {
clearopbeep(oap);
+ }
} else {
if (cap->count1 > 1) {
// if it fails, let the cursor still move to the last char
@@ -6916,10 +7154,10 @@ static void nv_g_cmd(cmdarg_T *cap)
case '*':
case '#':
#if POUND != '#'
- case POUND: /* pound sign (sometimes equal to '#') */
+ case POUND: // pound sign (sometimes equal to '#')
#endif
- case Ctrl_RSB: /* :tag or :tselect for current identifier */
- case ']': /* :tselect for current identifier */
+ case Ctrl_RSB: // :tag or :tselect for current identifier
+ case ']': // :tselect for current identifier
nv_ident(cap);
break;
@@ -6931,8 +7169,9 @@ static void nv_g_cmd(cmdarg_T *cap)
oap->motion_type = kMTCharWise;
curwin->w_set_curswant = true;
oap->inclusive = true;
- if (bckend_word(cap->count1, cap->nchar == 'E', false) == false)
+ if (bckend_word(cap->count1, cap->nchar == 'E', false) == false) {
clearopbeep(oap);
+ }
break;
// "g CTRL-G": display info about cursor position
@@ -6947,8 +7186,9 @@ static void nv_g_cmd(cmdarg_T *cap)
check_cursor_lnum();
i = (int)STRLEN(get_cursor_line_ptr());
if (curwin->w_cursor.col > (colnr_T)i) {
- if (virtual_active())
+ if (virtual_active()) {
curwin->w_cursor.coladd += curwin->w_cursor.col - i;
+ }
curwin->w_cursor.col = i;
}
}
@@ -6961,8 +7201,9 @@ static void nv_g_cmd(cmdarg_T *cap)
*/
case 'I':
beginline(0);
- if (!checkclearopq(oap))
+ if (!checkclearopq(oap)) {
invoke_edit(cap, false, 'g', false);
+ }
break;
/*
@@ -6974,7 +7215,7 @@ static void nv_g_cmd(cmdarg_T *cap)
nv_gotofile(cap);
break;
- /* "g'm" and "g`m": jump to mark without setting pcmark */
+ // "g'm" and "g`m": jump to mark without setting pcmark
case '\'':
cap->arg = true;
FALLTHROUGH;
@@ -6991,7 +7232,7 @@ static void nv_g_cmd(cmdarg_T *cap)
/*
* "ga": Display the ascii value of the character under the
- * cursor. It is displayed in decimal, hex, and octal. -- webb
+ * cursor. It is displayed in decimal, hex, and octal. -- webb
*/
case 'a':
do_ascii(NULL);
@@ -6999,14 +7240,15 @@ static void nv_g_cmd(cmdarg_T *cap)
/*
* "g8": Display the bytes used for the UTF-8 character under the
- * cursor. It is displayed in hex.
+ * cursor. It is displayed in hex.
* "8g8" finds illegal byte sequence.
*/
case '8':
- if (cap->count0 == 8)
+ if (cap->count0 == 8) {
utf_find_illegal();
- else
+ } else {
show_utf8();
+ }
break;
// "g<": show scrollback text
case '<':
@@ -7023,14 +7265,14 @@ static void nv_g_cmd(cmdarg_T *cap)
break;
/*
- * Two-character operators:
- * "gq" Format text
- * "gw" Format text and keep cursor position
- * "g~" Toggle the case of the text.
- * "gu" Change text to lower case.
- * "gU" Change text to upper case.
- * "g?" rot13 encoding
- * "g@" call 'operatorfunc'
+ * Two-character operators:
+ * "gq" Format text
+ * "gw" Format text and keep cursor position
+ * "g~" Toggle the case of the text.
+ * "gu" Change text to lower case.
+ * "gU" Change text to upper case.
+ * "g?" rot13 encoding
+ * "g@" call 'operatorfunc'
*/
case 'q':
case 'w':
@@ -7046,7 +7288,7 @@ static void nv_g_cmd(cmdarg_T *cap)
/*
* "gd": Find first occurrence of pattern under the cursor in the
- * current function
+ * current function
* "gD": idem, but in the current file.
*/
case 'd':
@@ -7088,12 +7330,12 @@ static void nv_g_cmd(cmdarg_T *cap)
nv_put(cap);
break;
- /* "go": goto byte count from start of buffer */
+ // "go": goto byte count from start of buffer
case 'o':
goto_byte(cap->count0);
break;
- /* "gQ": improved Ex mode */
+ // "gQ": improved Ex mode
case 'Q':
if (text_locked()) {
clearopbeep(cap->oap);
@@ -7101,8 +7343,9 @@ static void nv_g_cmd(cmdarg_T *cap)
break;
}
- if (!checkclearopq(oap))
- do_exmode(true);
+ if (!checkclearopq(oap)) {
+ do_exmode();
+ }
break;
case ',':
@@ -7115,12 +7358,14 @@ static void nv_g_cmd(cmdarg_T *cap)
break;
case 't':
- if (!checkclearop(oap))
+ if (!checkclearop(oap)) {
goto_tabpage((int)cap->count0);
+ }
break;
case 'T':
- if (!checkclearop(oap))
+ if (!checkclearop(oap)) {
goto_tabpage(-(int)cap->count1);
+ }
break;
case TAB:
if (!checkclearop(oap)) {
@@ -7129,10 +7374,11 @@ static void nv_g_cmd(cmdarg_T *cap)
break;
case '+':
- case '-': /* "g+" and "g-": undo or redo along the timeline */
- if (!checkclearopq(oap))
+ case '-': // "g+" and "g-": undo or redo along the timeline
+ if (!checkclearopq(oap)) {
undo_time(cap->nchar == '-' ? -cap->count1 : cap->count1,
- false, false, false);
+ false, false, false);
+ }
break;
default:
@@ -7147,19 +7393,20 @@ static void nv_g_cmd(cmdarg_T *cap)
static void n_opencmd(cmdarg_T *cap)
{
if (!checkclearopq(cap->oap)) {
- if (cap->cmdchar == 'O')
- /* Open above the first line of a folded sequence of lines */
+ if (cap->cmdchar == 'O') {
+ // Open above the first line of a folded sequence of lines
(void)hasFolding(curwin->w_cursor.lnum,
- &curwin->w_cursor.lnum, NULL);
- else
- /* Open below the last line of a folded sequence of lines */
+ &curwin->w_cursor.lnum, NULL);
+ } else {
+ // Open below the last line of a folded sequence of lines
(void)hasFolding(curwin->w_cursor.lnum,
- NULL, &curwin->w_cursor.lnum);
+ NULL, &curwin->w_cursor.lnum);
+ }
if (u_save((linenr_T)(curwin->w_cursor.lnum -
(cap->cmdchar == 'O' ? 1 : 0)),
- (linenr_T)(curwin->w_cursor.lnum +
- (cap->cmdchar == 'o' ? 1 : 0))
- )
+ (linenr_T)(curwin->w_cursor.lnum +
+ (cap->cmdchar == 'o' ? 1 : 0))
+ )
&& open_line(cap->cmdchar == 'O' ? BACKWARD : FORWARD,
has_format_option(FO_OPEN_COMS)
? OPENLINE_DO_COM : 0,
@@ -7184,8 +7431,9 @@ static void nv_dot(cmdarg_T *cap)
* instead of the last command (inserting text). This is used for
* CTRL-O <.> in insert mode.
*/
- if (start_redo(cap->count0, restart_edit != 0 && !arrow_used) == false)
+ if (start_redo(cap->count0, restart_edit != 0 && !arrow_used) == false) {
clearopbeep(cap->oap);
+ }
}
}
@@ -7205,11 +7453,10 @@ static void nv_redo(cmdarg_T *cap)
*/
static void nv_Undo(cmdarg_T *cap)
{
- /* In Visual mode and typing "gUU" triggers an operator */
+ // In Visual mode and typing "gUU" triggers an operator
if (cap->oap->op_type == OP_UPPER
- || VIsual_active
- ) {
- /* translate "gUU" to "gUgU" */
+ || VIsual_active) {
+ // translate "gUU" to "gUgU"
cap->cmdchar = 'g';
cap->nchar = 'U';
nv_operator(cap);
@@ -7254,9 +7501,9 @@ static void nv_operator(cmdarg_T *cap)
return;
}
- if (op_type == cap->oap->op_type) /* double operator works on lines */
+ if (op_type == cap->oap->op_type) { // double operator works on lines
nv_lineop(cap);
- else if (!checkclearop(cap->oap)) {
+ } else if (!checkclearop(cap->oap)) {
cap->oap->start = curwin->w_cursor;
cap->oap->op_type = op_type;
set_op_var(op_type);
@@ -7274,11 +7521,11 @@ static void set_op_var(int optype)
char opchars[3];
int opchar0 = get_op_char(optype);
assert(opchar0 >= 0 && opchar0 <= UCHAR_MAX);
- opchars[0] = (char) opchar0;
+ opchars[0] = (char)opchar0;
int opchar1 = get_extra_op_char(optype);
assert(opchar1 >= 0 && opchar1 <= UCHAR_MAX);
- opchars[1] = (char) opchar1;
+ opchars[1] = (char)opchar1;
opchars[2] = NUL;
set_vim_var_string(VV_OP, opchars, -1);
@@ -7316,10 +7563,10 @@ static void nv_lineop(cmdarg_T *cap)
*/
static void nv_home(cmdarg_T *cap)
{
- /* CTRL-HOME is like "gg" */
- if (mod_mask & MOD_MASK_CTRL)
+ // CTRL-HOME is like "gg"
+ if (mod_mask & MOD_MASK_CTRL) {
nv_goto(cap);
- else {
+ } else {
cap->count0 = 1;
nv_pipe(cap);
}
@@ -7338,8 +7585,9 @@ static void nv_pipe(cmdarg_T *cap)
if (cap->count0 > 0) {
coladvance((colnr_T)(cap->count0 - 1));
curwin->w_curswant = (colnr_T)(cap->count0 - 1);
- } else
+ } else {
curwin->w_curswant = 0;
+ }
/* keep curswant at the column where we wanted to go, not where
* we ended; differs if line is too short */
curwin->w_set_curswant = false;
@@ -7354,10 +7602,11 @@ static void nv_bck_word(cmdarg_T *cap)
cap->oap->motion_type = kMTCharWise;
cap->oap->inclusive = false;
curwin->w_set_curswant = true;
- if (bck_word(cap->count1, cap->arg, false) == false)
+ if (bck_word(cap->count1, cap->arg, false) == false) {
clearopbeep(cap->oap);
- else if ((fdo_flags & FDO_HOR) && KeyTyped && cap->oap->op_type == OP_NOP)
+ } else if ((fdo_flags & FDO_HOR) && KeyTyped && cap->oap->op_type == OP_NOP) {
foldOpenCursor();
+ }
}
/*
@@ -7374,10 +7623,11 @@ static void nv_wordcmd(cmdarg_T *cap)
/*
* Set inclusive for the "E" and "e" command.
*/
- if (cap->cmdchar == 'e' || cap->cmdchar == 'E')
+ if (cap->cmdchar == 'e' || cap->cmdchar == 'E') {
word_end = true;
- else
+ } else {
word_end = false;
+ }
cap->oap->inclusive = word_end;
/*
@@ -7404,22 +7654,25 @@ static void nv_wordcmd(cmdarg_T *cap)
cap->oap->motion_type = kMTCharWise;
curwin->w_set_curswant = true;
- if (word_end)
+ if (word_end) {
n = end_word(cap->count1, cap->arg, flag, false);
- else
+ } else {
n = fwd_word(cap->count1, cap->arg, cap->oap->op_type != OP_NOP);
+ }
/* Don't leave the cursor on the NUL past the end of line. Unless we
* didn't move it forward. */
- if (lt(startpos, curwin->w_cursor))
+ if (lt(startpos, curwin->w_cursor)) {
adjust_cursor(cap->oap);
+ }
- if (n == false && cap->oap->op_type == OP_NOP)
+ if (n == false && cap->oap->op_type == OP_NOP) {
clearopbeep(cap->oap);
- else {
+ } else {
adjust_for_sel(cap);
- if ((fdo_flags & FDO_HOR) && KeyTyped && cap->oap->op_type == OP_NOP)
+ if ((fdo_flags & FDO_HOR) && KeyTyped && cap->oap->op_type == OP_NOP) {
foldOpenCursor();
+ }
}
}
@@ -7437,8 +7690,8 @@ static void adjust_cursor(oparg_T *oap)
*/
if (curwin->w_cursor.col > 0 && gchar_cursor() == NUL
&& (!VIsual_active || *p_sel == 'o')
- && !virtual_active() && (ve_flags & VE_ONEMORE) == 0
- ) {
+ && !virtual_active() &&
+ (ve_flags & VE_ONEMORE) == 0) {
curwin->w_cursor.col--;
// prevent cursor from moving on the trail byte
mb_adjust_cursor();
@@ -7455,8 +7708,9 @@ static void nv_beginline(cmdarg_T *cap)
cap->oap->motion_type = kMTCharWise;
cap->oap->inclusive = false;
beginline(cap->arg);
- if ((fdo_flags & FDO_HOR) && KeyTyped && cap->oap->op_type == OP_NOP)
+ if ((fdo_flags & FDO_HOR) && KeyTyped && cap->oap->op_type == OP_NOP) {
foldOpenCursor();
+ }
ins_at_eol = false; /* Don't move cursor past eol (only necessary in a
one-character line). */
}
@@ -7480,13 +7734,14 @@ static void adjust_for_sel(cmdarg_T *cap)
*/
static bool unadjust_for_sel(void)
{
- pos_T *pp;
+ pos_T *pp;
if (*p_sel == 'e' && !equalpos(VIsual, curwin->w_cursor)) {
- if (lt(VIsual, curwin->w_cursor))
+ if (lt(VIsual, curwin->w_cursor)) {
pp = &curwin->w_cursor;
- else
+ } else {
pp = &VIsual;
+ }
if (pp->coladd > 0) {
pp->coladd--;
} else if (pp->col > 0) {
@@ -7506,10 +7761,10 @@ static bool unadjust_for_sel(void)
*/
static void nv_select(cmdarg_T *cap)
{
- if (VIsual_active)
+ if (VIsual_active) {
VIsual_select = true;
- else if (VIsual_reselect) {
- cap->nchar = 'v'; /* fake "gv" command */
+ } else if (VIsual_reselect) {
+ cap->nchar = 'v'; // fake "gv" command
cap->arg = true;
nv_g_cmd(cap);
}
@@ -7524,24 +7779,28 @@ static void nv_goto(cmdarg_T *cap)
{
linenr_T lnum;
- if (cap->arg)
+ if (cap->arg) {
lnum = curbuf->b_ml.ml_line_count;
- else
+ } else {
lnum = 1L;
+ }
cap->oap->motion_type = kMTLineWise;
setpcmark();
- /* When a count is given, use it instead of the default lnum */
- if (cap->count0 != 0)
+ // When a count is given, use it instead of the default lnum
+ if (cap->count0 != 0) {
lnum = cap->count0;
- if (lnum < 1L)
+ }
+ if (lnum < 1L) {
lnum = 1L;
- else if (lnum > curbuf->b_ml.ml_line_count)
+ } else if (lnum > curbuf->b_ml.ml_line_count) {
lnum = curbuf->b_ml.ml_line_count;
+ }
curwin->w_cursor.lnum = lnum;
beginline(BL_SOL | BL_FIX);
- if ((fdo_flags & FDO_JUMP) && KeyTyped && cap->oap->op_type == OP_NOP)
+ if ((fdo_flags & FDO_JUMP) && KeyTyped && cap->oap->op_type == OP_NOP) {
foldOpenCursor();
+ }
}
/*
@@ -7551,20 +7810,24 @@ static void nv_normal(cmdarg_T *cap)
{
if (cap->nchar == Ctrl_N || cap->nchar == Ctrl_G) {
clearop(cap->oap);
- if (restart_edit != 0 && mode_displayed)
- clear_cmdline = true; /* unshow mode later */
+ if (restart_edit != 0 && mode_displayed) {
+ clear_cmdline = true; // unshow mode later
+ }
restart_edit = 0;
- if (cmdwin_type != 0)
+ if (cmdwin_type != 0) {
cmdwin_result = Ctrl_C;
+ }
if (VIsual_active) {
- end_visual_mode(); /* stop Visual */
+ end_visual_mode(); // stop Visual
redraw_curbuf_later(INVERTED);
}
- /* CTRL-\ CTRL-G restarts Insert mode when 'insertmode' is set. */
- if (cap->nchar == Ctrl_G && p_im)
+ // CTRL-\ CTRL-G restarts Insert mode when 'insertmode' is set.
+ if (cap->nchar == Ctrl_G && p_im) {
restart_edit = 'a';
- } else
+ }
+ } else {
clearopbeep(cap->oap);
+ }
}
/*
@@ -7581,7 +7844,7 @@ static void nv_esc(cmdarg_T *cap)
&& cap->oap->regname == 0
&& !p_im);
- if (cap->arg) { /* true for CTRL-C */
+ if (cap->arg) { // true for CTRL-C
if (restart_edit == 0
&& cmdwin_type == 0
&& !VIsual_active
@@ -7596,11 +7859,12 @@ static void nv_esc(cmdarg_T *cap)
/* Don't reset "restart_edit" when 'insertmode' is set, it won't be
* set again below when halfway through a mapping. */
- if (!p_im)
+ if (!p_im) {
restart_edit = 0;
+ }
if (cmdwin_type != 0) {
cmdwin_result = K_IGNORE;
- got_int = false; /* don't stop executing autocommands et al. */
+ got_int = false; // don't stop executing autocommands et al.
return;
}
} else if (cmdwin_type != 0 && ex_normal_busy) {
@@ -7612,8 +7876,8 @@ static void nv_esc(cmdarg_T *cap)
}
if (VIsual_active) {
- end_visual_mode(); /* stop Visual */
- check_cursor_col(); /* make sure cursor is not beyond EOL */
+ end_visual_mode(); // stop Visual
+ check_cursor_col(); // make sure cursor is not beyond EOL
curwin->w_set_curswant = true;
redraw_curbuf_later(INVERTED);
} else if (no_reason) {
@@ -7624,9 +7888,9 @@ static void nv_esc(cmdarg_T *cap)
/* A CTRL-C is often used at the start of a menu. When 'insertmode' is
* set return to Insert mode afterwards. */
if (restart_edit == 0 && goto_im()
- && ex_normal_busy == 0
- )
+ && ex_normal_busy == 0) {
restart_edit = 'a';
+ }
}
// Move the cursor for the "A" command.
@@ -7657,7 +7921,7 @@ static void nv_edit(cmdarg_T *cap)
// in Visual mode "A" and "I" are an operator
if (VIsual_active && (cap->cmdchar == 'A' || cap->cmdchar == 'I')) {
v_visop(cap);
- // in Visual mode and after an operator "a" and "i" are for text objects
+ // in Visual mode and after an operator "a" and "i" are for text objects
} else if ((cap->cmdchar == 'a' || cap->cmdchar == 'i')
&& (cap->oap->op_type != OP_NOP || VIsual_active)) {
nv_object(cap);
@@ -7671,20 +7935,21 @@ static void nv_edit(cmdarg_T *cap)
set_cursor_for_append_to_line();
break;
- case 'I': /* "I"nsert before the first non-blank */
+ case 'I': // "I"nsert before the first non-blank
beginline(BL_WHITE);
break;
- case 'a': /* "a"ppend is like "i"nsert on the next character. */
+ case 'a': // "a"ppend is like "i"nsert on the next character.
/* increment coladd when in virtual space, increment the
* column otherwise, also to append after an unprintable char */
if (virtual_active()
&& (curwin->w_cursor.coladd > 0
|| *get_cursor_pos_ptr() == NUL
- || *get_cursor_pos_ptr() == TAB))
+ || *get_cursor_pos_ptr() == TAB)) {
curwin->w_cursor.coladd++;
- else if (*get_cursor_pos_ptr() != NUL)
+ } else if (*get_cursor_pos_ptr() != NUL) {
inc_cursor();
+ }
break;
}
@@ -7702,35 +7967,32 @@ static void nv_edit(cmdarg_T *cap)
}
}
-/*
- * Invoke edit() and take care of "restart_edit" and the return value.
- */
-static void
-invoke_edit (
- cmdarg_T *cap,
- int repl, /* "r" or "gr" command */
- int cmd,
- int startln
-)
+/// Invoke edit() and take care of "restart_edit" and the return value.
+///
+/// @param repl "r" or "gr" command
+static void invoke_edit(cmdarg_T *cap, int repl, int cmd, int startln)
{
int restart_edit_save = 0;
/* Complicated: When the user types "a<C-O>a" we don't want to do Insert
* mode recursively. But when doing "a<C-O>." or "a<C-O>rx" we do allow
* it. */
- if (repl || !stuff_empty())
+ if (repl || !stuff_empty()) {
restart_edit_save = restart_edit;
- else
+ } else {
restart_edit_save = 0;
+ }
- /* Always reset "restart_edit", this is not a restarted edit. */
+ // Always reset "restart_edit", this is not a restarted edit.
restart_edit = 0;
- if (edit(cmd, startln, cap->count1))
+ if (edit(cmd, startln, cap->count1)) {
cap->retval |= CA_COMMAND_BUSY;
+ }
- if (restart_edit == 0)
+ if (restart_edit == 0) {
restart_edit = restart_edit_save;
+ }
}
/*
@@ -7740,43 +8002,43 @@ static void nv_object(cmdarg_T *cap)
{
bool flag;
bool include;
- char_u *mps_save;
+ char_u *mps_save;
- if (cap->cmdchar == 'i')
- include = false; /* "ix" = inner object: exclude white space */
- else
- include = true; /* "ax" = an object: include white space */
-
- /* Make sure (), [], {} and <> are in 'matchpairs' */
+ if (cap->cmdchar == 'i') {
+ include = false; // "ix" = inner object: exclude white space
+ } else {
+ include = true; // "ax" = an object: include white space
+ }
+ // Make sure (), [], {} and <> are in 'matchpairs'
mps_save = curbuf->b_p_mps;
curbuf->b_p_mps = (char_u *)"(:),{:},[:],<:>";
switch (cap->nchar) {
- case 'w': /* "aw" = a word */
+ case 'w': // "aw" = a word
flag = current_word(cap->oap, cap->count1, include, false);
break;
- case 'W': /* "aW" = a WORD */
+ case 'W': // "aW" = a WORD
flag = current_word(cap->oap, cap->count1, include, true);
break;
- case 'b': /* "ab" = a braces block */
+ case 'b': // "ab" = a braces block
case '(':
case ')':
flag = current_block(cap->oap, cap->count1, include, '(', ')');
break;
- case 'B': /* "aB" = a Brackets block */
+ case 'B': // "aB" = a Brackets block
case '{':
case '}':
flag = current_block(cap->oap, cap->count1, include, '{', '}');
break;
- case '[': /* "a[" = a [] block */
+ case '[': // "a[" = a [] block
case ']':
flag = current_block(cap->oap, cap->count1, include, '[', ']');
break;
- case '<': /* "a<" = a <> block */
+ case '<': // "a<" = a <> block
case '>':
flag = current_block(cap->oap, cap->count1, include, '<', '>');
break;
- case 't': /* "at" = a tag block (xml and html) */
+ case 't': // "at" = a tag block (xml and html)
// Do not adjust oap->end in do_pending_operator()
// otherwise there are different results for 'dit'
// (note leading whitespace in last line):
@@ -7786,17 +8048,17 @@ static void nv_object(cmdarg_T *cap)
cap->retval |= CA_NO_ADJ_OP_END;
flag = current_tagblock(cap->oap, cap->count1, include);
break;
- case 'p': /* "ap" = a paragraph */
+ case 'p': // "ap" = a paragraph
flag = current_par(cap->oap, cap->count1, include, 'p');
break;
- case 's': /* "as" = a sentence */
+ case 's': // "as" = a sentence
flag = current_sent(cap->oap, cap->count1, include);
break;
- case '"': /* "a"" = a double quoted string */
- case '\'': /* "a'" = a single quoted string */
- case '`': /* "a`" = a backtick quoted string */
+ case '"': // "a"" = a double quoted string
+ case '\'': // "a'" = a single quoted string
+ case '`': // "a`" = a backtick quoted string
flag = current_quote(cap->oap, cap->count1, include,
- cap->nchar);
+ cap->nchar);
break;
default:
flag = false;
@@ -7804,8 +8066,9 @@ static void nv_object(cmdarg_T *cap)
}
curbuf->b_p_mps = mps_save;
- if (!flag)
+ if (!flag) {
clearopbeep(cap->oap);
+ }
adjust_cursor_col();
curwin->w_set_curswant = true;
}
@@ -7817,7 +8080,7 @@ static void nv_object(cmdarg_T *cap)
static void nv_record(cmdarg_T *cap)
{
if (cap->oap->op_type == OP_FORMAT) {
- /* "gqq" is the same as "gqgq": format line */
+ // "gqq" is the same as "gqgq": format line
cap->cmdchar = 'g';
cap->nchar = 'q';
nv_operator(cap);
@@ -7840,11 +8103,13 @@ static void nv_record(cmdarg_T *cap)
*/
static void nv_at(cmdarg_T *cap)
{
- if (checkclearop(cap->oap))
+ if (checkclearop(cap->oap)) {
return;
+ }
if (cap->nchar == '=') {
- if (get_expr_register() == NUL)
+ if (get_expr_register() == NUL) {
return;
+ }
}
while (cap->count1-- && !got_int) {
if (do_execreg(cap->nchar, false, false, false) == false) {
@@ -7862,10 +8127,11 @@ static void nv_halfpage(cmdarg_T *cap)
{
if ((cap->cmdchar == Ctrl_U && curwin->w_cursor.lnum == 1)
|| (cap->cmdchar == Ctrl_D
- && curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count))
+ && curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count)) {
clearopbeep(cap->oap);
- else if (!checkclearop(cap->oap))
+ } else if (!checkclearop(cap->oap)) {
halfpage(cap->cmdchar == Ctrl_D, cap->count0);
+ }
}
/*
@@ -7915,7 +8181,7 @@ static void nv_put_opt(cmdarg_T *cap, bool fix_indent)
int flags = 0;
if (cap->oap->op_type != OP_NOP) {
- /* "dp" is ":diffput" */
+ // "dp" is ":diffput"
if (cap->oap->op_type == OP_DELETE && cap->cmdchar == 'p') {
clearop(cap->oap);
assert(cap->opcount >= 0);
@@ -7952,7 +8218,7 @@ static void nv_put_opt(cmdarg_T *cap, bool fix_indent)
regname = cap->oap->regname;
// '+' and '*' could be the same selection
bool clipoverwrite = (regname == '+' || regname == '*')
- && (cb_flags & CB_UNNAMEDMASK);
+ && (cb_flags & CB_UNNAMEDMASK);
if (regname == 0 || regname == '"' || clipoverwrite
|| ascii_isdigit(regname) || regname == '-') {
// The delete might overwrite the register we want to put, save it first
@@ -7993,11 +8259,12 @@ static void nv_put_opt(cmdarg_T *cap, bool fix_indent)
if ((VIsual_mode != 'V'
&& curwin->w_cursor.col < curbuf->b_op_start.col)
|| (VIsual_mode == 'V'
- && curwin->w_cursor.lnum < curbuf->b_op_start.lnum))
+ && curwin->w_cursor.lnum < curbuf->b_op_start.lnum)) {
/* cursor is at the end of the line or end of file, put
* forward. */
dir = FORWARD;
- /* May have been reset in do_put(). */
+ }
+ // May have been reset in do_put().
VIsual_active = true;
}
do_put(cap->oap->regname, savereg, dir, cap->count1, flags);
@@ -8041,7 +8308,7 @@ static void nv_put_opt(cmdarg_T *cap, bool fix_indent)
*/
static void nv_open(cmdarg_T *cap)
{
- /* "do" is ":diffget" */
+ // "do" is ":diffget"
if (cap->oap->op_type == OP_DELETE && cap->cmdchar == 'o') {
clearop(cap->oap);
assert(cap->opcount >= 0);
@@ -8056,12 +8323,10 @@ static void nv_open(cmdarg_T *cap)
}
}
-// Calculate start/end virtual columns for operating in block mode.
-static void get_op_vcol(
- oparg_T *oap,
- colnr_T redo_VIsual_vcol,
- bool initial // when true: adjust position for 'selectmode'
-)
+/// Calculate start/end virtual columns for operating in block mode.
+///
+/// @param initial when true: adjust position for 'selectmode'
+static void get_op_vcol(oparg_T *oap, colnr_T redo_VIsual_vcol, bool initial)
{
colnr_T start;
colnr_T end;
@@ -8136,20 +8401,18 @@ static void nv_event(cmdarg_T *cap)
// not safe to perform garbage collection because there could be unreferenced
// lists or dicts being used.
may_garbage_collect = false;
- bool may_restart = (restart_edit != 0);
+ bool may_restart = (restart_edit != 0 || restart_VIsual_select != 0);
state_handle_k_event();
finish_op = false;
if (may_restart) {
// Tricky: if restart_edit was set before the handler we are in ctrl-o mode,
// but if not, the event should be allowed to trigger :startinsert.
- cap->retval |= CA_COMMAND_BUSY; // don't call edit() now
+ cap->retval |= CA_COMMAND_BUSY; // don't call edit() or restart Select now
}
}
-/*
- * Return TRUE when 'mousemodel' is set to "popup" or "popup_setpos".
- */
-static int mouse_model_popup(void)
+/// @return true when 'mousemodel' is set to "popup" or "popup_setpos".
+static bool mouse_model_popup(void)
{
return p_mousem[0] == 'p';
}
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index 855f63ba7b..1d737ee9fc 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -11,27 +11,27 @@
#include <stdbool.h>
#include <string.h>
-#include "nvim/vim.h"
#include "nvim/ascii.h"
-#include "nvim/ops.h"
+#include "nvim/assert.h"
#include "nvim/buffer.h"
#include "nvim/change.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
-#include "nvim/assert.h"
#include "nvim/edit.h"
#include "nvim/eval.h"
#include "nvim/eval/typval.h"
#include "nvim/ex_cmds.h"
#include "nvim/ex_cmds2.h"
#include "nvim/ex_getln.h"
+#include "nvim/extmark.h"
#include "nvim/fileio.h"
#include "nvim/fold.h"
#include "nvim/getchar.h"
#include "nvim/indent.h"
+#include "nvim/lib/kvec.h"
#include "nvim/log.h"
+#include "nvim/macros.h"
#include "nvim/mark.h"
-#include "nvim/extmark.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
@@ -39,8 +39,12 @@
#include "nvim/misc1.h"
#include "nvim/move.h"
#include "nvim/normal.h"
+#include "nvim/ops.h"
#include "nvim/option.h"
+#include "nvim/os/input.h"
+#include "nvim/os/time.h"
#include "nvim/path.h"
+#include "nvim/plines.h"
#include "nvim/screen.h"
#include "nvim/search.h"
#include "nvim/state.h"
@@ -48,15 +52,12 @@
#include "nvim/terminal.h"
#include "nvim/ui.h"
#include "nvim/undo.h"
-#include "nvim/macros.h"
+#include "nvim/vim.h"
#include "nvim/window.h"
-#include "nvim/lib/kvec.h"
-#include "nvim/os/input.h"
-#include "nvim/os/time.h"
static yankreg_T y_regs[NUM_REGISTERS];
-static yankreg_T *y_previous = NULL; /* ptr to last written yankreg */
+static yankreg_T *y_previous = NULL; // ptr to last written yankreg
// for behavior between start_batch_changes() and end_batch_changes())
static int batch_change_count = 0; // inside a script
@@ -69,20 +70,20 @@ static bool clipboard_didwarn = false;
* also op_change, op_shift, op_insert, op_replace - AKelly
*/
struct block_def {
- int startspaces; /* 'extra' cols before first char */
- int endspaces; /* 'extra' cols after last char */
- int textlen; /* chars in block */
- char_u *textstart; /* pointer to 1st char (partially) in block */
- colnr_T textcol; /* index of chars (partially) in block */
- colnr_T start_vcol; /* start col of 1st char wholly inside block */
- colnr_T end_vcol; /* start col of 1st char wholly after block */
- int is_short; /* TRUE if line is too short to fit in block */
- int is_MAX; /* TRUE if curswant==MAXCOL when starting */
- int is_oneChar; /* TRUE if block within one character */
- int pre_whitesp; /* screen cols of ws before block */
- int pre_whitesp_c; /* chars of ws before block */
- colnr_T end_char_vcols; /* number of vcols of post-block char */
- colnr_T start_char_vcols; /* number of vcols of pre-block char */
+ int startspaces; // 'extra' cols before first char
+ int endspaces; // 'extra' cols after last char
+ int textlen; // chars in block
+ char_u *textstart; // pointer to 1st char (partially) in block
+ colnr_T textcol; // index of chars (partially) in block
+ colnr_T start_vcol; // start col of 1st char wholly inside block
+ colnr_T end_vcol; // start col of 1st char wholly after block
+ int is_short; // TRUE if line is too short to fit in block
+ int is_MAX; // TRUE if curswant==MAXCOL when starting
+ int is_oneChar; // TRUE if block within one character
+ int pre_whitesp; // screen cols of ws before block
+ int pre_whitesp_c; // chars of ws before block
+ colnr_T end_char_vcols; // number of vcols of post-block char
+ colnr_T start_char_vcols; // number of vcols of pre-block char
};
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -182,7 +183,7 @@ int op_on_lines(int op)
// Return TRUE if operator "op" changes text.
int op_is_change(int op)
{
- return opchars[op][2] & OPF_CHANGE;
+ return opchars[op][2] & OPF_CHANGE;
}
/*
@@ -209,12 +210,13 @@ void op_shift(oparg_T *oap, int curs_top, int amount)
{
long i;
int first_char;
- char_u *s;
+ char_u *s;
int block_col = 0;
if (u_save((linenr_T)(oap->start.lnum - 1),
- (linenr_T)(oap->end.lnum + 1)) == FAIL)
+ (linenr_T)(oap->end.lnum + 1)) == FAIL) {
return;
+ }
if (oap->motion_type == kMTBlockWise) {
block_col = curwin->w_cursor.col;
@@ -237,32 +239,35 @@ void op_shift(oparg_T *oap, int curs_top, int amount)
if (oap->motion_type == kMTBlockWise) {
curwin->w_cursor.lnum = oap->start.lnum;
curwin->w_cursor.col = block_col;
- } else if (curs_top) { /* put cursor on first line, for ">>" */
+ } else if (curs_top) { // put cursor on first line, for ">>"
curwin->w_cursor.lnum = oap->start.lnum;
- beginline(BL_SOL | BL_FIX); /* shift_line() may have set cursor.col */
- } else
- --curwin->w_cursor.lnum; /* put cursor on last line, for ":>" */
-
+ beginline(BL_SOL | BL_FIX); // shift_line() may have set cursor.col
+ } else {
+ --curwin->w_cursor.lnum; // put cursor on last line, for ":>"
+ }
// The cursor line is not in a closed fold
foldOpenCursor();
if (oap->line_count > p_report) {
- if (oap->op_type == OP_RSHIFT)
+ if (oap->op_type == OP_RSHIFT) {
s = (char_u *)">";
- else
+ } else {
s = (char_u *)"<";
+ }
if (oap->line_count == 1) {
- if (amount == 1)
+ if (amount == 1) {
sprintf((char *)IObuff, _("1 line %sed 1 time"), s);
- else
+ } else {
sprintf((char *)IObuff, _("1 line %sed %d times"), s, amount);
+ }
} else {
- if (amount == 1)
+ if (amount == 1) {
sprintf((char *)IObuff, _("%" PRId64 " lines %sed 1 time"),
- (int64_t)oap->line_count, s);
- else
+ (int64_t)oap->line_count, s);
+ } else {
sprintf((char *)IObuff, _("%" PRId64 " lines %sed %d times"),
- (int64_t)oap->line_count, s, amount);
+ (int64_t)oap->line_count, s, amount);
+ }
}
msg_attr_keep(IObuff, 0, true, false);
}
@@ -280,14 +285,11 @@ void op_shift(oparg_T *oap, int curs_top, int amount)
changed_lines(oap->start.lnum, 0, oap->end.lnum + 1, 0L, true);
}
-// Shift the current line one shiftwidth left (if left != 0) or right
-// leaves cursor on first blank in the line.
-void shift_line(
- int left,
- int round,
- int amount,
- int call_changed_bytes // call changed_bytes()
-)
+/// Shift the current line one shiftwidth left (if left != 0) or right
+/// leaves cursor on first blank in the line.
+///
+/// @param call_changed_bytes call changed_bytes()
+void shift_line(int left, int round, int amount, int call_changed_bytes)
{
int count;
int i, j;
@@ -303,18 +305,22 @@ void shift_line(
}
if (left) {
i -= amount;
- if (i < 0)
+ if (i < 0) {
i = 0;
- } else
+ }
+ } else {
i += amount;
+ }
count = i * p_sw;
} else { // original vi indent
if (left) {
count -= p_sw * amount;
- if (count < 0)
+ if (count < 0) {
count = 0;
- } else
+ }
+ } else {
count += p_sw * amount;
+ }
}
// Set new indent
@@ -343,7 +349,7 @@ static void shift_block(oparg_T *oap, int amount)
int i = 0, j = 0;
const int old_p_ri = p_ri;
- p_ri = 0; /* don't want revins in indent */
+ p_ri = 0; // don't want revins in indent
State = INSERT; // don't want REPLACE for State
block_prep(oap, &bd, curwin->w_cursor.lnum, true);
@@ -381,7 +387,7 @@ static void shift_block(oparg_T *oap, int amount)
}
for (; ascii_iswhite(*bd.textstart); ) {
// TODO: is passing bd.textstart for start of the line OK?
- incr = lbr_chartabsize_adv(bd.textstart, &bd.textstart, (colnr_T)(bd.start_vcol));
+ incr = lbr_chartabsize_adv(bd.textstart, &bd.textstart, (bd.start_vcol));
total += incr;
bd.start_vcol += incr;
}
@@ -407,7 +413,7 @@ static void shift_block(oparg_T *oap, int amount)
newlen = i+j;
memset(newp + bd.textcol, TAB, (size_t)i);
memset(newp + bd.textcol + i, ' ', (size_t)j);
- /* the end */
+ // the end
memmove(newp + bd.textcol + i + j, bd.textstart, (size_t)len);
} else { // left
colnr_T destination_col; // column to which text in block will
@@ -419,7 +425,7 @@ static void shift_block(oparg_T *oap, int amount)
size_t fill; // nr of spaces that replace a TAB
size_t new_line_len; // the length of the line after the
// block shift
- char_u *non_white = bd.textstart;
+ char_u *non_white = bd.textstart;
/*
* Firstly, let's find the first non-whitespace character that is
@@ -461,15 +467,17 @@ static void shift_block(oparg_T *oap, int amount)
/* If "bd.startspaces" is set, "bd.textstart" points to the character
* preceding the block. We have to subtract its width to obtain its
* column number. */
- if (bd.startspaces)
+ if (bd.startspaces) {
verbatim_copy_width -= bd.start_char_vcols;
+ }
while (verbatim_copy_width < destination_col) {
char_u *line = verbatim_copy_end;
// TODO: is passing verbatim_copy_end for start of the line OK?
incr = lbr_chartabsize(line, verbatim_copy_end, verbatim_copy_width);
- if (verbatim_copy_width + incr > destination_col)
+ if (verbatim_copy_width + incr > destination_col) {
break;
+ }
verbatim_copy_width += incr;
MB_PTR_ADV(verbatim_copy_end);
}
@@ -498,7 +506,7 @@ static void shift_block(oparg_T *oap, int amount)
}
// replace the line
ml_replace(curwin->w_cursor.lnum, newp, false);
- changed_bytes(curwin->w_cursor.lnum, (colnr_T)bd.textcol);
+ changed_bytes(curwin->w_cursor.lnum, bd.textcol);
extmark_splice_cols(curbuf, (int)curwin->w_cursor.lnum-1, startcol,
oldlen, newlen,
kExtmarkUndo);
@@ -518,7 +526,7 @@ static void block_insert(oparg_T *oap, char_u *s, int b_insert, struct block_def
int spaces = 0; // non-zero if cutting a TAB
colnr_T offset; // pointer along new line
size_t s_len = STRLEN(s);
- char_u *newp, *oldp; // new, old lines
+ char_u *newp, *oldp; // new, old lines
linenr_T lnum; // loop var
int oldstate = State;
State = INSERT; // don't want REPLACE for State
@@ -534,20 +542,23 @@ static void block_insert(oparg_T *oap, char_u *s, int b_insert, struct block_def
if (b_insert) {
p_ts = bdp->start_char_vcols;
spaces = bdp->startspaces;
- if (spaces != 0)
- count = p_ts - 1; /* we're cutting a TAB */
+ if (spaces != 0) {
+ count = p_ts - 1; // we're cutting a TAB
+ }
offset = bdp->textcol;
- } else { /* append */
+ } else { // append
p_ts = bdp->end_char_vcols;
- if (!bdp->is_short) { /* spaces = padding after block */
+ if (!bdp->is_short) { // spaces = padding after block
spaces = (bdp->endspaces ? p_ts - bdp->endspaces : 0);
- if (spaces != 0)
- count = p_ts - 1; /* we're cutting a TAB */
+ if (spaces != 0) {
+ count = p_ts - 1; // we're cutting a TAB
+ }
offset = bdp->textcol + bdp->textlen - (spaces != 0);
- } else { /* spaces = padding to block edge */
- /* if $ used, just append to EOL (ie spaces==0) */
- if (!bdp->is_MAX)
+ } else { // spaces = padding to block edge
+ // if $ used, just append to EOL (ie spaces==0)
+ if (!bdp->is_MAX) {
spaces = (oap->end_vcol - bdp->end_vcol) + 1;
+ }
count = spaces;
offset = bdp->textcol + bdp->textlen;
}
@@ -593,8 +604,9 @@ static void block_insert(oparg_T *oap, char_u *s, int b_insert, struct block_def
skipped = 1;
}
- if (spaces > 0)
+ if (spaces > 0) {
offset += count;
+ }
STRMOVE(newp + offset, oldp);
ml_replace(lnum, newp, false);
@@ -607,7 +619,7 @@ static void block_insert(oparg_T *oap, char_u *s, int b_insert, struct block_def
curbuf->b_op_end.lnum = oap->end.lnum;
curbuf->b_op_end.col = offset;
}
- } /* for all lnum */
+ } // for all lnum
changed_lines(oap->start.lnum + 1, 0, oap->end.lnum + 1, 0L, true);
@@ -620,13 +632,13 @@ static void block_insert(oparg_T *oap, char_u *s, int b_insert, struct block_def
void op_reindent(oparg_T *oap, Indenter how)
{
long i;
- char_u *l;
+ char_u *l;
int amount;
linenr_T first_changed = 0;
linenr_T last_changed = 0;
linenr_T start_lnum = curwin->w_cursor.lnum;
- /* Don't even try when 'modifiable' is off. */
+ // Don't even try when 'modifiable' is off.
if (!MODIFIABLE(curbuf)) {
EMSG(_(e_modifiable));
return;
@@ -638,8 +650,9 @@ void op_reindent(oparg_T *oap, Indenter how)
if (i > 1
&& (i % 50 == 0 || i == oap->line_count - 1)
- && oap->line_count > p_report)
+ && oap->line_count > p_report) {
smsg(_("%" PRId64 " lines to indent... "), (int64_t)i);
+ }
/*
* Be vi-compatible: For lisp indenting the first line is not
@@ -648,11 +661,11 @@ void op_reindent(oparg_T *oap, Indenter how)
if (i != oap->line_count - 1 || oap->line_count == 1
|| how != get_lisp_indent) {
l = skipwhite(get_cursor_line_ptr());
- if (*l == NUL) /* empty or blank line */
+ if (*l == NUL) { // empty or blank line
amount = 0;
- else
- amount = how(); /* get the indent for this line */
-
+ } else {
+ amount = how(); // get the indent for this line
+ }
if (amount >= 0 && set_indent(amount, SIN_UNDO)) {
// did change the indent, call changed_lines() later
if (first_changed == 0) {
@@ -662,10 +675,10 @@ void op_reindent(oparg_T *oap, Indenter how)
}
}
++curwin->w_cursor.lnum;
- curwin->w_cursor.col = 0; /* make sure it's valid */
+ curwin->w_cursor.col = 0; // make sure it's valid
}
- /* put cursor on first non-blank of indented line */
+ // put cursor on first non-blank of indented line
curwin->w_cursor.lnum = start_lnum;
beginline(BL_SOL | BL_FIX);
@@ -682,12 +695,13 @@ void op_reindent(oparg_T *oap, Indenter how)
if (oap->line_count > p_report) {
i = oap->line_count - (i + 1);
- if (i == 1)
+ if (i == 1) {
MSG(_("1 line indented "));
- else
+ } else {
smsg(_("%" PRId64 " lines indented "), (int64_t)i);
+ }
}
- /* set '[ and '] marks */
+ // set '[ and '] marks
curbuf->b_op_start = oap->start;
curbuf->b_op_end = oap->end;
}
@@ -695,7 +709,7 @@ void op_reindent(oparg_T *oap, Indenter how)
/*
* Keep the last expression line here, for repeating.
*/
-static char_u *expr_line = NULL;
+static char_u *expr_line = NULL;
/*
* Get an expression for the "\"=expr1" or "CTRL-R =expr1"
@@ -703,7 +717,7 @@ static char_u *expr_line = NULL;
*/
int get_expr_register(void)
{
- char_u *new_line;
+ char_u *new_line;
new_line = getcmdline('=', 0L, 0, true);
if (new_line == NULL) {
@@ -733,12 +747,13 @@ void set_expr_line(char_u *new_line)
*/
char_u *get_expr_line(void)
{
- char_u *expr_copy;
- char_u *rv;
+ char_u *expr_copy;
+ char_u *rv;
static int nested = 0;
- if (expr_line == NULL)
+ if (expr_line == NULL) {
return NULL;
+ }
/* Make a copy of the expression, because evaluating it may cause it to be
* changed. */
@@ -746,12 +761,13 @@ char_u *get_expr_line(void)
/* When we are invoked recursively limit the evaluation to 10 levels.
* Then return the string as-is. */
- if (nested >= 10)
+ if (nested >= 10) {
return expr_copy;
+ }
- ++nested;
- rv = eval_to_string(expr_copy, NULL, TRUE);
- --nested;
+ nested++;
+ rv = eval_to_string(expr_copy, NULL, true);
+ nested--;
xfree(expr_copy);
return rv;
}
@@ -761,8 +777,9 @@ char_u *get_expr_line(void)
*/
char_u *get_expr_line_src(void)
{
- if (expr_line == NULL)
+ if (expr_line == NULL) {
return NULL;
+ }
return vim_strsave(expr_line);
}
@@ -775,7 +792,7 @@ char_u *get_expr_line_src(void)
bool valid_yank_reg(int regname, bool writing)
{
if ((regname > 0 && ASCII_ISALNUM(regname))
- || (!writing && vim_strchr((char_u *) "/.%:=" , regname) != NULL)
+ || (!writing && vim_strchr((char_u *)"/.%:=", regname) != NULL)
|| regname == '#'
|| regname == '"'
|| regname == '-'
@@ -787,12 +804,6 @@ bool valid_yank_reg(int regname, bool writing)
return false;
}
-typedef enum {
- YREG_PASTE,
- YREG_YANK,
- YREG_PUT,
-} yreg_mode_t;
-
/// 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!
@@ -819,8 +830,8 @@ yankreg_T *get_yank_register(int regname, int mode)
// reg is set to clipboard contents.
return reg;
} else if (mode != YREG_YANK
- && (regname == 0 || regname == '"' || regname == '*' || regname == '+')
- && y_previous != NULL) {
+ && (regname == 0 || regname == '"' || regname == '*' || regname == '+')
+ && y_previous != NULL) {
// in case clipboard not available, paste from previous used register
return y_previous;
}
@@ -893,9 +904,9 @@ bool yank_register_mline(int regname)
*/
int do_record(int c)
{
- char_u *p;
+ char_u *p;
static int regname;
- yankreg_T *old_y_previous;
+ yankreg_T *old_y_previous;
int retval;
if (reg_recording == 0) {
@@ -909,7 +920,7 @@ int do_record(int c)
regname = c;
retval = OK;
}
- } else { /* stop recording */
+ } else { // stop recording
/*
* Get the recorded key hits. K_SPECIAL and CSI will be escaped, this
* needs to be removed again to put it in a register. exec_reg then
@@ -922,10 +933,10 @@ int do_record(int c)
MSG("");
}
p = get_recorded();
- if (p == NULL)
+ if (p == NULL) {
retval = FAIL;
- else {
- /* Remove escaping for CSI and K_SPECIAL in multi-byte chars. */
+ } else {
+ // Remove escaping for CSI and K_SPECIAL in multi-byte chars.
vim_unescape_csi(p);
/*
@@ -954,18 +965,18 @@ static void set_yreg_additional_data(yankreg_T *reg, dict_T *additional_data)
/*
* Stuff string "p" into yank register "regname" as a single line (append if
- * uppercase). "p" must have been alloced.
+ * uppercase). "p" must have been allocated.
*
* return FAIL for failure, OK otherwise
*/
static int stuff_yank(int regname, char_u *p)
{
- /* check for read-only register */
+ // check for read-only register
if (regname != 0 && !valid_yank_reg(regname, true)) {
xfree(p);
return FAIL;
}
- if (regname == '_') { /* black hole: don't do anything */
+ if (regname == '_') { // black hole: don't do anything
xfree(p);
return OK;
}
@@ -995,36 +1006,35 @@ static int execreg_lastc = NUL;
/// Execute a yank register: copy it into the stuff buffer
///
-/// Return FAIL for failure, OK otherwise
-int
-do_execreg(
- int regname,
- int colon, /* insert ':' before each line */
- int addcr, /* always add '\n' to end of line */
- int silent /* set "silent" flag in typeahead buffer */
-)
+/// @param colon insert ':' before each line
+/// @param addcr always add '\n' to end of line
+/// @param silent set "silent" flag in typeahead buffer
+///
+/// @return FAIL for failure, OK otherwise
+int do_execreg(int regname, int colon, int addcr, int silent)
{
char_u *p;
int retval = OK;
- if (regname == '@') { /* repeat previous one */
+ if (regname == '@') { // repeat previous one
if (execreg_lastc == NUL) {
EMSG(_("E748: No previously used register"));
return FAIL;
}
regname = execreg_lastc;
}
- /* check for valid regname */
+ // check for valid regname
if (regname == '%' || regname == '#' || !valid_yank_reg(regname, false)) {
emsg_invreg(regname);
return FAIL;
}
execreg_lastc = regname;
- if (regname == '_') /* black hole: don't stuff anything */
+ if (regname == '_') { // black hole: don't stuff anything
return OK;
+ }
- if (regname == ':') { /* use last command line */
+ if (regname == ':') { // use last command line
if (last_cmdline == NULL) {
EMSG(_(e_nolastcmd));
return FAIL;
@@ -1032,13 +1042,12 @@ do_execreg(
// don't keep the cmdline containing @:
XFREE_CLEAR(new_last_cmdline);
// Escape all control characters with a CTRL-V
- p = vim_strsave_escaped_ext(
- last_cmdline,
- (char_u *)"\001\002\003\004\005\006\007"
- "\010\011\012\013\014\015\016\017"
- "\020\021\022\023\024\025\026\027"
- "\030\031\032\033\034\035\036\037",
- Ctrl_V, false);
+ p = vim_strsave_escaped_ext(last_cmdline,
+ (char_u *)"\001\002\003\004\005\006\007"
+ "\010\011\012\013\014\015\016\017"
+ "\020\021\022\023\024\025\026\027"
+ "\030\031\032\033\034\035\036\037",
+ Ctrl_V, false);
// When in Visual mode "'<,'>" will be prepended to the command.
// Remove it when it's already there.
if (VIsual_active && STRNCMP(p, "'<,'>", 5) == 0) {
@@ -1049,11 +1058,12 @@ do_execreg(
xfree(p);
} else if (regname == '=') {
p = get_expr_line();
- if (p == NULL)
+ if (p == NULL) {
return FAIL;
+ }
retval = put_in_typebuf(p, true, colon, silent);
xfree(p);
- } else if (regname == '.') { /* use last inserted text */
+ } else if (regname == '.') { // use last inserted text
p = get_last_insert_save();
if (p == NULL) {
EMSG(_(e_noinstext));
@@ -1063,10 +1073,11 @@ do_execreg(
xfree(p);
} else {
yankreg_T *reg = get_yank_register(regname, YREG_PASTE);
- if (reg->y_array == NULL)
+ if (reg->y_array == NULL) {
return FAIL;
+ }
- // Disallow remaping for ":@r".
+ // Disallow remapping for ":@r".
int remap = colon ? REMAP_NONE : REMAP_YES;
/*
@@ -1120,18 +1131,13 @@ static void put_reedit_in_typebuf(int silent)
}
}
-/*
- * Insert register contents "s" into the typeahead buffer, so that it will be
- * executed again.
- * When "esc" is TRUE it is to be taken literally: Escape CSI characters and
- * no remapping.
- */
-static int put_in_typebuf(
- char_u *s,
- bool esc,
- bool colon, // add ':' before the line
- int silent
-)
+/// Insert register contents "s" into the typeahead buffer, so that it will be
+/// executed again.
+///
+/// @param esc when true then it is to be taken literally: Escape CSI
+/// characters and no remapping.
+/// @param colon add ':' before the line
+static int put_in_typebuf(char_u *s, bool esc, bool colon, int silent)
{
int retval = OK;
@@ -1140,7 +1146,7 @@ static int put_in_typebuf(
retval = ins_typebuf((char_u *)"\n", REMAP_NONE, 0, true, silent);
}
if (retval == OK) {
- char_u *p;
+ char_u *p;
if (esc) {
p = vim_strsave_escape_csi(s);
@@ -1162,16 +1168,13 @@ static int put_in_typebuf(
return retval;
}
-/*
- * Insert a yank register: copy it into the Read buffer.
- * Used by CTRL-R command and middle mouse button in insert mode.
- *
- * return FAIL for failure, OK otherwise
- */
-int insert_reg(
- int regname,
- bool literally_arg // insert literally, not as if typed
-)
+/// Insert a yank register: copy it into the Read buffer.
+/// Used by CTRL-R command and middle mouse button in insert mode.
+///
+/// @param literally_arg insert literally, not as if typed
+///
+/// @return FAIL for failure, OK otherwise
+int insert_reg(int regname, bool literally_arg)
{
int retval = OK;
bool allocated;
@@ -1183,12 +1186,14 @@ int insert_reg(
* If you hit CTRL-C, the loop will be broken here.
*/
os_breakcheck();
- if (got_int)
+ if (got_int) {
return FAIL;
+ }
- /* check for valid regname */
- if (regname != NUL && !valid_yank_reg(regname, false))
+ // check for valid regname
+ if (regname != NUL && !valid_yank_reg(regname, false)) {
return FAIL;
+ }
char_u *arg;
if (regname == '.') { // Insert last inserted text.
@@ -1226,26 +1231,24 @@ int insert_reg(
return retval;
}
-/*
- * Stuff a string into the typeahead buffer, such that edit() will insert it
- * literally ("literally" TRUE) or interpret is as typed characters.
- */
-static void stuffescaped(const char *arg, int literally)
+/// Stuff a string into the typeahead buffer, such that edit() will insert it
+/// literally ("literally" true) or interpret is as typed characters.
+static void stuffescaped(const char *arg, bool literally)
{
while (*arg != NUL) {
// Stuff a sequence of normal ASCII characters, that's fast. Also
// stuff K_SPECIAL to get the effect of a special key when "literally"
- // is TRUE.
+ // is true.
const char *const start = arg;
while ((*arg >= ' ' && *arg < DEL) || ((uint8_t)(*arg) == K_SPECIAL
&& !literally)) {
arg++;
}
if (arg > start) {
- stuffReadbuffLen(start, (long)(arg - start));
+ stuffReadbuffLen(start, (arg - start));
}
- /* stuff a single special character */
+ // stuff a single special character
if (*arg != NUL) {
const int c = mb_cptr2char_adv((const char_u **)&arg);
if (literally && ((c < ' ' && c != TAB) || c == DEL)) {
@@ -1256,23 +1259,24 @@ static void stuffescaped(const char *arg, int literally)
}
}
-// If "regname" is a special register, return true and store a pointer to its
-// value in "argp".
-bool get_spec_reg(
- int regname,
- char_u **argp,
- bool *allocated, // return: true when value was allocated
- bool errmsg // give error message when failing
-)
+/// If "regname" is a special register, return true and store a pointer to its
+/// value in "argp".
+///
+/// @param allocated return: true when value was allocated
+/// @param errmsg give error message when failing
+///
+/// @return true if "regname" is a special register,
+bool get_spec_reg(int regname, char_u **argp, bool *allocated, bool errmsg)
{
size_t cnt;
*argp = NULL;
*allocated = false;
switch (regname) {
- case '%': /* file name */
- if (errmsg)
- check_fname(); /* will give emsg if not set */
+ case '%': // file name
+ if (errmsg) {
+ check_fname(); // will give emsg if not set
+ }
*argp = curbuf->b_fname;
return true;
@@ -1280,24 +1284,26 @@ bool get_spec_reg(
*argp = getaltfname(errmsg); // may give emsg if not set
return true;
- case '=': /* result of expression */
+ case '=': // result of expression
*argp = get_expr_line();
*allocated = true;
return true;
- case ':': /* last command line */
- if (last_cmdline == NULL && errmsg)
+ case ':': // last command line
+ if (last_cmdline == NULL && errmsg) {
EMSG(_(e_nolastcmd));
+ }
*argp = last_cmdline;
return true;
- case '/': /* last search-pattern */
- if (last_search_pat() == NULL && errmsg)
+ case '/': // last search-pattern
+ if (last_search_pat() == NULL && errmsg) {
EMSG(_(e_noprevre));
+ }
*argp = last_search_pat();
return true;
- case '.': /* last inserted text */
+ case '.': // last inserted text
*argp = get_last_insert_save();
*allocated = true;
if (*argp == NULL && errmsg) {
@@ -1310,9 +1316,8 @@ bool get_spec_reg(
if (!errmsg) {
return false;
}
- *argp = file_name_at_cursor(
- FNAME_MESS | FNAME_HYP | (regname == Ctrl_P ? FNAME_EXP : 0),
- 1L, NULL);
+ *argp = file_name_at_cursor(FNAME_MESS | FNAME_HYP | (regname == Ctrl_P ? FNAME_EXP : 0),
+ 1L, NULL);
*allocated = true;
return true;
@@ -1336,7 +1341,7 @@ bool get_spec_reg(
*argp = ml_get_buf(curwin->w_buffer, curwin->w_cursor.lnum, false);
return true;
- case '_': /* black hole: always empty */
+ case '_': // black hole: always empty
*argp = (char_u *)"";
return true;
}
@@ -1360,8 +1365,9 @@ bool cmdline_paste_reg(int regname, bool literally_arg, bool remcr)
const bool literally = literally_arg || is_literal_register(regname);
yankreg_T *reg = get_yank_register(regname, YREG_PASTE);
- if (reg->y_array == NULL)
+ if (reg->y_array == NULL) {
return FAIL;
+ }
for (size_t i = 0; i < reg->y_size; i++) {
cmdline_paste_str(reg->y_array[i], literally);
@@ -1374,8 +1380,9 @@ bool cmdline_paste_reg(int regname, bool literally_arg, bool remcr)
/* Check for CTRL-C, in case someone tries to paste a few thousand
* lines and gets bored. */
os_breakcheck();
- if (got_int)
+ if (got_int) {
return FAIL;
+ }
}
return OK;
}
@@ -1402,8 +1409,8 @@ int op_delete(oparg_T *oap)
{
int n;
linenr_T lnum;
- char_u *ptr;
- char_u *newp, *oldp;
+ char_u *ptr;
+ char_u *newp, *oldp;
struct block_def bd = { 0 };
linenr_T old_lcount = curbuf->b_ml.ml_line_count;
@@ -1434,8 +1441,9 @@ int op_delete(oparg_T *oap)
&& oap->motion_force == NUL
&& oap->op_type == OP_DELETE) {
ptr = ml_get(oap->end.lnum) + oap->end.col;
- if (*ptr != NUL)
+ if (*ptr != NUL) {
ptr += oap->inclusive;
+ }
ptr = skipwhite(ptr);
if (*ptr == NUL && inindent(0)) {
oap->motion_type = kMTLineWise;
@@ -1508,7 +1516,6 @@ int op_delete(oparg_T *oap)
set_clipboard(oap->regname, reg);
do_autocmd_textyankpost(oap, reg);
}
-
}
/*
@@ -1526,7 +1533,7 @@ int op_delete(oparg_T *oap)
continue;
}
- /* Adjust cursor position for tab replaced by spaces and 'lbr'. */
+ // Adjust cursor position for tab replaced by spaces and 'lbr'.
if (lnum == curwin->w_cursor.lnum) {
curwin->w_cursor.col = bd.textcol + bd.startspaces;
curwin->w_cursor.coladd = 0;
@@ -1566,12 +1573,13 @@ int op_delete(oparg_T *oap)
if (oap->line_count > 1) {
lnum = curwin->w_cursor.lnum;
- ++curwin->w_cursor.lnum;
- del_lines(oap->line_count - 1, TRUE);
+ curwin->w_cursor.lnum++;
+ del_lines(oap->line_count - 1, true);
curwin->w_cursor.lnum = lnum;
}
- if (u_save_cursor() == FAIL)
+ if (u_save_cursor() == FAIL) {
return FAIL;
+ }
if (curbuf->b_p_ai) { // don't delete indent
beginline(BL_WHITE); // cursor on first non-white
did_ai = true; // delete the indent when ESC hit
@@ -1587,25 +1595,27 @@ int op_delete(oparg_T *oap)
(int)curwin->w_cursor.lnum-1, curwin->w_cursor.col,
old_len - curwin->w_cursor.col, 0, kExtmarkUndo);
- // leave cursor past last char in line
+ // leave cursor past last char in line
if (oap->line_count > 1) {
u_clearline(); // "U" command not possible after "2cc"
}
} else {
- del_lines(oap->line_count, TRUE);
+ del_lines(oap->line_count, true);
beginline(BL_WHITE | BL_FIX);
- u_clearline(); /* "U" command not possible after "dd" */
+ u_clearline(); // "U" command not possible after "dd"
}
} else {
if (virtual_op) {
int endcol = 0;
- /* For virtualedit: break the tabs that are partly included. */
+ // For virtualedit: break the tabs that are partly included.
if (gchar_pos(&oap->start) == '\t') {
- if (u_save_cursor() == FAIL) /* save first line for undo */
+ if (u_save_cursor() == FAIL) { // save first line for undo
return FAIL;
- if (oap->line_count == 1)
+ }
+ if (oap->line_count == 1) {
endcol = getviscol2(oap->end.col, oap->end.coladd);
+ }
coladvance_force(getviscol2(oap->start.col, oap->start.coladd));
oap->start = curwin->w_cursor;
if (oap->line_count == 1) {
@@ -1616,14 +1626,15 @@ int op_delete(oparg_T *oap)
}
}
- /* Break a tab only when it's included in the area. */
+ // Break a tab only when it's included in the area.
if (gchar_pos(&oap->end) == '\t'
&& oap->end.coladd == 0
&& oap->inclusive) {
- /* save last line for undo */
+ // save last line for undo
if (u_save((linenr_T)(oap->end.lnum - 1),
- (linenr_T)(oap->end.lnum + 1)) == FAIL)
+ (linenr_T)(oap->end.lnum + 1)) == FAIL) {
return FAIL;
+ }
curwin->w_cursor = oap->end;
coladvance_force(getviscol2(oap->end.col, oap->end.coladd));
oap->end = curwin->w_cursor;
@@ -1632,17 +1643,18 @@ int op_delete(oparg_T *oap)
mb_adjust_opend(oap);
}
- if (oap->line_count == 1) { /* delete characters within one line */
- if (u_save_cursor() == FAIL) /* save line for undo */
+ if (oap->line_count == 1) { // delete characters within one line
+ if (u_save_cursor() == FAIL) { // save line for undo
return FAIL;
+ }
- /* if 'cpoptions' contains '$', display '$' at end of change */
- if ( vim_strchr(p_cpo, CPO_DOLLAR) != NULL
- && oap->op_type == OP_CHANGE
- && oap->end.lnum == curwin->w_cursor.lnum
- && !oap->is_VIsual
- )
+ // if 'cpoptions' contains '$', display '$' at end of change
+ if (vim_strchr(p_cpo, CPO_DOLLAR) != NULL
+ && oap->op_type == OP_CHANGE
+ && oap->end.lnum == curwin->w_cursor.lnum
+ && !oap->is_VIsual) {
display_dollar(oap->end.col - !oap->inclusive);
+ }
n = oap->end.col - oap->start.col + 1 - !oap->inclusive;
@@ -1650,20 +1662,23 @@ int op_delete(oparg_T *oap)
/* fix up things for virtualedit-delete:
* break the tabs which are going to get in our way
*/
- char_u *curline = get_cursor_line_ptr();
+ char_u *curline = get_cursor_line_ptr();
int len = (int)STRLEN(curline);
if (oap->end.coladd != 0
&& (int)oap->end.col >= len - 1
- && !(oap->start.coladd && (int)oap->end.col >= len - 1))
+ && !(oap->start.coladd && (int)oap->end.col >= len - 1)) {
n++;
- /* Delete at least one char (e.g, when on a control char). */
- if (n == 0 && oap->start.coladd != oap->end.coladd)
+ }
+ // Delete at least one char (e.g, when on a control char).
+ if (n == 0 && oap->start.coladd != oap->end.coladd) {
n = 1;
+ }
- /* When deleted a char in the line, reset coladd. */
- if (gchar_cursor() != NUL)
+ // When deleted a char in the line, reset coladd.
+ if (gchar_cursor() != NUL) {
curwin->w_cursor.coladd = 0;
+ }
}
(void)del_bytes((colnr_T)n, !virtual_op,
@@ -1672,16 +1687,17 @@ int op_delete(oparg_T *oap)
// delete characters between lines
pos_T curpos;
- /* save deleted and changed lines for undo */
+ // save deleted and changed lines for undo
if (u_save((linenr_T)(curwin->w_cursor.lnum - 1),
- (linenr_T)(curwin->w_cursor.lnum + oap->line_count)) == FAIL)
+ (linenr_T)(curwin->w_cursor.lnum + oap->line_count)) == FAIL) {
return FAIL;
+ }
curbuf_splice_pending++;
pos_T startpos = curwin->w_cursor; // start position for delete
- bcount_t deleted_bytes = get_region_bytecount(
- curbuf, startpos.lnum, oap->end.lnum, startpos.col,
- oap->end.col) + oap->inclusive;
+ bcount_t deleted_bytes = get_region_bytecount(curbuf, startpos.lnum, oap->end.lnum,
+ startpos.col,
+ oap->end.col) + oap->inclusive;
truncate_line(true); // delete from cursor to end of line
curpos = curwin->w_cursor; // remember curwin->w_cursor
@@ -1701,7 +1717,9 @@ int op_delete(oparg_T *oap)
(int)oap->line_count-1, n, deleted_bytes,
0, 0, 0, kExtmarkUndo);
}
- auto_format(false, true);
+ if (oap->op_type == OP_DELETE) {
+ auto_format(false, true);
+ }
}
msgmore(curbuf->b_ml.ml_line_count - old_lcount);
@@ -1724,7 +1742,7 @@ setmarks:
*/
static void mb_adjust_opend(oparg_T *oap)
{
- char_u *p;
+ char_u *p;
if (oap->inclusive) {
p = ml_get(oap->end.lnum);
@@ -1764,15 +1782,15 @@ int op_replace(oparg_T *oap, int c)
{
int n, numc;
int num_chars;
- char_u *newp, *oldp;
+ char_u *newp, *oldp;
colnr_T oldlen;
struct block_def bd;
- char_u *after_p = NULL;
+ char_u *after_p = NULL;
int had_ctrl_v_cr = false;
- if ((curbuf->b_ml.ml_flags & ML_EMPTY ) || oap->empty)
- return OK; /* nothing to do */
-
+ if ((curbuf->b_ml.ml_flags & ML_EMPTY ) || oap->empty) {
+ return OK; // nothing to do
+ }
if (c == REPLACE_CR_NCHAR) {
had_ctrl_v_cr = true;
c = CAR;
@@ -1784,8 +1802,9 @@ int op_replace(oparg_T *oap, int c)
mb_adjust_opend(oap);
if (u_save((linenr_T)(oap->start.lnum - 1),
- (linenr_T)(oap->end.lnum + 1)) == FAIL)
+ (linenr_T)(oap->end.lnum + 1)) == FAIL) {
return FAIL;
+ }
/*
* block mode replace
@@ -1812,18 +1831,20 @@ int op_replace(oparg_T *oap, int c)
getvpos(&vpos, oap->start_vcol);
bd.startspaces += vpos.coladd;
n = bd.startspaces;
- } else
- /* allow for pre spaces */
+ } else {
+ // allow for pre spaces
n = (bd.startspaces ? bd.start_char_vcols - 1 : 0);
+ }
- /* allow for post spp */
+ // allow for post spp
n += (bd.endspaces
&& !bd.is_oneChar
&& bd.end_char_vcols > 0) ? bd.end_char_vcols - 1 : 0;
- /* Figure out how many characters to replace. */
+ // Figure out how many characters to replace.
numc = oap->end_vcol - oap->start_vcol + 1;
- if (bd.is_short && (!virtual_op || bd.is_MAX))
+ if (bd.is_short && (!virtual_op || bd.is_MAX)) {
numc -= (oap->end_vcol - bd.end_vcol) + 1;
+ }
/* A double-wide character can be replaced only up to half the
* times. */
@@ -1835,7 +1856,7 @@ int op_replace(oparg_T *oap, int c)
numc = numc / 2;
}
- /* Compute bytes needed, move character count to num_chars. */
+ // Compute bytes needed, move character count to num_chars.
num_chars = numc;
numc *= (*mb_char2len)(c);
@@ -1863,19 +1884,19 @@ int op_replace(oparg_T *oap, int c)
assert(col >= 0);
int newrows = 0, newcols = 0;
if (had_ctrl_v_cr || (c != '\r' && c != '\n')) {
- // strlen(newp) at this point
- int newp_len = bd.textcol + bd.startspaces;
- while (--num_chars >= 0) {
- newp_len += utf_char2bytes(c, newp + newp_len);
- }
- if (!bd.is_short) {
- // insert post-spaces
- memset(newp + newp_len, ' ', (size_t)bd.endspaces);
- newp_len += bd.endspaces;
- // copy the part after the changed part
- memmove(newp + newp_len, oldp, (size_t)col);
- }
- newcols = newp_len - bd.textcol;
+ // strlen(newp) at this point
+ int newp_len = bd.textcol + bd.startspaces;
+ while (--num_chars >= 0) {
+ newp_len += utf_char2bytes(c, newp + newp_len);
+ }
+ if (!bd.is_short) {
+ // insert post-spaces
+ memset(newp + newp_len, ' ', (size_t)bd.endspaces);
+ newp_len += bd.endspaces;
+ // copy the part after the changed part
+ memmove(newp + newp_len, oldp, (size_t)col);
+ }
+ newcols = newp_len - bd.textcol;
} else {
// Replacing with \r or \n means splitting the line.
after_p_len = (size_t)col;
@@ -1904,10 +1925,12 @@ int op_replace(oparg_T *oap, int c)
oap->start.col = 0;
curwin->w_cursor.col = 0;
oap->end.col = (colnr_T)STRLEN(ml_get(oap->end.lnum));
- if (oap->end.col)
+ if (oap->end.col) {
--oap->end.col;
- } else if (!oap->inclusive)
+ }
+ } else if (!oap->inclusive) {
dec(&(oap->end));
+ }
// TODO(bfredl): we could batch all the splicing
// done on the same line, at least
@@ -1917,8 +1940,9 @@ int op_replace(oparg_T *oap, int c)
if ((*mb_char2len)(c) > 1 || (*mb_char2len)(n) > 1) {
/* This is slow, but it handles replacing a single-byte
* with a multi-byte and the other way around. */
- if (curwin->w_cursor.lnum == oap->end.lnum)
+ if (curwin->w_cursor.lnum == oap->end.lnum) {
oap->end.col += (*mb_char2len)(c) - (*mb_char2len)(n);
+ }
replace_character(c);
} else {
if (n == TAB) {
@@ -1928,11 +1952,12 @@ int op_replace(oparg_T *oap, int c)
/* oap->end has to be recalculated when
* the tab breaks */
end_vcol = getviscol2(oap->end.col,
- oap->end.coladd);
+ oap->end.coladd);
}
coladvance_force(getviscol());
- if (curwin->w_cursor.lnum == oap->end.lnum)
+ if (curwin->w_cursor.lnum == oap->end.lnum) {
getvpos(&oap->end, end_vcol);
+ }
}
pbyte(curwin->w_cursor, c);
}
@@ -1940,8 +1965,9 @@ int op_replace(oparg_T *oap, int c)
int virtcols = oap->end.coladd;
if (curwin->w_cursor.lnum == oap->start.lnum
- && oap->start.col == oap->end.col && oap->start.coladd)
+ && oap->start.col == oap->end.col && oap->start.coladd) {
virtcols -= oap->start.coladd;
+ }
/* oap->end has been trimmed so it's effectively inclusive;
* as a result an extra +1 must be counted so we don't
@@ -1960,9 +1986,10 @@ int op_replace(oparg_T *oap, int c)
}
}
- /* Advance to next character, stop at the end of the file. */
- if (inc_cursor() == -1)
+ // Advance to next character, stop at the end of the file.
+ if (inc_cursor() == -1) {
break;
+ }
}
}
@@ -1970,7 +1997,7 @@ int op_replace(oparg_T *oap, int c)
check_cursor();
changed_lines(oap->start.lnum, oap->start.col, oap->end.lnum + 1, 0L, true);
- /* Set "'[" and "']" marks. */
+ // Set "'[" and "']" marks.
curbuf->b_op_start = oap->start;
curbuf->b_op_end = oap->end;
@@ -1988,8 +2015,9 @@ void op_tilde(oparg_T *oap)
int did_change = FALSE;
if (u_save((linenr_T)(oap->start.lnum - 1),
- (linenr_T)(oap->end.lnum + 1)) == FAIL)
+ (linenr_T)(oap->end.lnum + 1)) == FAIL) {
return;
+ }
pos = oap->start;
if (oap->motion_type == kMTBlockWise) { // Visual block mode
@@ -2000,7 +2028,6 @@ void op_tilde(oparg_T *oap)
pos.col = bd.textcol;
one_change = swapchars(oap->op_type, &pos, bd.textlen);
did_change |= one_change;
-
}
if (did_change) {
changed_lines(oap->start.lnum, 0, oap->end.lnum + 1, 0L, true);
@@ -2010,31 +2037,36 @@ void op_tilde(oparg_T *oap)
oap->start.col = 0;
pos.col = 0;
oap->end.col = (colnr_T)STRLEN(ml_get(oap->end.lnum));
- if (oap->end.col)
+ if (oap->end.col) {
--oap->end.col;
- } else if (!oap->inclusive)
+ }
+ } else if (!oap->inclusive) {
dec(&(oap->end));
+ }
- if (pos.lnum == oap->end.lnum)
+ if (pos.lnum == oap->end.lnum) {
did_change = swapchars(oap->op_type, &pos,
- oap->end.col - pos.col + 1);
- else
+ oap->end.col - pos.col + 1);
+ } else {
for (;; ) {
did_change |= swapchars(oap->op_type, &pos,
- pos.lnum == oap->end.lnum ? oap->end.col + 1 :
- (int)STRLEN(ml_get_pos(&pos)));
- if (ltoreq(oap->end, pos) || inc(&pos) == -1)
+ pos.lnum == oap->end.lnum ? oap->end.col + 1 :
+ (int)STRLEN(ml_get_pos(&pos)));
+ if (ltoreq(oap->end, pos) || inc(&pos) == -1) {
break;
+ }
}
+ }
if (did_change) {
changed_lines(oap->start.lnum, oap->start.col, oap->end.lnum + 1,
0L, true);
}
}
- if (!did_change && oap->is_VIsual)
- /* No change: need to remove the Visual selection */
+ if (!did_change && oap->is_VIsual) {
+ // No change: need to remove the Visual selection
redraw_curbuf_later(INVERTED);
+ }
/*
* Set '[ and '] marks.
@@ -2043,10 +2075,11 @@ void op_tilde(oparg_T *oap)
curbuf->b_op_end = oap->end;
if (oap->line_count > p_report) {
- if (oap->line_count == 1)
+ if (oap->line_count == 1) {
MSG(_("1 line changed"));
- else
+ } else {
smsg(_("%" PRId64 " lines changed"), (int64_t)oap->line_count);
+ }
}
}
@@ -2070,8 +2103,9 @@ static int swapchars(int op_type, pos_T *pos, int length)
todo -= len - 1;
}
did_change |= swapchar(op_type, pos);
- if (inc(pos) == -1) /* at end of file */
+ if (inc(pos) == -1) { // at end of file
break;
+ }
}
return did_change;
}
@@ -2094,7 +2128,7 @@ bool swapchar(int op_type, pos_T *pos)
if (op_type == OP_UPPER && c == 0xdf) {
pos_T sp = curwin->w_cursor;
- /* Special handling of German sharp s: change to "SS". */
+ // Special handling of German sharp s: change to "SS".
curwin->w_cursor = *pos;
del_char(false);
ins_char('S');
@@ -2140,16 +2174,16 @@ bool swapchar(int op_type, pos_T *pos)
void op_insert(oparg_T *oap, long count1)
{
long ins_len, pre_textlen = 0;
- char_u *firstline, *ins_text;
+ char_u *firstline, *ins_text;
colnr_T ind_pre = 0;
struct block_def bd;
int i;
pos_T t1;
- /* edit() changes this - record it for OP_APPEND */
+ // edit() changes this - record it for OP_APPEND
bd.is_MAX = (curwin->w_curswant == MAXCOL);
- /* vis block is still marked. Get rid of it now. */
+ // vis block is still marked. Get rid of it now.
curwin->w_cursor.lnum = oap->start.lnum;
update_screen(INVERTED);
@@ -2162,12 +2196,14 @@ void op_insert(oparg_T *oap, long count1)
unsigned old_ve_flags = ve_flags;
ve_flags = VE_ALL;
- if (u_save_cursor() == FAIL)
+ if (u_save_cursor() == FAIL) {
return;
+ }
coladvance_force(oap->op_type == OP_APPEND
? oap->end_vcol + 1 : getviscol());
- if (oap->op_type == OP_APPEND)
+ if (oap->op_type == OP_APPEND) {
--curwin->w_cursor.col;
+ }
ve_flags = old_ve_flags;
}
// Get the info about the block before entering the text
@@ -2184,18 +2220,19 @@ void op_insert(oparg_T *oap, long count1)
if (oap->op_type == OP_APPEND) {
if (oap->motion_type == kMTBlockWise
- && curwin->w_cursor.coladd == 0
- ) {
- /* Move the cursor to the character right of the block. */
+ && curwin->w_cursor.coladd == 0) {
+ // Move the cursor to the character right of the block.
curwin->w_set_curswant = TRUE;
while (*get_cursor_pos_ptr() != NUL
- && (curwin->w_cursor.col < bd.textcol + bd.textlen))
+ && (curwin->w_cursor.col < bd.textcol + bd.textlen)) {
++curwin->w_cursor.col;
+ }
if (bd.is_short && !bd.is_MAX) {
/* First line was too short, make it longer and adjust the
* values in "bd". */
- if (u_save_cursor() == FAIL)
+ if (u_save_cursor() == FAIL) {
return;
+ }
for (i = 0; i < bd.endspaces; i++) {
ins_char(' ');
}
@@ -2227,8 +2264,9 @@ void op_insert(oparg_T *oap, long count1)
/* If user has moved off this line, we don't know what to do, so do
* nothing.
* Also don't repeat the insert when Insert mode ended with CTRL-C. */
- if (curwin->w_cursor.lnum != oap->start.lnum || got_int)
+ if (curwin->w_cursor.lnum != oap->start.lnum || got_int) {
return;
+ }
if (oap->motion_type == kMTBlockWise) {
struct block_def bd2;
@@ -2264,7 +2302,7 @@ void op_insert(oparg_T *oap, long count1)
int t = getviscol2(curbuf->b_op_start_orig.col,
curbuf->b_op_start_orig.coladd);
oap->start.col = curbuf->b_op_start_orig.col;
- /* reset pre_textlen to the value of OP_INSERT */
+ // reset pre_textlen to the value of OP_INSERT
pre_textlen += bd.textlen;
pre_textlen -= t - oap->start_vcol;
oap->start_vcol = t;
@@ -2281,8 +2319,9 @@ void op_insert(oparg_T *oap, long count1)
if (!bd.is_MAX || bd2.textlen < bd.textlen) {
if (oap->op_type == OP_APPEND) {
pre_textlen += bd2.textlen - bd.textlen;
- if (bd2.endspaces)
+ if (bd2.endspaces) {
--bd2.textlen;
+ }
}
bd.textcol = bd2.textcol;
bd.textlen = bd2.textlen;
@@ -2342,18 +2381,20 @@ int op_change(oparg_T *oap)
if (oap->motion_type == kMTLineWise) {
l = 0;
if (!p_paste && curbuf->b_p_si
- && !curbuf->b_p_cin
- )
+ && !curbuf->b_p_cin) {
can_si = true; // It's like opening a new line, do si
+ }
}
/* First delete the text in the region. In an empty buffer only need to
* save for undo */
if (curbuf->b_ml.ml_flags & ML_EMPTY) {
- if (u_save_cursor() == FAIL)
+ if (u_save_cursor() == FAIL) {
return FALSE;
- } else if (op_delete(oap) == FAIL)
+ }
+ } else if (op_delete(oap) == FAIL) {
return FALSE;
+ }
if ((l > curwin->w_cursor.col) && !LINEEMPTY(curwin->w_cursor.lnum)
&& !virtual_op) {
@@ -2439,6 +2480,7 @@ int op_change(oparg_T *oap)
xfree(ins_text);
}
}
+ auto_format(false, true);
return retval;
}
@@ -2464,9 +2506,9 @@ void clear_registers(void)
#endif
- /// Free contents of yankreg `reg`.
- /// Called for normal freeing and in case of error.
- /// `reg` must not be NULL (but `reg->y_array` might be)
+/// Free contents of yankreg `reg`.
+/// Called for normal freeing and in case of error.
+/// `reg` must not be NULL (but `reg->y_array` might be)
void free_register(yankreg_T *reg)
FUNC_ATTR_NONNULL_ALL
{
@@ -2496,7 +2538,7 @@ bool op_yank(oparg_T *oap, bool message, int deleting)
return false;
}
if (oap->regname == '_') {
- return true; // black hole: nothing to do
+ return true; // black hole: nothing to do
}
yankreg_T *reg = get_yank_register(oap->regname, YREG_YANK);
@@ -2558,8 +2600,9 @@ static void op_yank_reg(oparg_T *oap, bool message, yankreg_T *reg, bool append)
// Visual block mode
reg->y_width = oap->end_vcol - oap->start_vcol;
- if (curwin->w_curswant == MAXCOL && reg->y_width > 0)
+ if (curwin->w_curswant == MAXCOL && reg->y_width > 0) {
reg->y_width--;
+ }
}
for (; lnum <= yankendlnum; lnum++, y_idx++) {
@@ -2573,8 +2616,7 @@ static void op_yank_reg(oparg_T *oap, bool message, yankreg_T *reg, bool append)
reg->y_array[y_idx] = vim_strsave(ml_get(lnum));
break;
- case kMTCharWise:
- {
+ case kMTCharWise: {
colnr_T startcol = 0, endcol = MAXCOL;
int is_oneChar = false;
colnr_T cs, ce;
@@ -2620,11 +2662,11 @@ static void op_yank_reg(oparg_T *oap, bool message, yankreg_T *reg, bool append)
}
}
}
- if (endcol == MAXCOL)
+ if (endcol == MAXCOL) {
endcol = (colnr_T)STRLEN(p);
+ }
if (startcol > endcol
- || is_oneChar
- ) {
+ || is_oneChar) {
bd.textlen = 0;
} else {
bd.textlen = endcol - startcol + oap->inclusive;
@@ -2635,14 +2677,15 @@ static void op_yank_reg(oparg_T *oap, bool message, yankreg_T *reg, bool append)
}
// NOTREACHED
case kMTUnknown:
- abort();
+ abort();
}
}
- if (curr != reg) { /* append the new block to the old block */
+ if (curr != reg) { // append the new block to the old block
new_ptr = xmalloc(sizeof(char_u *) * (curr->y_size + reg->y_size));
- for (j = 0; j < curr->y_size; ++j)
+ for (j = 0; j < curr->y_size; ++j) {
new_ptr[j] = curr->y_array[j];
+ }
xfree(curr->y_array);
curr->y_array = new_ptr;
@@ -2663,10 +2706,12 @@ static void op_yank_reg(oparg_T *oap, bool message, yankreg_T *reg, bool append)
xfree(reg->y_array[0]);
curr->y_array[j++] = pnew;
y_idx = 1;
- } else
+ } else {
y_idx = 0;
- while (y_idx < reg->y_size)
+ }
+ while (y_idx < reg->y_size) {
curr->y_array[j++] = reg->y_array[y_idx++];
+ }
curr->y_size = j;
xfree(reg->y_array);
}
@@ -2719,8 +2764,8 @@ static void op_yank_reg(oparg_T *oap, bool message, yankreg_T *reg, bool append)
// Copy a block range into a register.
// If "exclude_trailing_space" is set, do not copy trailing whitespaces.
-static void yank_copy_line(yankreg_T *reg, struct block_def *bd,
- size_t y_idx, bool exclude_trailing_space)
+static void yank_copy_line(yankreg_T *reg, struct block_def *bd, size_t y_idx,
+ bool exclude_trailing_space)
FUNC_ATTR_NONNULL_ALL
{
if (exclude_trailing_space) {
@@ -2831,24 +2876,25 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
int delcount;
int incr = 0;
struct block_def bd;
- char_u **y_array = NULL;
+ char_u **y_array = NULL;
long nr_lines = 0;
pos_T new_cursor;
int indent;
- int orig_indent = 0; /* init for gcc */
- int indent_diff = 0; /* init for gcc */
- int first_indent = TRUE;
+ int orig_indent = 0; // init for gcc
+ int indent_diff = 0; // init for gcc
+ bool first_indent = true;
int lendiff = 0;
pos_T old_pos;
- char_u *insert_string = NULL;
+ char_u *insert_string = NULL;
bool allocated = false;
long cnt;
- if (flags & PUT_FIXINDENT)
+ if (flags & PUT_FIXINDENT) {
orig_indent = get_indent();
+ }
- curbuf->b_op_start = curwin->w_cursor; /* default for '[ mark */
- curbuf->b_op_end = curwin->w_cursor; /* default for '] mark */
+ curbuf->b_op_start = curwin->w_cursor; // default for '[ mark
+ curbuf->b_op_end = curwin->w_cursor; // default for '] mark
/*
* Using inserted text works differently, because the register includes
@@ -2859,7 +2905,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
// PUT_LINE has special handling below which means we use 'i' to start.
char command_start_char = non_linewise_vis ? 'c' :
- (flags & PUT_LINE ? 'i' : (dir == FORWARD ? 'a' : 'i'));
+ (flags & PUT_LINE ? 'i' : (dir == FORWARD ? 'a' : 'i'));
// To avoid 'autoindent' on linewise puts, create a new line with `:put _`.
if (flags & PUT_LINE) {
@@ -2961,27 +3007,30 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
y_size = 0;
ptr = insert_string;
while (ptr != NULL) {
- if (y_array != NULL)
+ if (y_array != NULL) {
y_array[y_size] = ptr;
+ }
++y_size;
ptr = vim_strchr(ptr, '\n');
if (ptr != NULL) {
- if (y_array != NULL)
+ if (y_array != NULL) {
*ptr = NUL;
+ }
++ptr;
- /* A trailing '\n' makes the register linewise. */
+ // A trailing '\n' makes the register linewise.
if (*ptr == NUL) {
y_type = kMTLineWise;
break;
}
}
}
- if (y_array != NULL)
+ if (y_array != NULL) {
break;
+ }
y_array = (char_u **)xmalloc(y_size * sizeof(char_u *));
}
} else {
- y_size = 1; /* use fake one-line yank register */
+ y_size = 1; // use fake one-line yank register
y_array = &insert_string;
}
} else {
@@ -3029,12 +3078,12 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
dir = FORWARD;
}
if (flags & PUT_LINE_FORWARD) {
- /* Must be "p" for a Visual block, put lines below the block. */
+ // Must be "p" for a Visual block, put lines below the block.
curwin->w_cursor = curbuf->b_visual.vi_end;
dir = FORWARD;
}
- curbuf->b_op_start = curwin->w_cursor; /* default for '[ mark */
- curbuf->b_op_end = curwin->w_cursor; /* default for '] mark */
+ curbuf->b_op_start = curwin->w_cursor; // default for '[ mark
+ curbuf->b_op_end = curwin->w_cursor; // default for '] mark
}
if (flags & PUT_LINE) { // :put command or "p" in Visual line mode.
@@ -3043,7 +3092,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
if (y_size == 0 || y_array == NULL) {
EMSG2(_("E353: Nothing in register %s"),
- regname == 0 ? (char_u *)"\"" : transchar(regname));
+ regname == 0 ? (char_u *)"\"" : transchar(regname));
goto end;
}
@@ -3069,7 +3118,8 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
}
// In an empty buffer the empty line is going to be replaced, include
// it in the saved lines.
- if ((BUFEMPTY() ? u_save(0, 2) : u_save(lnum - 1, lnum)) == FAIL) {
+ if ((buf_is_empty(curbuf) ?
+ u_save(0, 2) : u_save(lnum - 1, lnum)) == FAIL) {
goto end;
}
if (dir == FORWARD) {
@@ -3112,10 +3162,11 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
colnr_T endcol2 = 0;
if (dir == FORWARD && c != NUL) {
- if (ve_flags == VE_ALL)
+ if (ve_flags == VE_ALL) {
getvcol(curwin, &curwin->w_cursor, &col, NULL, &endcol2);
- else
+ } else {
getvcol(curwin, &curwin->w_cursor, NULL, NULL, &col);
+ }
// move to start of next multi-byte character
curwin->w_cursor.col += utfc_ptr2len(get_cursor_pos_ptr());
@@ -3135,10 +3186,12 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
curwin->w_cursor.col++;
}
if (c == TAB) {
- if (dir == BACKWARD && curwin->w_cursor.col)
+ if (dir == BACKWARD && curwin->w_cursor.col) {
curwin->w_cursor.col--;
- if (dir == FORWARD && col - 1 == endcol2)
+ }
+ if (dir == FORWARD && col - 1 == endcol2) {
curwin->w_cursor.col++;
+ }
}
}
curwin->w_cursor.coladd = 0;
@@ -3155,7 +3208,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
vcol = 0;
delcount = 0;
- /* add a new line */
+ // add a new line
if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count) {
if (ml_append(curbuf->b_ml.ml_line_count, (char_u *)"",
(colnr_T)1, false) == FAIL) {
@@ -3164,21 +3217,21 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
nr_lines++;
lines_appended = 1;
}
- /* get the old line and advance to the position to insert at */
+ // get the old line and advance to the position to insert at
oldp = get_cursor_line_ptr();
oldlen = STRLEN(oldp);
for (ptr = oldp; vcol < col && *ptr; ) {
- /* Count a tab for what it's worth (if list mode not on) */
- incr = lbr_chartabsize_adv(oldp, &ptr, (colnr_T)vcol);
+ // Count a tab for what it's worth (if list mode not on)
+ incr = lbr_chartabsize_adv(oldp, &ptr, vcol);
vcol += incr;
}
bd.textcol = (colnr_T)(ptr - oldp);
shortline = (vcol < col) || (vcol == col && !*ptr);
- if (vcol < col) /* line too short, padd with spaces */
+ if (vcol < col) { // line too short, padd with spaces
bd.startspaces = col - vcol;
- else if (vcol > col) {
+ } else if (vcol > col) {
bd.endspaces = vcol - col;
bd.startspaces = incr - bd.endspaces;
--bd.textcol;
@@ -3244,18 +3297,19 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
delcount, addcount, kExtmarkUndo);
++curwin->w_cursor.lnum;
- if (i == 0)
+ if (i == 0) {
curwin->w_cursor.col += bd.startspaces;
+ }
}
changed_lines(lnum, 0, curbuf->b_op_start.lnum + (linenr_T)y_size
- - (linenr_T)nr_lines , nr_lines, true);
+ - (linenr_T)nr_lines, nr_lines, true);
- /* Set '[ mark. */
+ // Set '[ mark.
curbuf->b_op_start = curwin->w_cursor;
curbuf->b_op_start.lnum = lnum;
- /* adjust '] mark */
+ // adjust '] mark
curbuf->b_op_end.lnum = curwin->w_cursor.lnum - 1;
curbuf->b_op_end.col = bd.textcol + (colnr_T)totlen - 1;
curbuf->b_op_end.coladd = 0;
@@ -3265,12 +3319,14 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
curwin->w_cursor = curbuf->b_op_end;
curwin->w_cursor.col++;
- /* in Insert mode we might be after the NUL, correct for that */
+ // in Insert mode we might be after the NUL, correct for that
len = (colnr_T)STRLEN(get_cursor_line_ptr());
- if (curwin->w_cursor.col > len)
+ if (curwin->w_cursor.col > len) {
curwin->w_cursor.col = len;
- } else
+ }
+ } else {
curwin->w_cursor.lnum = lnum;
+ }
} else {
// Character or Line mode
if (y_type == kMTCharWise) {
@@ -3291,8 +3347,9 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
/*
* Line mode: BACKWARD is the same as FORWARD on the previous line
*/
- else if (dir == BACKWARD)
+ else if (dir == BACKWARD) {
--lnum;
+ }
new_cursor = curwin->w_cursor;
// simple case: insert into one line at a time
@@ -3303,7 +3360,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
if (VIsual_active) {
end_lnum = curbuf->b_visual.vi_end.lnum;
if (end_lnum < curbuf->b_visual.vi_start.lnum) {
- end_lnum = curbuf->b_visual.vi_start.lnum;
+ end_lnum = curbuf->b_visual.vi_start.lnum;
}
if (end_lnum > start_lnum) {
// "col" is valid for the first line, in following lines
@@ -3360,7 +3417,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
}
} while (VIsual_active && lnum <= end_lnum);
- if (VIsual_active) { /* reset lnum to the last visual line */
+ if (VIsual_active) { // reset lnum to the last visual line
lnum--;
}
@@ -3381,7 +3438,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
lnum = new_cursor.lnum;
ptr = ml_get(lnum) + col;
totlen = STRLEN(y_array[y_size - 1]);
- newp = (char_u *) xmalloc((size_t)(STRLEN(ptr) + totlen + 1));
+ newp = (char_u *)xmalloc((size_t)(STRLEN(ptr) + totlen + 1));
STRCPY(newp, y_array[y_size - 1]);
STRCAT(newp, ptr);
// insert second line
@@ -3412,23 +3469,26 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
old_pos = curwin->w_cursor;
curwin->w_cursor.lnum = lnum;
ptr = ml_get(lnum);
- if (cnt == count && i == y_size - 1)
+ if (cnt == count && i == y_size - 1) {
lendiff = (int)STRLEN(ptr);
- if (*ptr == '#' && preprocs_left())
- indent = 0; /* Leave # lines at start */
- else if (*ptr == NUL)
- indent = 0; /* Ignore empty lines */
- else if (first_indent) {
+ }
+ if (*ptr == '#' && preprocs_left()) {
+ indent = 0; // Leave # lines at start
+ } else if (*ptr == NUL) {
+ indent = 0; // Ignore empty lines
+ } else if (first_indent) {
indent_diff = orig_indent - get_indent();
indent = orig_indent;
- first_indent = FALSE;
- } else if ((indent = get_indent() + indent_diff) < 0)
+ first_indent = false;
+ } else if ((indent = get_indent() + indent_diff) < 0) {
indent = 0;
+ }
(void)set_indent(indent, SIN_NOMARK);
curwin->w_cursor = old_pos;
- /* remember how many chars were removed */
- if (cnt == count && i == y_size - 1)
+ // remember how many chars were removed
+ if (cnt == count && i == y_size - 1) {
lendiff -= (int)STRLEN(ml_get(lnum));
+ }
}
}
@@ -3447,8 +3507,9 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
(int)y_size-1, lastsize, totsize,
kExtmarkUndo);
} else if (y_type == kMTLineWise && flags & PUT_LINE_SPLIT) {
- extmark_splice(curbuf, (int)new_cursor.lnum-1, col, 0, 0, 0,
- (int)y_size+1, 0, totsize+1, kExtmarkUndo);
+ // Account for last pasted NL + last NL
+ extmark_splice(curbuf, (int)new_cursor.lnum-1, col + 1, 0, 0, 0,
+ (int)y_size+1, 0, totsize+2, kExtmarkUndo);
}
}
@@ -3456,8 +3517,9 @@ error:
// Adjust marks.
if (y_type == kMTLineWise) {
curbuf->b_op_start.col = 0;
- if (dir == FORWARD)
+ if (dir == FORWARD) {
curbuf->b_op_start.lnum++;
+ }
}
ExtmarkOp kind = (y_type == kMTLineWise && !(flags & PUT_LINE_SPLIT))
@@ -3474,17 +3536,18 @@ error:
curbuf->b_op_start.lnum, nr_lines, true);
}
- /* put '] mark at last inserted character */
+ // put '] mark at last inserted character
curbuf->b_op_end.lnum = lnum;
- /* correct length for change in indent */
+ // correct length for change in indent
col = (colnr_T)STRLEN(y_array[y_size - 1]) - lendiff;
- if (col > 1)
+ if (col > 1) {
curbuf->b_op_end.col = col - 1;
- else
+ } else {
curbuf->b_op_end.col = 0;
+ }
if (flags & PUT_CURSLINE) {
- /* ":put": put cursor on last inserted line */
+ // ":put": put cursor on last inserted line
curwin->w_cursor.lnum = lnum;
beginline(BL_WHITE | BL_FIX);
} else if (flags & PUT_CURSEND) {
@@ -3503,11 +3566,13 @@ error:
} else if (y_type == kMTLineWise) {
// put cursor on first non-blank in first inserted line
curwin->w_cursor.col = 0;
- if (dir == FORWARD)
+ if (dir == FORWARD) {
++curwin->w_cursor.lnum;
+ }
beginline(BL_WHITE | BL_FIX);
- } else /* put cursor on first inserted character */
+ } else { // put cursor on first inserted character
curwin->w_cursor = new_cursor;
+ }
}
}
@@ -3515,14 +3580,16 @@ error:
curwin->w_set_curswant = TRUE;
end:
- if (allocated)
+ if (allocated) {
xfree(insert_string);
- if (regname == '=')
+ }
+ if (regname == '=') {
xfree(y_array);
+ }
VIsual_active = FALSE;
- /* If the cursor is past the end of the line put it at the end. */
+ // If the cursor is past the end of the line put it at the end.
adjust_cursor_eol();
} // NOLINT(readability/fn_size)
@@ -3536,13 +3603,13 @@ void adjust_cursor_eol(void)
&& gchar_cursor() == NUL
&& (ve_flags & VE_ONEMORE) == 0
&& !(restart_edit || (State & INSERT))) {
- /* Put the cursor on the last character in the line. */
+ // Put the cursor on the last character in the line.
dec_cursor();
if (ve_flags == VE_ALL) {
colnr_T scol, ecol;
- /* Coladd is set to the width of the last character. */
+ // Coladd is set to the width of the last character.
getvcol(curwin, &curwin->w_cursor, &scol, NULL, &ecol);
curwin->w_cursor.coladd = ecol - scol + 1;
}
@@ -3559,24 +3626,30 @@ int preprocs_left(void)
&& curbuf->b_ind_hash_comment == 0));
}
-/* Return the character name of the register with the given number */
+// Return the character name of the register with the given number
int get_register_name(int num)
{
- if (num == -1)
+ if (num == -1) {
return '"';
- else if (num < 10)
+ } else if (num < 10) {
return num + '0';
- else if (num == DELETION_REGISTER)
+ } else if (num == DELETION_REGISTER) {
return '-';
- else if (num == STAR_REGISTER)
+ } else if (num == STAR_REGISTER) {
return '*';
- else if (num == PLUS_REGISTER)
+ } else if (num == PLUS_REGISTER) {
return '+';
- else {
+ } else {
return num + 'a' - 10;
}
}
+/// @return the index of the register "" points to.
+int get_unname_register(void)
+{
+ return y_previous == NULL ? -1 : (int)(y_previous - &y_regs[0]);
+}
+
/*
* ":dis" and ":registers": Display the contents of the yank registers.
*/
@@ -3589,8 +3662,9 @@ void ex_display(exarg_T *eap)
int clen;
char_u type[2];
- if (arg != NULL && *arg == NUL)
+ if (arg != NULL && *arg == NUL) {
arg = NULL;
+ }
int attr = HL_ATTR(HLF_8);
// Highlight title
@@ -3598,23 +3672,28 @@ void ex_display(exarg_T *eap)
for (int i = -1; i < NUM_REGISTERS && !got_int; i++) {
name = get_register_name(i);
switch (get_reg_type(name, NULL)) {
- case kMTLineWise: type[0] = 'l'; break;
- case kMTCharWise: type[0] = 'c'; break;
- default: type[0] = 'b'; break;
+ case kMTLineWise:
+ type[0] = 'l'; break;
+ case kMTCharWise:
+ type[0] = 'c'; break;
+ default:
+ type[0] = 'b'; break;
}
if (arg != NULL && vim_strchr(arg, name) == NULL) {
- continue; /* did not ask for this register */
+ continue; // did not ask for this register
}
if (i == -1) {
- if (y_previous != NULL)
+ if (y_previous != NULL) {
yb = y_previous;
- else
+ } else {
yb = &(y_regs[0]);
- } else
+ }
+ } else {
yb = &(y_regs[i]);
+ }
get_clipboard(name, &yb, true);
@@ -3684,7 +3763,7 @@ void ex_display(exarg_T *eap)
* display alternate file name
*/
if ((arg == NULL || vim_strchr(arg, '%') != NULL) && !got_int) {
- char_u *fname;
+ char_u *fname;
linenr_T dummy;
if (buflist_name_nr(0, &fname, &dummy) != FAIL) {
@@ -3712,15 +3791,11 @@ void ex_display(exarg_T *eap)
}
}
-/*
- * display a string for do_dis()
- * truncate at end of screen line
- */
-static void
-dis_msg(
- const char_u *p,
- bool skip_esc // if true, ignore trailing ESC
-)
+/// display a string for do_dis()
+/// truncate at end of screen line
+///
+/// @param skip_esc if true, ignore trailing ESC
+static void dis_msg(const char_u *p, bool skip_esc)
FUNC_ATTR_NONNULL_ALL
{
int n;
@@ -3733,8 +3808,9 @@ dis_msg(
if ((l = utfc_ptr2len(p)) > 1) {
msg_outtrans_len(p, l);
p += l;
- } else
+ } else {
msg_outtrans_len(p++, 1);
+ }
}
os_breakcheck();
}
@@ -3750,9 +3826,7 @@ dis_msg(
/// @param include_space - whether to skip space following the comment leader
/// @param[out] is_comment - whether the current line ends with an unclosed
/// comment.
-char_u *skip_comment(
- char_u *line, bool process, bool include_space, bool *is_comment
-)
+char_u *skip_comment(char_u *line, bool process, bool include_space, bool *is_comment)
{
char_u *comment_flags = NULL;
int lead_len;
@@ -3781,8 +3855,9 @@ char_u *skip_comment(
lead_len = get_leader_len(line, &comment_flags, false, include_space);
- if (lead_len == 0)
+ if (lead_len == 0) {
return line;
+ }
/* Find:
* - COM_END,
@@ -3816,25 +3891,21 @@ char_u *skip_comment(
// to set those marks.
//
// return FAIL for failure, OK otherwise
-int do_join(size_t count,
- int insert_space,
- int save_undo,
- int use_formatoptions,
- bool setmark)
+int do_join(size_t count, int insert_space, int save_undo, int use_formatoptions, bool setmark)
{
- char_u *curr = NULL;
- char_u *curr_start = NULL;
- char_u *cend;
- char_u *newp;
- char_u *spaces; /* number of spaces inserted before a line */
+ char_u *curr = NULL;
+ char_u *curr_start = NULL;
+ char_u *cend;
+ char_u *newp;
+ char_u *spaces; // number of spaces inserted before a line
int endcurr1 = NUL;
int endcurr2 = NUL;
- int currsize = 0; /* size of the current line */
- int sumsize = 0; /* size of the long new line */
+ int currsize = 0; // size of the current line
+ int sumsize = 0; // size of the long new line
linenr_T t;
colnr_T col = 0;
int ret = OK;
- int *comments = NULL;
+ int *comments = NULL;
int remove_comments = (use_formatoptions == TRUE)
&& has_format_option(FO_REMOVE_COMS);
bool prev_was_comment = false;
@@ -3884,13 +3955,14 @@ int do_join(size_t count,
|| (utf_ptr2char(curr) < 0x100 && endcurr1 < 0x100))
&& (!has_format_option(FO_MBYTE_JOIN2)
|| (utf_ptr2char(curr) < 0x100 && !utf_eat_space(endcurr1))
- || (endcurr1 < 0x100 && !utf_eat_space(utf_ptr2char(curr))))
- ) {
- /* don't add a space if the line is ending in a space */
- if (endcurr1 == ' ')
+ || (endcurr1 < 0x100 &&
+ !utf_eat_space(utf_ptr2char(curr))))) {
+ // don't add a space if the line is ending in a space
+ if (endcurr1 == ' ') {
endcurr1 = endcurr2;
- else
+ } else {
++spaces[t];
+ }
// Extra space when 'joinspaces' set and line ends in '.', '?', or '!'.
if (p_js && (endcurr1 == '.' || endcurr1 == '?' || endcurr1 == '!')) {
++spaces[t];
@@ -3955,8 +4027,8 @@ int do_join(size_t count,
const int spaces_removed = (int)((curr - curr_start) - spaces[t]);
linenr_T lnum = curwin->w_cursor.lnum + t;
colnr_T mincol = (colnr_T)0;
- long lnum_amount = (linenr_T)-t;
- long col_amount = (long)(cend - newp - spaces_removed);
+ long lnum_amount = -t;
+ long col_amount = (cend - newp - spaces_removed);
mark_col_adjust(lnum, mincol, lnum_amount, col_amount, spaces_removed);
@@ -3965,10 +4037,12 @@ int do_join(size_t count,
}
curr = curr_start = ml_get((linenr_T)(curwin->w_cursor.lnum + t - 1));
- if (remove_comments)
+ if (remove_comments) {
curr += comments[t - 1];
- if (insert_space && t > 1)
+ }
+ if (insert_space && t > 1) {
curr = skipwhite(curr);
+ }
currsize = (int)STRLEN(curr);
}
@@ -4000,7 +4074,7 @@ int do_join(size_t count,
/*
* Set the cursor column:
* Vi compatible: use the column of the first join
- * vim: use the column of the last join
+ * vim: use the column of the last join
*/
curwin->w_cursor.col =
(vim_strchr(p_cpo, CPO_JOINCOL) != NULL ? currsize : col);
@@ -4011,8 +4085,9 @@ int do_join(size_t count,
theend:
xfree(spaces);
- if (remove_comments)
+ if (remove_comments) {
xfree(comments);
+ }
return ret;
}
@@ -4021,15 +4096,17 @@ theend:
* the first line. White-space is ignored. Note that the whole of
* 'leader1' must match 'leader2_len' characters from 'leader2' -- webb
*/
-static int same_leader(linenr_T lnum, int leader1_len, char_u *leader1_flags, int leader2_len, char_u *leader2_flags)
+static int same_leader(linenr_T lnum, int leader1_len, char_u *leader1_flags, int leader2_len,
+ char_u *leader2_flags)
{
int idx1 = 0, idx2 = 0;
- char_u *p;
- char_u *line1;
- char_u *line2;
+ char_u *p;
+ char_u *line1;
+ char_u *line2;
- if (leader1_len == 0)
+ if (leader1_len == 0) {
return leader2_len == 0;
+ }
/*
* If first leader has 'f' flag, the lines can be joined only if the
@@ -4040,18 +4117,24 @@ static int same_leader(linenr_T lnum, int leader1_len, char_u *leader1_flags, in
*/
if (leader1_flags != NULL) {
for (p = leader1_flags; *p && *p != ':'; ++p) {
- if (*p == COM_FIRST)
+ if (*p == COM_FIRST) {
return leader2_len == 0;
- if (*p == COM_END)
+ }
+ if (*p == COM_END) {
return FALSE;
+ }
if (*p == COM_START) {
- if (*(ml_get(lnum) + leader1_len) == NUL)
+ if (*(ml_get(lnum) + leader1_len) == NUL) {
return FALSE;
- if (leader2_flags == NULL || leader2_len == 0)
+ }
+ if (leader2_flags == NULL || leader2_len == 0) {
return FALSE;
- for (p = leader2_flags; *p && *p != ':'; ++p)
- if (*p == COM_MIDDLE)
+ }
+ for (p = leader2_flags; *p && *p != ':'; ++p) {
+ if (*p == COM_MIDDLE) {
return TRUE;
+ }
+ }
return FALSE;
}
}
@@ -4062,30 +4145,30 @@ static int same_leader(linenr_T lnum, int leader1_len, char_u *leader1_flags, in
* The first line has to be saved, only one line can be locked at a time.
*/
line1 = vim_strsave(ml_get(lnum));
- for (idx1 = 0; ascii_iswhite(line1[idx1]); ++idx1)
+ for (idx1 = 0; ascii_iswhite(line1[idx1]); ++idx1) {
;
+ }
line2 = ml_get(lnum + 1);
for (idx2 = 0; idx2 < leader2_len; ++idx2) {
if (!ascii_iswhite(line2[idx2])) {
- if (line1[idx1++] != line2[idx2])
+ if (line1[idx1++] != line2[idx2]) {
break;
- } else
- while (ascii_iswhite(line1[idx1]))
+ }
+ } else {
+ while (ascii_iswhite(line1[idx1])) {
++idx1;
+ }
+ }
}
xfree(line1);
return idx2 == leader2_len && idx1 == leader1_len;
}
-/*
- * Implementation of the format operator 'gq'.
- */
-void
-op_format(
- oparg_T *oap,
- int keep_cursor /* keep cursor on same text char */
-)
+/// Implementation of the format operator 'gq'.
+///
+/// @param keep_cursor keep cursor on same text char
+void op_format(oparg_T *oap, int keep_cursor)
{
long old_line_count = curbuf->b_ml.ml_line_count;
@@ -4094,21 +4177,24 @@ op_format(
curwin->w_cursor = oap->cursor_start;
if (u_save((linenr_T)(oap->start.lnum - 1),
- (linenr_T)(oap->end.lnum + 1)) == FAIL)
+ (linenr_T)(oap->end.lnum + 1)) == FAIL) {
return;
+ }
curwin->w_cursor = oap->start;
- if (oap->is_VIsual)
- /* When there is no change: need to remove the Visual selection */
+ if (oap->is_VIsual) {
+ // When there is no change: need to remove the Visual selection
redraw_curbuf_later(INVERTED);
+ }
- /* Set '[ mark at the start of the formatted area */
+ // Set '[ mark at the start of the formatted area
curbuf->b_op_start = oap->start;
/* For "gw" remember the cursor position and put it back below (adjusted
* for joined and split lines). */
- if (keep_cursor)
+ if (keep_cursor) {
saved_cursor = oap->cursor_start;
+ }
format_lines(oap->line_count, keep_cursor);
@@ -4117,13 +4203,14 @@ op_format(
* If the cursor was moved one line back (e.g. with "Q}") go to the next
* line, so "." will do the next lines.
*/
- if (oap->end_adjusted && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count)
+ if (oap->end_adjusted && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) {
++curwin->w_cursor.lnum;
+ }
beginline(BL_WHITE | BL_FIX);
old_line_count = curbuf->b_ml.ml_line_count - old_line_count;
msgmore(old_line_count);
- /* put '] mark on the end of the formatted area */
+ // put '] mark on the end of the formatted area
curbuf->b_op_end = curwin->w_cursor;
if (keep_cursor) {
@@ -4151,25 +4238,22 @@ op_format(
*/
void op_formatexpr(oparg_T *oap)
{
- if (oap->is_VIsual)
- /* When there is no change: need to remove the Visual selection */
+ if (oap->is_VIsual) {
+ // When there is no change: need to remove the Visual selection
redraw_curbuf_later(INVERTED);
+ }
- if (fex_format(oap->start.lnum, oap->line_count, NUL) != 0)
+ if (fex_format(oap->start.lnum, oap->line_count, NUL) != 0) {
/* As documented: when 'formatexpr' returns non-zero fall back to
* internal formatting. */
op_format(oap, FALSE);
+ }
}
-int
-fex_format(
- linenr_T lnum,
- long count,
- int c /* character to be inserted */
-)
+/// @param c character to be inserted
+int fex_format(linenr_T lnum, long count, int c)
{
- int use_sandbox = was_set_insecurely(
- curwin, (char_u *)"formatexpr", OPT_LOCAL);
+ int use_sandbox = was_set_insecurely(curwin, (char_u *)"formatexpr", OPT_LOCAL);
int r;
char_u *fex;
@@ -4198,17 +4282,13 @@ fex_format(
return r;
}
-/*
- * Format "line_count" lines, starting at the cursor position.
- * When "line_count" is negative, format until the end of the paragraph.
- * Lines after the cursor line are saved for undo, caller must have saved the
- * first line.
- */
-void
-format_lines(
- linenr_T line_count,
- int avoid_fex /* don't use 'formatexpr' */
-)
+/// Format "line_count" lines, starting at the cursor position.
+/// When "line_count" is negative, format until the end of the paragraph.
+/// Lines after the cursor line are saved for undo, caller must have saved the
+/// first line.
+///
+/// @param avoid_fex don't use 'formatexpr'
+void format_lines(linenr_T line_count, int avoid_fex)
{
bool is_not_par; // current line not part of parag.
bool next_is_not_par; // next line not part of paragraph
@@ -4246,11 +4326,12 @@ format_lines(
is_not_par = true;
}
next_is_not_par = fmt_check_par(curwin->w_cursor.lnum
- , &next_leader_len, &next_leader_flags, do_comments
- );
+ , &next_leader_len, &next_leader_flags, do_comments
+ );
is_end_par = (is_not_par || next_is_not_par);
- if (!is_end_par && do_trail_white)
+ if (!is_end_par && do_trail_white) {
is_end_par = !ends_in_white(curwin->w_cursor.lnum - 1);
+ }
curwin->w_cursor.lnum--;
for (count = line_count; count != 0 && !got_int; --count) {
@@ -4274,23 +4355,26 @@ format_lines(
next_leader_flags = NULL;
} else {
next_is_not_par = fmt_check_par(curwin->w_cursor.lnum + 1
- , &next_leader_len, &next_leader_flags, do_comments
- );
- if (do_number_indent)
+ , &next_leader_len, &next_leader_flags, do_comments
+ );
+ if (do_number_indent) {
next_is_start_par =
(get_number_indent(curwin->w_cursor.lnum + 1) > 0);
+ }
}
advance = true;
is_end_par = (is_not_par || next_is_not_par || next_is_start_par);
- if (!is_end_par && do_trail_white)
+ if (!is_end_par && do_trail_white) {
is_end_par = !ends_in_white(curwin->w_cursor.lnum);
+ }
/*
* Skip lines that are not in a paragraph.
*/
if (is_not_par) {
- if (line_count < 0)
+ if (line_count < 0) {
break;
+ }
} else {
/*
* For the first line of a paragraph, check indent of second line.
@@ -4302,7 +4386,7 @@ format_lines(
&& curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) {
if (do_second_indent && !LINEEMPTY(curwin->w_cursor.lnum + 1)) {
if (leader_len == 0 && next_leader_len == 0) {
- /* no comment found */
+ // no comment found
second_indent =
get_indent_lnum(curwin->w_cursor.lnum + 1);
} else {
@@ -4311,11 +4395,11 @@ format_lines(
}
} else if (do_number_indent) {
if (leader_len == 0 && next_leader_len == 0) {
- /* no comment found */
+ // no comment found
second_indent =
get_number_indent(curwin->w_cursor.lnum);
} else {
- /* get_number_indent() is now "comment aware"... */
+ // get_number_indent() is now "comment aware"...
second_indent =
get_number_indent(curwin->w_cursor.lnum);
do_comments_list = 1;
@@ -4328,20 +4412,22 @@ format_lines(
*/
if (curwin->w_cursor.lnum >= curbuf->b_ml.ml_line_count
|| !same_leader(curwin->w_cursor.lnum,
- leader_len, leader_flags,
- next_leader_len, next_leader_flags)
- )
+ leader_len, leader_flags,
+ next_leader_len,
+ next_leader_flags)) {
is_end_par = true;
+ }
/*
* If we have got to the end of a paragraph, or the line is
* getting long, format it.
*/
if (is_end_par || force_format) {
- if (need_set_indent)
+ if (need_set_indent) {
/* replace indent in first line with minimal number of
* tabs and spaces, according to current options */
(void)set_indent(get_indent(), SIN_CHANGED);
+ }
// put cursor on last non-space
State = NORMAL; // don't go past end-of-line
@@ -4350,25 +4436,26 @@ format_lines(
dec_cursor();
}
- /* do the formatting, without 'showmode' */
- State = INSERT; /* for open_line() */
+ // do the formatting, without 'showmode'
+ State = INSERT; // for open_line()
smd_save = p_smd;
p_smd = FALSE;
insertchar(NUL, INSCHAR_FORMAT
- + (do_comments ? INSCHAR_DO_COM : 0)
- + (do_comments && do_comments_list
+ + (do_comments ? INSCHAR_DO_COM : 0)
+ + (do_comments && do_comments_list
? INSCHAR_COM_LIST : 0)
- + (avoid_fex ? INSCHAR_NO_FEX : 0), second_indent);
+ + (avoid_fex ? INSCHAR_NO_FEX : 0), second_indent);
State = old_State;
p_smd = smd_save;
second_indent = -1;
- /* at end of par.: need to set indent of next par. */
+ // at end of par.: need to set indent of next par.
need_set_indent = is_end_par;
if (is_end_par) {
/* When called with a negative line count, break at the
* end of the paragraph. */
- if (line_count < 0)
+ if (line_count < 0) {
break;
+ }
first_par_line = true;
}
force_format = false;
@@ -4382,8 +4469,9 @@ format_lines(
advance = false;
curwin->w_cursor.lnum++;
curwin->w_cursor.col = 0;
- if (line_count < 0 && u_save_cursor() == FAIL)
+ if (line_count < 0 && u_save_cursor() == FAIL) {
break;
+ }
if (next_leader_len > 0) {
(void)del_bytes(next_leader_len, false, false);
mark_col_adjust(curwin->w_cursor.lnum, (colnr_T)0, 0L,
@@ -4420,11 +4508,12 @@ format_lines(
*/
static int ends_in_white(linenr_T lnum)
{
- char_u *s = ml_get(lnum);
+ char_u *s = ml_get(lnum);
size_t l;
- if (*s == NUL)
+ if (*s == NUL) {
return FALSE;
+ }
l = STRLEN(s) - 1;
return ascii_iswhite(s[l]);
}
@@ -4439,22 +4528,24 @@ static int ends_in_white(linenr_T lnum)
*/
static int fmt_check_par(linenr_T lnum, int *leader_len, char_u **leader_flags, int do_comments)
{
- char_u *flags = NULL; /* init for GCC */
- char_u *ptr;
+ char_u *flags = NULL; // init for GCC
+ char_u *ptr;
ptr = ml_get(lnum);
- if (do_comments)
- *leader_len = get_leader_len(ptr, leader_flags, FALSE, TRUE);
- else
+ if (do_comments) {
+ *leader_len = get_leader_len(ptr, leader_flags, false, true);
+ } else {
*leader_len = 0;
+ }
if (*leader_len > 0) {
/*
* Search for 'e' flag in comment leader flags.
*/
flags = *leader_flags;
- while (*flags && *flags != ':' && *flags != COM_END)
+ while (*flags && *flags != ':' && *flags != COM_END) {
++flags;
+ }
}
return *skipwhite(ptr + *leader_len) == NUL
@@ -4474,13 +4565,13 @@ int paragraph_start(linenr_T lnum)
int next_leader_len = 0; // leader len of next line
char_u *next_leader_flags = NULL; // flags for leader of next line
- if (lnum <= 1)
- return TRUE; /* start of the file */
-
+ if (lnum <= 1) {
+ return TRUE; // start of the file
+ }
p = ml_get(lnum - 1);
- if (*p == NUL)
- return TRUE; /* after empty line */
-
+ if (*p == NUL) {
+ return TRUE; // after empty line
+ }
const bool do_comments = has_format_option(FO_Q_COMS); // format comments
if (fmt_check_par(lnum - 1, &leader_len, &leader_flags, do_comments)) {
return true; // after non-paragraph line
@@ -4490,16 +4581,16 @@ int paragraph_start(linenr_T lnum)
return true; // "lnum" is not a paragraph line
}
- if (has_format_option(FO_WHITE_PAR) && !ends_in_white(lnum - 1))
- return TRUE; /* missing trailing space in previous line. */
-
- if (has_format_option(FO_Q_NUMBER) && (get_number_indent(lnum) > 0))
- return TRUE; /* numbered item starts in "lnum". */
-
+ if (has_format_option(FO_WHITE_PAR) && !ends_in_white(lnum - 1)) {
+ return TRUE; // missing trailing space in previous line.
+ }
+ if (has_format_option(FO_Q_NUMBER) && (get_number_indent(lnum) > 0)) {
+ return TRUE; // numbered item starts in "lnum".
+ }
if (!same_leader(lnum - 1, leader_len, leader_flags,
- next_leader_len, next_leader_flags))
- return TRUE; /* change of comment leader. */
-
+ next_leader_len, next_leader_flags)) {
+ return TRUE; // change of comment leader.
+ }
return FALSE;
}
@@ -4516,15 +4607,14 @@ int paragraph_start(linenr_T lnum)
* - start/endspaces is the number of columns of the first/last yanked char
* that are to be yanked.
*/
-static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum,
- bool is_del)
+static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum, bool is_del)
{
int incr = 0;
- char_u *pend;
- char_u *pstart;
- char_u *line;
- char_u *prev_pstart;
- char_u *prev_pend;
+ char_u *pend;
+ char_u *pstart;
+ char_u *line;
+ char_u *prev_pstart;
+ char_u *prev_pend;
const int lbr_saved = curwin->w_p_lbr;
// Avoid a problem with unwanted linebreaks in block mode.
@@ -4545,8 +4635,8 @@ static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum,
pstart = line;
prev_pstart = line;
while (bdp->start_vcol < oap->start_vcol && *pstart) {
- /* Count a tab for what it's worth (if list mode not on) */
- incr = lbr_chartabsize(line, pstart, (colnr_T)bdp->start_vcol);
+ // Count a tab for what it's worth (if list mode not on)
+ incr = lbr_chartabsize(line, pstart, bdp->start_vcol);
bdp->start_vcol += incr;
if (ascii_iswhite(*pstart)) {
bdp->pre_whitesp += incr;
@@ -4559,7 +4649,7 @@ static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum,
MB_PTR_ADV(pstart);
}
bdp->start_char_vcols = incr;
- if (bdp->start_vcol < oap->start_vcol) { /* line too short */
+ if (bdp->start_vcol < oap->start_vcol) { // line too short
bdp->end_vcol = bdp->start_vcol;
bdp->is_short = true;
if (!is_del || oap->op_type == OP_APPEND) {
@@ -4569,8 +4659,9 @@ static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum,
/* notice: this converts partly selected Multibyte characters to
* spaces, too. */
bdp->startspaces = bdp->start_vcol - oap->start_vcol;
- if (is_del && bdp->startspaces)
+ if (is_del && bdp->startspaces) {
bdp->startspaces = bdp->start_char_vcols - bdp->startspaces;
+ }
pend = pstart;
bdp->end_vcol = bdp->start_vcol;
if (bdp->end_vcol > oap->end_vcol) { // it's all in one character
@@ -4594,9 +4685,9 @@ static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum,
} else {
prev_pend = pend;
while (bdp->end_vcol <= oap->end_vcol && *pend != NUL) {
- /* Count a tab for what it's worth (if list mode not on) */
+ // Count a tab for what it's worth (if list mode not on)
prev_pend = pend;
- incr = lbr_chartabsize_adv(line, &pend, (colnr_T)bdp->end_vcol);
+ incr = lbr_chartabsize_adv(line, &pend, bdp->end_vcol);
bdp->end_vcol += incr;
}
if (bdp->end_vcol <= oap->end_vcol
@@ -4616,17 +4707,19 @@ static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum,
bdp->endspaces = bdp->end_vcol - oap->end_vcol - 1;
if (!is_del && bdp->endspaces) {
bdp->endspaces = incr - bdp->endspaces;
- if (pend != pstart)
+ if (pend != pstart) {
pend = prev_pend;
+ }
}
}
}
bdp->end_char_vcols = incr;
- if (is_del && bdp->startspaces)
+ if (is_del && bdp->startspaces) {
pstart = prev_pstart;
+ }
bdp->textlen = (int)(pend - pstart);
}
- bdp->textcol = (colnr_T) (pstart - line);
+ bdp->textcol = (colnr_T)(pstart - line);
bdp->textstart = pstart;
curwin->w_p_lbr = lbr_saved;
}
@@ -4741,13 +4834,13 @@ void op_addsub(oparg_T *oap, linenr_T Prenum1, bool g_cmd)
int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
{
int col;
- char_u *buf1 = NULL;
+ char_u *buf1 = NULL;
char_u buf2[NUMBUFLEN];
int pre; // 'X' or 'x': hex; '0': octal; 'B' or 'b': bin
static bool hexupper = false; // 0xABC
uvarnumber_T n;
uvarnumber_T oldn;
- char_u *ptr;
+ char_u *ptr;
int c;
int todel;
int firstdigit;
@@ -4803,14 +4896,14 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
&& ptr[col - 1] == '0'
&& !utf_head_off(ptr, ptr + col - 1)
&& ascii_isxdigit(ptr[col + 1])))) {
- // In case of binary/hexadecimal pattern overlap match, rescan
+ // In case of binary/hexadecimal pattern overlap match, rescan
- col = curwin->w_cursor.col;
+ col = curwin->w_cursor.col;
- while (col > 0 && ascii_isdigit(ptr[col])) {
- col--;
- col -= utf_head_off(ptr, ptr + col);
- }
+ while (col > 0 && ascii_isdigit(ptr[col])) {
+ col--;
+ col -= utf_head_off(ptr, ptr + col);
+ }
}
if ((do_hex
@@ -4826,8 +4919,8 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
&& !utf_head_off(ptr, ptr + col - 1)
&& ascii_isbdigit(ptr[col + 1]))) {
// Found hexadecimal or binary number, move to its start.
- col--;
- col -= utf_head_off(ptr, ptr + col);
+ col--;
+ col -= utf_head_off(ptr, ptr + col);
} else {
// Search forward and then backward to find the start of number.
col = pos->col;
@@ -4925,7 +5018,7 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
0 + (do_bin ? STR2NR_BIN : 0)
+ (do_oct ? STR2NR_OCT : 0)
+ (do_hex ? STR2NR_HEX : 0),
- NULL, &n, maxlen);
+ NULL, &n, maxlen, false);
// ignore leading '-' for hex, octal and bin numbers
if (pre && negative) {
@@ -5033,17 +5126,16 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
// leading zeros
for (bits = 8 * sizeof(n); bits > 0; bits--) {
- if ((n >> (bits - 1)) & 0x1) {
- break;
- }
+ if ((n >> (bits - 1)) & 0x1) {
+ break;
+ }
}
while (bits > 0) {
- buf2[i++] = ((n >> --bits) & 0x1) ? '1' : '0';
+ buf2[i++] = ((n >> --bits) & 0x1) ? '1' : '0';
}
buf2[i] = '\0';
-
} else if (pre == 0) {
vim_snprintf((char *)buf2, ARRAY_SIZE(buf2), "%" PRIu64, (uint64_t)n);
} else if (pre == '0') {
@@ -5101,18 +5193,18 @@ theend:
MotionType get_reg_type(int regname, colnr_T *reg_width)
{
switch (regname) {
- case '%': // file name
- case '#': // alternate file name
- case '=': // expression
- case ':': // last command line
- case '/': // last search-pattern
- case '.': // last inserted text
- case Ctrl_F: // Filename under cursor
- case Ctrl_P: // Path under cursor, expand via "path"
- case Ctrl_W: // word under cursor
- case Ctrl_A: // WORD (mnemonic All) under cursor
- case '_': // black hole: always empty
- return kMTCharWise;
+ case '%': // file name
+ case '#': // alternate file name
+ case '=': // expression
+ case ':': // last command line
+ case '/': // last search-pattern
+ case '.': // last inserted text
+ case Ctrl_F: // Filename under cursor
+ case Ctrl_P: // Path under cursor, expand via "path"
+ case Ctrl_W: // word under cursor
+ case Ctrl_A: // WORD (mnemonic All) under cursor
+ case '_': // black hole: always empty
+ return kMTCharWise;
}
if (regname != NUL && !valid_yank_reg(regname, false)) {
@@ -5137,26 +5229,25 @@ MotionType get_reg_type(int regname, colnr_T *reg_width)
/// @param[out] buf Buffer to store formatted string. The allocated size should
/// be at least NUMBUFLEN+2 to always fit the value.
/// @param buf_len The allocated size of the buffer.
-void format_reg_type(MotionType reg_type, colnr_T reg_width,
- char *buf, size_t buf_len)
+void format_reg_type(MotionType reg_type, colnr_T reg_width, char *buf, size_t buf_len)
FUNC_ATTR_NONNULL_ALL
{
assert(buf_len > 1);
switch (reg_type) {
- case kMTLineWise:
- buf[0] = 'V';
- buf[1] = NUL;
- break;
- case kMTCharWise:
- buf[0] = 'v';
- buf[1] = NUL;
- break;
- case kMTBlockWise:
- snprintf(buf, buf_len, CTRL_V_STR "%" PRIdCOLNR, reg_width + 1);
- break;
- case kMTUnknown:
- buf[0] = NUL;
- break;
+ case kMTLineWise:
+ buf[0] = 'V';
+ buf[1] = NUL;
+ break;
+ case kMTCharWise:
+ buf[0] = 'v';
+ buf[1] = NUL;
+ break;
+ case kMTBlockWise:
+ snprintf(buf, buf_len, CTRL_V_STR "%" PRIdCOLNR, reg_width + 1);
+ break;
+ case kMTUnknown:
+ buf[0] = NUL;
+ break;
}
}
@@ -5197,12 +5288,14 @@ void *get_reg_contents(int regname, int flags)
return get_reg_wrap_one_line(get_expr_line(), flags);
}
- if (regname == '@') /* "@@" is used for unnamed register */
+ if (regname == '@') { // "@@" is used for unnamed register
regname = '"';
+ }
- /* check for valid regname */
- if (regname != NUL && !valid_yank_reg(regname, false))
+ // check for valid regname
+ if (regname != NUL && !valid_yank_reg(regname, false)) {
return NULL;
+ }
char_u *retval;
bool allocated;
@@ -5217,8 +5310,9 @@ void *get_reg_contents(int regname, int flags)
}
yankreg_T *reg = get_yank_register(regname, YREG_PASTE);
- if (reg->y_array == NULL)
+ if (reg->y_array == NULL) {
return NULL;
+ }
if (flags & kGRegList) {
list_T *const list = tv_list_alloc((ptrdiff_t)reg->y_size);
@@ -5279,7 +5373,7 @@ static yankreg_T *init_write_reg(int name, yankreg_T **old_y_previous, bool must
yankreg_T *reg = get_yank_register(name, YREG_YANK);
if (!is_append_register(name) && !must_append) {
- free_register(reg);
+ free_register(reg);
}
return reg;
}
@@ -5298,18 +5392,16 @@ static void finish_write_reg(int name, yankreg_T *reg, yankreg_T *old_y_previous
/// write_reg_contents - store `str` in register `name`
///
/// @see write_reg_contents_ex
-void write_reg_contents(int name, const char_u *str, ssize_t len,
- int must_append)
+void write_reg_contents(int name, const char_u *str, ssize_t len, int must_append)
{
write_reg_contents_ex(name, str, len, must_append, kMTUnknown, 0L);
}
-void write_reg_contents_lst(int name, char_u **strings,
- bool must_append, MotionType yank_type,
+void write_reg_contents_lst(int name, char_u **strings, bool must_append, MotionType yank_type,
colnr_T block_len)
{
if (name == '/' || name == '=') {
- char_u *s = strings[0];
+ char_u *s = strings[0];
if (strings[0] == NULL) {
s = (char_u *)"";
} else if (strings[1] != NULL) {
@@ -5326,7 +5418,7 @@ void write_reg_contents_lst(int name, char_u **strings,
return;
}
- yankreg_T *old_y_previous, *reg;
+ yankreg_T *old_y_previous, *reg;
if (!(reg = init_write_reg(name, &old_y_previous, must_append))) {
return;
}
@@ -5354,18 +5446,14 @@ void write_reg_contents_lst(int name, char_u **strings,
/// is an uppercase letter.
/// @param yank_type The motion type (kMTUnknown to auto detect)
/// @param block_len width of visual block
-void write_reg_contents_ex(int name,
- const char_u *str,
- ssize_t len,
- bool must_append,
- MotionType yank_type,
- colnr_T block_len)
+void write_reg_contents_ex(int name, const char_u *str, ssize_t len, bool must_append,
+ MotionType yank_type, colnr_T block_len)
{
if (len < 0) {
- len = (ssize_t) STRLEN(str);
+ len = (ssize_t)STRLEN(str);
}
- /* Special case: '/' search pattern */
+ // Special case: '/' search pattern
if (name == '/') {
set_last_search_pat(str, RE_SEARCH, TRUE, TRUE);
return;
@@ -5394,7 +5482,7 @@ void write_reg_contents_ex(int name,
if (name == '=') {
size_t offset = 0;
- size_t totlen = (size_t) len;
+ size_t totlen = (size_t)len;
if (must_append && expr_line) {
// append has been specified and expr_line already exists, so we'll
@@ -5419,7 +5507,7 @@ void write_reg_contents_ex(int name,
return;
}
- yankreg_T *old_y_previous, *reg;
+ yankreg_T *old_y_previous, *reg;
if (!(reg = init_write_reg(name, &old_y_previous, must_append))) {
return;
}
@@ -5437,9 +5525,8 @@ void write_reg_contents_ex(int name,
/// @param len length of the string (Ignored when str_list=true.)
/// @param blocklen width of visual block, or -1 for "I don't know."
/// @param str_list True if str is `char_u **`.
-static void str_to_reg(yankreg_T *y_ptr, MotionType yank_type,
- const char_u *str, size_t len, colnr_T blocklen,
- bool str_list)
+static void str_to_reg(yankreg_T *y_ptr, MotionType yank_type, const char_u *str, size_t len,
+ colnr_T blocklen, bool str_list)
FUNC_ATTR_NONNULL_ALL
{
if (y_ptr->y_array == NULL) { // NULL means empty register
@@ -5458,7 +5545,7 @@ static void str_to_reg(yankreg_T *y_ptr, MotionType yank_type,
// Count the number of lines within the string
if (str_list) {
- for (char_u **ss = (char_u **) str; *ss != NULL; ++ss) {
+ for (char_u **ss = (char_u **)str; *ss != NULL; ++ss) {
newlines++;
}
} else {
@@ -5473,6 +5560,11 @@ static void str_to_reg(yankreg_T *y_ptr, MotionType yank_type,
}
}
+ // Without any lines make the register empty.
+ if (y_ptr->y_size + newlines == 0) {
+ XFREE_CLEAR(y_ptr->y_array);
+ return;
+ }
// Grow the register array to hold the pointers to the new lines.
char_u **pp = xrealloc(y_ptr->y_array,
@@ -5486,7 +5578,7 @@ static void str_to_reg(yankreg_T *y_ptr, MotionType yank_type,
// Find the end of each line and save it into the array.
if (str_list) {
- for (char_u **ss = (char_u **) str; *ss != NULL; ++ss, ++lnum) {
+ for (char_u **ss = (char_u **)str; *ss != NULL; ++ss, ++lnum) {
size_t ss_len = STRLEN(*ss);
pp[lnum] = xmemdupz(*ss, ss_len);
if (ss_len > maxlen) {
@@ -5527,7 +5619,7 @@ static void str_to_reg(yankreg_T *y_ptr, MotionType yank_type,
set_yreg_additional_data(y_ptr, NULL);
y_ptr->timestamp = os_time();
if (yank_type == kMTBlockWise) {
- y_ptr->y_width = (blocklen == -1 ? (colnr_T) maxlen - 1 : blocklen);
+ y_ptr->y_width = (blocklen == -1 ? (colnr_T)maxlen - 1 : blocklen);
} else {
y_ptr->y_width = 0;
}
@@ -5553,9 +5645,8 @@ void clear_oparg(oparg_T *oap)
* case, eol_size will be added to the character count to account for
* the size of the EOL character.
*/
-static varnumber_T line_count_info(char_u *line, varnumber_T *wc,
- varnumber_T *cc, varnumber_T limit,
- int eol_size)
+static varnumber_T line_count_info(char_u *line, varnumber_T *wc, varnumber_T *cc,
+ varnumber_T limit, int eol_size)
{
varnumber_T i;
varnumber_T words = 0;
@@ -5568,17 +5659,19 @@ static varnumber_T line_count_info(char_u *line, varnumber_T *wc,
words++;
is_word = 0;
}
- } else if (!ascii_isspace(line[i]))
+ } else if (!ascii_isspace(line[i])) {
is_word = 1;
+ }
++chars;
i += (*mb_ptr2len)(line + i);
}
- if (is_word)
+ if (is_word) {
words++;
+ }
*wc += words;
- /* Add eol_size if the end of line was reached before hitting limit. */
+ // Add eol_size if the end of line was reached before hitting limit.
if (i < limit && line[i] == NUL) {
i += eol_size;
chars += eol_size;
@@ -5593,7 +5686,7 @@ static varnumber_T line_count_info(char_u *line, varnumber_T *wc,
/// When "dict" is not NULL store the info there instead of showing it.
void cursor_pos_info(dict_T *dict)
{
- char_u *p;
+ char_u *p;
char_u buf1[50];
char_u buf2[40];
linenr_T lnum;
@@ -5620,10 +5713,11 @@ void cursor_pos_info(dict_T *dict)
return;
}
} else {
- if (get_fileformat(curbuf) == EOL_DOS)
+ if (get_fileformat(curbuf) == EOL_DOS) {
eol_size = 2;
- else
+ } else {
eol_size = 1;
+ }
if (l_VIsual_active) {
if (lt(VIsual, curwin->w_cursor)) {
@@ -5633,23 +5727,28 @@ void cursor_pos_info(dict_T *dict)
min_pos = curwin->w_cursor;
max_pos = VIsual;
}
- if (*p_sel == 'e' && max_pos.col > 0)
+ if (*p_sel == 'e' && max_pos.col > 0) {
--max_pos.col;
+ }
if (l_VIsual_mode == Ctrl_V) {
- char_u * saved_sbr = p_sbr;
+ char_u *const saved_sbr = p_sbr;
+ char_u *const saved_w_sbr = curwin->w_p_sbr;
- /* Make 'sbr' empty for a moment to get the correct size. */
+ // Make 'sbr' empty for a moment to get the correct size.
p_sbr = empty_option;
+ curwin->w_p_sbr = empty_option;
oparg.is_VIsual = true;
oparg.motion_type = kMTBlockWise;
oparg.op_type = OP_NOP;
getvcols(curwin, &min_pos, &max_pos,
- &oparg.start_vcol, &oparg.end_vcol);
+ &oparg.start_vcol, &oparg.end_vcol);
p_sbr = saved_sbr;
- if (curwin->w_curswant == MAXCOL)
+ curwin->w_p_sbr = saved_w_sbr;
+ if (curwin->w_curswant == MAXCOL) {
oparg.end_vcol = MAXCOL;
- /* Swap the start, end vcol if needed */
+ }
+ // Swap the start, end vcol if needed
if (oparg.end_vcol < oparg.start_vcol) {
oparg.end_vcol += oparg.start_vcol;
oparg.start_vcol = oparg.end_vcol - oparg.start_vcol;
@@ -5660,18 +5759,19 @@ void cursor_pos_info(dict_T *dict)
}
for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count; ++lnum) {
- /* Check for a CTRL-C every 100000 characters. */
+ // Check for a CTRL-C every 100000 characters.
if (byte_count > last_check) {
os_breakcheck();
- if (got_int)
+ if (got_int) {
return;
+ }
last_check = byte_count + 100000L;
}
- /* Do extra processing for VIsual mode. */
+ // Do extra processing for VIsual mode.
if (l_VIsual_active
&& lnum >= min_pos.lnum && lnum <= max_pos.lnum) {
- char_u *s = NULL;
+ char_u *s = NULL;
long len = 0L;
switch (l_VIsual_mode) {
@@ -5686,8 +5786,7 @@ void cursor_pos_info(dict_T *dict)
s = ml_get(lnum);
len = MAXCOL;
break;
- case 'v':
- {
+ case 'v': {
colnr_T start_col = (lnum == min_pos.lnum)
? min_pos.col : 0;
colnr_T end_col = (lnum == max_pos.lnum)
@@ -5700,23 +5799,24 @@ void cursor_pos_info(dict_T *dict)
}
if (s != NULL) {
byte_count_cursor += line_count_info(s, &word_count_cursor,
- &char_count_cursor, len, eol_size);
+ &char_count_cursor, len, eol_size);
if (lnum == curbuf->b_ml.ml_line_count
&& !curbuf->b_p_eol
&& (curbuf->b_p_bin || !curbuf->b_p_fixeol)
- && (long)STRLEN(s) < len)
+ && (long)STRLEN(s) < len) {
byte_count_cursor -= eol_size;
+ }
}
} else {
- /* In non-visual mode, check for the line the cursor is on */
+ // In non-visual mode, check for the line the cursor is on
if (lnum == curwin->w_cursor.lnum) {
word_count_cursor += word_count;
char_count_cursor += char_count;
byte_count_cursor = byte_count
- + line_count_info(ml_get(lnum), &word_count_cursor,
- &char_count_cursor,
- (varnumber_T)curwin->w_cursor.col + 1,
- eol_size);
+ + line_count_info(ml_get(lnum), &word_count_cursor,
+ &char_count_cursor,
+ (varnumber_T)curwin->w_cursor.col + 1,
+ eol_size);
}
}
// Add to the running totals
@@ -5814,18 +5914,18 @@ void cursor_pos_info(dict_T *dict)
if (dict != NULL) {
// Don't shorten this message, the user asked for it.
- tv_dict_add_nr(dict, S_LEN("words"), (varnumber_T)word_count);
- tv_dict_add_nr(dict, S_LEN("chars"), (varnumber_T)char_count);
+ tv_dict_add_nr(dict, S_LEN("words"), word_count);
+ tv_dict_add_nr(dict, S_LEN("chars"), char_count);
tv_dict_add_nr(dict, S_LEN("bytes"), (varnumber_T)(byte_count + bom_count));
STATIC_ASSERT(sizeof("visual") == sizeof("cursor"),
"key_len argument in tv_dict_add_nr is wrong");
tv_dict_add_nr(dict, l_VIsual_active ? "visual_bytes" : "cursor_bytes",
- sizeof("visual_bytes") - 1, (varnumber_T)byte_count_cursor);
+ sizeof("visual_bytes") - 1, byte_count_cursor);
tv_dict_add_nr(dict, l_VIsual_active ? "visual_chars" : "cursor_chars",
- sizeof("visual_chars") - 1, (varnumber_T)char_count_cursor);
+ sizeof("visual_chars") - 1, char_count_cursor);
tv_dict_add_nr(dict, l_VIsual_active ? "visual_words" : "cursor_words",
- sizeof("visual_words") - 1, (varnumber_T)word_count_cursor);
+ sizeof("visual_words") - 1, word_count_cursor);
}
}
@@ -5914,13 +6014,16 @@ bool prepare_yankreg_from_object(yankreg_T *reg, String regtype, size_t lines)
case 0:
reg->y_type = kMTUnknown;
break;
- case 'v': case 'c':
+ case 'v':
+ case 'c':
reg->y_type = kMTCharWise;
break;
- case 'V': case 'l':
+ case 'V':
+ case 'l':
reg->y_type = kMTLineWise;
break;
- case 'b': case Ctrl_V:
+ case 'b':
+ case Ctrl_V:
reg->y_type = kMTBlockWise;
break;
default:
@@ -6025,13 +6128,16 @@ static bool get_clipboard(int name, yankreg_T **target, bool quiet)
case 0:
reg->y_type = kMTUnknown;
break;
- case 'v': case 'c':
+ case 'v':
+ case 'c':
reg->y_type = kMTCharWise;
break;
- case 'V': case 'l':
+ case 'V':
+ case 'l':
reg->y_type = kMTLineWise;
break;
- case 'b': case Ctrl_V:
+ case 'b':
+ case Ctrl_V:
reg->y_type = kMTBlockWise;
break;
default:
@@ -6055,11 +6161,10 @@ static bool get_clipboard(int name, yankreg_T **target, bool quiet)
if (TV_LIST_ITEM_TV(li)->v_type != VAR_STRING) {
goto err;
}
- reg->y_array[tv_idx++] = (char_u *)xstrdupnul(
- (const char *)TV_LIST_ITEM_TV(li)->vval.v_string);
+ reg->y_array[tv_idx++] = (char_u *)xstrdupnul((const char *)TV_LIST_ITEM_TV(li)->vval.v_string);
});
- if (reg->y_size > 0 && strlen((char*)reg->y_array[reg->y_size-1]) == 0) {
+ if (reg->y_size > 0 && strlen((char *)reg->y_array[reg->y_size-1]) == 0) {
// a known-to-be charwise yank might have a final linebreak
// but otherwise there is no line after the final newline
if (reg->y_type != kMTCharWise) {
@@ -6114,8 +6219,7 @@ static void set_clipboard(int name, yankreg_T *reg)
return;
}
- list_T *const lines = tv_list_alloc(
- (ptrdiff_t)reg->y_size + (reg->y_type != kMTCharWise));
+ list_T *const lines = tv_list_alloc((ptrdiff_t)reg->y_size + (reg->y_type != kMTCharWise));
for (size_t i = 0; i < reg->y_size; i++) {
tv_list_append_string(lines, (const char *)reg->y_array[i], -1);
@@ -6123,23 +6227,19 @@ static void set_clipboard(int name, yankreg_T *reg)
char regtype;
switch (reg->y_type) {
- case kMTLineWise: {
- regtype = 'V';
- tv_list_append_string(lines, NULL, 0);
- break;
- }
- case kMTCharWise: {
- regtype = 'v';
- break;
- }
- case kMTBlockWise: {
- regtype = 'b';
- tv_list_append_string(lines, NULL, 0);
- break;
- }
- case kMTUnknown: {
- abort();
- }
+ case kMTLineWise:
+ regtype = 'V';
+ tv_list_append_string(lines, NULL, 0);
+ break;
+ case kMTCharWise:
+ regtype = 'v';
+ break;
+ case kMTBlockWise:
+ regtype = 'b';
+ tv_list_append_string(lines, NULL, 0);
+ break;
+ case kMTUnknown:
+ abort();
}
list_T *args = tv_list_alloc(3);
@@ -6213,8 +6313,8 @@ 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)
+const void *op_global_reg_iter(const void *const 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);
@@ -6229,9 +6329,8 @@ const void *op_global_reg_iter(const void *const iter, char *const name,
///
/// @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)
+const void *op_reg_iter(const void *const iter, const yankreg_T *const 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;
@@ -6250,7 +6349,7 @@ const void *op_reg_iter(const void *const iter, const yankreg_T *const regs,
*is_unnamed = (iter_reg == y_previous);
while (++iter_reg - &(regs[0]) < NUM_SAVED_REGISTERS) {
if (!reg_empty(iter_reg)) {
- return (void *) iter_reg;
+ return (void *)iter_reg;
}
}
return NULL;
@@ -6325,8 +6424,7 @@ bool op_reg_set_previous(const char name)
/// Get the byte count of buffer region. End-exclusive.
///
/// @return number of bytes
-bcount_t get_region_bytecount(buf_T *buf, linenr_T start_lnum,
- linenr_T end_lnum, colnr_T start_col,
+bcount_t get_region_bytecount(buf_T *buf, linenr_T start_lnum, linenr_T end_lnum, colnr_T start_col,
colnr_T end_col)
{
linenr_T max_lnum = buf->b_ml.ml_line_count;
@@ -6343,8 +6441,7 @@ bcount_t get_region_bytecount(buf_T *buf, linenr_T start_lnum,
if (start_lnum + i > max_lnum) {
return deleted_bytes;
}
- deleted_bytes += (bcount_t)STRLEN(
- ml_get_buf(buf, start_lnum + i, false)) + 1;
+ deleted_bytes += (bcount_t)STRLEN(ml_get_buf(buf, start_lnum + i, false)) + 1;
}
if (end_lnum > max_lnum) {
return deleted_bytes;
diff --git a/src/nvim/ops.h b/src/nvim/ops.h
index 112ffbeaba..5b87746921 100644
--- a/src/nvim/ops.h
+++ b/src/nvim/ops.h
@@ -90,6 +90,13 @@ typedef struct yankreg {
dict_T *additional_data; ///< Additional data from ShaDa file.
} yankreg_T;
+/// Modes for get_yank_register()
+typedef enum {
+ YREG_PASTE,
+ YREG_YANK,
+ YREG_PUT,
+} yreg_mode_t;
+
/// Convert register name into register index
///
/// @param[in] regname Register name.
diff --git a/src/nvim/option.c b/src/nvim/option.c
index 388bedc043..5646a62cd4 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -16,58 +16,56 @@
// - If it's a numeric option, add any necessary bounds checks to
// set_num_option().
// - If it's a list of flags, add some code in do_set(), search for WW_ALL.
-// - When adding an option with expansion (P_EXPAND), but with a different
-// default for Vi and Vim (no P_VI_DEF), add some code at VIMEXP.
// - Add documentation! doc/options.txt, and any other related places.
// - Add an entry in runtime/optwin.vim.
#define IN_OPTION_C
#include <assert.h>
#include <inttypes.h>
+#include <limits.h>
#include <stdbool.h>
-#include <string.h>
#include <stdlib.h>
-#include <limits.h>
+#include <string.h>
-#include "nvim/vim.h"
-#include "nvim/macros.h"
#include "nvim/ascii.h"
-#include "nvim/edit.h"
-#include "nvim/option.h"
#include "nvim/buffer.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
+#include "nvim/cursor_shape.h"
#include "nvim/diff.h"
#include "nvim/digraph.h"
+#include "nvim/edit.h"
#include "nvim/eval.h"
#include "nvim/eval/typval.h"
#include "nvim/ex_cmds2.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_getln.h"
+#include "nvim/ex_session.h"
#include "nvim/fileio.h"
#include "nvim/fold.h"
+#include "nvim/garray.h"
#include "nvim/getchar.h"
#include "nvim/hardcopy.h"
#include "nvim/highlight.h"
#include "nvim/indent_c.h"
+#include "nvim/keymap.h"
+#include "nvim/macros.h"
#include "nvim/mbyte.h"
#include "nvim/memfile.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/runtime.h"
-#include "nvim/keymap.h"
-#include "nvim/garray.h"
-#include "nvim/cursor_shape.h"
-#include "nvim/move.h"
#include "nvim/mouse.h"
+#include "nvim/move.h"
#include "nvim/normal.h"
+#include "nvim/option.h"
+#include "nvim/os/os.h"
#include "nvim/os_unix.h"
#include "nvim/path.h"
#include "nvim/popupmnu.h"
#include "nvim/regexp.h"
-#include "nvim/ex_session.h"
+#include "nvim/runtime.h"
#include "nvim/screen.h"
#include "nvim/spell.h"
#include "nvim/spellfile.h"
@@ -76,13 +74,13 @@
#include "nvim/ui.h"
#include "nvim/ui_compositor.h"
#include "nvim/undo.h"
+#include "nvim/vim.h"
#include "nvim/window.h"
-#include "nvim/os/os.h"
#ifdef WIN32
# include "nvim/os/pty_conpty_win.h"
#endif
-#include "nvim/lua/executor.h"
#include "nvim/api/private/helpers.h"
+#include "nvim/lua/executor.h"
#include "nvim/os/input.h"
#include "nvim/os/lang.h"
#include "nvim/quickfix.h"
@@ -126,64 +124,64 @@ static char *p_ttytype = NULL;
static int p_ai;
static int p_bin;
static int p_bomb;
-static char_u *p_bh;
-static char_u *p_bt;
+static char_u *p_bh;
+static char_u *p_bt;
static int p_bl;
static long p_channel;
static int p_ci;
static int p_cin;
-static char_u *p_cink;
-static char_u *p_cino;
-static char_u *p_cinw;
-static char_u *p_com;
-static char_u *p_cms;
-static char_u *p_cpt;
-static char_u *p_cfu;
-static char_u *p_ofu;
-static char_u *p_tfu;
+static char_u *p_cink;
+static char_u *p_cino;
+static char_u *p_cinw;
+static char_u *p_com;
+static char_u *p_cms;
+static char_u *p_cpt;
+static char_u *p_cfu;
+static char_u *p_ofu;
+static char_u *p_tfu;
static int p_eol;
static int p_fixeol;
static int p_et;
-static char_u *p_fenc;
-static char_u *p_ff;
-static char_u *p_fo;
-static char_u *p_flp;
-static char_u *p_ft;
+static char_u *p_fenc;
+static char_u *p_ff;
+static char_u *p_fo;
+static char_u *p_flp;
+static char_u *p_ft;
static long p_iminsert;
static long p_imsearch;
-static char_u *p_inex;
-static char_u *p_inde;
-static char_u *p_indk;
-static char_u *p_fex;
+static char_u *p_inex;
+static char_u *p_inde;
+static char_u *p_indk;
+static char_u *p_fex;
static int p_inf;
-static char_u *p_isk;
+static char_u *p_isk;
static int p_lisp;
static int p_ml;
static int p_ma;
static int p_mod;
-static char_u *p_mps;
-static char_u *p_nf;
+static char_u *p_mps;
+static char_u *p_nf;
static int p_pi;
-static char_u *p_qe;
+static char_u *p_qe;
static int p_ro;
static int p_si;
static long p_sts;
-static char_u *p_sua;
+static char_u *p_sua;
static long p_sw;
static int p_swf;
static long p_smc;
-static char_u *p_syn;
-static char_u *p_spc;
-static char_u *p_spf;
-static char_u *p_spl;
-static char_u *p_spo;
+static char_u *p_syn;
+static char_u *p_spc;
+static char_u *p_spf;
+static char_u *p_spl;
+static char_u *p_spo;
static long p_ts;
static long p_tw;
static int p_udf;
static long p_wm;
static char_u *p_vsts;
static char_u *p_vts;
-static char_u *p_keymap;
+static char_u *p_keymap;
// Saved values for when 'bin' is set.
static int p_et_nobin;
@@ -200,20 +198,18 @@ static long p_wm_nopaste;
static char_u *p_vsts_nopaste;
typedef struct vimoption {
- char *fullname; // full option name
- char *shortname; // permissible abbreviation
+ char *fullname; // full option name
+ char *shortname; // permissible abbreviation
uint32_t flags; // see below
- char_u *var; // global option: pointer to variable;
- // window-local option: VAR_WIN;
- // buffer-local option: global value
+ char_u *var; // global option: pointer to variable;
+ // window-local option: VAR_WIN;
+ // buffer-local option: global value
idopt_T indir; // global option: PV_NONE;
// local option: indirect option index
- char_u *def_val[2]; // default values for variable (vi and vim)
+ char_u *def_val; // default values for variable (neovim!!)
LastSet last_set; // script in which the option was last set
} vimoption_T;
-#define VI_DEFAULT 0 // def_val[VI_DEFAULT] is Vi default value
-#define VIM_DEFAULT 1 // def_val[VIM_DEFAULT] is Vim default value
/*
* Flags
@@ -232,8 +228,6 @@ typedef struct vimoption {
// use free() when assigning new value
#define P_WAS_SET 0x100U // option has been set/reset
#define P_NO_MKRC 0x200U // don't include in :mkvimrc output
-#define P_VI_DEF 0x400U // Use Vi default for Vim
-#define P_VIM 0x800U // Vim option
// when option changed, what to display:
#define P_RSTAT 0x1000U ///< redraw status lines
@@ -266,15 +260,13 @@ typedef struct vimoption {
#define P_MLE 0x80000000U ///< under control of 'modelineexpr'
#define HIGHLIGHT_INIT \
- "8:SpecialKey,~:EndOfBuffer,z:TermCursor,Z:TermCursorNC,@:NonText," \
- "d:Directory,e:ErrorMsg,i:IncSearch,l:Search,m:MoreMsg,M:ModeMsg,n:LineNr," \
- "N:CursorLineNr,r:Question,s:StatusLine,S:StatusLineNC,c:VertSplit,t:Title," \
- "v:Visual,V:VisualNOS,w:WarningMsg,W:WildMenu,f:Folded,F:FoldColumn," \
- "A:DiffAdd,C:DiffChange,D:DiffDelete,T:DiffText,>:SignColumn,-:Conceal," \
- "B:SpellBad,P:SpellCap,R:SpellRare,L:SpellLocal,+:Pmenu,=:PmenuSel," \
- "x:PmenuSbar,X:PmenuThumb,*:TabLine,#:TabLineSel,_:TabLineFill," \
- "!:CursorColumn,.:CursorLine,o:ColorColumn,q:QuickFixLine," \
- "0:Whitespace,I:NormalNC"
+ "8:SpecialKey,~:EndOfBuffer,z:TermCursor,Z:TermCursorNC,@:NonText,d:Directory,e:ErrorMsg," \
+ "i:IncSearch,l:Search,m:MoreMsg,M:ModeMsg,n:LineNr,a:LineNrAbove,b:LineNrBelow,N:CursorLineNr," \
+ "r:Question,s:StatusLine,S:StatusLineNC,c:VertSplit,t:Title,v:Visual,V:VisualNOS,w:WarningMsg," \
+ "W:WildMenu,f:Folded,F:FoldColumn,A:DiffAdd,C:DiffChange,D:DiffDelete,T:DiffText,>:SignColumn," \
+ "-:Conceal,B:SpellBad,P:SpellCap,R:SpellRare,L:SpellLocal,+:Pmenu,=:PmenuSel,x:PmenuSbar," \
+ "X:PmenuThumb,*:TabLine,#:TabLineSel,_:TabLineFill,!:CursorColumn,.:CursorLine,o:ColorColumn," \
+ "q:QuickFixLine,0:Whitespace,I:NormalNC"
/*
* options[] is initialized here.
@@ -322,12 +314,15 @@ static char *(p_csl_values[]) = { "slash", "backslash", NULL };
#endif
static char *(p_icm_values[]) = { "nosplit", "split", NULL };
static char *(p_scl_values[]) = { "yes", "no", "auto", "auto:1", "auto:2",
- "auto:3", "auto:4", "auto:5", "auto:6", "auto:7", "auto:8", "auto:9",
- "yes:1", "yes:2", "yes:3", "yes:4", "yes:5", "yes:6", "yes:7", "yes:8",
- "yes:9", "number", NULL };
+ "auto:3", "auto:4", "auto:5", "auto:6", "auto:7", "auto:8",
+ "auto:9",
+ "yes:1", "yes:2", "yes:3", "yes:4", "yes:5", "yes:6",
+ "yes:7", "yes:8",
+ "yes:9", "number", NULL };
static char *(p_fdc_values[]) = { "auto", "auto:1", "auto:2",
- "auto:3", "auto:4", "auto:5", "auto:6", "auto:7", "auto:8", "auto:9",
- "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", NULL };
+ "auto:3", "auto:4", "auto:5", "auto:6", "auto:7", "auto:8",
+ "auto:9",
+ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", NULL };
/// All possible flags for 'shm'.
static char_u SHM_ALL[] = {
@@ -379,11 +374,11 @@ void set_init_1(bool clean_arg)
* temp files.
*/
{
-# ifdef UNIX
- static char *(names[4]) = {"", "TMPDIR", "TEMP", "TMP"};
-# else
- static char *(names[3]) = {"TMPDIR", "TEMP", "TMP"};
-# endif
+#ifdef UNIX
+ static char *(names[4]) = { "", "TMPDIR", "TEMP", "TMP" };
+#else
+ static char *(names[3]) = { "TMPDIR", "TEMP", "TMP" };
+#endif
garray_T ga;
opt_idx = findoption("backupskip");
@@ -391,16 +386,16 @@ void set_init_1(bool clean_arg)
for (size_t n = 0; n < ARRAY_SIZE(names); n++) {
bool mustfree = true;
char *p;
-# ifdef UNIX
+#ifdef UNIX
if (*names[n] == NUL) {
-# ifdef __APPLE__
+# ifdef __APPLE__
p = "/private/tmp";
-# else
+# else
p = "/tmp";
-# endif
+# endif
mustfree = false;
} else
-# endif
+#endif
{
p = vim_getenv(names[n]);
}
@@ -434,8 +429,8 @@ void set_init_1(bool clean_arg)
}
{
- char_u *cdpath;
- char_u *buf;
+ char_u *cdpath;
+ char_u *buf;
int i;
int j;
@@ -459,7 +454,7 @@ void set_init_1(bool clean_arg)
buf[j] = NUL;
opt_idx = findoption("cdpath");
if (opt_idx >= 0) {
- options[opt_idx].def_val[VI_DEFAULT] = buf;
+ options[opt_idx].def_val = buf;
options[opt_idx].flags |= P_DEF_ALLOCED;
} else {
xfree(buf); // cannot happen
@@ -478,30 +473,30 @@ void set_init_1(bool clean_arg)
set_string_default("printexpr",
#ifdef UNIX
"system(['lpr'] "
- "+ (empty(&printdevice)?[]:['-P', &printdevice]) "
- "+ [v:fname_in])"
+ "+ (empty(&printdevice)?[]:['-P', &printdevice]) "
+ "+ [v:fname_in])"
". delete(v:fname_in)"
"+ v:shell_error",
#elif defined(MSWIN)
"system(['copy', v:fname_in, "
- "empty(&printdevice)?'LPT1':&printdevice])"
+ "empty(&printdevice)?'LPT1':&printdevice])"
". delete(v:fname_in)",
#else
"",
#endif
false);
- char *backupdir = stdpaths_user_data_subpath("backup", 0, true);
+ char *backupdir = stdpaths_user_data_subpath("backup", 2, true);
const size_t backupdir_len = strlen(backupdir);
backupdir = xrealloc(backupdir, backupdir_len + 3);
memmove(backupdir + 2, backupdir, backupdir_len + 1);
memmove(backupdir, ".,", 2);
- set_string_default("viewdir", stdpaths_user_data_subpath("view", 0, true),
- true);
set_string_default("backupdir", backupdir, true);
+ set_string_default("viewdir", stdpaths_user_data_subpath("view", 2, true),
+ true);
set_string_default("directory", stdpaths_user_data_subpath("swap", 2, true),
true);
- set_string_default("undodir", stdpaths_user_data_subpath("undo", 0, true),
+ set_string_default("undodir", stdpaths_user_data_subpath("undo", 2, true),
true);
// Set default for &runtimepath. All necessary expansions are performed in
// this function.
@@ -527,7 +522,7 @@ void set_init_1(bool clean_arg)
check_win_options(curwin);
check_options();
- // Set all options to their Vim default
+ // Set all options to their default value
set_options_default(OPT_FREE);
// set 'laststatus'
@@ -558,20 +553,15 @@ void set_init_1(bool clean_arg)
&& options[opt_idx].var != NULL) {
p = _(*(char **)options[opt_idx].var);
} else {
- p = (char *) option_expand(opt_idx, NULL);
+ p = (char *)option_expand(opt_idx, NULL);
}
if (p != NULL) {
p = xstrdup(p);
*(char **)options[opt_idx].var = p;
- /* VIMEXP
- * Defaults for all expanded options are currently the same for Vi
- * and Vim. When this changes, add some code here! Also need to
- * split P_DEF_ALLOCED in two.
- */
if (options[opt_idx].flags & P_DEF_ALLOCED) {
- xfree(options[opt_idx].def_val[VI_DEFAULT]);
+ xfree(options[opt_idx].def_val);
}
- options[opt_idx].def_val[VI_DEFAULT] = (char_u *)p;
+ options[opt_idx].def_val = (char_u *)p;
options[opt_idx].flags |= P_DEF_ALLOCED;
}
}
@@ -597,8 +587,8 @@ void set_init_1(bool clean_arg)
// in 'fileencodings'
char_u *p = enc_locale();
if (p == NULL) {
- // use utf-8 as 'default' if locale encoding can't be detected.
- p = (char_u *)xmemdupz(S_LEN("utf-8"));
+ // use utf-8 as 'default' if locale encoding can't be detected.
+ p = (char_u *)xmemdupz(S_LEN("utf-8"));
}
fenc_default = p;
@@ -614,39 +604,34 @@ void set_init_1(bool clean_arg)
/// Set an option to its default value.
/// This does not take care of side effects!
-static void
-set_option_default(
- int opt_idx,
- int opt_flags, // OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL
- int compatible // use Vi default value
-)
-{
- char_u *varp; // pointer to variable for current option
- int dvi; // index in def_val[]
+///
+/// @param opt_flags OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL
+static void set_option_default(int opt_idx, int opt_flags)
+{
+ char_u *varp; // pointer to variable for current option
int both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0;
varp = get_varp_scope(&(options[opt_idx]), both ? OPT_LOCAL : opt_flags);
uint32_t flags = options[opt_idx].flags;
if (varp != NULL) { // skip hidden option, nothing to do for it
- dvi = ((flags & P_VI_DEF) || compatible) ? VI_DEFAULT : VIM_DEFAULT;
if (flags & P_STRING) {
/* Use set_string_option_direct() for local options to handle
* freeing and allocating the value. */
if (options[opt_idx].indir != PV_NONE) {
set_string_option_direct(NULL, opt_idx,
- options[opt_idx].def_val[dvi], opt_flags, 0);
+ options[opt_idx].def_val, opt_flags, 0);
} else {
if ((opt_flags & OPT_FREE) && (flags & P_ALLOCED)) {
free_string_option(*(char_u **)(varp));
}
- *(char_u **)varp = options[opt_idx].def_val[dvi];
+ *(char_u **)varp = options[opt_idx].def_val;
options[opt_idx].flags &= ~P_ALLOCED;
}
- } else if (flags & P_NUM) {
+ } else if (flags & P_NUM) {
if (options[opt_idx].indir == PV_SCROLL) {
win_comp_scroll(curwin);
} else {
- long def_val = (long)options[opt_idx].def_val[dvi];
+ long def_val = (long)options[opt_idx].def_val;
if ((long *)varp == &curwin->w_p_so
|| (long *)varp == &curwin->w_p_siso) {
// 'scrolloff' and 'sidescrolloff' local values have a
@@ -662,7 +647,7 @@ set_option_default(
}
}
} else { // P_BOOL
- *(int *)varp = (int)(intptr_t)options[opt_idx].def_val[dvi];
+ *(int *)varp = (int)(intptr_t)options[opt_idx].def_val;
#ifdef UNIX
// 'modeline' defaults to off for root
if (options[opt_idx].indir == PV_ML && getuid() == ROOT_UID) {
@@ -685,14 +670,13 @@ set_option_default(
}
/// Set all options (except terminal options) to their default value.
-static void
-set_options_default(
- int opt_flags // OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL
-)
+///
+/// @param opt_flags OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL
+static void set_options_default(int opt_flags)
{
for (int i = 0; options[i].fullname; i++) {
if (!(options[i].flags & P_NODEFAULT)) {
- set_option_default(i, opt_flags, false);
+ set_option_default(i, opt_flags);
}
}
@@ -716,10 +700,10 @@ static void set_string_default(const char *name, char *val, bool allocated)
int opt_idx = findoption(name);
if (opt_idx >= 0) {
if (options[opt_idx].flags & P_DEF_ALLOCED) {
- xfree(options[opt_idx].def_val[VI_DEFAULT]);
+ xfree(options[opt_idx].def_val);
}
- options[opt_idx].def_val[VI_DEFAULT] = allocated
+ options[opt_idx].def_val = allocated
? (char_u *)val
: (char_u *)xstrdup(val);
options[opt_idx].flags |= P_DEF_ALLOCED;
@@ -728,8 +712,7 @@ static void set_string_default(const char *name, char *val, bool allocated)
// For an option value that contains comma separated items, find "newval" in
// "origval". Return NULL if not found.
-static char_u *find_dup_item(char_u *origval, const char_u *newval,
- uint32_t flags)
+static char_u *find_dup_item(char_u *origval, const char_u *newval, uint32_t flags)
FUNC_ATTR_NONNULL_ARG(2)
{
int bs = 0;
@@ -766,7 +749,7 @@ void set_number_default(char *name, long val)
opt_idx = findoption(name);
if (opt_idx >= 0) {
- options[opt_idx].def_val[VI_DEFAULT] = (char_u *)(intptr_t)val;
+ options[opt_idx].def_val = (char_u *)(intptr_t)val;
}
}
@@ -781,11 +764,11 @@ void free_all_options(void)
free_string_option(*(char_u **)options[i].var);
}
if (options[i].flags & P_DEF_ALLOCED) {
- free_string_option(options[i].def_val[VI_DEFAULT]);
+ free_string_option(options[i].def_val);
}
} else if (options[i].var != VAR_WIN && (options[i].flags & P_STRING)) {
// buffer-local option: free global value
- free_string_option(*(char_u **)options[i].var);
+ clear_string_option((char_u **)options[i].var);
}
}
}
@@ -804,7 +787,7 @@ void set_init_2(bool headless)
// which results in the actual value computed from the window height.
idx = findoption("scroll");
if (idx >= 0 && !(options[idx].flags & P_WAS_SET)) {
- set_option_default(idx, OPT_LOCAL, false);
+ set_option_default(idx, OPT_LOCAL);
}
comp_col();
@@ -845,16 +828,15 @@ 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 ( fnamecmp(p, "csh") == 0
- || fnamecmp(p, "tcsh") == 0
- ) {
+ if (fnamecmp(p, "csh") == 0
+ || fnamecmp(p, "tcsh") == 0) {
if (do_sp) {
p_sp = (char_u *)"|& tee";
- options[idx_sp].def_val[VI_DEFAULT] = p_sp;
+ options[idx_sp].def_val = p_sp;
}
if (do_srr) {
p_srr = (char_u *)">&";
- options[idx_srr].def_val[VI_DEFAULT] = p_srr;
+ options[idx_srr].def_val = p_srr;
}
} else if (fnamecmp(p, "sh") == 0
|| fnamecmp(p, "ksh") == 0
@@ -865,22 +847,21 @@ void set_init_3(void)
|| fnamecmp(p, "bash") == 0
|| fnamecmp(p, "fish") == 0
|| fnamecmp(p, "ash") == 0
- || fnamecmp(p, "dash") == 0
- ) {
+ || fnamecmp(p, "dash") == 0) {
// Always use POSIX shell style redirection if we reach this
if (do_sp) {
p_sp = (char_u *)"2>&1| tee";
- options[idx_sp].def_val[VI_DEFAULT] = p_sp;
+ options[idx_sp].def_val = p_sp;
}
if (do_srr) {
p_srr = (char_u *)">%s 2>&1";
- options[idx_srr].def_val[VI_DEFAULT] = p_srr;
+ options[idx_srr].def_val = p_srr;
}
}
xfree(p);
}
- if (BUFEMPTY()) {
+ if (buf_is_empty(curbuf)) {
int idx_ffs = findoption_len(S_LEN("ffs"));
// Apply the first entry of 'fileformats' to the initial buffer.
@@ -941,38 +922,37 @@ void set_title_defaults(void)
*/
idx1 = findoption("title");
if (idx1 >= 0 && !(options[idx1].flags & P_WAS_SET)) {
- options[idx1].def_val[VI_DEFAULT] = (char_u *)(intptr_t)0;
+ options[idx1].def_val = (char_u *)(intptr_t)0;
p_title = 0;
}
idx1 = findoption("icon");
if (idx1 >= 0 && !(options[idx1].flags & P_WAS_SET)) {
- options[idx1].def_val[VI_DEFAULT] = (char_u *)(intptr_t)0;
+ options[idx1].def_val = (char_u *)(intptr_t)0;
p_icon = 0;
}
}
-// Parse 'arg' for option settings.
-//
-// 'arg' may be IObuff, but only when no errors can be present and option
-// does not need to be expanded with option_expand().
-// "opt_flags":
-// 0 for ":set"
-// OPT_GLOBAL for ":setglobal"
-// OPT_LOCAL for ":setlocal" and a modeline
-// OPT_MODELINE for a modeline
-// OPT_WINONLY to only set window-local options
-// OPT_NOWIN to skip setting window-local options
-//
-// returns FAIL if an error is detected, OK otherwise
-int do_set(
- char_u *arg, // option string (may be written to!)
- int opt_flags
-)
+/// Parse 'arg' for option settings.
+///
+/// 'arg' may be IObuff, but only when no errors can be present and option
+/// does not need to be expanded with option_expand().
+/// "opt_flags":
+/// 0 for ":set"
+/// OPT_GLOBAL for ":setglobal"
+/// OPT_LOCAL for ":setlocal" and a modeline
+/// OPT_MODELINE for a modeline
+/// OPT_WINONLY to only set window-local options
+/// OPT_NOWIN to skip setting window-local options
+///
+/// @param arg option string (may be written to!)
+///
+/// @return FAIL if an error is detected, OK otherwise
+int do_set(char_u *arg, int opt_flags)
{
int opt_idx;
- char_u *errmsg;
+ char_u *errmsg;
char_u errbuf[80];
- char_u *startarg;
+ char_u *startarg;
int prefix; // 1: nothing, 0: "no", 2: "inv" in front of name
char_u nextchar; // next non-white char after option name
int afterchar; // character just after option name
@@ -981,12 +961,11 @@ int do_set(
varnumber_T value;
int key;
uint32_t flags; // flags for current option
- char_u *varp = NULL; // pointer to variable for current option
+ char_u *varp = NULL; // pointer to variable for current option
int did_show = false; // already showed one value
int adding; // "opt+=arg"
int prepending; // "opt^=arg"
int removing; // "opt-=arg"
- int cp_val = 0;
if (*arg == NUL) {
showoptions(0, opt_flags);
@@ -1118,8 +1097,9 @@ int do_set(
/* Skip all options that are not window-local (used when showing
* an already loaded buffer in a window). */
if ((opt_flags & OPT_WINONLY)
- && (opt_idx < 0 || options[opt_idx].var != VAR_WIN))
+ && (opt_idx < 0 || options[opt_idx].var != VAR_WIN)) {
goto skip;
+ }
// Skip all options that are window-local (used for :vimgrep).
if ((opt_flags & OPT_NOWIN) && opt_idx >= 0
@@ -1134,8 +1114,7 @@ int do_set(
goto skip;
}
if ((flags & P_MLE) && !p_mle) {
- errmsg = (char_u *)N_(
- "E992: Not allowed in a modeline when 'modelineexpr' is off");
+ errmsg = (char_u *)N_("E992: Not allowed in a modeline when 'modelineexpr' is off");
goto skip;
}
// In diff mode some options are overruled. This avoids that
@@ -1157,13 +1136,10 @@ int do_set(
if (vim_strchr((char_u *)"?=:!&<", nextchar) != NULL) {
arg += len;
- cp_val = false;
if (nextchar == '&' && arg[1] == 'v' && arg[2] == 'i') {
- if (arg[3] == 'm') { // "opt&vim": set to Vim default
- cp_val = false;
+ if (arg[3] == 'm') { // "opt&vim": set to Vim default
arg += 3;
- } else { // "opt&vi": set to Vi default
- cp_val = true;
+ } else { // "opt&vi": set to Vi default
arg += 2;
}
}
@@ -1174,10 +1150,10 @@ int do_set(
}
}
- /*
- * allow '=' and ':' as MSDOS command.com allows only one
- * '=' character per "set" command line. grrr. (jw)
- */
+ //
+ // allow '=' and ':' as MS-DOS command.com allows only one
+ // '=' character per "set" command line. grrr. (jw)
+ //
if (nextchar == '?'
|| (prefix == 1
&& vim_strchr((char_u *)"=:&<", nextchar) == NULL
@@ -1199,10 +1175,10 @@ int do_set(
option_last_set_msg(options[opt_idx].last_set);
} else if ((int)options[opt_idx].indir & PV_WIN) {
option_last_set_msg(curwin->w_p_script_ctx[
- (int)options[opt_idx].indir & PV_MASK]);
+ (int)options[opt_idx].indir & PV_MASK]);
} else if ((int)options[opt_idx].indir & PV_BUF) {
option_last_set_msg(curbuf->b_p_script_ctx[
- (int)options[opt_idx].indir & PV_MASK]);
+ (int)options[opt_idx].indir & PV_MASK]);
}
}
} else {
@@ -1210,8 +1186,9 @@ int do_set(
goto skip;
}
if (nextchar != '?'
- && nextchar != NUL && !ascii_iswhite(afterchar))
+ && nextchar != NUL && !ascii_iswhite(afterchar)) {
errmsg = e_trailing;
+ }
} else {
int value_is_replaced = !prepending && !adding && !removing;
int value_checked = false;
@@ -1230,9 +1207,7 @@ int do_set(
if (nextchar == '!') {
value = *(int *)(varp) ^ 1;
} else if (nextchar == '&') {
- value = (int)(intptr_t)options[opt_idx].def_val[
- ((flags & P_VI_DEF) || cp_val)
- ? VI_DEFAULT : VIM_DEFAULT];
+ value = (int)(intptr_t)options[opt_idx].def_val;
} else if (nextchar == '<') {
// For 'autoread' -1 means to use global value.
if ((int *)varp == &curbuf->b_p_ar
@@ -1277,16 +1252,14 @@ int do_set(
// other error
arg++;
if (nextchar == '&') {
- value = (long)(intptr_t)options[opt_idx].def_val[
- ((flags & P_VI_DEF) || cp_val) ? VI_DEFAULT : VIM_DEFAULT];
+ value = (long)(intptr_t)options[opt_idx].def_val;
} else if (nextchar == '<') {
// For 'undolevels' NO_LOCAL_UNDOLEVEL means to
// use the global value.
if ((long *)varp == &curbuf->b_p_ul && opt_flags == OPT_LOCAL) {
value = NO_LOCAL_UNDOLEVEL;
} else {
- value = *(long *)get_varp_scope(
- &(options[opt_idx]), OPT_GLOBAL);
+ value = *(long *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL);
}
} else if (((long *)varp == &p_wc
|| (long *)varp == &p_wcm)
@@ -1301,9 +1274,9 @@ int do_set(
}
} else if (*arg == '-' || ascii_isdigit(*arg)) {
// Allow negative, octal and hex numbers.
- vim_str2nr(arg, NULL, &i, STR2NR_ALL, &value, NULL, 0);
- if (arg[i] != NUL && !ascii_iswhite(arg[i])) {
- errmsg = e_invarg;
+ vim_str2nr(arg, NULL, &i, STR2NR_ALL, &value, NULL, 0, true);
+ if (i == 0 || (arg[i] != NUL && !ascii_iswhite(arg[i]))) {
+ errmsg = (char_u *)N_("E521: Number required after =");
goto skip;
}
} else {
@@ -1324,11 +1297,11 @@ int do_set(
errbuf, sizeof(errbuf),
opt_flags);
} else if (opt_idx >= 0) { // String.
- char_u *save_arg = NULL;
- char_u *s = NULL;
- char_u *oldval = NULL; // previous value if *varp
- char_u *newval;
- char_u *origval = NULL;
+ char_u *save_arg = NULL;
+ char_u *s = NULL;
+ char_u *oldval = NULL; // previous value if *varp
+ char_u *newval;
+ char_u *origval = NULL;
char *saved_origval = NULL;
char *saved_newval = NULL;
unsigned newlen;
@@ -1339,8 +1312,9 @@ int do_set(
* with a local value the local value will be
* reset, use the global value here. */
if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0
- && ((int)options[opt_idx].indir & PV_BOTH))
+ && ((int)options[opt_idx].indir & PV_BOTH)) {
varp = options[opt_idx].var;
+ }
/* The old value is kept until we are sure that the
* new value is valid. */
@@ -1355,14 +1329,12 @@ int do_set(
origval = oldval;
}
- if (nextchar == '&') { // set to default val
- newval = options[opt_idx].def_val[
- ((flags & P_VI_DEF) || cp_val)
- ? VI_DEFAULT : VIM_DEFAULT];
- /* expand environment variables and ~ (since the
- * default value was already expanded, only
- * required when an environment variable was set
- * later */
+ if (nextchar == '&') { // set to default val
+ newval = options[opt_idx].def_val;
+ // expand environment variables and ~ (since the
+ // default value was already expanded, only
+ // required when an environment variable was set
+ // later
new_value_alloced = true;
if (newval == NULL) {
newval = empty_option;
@@ -1376,8 +1348,7 @@ int do_set(
newval = (char_u *)xstrdup((char *)newval);
}
} else if (nextchar == '<') { // set to global val
- newval = vim_strsave(*(char_u **)get_varp_scope(
- &(options[opt_idx]), OPT_GLOBAL));
+ newval = vim_strsave(*(char_u **)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL));
new_value_alloced = true;
} else {
arg++; // jump to after the '=' or ':'
@@ -1405,16 +1376,13 @@ int do_set(
*(char_u **)varp = empty_option;
break;
case 1:
- *(char_u **)varp = vim_strsave(
- (char_u *)"indent,eol");
+ *(char_u **)varp = vim_strsave((char_u *)"indent,eol");
break;
case 2:
- *(char_u **)varp = vim_strsave(
- (char_u *)"indent,eol,start");
+ *(char_u **)varp = vim_strsave((char_u *)"indent,eol,start");
break;
case 3:
- *(char_u **)varp = vim_strsave(
- (char_u *)"indent,eol,nostop");
+ *(char_u **)varp = vim_strsave((char_u *)"indent,eol,nostop");
break;
}
xfree(oldval);
@@ -1433,22 +1401,19 @@ int do_set(
*errbuf = NUL;
i = getdigits_int(&arg, true, 0);
if (i & 1) {
- STRCAT(errbuf, "b,");
+ STRLCAT(errbuf, "b,", sizeof(errbuf));
}
if (i & 2) {
- STRCAT(errbuf, "s,");
+ STRLCAT(errbuf, "s,", sizeof(errbuf));
}
if (i & 4) {
- STRCAT(errbuf, "h,l,");
+ STRLCAT(errbuf, "h,l,", sizeof(errbuf));
}
if (i & 8) {
- STRCAT(errbuf, "<,>,");
+ STRLCAT(errbuf, "<,>,", sizeof(errbuf));
}
if (i & 16) {
- STRCAT(errbuf, "[,],");
- }
- if (*errbuf != NUL) { // remove trailing ,
- errbuf[STRLEN(errbuf) - 1] = NUL;
+ STRLCAT(errbuf, "[,],", sizeof(errbuf));
}
save_arg = arg;
arg = errbuf;
@@ -1457,9 +1422,9 @@ int do_set(
* Remove '>' before 'dir' and 'bdir', for
* backwards compatibility with version 3.0
*/
- else if ( *arg == '>'
- && (varp == (char_u *)&p_dir
- || varp == (char_u *)&p_bdir)) {
+ else if (*arg == '>'
+ && (varp == (char_u *)&p_dir
+ || varp == (char_u *)&p_bdir)) {
arg++;
}
@@ -1494,8 +1459,9 @@ int do_set(
|| (s == newval
&& arg[2] != '\\')))
#endif
- )
+ ) {
arg++; // remove backslash
+ }
i = utfc_ptr2len(arg);
if (i > 1) {
// copy multibyte char
@@ -1563,7 +1529,7 @@ int do_set(
i--;
}
memmove(newval + i + comma, newval,
- STRLEN(newval) + 1);
+ STRLEN(newval) + 1);
memmove(newval, origval, (size_t)i);
} else {
i = (int)STRLEN(newval);
@@ -1680,7 +1646,6 @@ int do_set(
if (errmsg != NULL) {
goto skip;
}
-
} else {
// key code option(FIXME(tarruda): Show a warning or something
// similar)
@@ -1749,15 +1714,13 @@ theend:
return OK;
}
-// Call this when an option has been given a new value through a user command.
-// Sets the P_WAS_SET flag and takes care of the P_INSECURE flag.
-static void did_set_option(
- int opt_idx,
- int opt_flags, // possibly with OPT_MODELINE
- int new_value, // value was replaced completely
- int value_checked // value was checked to be safe, no need to
- // set P_INSECURE
-)
+/// Call this when an option has been given a new value through a user command.
+/// Sets the P_WAS_SET flag and takes care of the P_INSECURE flag.
+///
+/// @param opt_flags possibly with OPT_MODELINE
+/// @param new_value value was replaced completely
+/// @param value_checked value was checked to be safe, no need to set P_INSECURE
+static void did_set_option(int opt_idx, int opt_flags, int new_value, int value_checked)
{
options[opt_idx].flags |= P_WAS_SET;
@@ -1826,12 +1789,10 @@ static void did_set_title(void)
}
}
-// set_options_bin - called when 'bin' changes value.
-void set_options_bin(
- int oldval,
- int newval,
- int opt_flags // OPT_LOCAL and/or OPT_GLOBAL
-)
+/// set_options_bin - called when 'bin' changes value.
+///
+/// @param opt_flags OPT_LOCAL and/or OPT_GLOBAL
+void set_options_bin(int oldval, int newval, int opt_flags)
{
/*
* The option values that are changed when 'bin' changes are
@@ -1889,7 +1850,7 @@ void set_options_bin(
/// number, return -1.
int get_shada_parameter(int type)
{
- char_u *p;
+ char_u *p;
p = find_shada_parameter(type);
if (p != NULL && ascii_isdigit(*p)) {
@@ -1903,7 +1864,7 @@ int get_shada_parameter(int type)
/// Return NULL if the parameter is not specified in the string.
char_u *find_shada_parameter(int type)
{
- char_u *p;
+ char_u *p;
for (p = p_shada; *p; p++) {
if (*p == type) {
@@ -1987,6 +1948,7 @@ static void didset_options(void)
briopt_check(curwin);
// initialize the table for 'breakat'.
fill_breakat_flags();
+ fill_culopt_flags(NULL, curwin);
}
// More side effects of setting options.
@@ -2131,12 +2093,18 @@ static uint32_t *insecure_flag(win_T *const wp, int opt_idx, int opt_flags)
if (opt_flags & OPT_LOCAL) {
assert(wp != NULL);
switch ((int)options[opt_idx].indir) {
- case PV_STL: return &wp->w_p_stl_flags;
- case PV_FDE: return &wp->w_p_fde_flags;
- case PV_FDT: return &wp->w_p_fdt_flags;
- case PV_INDE: return &wp->w_buffer->b_p_inde_flags;
- case PV_FEX: return &wp->w_buffer->b_p_fex_flags;
- case PV_INEX: return &wp->w_buffer->b_p_inex_flags;
+ case PV_STL:
+ return &wp->w_p_stl_flags;
+ case PV_FDE:
+ return &wp->w_p_fde_flags;
+ case PV_FDT:
+ return &wp->w_p_fdt_flags;
+ case PV_INDE:
+ return &wp->w_buffer->b_p_inde_flags;
+ case PV_FEX:
+ return &wp->w_buffer->b_p_fex_flags;
+ case PV_INEX:
+ return &wp->w_buffer->b_p_inex_flags;
}
}
@@ -2154,23 +2122,19 @@ static void redraw_titles(void)
static int shada_idx = -1;
-// Set a string option to a new value (without checking the effect).
-// The string is copied into allocated memory.
-// if ("opt_idx" == -1) "name" is used, otherwise "opt_idx" is used.
-// When "set_sid" is zero set the scriptID to current_sctx.sc_sid. When
-// "set_sid" is SID_NONE don't set the scriptID. Otherwise set the scriptID to
-// "set_sid".
-void
-set_string_option_direct(
- const char *name,
- int opt_idx,
- const char_u *val,
- int opt_flags, // OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL
- int set_sid
-)
-{
- char_u *s;
- char_u **varp;
+/// Set a string option to a new value (without checking the effect).
+/// The string is copied into allocated memory.
+/// if ("opt_idx" == -1) "name" is used, otherwise "opt_idx" is used.
+/// When "set_sid" is zero set the scriptID to current_sctx.sc_sid. When
+/// "set_sid" is SID_NONE don't set the scriptID. Otherwise set the scriptID to
+/// "set_sid".
+///
+/// @param opt_flags OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL
+void set_string_option_direct(const char *name, int opt_idx, const char_u *val, int opt_flags,
+ int set_sid)
+{
+ char_u *s;
+ char_u **varp;
int both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0;
int idx = opt_idx;
@@ -2187,7 +2151,7 @@ set_string_option_direct(
return;
}
- assert((void *) options[idx].var != (void *) &p_shada);
+ assert((void *)options[idx].var != (void *)&p_shada);
s = vim_strsave(val);
{
@@ -2227,13 +2191,12 @@ set_string_option_direct(
}
/// Set global value for string option when it's a local option.
-static void
-set_string_option_global(
- int opt_idx, // option index
- char_u **varp // pointer to option variable
-)
+///
+/// @param opt_idx option index
+/// @param varp pointer to option variable
+static void set_string_option_global(int opt_idx, char_u **varp)
{
- char_u **p, *s;
+ char_u **p, *s;
// the global value is always allocated
if (options[opt_idx].var == VAR_WIN) {
@@ -2256,8 +2219,7 @@ set_string_option_global(
/// #OPT_GLOBAL.
///
/// @return NULL on success, error message on error.
-static char *set_string_option(const int opt_idx, const char *const value,
- const int opt_flags)
+static char *set_string_option(const int opt_idx, const char *const value, const int opt_flags)
FUNC_ATTR_NONNULL_ARG(2) FUNC_ATTR_WARN_UNUSED_RESULT
{
if (options[opt_idx].var == NULL) { // don't set hidden option
@@ -2265,12 +2227,11 @@ static char *set_string_option(const int opt_idx, const char *const value,
}
char *const s = xstrdup(value);
- char **const varp = (char **)get_varp_scope(
- &(options[opt_idx]),
- ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0
+ char **const varp = (char **)get_varp_scope(&(options[opt_idx]),
+ ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0
? (((int)options[opt_idx].indir & PV_BOTH)
? OPT_GLOBAL : OPT_LOCAL)
- : opt_flags));
+ : opt_flags));
char *const oldval = *varp;
*varp = s;
@@ -2278,9 +2239,9 @@ static char *set_string_option(const int opt_idx, const char *const value,
char *const saved_newval = xstrdup(s);
int value_checked = false;
- char *const r = (char *)did_set_string_option(
- opt_idx, (char_u **)varp, (int)true, (char_u *)oldval,
- NULL, 0, opt_flags, &value_checked);
+ char *const r = (char *)did_set_string_option(opt_idx, (char_u **)varp, (int)true,
+ (char_u *)oldval,
+ NULL, 0, opt_flags, &value_checked);
if (r == NULL) {
did_set_option(opt_idx, opt_flags, true, value_checked);
}
@@ -2344,23 +2305,23 @@ static bool valid_spellfile(const char_u *val)
/// Handle string options that need some action to perform when changed.
/// Returns NULL for success, or an error message for an error.
-static char_u *
-did_set_string_option(
- int opt_idx, // index in options[] table
- char_u **varp, // pointer to the option variable
- bool new_value_alloced, // new value was allocated
- char_u *oldval, // previous value of the option
- char_u *errbuf, // buffer for errors, or NULL
- size_t errbuflen, // length of errors buffer
- int opt_flags, // OPT_LOCAL and/or OPT_GLOBAL
- int *value_checked // value was checked to be safe, no
- // need to set P_INSECURE
-)
-{
- char_u *errmsg = NULL;
- char_u *s, *p;
+///
+/// @param opt_idx index in options[] table
+/// @param varp pointer to the option variable
+/// @param new_value_alloced new value was allocated
+/// @param oldval previous value of the option
+/// @param errbuf buffer for errors, or NULL
+/// @param errbuflen length of errors buffer
+/// @param opt_flags OPT_LOCAL and/or OPT_GLOBAL
+/// @param value_checked value was checked to be safe, no need to set P_INSECURE
+static char_u *did_set_string_option(int opt_idx, char_u **varp, bool new_value_alloced,
+ char_u *oldval, char_u *errbuf, size_t errbuflen,
+ int opt_flags, int *value_checked)
+{
+ char_u *errmsg = NULL;
+ char_u *s, *p;
int did_chartab = false;
- char_u **gvarp;
+ char_u **gvarp;
bool free_oldval = (options[opt_idx].flags & P_ALLOCED);
bool value_changed = false;
@@ -2374,7 +2335,7 @@ did_set_string_option(
errmsg = e_secure;
} else if (((options[opt_idx].flags & P_NFNAME)
&& vim_strpbrk(*varp, (char_u *)(secure ? "/\\*?[|;&<>\r\n"
- : "/\\*?[<>\r\n")) != NULL)
+ : "/\\*?[<>\r\n")) != NULL)
|| ((options[opt_idx].flags & P_NDNAME)
&& vim_strpbrk(*varp, (char_u *)"*?[|;&<>\r\n") != NULL)) {
// Check for a "normal" directory or file name in some options. Disallow a
@@ -2382,7 +2343,7 @@ did_set_string_option(
// are often illegal in a file name. Be more permissive if "secure" is off.
errmsg = e_invarg;
} else if (gvarp == &p_bkc) { // 'backupcopy'
- char_u *bkc = p_bkc;
+ char_u *bkc = p_bkc;
unsigned int *flags = &bkc_flags;
if (opt_flags & OPT_LOCAL) {
@@ -2436,6 +2397,13 @@ did_set_string_option(
os_setenv("VIMRUNTIME", "", 1);
didset_vimruntime = false;
}
+ } else if (varp == &p_rtp || varp == &p_pp) { // 'runtimepath' 'packpath'
+ runtime_search_path_invalidate();
+ } else if (varp == &curwin->w_p_culopt
+ || gvarp == &curwin->w_allbuf_opt.wo_culopt) { // 'cursorlineopt'
+ if (**varp == NUL || fill_culopt_flags(*varp, curwin) != OK) {
+ errmsg = e_invarg;
+ }
} else if (varp == &curwin->w_p_cc) { // 'colorcolumn'
errmsg = check_colorcolumn(curwin);
} else if (varp == &p_hlg) { // 'helplang'
@@ -2517,13 +2485,14 @@ ambw_end:
check_string_option(&p_bg);
init_highlight(false, false);
}
- } else
+ } else {
errmsg = e_invarg;
+ }
} else if (varp == &p_wim) { // 'wildmode'
if (check_opt_wim() == FAIL) {
errmsg = e_invarg;
}
- // 'wildoptions'
+ // 'wildoptions'
} else if (varp == &p_wop) {
if (opt_strings_flags(p_wop, p_wop_values, &wop_flags, true) != OK) {
errmsg = e_invarg;
@@ -2537,7 +2506,7 @@ ambw_end:
if (check_ei() == FAIL) {
errmsg = e_invarg;
}
- // 'encoding', 'fileencoding' and 'makeencoding'
+ // 'encoding', 'fileencoding' and 'makeencoding'
} else if (varp == &p_enc || gvarp == &p_fenc || gvarp == &p_menc) {
if (gvarp == &p_fenc) {
if (!MODIFIABLE(curbuf) && opt_flags != OPT_GLOBAL) {
@@ -2708,7 +2677,7 @@ ambw_end:
if (*p_vfile != NUL && verbose_open() == FAIL) {
errmsg = e_invarg;
}
- // 'shada'
+ // 'shada'
} else if (varp == &p_shada) {
// TODO(ZyX-I): Remove this code in the future, alongside with &viminfo
// option.
@@ -2716,10 +2685,10 @@ ambw_end:
? (shada_idx == -1
? ((shada_idx = findoption("shada")))
: shada_idx)
- : opt_idx);
+ : opt_idx);
// Update free_oldval now that we have the opt_idx for 'shada', otherwise
// there would be a disconnect between the check for P_ALLOCED at the start
- // of the function and the set of P_ALLOCED at the end of the fuction.
+ // of the function and the set of P_ALLOCED at the end of the function.
free_oldval = (options[opt_idx].flags & P_ALLOCED);
for (s = p_shada; *s; ) {
// Check it's a valid character
@@ -2745,8 +2714,9 @@ ambw_end:
_("E526: Missing number after <%s>"),
transchar_byte(*(s - 1)));
errmsg = errbuf;
- } else
+ } else {
errmsg = (char_u *)"";
+ }
break;
}
}
@@ -2764,10 +2734,10 @@ ambw_end:
if (*p_shada && errmsg == NULL && get_shada_parameter('\'') < 0) {
errmsg = (char_u *)N_("E528: Must specify a ' value");
}
- } else if (varp == &p_sbr) { // 'showbreak'
- for (s = p_sbr; *s; ) {
+ } else if (gvarp == &p_sbr) { // 'showbreak'
+ for (s = *varp; *s; ) {
if (ptr2cells(s) != 1) {
- errmsg = (char_u *)N_("E595: contains unprintable or wide character");
+ errmsg = (char_u *)N_("E595: 'showbreak' contains unprintable or wide character");
}
MB_PTR_ADV(s);
}
@@ -2792,7 +2762,6 @@ ambw_end:
stl_syntax &= ~flagval;
}
did_set_title();
-
} else if (varp == &p_sel) { // 'selection'
if (*p_sel == NUL
|| check_opt_strings(p_sel, p_sel_values, false) != OK) {
@@ -2911,8 +2880,9 @@ ambw_end:
} else if (gvarp == &p_cpt) {
// check if it is a valid value for 'complete' -- Acevedo
for (s = *varp; *s; ) {
- while (*s == ',' || *s == ' ')
+ while (*s == ',' || *s == ' ') {
s++;
+ }
if (!*s) {
break;
}
@@ -2935,8 +2905,9 @@ ambw_end:
_("E535: Illegal character after <%c>"),
*--s);
errmsg = errbuf;
- } else
+ } else {
errmsg = (char_u *)"";
+ }
break;
}
}
@@ -3047,8 +3018,7 @@ ambw_end:
}
} else if (gvarp == &p_cms) { // 'commentstring'
if (**varp != NUL && strstr((char *)(*varp), "%s") == NULL) {
- errmsg = (char_u *)N_(
- "E537: 'commentstring' must be empty or contain %s");
+ errmsg = (char_u *)N_("E537: 'commentstring' must be empty or contain %s");
}
} else if (varp == &p_fdo) { // 'foldopen'
if (opt_strings_flags(p_fdo, p_fdo_values, &fdo_flags, true) != OK) {
@@ -3091,11 +3061,11 @@ ambw_end:
} else if (gvarp == &p_cino) { // 'cinoptions'
// TODO(vim): recognize errors
parse_cino(curbuf);
- // inccommand
+ // inccommand
} else if (varp == &p_icm) {
- if (check_opt_strings(p_icm, p_icm_values, false) != OK) {
- errmsg = e_invarg;
- }
+ if (check_opt_strings(p_icm, p_icm_values, false) != OK) {
+ errmsg = e_invarg;
+ }
} else if (gvarp == &p_ft) {
if (!valid_filetype(*varp)) {
errmsg = e_invarg;
@@ -3297,7 +3267,7 @@ ambw_end:
}
if (varp == &(curwin->w_s->b_p_spl)) {
char_u fname[200];
- char_u *q = curwin->w_s->b_p_spl;
+ char_u *q = curwin->w_s->b_p_spl;
// Skip the first name if it is "cjk".
if (STRNCMP(q, "cjk,", 4) == 0) {
@@ -3328,8 +3298,9 @@ ambw_end:
}
if (curwin->w_curswant != MAXCOL
- && (options[opt_idx].flags & (P_CURSWANT | P_RALL)) != 0)
+ && (options[opt_idx].flags & (P_CURSWANT | P_RALL)) != 0) {
curwin->w_set_curswant = true;
+ }
check_redraw(options[opt_idx].flags);
@@ -3357,8 +3328,7 @@ int check_signcolumn(char_u *val)
&& !STRNCMP(val, "auto:", 5)
&& ascii_isdigit(val[5])
&& val[6] == '-'
- && ascii_isdigit(val[7])
- ) {
+ && ascii_isdigit(val[7])) {
int min = val[5] - '0';
int max = val[7] - '0';
if (min < 1 || max < 2 || min > 8 || max > 9 || min >= max) {
@@ -3375,7 +3345,7 @@ int check_signcolumn(char_u *val)
/// @return error message, NULL if it's OK.
char_u *check_colorcolumn(win_T *wp)
{
- char_u *s;
+ char_u *s;
int col;
unsigned int count = 0;
int color_cols[256];
@@ -3465,11 +3435,13 @@ static char_u *set_chars_option(win_T *wp, char_u **varp, bool set)
int c1;
int c2 = 0;
int c3 = 0;
+ char_u *last_multispace = NULL; // Last occurrence of "multispace:"
+ int multispace_len = 0; // Length of lcs-multispace string
struct chars_tab {
- int *cp; ///< char value
- char *name; ///< char id
- int def; ///< default value
+ int *cp; ///< char value
+ char *name; ///< char id
+ int def; ///< default value
};
struct chars_tab *tab;
@@ -3534,6 +3506,15 @@ static char_u *set_chars_option(win_T *wp, char_u **varp, bool set)
if (varp == &p_lcs || varp == &wp->w_p_lcs) {
wp->w_p_lcs_chars.tab1 = NUL;
wp->w_p_lcs_chars.tab3 = NUL;
+ if (wp->w_p_lcs_chars.multispace != NULL) {
+ xfree(wp->w_p_lcs_chars.multispace);
+ }
+ if (multispace_len > 0) {
+ wp->w_p_lcs_chars.multispace = xmalloc((size_t)(multispace_len + 1) * sizeof(int));
+ wp->w_p_lcs_chars.multispace[multispace_len] = NUL;
+ } else {
+ wp->w_p_lcs_chars.multispace = NULL;
+ }
}
}
p = *varp;
@@ -3550,27 +3531,27 @@ static char_u *set_chars_option(win_T *wp, char_u **varp, bool set)
int c1len = utf_ptr2len(s);
c1 = mb_cptr2char_adv((const char_u **)&s);
if (mb_char2cells(c1) > 1 || (c1len == 1 && c1 > 127)) {
- continue;
+ return e_invarg;
}
if (tab[i].cp == &wp->w_p_lcs_chars.tab2) {
if (*s == NUL) {
- continue;
+ return e_invarg;
}
int c2len = utf_ptr2len(s);
c2 = mb_cptr2char_adv((const char_u **)&s);
if (mb_char2cells(c2) > 1 || (c2len == 1 && c2 > 127)) {
- continue;
+ return e_invarg;
}
if (!(*s == ',' || *s == NUL)) {
int c3len = utf_ptr2len(s);
c3 = mb_cptr2char_adv((const char_u **)&s);
if (mb_char2cells(c3) > 1 || (c3len == 1 && c3 > 127)) {
- continue;
+ return e_invarg;
}
}
}
if (*s == ',' || *s == NUL) {
- if (round) {
+ if (round > 0) {
if (tab[i].cp == &wp->w_p_lcs_chars.tab2) {
wp->w_p_lcs_chars.tab1 = c1;
wp->w_p_lcs_chars.tab2 = c2;
@@ -3586,7 +3567,42 @@ static char_u *set_chars_option(win_T *wp, char_u **varp, bool set)
}
if (i == entries) {
- return e_invarg;
+ len = (int)STRLEN("multispace");
+ if ((varp == &p_lcs || varp == &wp->w_p_lcs)
+ && STRNCMP(p, "multispace", len) == 0
+ && p[len] == ':'
+ && p[len + 1] != NUL) {
+ s = p + len + 1;
+ if (round == 0) {
+ // Get length of lcs-multispace string in the first round
+ last_multispace = p;
+ multispace_len = 0;
+ while (*s != NUL && *s != ',') {
+ int c1len = utf_ptr2len(s);
+ c1 = mb_cptr2char_adv((const char_u **)&s);
+ if (mb_char2cells(c1) > 1 || (c1len == 1 && c1 > 127)) {
+ return e_invarg;
+ }
+ multispace_len++;
+ }
+ if (multispace_len == 0) {
+ // lcs-multispace cannot be an empty string
+ return e_invarg;
+ }
+ p = s;
+ } else {
+ int multispace_pos = 0;
+ while (*s != NUL && *s != ',') {
+ c1 = mb_cptr2char_adv((const char_u **)&s);
+ if (p == last_multispace) {
+ wp->w_p_lcs_chars.multispace[multispace_pos++] = c1;
+ }
+ }
+ p = s;
+ }
+ } else {
+ return e_invarg;
+ }
}
if (*p == ',') {
p++;
@@ -3635,8 +3651,9 @@ char_u *check_stl_option(char_u *s)
}
if (*s == '.') {
s++;
- while (*s && ascii_isdigit(*s))
+ while (*s && ascii_isdigit(*s)) {
s++;
+ }
}
if (*s == '(') {
groupdepth++;
@@ -3664,7 +3681,7 @@ char_u *check_stl_option(char_u *s)
static char_u *did_set_spell_option(bool is_spellfile)
{
- char_u *errmsg = NULL;
+ char_u *errmsg = NULL;
if (is_spellfile) {
int l = (int)STRLEN(curwin->w_s->b_p_spf);
@@ -3691,8 +3708,8 @@ static char_u *did_set_spell_option(bool is_spellfile)
static char_u *compile_cap_prog(synblock_T *synblock)
FUNC_ATTR_NONNULL_ALL
{
- regprog_T *rp = synblock->b_cap_prog;
- char_u *re;
+ regprog_T *rp = synblock->b_cap_prog;
+ char_u *re;
if (synblock->b_p_spc == NULL || *synblock->b_p_spc == NUL) {
synblock->b_cap_prog = NULL;
@@ -3791,8 +3808,7 @@ static void set_option_sctx_idx(int opt_idx, int opt_flags, sctx_T script_ctx)
/// @param[in] opt_flags OPT_LOCAL and/or OPT_GLOBAL.
///
/// @return NULL on success, error message on error.
-static char *set_bool_option(const int opt_idx, char_u *const varp,
- const int value,
+static char *set_bool_option(const int opt_idx, char_u *const varp, const int value,
const int opt_flags)
{
int old_value = *(int *)varp;
@@ -3817,7 +3833,7 @@ static char *set_bool_option(const int opt_idx, char_u *const varp,
if ((int *)varp == &p_force_on && p_force_on == false) {
p_force_on = true;
return (char *)e_unsupportedoption;
- // Ensure that options set to p_force_off cannot be enabled.
+ // Ensure that options set to p_force_off cannot be enabled.
} else if ((int *)varp == &p_force_off && p_force_off == true) {
p_force_off = false;
return (char *)e_unsupportedoption;
@@ -3830,29 +3846,26 @@ static char *set_bool_option(const int opt_idx, char_u *const varp,
} else if ((int *)varp == &curwin->w_p_cul && !value && old_value) {
// 'cursorline'
reset_cursorline();
- // 'undofile'
+ // 'undofile'
} else if ((int *)varp == &curbuf->b_p_udf || (int *)varp == &p_udf) {
// Only take action when the option was set. When reset we do not
// delete the undo file, the option may be set again without making
// any changes in between.
if (curbuf->b_p_udf || p_udf) {
char_u hash[UNDO_HASH_SIZE];
- buf_T *save_curbuf = curbuf;
FOR_ALL_BUFFERS(bp) {
- curbuf = bp;
// When 'undofile' is set globally: for every buffer, otherwise
// only for the current buffer: Try to read in the undofile,
// if one exists, the buffer wasn't changed and the buffer was
// loaded
- if ((curbuf == save_curbuf
+ if ((curbuf == bp
|| (opt_flags & OPT_GLOBAL) || opt_flags == 0)
- && !curbufIsChanged() && curbuf->b_ml.ml_mfp != NULL) {
- u_compute_hash(hash);
- u_read_undo(NULL, hash, curbuf->b_fname);
+ && !bufIsChanged(bp) && bp->b_ml.ml_mfp != NULL) {
+ u_compute_hash(bp, hash);
+ u_read_undo(NULL, hash, bp->b_fname);
}
}
- curbuf = save_curbuf;
}
} else if ((int *)varp == &curbuf->b_p_ro) {
// when 'readonly' is reset globally, also reset readonlymode
@@ -3897,7 +3910,7 @@ static char *set_bool_option(const int opt_idx, char_u *const varp,
}
} else if ((int *)varp == &p_terse) {
// when 'terse' is set change 'shortmess'
- char_u *p;
+ char_u *p;
p = vim_strchr(p_shm, SHM_SEARCH);
@@ -3934,8 +3947,8 @@ static char *set_bool_option(const int opt_idx, char_u *const varp,
// when 'hlsearch' is set or reset: reset no_hlsearch
set_no_hlsearch(false);
} else if ((int *)varp == &curwin->w_p_scb) {
- // when 'scrollbind' is set: snapshot the current position to avoid a jump
- // at the end of normal_cmd()
+ // when 'scrollbind' is set: snapshot the current position to avoid a jump
+ // at the end of normal_cmd()
if (curwin->w_p_scb) {
do_check_scrollbind(false);
curwin->w_scbind_pos = curwin->w_topline;
@@ -4005,7 +4018,7 @@ static char *set_bool_option(const int opt_idx, char_u *const varp,
}
} else if ((int *)varp == &curwin->w_p_spell) { // 'spell'
if (curwin->w_p_spell) {
- char_u *errmsg = did_set_spelllang(curwin);
+ char_u *errmsg = did_set_spelllang(curwin);
if (errmsg != NULL) {
EMSG(_(errmsg));
}
@@ -4034,8 +4047,7 @@ static char *set_bool_option(const int opt_idx, char_u *const varp,
/* Arabic requires a utf-8 encoding, inform the user if its not
* set. */
if (STRCMP(p_enc, "utf-8") != 0) {
- static char *w_arabic = N_(
- "W17: Arabic requires UTF-8, do ':set encoding=utf-8'");
+ static char *w_arabic = N_("W17: Arabic requires UTF-8, do ':set encoding=utf-8'");
msg_source(HL_ATTR(HLF_W));
msg_attr(_(w_arabic), HL_ATTR(HLF_W));
@@ -4095,7 +4107,7 @@ static char *set_bool_option(const int opt_idx, char_u *const varp,
set_vim_var_string(VV_OPTION_OLD, buf_old, -1);
set_vim_var_string(VV_OPTION_TYPE, buf_type, -1);
apply_autocmds(EVENT_OPTIONSET,
- (char_u *) options[opt_idx].fullname,
+ (char_u *)options[opt_idx].fullname,
NULL, false, NULL);
reset_v_option_vars();
}
@@ -4125,13 +4137,13 @@ static char *set_bool_option(const int opt_idx, char_u *const varp,
/// @param[in] opt_flags OPT_LOCAL, OPT_GLOBAL or OPT_MODELINE.
///
/// @return NULL on success, error message on error.
-static char *set_num_option(int opt_idx, char_u *varp, long value,
- char_u *errbuf, size_t errbuflen, int opt_flags)
+static char *set_num_option(int opt_idx, char_u *varp, long value, char_u *errbuf, size_t errbuflen,
+ int opt_flags)
{
- char_u *errmsg = NULL;
+ char_u *errmsg = NULL;
long old_value = *(long *)varp;
long old_Rows = Rows; // remember old Rows
- long *pp = (long *)varp;
+ long *pp = (long *)varp;
// Disallow changing some options from secure mode.
if ((secure || sandbox != 0)
@@ -4141,7 +4153,7 @@ static char *set_num_option(int opt_idx, char_u *varp, long value,
// Many number options assume their value is in the signed int range.
if (value < INT_MIN || value > INT_MAX) {
- return (char *)e_invarg;
+ return (char *)e_invarg;
}
// Options that need some validation.
@@ -4405,7 +4417,7 @@ static char *set_num_option(int opt_idx, char_u *varp, long value,
if (p_lines < min_rows() && full_screen) {
if (errbuf != NULL) {
vim_snprintf((char *)errbuf, errbuflen,
- _("E593: Need at least %d lines"), min_rows());
+ _("E593: Need at least %d lines"), min_rows());
errmsg = errbuf;
}
p_lines = min_rows();
@@ -4413,7 +4425,7 @@ static char *set_num_option(int opt_idx, char_u *varp, long value,
if (p_columns < MIN_COLUMNS && full_screen) {
if (errbuf != NULL) {
vim_snprintf((char *)errbuf, errbuflen,
- _("E594: Need at least %d columns"), MIN_COLUMNS);
+ _("E594: Need at least %d columns"), MIN_COLUMNS);
errmsg = errbuf;
}
p_columns = MIN_COLUMNS;
@@ -4458,7 +4470,7 @@ static char *set_num_option(int opt_idx, char_u *varp, long value,
}
win_comp_scroll(curwin);
} else if (curwin->w_p_scr <= 0) {
- // If 'scroll' became invalid because of a side effect silently adjust it.
+ // If 'scroll' became invalid because of a side effect silently adjust it.
curwin->w_p_scr = 1;
} else { // curwin->w_p_scr > curwin->w_height
curwin->w_p_scr = curwin->w_height;
@@ -4494,7 +4506,7 @@ static char *set_num_option(int opt_idx, char_u *varp, long value,
set_vim_var_string(VV_OPTION_OLD, buf_old, -1);
set_vim_var_string(VV_OPTION_TYPE, buf_type, -1);
apply_autocmds(EVENT_OPTIONSET,
- (char_u *) options[opt_idx].fullname,
+ (char_u *)options[opt_idx].fullname,
NULL, false, NULL);
reset_v_option_vars();
}
@@ -4514,8 +4526,7 @@ static char *set_num_option(int opt_idx, char_u *varp, long value,
return (char *)errmsg;
}
-static void trigger_optionsset_string(int opt_idx, int opt_flags,
- char *oldval, char *newval)
+static void trigger_optionsset_string(int opt_idx, int opt_flags, char *oldval, char *newval)
{
// Don't do this recursively.
if (oldval != NULL
@@ -4638,8 +4649,8 @@ 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");
+ || strequal(name, "term")
+ || strequal(name, "ttytype");
}
#define TCO_BUFFER_SIZE 8
@@ -4718,18 +4729,15 @@ static int findoption(const char *const arg)
/// Gets the value for an option.
///
+/// @param stringval NULL when only checking existence
+///
/// @returns:
/// Number or Toggle option: 1, *numval gets value.
/// String option: 0, *stringval gets allocated string.
/// Hidden Number or Toggle option: -1.
/// hidden String option: -2.
/// unknown option: -3.
-int get_option_value(
- const char *name,
- long *numval,
- char_u **stringval, ///< NULL when only checking existence
- int opt_flags
-)
+int get_option_value(const char *name, long *numval, char_u **stringval, int opt_flags)
{
if (get_tty_option(name, (char **)stringval)) {
return 0;
@@ -4763,7 +4771,7 @@ int get_option_value(
if ((int *)varp == &curbuf->b_changed) {
*numval = curbufIsChanged();
} else {
- *numval = (long) *(int *)varp; // NOLINT(whitespace/cast)
+ *numval = (long)*(int *)varp; // NOLINT(whitespace/cast)
}
}
return 1;
@@ -4785,11 +4793,7 @@ int get_option_value(
// see SOPT_* in option_defs.h for other flags
//
// Possible opt_type values: see SREQ_* in option_defs.h
-int get_option_value_strict(char *name,
- int64_t *numval,
- char **stringval,
- int opt_type,
- void *from)
+int get_option_value_strict(char *name, int64_t *numval, char **stringval, int opt_type, void *from)
{
if (get_tty_option(name, stringval)) {
return SOPT_STRING | SOPT_GLOBAL;
@@ -4905,8 +4909,8 @@ int get_option_value_strict(char *name,
/// @param[in] opt_flags Flags: OPT_LOCAL, OPT_GLOBAL, or 0 (both).
///
/// @return NULL on success, error message on error.
-char *set_option_value(const char *const name, const long number,
- const char *const string, const int opt_flags)
+char *set_option_value(const char *const name, const long number, const char *const string,
+ const int opt_flags)
FUNC_ATTR_NONNULL_ARG(1)
{
if (is_tty_option(name)) {
@@ -4914,7 +4918,7 @@ char *set_option_value(const char *const name, const long number,
}
int opt_idx;
- char_u *varp;
+ char_u *varp;
opt_idx = findoption(name);
if (opt_idx < 0) {
@@ -4974,7 +4978,7 @@ int find_key_option_len(const char_u *arg_arg, size_t len, bool has_lt)
// add_termcap_entry().
if (len >= 4 && arg[0] == 't' && arg[1] == '_') {
key = TERMCAP2KEY(arg[2], arg[3]);
- } else if (has_lt) {
+ } else if (has_lt) {
arg--; // put arg at the '<'
modifiers = 0;
key = find_special_key(&arg, len + 1, &modifiers, true, true, false);
@@ -4992,15 +4996,13 @@ static int find_key_option(const char_u *arg, bool has_lt)
/// if 'all' == 0: show changed options
/// if 'all' == 1: show all normal options
-static void
-showoptions(
- int all,
- int opt_flags // OPT_LOCAL and/or OPT_GLOBAL
-)
+///
+/// @param opt_flags OPT_LOCAL and/or OPT_GLOBAL
+static void showoptions(int all, int opt_flags)
{
- vimoption_T *p;
+ vimoption_T *p;
int col;
- char_u *varp;
+ char_u *varp;
int item_count;
int run;
int row, rows;
@@ -5094,20 +5096,17 @@ showoptions(
/// Return true if option "p" has its default value.
static int optval_default(vimoption_T *p, char_u *varp)
{
- int dvi;
-
if (varp == NULL) {
return true; // hidden option is always at default
}
- dvi = (p->flags & P_VI_DEF) ? VI_DEFAULT : VIM_DEFAULT;
if (p->flags & P_NUM) {
- return *(long *)varp == (long)(intptr_t)p->def_val[dvi];
+ return *(long *)varp == (long)(intptr_t)p->def_val;
}
if (p->flags & P_BOOL) {
- return *(int *)varp == (int)(intptr_t)p->def_val[dvi];
+ return *(int *)varp == (int)(intptr_t)p->def_val;
}
// P_STRING
- return STRCMP(*(char_u **)varp, p->def_val[dvi]) == 0;
+ return STRCMP(*(char_u **)varp, p->def_val) == 0;
}
/// Send update to UIs with values of UI relevant options
@@ -5138,13 +5137,11 @@ void ui_refresh_options(void)
/// showoneopt: show the value of one option
/// must not be called with a hidden option!
-static void
-showoneopt(
- vimoption_T *p,
- int opt_flags // OPT_LOCAL or OPT_GLOBAL
-)
+///
+/// @param opt_flags OPT_LOCAL or OPT_GLOBAL
+static void showoneopt(vimoption_T *p, int opt_flags)
{
- char_u *varp;
+ char_u *varp;
int save_silent = silent_mode;
silent_mode = false;
@@ -5195,11 +5192,11 @@ showoneopt(
/// Return FAIL on error, OK otherwise.
int makeset(FILE *fd, int opt_flags, int local_only)
{
- vimoption_T *p;
- char_u *varp; // currently used value
- char_u *varp_fresh; // local value
- char_u *varp_local = NULL; // fresh value
- char *cmd;
+ vimoption_T *p;
+ char_u *varp; // currently used value
+ char_u *varp_fresh; // local value
+ char_u *varp_local = NULL; // fresh value
+ char *cmd;
int round;
int pri;
@@ -5323,21 +5320,20 @@ int makefoldset(FILE *fd)
|| put_setnum(fd, "setlocal", "fdl", &curwin->w_p_fdl) == FAIL
|| put_setnum(fd, "setlocal", "fml", &curwin->w_p_fml) == FAIL
|| put_setnum(fd, "setlocal", "fdn", &curwin->w_p_fdn) == FAIL
- || put_setbool(fd, "setlocal", "fen", curwin->w_p_fen) == FAIL
- ) {
+ || put_setbool(fd, "setlocal", "fen",
+ curwin->w_p_fen) == FAIL) {
return FAIL;
}
return OK;
}
-static int put_setstring(FILE *fd, char *cmd, char *name,
- char_u **valuep, uint64_t flags)
+static int put_setstring(FILE *fd, char *cmd, char *name, char_u **valuep, uint64_t flags)
{
- char_u *s;
- char_u *buf = NULL;
- char_u *part = NULL;
- char_u *p;
+ char_u *s;
+ char_u *buf = NULL;
+ char_u *part = NULL;
+ char_u *p;
if (fprintf(fd, "%s %s=", cmd, name) < 0) {
return FAIL;
@@ -5363,7 +5359,7 @@ static int put_setstring(FILE *fd, char *cmd, char *name,
home_replace(NULL, *valuep, buf, size, false);
// If the option value is longer than MAXPATHL, we need to append
- // earch comma separated part of the option sperately, so that it
+ // search comma separated part of the option separately, so that it
// can be expanded when read back.
if (size >= MAXPATHL && (flags & P_COMMA) != 0
&& vim_strchr(*valuep, ',') != NULL) {
@@ -5375,15 +5371,15 @@ static int put_setstring(FILE *fd, char *cmd, char *name,
}
p = buf;
while (*p != NUL) {
- // for each comma separated option part, append value to
- // the option, :set rtp+=value
- if (fprintf(fd, "%s %s+=", cmd, name) < 0) {
- goto fail;
- }
- (void)copy_option_part(&p, part, size, ",");
- if (put_escstr(fd, part, 2) == FAIL || put_eol(fd) == FAIL) {
- goto fail;
- }
+ // for each comma separated option part, append value to
+ // the option, :set rtp+=value
+ if (fprintf(fd, "%s %s+=", cmd, name) < 0) {
+ goto fail;
+ }
+ (void)copy_option_part(&p, part, size, ",");
+ if (put_escstr(fd, part, 2) == FAIL || put_eol(fd) == FAIL) {
+ goto fail;
+ }
}
xfree(buf);
xfree(part);
@@ -5499,120 +5495,149 @@ void unset_global_local_option(char *name, void *from)
switch ((int)p->indir)
{
- // global option with local value: use local value if it's been set
+ // global option with local value: use local value if it's been set
+ case PV_EP:
+ clear_string_option(&buf->b_p_ep);
+ break;
+ case PV_KP:
+ clear_string_option(&buf->b_p_kp);
+ break;
+ case PV_PATH:
+ clear_string_option(&buf->b_p_path);
+ break;
+ case PV_AR:
+ buf->b_p_ar = -1;
+ break;
+ case PV_BKC:
+ clear_string_option(&buf->b_p_bkc);
+ buf->b_bkc_flags = 0;
+ break;
+ case PV_TAGS:
+ clear_string_option(&buf->b_p_tags);
+ break;
+ case PV_TC:
+ clear_string_option(&buf->b_p_tc);
+ buf->b_tc_flags = 0;
+ break;
+ case PV_SISO:
+ curwin->w_p_siso = -1;
+ break;
+ case PV_SO:
+ curwin->w_p_so = -1;
+ break;
+ case PV_DEF:
+ clear_string_option(&buf->b_p_def);
+ break;
+ case PV_INC:
+ clear_string_option(&buf->b_p_inc);
+ break;
+ case PV_DICT:
+ clear_string_option(&buf->b_p_dict);
+ break;
+ case PV_TSR:
+ clear_string_option(&buf->b_p_tsr);
+ break;
+ case PV_FP:
+ clear_string_option(&buf->b_p_fp);
+ break;
+ case PV_EFM:
+ clear_string_option(&buf->b_p_efm);
+ break;
+ case PV_GP:
+ clear_string_option(&buf->b_p_gp);
+ break;
+ case PV_MP:
+ clear_string_option(&buf->b_p_mp);
+ break;
+ case PV_SBR:
+ clear_string_option(&((win_T *)from)->w_p_sbr);
+ break;
+ case PV_STL:
+ clear_string_option(&((win_T *)from)->w_p_stl);
+ break;
+ case PV_UL:
+ buf->b_p_ul = NO_LOCAL_UNDOLEVEL;
+ break;
+ case PV_LW:
+ clear_string_option(&buf->b_p_lw);
+ break;
+ case PV_MENC:
+ clear_string_option(&buf->b_p_menc);
+ break;
+ case PV_LCS:
+ clear_string_option(&((win_T *)from)->w_p_lcs);
+ set_chars_option((win_T *)from, &((win_T *)from)->w_p_lcs, true);
+ redraw_later((win_T *)from, NOT_VALID);
+ break;
+ case PV_FCS:
+ clear_string_option(&((win_T *)from)->w_p_fcs);
+ set_chars_option((win_T *)from, &((win_T *)from)->w_p_fcs, true);
+ redraw_later((win_T *)from, NOT_VALID);
+ break;
+ }
+}
+
+/// Get pointer to option variable, depending on local or global scope.
+static char_u *get_varp_scope(vimoption_T *p, int opt_flags)
+{
+ if ((opt_flags & OPT_GLOBAL) && p->indir != PV_NONE) {
+ if (p->var == VAR_WIN) {
+ return (char_u *)GLOBAL_WO(get_varp(p));
+ }
+ return p->var;
+ }
+ if ((opt_flags & OPT_LOCAL) && ((int)p->indir & PV_BOTH)) {
+ switch ((int)p->indir) {
+ case PV_FP:
+ return (char_u *)&(curbuf->b_p_fp);
+ case PV_EFM:
+ return (char_u *)&(curbuf->b_p_efm);
+ case PV_GP:
+ return (char_u *)&(curbuf->b_p_gp);
+ case PV_MP:
+ return (char_u *)&(curbuf->b_p_mp);
case PV_EP:
- clear_string_option(&buf->b_p_ep);
- break;
+ return (char_u *)&(curbuf->b_p_ep);
case PV_KP:
- clear_string_option(&buf->b_p_kp);
- break;
+ return (char_u *)&(curbuf->b_p_kp);
case PV_PATH:
- clear_string_option(&buf->b_p_path);
- break;
+ return (char_u *)&(curbuf->b_p_path);
case PV_AR:
- buf->b_p_ar = -1;
- break;
- case PV_BKC:
- clear_string_option(&buf->b_p_bkc);
- buf->b_bkc_flags = 0;
- break;
+ return (char_u *)&(curbuf->b_p_ar);
case PV_TAGS:
- clear_string_option(&buf->b_p_tags);
- break;
+ return (char_u *)&(curbuf->b_p_tags);
case PV_TC:
- clear_string_option(&buf->b_p_tc);
- buf->b_tc_flags = 0;
- break;
+ return (char_u *)&(curbuf->b_p_tc);
case PV_SISO:
- curwin->w_p_siso = -1;
- break;
+ return (char_u *)&(curwin->w_p_siso);
case PV_SO:
- curwin->w_p_so = -1;
- break;
+ return (char_u *)&(curwin->w_p_so);
case PV_DEF:
- clear_string_option(&buf->b_p_def);
- break;
+ return (char_u *)&(curbuf->b_p_def);
case PV_INC:
- clear_string_option(&buf->b_p_inc);
- break;
+ return (char_u *)&(curbuf->b_p_inc);
case PV_DICT:
- clear_string_option(&buf->b_p_dict);
- break;
+ return (char_u *)&(curbuf->b_p_dict);
case PV_TSR:
- clear_string_option(&buf->b_p_tsr);
- break;
- case PV_FP:
- clear_string_option(&buf->b_p_fp);
- break;
- case PV_EFM:
- clear_string_option(&buf->b_p_efm);
- break;
- case PV_GP:
- clear_string_option(&buf->b_p_gp);
- break;
- case PV_MP:
- clear_string_option(&buf->b_p_mp);
- break;
+ return (char_u *)&(curbuf->b_p_tsr);
+ case PV_TFU:
+ return (char_u *)&(curbuf->b_p_tfu);
+ case PV_SBR:
+ return (char_u *)&(curwin->w_p_sbr);
case PV_STL:
- clear_string_option(&((win_T *)from)->w_p_stl);
- break;
+ return (char_u *)&(curwin->w_p_stl);
case PV_UL:
- buf->b_p_ul = NO_LOCAL_UNDOLEVEL;
- break;
+ return (char_u *)&(curbuf->b_p_ul);
case PV_LW:
- clear_string_option(&buf->b_p_lw);
- break;
+ return (char_u *)&(curbuf->b_p_lw);
+ case PV_BKC:
+ return (char_u *)&(curbuf->b_p_bkc);
case PV_MENC:
- clear_string_option(&buf->b_p_menc);
- break;
- case PV_LCS:
- clear_string_option(&((win_T *)from)->w_p_lcs);
- set_chars_option((win_T *)from, &((win_T *)from)->w_p_lcs, true);
- redraw_later((win_T *)from, NOT_VALID);
- break;
+ return (char_u *)&(curbuf->b_p_menc);
case PV_FCS:
- clear_string_option(&((win_T *)from)->w_p_fcs);
- set_chars_option((win_T *)from, &((win_T *)from)->w_p_fcs, true);
- redraw_later((win_T *)from, NOT_VALID);
- break;
- }
-}
-
-/// Get pointer to option variable, depending on local or global scope.
-static char_u *get_varp_scope(vimoption_T *p, int opt_flags)
-{
- if ((opt_flags & OPT_GLOBAL) && p->indir != PV_NONE) {
- if (p->var == VAR_WIN) {
- return (char_u *)GLOBAL_WO(get_varp(p));
- }
- return p->var;
- }
- if ((opt_flags & OPT_LOCAL) && ((int)p->indir & PV_BOTH)) {
- switch ((int)p->indir) {
- case PV_FP: return (char_u *)&(curbuf->b_p_fp);
- case PV_EFM: return (char_u *)&(curbuf->b_p_efm);
- case PV_GP: return (char_u *)&(curbuf->b_p_gp);
- case PV_MP: return (char_u *)&(curbuf->b_p_mp);
- case PV_EP: return (char_u *)&(curbuf->b_p_ep);
- case PV_KP: return (char_u *)&(curbuf->b_p_kp);
- case PV_PATH: return (char_u *)&(curbuf->b_p_path);
- case PV_AR: return (char_u *)&(curbuf->b_p_ar);
- case PV_TAGS: return (char_u *)&(curbuf->b_p_tags);
- case PV_TC: return (char_u *)&(curbuf->b_p_tc);
- case PV_SISO: return (char_u *)&(curwin->w_p_siso);
- case PV_SO: return (char_u *)&(curwin->w_p_so);
- case PV_DEF: return (char_u *)&(curbuf->b_p_def);
- case PV_INC: return (char_u *)&(curbuf->b_p_inc);
- case PV_DICT: return (char_u *)&(curbuf->b_p_dict);
- case PV_TSR: return (char_u *)&(curbuf->b_p_tsr);
- case PV_TFU: return (char_u *)&(curbuf->b_p_tfu);
- case PV_STL: return (char_u *)&(curwin->w_p_stl);
- case PV_UL: return (char_u *)&(curbuf->b_p_ul);
- case PV_LW: return (char_u *)&(curbuf->b_p_lw);
- case PV_BKC: return (char_u *)&(curbuf->b_p_bkc);
- case PV_MENC: return (char_u *)&(curbuf->b_p_menc);
- case PV_FCS: return (char_u *)&(curwin->w_p_fcs);
- case PV_LCS: return (char_u *)&(curwin->w_p_lcs);
+ return (char_u *)&(curwin->w_p_fcs);
+ case PV_LCS:
+ return (char_u *)&(curwin->w_p_lcs);
}
return NULL; // "cannot happen"
}
@@ -5628,160 +5653,290 @@ static char_u *get_varp(vimoption_T *p)
}
switch ((int)p->indir) {
- case PV_NONE: return p->var;
+ case PV_NONE:
+ return p->var;
// global option with local value: use local value if it's been set
- case PV_EP: return *curbuf->b_p_ep != NUL
+ case PV_EP:
+ return *curbuf->b_p_ep != NUL
? (char_u *)&curbuf->b_p_ep : p->var;
- case PV_KP: return *curbuf->b_p_kp != NUL
+ case PV_KP:
+ return *curbuf->b_p_kp != NUL
? (char_u *)&curbuf->b_p_kp : p->var;
- case PV_PATH: return *curbuf->b_p_path != NUL
+ case PV_PATH:
+ return *curbuf->b_p_path != NUL
? (char_u *)&(curbuf->b_p_path) : p->var;
- case PV_AR: return curbuf->b_p_ar >= 0
+ case PV_AR:
+ return curbuf->b_p_ar >= 0
? (char_u *)&(curbuf->b_p_ar) : p->var;
- case PV_TAGS: return *curbuf->b_p_tags != NUL
+ case PV_TAGS:
+ return *curbuf->b_p_tags != NUL
? (char_u *)&(curbuf->b_p_tags) : p->var;
- case PV_TC: return *curbuf->b_p_tc != NUL
+ case PV_TC:
+ return *curbuf->b_p_tc != NUL
? (char_u *)&(curbuf->b_p_tc) : p->var;
- case PV_SISO: return curwin->w_p_siso >= 0
+ case PV_SISO:
+ return curwin->w_p_siso >= 0
? (char_u *)&(curwin->w_p_siso) : p->var;
- case PV_SO: return curwin->w_p_so >= 0
+ case PV_SO:
+ return curwin->w_p_so >= 0
? (char_u *)&(curwin->w_p_so) : p->var;
- case PV_BKC: return *curbuf->b_p_bkc != NUL
+ case PV_BKC:
+ return *curbuf->b_p_bkc != NUL
? (char_u *)&(curbuf->b_p_bkc) : p->var;
- case PV_DEF: return *curbuf->b_p_def != NUL
+ case PV_DEF:
+ return *curbuf->b_p_def != NUL
? (char_u *)&(curbuf->b_p_def) : p->var;
- case PV_INC: return *curbuf->b_p_inc != NUL
+ case PV_INC:
+ return *curbuf->b_p_inc != NUL
? (char_u *)&(curbuf->b_p_inc) : p->var;
- case PV_DICT: return *curbuf->b_p_dict != NUL
+ case PV_DICT:
+ return *curbuf->b_p_dict != NUL
? (char_u *)&(curbuf->b_p_dict) : p->var;
- case PV_TSR: return *curbuf->b_p_tsr != NUL
+ case PV_TSR:
+ return *curbuf->b_p_tsr != NUL
? (char_u *)&(curbuf->b_p_tsr) : p->var;
- case PV_FP: return *curbuf->b_p_fp != NUL
+ case PV_FP:
+ return *curbuf->b_p_fp != NUL
? (char_u *)&(curbuf->b_p_fp) : p->var;
- case PV_EFM: return *curbuf->b_p_efm != NUL
+ case PV_EFM:
+ return *curbuf->b_p_efm != NUL
? (char_u *)&(curbuf->b_p_efm) : p->var;
- case PV_GP: return *curbuf->b_p_gp != NUL
+ case PV_GP:
+ return *curbuf->b_p_gp != NUL
? (char_u *)&(curbuf->b_p_gp) : p->var;
- case PV_MP: return *curbuf->b_p_mp != NUL
+ case PV_MP:
+ return *curbuf->b_p_mp != NUL
? (char_u *)&(curbuf->b_p_mp) : p->var;
- case PV_STL: return *curwin->w_p_stl != NUL
+ case PV_SBR:
+ return *curwin->w_p_sbr != NUL
+ ? (char_u *)&(curwin->w_p_sbr) : p->var;
+ case PV_STL:
+ return *curwin->w_p_stl != NUL
? (char_u *)&(curwin->w_p_stl) : p->var;
- case PV_UL: return curbuf->b_p_ul != NO_LOCAL_UNDOLEVEL
+ case PV_UL:
+ return curbuf->b_p_ul != NO_LOCAL_UNDOLEVEL
? (char_u *)&(curbuf->b_p_ul) : p->var;
- case PV_LW: return *curbuf->b_p_lw != NUL
+ case PV_LW:
+ return *curbuf->b_p_lw != NUL
? (char_u *)&(curbuf->b_p_lw) : p->var;
- case PV_MENC: return *curbuf->b_p_menc != NUL
+ case PV_MENC:
+ return *curbuf->b_p_menc != NUL
? (char_u *)&(curbuf->b_p_menc) : p->var;
- case PV_FCS: return *curwin->w_p_fcs != NUL
+ case PV_FCS:
+ return *curwin->w_p_fcs != NUL
? (char_u *)&(curwin->w_p_fcs) : p->var;
- case PV_LCS: return *curwin->w_p_lcs != NUL
+ case PV_LCS:
+ return *curwin->w_p_lcs != NUL
? (char_u *)&(curwin->w_p_lcs) : p->var;
- case PV_ARAB: return (char_u *)&(curwin->w_p_arab);
- case PV_LIST: return (char_u *)&(curwin->w_p_list);
- case PV_SPELL: return (char_u *)&(curwin->w_p_spell);
- case PV_CUC: return (char_u *)&(curwin->w_p_cuc);
- case PV_CUL: return (char_u *)&(curwin->w_p_cul);
- case PV_CC: return (char_u *)&(curwin->w_p_cc);
- case PV_DIFF: return (char_u *)&(curwin->w_p_diff);
- case PV_FDC: return (char_u *)&(curwin->w_p_fdc);
- case PV_FEN: return (char_u *)&(curwin->w_p_fen);
- case PV_FDI: return (char_u *)&(curwin->w_p_fdi);
- case PV_FDL: return (char_u *)&(curwin->w_p_fdl);
- case PV_FDM: return (char_u *)&(curwin->w_p_fdm);
- case PV_FML: return (char_u *)&(curwin->w_p_fml);
- case PV_FDN: return (char_u *)&(curwin->w_p_fdn);
- case PV_FDE: return (char_u *)&(curwin->w_p_fde);
- case PV_FDT: return (char_u *)&(curwin->w_p_fdt);
- case PV_FMR: return (char_u *)&(curwin->w_p_fmr);
- case PV_NU: return (char_u *)&(curwin->w_p_nu);
- case PV_RNU: return (char_u *)&(curwin->w_p_rnu);
- case PV_NUW: return (char_u *)&(curwin->w_p_nuw);
- case PV_WFH: return (char_u *)&(curwin->w_p_wfh);
- case PV_WFW: return (char_u *)&(curwin->w_p_wfw);
- case PV_PVW: return (char_u *)&(curwin->w_p_pvw);
- case PV_RL: return (char_u *)&(curwin->w_p_rl);
- case PV_RLC: return (char_u *)&(curwin->w_p_rlc);
- case PV_SCROLL: return (char_u *)&(curwin->w_p_scr);
- case PV_WRAP: return (char_u *)&(curwin->w_p_wrap);
- case PV_LBR: return (char_u *)&(curwin->w_p_lbr);
- case PV_BRI: return (char_u *)&(curwin->w_p_bri);
- case PV_BRIOPT: return (char_u *)&(curwin->w_p_briopt);
- case PV_SCBIND: return (char_u *)&(curwin->w_p_scb);
- case PV_CRBIND: return (char_u *)&(curwin->w_p_crb);
- case PV_COCU: return (char_u *)&(curwin->w_p_cocu);
- case PV_COLE: return (char_u *)&(curwin->w_p_cole);
-
- case PV_AI: return (char_u *)&(curbuf->b_p_ai);
- case PV_BIN: return (char_u *)&(curbuf->b_p_bin);
- case PV_BOMB: return (char_u *)&(curbuf->b_p_bomb);
- case PV_BH: return (char_u *)&(curbuf->b_p_bh);
- case PV_BT: return (char_u *)&(curbuf->b_p_bt);
- case PV_BL: return (char_u *)&(curbuf->b_p_bl);
- case PV_CHANNEL:return (char_u *)&(curbuf->b_p_channel);
- case PV_CI: return (char_u *)&(curbuf->b_p_ci);
- case PV_CIN: return (char_u *)&(curbuf->b_p_cin);
- case PV_CINK: return (char_u *)&(curbuf->b_p_cink);
- case PV_CINO: return (char_u *)&(curbuf->b_p_cino);
- case PV_CINW: return (char_u *)&(curbuf->b_p_cinw);
- case PV_COM: return (char_u *)&(curbuf->b_p_com);
- case PV_CMS: return (char_u *)&(curbuf->b_p_cms);
- case PV_CPT: return (char_u *)&(curbuf->b_p_cpt);
-# ifdef BACKSLASH_IN_FILENAME
- case PV_CSL: return (char_u *)&(curbuf->b_p_csl);
-# endif
- case PV_CFU: return (char_u *)&(curbuf->b_p_cfu);
- case PV_OFU: return (char_u *)&(curbuf->b_p_ofu);
- case PV_EOL: return (char_u *)&(curbuf->b_p_eol);
- case PV_FIXEOL: return (char_u *)&(curbuf->b_p_fixeol);
- case PV_ET: return (char_u *)&(curbuf->b_p_et);
- case PV_FENC: return (char_u *)&(curbuf->b_p_fenc);
- case PV_FF: return (char_u *)&(curbuf->b_p_ff);
- case PV_FT: return (char_u *)&(curbuf->b_p_ft);
- case PV_FO: return (char_u *)&(curbuf->b_p_fo);
- case PV_FLP: return (char_u *)&(curbuf->b_p_flp);
- case PV_IMI: return (char_u *)&(curbuf->b_p_iminsert);
- case PV_IMS: return (char_u *)&(curbuf->b_p_imsearch);
- case PV_INF: return (char_u *)&(curbuf->b_p_inf);
- case PV_ISK: return (char_u *)&(curbuf->b_p_isk);
- case PV_INEX: return (char_u *)&(curbuf->b_p_inex);
- case PV_INDE: return (char_u *)&(curbuf->b_p_inde);
- case PV_INDK: return (char_u *)&(curbuf->b_p_indk);
- case PV_FEX: return (char_u *)&(curbuf->b_p_fex);
- case PV_LISP: return (char_u *)&(curbuf->b_p_lisp);
- case PV_ML: return (char_u *)&(curbuf->b_p_ml);
- case PV_MPS: return (char_u *)&(curbuf->b_p_mps);
- case PV_MA: return (char_u *)&(curbuf->b_p_ma);
- case PV_MOD: return (char_u *)&(curbuf->b_changed);
- case PV_NF: return (char_u *)&(curbuf->b_p_nf);
- case PV_PI: return (char_u *)&(curbuf->b_p_pi);
- case PV_QE: return (char_u *)&(curbuf->b_p_qe);
- case PV_RO: return (char_u *)&(curbuf->b_p_ro);
- case PV_SCBK: return (char_u *)&(curbuf->b_p_scbk);
- case PV_SI: return (char_u *)&(curbuf->b_p_si);
- case PV_STS: return (char_u *)&(curbuf->b_p_sts);
- case PV_SUA: return (char_u *)&(curbuf->b_p_sua);
- case PV_SWF: return (char_u *)&(curbuf->b_p_swf);
- case PV_SMC: return (char_u *)&(curbuf->b_p_smc);
- case PV_SYN: return (char_u *)&(curbuf->b_p_syn);
- case PV_SPC: return (char_u *)&(curwin->w_s->b_p_spc);
- case PV_SPF: return (char_u *)&(curwin->w_s->b_p_spf);
- case PV_SPL: return (char_u *)&(curwin->w_s->b_p_spl);
- case PV_SPO: return (char_u *)&(curwin->w_s->b_p_spo);
- case PV_SW: return (char_u *)&(curbuf->b_p_sw);
- case PV_TFU: return (char_u *)&(curbuf->b_p_tfu);
- case PV_TS: return (char_u *)&(curbuf->b_p_ts);
- case PV_TW: return (char_u *)&(curbuf->b_p_tw);
- case PV_UDF: return (char_u *)&(curbuf->b_p_udf);
- case PV_WM: return (char_u *)&(curbuf->b_p_wm);
- case PV_VSTS: return (char_u *)&(curbuf->b_p_vsts);
- case PV_VTS: return (char_u *)&(curbuf->b_p_vts);
- case PV_KMAP: return (char_u *)&(curbuf->b_p_keymap);
- case PV_SCL: return (char_u *)&(curwin->w_p_scl);
- case PV_WINHL: return (char_u *)&(curwin->w_p_winhl);
- case PV_WINBL: return (char_u *)&(curwin->w_p_winbl);
- default: IEMSG(_("E356: get_varp ERROR"));
+ case PV_ARAB:
+ return (char_u *)&(curwin->w_p_arab);
+ case PV_LIST:
+ return (char_u *)&(curwin->w_p_list);
+ case PV_SPELL:
+ return (char_u *)&(curwin->w_p_spell);
+ case PV_CUC:
+ return (char_u *)&(curwin->w_p_cuc);
+ case PV_CUL:
+ return (char_u *)&(curwin->w_p_cul);
+ case PV_CULOPT:
+ return (char_u *)&(curwin->w_p_culopt);
+ case PV_CC:
+ return (char_u *)&(curwin->w_p_cc);
+ case PV_DIFF:
+ return (char_u *)&(curwin->w_p_diff);
+ case PV_FDC:
+ return (char_u *)&(curwin->w_p_fdc);
+ case PV_FEN:
+ return (char_u *)&(curwin->w_p_fen);
+ case PV_FDI:
+ return (char_u *)&(curwin->w_p_fdi);
+ case PV_FDL:
+ return (char_u *)&(curwin->w_p_fdl);
+ case PV_FDM:
+ return (char_u *)&(curwin->w_p_fdm);
+ case PV_FML:
+ return (char_u *)&(curwin->w_p_fml);
+ case PV_FDN:
+ return (char_u *)&(curwin->w_p_fdn);
+ case PV_FDE:
+ return (char_u *)&(curwin->w_p_fde);
+ case PV_FDT:
+ return (char_u *)&(curwin->w_p_fdt);
+ case PV_FMR:
+ return (char_u *)&(curwin->w_p_fmr);
+ case PV_NU:
+ return (char_u *)&(curwin->w_p_nu);
+ case PV_RNU:
+ return (char_u *)&(curwin->w_p_rnu);
+ case PV_NUW:
+ return (char_u *)&(curwin->w_p_nuw);
+ case PV_WFH:
+ return (char_u *)&(curwin->w_p_wfh);
+ case PV_WFW:
+ return (char_u *)&(curwin->w_p_wfw);
+ case PV_PVW:
+ return (char_u *)&(curwin->w_p_pvw);
+ case PV_RL:
+ return (char_u *)&(curwin->w_p_rl);
+ case PV_RLC:
+ return (char_u *)&(curwin->w_p_rlc);
+ case PV_SCROLL:
+ return (char_u *)&(curwin->w_p_scr);
+ case PV_WRAP:
+ return (char_u *)&(curwin->w_p_wrap);
+ case PV_LBR:
+ return (char_u *)&(curwin->w_p_lbr);
+ case PV_BRI:
+ return (char_u *)&(curwin->w_p_bri);
+ case PV_BRIOPT:
+ return (char_u *)&(curwin->w_p_briopt);
+ case PV_SCBIND:
+ return (char_u *)&(curwin->w_p_scb);
+ case PV_CRBIND:
+ return (char_u *)&(curwin->w_p_crb);
+ case PV_COCU:
+ return (char_u *)&(curwin->w_p_cocu);
+ case PV_COLE:
+ return (char_u *)&(curwin->w_p_cole);
+
+ case PV_AI:
+ return (char_u *)&(curbuf->b_p_ai);
+ case PV_BIN:
+ return (char_u *)&(curbuf->b_p_bin);
+ case PV_BOMB:
+ return (char_u *)&(curbuf->b_p_bomb);
+ case PV_BH:
+ return (char_u *)&(curbuf->b_p_bh);
+ case PV_BT:
+ return (char_u *)&(curbuf->b_p_bt);
+ case PV_BL:
+ return (char_u *)&(curbuf->b_p_bl);
+ case PV_CHANNEL:
+ return (char_u *)&(curbuf->b_p_channel);
+ case PV_CI:
+ return (char_u *)&(curbuf->b_p_ci);
+ case PV_CIN:
+ return (char_u *)&(curbuf->b_p_cin);
+ case PV_CINK:
+ return (char_u *)&(curbuf->b_p_cink);
+ case PV_CINO:
+ return (char_u *)&(curbuf->b_p_cino);
+ case PV_CINW:
+ return (char_u *)&(curbuf->b_p_cinw);
+ case PV_COM:
+ return (char_u *)&(curbuf->b_p_com);
+ case PV_CMS:
+ return (char_u *)&(curbuf->b_p_cms);
+ case PV_CPT:
+ return (char_u *)&(curbuf->b_p_cpt);
+#ifdef BACKSLASH_IN_FILENAME
+ case PV_CSL:
+ return (char_u *)&(curbuf->b_p_csl);
+#endif
+ case PV_CFU:
+ return (char_u *)&(curbuf->b_p_cfu);
+ case PV_OFU:
+ return (char_u *)&(curbuf->b_p_ofu);
+ case PV_EOL:
+ return (char_u *)&(curbuf->b_p_eol);
+ case PV_FIXEOL:
+ return (char_u *)&(curbuf->b_p_fixeol);
+ case PV_ET:
+ return (char_u *)&(curbuf->b_p_et);
+ case PV_FENC:
+ return (char_u *)&(curbuf->b_p_fenc);
+ case PV_FF:
+ return (char_u *)&(curbuf->b_p_ff);
+ case PV_FT:
+ return (char_u *)&(curbuf->b_p_ft);
+ case PV_FO:
+ return (char_u *)&(curbuf->b_p_fo);
+ case PV_FLP:
+ return (char_u *)&(curbuf->b_p_flp);
+ case PV_IMI:
+ return (char_u *)&(curbuf->b_p_iminsert);
+ case PV_IMS:
+ return (char_u *)&(curbuf->b_p_imsearch);
+ case PV_INF:
+ return (char_u *)&(curbuf->b_p_inf);
+ case PV_ISK:
+ return (char_u *)&(curbuf->b_p_isk);
+ case PV_INEX:
+ return (char_u *)&(curbuf->b_p_inex);
+ case PV_INDE:
+ return (char_u *)&(curbuf->b_p_inde);
+ case PV_INDK:
+ return (char_u *)&(curbuf->b_p_indk);
+ case PV_FEX:
+ return (char_u *)&(curbuf->b_p_fex);
+ case PV_LISP:
+ return (char_u *)&(curbuf->b_p_lisp);
+ case PV_ML:
+ return (char_u *)&(curbuf->b_p_ml);
+ case PV_MPS:
+ return (char_u *)&(curbuf->b_p_mps);
+ case PV_MA:
+ return (char_u *)&(curbuf->b_p_ma);
+ case PV_MOD:
+ return (char_u *)&(curbuf->b_changed);
+ case PV_NF:
+ return (char_u *)&(curbuf->b_p_nf);
+ case PV_PI:
+ return (char_u *)&(curbuf->b_p_pi);
+ case PV_QE:
+ return (char_u *)&(curbuf->b_p_qe);
+ case PV_RO:
+ return (char_u *)&(curbuf->b_p_ro);
+ case PV_SCBK:
+ return (char_u *)&(curbuf->b_p_scbk);
+ case PV_SI:
+ return (char_u *)&(curbuf->b_p_si);
+ case PV_STS:
+ return (char_u *)&(curbuf->b_p_sts);
+ case PV_SUA:
+ return (char_u *)&(curbuf->b_p_sua);
+ case PV_SWF:
+ return (char_u *)&(curbuf->b_p_swf);
+ case PV_SMC:
+ return (char_u *)&(curbuf->b_p_smc);
+ case PV_SYN:
+ return (char_u *)&(curbuf->b_p_syn);
+ case PV_SPC:
+ return (char_u *)&(curwin->w_s->b_p_spc);
+ case PV_SPF:
+ return (char_u *)&(curwin->w_s->b_p_spf);
+ case PV_SPL:
+ return (char_u *)&(curwin->w_s->b_p_spl);
+ case PV_SPO:
+ return (char_u *)&(curwin->w_s->b_p_spo);
+ case PV_SW:
+ return (char_u *)&(curbuf->b_p_sw);
+ case PV_TFU:
+ return (char_u *)&(curbuf->b_p_tfu);
+ case PV_TS:
+ return (char_u *)&(curbuf->b_p_ts);
+ case PV_TW:
+ return (char_u *)&(curbuf->b_p_tw);
+ case PV_UDF:
+ return (char_u *)&(curbuf->b_p_udf);
+ case PV_WM:
+ return (char_u *)&(curbuf->b_p_wm);
+ case PV_VSTS:
+ return (char_u *)&(curbuf->b_p_vsts);
+ case PV_VTS:
+ return (char_u *)&(curbuf->b_p_vts);
+ case PV_KMAP:
+ return (char_u *)&(curbuf->b_p_keymap);
+ case PV_SCL:
+ return (char_u *)&(curwin->w_p_scl);
+ case PV_WINHL:
+ return (char_u *)&(curwin->w_p_winhl);
+ case PV_WINBL:
+ return (char_u *)&(curwin->w_p_winbl);
+ default:
+ IEMSG(_("E356: get_varp ERROR"));
}
// always return a valid pointer to avoid a crash!
return (char_u *)&(curbuf->b_p_wm);
@@ -5817,6 +5972,7 @@ void copy_winopt(winopt_T *from, winopt_T *to)
to->wo_nuw = from->wo_nuw;
to->wo_rl = from->wo_rl;
to->wo_rlc = vim_strsave(from->wo_rlc);
+ to->wo_sbr = vim_strsave(from->wo_sbr);
to->wo_stl = vim_strsave(from->wo_stl);
to->wo_wrap = from->wo_wrap;
to->wo_wrap_save = from->wo_wrap_save;
@@ -5830,6 +5986,7 @@ void copy_winopt(winopt_T *from, winopt_T *to)
to->wo_spell = from->wo_spell;
to->wo_cuc = from->wo_cuc;
to->wo_cul = from->wo_cul;
+ to->wo_culopt = vim_strsave(from->wo_culopt);
to->wo_cc = vim_strsave(from->wo_cc);
to->wo_diff = from->wo_diff;
to->wo_diff_saved = from->wo_diff_saved;
@@ -5879,7 +6036,9 @@ static void check_winopt(winopt_T *wop)
check_string_option(&wop->wo_fmr);
check_string_option(&wop->wo_scl);
check_string_option(&wop->wo_rlc);
+ check_string_option(&wop->wo_sbr);
check_string_option(&wop->wo_stl);
+ check_string_option(&wop->wo_culopt);
check_string_option(&wop->wo_cc);
check_string_option(&wop->wo_cocu);
check_string_option(&wop->wo_briopt);
@@ -5901,7 +6060,9 @@ void clear_winopt(winopt_T *wop)
clear_string_option(&wop->wo_fmr);
clear_string_option(&wop->wo_scl);
clear_string_option(&wop->wo_rlc);
+ clear_string_option(&wop->wo_sbr);
clear_string_option(&wop->wo_stl);
+ clear_string_option(&wop->wo_culopt);
clear_string_option(&wop->wo_cc);
clear_string_option(&wop->wo_cocu);
clear_string_option(&wop->wo_briopt);
@@ -5914,6 +6075,7 @@ void didset_window_options(win_T *wp)
{
check_colorcolumn(wp);
briopt_check(wp);
+ fill_culopt_flags(NULL, wp);
set_chars_option(wp, &wp->w_p_fcs, true);
set_chars_option(wp, &wp->w_p_lcs, true);
parse_winhl_opt(wp); // sets w_hl_needs_update also for w_p_winbl
@@ -5932,7 +6094,7 @@ void didset_window_options(win_T *wp)
void buf_copy_options(buf_T *buf, int flags)
{
int should_copy = true;
- char_u *save_p_isk = NULL; // init for GCC
+ char_u *save_p_isk = NULL; // init for GCC
int dont_do_help;
int did_isk = false;
@@ -5977,22 +6139,18 @@ void buf_copy_options(buf_T *buf, int flags)
buf->b_p_ro = false; // don't copy readonly
buf->b_p_fenc = vim_strsave(p_fenc);
switch (*p_ffs) {
- case 'm': {
- buf->b_p_ff = vim_strsave((char_u *)FF_MAC);
- break;
- }
- case 'd': {
- buf->b_p_ff = vim_strsave((char_u *)FF_DOS);
- break;
- }
- case 'u': {
- buf->b_p_ff = vim_strsave((char_u *)FF_UNIX);
- break;
- }
- default: {
- buf->b_p_ff = vim_strsave(p_ff);
- break;
- }
+ case 'm':
+ buf->b_p_ff = vim_strsave((char_u *)FF_MAC);
+ break;
+ case 'd':
+ buf->b_p_ff = vim_strsave((char_u *)FF_DOS);
+ break;
+ case 'u':
+ buf->b_p_ff = vim_strsave((char_u *)FF_UNIX);
+ break;
+ default:
+ buf->b_p_ff = vim_strsave(p_ff);
+ break;
}
buf->b_p_bh = empty_option;
buf->b_p_bt = empty_option;
@@ -6021,9 +6179,9 @@ void buf_copy_options(buf_T *buf, int flags)
buf->b_p_inf = p_inf;
buf->b_p_swf = cmdmod.noswapfile ? false : p_swf;
buf->b_p_cpt = vim_strsave(p_cpt);
-# ifdef BACKSLASH_IN_FILENAME
+#ifdef BACKSLASH_IN_FILENAME
buf->b_p_csl = vim_strsave(p_csl);
-# endif
+#endif
buf->b_p_cfu = vim_strsave(p_cfu);
buf->b_p_ofu = vim_strsave(p_ofu);
buf->b_p_tfu = vim_strsave(p_tfu);
@@ -6156,7 +6314,7 @@ void reset_modifiable(void)
p_ma = false;
opt_idx = findoption("ma");
if (opt_idx >= 0) {
- options[opt_idx].def_val[VI_DEFAULT] = false;
+ options[opt_idx].def_val = false;
}
}
@@ -6173,21 +6331,17 @@ void set_imsearch_global(void)
}
static int expand_option_idx = -1;
-static char_u expand_option_name[5] = {'t', '_', NUL, NUL, NUL};
+static char_u expand_option_name[5] = { 't', '_', NUL, NUL, NUL };
static int expand_option_flags = 0;
-void
-set_context_in_set_cmd(
- expand_T *xp,
- char_u *arg,
- int opt_flags // OPT_GLOBAL and/or OPT_LOCAL
-)
+/// @param opt_flags OPT_GLOBAL and/or OPT_LOCAL
+void set_context_in_set_cmd(expand_T *xp, char_u *arg, int opt_flags)
{
char_u nextchar;
uint32_t flags = 0; // init for GCC
int opt_idx = 0; // init for GCC
- char_u *p;
- char_u *s;
+ char_u *p;
+ char_u *s;
int is_term_option = false;
int key;
@@ -6311,15 +6465,14 @@ set_context_in_set_cmd(
|| p == (char_u *)&p_pp
|| p == (char_u *)&p_rtp
|| p == (char_u *)&p_cdpath
- || p == (char_u *)&p_vdir
- ) {
+ || p == (char_u *)&p_vdir) {
xp->xp_context = EXPAND_DIRECTORIES;
if (p == (char_u *)&p_path
- || p == (char_u *)&p_cdpath
- )
+ || p == (char_u *)&p_cdpath) {
xp->xp_backslash = XP_BS_THREE;
- else
+ } else {
xp->xp_backslash = XP_BS_ONE;
+ }
} else if (p == (char_u *)&p_ft) {
xp->xp_context = EXPAND_FILETYPE;
} else {
@@ -6365,7 +6518,7 @@ int ExpandSettings(expand_T *xp, regmatch_T *regmatch, int *num_file, char_u ***
int num_normal = 0; // Nr of matching non-term-code settings
int match;
int count = 0;
- char_u *str;
+ char_u *str;
int loop;
static char *(names[]) = { "all" };
int ic = regmatch->rm_ic; // remember the ignore-case flag
@@ -6409,8 +6562,9 @@ int ExpandSettings(expand_T *xp, regmatch_T *regmatch, int *num_file, char_u ***
if (match) {
if (loop == 0) {
num_normal++;
- } else
+ } else {
(*file)[count++] = vim_strsave(str);
+ }
}
}
@@ -6472,13 +6626,11 @@ void ExpandOldSetting(int *num_file, char_u ***file)
/// Get the value for the numeric or string option///opp in a nice format into
/// NameBuff[]. Must not be called with a hidden option!
-static void
-option_value2string(
- vimoption_T *opp,
- int opt_flags // OPT_GLOBAL and/or OPT_LOCAL
-)
+///
+/// @param opt_flags OPT_GLOBAL and/or OPT_LOCAL
+static void option_value2string(vimoption_T *opp, int opt_flags)
{
- char_u *varp;
+ char_u *varp;
varp = get_varp_scope(opp, opt_flags);
@@ -6501,7 +6653,7 @@ option_value2string(
NameBuff[0] = NUL;
} else if (opp->flags & P_EXPAND) {
home_replace(NULL, varp, NameBuff, MAXPATHL, false);
- // Translate 'pastetoggle' into special key names.
+ // Translate 'pastetoggle' into special key names.
} else if ((char_u **)opp->var == &p_pt) {
str2specialbuf((const char *)p_pt, (char *)NameBuff, MAXPATHL);
} else {
@@ -6614,8 +6766,8 @@ static void langmap_init(void)
/// changed at any time!
static void langmap_set(void)
{
- char_u *p;
- char_u *p2;
+ char_u *p;
+ char_u *p2;
int from, to;
ga_clear(&langmap_mapga); // clear the previous map first
@@ -6661,7 +6813,7 @@ static void langmap_set(void)
}
if (to == NUL) {
EMSG2(_("E357: 'langmap': Matching character missing for %s"),
- transchar(from));
+ transchar(from));
return;
}
@@ -6680,9 +6832,8 @@ static void langmap_set(void)
p = p2;
if (p[0] != NUL) {
if (p[0] != ',') {
- EMSG2(_(
- "E358: 'langmap': Extra characters after semicolon: %s"),
- p);
+ EMSG2(_("E358: 'langmap': Extra characters after semicolon: %s"),
+ p);
return;
}
p++;
@@ -6855,17 +7006,17 @@ static void paste_option_changed(void)
/// vimrc_found() - Called when a vimrc or "VIMINIT" has been found.
///
-/// Set the values for options that didn't get set yet to the Vim defaults.
+/// Set the values for options that didn't get set yet to the defaults.
/// When "fname" is not NULL, use it to set $"envname" when it wasn't set yet.
-void vimrc_found(char_u *fname, char_u *envname)
+void vimrc_found(char *fname, char *envname)
{
if (fname != NULL && envname != NULL) {
- char *p = vim_getenv((char *)envname);
+ char *p = vim_getenv(envname);
if (p == NULL) {
// Set $MYVIMRC to the first vimrc file found.
- p = FullName_save((char *)fname, false);
+ p = FullName_save(fname, false);
if (p != NULL) {
- os_setenv((char *)envname, p, 1);
+ os_setenv(envname, p, 1);
xfree(p);
}
} else {
@@ -6907,7 +7058,7 @@ void reset_option_was_set(const char *name)
/// fill_breakat_flags() -- called when 'breakat' changes value.
static void fill_breakat_flags(void)
{
- char_u *p;
+ char_u *p;
int i;
for (i = 0; i < 256; i++) {
@@ -6921,15 +7072,55 @@ static void fill_breakat_flags(void)
}
}
+/// fill_culopt_flags() -- called when 'culopt' changes value
+static int fill_culopt_flags(char_u *val, win_T *wp)
+{
+ char_u *p;
+ char_u culopt_flags_new = 0;
+
+ if (val == NULL) {
+ p = wp->w_p_culopt;
+ } else {
+ p = val;
+ }
+ while (*p != NUL) {
+ if (STRNCMP(p, "line", 4) == 0) {
+ p += 4;
+ culopt_flags_new |= CULOPT_LINE;
+ } else if (STRNCMP(p, "both", 4) == 0) {
+ p += 4;
+ culopt_flags_new |= CULOPT_LINE | CULOPT_NBR;
+ } else if (STRNCMP(p, "number", 6) == 0) {
+ p += 6;
+ culopt_flags_new |= CULOPT_NBR;
+ } else if (STRNCMP(p, "screenline", 10) == 0) {
+ p += 10;
+ culopt_flags_new |= CULOPT_SCRLINE;
+ }
+
+ if (*p != ',' && *p != NUL) {
+ return FAIL;
+ }
+ if (*p == ',') {
+ p++;
+ }
+ }
+
+ // Can't have both "line" and "screenline".
+ if ((culopt_flags_new & CULOPT_LINE) && (culopt_flags_new & CULOPT_SCRLINE)) {
+ return FAIL;
+ }
+ wp->w_p_culopt_flags = culopt_flags_new;
+
+ return OK;
+}
+
/// Check an option that can be a range of string values.
///
-/// Return OK for correct value, FAIL otherwise.
-/// Empty is always OK.
-static int check_opt_strings(
- char_u *val,
- char **values,
- int list // when true: accept a list of values
-)
+/// @param list when true: accept a list of values
+///
+/// @return OK for correct value, FAIL otherwise. Empty is always OK.
+static int check_opt_strings(char_u *val, char **values, int list)
{
return opt_strings_flags(val, values, NULL, list);
}
@@ -6937,14 +7128,12 @@ static int check_opt_strings(
/// Handle an option that can be a range of string values.
/// Set a flag in "*flagp" for each string present.
///
-/// Return OK for correct value, FAIL otherwise.
-/// Empty is always OK.
-static int opt_strings_flags(
- char_u *val, // new value
- char **values, // array of valid string values
- unsigned *flagp,
- bool list // when true: accept a list of values
-)
+/// @param val new value
+/// @param values array of valid string values
+/// @param list when true: accept a list of values
+///
+/// @return OK for correct value, FAIL otherwise. Empty is always OK.
+static int opt_strings_flags(char_u *val, char **values, unsigned *flagp, bool list)
{
unsigned int new_flags = 0;
@@ -6975,7 +7164,7 @@ static int opt_strings_flags(
static int check_opt_wim(void)
{
char_u new_wim_flags[4];
- char_u *p;
+ char_u *p;
int i;
int idx = 0;
@@ -7032,10 +7221,14 @@ bool can_bs(int what)
return false;
}
switch (*p_bs) {
- case '3': return true;
- case '2': return what != BS_NOSTOP;
- case '1': return what != BS_START;
- case '0': return false;
+ case '3':
+ return true;
+ case '2':
+ return what != BS_NOSTOP;
+ case '1':
+ return what != BS_START;
+ case '0':
+ return false;
}
return vim_strchr(p_bs, what) != NULL;
}
@@ -7232,11 +7425,7 @@ colnr_T tabstop_start(colnr_T col, long ts, long *vts)
// Find the number of tabs and spaces necessary to get from one column
// to another.
-void tabstop_fromto(colnr_T start_col,
- colnr_T end_col,
- long ts_arg,
- long *vts,
- int *ntabs,
+void tabstop_fromto(colnr_T start_col, colnr_T end_col, long ts_arg, long *vts, int *ntabs,
int *nspcs)
{
int spaces = end_col - start_col;
@@ -7406,25 +7595,24 @@ static bool briopt_check(win_T *wp)
int bri_shift = 0;
int bri_min = 20;
bool bri_sbr = false;
+ int bri_list = 0;
char_u *p = wp->w_p_briopt;
while (*p != NUL)
{
if (STRNCMP(p, "shift:", 6) == 0
- && ((p[6] == '-' && ascii_isdigit(p[7])) || ascii_isdigit(p[6])))
- {
+ && ((p[6] == '-' && ascii_isdigit(p[7])) || ascii_isdigit(p[6]))) {
p += 6;
bri_shift = getdigits_int(&p, true, 0);
- }
- else if (STRNCMP(p, "min:", 4) == 0 && ascii_isdigit(p[4]))
- {
+ } else if (STRNCMP(p, "min:", 4) == 0 && ascii_isdigit(p[4])) {
p += 4;
bri_min = getdigits_int(&p, true, 0);
- }
- else if (STRNCMP(p, "sbr", 3) == 0)
- {
+ } else if (STRNCMP(p, "sbr", 3) == 0) {
p += 3;
bri_sbr = true;
+ } else if (STRNCMP(p, "list:", 5) == 0) {
+ p += 5;
+ bri_list = (int)getdigits(&p, false, 0);
}
if (*p != ',' && *p != NUL) {
return false;
@@ -7437,6 +7625,7 @@ static bool briopt_check(win_T *wp)
wp->w_briopt_shift = bri_shift;
wp->w_briopt_min = bri_min;
wp->w_briopt_sbr = bri_sbr;
+ wp->w_briopt_list = bri_list;
return true;
}
@@ -7449,6 +7638,22 @@ unsigned int get_bkc_value(buf_T *buf)
return buf->b_bkc_flags ? buf->b_bkc_flags : bkc_flags;
}
+/// Get the local or global value of 'showbreak'.
+///
+/// @param win If not NULL, the window to get the local option from; global
+/// otherwise.
+char_u *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;
+ }
+ if (STRCMP(win->w_p_sbr, "NONE") == 0) {
+ return empty_option;
+ }
+ return win->w_p_sbr;
+}
+
/// Return the current end-of-line type: EOL_DOS, EOL_UNIX or EOL_MAC.
int get_fileformat(const buf_T *buf)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
@@ -7495,8 +7700,10 @@ int get_fileformat_force(const buf_T *buf, const exarg_T *eap)
int default_fileformat(void)
{
switch (*p_ffs) {
- case 'm': return EOL_MAC;
- case 'd': return EOL_DOS;
+ case 'm':
+ return EOL_MAC;
+ case 'd':
+ return EOL_DOS;
}
return EOL_UNIX;
}
@@ -7512,15 +7719,15 @@ void set_fileformat(int eol_style, int opt_flags)
char *p = NULL;
switch (eol_style) {
- case EOL_UNIX:
- p = FF_UNIX;
- break;
- case EOL_MAC:
- p = FF_MAC;
- break;
- case EOL_DOS:
- p = FF_DOS;
- break;
+ case EOL_UNIX:
+ p = FF_UNIX;
+ break;
+ case EOL_MAC:
+ p = FF_MAC;
+ break;
+ case EOL_DOS:
+ p = FF_DOS;
+ break;
}
// p is NULL if "eol_style" is EOL_UNKNOWN.
@@ -7558,11 +7765,10 @@ char_u *skip_to_option_part(const char_u *p)
/// @param[in] sep_chars chars that separate the option parts
///
/// @return length of `*option`
-size_t copy_option_part(char_u **option, char_u *buf, size_t maxlen,
- char *sep_chars)
+size_t copy_option_part(char_u **option, char_u *buf, size_t maxlen, char *sep_chars)
{
size_t len = 0;
- char_u *p = *option;
+ char_u *p = *option;
// skip '.' at start of option part, for 'suffixes'
if (*p == '.') {
@@ -7595,6 +7801,12 @@ int csh_like_shell(void)
return strstr((char *)path_tail(p_sh), "csh") != NULL;
}
+/// Return true when 'shell' has "fish" in the tail.
+bool fish_like_shell(void)
+{
+ return strstr((char *)path_tail(p_sh), "fish") != NULL;
+}
+
/// Return the number of requested sign columns, based on current
/// buffer signs and on user configuration.
int win_signcol_count(win_T *wp)
@@ -7719,53 +7931,52 @@ Dictionary get_all_vimoptions(void)
static Dictionary vimoption2dict(vimoption_T *opt)
{
- Dictionary dict = ARRAY_DICT_INIT;
+ Dictionary dict = ARRAY_DICT_INIT;
- PUT(dict, "name", CSTR_TO_OBJ(opt->fullname));
- PUT(dict, "shortname", CSTR_TO_OBJ(opt->shortname));
+ PUT(dict, "name", CSTR_TO_OBJ(opt->fullname));
+ PUT(dict, "shortname", CSTR_TO_OBJ(opt->shortname));
- const char *scope;
- if (opt->indir & PV_BUF) {
- scope = "buf";
- } else if (opt->indir & PV_WIN) {
- scope = "win";
- } else {
- scope = "global";
- }
-
- PUT(dict, "scope", CSTR_TO_OBJ(scope));
-
- // welcome to the jungle
- PUT(dict, "global_local", BOOL(opt->indir & PV_BOTH));
- PUT(dict, "commalist", BOOL(opt->flags & P_COMMA));
- PUT(dict, "flaglist", BOOL(opt->flags & P_FLAGLIST));
-
- PUT(dict, "was_set", BOOL(opt->flags & P_WAS_SET));
-
- PUT(dict, "last_set_sid", INTEGER_OBJ(opt->last_set.script_ctx.sc_sid));
- PUT(dict, "last_set_linenr", INTEGER_OBJ(opt->last_set.script_ctx.sc_lnum));
- PUT(dict, "last_set_chan", INTEGER_OBJ((int64_t)opt->last_set.channel_id));
-
- const char *type;
- Object def;
- // TODO(bfredl): do you even nocp?
- char_u *def_val = opt->def_val[(opt->flags & P_VI_DEF)
- ? VI_DEFAULT : VIM_DEFAULT];
- if (opt->flags & P_STRING) {
- type = "string";
- def = CSTR_TO_OBJ(def_val ? (char *)def_val : "");
- } else if (opt->flags & P_NUM) {
- type = "number";
- def = INTEGER_OBJ((Integer)(intptr_t)def_val);
- } else if (opt->flags & P_BOOL) {
- type = "boolean";
- def = BOOL((intptr_t)def_val);
- } else {
- type = ""; def = NIL;
- }
- PUT(dict, "type", CSTR_TO_OBJ(type));
- PUT(dict, "default", def);
- PUT(dict, "allows_duplicates", BOOL(!(opt->flags & P_NODUP)));
+ const char *scope;
+ if (opt->indir & PV_BUF) {
+ scope = "buf";
+ } else if (opt->indir & PV_WIN) {
+ scope = "win";
+ } else {
+ scope = "global";
+ }
+
+ PUT(dict, "scope", CSTR_TO_OBJ(scope));
+
+ // welcome to the jungle
+ PUT(dict, "global_local", BOOL(opt->indir & PV_BOTH));
+ PUT(dict, "commalist", BOOL(opt->flags & P_COMMA));
+ PUT(dict, "flaglist", BOOL(opt->flags & P_FLAGLIST));
+
+ PUT(dict, "was_set", BOOL(opt->flags & P_WAS_SET));
+
+ PUT(dict, "last_set_sid", INTEGER_OBJ(opt->last_set.script_ctx.sc_sid));
+ PUT(dict, "last_set_linenr", INTEGER_OBJ(opt->last_set.script_ctx.sc_lnum));
+ PUT(dict, "last_set_chan", INTEGER_OBJ((int64_t)opt->last_set.channel_id));
+
+ const char *type;
+ Object def;
+ // TODO(bfredl): do you even nocp?
+ char_u *def_val = opt->def_val;
+ if (opt->flags & P_STRING) {
+ type = "string";
+ def = CSTR_TO_OBJ(def_val ? (char *)def_val : "");
+ } else if (opt->flags & P_NUM) {
+ type = "number";
+ def = INTEGER_OBJ((Integer)(intptr_t)def_val);
+ } else if (opt->flags & P_BOOL) {
+ type = "boolean";
+ def = BOOL((intptr_t)def_val);
+ } else {
+ type = ""; def = NIL;
+ }
+ PUT(dict, "type", CSTR_TO_OBJ(type));
+ PUT(dict, "default", def);
+ PUT(dict, "allows_duplicates", BOOL(!(opt->flags & P_NODUP)));
- return dict;
+ return dict;
}
diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h
index beb62a6a0b..e588d3f373 100644
--- a/src/nvim/option_defs.h
+++ b/src/nvim/option_defs.h
@@ -276,10 +276,10 @@ enum {
})
// flags used for parsed 'wildmode'
-#define WIM_FULL 1
-#define WIM_LONGEST 2
-#define WIM_LIST 4
-#define WIM_BUFLASTUSED 8
+#define WIM_FULL 0x01
+#define WIM_LONGEST 0x02
+#define WIM_LIST 0x04
+#define WIM_BUFLASTUSED 0x08
// arguments for can_bs()
// each defined char should be unique over all values
@@ -291,6 +291,11 @@ enum {
#define BS_START 's' // "Start"
#define BS_NOSTOP 'p' // "nostoP
+// flags for the 'culopt' option
+#define CULOPT_LINE 0x01 // Highlight complete line
+#define CULOPT_SCRLINE 0x02 // Highlight screen line
+#define CULOPT_NBR 0x04 // Highlight Number column
+
#define LISPWORD_VALUE \
"defun,define,defmacro,set!,lambda,if,case,let,flet,let*,letrec,do,do*,define-syntax,let-syntax,letrec-syntax,destructuring-bind,defpackage,defparameter,defstruct,deftype,defvar,do-all-symbols,do-external-symbols,do-symbols,dolist,dotimes,ecase,etypecase,eval-when,labels,macrolet,multiple-value-bind,multiple-value-call,multiple-value-prog1,multiple-value-setq,prog1,progv,typecase,unless,unwind-protect,when,with-input-from-string,with-open-file,with-open-stream,with-output-to-string,with-package-iterator,define-condition,handler-bind,handler-case,restart-bind,restart-case,with-simple-restart,store-value,use-value,muffle-warning,abort,continue,with-slots,with-slots*,with-accessors,with-accessors*,defclass,defmethod,print-unreadable-object"
@@ -459,7 +464,6 @@ EXTERN char_u *p_pmcs; // 'printmbcharset'
EXTERN char_u *p_pfn; // 'printfont'
EXTERN char_u *p_popt; // 'printoptions'
EXTERN char_u *p_header; // 'printheader'
-EXTERN int p_prompt; // 'prompt'
EXTERN char_u *p_guicursor; // 'guicursor'
EXTERN char_u *p_guifont; // 'guifont'
EXTERN char_u *p_guifontwide; // 'guifontwide'
@@ -740,11 +744,11 @@ EXTERN long p_wd; // 'writedelay'
EXTERN int p_force_on; ///< options that cannot be turned off.
EXTERN int p_force_off; ///< options that cannot be turned on.
-/*
- * "indir" values for buffer-local opions.
- * These need to be defined globally, so that the BV_COUNT can be used with
- * b_p_scriptID[].
- */
+//
+// "indir" values for buffer-local options.
+// These need to be defined globally, so that the BV_COUNT can be used with
+// b_p_scriptID[].
+//
enum {
BV_AI = 0
, BV_AR
@@ -871,7 +875,9 @@ enum {
, WV_SPELL
, WV_CUC
, WV_CUL
+ , WV_CULOPT
, WV_CC
+ , WV_SBR
, WV_STL
, WV_WFH
, WV_WFW
diff --git a/src/nvim/options.lua b/src/nvim/options.lua
index 0b09686675..8b9cdefd57 100644
--- a/src/nvim/options.lua
+++ b/src/nvim/options.lua
@@ -6,11 +6,11 @@
-- type='number', list=nil, scope={'global'},
-- deny_duplicates=nil,
-- enable_if=nil,
--- defaults={condition=nil, if_true={vi=224, vim=0}, if_false=nil},
+-- defaults={condition=nil, if_true=224, if_false=nil},
-- secure=nil, gettext=nil, noglob=nil, normal_fname_chars=nil,
-- pri_mkrc=nil, deny_in_modelines=nil, normal_dname_chars=nil,
-- modelineexpr=nil,
--- expand=nil, nodefault=nil, no_mkrc=nil, vi_def=true, vim=true,
+-- expand=nil, nodefault=nil, no_mkrc=nil,
-- alloced=nil,
-- save_pv_indir=nil,
-- redraw={'curswant'},
@@ -21,7 +21,6 @@
-- scopes: global, buffer, window
-- redraw options: statuslines, current_window, curent_window_only,
-- current_buffer, all_windows, everything, curswant
--- default: {vi=…[, vim=…]}
-- defaults: {condition=#if condition, if_true=default, if_false=default}
-- #if condition:
-- string: #ifdef string
@@ -55,125 +54,109 @@ return {
full_name='aleph', abbreviation='al',
short_desc=N_("ASCII code of the letter Aleph (Hebrew)"),
type='number', scope={'global'},
- vi_def=true,
redraw={'curswant'},
varname='p_aleph',
- defaults={if_true={vi=224}}
+ defaults={if_true=224}
},
{
full_name='arabic', abbreviation='arab',
short_desc=N_("Arabic as a default second language"),
type='bool', scope={'window'},
- vi_def=true,
- vim=true,
redraw={'curswant'},
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='arabicshape', abbreviation='arshape',
short_desc=N_("do shaping for Arabic characters"),
type='bool', scope={'global'},
- vi_def=true,
- vim=true,
redraw={'all_windows', 'ui_option'},
varname='p_arshape',
- defaults={if_true={vi=true}}
+ defaults={if_true=true}
},
{
full_name='allowrevins', abbreviation='ari',
short_desc=N_("allow CTRL-_ in Insert and Command-line mode"),
type='bool', scope={'global'},
- vi_def=true,
- vim=true,
varname='p_ari',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='ambiwidth', abbreviation='ambw',
short_desc=N_("what to do with Unicode chars of ambiguous width"),
type='string', scope={'global'},
- vi_def=true,
redraw={'all_windows', 'ui_option'},
varname='p_ambw',
- defaults={if_true={vi="single"}}
+ defaults={if_true="single"}
},
{
full_name='autochdir', abbreviation='acd',
short_desc=N_("change directory to the file in the current window"),
type='bool', scope={'global'},
- vi_def=true,
varname='p_acd',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='autoindent', abbreviation='ai',
short_desc=N_("take indent for new line from previous line"),
type='bool', scope={'buffer'},
varname='p_ai',
- defaults={if_true={vi=false, vim=true}}
+ defaults={if_true=true}
},
{
full_name='autoread', abbreviation='ar',
short_desc=N_("autom. read file when changed outside of Vim"),
type='bool', scope={'global', 'buffer'},
varname='p_ar',
- defaults={if_true={vi=false, vim=true}}
+ defaults={if_true=true}
},
{
full_name='autowrite', abbreviation='aw',
short_desc=N_("automatically write file if changed"),
type='bool', scope={'global'},
- vi_def=true,
varname='p_aw',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='autowriteall', abbreviation='awa',
short_desc=N_("as 'autowrite', but works with more commands"),
type='bool', scope={'global'},
- vi_def=true,
varname='p_awa',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='background', abbreviation='bg',
short_desc=N_("\"dark\" or \"light\", used for highlight colors"),
type='string', scope={'global'},
- vim=true,
redraw={'all_windows'},
varname='p_bg',
- defaults={if_true={vi="light",vim="dark"}}
+ defaults={if_true="dark"}
},
{
full_name='backspace', abbreviation='bs',
short_desc=N_("how backspace works at start of line"),
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
- vim=true,
varname='p_bs',
- defaults={if_true={vi="", vim="indent,eol,start"}}
+ defaults={if_true="indent,eol,start"}
},
{
full_name='backup', abbreviation='bk',
short_desc=N_("keep backup file after overwriting a file"),
type='bool', scope={'global'},
- vi_def=true,
- vim=true,
varname='p_bk',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='backupcopy', abbreviation='bkc',
short_desc=N_("make backup as a copy, don't rename the file"),
type='string', list='onecomma', scope={'global', 'buffer'},
deny_duplicates=true,
- vim=true,
varname='p_bkc',
defaults={
condition='UNIX',
- if_true={vi="yes", vim="auto"},
- if_false={vi="auto", vim="auto"}
+ if_true="auto",
+ if_false="auto"
},
},
{
@@ -182,90 +165,79 @@ return {
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
secure=true,
- vi_def=true,
expand='nodefault',
varname='p_bdir',
- defaults={if_true={vi=''}}
+ defaults={if_true=''}
},
{
full_name='backupext', abbreviation='bex',
short_desc=N_("extension used for the backup file"),
type='string', scope={'global'},
normal_fname_chars=true,
- vi_def=true,
varname='p_bex',
- defaults={if_true={vi="~"}}
+ defaults={if_true="~"}
},
{
full_name='backupskip', abbreviation='bsk',
short_desc=N_("no backup for files that match these patterns"),
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
- vi_def=true,
varname='p_bsk',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='belloff', abbreviation='bo',
short_desc=N_("do not ring the bell for these reasons"),
type='string', list='comma', scope={'global'},
deny_duplicates=true,
- vi_def=true,
varname='p_bo',
- defaults={if_true={vi="all"}}
+ defaults={if_true="all"}
},
{
full_name='binary', abbreviation='bin',
short_desc=N_("read/write/edit file in binary mode"),
type='bool', scope={'buffer'},
- vi_def=true,
redraw={'statuslines'},
varname='p_bin',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='bomb',
short_desc=N_("a Byte Order Mark to the file"),
type='bool', scope={'buffer'},
no_mkrc=true,
- vi_def=true,
redraw={'statuslines'},
varname='p_bomb',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='breakat', abbreviation='brk',
short_desc=N_("characters that may cause a line break"),
type='string', list='flags', scope={'global'},
- vi_def=true,
redraw={'all_windows'},
varname='p_breakat',
- defaults={if_true={vi=" \t!@*-+;:,./?"}}
+ defaults={if_true=" \t!@*-+;:,./?"}
},
{
full_name='breakindent', abbreviation='bri',
short_desc=N_("wrapped line repeats indent"),
type='bool', scope={'window'},
- vi_def=true,
- vim=true,
redraw={'current_window'},
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='breakindentopt', abbreviation='briopt',
short_desc=N_("settings for 'breakindent'"),
type='string', list='onecomma', scope={'window'},
deny_duplicates=true,
- vi_def=true,
alloced=true,
redraw={'current_buffer'},
- defaults={if_true={vi=""}},
+ defaults={if_true=""},
},
{
full_name='browsedir', abbreviation='bsdir',
short_desc=N_("which directory to start browsing in"),
type='string', scope={'global'},
- vi_def=true,
enable_if=false,
},
{
@@ -273,56 +245,51 @@ return {
short_desc=N_("what to do when buffer is no longer in window"),
type='string', scope={'buffer'},
noglob=true,
- vi_def=true,
alloced=true,
varname='p_bh',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='buflisted', abbreviation='bl',
short_desc=N_("whether the buffer shows up in the buffer list"),
type='bool', scope={'buffer'},
noglob=true,
- vi_def=true,
varname='p_bl',
- defaults={if_true={vi=1}}
+ defaults={if_true=1}
},
{
full_name='buftype', abbreviation='bt',
short_desc=N_("special type of buffer"),
type='string', scope={'buffer'},
noglob=true,
- vi_def=true,
alloced=true,
varname='p_bt',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='casemap', abbreviation='cmp',
short_desc=N_("specifies how case of letters is changed"),
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
- vi_def=true,
varname='p_cmp',
- defaults={if_true={vi="internal,keepascii"}}
+ defaults={if_true="internal,keepascii"}
},
{
full_name='cdpath', abbreviation='cd',
short_desc=N_("list of directories searched with \":cd\""),
type='string', list='comma', scope={'global'},
deny_duplicates=true,
- vi_def=true,
expand=true,
secure=true,
varname='p_cdpath',
- defaults={if_true={vi=",,"}}
+ defaults={if_true=",,"}
},
{
full_name='cedit',
short_desc=N_("used to open the command-line window"),
type='string', scope={'global'},
varname='p_cedit',
- defaults={if_true={vi="", vim=macros('CTRL_F_STR')}}
+ defaults={if_true=macros('CTRL_F_STR')}
},
{
full_name='channel',
@@ -331,121 +298,108 @@ return {
no_mkrc=true,
nodefault=true,
varname='p_channel',
- defaults={if_true={vi=0}}
+ defaults={if_true=0}
},
{
full_name='charconvert', abbreviation='ccv',
short_desc=N_("expression for character encoding conversion"),
type='string', scope={'global'},
secure=true,
- vi_def=true,
varname='p_ccv',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='cindent', abbreviation='cin',
short_desc=N_("do C program indenting"),
type='bool', scope={'buffer'},
- vi_def=true,
- vim=true,
varname='p_cin',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='cinkeys', abbreviation='cink',
short_desc=N_("keys that trigger indent when 'cindent' is set"),
type='string', list='onecomma', scope={'buffer'},
deny_duplicates=true,
- vi_def=true,
alloced=true,
varname='p_cink',
- defaults={if_true={vi=indentkeys_default}}
+ defaults={if_true=indentkeys_default}
},
{
full_name='cinoptions', abbreviation='cino',
short_desc=N_("how to do indenting when 'cindent' is set"),
type='string', list='onecomma', scope={'buffer'},
deny_duplicates=true,
- vi_def=true,
alloced=true,
varname='p_cino',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='cinwords', abbreviation='cinw',
short_desc=N_("words where 'si' and 'cin' add an indent"),
type='string', list='onecomma', scope={'buffer'},
deny_duplicates=true,
- vi_def=true,
alloced=true,
varname='p_cinw',
- defaults={if_true={vi="if,else,while,do,for,switch"}}
+ defaults={if_true="if,else,while,do,for,switch"}
},
{
full_name='clipboard', abbreviation='cb',
short_desc=N_("use the clipboard as the unnamed register"),
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
- vi_def=true,
varname='p_cb',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='cmdheight', abbreviation='ch',
short_desc=N_("number of lines to use for the command-line"),
type='number', scope={'global'},
- vi_def=true,
redraw={'all_windows'},
varname='p_ch',
- defaults={if_true={vi=1}}
+ defaults={if_true=1}
},
{
full_name='cmdwinheight', abbreviation='cwh',
short_desc=N_("height of the command-line window"),
type='number', scope={'global'},
- vi_def=true,
varname='p_cwh',
- defaults={if_true={vi=7}}
+ defaults={if_true=7}
},
{
full_name='colorcolumn', abbreviation='cc',
short_desc=N_("columns to highlight"),
type='string', list='onecomma', scope={'window'},
deny_duplicates=true,
- vi_def=true,
redraw={'current_window'},
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='columns', abbreviation='co',
short_desc=N_("number of columns in the display"),
type='number', scope={'global'},
no_mkrc=true,
- vi_def=true,
redraw={'everything'},
varname='p_columns',
- defaults={if_true={vi=macros('DFLT_COLS')}}
+ defaults={if_true=macros('DFLT_COLS')}
},
{
full_name='comments', abbreviation='com',
short_desc=N_("patterns that can start a comment line"),
type='string', list='onecomma', scope={'buffer'},
deny_duplicates=true,
- vi_def=true,
alloced=true,
redraw={'curswant'},
varname='p_com',
- defaults={if_true={vi="s1:/*,mb:*,ex:*/,://,b:#,:%,:XCOMM,n:>,fb:-"}}
+ defaults={if_true="s1:/*,mb:*,ex:*/,://,b:#,:%,:XCOMM,n:>,fb:-"}
},
{
full_name='commentstring', abbreviation='cms',
short_desc=N_("template for comments; used for fold marker"),
type='string', scope={'buffer'},
- vi_def=true,
alloced=true,
redraw={'curswant'},
varname='p_cms',
- defaults={if_true={vi="/*%s*/"}}
+ defaults={if_true="/*%s*/"}
},
{
full_name='compatible', abbreviation='cp',
@@ -455,7 +409,7 @@ return {
varname='p_force_off',
-- pri_mkrc isn't needed here, optval_default()
-- always returns TRUE for 'compatible'
- defaults={if_true={vi=true, vim=false}}
+ defaults={if_true=false}
},
{
full_name='complete', abbreviation='cpt',
@@ -464,193 +418,172 @@ return {
deny_duplicates=true,
alloced=true,
varname='p_cpt',
- defaults={if_true={vi=".,w,b,u,t,i", vim=".,w,b,u,t"}}
+ defaults={if_true=".,w,b,u,t"}
},
{
full_name='concealcursor', abbreviation='cocu',
short_desc=N_("whether concealable text is hidden in cursor line"),
type='string', scope={'window'},
- vi_def=true,
alloced=true,
redraw={'current_window'},
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='conceallevel', abbreviation='cole',
short_desc=N_("whether concealable text is shown or hidden"),
type='number', scope={'window'},
- vi_def=true,
redraw={'current_window'},
- defaults={if_true={vi=0}}
+ defaults={if_true=0}
},
{
full_name='completefunc', abbreviation='cfu',
short_desc=N_("function to be used for Insert mode completion"),
type='string', scope={'buffer'},
secure=true,
- vi_def=true,
alloced=true,
varname='p_cfu',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='completeopt', abbreviation='cot',
short_desc=N_("options for Insert mode completion"),
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
- vi_def=true,
varname='p_cot',
- defaults={if_true={vi="menu,preview"}}
+ defaults={if_true="menu,preview"}
},
{
full_name='completeslash', abbreviation='csl',
type='string', scope={'buffer'},
- vi_def=true,
- vim=true,
varname='p_csl',
enable_if='BACKSLASH_IN_FILENAME',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='confirm', abbreviation='cf',
short_desc=N_("ask what to do about unsaved/read-only files"),
type='bool', scope={'global'},
- vi_def=true,
varname='p_confirm',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='copyindent', abbreviation='ci',
short_desc=N_("make 'autoindent' use existing indent structure"),
type='bool', scope={'buffer'},
- vi_def=true,
- vim=true,
varname='p_ci',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='cpoptions', abbreviation='cpo',
short_desc=N_("flags for Vi-compatible behavior"),
type='string', list='flags', scope={'global'},
- vim=true,
redraw={'all_windows'},
varname='p_cpo',
- defaults={if_true={vi=macros('CPO_VI'), vim=macros('CPO_VIM')}}
+ defaults={if_true=macros('CPO_VIM')}
},
{
full_name='cscopepathcomp', abbreviation='cspc',
short_desc=N_("how many components of the path to show"),
type='number', scope={'global'},
- vi_def=true,
- vim=true,
varname='p_cspc',
- defaults={if_true={vi=0}}
+ defaults={if_true=0}
},
{
full_name='cscopeprg', abbreviation='csprg',
short_desc=N_("command to execute cscope"),
type='string', scope={'global'},
secure=true,
- vi_def=true,
expand=true,
varname='p_csprg',
- defaults={if_true={vi="cscope"}}
+ defaults={if_true="cscope"}
},
{
full_name='cscopequickfix', abbreviation='csqf',
short_desc=N_("use quickfix window for cscope results"),
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
- vi_def=true,
varname='p_csqf',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='cscoperelative', abbreviation='csre',
short_desc=N_("Use cscope.out path basename as prefix"),
type='bool', scope={'global'},
- vi_def=true,
- vim=true,
varname='p_csre',
- defaults={if_true={vi=0}}
+ defaults={if_true=0}
},
{
full_name='cscopetag', abbreviation='cst',
short_desc=N_("use cscope for tag commands"),
type='bool', scope={'global'},
- vi_def=true,
- vim=true,
varname='p_cst',
- defaults={if_true={vi=0}}
+ defaults={if_true=0}
},
{
full_name='cscopetagorder', abbreviation='csto',
short_desc=N_("determines \":cstag\" search order"),
type='number', scope={'global'},
- vi_def=true,
- vim=true,
varname='p_csto',
- defaults={if_true={vi=0}}
+ defaults={if_true=0}
},
{
full_name='cscopeverbose', abbreviation='csverb',
short_desc=N_("give messages when adding a cscope database"),
type='bool', scope={'global'},
- vi_def=true,
- vim=true,
varname='p_csverbose',
- defaults={if_true={vi=1}}
+ defaults={if_true=1}
},
{
full_name='cursorbind', abbreviation='crb',
short_desc=N_("move cursor in window as it moves in other windows"),
type='bool', scope={'window'},
- vi_def=true,
pv_name='p_crbind',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='cursorcolumn', abbreviation='cuc',
short_desc=N_("highlight the screen column of the cursor"),
type='bool', scope={'window'},
- vi_def=true,
redraw={'current_window_only'},
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='cursorline', abbreviation='cul',
short_desc=N_("highlight the screen line of the cursor"),
type='bool', scope={'window'},
- vi_def=true,
redraw={'current_window_only'},
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
+ },
+ {
+ full_name='cursorlineopt', abbreviation='culopt',
+ short_desc=N_("settings for 'cursorline'"),
+ type='string', list='onecomma', scope={'window'},
+ deny_duplicates=true,
+ redraw={'current_window_only'},
+ defaults={if_true="both"}
},
{
full_name='debug',
short_desc=N_("to \"msg\" to see all error messages"),
type='string', scope={'global'},
- vi_def=true,
varname='p_debug',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='define', abbreviation='def',
short_desc=N_("pattern to be used to find a macro definition"),
type='string', scope={'global', 'buffer'},
- vi_def=true,
alloced=true,
redraw={'curswant'},
varname='p_def',
- defaults={if_true={vi="^\\s*#\\s*define"}}
+ defaults={if_true="^\\s*#\\s*define"}
},
{
full_name='delcombine', abbreviation='deco',
short_desc=N_("delete combining characters on their own"),
type='bool', scope={'global'},
- vi_def=true,
- vim=true,
varname='p_deco',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='dictionary', abbreviation='dict',
@@ -658,49 +591,43 @@ return {
type='string', list='onecomma', scope={'global', 'buffer'},
deny_duplicates=true,
normal_dname_chars=true,
- vi_def=true,
expand=true,
varname='p_dict',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='diff',
short_desc=N_("diff mode for the current window"),
type='bool', scope={'window'},
noglob=true,
- vi_def=true,
redraw={'current_window'},
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='diffexpr', abbreviation='dex',
short_desc=N_("expression used to obtain a diff file"),
type='string', scope={'global'},
secure=true,
- vi_def=true,
redraw={'curswant'},
varname='p_dex',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='diffopt', abbreviation='dip',
short_desc=N_("options for using diff mode"),
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
- vi_def=true,
alloced=true,
redraw={'current_window'},
varname='p_dip',
- defaults={if_true={vi="internal,filler,closeoff"}}
+ defaults={if_true="internal,filler,closeoff"}
},
{
full_name='digraph', abbreviation='dg',
short_desc=N_("enable the entering of digraphs in Insert mode"),
type='bool', scope={'global'},
- vi_def=true,
- vim=true,
varname='p_dg',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='directory', abbreviation='dir',
@@ -708,188 +635,167 @@ return {
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
secure=true,
- vi_def=true,
expand='nodefault',
varname='p_dir',
- defaults={if_true={vi=''}}
+ defaults={if_true=''}
},
{
full_name='display', abbreviation='dy',
short_desc=N_("list of flags for how to display text"),
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
- vim=true,
redraw={'all_windows'},
varname='p_dy',
- defaults={if_true={vi="", vim="lastline,msgsep"}}
+ defaults={if_true="lastline,msgsep"}
},
{
full_name='eadirection', abbreviation='ead',
short_desc=N_("in which direction 'equalalways' works"),
type='string', scope={'global'},
- vi_def=true,
varname='p_ead',
- defaults={if_true={vi="both"}}
+ defaults={if_true="both"}
},
{
full_name='edcompatible', abbreviation='ed',
short_desc=N_("No description"),
type='bool', scope={'global'},
- vi_def=true,
varname='p_force_off',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='emoji', abbreviation='emo',
short_desc=N_("No description"),
type='bool', scope={'global'},
- vi_def=true,
redraw={'all_windows', 'ui_option'},
varname='p_emoji',
- defaults={if_true={vi=true}}
+ defaults={if_true=true}
},
{
full_name='encoding', abbreviation='enc',
short_desc=N_("encoding used internally"),
type='string', scope={'global'},
deny_in_modelines=true,
- vi_def=true,
varname='p_enc',
- defaults={if_true={vi=macros('ENC_DFLT')}}
+ defaults={if_true=macros('ENC_DFLT')}
},
{
full_name='endofline', abbreviation='eol',
short_desc=N_("write <EOL> for last line in file"),
type='bool', scope={'buffer'},
no_mkrc=true,
- vi_def=true,
redraw={'statuslines'},
varname='p_eol',
- defaults={if_true={vi=true}}
+ defaults={if_true=true}
},
{
full_name='equalalways', abbreviation='ea',
short_desc=N_("windows are automatically made the same size"),
type='bool', scope={'global'},
- vi_def=true,
redraw={'all_windows'},
varname='p_ea',
- defaults={if_true={vi=true}}
+ defaults={if_true=true}
},
{
full_name='equalprg', abbreviation='ep',
short_desc=N_("external program to use for \"=\" command"),
type='string', scope={'global', 'buffer'},
secure=true,
- vi_def=true,
expand=true,
varname='p_ep',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='errorbells', abbreviation='eb',
short_desc=N_("ring the bell for error messages"),
type='bool', scope={'global'},
- vi_def=true,
varname='p_eb',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='errorfile', abbreviation='ef',
short_desc=N_("name of the errorfile for the QuickFix mode"),
type='string', scope={'global'},
secure=true,
- vi_def=true,
expand=true,
varname='p_ef',
- defaults={if_true={vi=macros('DFLT_ERRORFILE')}}
+ defaults={if_true=macros('DFLT_ERRORFILE')}
},
{
full_name='errorformat', abbreviation='efm',
short_desc=N_("description of the lines in the error file"),
type='string', list='onecomma', scope={'global', 'buffer'},
deny_duplicates=true,
- vi_def=true,
varname='p_efm',
- defaults={if_true={vi=macros('DFLT_EFM')}}
+ defaults={if_true=macros('DFLT_EFM')}
},
{
full_name='eventignore', abbreviation='ei',
short_desc=N_("autocommand events that are ignored"),
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
- vi_def=true,
varname='p_ei',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='expandtab', abbreviation='et',
short_desc=N_("use spaces when <Tab> is inserted"),
type='bool', scope={'buffer'},
- vi_def=true,
- vim=true,
varname='p_et',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='exrc', abbreviation='ex',
short_desc=N_("read .nvimrc and .exrc in the current directory"),
type='bool', scope={'global'},
secure=true,
- vi_def=true,
varname='p_exrc',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='fileencoding', abbreviation='fenc',
short_desc=N_("file encoding for multi-byte text"),
type='string', scope={'buffer'},
no_mkrc=true,
- vi_def=true,
alloced=true,
redraw={'statuslines', 'current_buffer'},
varname='p_fenc',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='fileencodings', abbreviation='fencs',
short_desc=N_("automatically detected character encodings"),
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
- vi_def=true,
varname='p_fencs',
- defaults={if_true={vi="ucs-bom,utf-8,default,latin1"}}
+ defaults={if_true="ucs-bom,utf-8,default,latin1"}
},
{
full_name='fileformat', abbreviation='ff',
short_desc=N_("file format used for file I/O"),
type='string', scope={'buffer'},
no_mkrc=true,
- vi_def=true,
alloced=true,
redraw={'curswant', 'statuslines'},
varname='p_ff',
- defaults={if_true={vi=macros('DFLT_FF')}}
+ defaults={if_true=macros('DFLT_FF')}
},
{
full_name='fileformats', abbreviation='ffs',
short_desc=N_("automatically detected values for 'fileformat'"),
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
- vim=true,
varname='p_ffs',
- defaults={if_true={vi=macros('DFLT_FFS_VI'), vim=macros('DFLT_FFS_VIM')}}
+ defaults={if_true=macros('DFLT_FFS_VIM')}
},
{
full_name='fileignorecase', abbreviation='fic',
short_desc=N_("ignore case when using file names"),
type='bool', scope={'global'},
- vi_def=true,
varname='p_fic',
defaults={
condition='CASE_INSENSITIVE_FILENAME',
- if_true={vi=true},
- if_false={vi=false},
+ if_true=true,
+ if_false=false,
}
},
{
@@ -898,235 +804,204 @@ return {
type='string', scope={'buffer'},
noglob=true,
normal_fname_chars=true,
- vi_def=true,
alloced=true,
expand=true,
varname='p_ft',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='fillchars', abbreviation='fcs',
short_desc=N_("characters to use for displaying special items"),
type='string', list='onecomma', scope={'global', 'window'},
deny_duplicates=true,
- vi_def=true,
alloced=true,
redraw={'current_window'},
varname='p_fcs',
- defaults={if_true={vi=''}}
+ defaults={if_true=''}
},
{
full_name='fixendofline', abbreviation='fixeol',
short_desc=N_("make sure last line in file has <EOL>"),
type='bool', scope={'buffer'},
- vi_def=true,
redraw={'statuslines'},
varname='p_fixeol',
- defaults={if_true={vi=true}}
+ defaults={if_true=true}
},
{
full_name='foldclose', abbreviation='fcl',
short_desc=N_("close a fold when the cursor leaves it"),
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
- vi_def=true,
redraw={'current_window'},
varname='p_fcl',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='foldcolumn', abbreviation='fdc',
short_desc=N_("width of the column used to indicate folds"),
type='string', scope={'window'},
- vi_def=true,
alloced=true,
redraw={'current_window'},
- defaults={if_true={vi="0"}}
+ defaults={if_true="0"}
},
{
full_name='foldenable', abbreviation='fen',
short_desc=N_("set to display all folds open"),
type='bool', scope={'window'},
- vi_def=true,
redraw={'current_window'},
- defaults={if_true={vi=true}}
+ defaults={if_true=true}
},
{
full_name='foldexpr', abbreviation='fde',
short_desc=N_("expression used when 'foldmethod' is \"expr\""),
type='string', scope={'window'},
- vi_def=true,
- vim=true,
modelineexpr=true,
alloced=true,
redraw={'current_window'},
- defaults={if_true={vi="0"}}
+ defaults={if_true="0"}
},
{
full_name='foldignore', abbreviation='fdi',
short_desc=N_("ignore lines when 'foldmethod' is \"indent\""),
type='string', scope={'window'},
- vi_def=true,
- vim=true,
alloced=true,
redraw={'current_window'},
- defaults={if_true={vi="#"}}
+ defaults={if_true="#"}
},
{
full_name='foldlevel', abbreviation='fdl',
short_desc=N_("close folds with a level higher than this"),
type='number', scope={'window'},
- vi_def=true,
redraw={'current_window'},
- defaults={if_true={vi=0}}
+ defaults={if_true=0}
},
{
full_name='foldlevelstart', abbreviation='fdls',
short_desc=N_("'foldlevel' when starting to edit a file"),
type='number', scope={'global'},
- vi_def=true,
redraw={'curswant'},
varname='p_fdls',
- defaults={if_true={vi=-1}}
+ defaults={if_true=-1}
},
{
full_name='foldmarker', abbreviation='fmr',
short_desc=N_("markers used when 'foldmethod' is \"marker\""),
type='string', list='onecomma', scope={'window'},
deny_duplicates=true,
- vi_def=true,
- vim=true,
alloced=true,
redraw={'current_window'},
- defaults={if_true={vi="{{{,}}}"}}
+ defaults={if_true="{{{,}}}"}
},
{
full_name='foldmethod', abbreviation='fdm',
short_desc=N_("folding type"),
type='string', scope={'window'},
- vi_def=true,
- vim=true,
alloced=true,
redraw={'current_window'},
- defaults={if_true={vi="manual"}}
+ defaults={if_true="manual"}
},
{
full_name='foldminlines', abbreviation='fml',
short_desc=N_("minimum number of lines for a fold to be closed"),
type='number', scope={'window'},
- vi_def=true,
redraw={'current_window'},
- defaults={if_true={vi=1}}
+ defaults={if_true=1}
},
{
full_name='foldnestmax', abbreviation='fdn',
short_desc=N_("maximum fold depth"),
type='number', scope={'window'},
- vi_def=true,
redraw={'current_window'},
- defaults={if_true={vi=20}}
+ defaults={if_true=20}
},
{
full_name='foldopen', abbreviation='fdo',
short_desc=N_("for which commands a fold will be opened"),
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
- vi_def=true,
redraw={'curswant'},
varname='p_fdo',
- defaults={if_true={vi="block,hor,mark,percent,quickfix,search,tag,undo"}}
+ defaults={if_true="block,hor,mark,percent,quickfix,search,tag,undo"}
},
{
full_name='foldtext', abbreviation='fdt',
short_desc=N_("expression used to display for a closed fold"),
type='string', scope={'window'},
- vi_def=true,
- vim=true,
modelineexpr=true,
alloced=true,
redraw={'current_window'},
- defaults={if_true={vi="foldtext()"}}
+ defaults={if_true="foldtext()"}
},
{
full_name='formatexpr', abbreviation='fex',
short_desc=N_("expression used with \"gq\" command"),
type='string', scope={'buffer'},
- vi_def=true,
- vim=true,
modelineexpr=true,
alloced=true,
varname='p_fex',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='formatoptions', abbreviation='fo',
short_desc=N_("how automatic formatting is to be done"),
type='string', list='flags', scope={'buffer'},
- vim=true,
alloced=true,
varname='p_fo',
- defaults={if_true={vi=macros('DFLT_FO_VI'), vim=macros('DFLT_FO_VIM')}}
+ defaults={if_true=macros('DFLT_FO_VIM')}
},
{
full_name='formatlistpat', abbreviation='flp',
short_desc=N_("pattern used to recognize a list header"),
type='string', scope={'buffer'},
- vi_def=true,
alloced=true,
varname='p_flp',
- defaults={if_true={vi="^\\s*\\d\\+[\\]:.)}\\t ]\\s*"}}
+ defaults={if_true="^\\s*\\d\\+[\\]:.)}\\t ]\\s*"}
},
{
full_name='formatprg', abbreviation='fp',
short_desc=N_("name of external program used with \"gq\" command"),
type='string', scope={'global', 'buffer'},
secure=true,
- vi_def=true,
expand=true,
varname='p_fp',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='fsync', abbreviation='fs',
short_desc=N_("whether to invoke fsync() after file write"),
type='bool', scope={'global'},
secure=true,
- vi_def=true,
varname='p_fs',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='gdefault', abbreviation='gd',
short_desc=N_("the \":substitute\" flag 'g' is default on"),
type='bool', scope={'global'},
- vi_def=true,
- vim=true,
varname='p_gd',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='grepformat', abbreviation='gfm',
short_desc=N_("format of 'grepprg' output"),
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
- vi_def=true,
varname='p_gefm',
- defaults={if_true={vi=macros('DFLT_GREPFORMAT')}}
+ defaults={if_true=macros('DFLT_GREPFORMAT')}
},
{
full_name='grepprg', abbreviation='gp',
short_desc=N_("program to use for \":grep\""),
type='string', scope={'global', 'buffer'},
secure=true,
- vi_def=true,
expand=true,
varname='p_gp',
defaults={
condition='WIN32',
-- Add an extra file name so that grep will always
-- insert a file name in the match line. */
- if_true={vi="findstr /n $* nul"},
- if_false={vi="grep -n $* /dev/null"}
+ if_true="findstr /n $* nul",
+ if_false="grep -n $* /dev/null"
}
},
{
@@ -1134,35 +1009,31 @@ return {
short_desc=N_("GUI: settings for cursor shape and blinking"),
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
- vi_def=true,
varname='p_guicursor',
- defaults={if_true={vi="n-v-c-sm:block,i-ci-ve:ver25,r-cr-o:hor20"}}
+ defaults={if_true="n-v-c-sm:block,i-ci-ve:ver25,r-cr-o:hor20"}
},
{
full_name='guifont', abbreviation='gfn',
short_desc=N_("GUI: Name(s) of font(s) to be used"),
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
- vi_def=true,
varname='p_guifont',
redraw={'ui_option'},
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='guifontwide', abbreviation='gfw',
short_desc=N_("list of font names for double-wide characters"),
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
- vi_def=true,
redraw={'ui_option'},
varname='p_guifontwide',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='guioptions', abbreviation='go',
short_desc=N_("GUI: Which components and options are used"),
type='string', list='flags', scope={'global'},
- vi_def=true,
redraw={'all_windows'},
enable_if=false,
},
@@ -1170,7 +1041,6 @@ return {
full_name='guitablabel', abbreviation='gtl',
short_desc=N_("GUI: custom label for a tab page"),
type='string', scope={'global'},
- vi_def=true,
modelineexpr=true,
redraw={'current_window'},
enable_if=false,
@@ -1179,7 +1049,6 @@ return {
full_name='guitabtooltip', abbreviation='gtt',
short_desc=N_("GUI: custom tooltip for a tab page"),
type='string', scope={'global'},
- vi_def=true,
redraw={'current_window'},
enable_if=false,
},
@@ -1188,228 +1057,199 @@ return {
short_desc=N_("full path name of the main help file"),
type='string', scope={'global'},
secure=true,
- vi_def=true,
expand=true,
varname='p_hf',
- defaults={if_true={vi=macros('DFLT_HELPFILE')}}
+ defaults={if_true=macros('DFLT_HELPFILE')}
},
{
full_name='helpheight', abbreviation='hh',
short_desc=N_("minimum height of a new help window"),
type='number', scope={'global'},
- vi_def=true,
varname='p_hh',
- defaults={if_true={vi=20}}
+ defaults={if_true=20}
},
{
full_name='helplang', abbreviation='hlg',
short_desc=N_("preferred help languages"),
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
- vi_def=true,
varname='p_hlg',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='hidden', abbreviation='hid',
short_desc=N_("don't unload buffer when it is |abandon|ed"),
type='bool', scope={'global'},
- vi_def=true,
varname='p_hid',
- defaults={if_true={vi=false}}
+ defaults={if_true=true}
},
{
full_name='highlight', abbreviation='hl',
short_desc=N_("sets highlighting mode for various occasions"),
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
- vi_def=true,
varname='p_hl',
- defaults={if_true={vi=macros('HIGHLIGHT_INIT')}}
+ defaults={if_true=macros('HIGHLIGHT_INIT')}
},
{
full_name='history', abbreviation='hi',
short_desc=N_("number of command-lines that are remembered"),
type='number', scope={'global'},
- vim=true,
varname='p_hi',
- defaults={if_true={vi=0, vim=10000}}
+ defaults={if_true=10000}
},
{
full_name='hkmap', abbreviation='hk',
short_desc=N_("Hebrew keyboard mapping"),
type='bool', scope={'global'},
- vi_def=true,
- vim=true,
varname='p_hkmap',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='hkmapp', abbreviation='hkp',
short_desc=N_("phonetic Hebrew keyboard mapping"),
type='bool', scope={'global'},
- vi_def=true,
- vim=true,
varname='p_hkmapp',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='hlsearch', abbreviation='hls',
short_desc=N_("highlight matches with last search pattern"),
type='bool', scope={'global'},
- vim=true,
redraw={'all_windows'},
varname='p_hls',
- defaults={if_true={vi=false, vim=true}}
+ defaults={if_true=true}
},
{
full_name='icon',
short_desc=N_("Vim set the text of the window icon"),
type='bool', scope={'global'},
- vi_def=true,
varname='p_icon',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='iconstring',
short_desc=N_("to use for the Vim icon text"),
type='string', scope={'global'},
- vi_def=true,
modelineexpr=true,
varname='p_iconstring',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='ignorecase', abbreviation='ic',
short_desc=N_("ignore case in search patterns"),
type='bool', scope={'global'},
- vi_def=true,
varname='p_ic',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='imcmdline', abbreviation='imc',
short_desc=N_("use IM when starting to edit a command line"),
type='bool', scope={'global'},
- vi_def=true,
enable_if=false,
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='imdisable', abbreviation='imd',
short_desc=N_("do not use the IM in any mode"),
type='bool', scope={'global'},
- vi_def=true,
enable_if=false,
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='iminsert', abbreviation='imi',
short_desc=N_("use :lmap or IM in Insert mode"),
type='number', scope={'buffer'},
- vi_def=true,
varname='p_iminsert', pv_name='p_imi',
defaults={
- if_true={vi=macros('B_IMODE_NONE')},
+ if_true=macros('B_IMODE_NONE'),
}
},
{
full_name='imsearch', abbreviation='ims',
short_desc=N_("use :lmap or IM when typing a search pattern"),
type='number', scope={'buffer'},
- vi_def=true,
varname='p_imsearch', pv_name='p_ims',
defaults={
- if_true={vi=macros('B_IMODE_USE_INSERT')},
+ if_true=macros('B_IMODE_USE_INSERT'),
}
},
{
full_name='inccommand', abbreviation='icm',
short_desc=N_("Live preview of substitution"),
type='string', scope={'global'},
- vi_def=true,
redraw={'all_windows'},
varname='p_icm',
- defaults={if_true={vi=""}}
+ defaults={if_true="nosplit"}
},
{
full_name='include', abbreviation='inc',
short_desc=N_("pattern to be used to find an include file"),
type='string', scope={'global', 'buffer'},
- vi_def=true,
alloced=true,
varname='p_inc',
- defaults={if_true={vi="^\\s*#\\s*include"}}
+ defaults={if_true="^\\s*#\\s*include"}
},
{
full_name='includeexpr', abbreviation='inex',
short_desc=N_("expression used to process an include line"),
type='string', scope={'buffer'},
- vi_def=true,
modelineexpr=true,
alloced=true,
varname='p_inex',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='incsearch', abbreviation='is',
short_desc=N_("highlight match while typing search pattern"),
type='bool', scope={'global'},
- vim=true,
varname='p_is',
- defaults={if_true={vi=false, vim=true}}
+ defaults={if_true=true}
},
{
full_name='indentexpr', abbreviation='inde',
short_desc=N_("expression used to obtain the indent of a line"),
type='string', scope={'buffer'},
- vi_def=true,
- vim=true,
modelineexpr=true,
alloced=true,
varname='p_inde',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='indentkeys', abbreviation='indk',
short_desc=N_("keys that trigger indenting with 'indentexpr'"),
type='string', list='onecomma', scope={'buffer'},
deny_duplicates=true,
- vi_def=true,
alloced=true,
varname='p_indk',
- defaults={if_true={vi=indentkeys_default}}
+ defaults={if_true=indentkeys_default}
},
{
full_name='infercase', abbreviation='inf',
short_desc=N_("adjust case of match for keyword completion"),
type='bool', scope={'buffer'},
- vi_def=true,
varname='p_inf',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='insertmode', abbreviation='im',
short_desc=N_("start the edit of a file in Insert mode"),
type='bool', scope={'global'},
- vi_def=true,
- vim=true,
varname='p_im',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='isfname', abbreviation='isf',
short_desc=N_("characters included in file names and pathnames"),
type='string', list='comma', scope={'global'},
deny_duplicates=true,
- vi_def=true,
varname='p_isf',
defaults={
condition='BACKSLASH_IN_FILENAME',
-- Excluded are: & and ^ are special in cmd.exe
-- ( and ) are used in text separating fnames */
- if_true={vi="@,48-57,/,\\,.,-,_,+,,,#,$,%,{,},[,],:,@-@,!,~,="},
- if_false={vi="@,48-57,/,.,-,_,+,,,#,$,%,~,="}
+ if_true="@,48-57,/,\\,.,-,_,+,,,#,$,%,{,},[,],:,@-@,!,~,=",
+ if_false="@,48-57,/,.,-,_,+,,,#,$,%,~,="
}
},
{
@@ -1417,12 +1257,11 @@ return {
short_desc=N_("characters included in identifiers"),
type='string', list='comma', scope={'global'},
deny_duplicates=true,
- vi_def=true,
varname='p_isi',
defaults={
condition='WIN32',
- if_true={vi="@,48-57,_,128-167,224-235"},
- if_false={vi="@,48-57,_,192-255"}
+ if_true="@,48-57,_,128-167,224-235",
+ if_false="@,48-57,_,192-255"
}
},
{
@@ -1430,30 +1269,26 @@ return {
short_desc=N_("characters included in keywords"),
type='string', list='comma', scope={'buffer'},
deny_duplicates=true,
- vim=true,
alloced=true,
varname='p_isk',
- defaults={if_true={vi="@,48-57,_", vim="@,48-57,_,192-255"}}
+ defaults={if_true="@,48-57,_,192-255"}
},
{
full_name='isprint', abbreviation='isp',
short_desc=N_("printable characters"),
type='string', list='comma', scope={'global'},
deny_duplicates=true,
- vi_def=true,
redraw={'all_windows'},
varname='p_isp',
- defaults={if_true={vi="@,161-255"}
+ defaults={if_true="@,161-255"
}
},
{
full_name='joinspaces', abbreviation='js',
short_desc=N_("two spaces after a period with a join command"),
type='bool', scope={'global'},
- vi_def=true,
- vim=true,
varname='p_js',
- defaults={if_true={vi=true}}
+ defaults={if_true=false}
},
{
full_name='jumpoptions', abbreviation='jop',
@@ -1461,8 +1296,7 @@ return {
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
varname='p_jop',
- vim=true,
- defaults={if_true={vim=''}}
+ defaults={if_true=''}
},
{
full_name='keymap', abbreviation='kmp',
@@ -1470,31 +1304,28 @@ return {
type='string', scope={'buffer'},
normal_fname_chars=true,
pri_mkrc=true,
- vi_def=true,
alloced=true,
redraw={'statuslines', 'current_buffer'},
varname='p_keymap', pv_name='p_kmap',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='keymodel', abbreviation='km',
short_desc=N_("enable starting/stopping selection with keys"),
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
- vi_def=true,
varname='p_km',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='keywordprg', abbreviation='kp',
short_desc=N_("program to use for the \"K\" command"),
type='string', scope={'global', 'buffer'},
secure=true,
- vi_def=true,
expand=true,
varname='p_kp',
defaults={
- if_true={vi=":Man"},
+ if_true=":Man",
}
},
{
@@ -1503,324 +1334,289 @@ return {
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
secure=true,
- vi_def=true,
varname='p_langmap',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='langmenu', abbreviation='lm',
short_desc=N_("language to be used for the menus"),
type='string', scope={'global'},
normal_fname_chars=true,
- vi_def=true,
varname='p_lm',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='langnoremap', abbreviation='lnr',
short_desc=N_("do not apply 'langmap' to mapped characters"),
type='bool', scope={'global'},
varname='p_lnr',
- defaults={if_true={vi=false, vim=true}}
+ defaults={if_true=true}
},
{
full_name='langremap', abbreviation='lrm',
short_desc=N_('No description'),
type='bool', scope={'global'},
varname='p_lrm',
- defaults={if_true={vi=true, vim=false}}
+ defaults={if_true=false}
},
{
full_name='laststatus', abbreviation='ls',
short_desc=N_("tells when last window has status lines"),
type='number', scope={'global'},
- vim=true,
redraw={'all_windows'},
varname='p_ls',
- defaults={if_true={vi=1,vim=2}}
+ defaults={if_true=2}
},
{
full_name='lazyredraw', abbreviation='lz',
short_desc=N_("don't redraw while executing macros"),
type='bool', scope={'global'},
- vi_def=true,
varname='p_lz',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='linebreak', abbreviation='lbr',
short_desc=N_("wrap long lines at a blank"),
type='bool', scope={'window'},
- vi_def=true,
redraw={'current_window'},
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='lines',
short_desc=N_("of lines in the display"),
type='number', scope={'global'},
no_mkrc=true,
- vi_def=true,
redraw={'everything'},
varname='p_lines',
- defaults={if_true={vi=macros('DFLT_ROWS')}}
+ defaults={if_true=macros('DFLT_ROWS')}
},
{
full_name='linespace', abbreviation='lsp',
short_desc=N_("number of pixel lines to use between characters"),
type='number', scope={'global'},
- vi_def=true,
redraw={'ui_option'},
varname='p_linespace',
- defaults={if_true={vi=0}}
+ defaults={if_true=0}
},
{
full_name='lisp',
short_desc=N_("indenting for Lisp"),
type='bool', scope={'buffer'},
- vi_def=true,
varname='p_lisp',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='lispwords', abbreviation='lw',
short_desc=N_("words that change how lisp indenting works"),
type='string', list='onecomma', scope={'global', 'buffer'},
deny_duplicates=true,
- vi_def=true,
varname='p_lispwords', pv_name='p_lw',
- defaults={if_true={vi=macros('LISPWORD_VALUE')}}
+ defaults={if_true=macros('LISPWORD_VALUE')}
},
{
full_name='list',
short_desc=N_("<Tab> and <EOL>"),
type='bool', scope={'window'},
- vi_def=true,
redraw={'current_window'},
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='listchars', abbreviation='lcs',
short_desc=N_("characters for displaying in list mode"),
type='string', list='onecomma', scope={'global', 'window'},
deny_duplicates=true,
- vim=true,
alloced=true,
redraw={'current_window'},
varname='p_lcs',
- defaults={if_true={vi="eol:$", vim="tab:> ,trail:-,nbsp:+"}}
+ defaults={if_true="tab:> ,trail:-,nbsp:+"}
},
{
full_name='loadplugins', abbreviation='lpl',
short_desc=N_("load plugin scripts when starting up"),
type='bool', scope={'global'},
- vi_def=true,
varname='p_lpl',
- defaults={if_true={vi=true}}
+ defaults={if_true=true}
},
{
full_name='magic',
short_desc=N_("special characters in search patterns"),
type='bool', scope={'global'},
- vi_def=true,
varname='p_magic',
- defaults={if_true={vi=true}}
+ defaults={if_true=true}
},
{
full_name='makeef', abbreviation='mef',
short_desc=N_("name of the errorfile for \":make\""),
type='string', scope={'global'},
secure=true,
- vi_def=true,
expand=true,
varname='p_mef',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='makeencoding', abbreviation='menc',
short_desc=N_("Converts the output of external commands"),
type='string', scope={'global', 'buffer'},
- vi_def=true,
varname='p_menc',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='makeprg', abbreviation='mp',
short_desc=N_("program to use for the \":make\" command"),
type='string', scope={'global', 'buffer'},
secure=true,
- vi_def=true,
expand=true,
varname='p_mp',
- defaults={if_true={vi="make"}}
+ defaults={if_true="make"}
},
{
full_name='matchpairs', abbreviation='mps',
short_desc=N_("pairs of characters that \"%\" can match"),
type='string', list='onecomma', scope={'buffer'},
deny_duplicates=true,
- vi_def=true,
alloced=true,
varname='p_mps',
- defaults={if_true={vi="(:),{:},[:]"}}
+ defaults={if_true="(:),{:},[:]"}
},
{
full_name='matchtime', abbreviation='mat',
short_desc=N_("tenths of a second to show matching paren"),
type='number', scope={'global'},
- vi_def=true,
varname='p_mat',
- defaults={if_true={vi=5}}
+ defaults={if_true=5}
},
{
full_name='maxcombine', abbreviation='mco',
short_desc=N_("maximum nr of combining characters displayed"),
type='number', scope={'global'},
- vi_def=true,
varname='p_mco',
- defaults={if_true={vi=6}}
+ defaults={if_true=6}
},
{
full_name='maxfuncdepth', abbreviation='mfd',
short_desc=N_("maximum recursive depth for user functions"),
type='number', scope={'global'},
- vi_def=true,
varname='p_mfd',
- defaults={if_true={vi=100}}
+ defaults={if_true=100}
},
{
full_name='maxmapdepth', abbreviation='mmd',
short_desc=N_("maximum recursive depth for mapping"),
type='number', scope={'global'},
- vi_def=true,
varname='p_mmd',
- defaults={if_true={vi=1000}}
+ defaults={if_true=1000}
},
{
full_name='maxmempattern', abbreviation='mmp',
short_desc=N_("maximum memory (in Kbyte) used for pattern search"),
type='number', scope={'global'},
- vi_def=true,
varname='p_mmp',
- defaults={if_true={vi=1000}}
+ defaults={if_true=1000}
},
{
full_name='menuitems', abbreviation='mis',
short_desc=N_("maximum number of items in a menu"),
type='number', scope={'global'},
- vi_def=true,
varname='p_mis',
- defaults={if_true={vi=25}}
+ defaults={if_true=25}
},
{
full_name='mkspellmem', abbreviation='msm',
short_desc=N_("memory used before |:mkspell| compresses the tree"),
type='string', scope={'global'},
secure=true,
- vi_def=true,
expand=true,
varname='p_msm',
- defaults={if_true={vi="460000,2000,500"}}
+ defaults={if_true="460000,2000,500"}
},
{
full_name='modeline', abbreviation='ml',
short_desc=N_("recognize modelines at start or end of file"),
type='bool', scope={'buffer'},
- vim=true,
varname='p_ml',
- defaults={if_true={vi=false, vim=true}}
+ defaults={if_true=true}
},
{
full_name='modelineexpr', abbreviation='mle',
short_desc=N_("allow some options to be set in modeline"),
type='bool', scope={'global'},
- vi_def=true,
secure=true,
varname='p_mle',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='modelines', abbreviation='mls',
short_desc=N_("number of lines checked for modelines"),
type='number', scope={'global'},
- vi_def=true,
varname='p_mls',
- defaults={if_true={vi=5}}
+ defaults={if_true=5}
},
{
full_name='modifiable', abbreviation='ma',
short_desc=N_("changes to the text are not possible"),
type='bool', scope={'buffer'},
noglob=true,
- vi_def=true,
varname='p_ma',
- defaults={if_true={vi=true}}
+ defaults={if_true=true}
},
{
full_name='modified', abbreviation='mod',
short_desc=N_("buffer has been modified"),
type='bool', scope={'buffer'},
no_mkrc=true,
- vi_def=true,
redraw={'statuslines'},
varname='p_mod',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='more',
short_desc=N_("listings when the whole screen is filled"),
type='bool', scope={'global'},
- vim=true,
varname='p_more',
- defaults={if_true={vi=false, vim=true}}
+ defaults={if_true=true}
},
{
full_name='mouse',
short_desc=N_("the use of mouse clicks"),
type='string', list='flags', scope={'global'},
varname='p_mouse',
- defaults={if_true={vi="", vim=""}}
+ defaults={if_true=""}
},
{
full_name='mousefocus', abbreviation='mousef',
short_desc=N_("keyboard focus follows the mouse"),
type='bool', scope={'global'},
- vi_def=true,
redraw={'ui_option'},
varname='p_mousef',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='mousehide', abbreviation='mh',
short_desc=N_("hide mouse pointer while typing"),
type='bool', scope={'global'},
- vi_def=true,
enable_if=false,
- defaults={if_true={vi=true}}
+ defaults={if_true=true}
},
{
full_name='mousemodel', abbreviation='mousem',
short_desc=N_("changes meaning of mouse buttons"),
type='string', scope={'global'},
- vi_def=true,
varname='p_mousem',
- defaults={if_true={vi="extend"}}
+ defaults={if_true="extend"}
},
{
full_name='mouseshape', abbreviation='mouses',
short_desc=N_("shape of the mouse pointer in different modes"),
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
- vi_def=true,
enable_if=false,
},
{
full_name='mousetime', abbreviation='mouset',
short_desc=N_("max time between mouse double-click"),
type='number', scope={'global'},
- vi_def=true,
varname='p_mouset',
- defaults={if_true={vi=500}}
+ defaults={if_true=500}
},
{
full_name='nrformats', abbreviation='nf',
@@ -1829,50 +1625,45 @@ return {
deny_duplicates=true,
alloced=true,
varname='p_nf',
- defaults={if_true={vi="bin,octal,hex", vim="bin,hex"}}
+ defaults={if_true="bin,hex"}
},
{
full_name='number', abbreviation='nu',
short_desc=N_("print the line number in front of each line"),
type='bool', scope={'window'},
- vi_def=true,
redraw={'current_window'},
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='numberwidth', abbreviation='nuw',
short_desc=N_("number of columns used for the line number"),
type='number', scope={'window'},
- vim=true,
redraw={'current_window'},
- defaults={if_true={vi=8, vim=4}}
+ defaults={if_true=4}
},
{
full_name='omnifunc', abbreviation='ofu',
short_desc=N_("function for filetype-specific completion"),
type='string', scope={'buffer'},
secure=true,
- vi_def=true,
alloced=true,
varname='p_ofu',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='opendevice', abbreviation='odev',
short_desc=N_("allow reading/writing devices on MS-Windows"),
type='bool', scope={'global'},
- vi_def=true,
enable_if=false,
- defaults={if_true={vi=false, vim=false}}
+ defaults={if_true=false}
},
{
full_name='operatorfunc', abbreviation='opfunc',
short_desc=N_("function to be called for |g@| operator"),
type='string', scope={'global'},
secure=true,
- vi_def=true,
varname='p_opfunc',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='packpath', abbreviation='pp',
@@ -1880,320 +1671,280 @@ return {
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
secure=true,
- vi_def=true,
expand=true,
varname='p_pp',
- defaults={if_true={vi=''}}
+ defaults={if_true=''}
},
{
full_name='paragraphs', abbreviation='para',
short_desc=N_("nroff macros that separate paragraphs"),
type='string', scope={'global'},
- vi_def=true,
varname='p_para',
- defaults={if_true={vi="IPLPPPQPP TPHPLIPpLpItpplpipbp"}}
+ defaults={if_true="IPLPPPQPP TPHPLIPpLpItpplpipbp"}
},
{
full_name='paste',
short_desc=N_("pasting text"),
type='bool', scope={'global'},
pri_mkrc=true,
- vi_def=true,
varname='p_paste',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='pastetoggle', abbreviation='pt',
short_desc=N_("key code that causes 'paste' to toggle"),
type='string', scope={'global'},
- vi_def=true,
varname='p_pt',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='patchexpr', abbreviation='pex',
short_desc=N_("expression used to patch a file"),
type='string', scope={'global'},
secure=true,
- vi_def=true,
varname='p_pex',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='patchmode', abbreviation='pm',
short_desc=N_("keep the oldest version of a file"),
type='string', scope={'global'},
normal_fname_chars=true,
- vi_def=true,
varname='p_pm',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='path', abbreviation='pa',
short_desc=N_("list of directories searched with \"gf\" et.al."),
type='string', list='comma', scope={'global', 'buffer'},
deny_duplicates=true,
- vi_def=true,
expand=true,
varname='p_path',
- defaults={if_true={vi=".,/usr/include,,"}}
+ defaults={if_true=".,/usr/include,,"}
},
{
full_name='preserveindent', abbreviation='pi',
short_desc=N_("preserve the indent structure when reindenting"),
type='bool', scope={'buffer'},
- vi_def=true,
- vim=true,
varname='p_pi',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='previewheight', abbreviation='pvh',
short_desc=N_("height of the preview window"),
type='number', scope={'global'},
- vi_def=true,
varname='p_pvh',
- defaults={if_true={vi=12}}
+ defaults={if_true=12}
},
{
full_name='previewwindow', abbreviation='pvw',
short_desc=N_("identifies the preview window"),
type='bool', scope={'window'},
noglob=true,
- vi_def=true,
redraw={'statuslines'},
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='printdevice', abbreviation='pdev',
short_desc=N_("name of the printer to be used for :hardcopy"),
type='string', scope={'global'},
secure=true,
- vi_def=true,
varname='p_pdev',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='printencoding', abbreviation='penc',
short_desc=N_("encoding to be used for printing"),
type='string', scope={'global'},
- vi_def=true,
varname='p_penc',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='printexpr', abbreviation='pexpr',
short_desc=N_("expression used to print PostScript for :hardcopy"),
type='string', scope={'global'},
secure=true,
- vi_def=true,
varname='p_pexpr',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='printfont', abbreviation='pfn',
short_desc=N_("name of the font to be used for :hardcopy"),
type='string', scope={'global'},
- vi_def=true,
varname='p_pfn',
- defaults={if_true={vi="courier"}}
+ defaults={if_true="courier"}
},
{
full_name='printheader', abbreviation='pheader',
short_desc=N_("format of the header used for :hardcopy"),
type='string', scope={'global'},
- vi_def=true,
varname='p_header',
- defaults={if_true={vi="%<%f%h%m%=Page %N"}}
+ defaults={if_true="%<%f%h%m%=Page %N"}
},
{
full_name='printmbcharset', abbreviation='pmbcs',
short_desc=N_("CJK character set to be used for :hardcopy"),
type='string', scope={'global'},
- vi_def=true,
varname='p_pmcs',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='printmbfont', abbreviation='pmbfn',
short_desc=N_("font names to be used for CJK output of :hardcopy"),
type='string', scope={'global'},
- vi_def=true,
varname='p_pmfn',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='printoptions', abbreviation='popt',
short_desc=N_("controls the format of :hardcopy output"),
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
- vi_def=true,
varname='p_popt',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='prompt',
short_desc=N_("enable prompt in Ex mode"),
type='bool', scope={'global'},
- vi_def=true,
- varname='p_prompt',
- defaults={if_true={vi=true}}
+ varname='p_force_on',
+ defaults={if_true=true}
},
{
full_name='pumblend', abbreviation='pb',
short_desc=N_("Controls transparency level of popup menu"),
type='number', scope={'global'},
- vi_def=true,
redraw={'ui_option'},
varname='p_pb',
- defaults={if_true={vi=0}}
+ defaults={if_true=0}
},
{
full_name='pumheight', abbreviation='ph',
short_desc=N_("maximum height of the popup menu"),
type='number', scope={'global'},
- vi_def=true,
varname='p_ph',
- defaults={if_true={vi=0}}
+ defaults={if_true=0}
},
{
full_name='pumwidth', abbreviation='pw',
short_desc=N_("minimum width of the popup menu"),
type='number', scope={'global'},
- vi_def=true,
varname='p_pw',
- defaults={if_true={vi=15}}
+ defaults={if_true=15}
},
{
full_name='pyxversion', abbreviation='pyx',
short_desc=N_("selects default python version to use"),
type='number', scope={'global'},
secure=true,
- vi_def=true,
varname='p_pyx',
- defaults={if_true={vi=0}}
+ defaults={if_true=0}
},
{
full_name='quickfixtextfunc', abbreviation='qftf',
short_desc=N_("customize the quickfix window"),
type='string', scope={'global'},
- vi_def=true,
varname='p_qftf',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='quoteescape', abbreviation='qe',
short_desc=N_("escape characters used in a string"),
type='string', scope={'buffer'},
- vi_def=true,
alloced=true,
varname='p_qe',
- defaults={if_true={vi="\\"}}
+ defaults={if_true="\\"}
},
{
full_name='readonly', abbreviation='ro',
short_desc=N_("disallow writing the buffer"),
type='bool', scope={'buffer'},
noglob=true,
- vi_def=true,
redraw={'statuslines'},
varname='p_ro',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='redrawdebug', abbreviation='rdb',
short_desc=N_("Changes the way redrawing works (debug)"),
type='string', list='onecomma', scope={'global'},
- vi_def=true,
varname='p_rdb',
- defaults={if_true={vi=''}}
+ defaults={if_true=''}
},
{
full_name='redrawtime', abbreviation='rdt',
short_desc=N_("timeout for 'hlsearch' and |:match| highlighting"),
type='number', scope={'global'},
- vi_def=true,
varname='p_rdt',
- defaults={if_true={vi=2000}}
+ defaults={if_true=2000}
},
{
full_name='regexpengine', abbreviation='re',
short_desc=N_("default regexp engine to use"),
type='number', scope={'global'},
- vi_def=true,
varname='p_re',
- defaults={if_true={vi=0}}
+ defaults={if_true=0}
},
{
full_name='relativenumber', abbreviation='rnu',
short_desc=N_("show relative line number in front of each line"),
type='bool', scope={'window'},
- vi_def=true,
redraw={'current_window'},
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='remap',
short_desc=N_("mappings to work recursively"),
type='bool', scope={'global'},
- vi_def=true,
varname='p_remap',
- defaults={if_true={vi=true}}
+ defaults={if_true=true}
},
{
full_name='report',
short_desc=N_("for reporting nr. of lines changed"),
type='number', scope={'global'},
- vi_def=true,
varname='p_report',
- defaults={if_true={vi=2}}
+ defaults={if_true=2}
},
{
full_name='revins', abbreviation='ri',
short_desc=N_("inserting characters will work backwards"),
type='bool', scope={'global'},
- vi_def=true,
- vim=true,
varname='p_ri',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='rightleft', abbreviation='rl',
short_desc=N_("window is right-to-left oriented"),
type='bool', scope={'window'},
- vi_def=true,
redraw={'current_window'},
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='rightleftcmd', abbreviation='rlc',
short_desc=N_("commands for which editing works right-to-left"),
type='string', scope={'window'},
- vi_def=true,
alloced=true,
redraw={'current_window'},
- defaults={if_true={vi="search"}}
+ defaults={if_true="search"}
},
{
full_name='ruler', abbreviation='ru',
short_desc=N_("show cursor line and column in the status line"),
type='bool', scope={'global'},
- vi_def=true,
- vim=true,
redraw={'statuslines'},
varname='p_ru',
- defaults={if_true={vi=true}}
+ defaults={if_true=true}
},
{
full_name='rulerformat', abbreviation='ruf',
short_desc=N_("custom format for the ruler"),
type='string', scope={'global'},
- vi_def=true,
alloced=true,
modelineexpr=true,
redraw={'statuslines'},
varname='p_ruf',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='runtimepath', abbreviation='rtp',
@@ -2201,110 +1952,93 @@ return {
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
secure=true,
- vi_def=true,
expand='nodefault',
varname='p_rtp',
- defaults={if_true={vi=''}}
+ defaults={if_true=''}
},
{
full_name='scroll', abbreviation='scr',
short_desc=N_("lines to scroll with CTRL-U and CTRL-D"),
type='number', scope={'window'},
no_mkrc=true,
- vi_def=true,
pv_name='p_scroll',
- defaults={if_true={vi=0}}
+ defaults={if_true=0}
},
{
full_name='scrollback', abbreviation='scbk',
short_desc=N_("lines to scroll with CTRL-U and CTRL-D"),
type='number', scope={'buffer'},
- vi_def=true,
varname='p_scbk',
redraw={'current_buffer'},
- defaults={if_true={vi=-1}}
+ defaults={if_true=-1}
},
{
full_name='scrollbind', abbreviation='scb',
short_desc=N_("scroll in window as other windows scroll"),
type='bool', scope={'window'},
- vi_def=true,
pv_name='p_scbind',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='scrolljump', abbreviation='sj',
short_desc=N_("minimum number of lines to scroll"),
type='number', scope={'global'},
- vi_def=true,
- vim=true,
varname='p_sj',
- defaults={if_true={vi=1}}
+ defaults={if_true=1}
},
{
full_name='scrolloff', abbreviation='so',
short_desc=N_("minimum nr. of lines above and below cursor"),
type='number', scope={'global', 'window'},
- vi_def=true,
- vim=true,
redraw={'all_windows'},
varname='p_so',
- defaults={if_true={vi=0}}
+ defaults={if_true=0}
},
{
full_name='scrollopt', abbreviation='sbo',
short_desc=N_("how 'scrollbind' should behave"),
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
- vi_def=true,
varname='p_sbo',
- defaults={if_true={vi="ver,jump"}}
+ defaults={if_true="ver,jump"}
},
{
full_name='sections', abbreviation='sect',
short_desc=N_("nroff macros that separate sections"),
type='string', scope={'global'},
- vi_def=true,
varname='p_sections',
- defaults={if_true={vi="SHNHH HUnhsh"}}
+ defaults={if_true="SHNHH HUnhsh"}
},
{
full_name='secure',
short_desc=N_("mode for reading .vimrc in current dir"),
type='bool', scope={'global'},
secure=true,
- vi_def=true,
varname='p_secure',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='selection', abbreviation='sel',
short_desc=N_("what type of selection to use"),
type='string', scope={'global'},
- vi_def=true,
varname='p_sel',
- defaults={if_true={vi="inclusive"}}
+ defaults={if_true="inclusive"}
},
{
full_name='selectmode', abbreviation='slm',
short_desc=N_("when to use Select mode instead of Visual mode"),
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
- vi_def=true,
varname='p_slm',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='sessionoptions', abbreviation='ssop',
short_desc=N_("options for |:mksession|"),
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
- vim=true,
varname='p_ssop',
- defaults={if_true={
- vi="blank,buffers,curdir,folds,help,options,tabpages,winsize",
- vim="blank,buffers,curdir,folds,help,tabpages,winsize"
- }}
+ defaults={if_true="blank,buffers,curdir,folds,help,tabpages,winsize"}
},
{
full_name='shada', abbreviation='sd',
@@ -2313,31 +2047,29 @@ return {
deny_duplicates=true,
secure=true,
varname='p_shada',
- defaults={if_true={vi="", vim="!,'100,<50,s10,h"}}
+ defaults={if_true="!,'100,<50,s10,h"}
},
{
full_name='shadafile', abbreviation='sdf',
short_desc=N_("overrides the filename used for shada"),
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
- vi_def=true,
secure=true,
expand=true,
varname='p_shadafile',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='shell', abbreviation='sh',
short_desc=N_("name of shell to use for external commands"),
type='string', scope={'global'},
secure=true,
- vi_def=true,
expand=true,
varname='p_sh',
defaults={
condition='WIN32',
- if_true={vi="cmd.exe"},
- if_false={vi="sh"}
+ if_true="cmd.exe",
+ if_false="sh"
}
},
{
@@ -2345,12 +2077,11 @@ return {
short_desc=N_("flag to shell to execute one command"),
type='string', scope={'global'},
secure=true,
- vi_def=true,
varname='p_shcf',
defaults={
condition='WIN32',
- if_true={vi="/s /c"},
- if_false={vi="-c"}
+ if_true="/s /c",
+ if_false="-c"
}
},
{
@@ -2358,12 +2089,11 @@ return {
short_desc=N_("string to put output of \":make\" in error file"),
type='string', scope={'global'},
secure=true,
- vi_def=true,
varname='p_sp',
defaults={
condition='WIN32',
- if_true={vi=">%s 2>&1"},
- if_false={vi="| tee"},
+ if_true=">%s 2>&1",
+ if_false="| tee",
}
},
{
@@ -2371,50 +2101,46 @@ return {
short_desc=N_("quote character(s) for around shell command"),
type='string', scope={'global'},
secure=true,
- vi_def=true,
varname='p_shq',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='shellredir', abbreviation='srr',
short_desc=N_("string to put output of filter in a temp file"),
type='string', scope={'global'},
secure=true,
- vi_def=true,
varname='p_srr',
defaults={
condition='WIN32',
- if_true={vi=">%s 2>&1"},
- if_false={vi=">"}
+ if_true=">%s 2>&1",
+ if_false=">"
}
},
{
full_name='shellslash', abbreviation='ssl',
short_desc=N_("use forward slash for shell file names"),
type='bool', scope={'global'},
- vi_def=true,
varname='p_ssl',
enable_if='BACKSLASH_IN_FILENAME',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='shelltemp', abbreviation='stmp',
short_desc=N_("whether to use a temp file for shell commands"),
type='bool', scope={'global'},
varname='p_stmp',
- defaults={if_true={vi=false, vim=true}}
+ defaults={if_true=true}
},
{
full_name='shellxquote', abbreviation='sxq',
short_desc=N_("like 'shellquote', but include redirection"),
type='string', scope={'global'},
secure=true,
- vi_def=true,
varname='p_sxq',
defaults={
condition='WIN32',
- if_true={vi="\""},
- if_false={vi=""},
+ if_true="\"",
+ if_false="",
}
},
{
@@ -2422,164 +2148,140 @@ return {
short_desc=N_("characters to escape when 'shellxquote' is ("),
type='string', scope={'global'},
secure=true,
- vi_def=true,
varname='p_sxe',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='shiftround', abbreviation='sr',
short_desc=N_("round indent to multiple of shiftwidth"),
type='bool', scope={'global'},
- vi_def=true,
- vim=true,
varname='p_sr',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='shiftwidth', abbreviation='sw',
short_desc=N_("number of spaces to use for (auto)indent step"),
type='number', scope={'buffer'},
- vi_def=true,
varname='p_sw',
- defaults={if_true={vi=8}}
+ defaults={if_true=8}
},
{
full_name='shortmess', abbreviation='shm',
short_desc=N_("list of flags, reduce length of messages"),
type='string', list='flags', scope={'global'},
- vim=true,
varname='p_shm',
- defaults={if_true={vi="S", vim="filnxtToOF"}}
+ defaults={if_true="filnxtToOF"}
},
{
full_name='showbreak', abbreviation='sbr',
short_desc=N_("string to use at the start of wrapped lines"),
- type='string', scope={'global'},
- vi_def=true,
+ type='string', scope={'global', 'window'},
redraw={'all_windows'},
varname='p_sbr',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='showcmd', abbreviation='sc',
short_desc=N_("show (partial) command in status line"),
type='bool', scope={'global'},
- vim=true,
varname='p_sc',
- defaults={if_true={vi=false, vim=true}}
+ defaults={if_true=true}
},
{
full_name='showfulltag', abbreviation='sft',
short_desc=N_("show full tag pattern when completing tag"),
type='bool', scope={'global'},
- vi_def=true,
varname='p_sft',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='showmatch', abbreviation='sm',
short_desc=N_("briefly jump to matching bracket if insert one"),
type='bool', scope={'global'},
- vi_def=true,
varname='p_sm',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='showmode', abbreviation='smd',
short_desc=N_("message on status line to show current mode"),
type='bool', scope={'global'},
- vim=true,
varname='p_smd',
- defaults={if_true={vi=false, vim=true}}
+ defaults={if_true=true}
},
{
full_name='showtabline', abbreviation='stal',
short_desc=N_("tells when the tab pages line is displayed"),
type='number', scope={'global'},
- vi_def=true,
redraw={'all_windows', 'ui_option'},
varname='p_stal',
- defaults={if_true={vi=1}}
+ defaults={if_true=1}
},
{
full_name='sidescroll', abbreviation='ss',
short_desc=N_("minimum number of columns to scroll horizontal"),
type='number', scope={'global'},
- vi_def=true,
varname='p_ss',
- defaults={if_true={vi=1}}
+ defaults={if_true=1}
},
{
full_name='sidescrolloff', abbreviation='siso',
short_desc=N_("min. nr. of columns to left and right of cursor"),
type='number', scope={'global', 'window'},
- vi_def=true,
- vim=true,
redraw={'all_windows'},
varname='p_siso',
- defaults={if_true={vi=0}}
+ defaults={if_true=0}
},
{
full_name='signcolumn', abbreviation='scl',
short_desc=N_("when to display the sign column"),
type='string', scope={'window'},
- vi_def=true,
alloced=true,
redraw={'current_window'},
- defaults={if_true={vi="auto"}}
+ defaults={if_true="auto"}
},
{
full_name='smartcase', abbreviation='scs',
short_desc=N_("no ignore case when pattern has uppercase"),
type='bool', scope={'global'},
- vi_def=true,
- vim=true,
varname='p_scs',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='smartindent', abbreviation='si',
short_desc=N_("smart autoindenting for C programs"),
type='bool', scope={'buffer'},
- vi_def=true,
- vim=true,
varname='p_si',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='smarttab', abbreviation='sta',
short_desc=N_("use 'shiftwidth' when inserting <Tab>"),
type='bool', scope={'global'},
- vim=true,
varname='p_sta',
- defaults={if_true={vi=false, vim=true}}
+ defaults={if_true=true}
},
{
full_name='softtabstop', abbreviation='sts',
short_desc=N_("number of spaces that <Tab> uses while editing"),
type='number', scope={'buffer'},
- vi_def=true,
- vim=true,
varname='p_sts',
- defaults={if_true={vi=0}}
+ defaults={if_true=0}
},
{
full_name='spell',
short_desc=N_("spell checking"),
type='bool', scope={'window'},
- vi_def=true,
redraw={'current_window'},
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='spellcapcheck', abbreviation='spc',
short_desc=N_("pattern to locate end of a sentence"),
type='string', scope={'buffer'},
- vi_def=true,
alloced=true,
redraw={'current_buffer'},
varname='p_spc',
- defaults={if_true={vi="[.?!]\\_[\\])'\" ]\\+"}}
+ defaults={if_true="[.?!]\\_[\\])'\" ]\\+"}
},
{
full_name='spellfile', abbreviation='spf',
@@ -2587,23 +2289,21 @@ return {
type='string', list='onecomma', scope={'buffer'},
deny_duplicates=true,
secure=true,
- vi_def=true,
alloced=true,
expand=true,
varname='p_spf',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='spelllang', abbreviation='spl',
short_desc=N_("language(s) to do spell checking for"),
type='string', list='onecomma', scope={'buffer'},
deny_duplicates=true,
- vi_def=true,
alloced=true,
expand=true,
redraw={'current_buffer'},
varname='p_spl',
- defaults={if_true={vi="en"}}
+ defaults={if_true="en"}
},
{
full_name='spellsuggest', abbreviation='sps',
@@ -2611,102 +2311,91 @@ return {
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
secure=true,
- vi_def=true,
expand=true,
varname='p_sps',
- defaults={if_true={vi="best"}}
+ defaults={if_true="best"}
},
{
full_name='spelloptions', abbreviation='spo',
type='string', list='onecomma', scope={'buffer'},
deny_duplicates=true,
secure=true,
- vi_def=true,
expand=true,
varname='p_spo',
- defaults={if_true={vi="", vim=""}}
+ defaults={if_true=""}
},
{
full_name='splitbelow', abbreviation='sb',
short_desc=N_("new window from split is below the current one"),
type='bool', scope={'global'},
- vi_def=true,
varname='p_sb',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='splitright', abbreviation='spr',
short_desc=N_("new window is put right of the current one"),
type='bool', scope={'global'},
- vi_def=true,
varname='p_spr',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='startofline', abbreviation='sol',
short_desc=N_("commands move cursor to first non-blank in line"),
type='bool', scope={'global'},
- vi_def=true,
vim=false,
varname='p_sol',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='statusline', abbreviation='stl',
short_desc=N_("custom format for the status line"),
type='string', scope={'global', 'window'},
- vi_def=true,
alloced=true,
modelineexpr=true,
redraw={'statuslines'},
varname='p_stl',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='suffixes', abbreviation='su',
short_desc=N_("suffixes that are ignored with multiple match"),
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
- vi_def=true,
varname='p_su',
- defaults={if_true={vi=".bak,~,.o,.h,.info,.swp,.obj"}}
+ defaults={if_true=".bak,~,.o,.h,.info,.swp,.obj"}
},
{
full_name='suffixesadd', abbreviation='sua',
short_desc=N_("suffixes added when searching for a file"),
type='string', list='onecomma', scope={'buffer'},
deny_duplicates=true,
- vi_def=true,
alloced=true,
varname='p_sua',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='swapfile', abbreviation='swf',
short_desc=N_("whether to use a swapfile for a buffer"),
type='bool', scope={'buffer'},
- vi_def=true,
redraw={'statuslines'},
varname='p_swf',
- defaults={if_true={vi=true}}
+ defaults={if_true=true}
},
{
full_name='switchbuf', abbreviation='swb',
short_desc=N_("sets behavior when switching to another buffer"),
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
- vi_def=true,
varname='p_swb',
- defaults={if_true={vi=""}}
+ defaults={if_true="uselast"}
},
{
full_name='synmaxcol', abbreviation='smc',
short_desc=N_("maximum column to find syntax items"),
type='number', scope={'buffer'},
- vi_def=true,
redraw={'current_buffer'},
varname='p_smc',
- defaults={if_true={vi=3000}}
+ defaults={if_true=3000}
},
{
full_name='syntax', abbreviation='syn',
@@ -2714,146 +2403,127 @@ return {
type='string', scope={'buffer'},
noglob=true,
normal_fname_chars=true,
- vi_def=true,
alloced=true,
varname='p_syn',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='tagfunc', abbreviation='tfu',
short_desc=N_("function used to perform tag searches"),
type='string', scope={'buffer'},
- vim=true,
- vi_def=true,
varname='p_tfu',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='tabline', abbreviation='tal',
short_desc=N_("custom format for the console tab pages line"),
type='string', scope={'global'},
- vi_def=true,
modelineexpr=true,
redraw={'all_windows'},
varname='p_tal',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='tabpagemax', abbreviation='tpm',
short_desc=N_("maximum number of tab pages for |-p| and \"tab all\""),
type='number', scope={'global'},
- vim=true,
varname='p_tpm',
- defaults={if_true={vi=10, vim=50}}
+ defaults={if_true=50}
},
{
full_name='tabstop', abbreviation='ts',
short_desc=N_("number of spaces that <Tab> in file uses"),
type='number', scope={'buffer'},
- vi_def=true,
redraw={'current_buffer'},
varname='p_ts',
- defaults={if_true={vi=8}}
+ defaults={if_true=8}
},
{
full_name='tagbsearch', abbreviation='tbs',
short_desc=N_("use binary searching in tags files"),
type='bool', scope={'global'},
- vi_def=true,
varname='p_tbs',
- defaults={if_true={vi=true}}
+ defaults={if_true=true}
},
{
full_name='tagcase', abbreviation='tc',
short_desc=N_("how to handle case when searching in tags files"),
type='string', scope={'global', 'buffer'},
- vim=true,
varname='p_tc',
- defaults={if_true={vi="followic", vim="followic"}}
+ defaults={if_true="followic"}
},
{
full_name='taglength', abbreviation='tl',
short_desc=N_("number of significant characters for a tag"),
type='number', scope={'global'},
- vi_def=true,
varname='p_tl',
- defaults={if_true={vi=0}}
+ defaults={if_true=0}
},
{
full_name='tagrelative', abbreviation='tr',
short_desc=N_("file names in tag file are relative"),
type='bool', scope={'global'},
- vim=true,
varname='p_tr',
- defaults={if_true={vi=false, vim=true}}
+ defaults={if_true=true}
},
{
full_name='tags', abbreviation='tag',
short_desc=N_("list of file names used by the tag command"),
type='string', list='onecomma', scope={'global', 'buffer'},
deny_duplicates=true,
- vi_def=true,
expand=true,
varname='p_tags',
- defaults={if_true={vi="./tags;,tags"}}
+ defaults={if_true="./tags;,tags"}
},
{
full_name='tagstack', abbreviation='tgst',
short_desc=N_("push tags onto the tag stack"),
type='bool', scope={'global'},
- vi_def=true,
varname='p_tgst',
- defaults={if_true={vi=true}}
+ defaults={if_true=true}
},
{
full_name='termbidi', abbreviation='tbidi',
short_desc=N_("terminal takes care of bi-directionality"),
type='bool', scope={'global'},
- vi_def=true,
varname='p_tbidi',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='termencoding', abbreviation='tenc',
short_desc=N_("Terminal encodig"),
type='string', scope={'global'},
- vi_def=true,
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='termguicolors', abbreviation='tgc',
short_desc=N_("Terminal true color support"),
type='bool', scope={'global'},
- vi_def=false,
redraw={'ui_option'},
varname='p_tgc',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='termpastefilter', abbreviation='tpf',
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
- vim=true,
varname='p_tpf',
- defaults={if_true={vi="", vim="BS,HT,ESC,DEL"}}
+ defaults={if_true="BS,HT,ESC,DEL"}
},
{
full_name='terse',
short_desc=N_("hides notification of search wrap"),
type='bool', scope={'global'},
- vi_def=true,
varname='p_terse',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='textwidth', abbreviation='tw',
short_desc=N_("maximum width of text that is being inserted"),
type='number', scope={'buffer'},
- vi_def=true,
- vim=true,
redraw={'current_buffer'},
varname='p_tw',
- defaults={if_true={vi=0}}
+ defaults={if_true=0}
},
{
full_name='thesaurus', abbreviation='tsr',
@@ -2861,51 +2531,44 @@ return {
type='string', list='onecomma', scope={'global', 'buffer'},
deny_duplicates=true,
normal_dname_chars=true,
- vi_def=true,
expand=true,
varname='p_tsr',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='tildeop', abbreviation='top',
short_desc=N_("tilde command \"~\" behaves like an operator"),
type='bool', scope={'global'},
- vi_def=true,
- vim=true,
varname='p_to',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='timeout', abbreviation='to',
short_desc=N_("time out on mappings and key codes"),
type='bool', scope={'global'},
- vi_def=true,
varname='p_timeout',
- defaults={if_true={vi=true}}
+ defaults={if_true=true}
},
{
full_name='timeoutlen', abbreviation='tm',
short_desc=N_("time out time in milliseconds"),
type='number', scope={'global'},
- vi_def=true,
varname='p_tm',
- defaults={if_true={vi=1000}}
+ defaults={if_true=1000}
},
{
full_name='title',
short_desc=N_("Vim set the title of the window"),
type='bool', scope={'global'},
- vi_def=true,
varname='p_title',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='titlelen',
short_desc=N_("of 'columns' used for window title"),
type='number', scope={'global'},
- vi_def=true,
varname='p_titlelen',
- defaults={if_true={vi=85}}
+ defaults={if_true=85}
},
{
full_name='titleold',
@@ -2913,46 +2576,40 @@ return {
type='string', scope={'global'},
secure=true,
no_mkrc=true,
- vi_def=true,
varname='p_titleold',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='titlestring',
short_desc=N_("to use for the Vim window title"),
type='string', scope={'global'},
- vi_def=true,
modelineexpr=true,
varname='p_titlestring',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='ttimeout',
short_desc=N_("out on mappings"),
type='bool', scope={'global'},
- vi_def=true,
- vim=true,
redraw={'ui_option'},
varname='p_ttimeout',
- defaults={if_true={vi=true}}
+ defaults={if_true=true}
},
{
full_name='ttimeoutlen', abbreviation='ttm',
short_desc=N_("time out time for key codes in milliseconds"),
type='number', scope={'global'},
- vi_def=true,
redraw={'ui_option'},
varname='p_ttm',
- defaults={if_true={vi=50}}
+ defaults={if_true=50}
},
{
full_name='ttyfast', abbreviation='tf',
short_desc=N_("No description"),
type='bool', scope={'global'},
no_mkrc=true,
- vi_def=true,
varname='p_force_on',
- defaults={if_true={vi=true}}
+ defaults={if_true=true}
},
{
full_name='undodir', abbreviation='udir',
@@ -2960,105 +2617,92 @@ return {
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
secure=true,
- vi_def=true,
expand='nodefault',
varname='p_udir',
- defaults={if_true={vi=''}}
+ defaults={if_true=''}
},
{
full_name='undofile', abbreviation='udf',
short_desc=N_("save undo information in a file"),
type='bool', scope={'buffer'},
- vi_def=true,
- vim=true,
varname='p_udf',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='undolevels', abbreviation='ul',
short_desc=N_("maximum number of changes that can be undone"),
type='number', scope={'global', 'buffer'},
- vi_def=true,
varname='p_ul',
- defaults={if_true={vi=1000}}
+ defaults={if_true=1000}
},
{
full_name='undoreload', abbreviation='ur',
short_desc=N_("max nr of lines to save for undo on a buffer reload"),
type='number', scope={'global'},
- vi_def=true,
varname='p_ur',
- defaults={if_true={vi=10000}}
+ defaults={if_true=10000}
},
{
full_name='updatecount', abbreviation='uc',
short_desc=N_("after this many characters flush swap file"),
type='number', scope={'global'},
- vi_def=true,
varname='p_uc',
- defaults={if_true={vi=200}}
+ defaults={if_true=200}
},
{
full_name='updatetime', abbreviation='ut',
short_desc=N_("after this many milliseconds flush swap file"),
type='number', scope={'global'},
- vi_def=true,
varname='p_ut',
- defaults={if_true={vi=4000}}
+ defaults={if_true=4000}
},
{
full_name='varsofttabstop', abbreviation='vsts',
short_desc=N_("list of numbers of spaces that <Tab> uses while editing"),
type='string', list='comma', scope={'buffer'},
- vi_def=true,
varname='p_vsts',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='vartabstop', abbreviation='vts',
short_desc=N_("list of numbers of spaces that <Tab> in file uses"),
type='string', list='comma', scope={'buffer'},
- vi_def=true,
varname='p_vts',
redraw={'current_buffer'},
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='verbose', abbreviation='vbs',
short_desc=N_("give informative messages"),
type='number', scope={'global'},
- vi_def=true,
varname='p_verbose',
- defaults={if_true={vi=0}}
+ defaults={if_true=0}
},
{
full_name='verbosefile', abbreviation='vfile',
short_desc=N_("file to write messages in"),
type='string', scope={'global'},
secure=true,
- vi_def=true,
expand=true,
varname='p_vfile',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='viewdir', abbreviation='vdir',
short_desc=N_("directory where to store files with :mkview"),
type='string', scope={'global'},
secure=true,
- vi_def=true,
expand='nodefault',
varname='p_vdir',
- defaults={if_true={vi=''}}
+ defaults={if_true=''}
},
{
full_name='viewoptions', abbreviation='vop',
short_desc=N_("specifies what to save for :mkview"),
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
- vi_def=true,
varname='p_vop',
- defaults={if_true={vi="folds,options,cursor,curdir"}}
+ defaults={if_true="folds,cursor,curdir"}
},
{
-- Alias for "shada".
@@ -3077,232 +2721,202 @@ return {
short_desc=N_("when to use virtual editing"),
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
- vi_def=true,
- vim=true,
redraw={'curswant'},
varname='p_ve',
- defaults={if_true={vi="", vim=""}}
+ defaults={if_true=""}
},
{
full_name='visualbell', abbreviation='vb',
short_desc=N_("use visual bell instead of beeping"),
type='bool', scope={'global'},
- vi_def=true,
varname='p_vb',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='warn',
short_desc=N_("for shell command when buffer was changed"),
type='bool', scope={'global'},
- vi_def=true,
varname='p_warn',
- defaults={if_true={vi=true}}
+ defaults={if_true=true}
},
{
full_name='whichwrap', abbreviation='ww',
short_desc=N_("allow specified keys to cross line boundaries"),
type='string', list='flagscomma', scope={'global'},
- vim=true,
varname='p_ww',
- defaults={if_true={vi="", vim="b,s"}}
+ defaults={if_true="b,s"}
},
{
full_name='wildchar', abbreviation='wc',
short_desc=N_("command-line character for wildcard expansion"),
type='number', scope={'global'},
- vim=true,
varname='p_wc',
- defaults={if_true={vi=imacros('Ctrl_E'), vim=imacros('TAB')}}
+ defaults={if_true=imacros('TAB')}
},
{
full_name='wildcharm', abbreviation='wcm',
short_desc=N_("like 'wildchar' but also works when mapped"),
type='number', scope={'global'},
- vi_def=true,
varname='p_wcm',
- defaults={if_true={vi=0}}
+ defaults={if_true=0}
},
{
full_name='wildignore', abbreviation='wig',
short_desc=N_("files matching these patterns are not completed"),
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
- vi_def=true,
varname='p_wig',
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='wildignorecase', abbreviation='wic',
short_desc=N_("ignore case when completing file names"),
type='bool', scope={'global'},
- vi_def=true,
varname='p_wic',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='wildmenu', abbreviation='wmnu',
short_desc=N_("use menu for command line completion"),
type='bool', scope={'global'},
- vim=true,
varname='p_wmnu',
- defaults={if_true={vi=false, vim=true}}
+ defaults={if_true=true}
},
{
full_name='wildmode', abbreviation='wim',
short_desc=N_("mode for 'wildchar' command-line expansion"),
type='string', list='onecomma', scope={'global'},
deny_duplicates=false,
- vim=true,
varname='p_wim',
- defaults={if_true={vi="", vim="full"}}
+ defaults={if_true="full"}
},
{
full_name='wildoptions', abbreviation='wop',
short_desc=N_("specifies how command line completion is done"),
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
- vim=true,
varname='p_wop',
- defaults={if_true={vi='', vim='pum,tagfile'}}
+ defaults={if_true='pum,tagfile'}
},
{
full_name='winaltkeys', abbreviation='wak',
short_desc=N_("when the windows system handles ALT keys"),
type='string', scope={'global'},
- vi_def=true,
varname='p_wak',
- defaults={if_true={vi="menu"}}
+ defaults={if_true="menu"}
},
{
full_name='winblend', abbreviation='winbl',
short_desc=N_("Controls transparency level for floating windows"),
type='number', scope={'window'},
- vi_def=true,
redraw={'current_window'},
- defaults={if_true={vi=0}}
+ defaults={if_true=0}
},
{
full_name='winhighlight', abbreviation='winhl',
short_desc=N_("Setup window-local highlights");
type='string', scope={'window'},
- vi_def=true,
alloced=true,
redraw={'current_window'},
- defaults={if_true={vi=""}}
+ defaults={if_true=""}
},
{
full_name='window', abbreviation='wi',
short_desc=N_("nr of lines to scroll for CTRL-F and CTRL-B"),
type='number', scope={'global'},
- vi_def=true,
varname='p_window',
- defaults={if_true={vi=0}}
+ defaults={if_true=0}
},
{
full_name='winheight', abbreviation='wh',
short_desc=N_("minimum number of lines for the current window"),
type='number', scope={'global'},
- vi_def=true,
varname='p_wh',
- defaults={if_true={vi=1}}
+ defaults={if_true=1}
},
{
full_name='winfixheight', abbreviation='wfh',
short_desc=N_("keep window height when opening/closing windows"),
type='bool', scope={'window'},
- vi_def=true,
redraw={'statuslines'},
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='winfixwidth', abbreviation='wfw',
short_desc=N_("keep window width when opening/closing windows"),
type='bool', scope={'window'},
- vi_def=true,
redraw={'statuslines'},
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='winminheight', abbreviation='wmh',
short_desc=N_("minimum number of lines for any window"),
type='number', scope={'global'},
- vi_def=true,
varname='p_wmh',
- defaults={if_true={vi=1}}
+ defaults={if_true=1}
},
{
full_name='winminwidth', abbreviation='wmw',
short_desc=N_("minimal number of columns for any window"),
type='number', scope={'global'},
- vi_def=true,
varname='p_wmw',
- defaults={if_true={vi=1}}
+ defaults={if_true=1}
},
{
full_name='winwidth', abbreviation='wiw',
short_desc=N_("minimal number of columns for current window"),
type='number', scope={'global'},
- vi_def=true,
varname='p_wiw',
- defaults={if_true={vi=20}}
+ defaults={if_true=20}
},
{
full_name='wrap',
short_desc=N_("lines wrap and continue on the next line"),
type='bool', scope={'window'},
- vi_def=true,
redraw={'current_window'},
- defaults={if_true={vi=true}}
+ defaults={if_true=true}
},
{
full_name='wrapmargin', abbreviation='wm',
short_desc=N_("chars from the right where wrapping starts"),
type='number', scope={'buffer'},
- vi_def=true,
varname='p_wm',
- defaults={if_true={vi=0}}
+ defaults={if_true=0}
},
{
full_name='wrapscan', abbreviation='ws',
short_desc=N_("searches wrap around the end of the file"),
type='bool', scope={'global'},
- vi_def=true,
varname='p_ws',
- defaults={if_true={vi=true}}
+ defaults={if_true=true}
},
{
full_name='write',
short_desc=N_("to a file is allowed"),
type='bool', scope={'global'},
- vi_def=true,
varname='p_write',
- defaults={if_true={vi=true}}
+ defaults={if_true=true}
},
{
full_name='writeany', abbreviation='wa',
short_desc=N_("write to file with no need for \"!\" override"),
type='bool', scope={'global'},
- vi_def=true,
varname='p_wa',
- defaults={if_true={vi=false}}
+ defaults={if_true=false}
},
{
full_name='writebackup', abbreviation='wb',
short_desc=N_("make a backup before overwriting a file"),
type='bool', scope={'global'},
- vi_def=true,
- vim=true,
varname='p_wb',
- defaults={if_true={vi=true}}
+ defaults={if_true=true}
},
{
full_name='writedelay', abbreviation='wd',
short_desc=N_("delay this many msec for each char (for debug)"),
type='number', scope={'global'},
- vi_def=true,
varname='p_wd',
- defaults={if_true={vi=0}}
+ defaults={if_true=0}
},
}
}
diff --git a/src/nvim/os/dl.c b/src/nvim/os/dl.c
index 8483d316f3..b2e3994d10 100644
--- a/src/nvim/os/dl.c
+++ b/src/nvim/os/dl.c
@@ -7,10 +7,10 @@
#include <stdint.h>
#include <uv.h>
-#include "nvim/os/dl.h"
-#include "nvim/os/os.h"
#include "nvim/memory.h"
#include "nvim/message.h"
+#include "nvim/os/dl.h"
+#include "nvim/os/os.h"
/// possible function prototypes that can be called by os_libcall()
/// int -> int
@@ -38,12 +38,8 @@ typedef int (*int_int_fn)(int i);
/// not NULL. NULL when using `int_out`.
/// @param[out] int_out the output integer param
/// @return true on success, false on failure
-bool os_libcall(const char *libname,
- const char *funcname,
- const char *argv,
- int argi,
- char **str_out,
- int *int_out)
+bool os_libcall(const char *libname, const char *funcname, const char *argv, int argi,
+ char **str_out, int *int_out)
{
if (!libname || !funcname) {
return false;
@@ -53,17 +49,17 @@ bool os_libcall(const char *libname,
// open the dynamic loadable library
if (uv_dlopen(libname, &lib)) {
- EMSG2(_("dlerror = \"%s\""), uv_dlerror(&lib));
- uv_dlclose(&lib);
- return false;
+ EMSG2(_("dlerror = \"%s\""), uv_dlerror(&lib));
+ uv_dlclose(&lib);
+ return false;
}
// find and load the requested function in the library
gen_fn fn;
- if (uv_dlsym(&lib, funcname, (void **) &fn)) {
- EMSG2(_("dlerror = \"%s\""), uv_dlerror(&lib));
- uv_dlclose(&lib);
- return false;
+ if (uv_dlsym(&lib, funcname, (void **)&fn)) {
+ EMSG2(_("dlerror = \"%s\""), uv_dlerror(&lib));
+ uv_dlclose(&lib);
+ return false;
}
// call the library and save the result
@@ -71,17 +67,17 @@ bool os_libcall(const char *libname,
// exceptions. jmp's on Unix seem to interact trickily with signals as
// well. So for now we only support those libraries that are well-behaved.
if (str_out) {
- str_str_fn sfn = (str_str_fn) fn;
- int_str_fn ifn = (int_str_fn) fn;
+ str_str_fn sfn = (str_str_fn)fn;
+ int_str_fn ifn = (int_str_fn)fn;
const char *res = argv ? sfn(argv) : ifn(argi);
// assume that ptr values of NULL, 1 or -1 are illegal
- *str_out = (res && (intptr_t) res != 1 && (intptr_t) res != -1)
+ *str_out = (res && (intptr_t)res != 1 && (intptr_t)res != -1)
? xstrdup(res) : NULL;
} else {
- str_int_fn sfn = (str_int_fn) fn;
- int_int_fn ifn = (int_int_fn) fn;
+ str_int_fn sfn = (str_int_fn)fn;
+ int_int_fn ifn = (int_int_fn)fn;
*int_out = argv ? sfn(argv) : ifn(argi);
}
diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c
index 008f5ef63b..0f363ecfc3 100644
--- a/src/nvim/os/env.c
+++ b/src/nvim/os/env.c
@@ -6,41 +6,40 @@
#include <assert.h>
#include <uv.h>
-#include "nvim/vim.h"
#include "nvim/ascii.h"
#include "nvim/charset.h"
+#include "nvim/eval.h"
+#include "nvim/ex_getln.h"
#include "nvim/fileio.h"
-#include "nvim/os/os.h"
+#include "nvim/macros.h"
+#include "nvim/map.h"
#include "nvim/memory.h"
#include "nvim/message.h"
+#include "nvim/os/os.h"
#include "nvim/path.h"
-#include "nvim/macros.h"
#include "nvim/strings.h"
-#include "nvim/eval.h"
-#include "nvim/ex_getln.h"
#include "nvim/version.h"
-#include "nvim/map.h"
+#include "nvim/vim.h"
#ifdef WIN32
-#include "nvim/mbyte.h" // for utf8_to_utf16, utf16_to_utf8
+# include "nvim/mbyte.h" // for utf8_to_utf16, utf16_to_utf8
#endif
#ifdef HAVE__NSGETENVIRON
-#include <crt_externs.h>
+# include <crt_externs.h>
#endif
#ifdef HAVE_SYS_UTSNAME_H
-#include <sys/utsname.h>
+# include <sys/utsname.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;
+static PMap(cstr_t) envmap = MAP_INIT;
static uv_mutex_t mutex;
void env_init(void)
{
- envmap = pmap_new(cstr_t)();
uv_mutex_init(&mutex);
}
@@ -66,8 +65,8 @@ const char *os_getenv(const char *name)
}
uv_mutex_lock(&mutex);
int r = 0;
- if (pmap_has(cstr_t)(envmap, name)
- && !!(e = (char *)pmap_get(cstr_t)(envmap, name))) {
+ if (pmap_has(cstr_t)(&envmap, name)
+ && !!(e = (char *)pmap_get(cstr_t)(&envmap, name))) {
if (e[0] != '\0') {
// Found non-empty cached env var.
// NOTE: This risks incoherence if an in-process library changes the
@@ -75,7 +74,7 @@ const char *os_getenv(const char *name)
// that turns out to be a problem, we can just remove this codepath.
goto end;
}
- pmap_del2(envmap, name);
+ pmap_del2(&envmap, name);
}
e = xmalloc(size);
r = uv_os_getenv(name, e, &size);
@@ -88,7 +87,7 @@ const char *os_getenv(const char *name)
e = NULL;
goto end;
}
- pmap_put(cstr_t)(envmap, xstrdup(name), e);
+ pmap_put(cstr_t)(&envmap, xstrdup(name), e);
end:
// Must do this before ELOG, log.c may call os_setenv.
uv_mutex_unlock(&mutex);
@@ -157,7 +156,7 @@ int os_setenv(const char *name, const char *value, int overwrite)
assert(r != UV_EINVAL);
// Destroy the old map item. Do this AFTER uv_os_setenv(), because `value`
// could be a previous os_getenv() result.
- pmap_del2(envmap, name);
+ pmap_del2(&envmap, name);
// Must do this before ELOG, log.c may call os_setenv.
uv_mutex_unlock(&mutex);
if (r != 0) {
@@ -174,7 +173,7 @@ int os_unsetenv(const char *name)
return -1;
}
uv_mutex_lock(&mutex);
- pmap_del2(envmap, name);
+ pmap_del2(&envmap, name);
int r = uv_os_unsetenv(name);
// Must do this before ELOG, log.c may call os_setenv.
uv_mutex_unlock(&mutex);
@@ -207,7 +206,7 @@ size_t os_get_fullenv_size(void)
# if defined(HAVE__NSGETENVIRON)
char **environ = *_NSGetEnviron();
# else
- extern char **environ;
+ extern char **environ;
# endif
while (environ[len] != NULL) {
@@ -220,7 +219,9 @@ size_t os_get_fullenv_size(void)
void os_free_fullenv(char **env)
{
- if (!env) { return; }
+ if (!env) {
+ return;
+ }
for (char **it = env; *it; it++) {
XFREE_CLEAR(*it);
}
@@ -263,7 +264,7 @@ void os_copy_fullenv(char **env, size_t env_size)
# if defined(HAVE__NSGETENVIRON)
char **environ = *_NSGetEnviron();
# else
- extern char **environ;
+ extern char **environ;
# endif
for (size_t i = 0; i < env_size && environ[i] != NULL; i++) {
@@ -323,7 +324,7 @@ char *os_getenvname_at_index(size_t index)
# if defined(HAVE__NSGETENVIRON)
char **environ = *_NSGetEnviron();
# else
- extern char **environ;
+ extern char **environ;
# endif
// check if index is inside the environ array
@@ -567,16 +568,12 @@ void expand_env(char_u *src, char_u *dst, int dstlen)
/// @param esc Escape spaces in expanded variables
/// @param one `srcp` is a single filename
/// @param prefix Start again after this (can be NULL)
-void expand_env_esc(char_u *restrict srcp,
- char_u *restrict dst,
- int dstlen,
- bool esc,
- bool one,
+void expand_env_esc(char_u *restrict srcp, char_u *restrict dst, int dstlen, bool esc, bool one,
char_u *prefix)
FUNC_ATTR_NONNULL_ARG(1, 2)
{
- char_u *tail;
- char_u *var;
+ char_u *tail;
+ char_u *var;
bool copy_char;
bool mustfree; // var was allocated, need to free it later
bool at_start = true; // at start of a name
@@ -622,7 +619,7 @@ void expand_env_esc(char_u *restrict srcp,
while (c-- > 0 && *tail != NUL && *tail != '}') {
*var++ = *tail++;
}
- } else // NOLINT
+ } else // NOLINT
#endif
{
while (c-- > 0 && *tail != NUL && vim_isIDc(*tail)) {
@@ -643,7 +640,7 @@ void expand_env_esc(char_u *restrict srcp,
var = (char_u *)vim_getenv((char *)dst);
mustfree = true;
#if defined(UNIX)
- }
+ }
#endif
} else if (src[1] == NUL // home directory
|| vim_ispathsep(src[1])
@@ -674,7 +671,7 @@ void expand_env_esc(char_u *restrict srcp,
ExpandInit(&xpc);
xpc.xp_context = EXPAND_FILES;
var = ExpandOne(&xpc, dst, NULL,
- WILD_ADD_SLASH|WILD_SILENT, WILD_EXPAND_FREE);
+ WILD_ADD_SLASH|WILD_SILENT, WILD_EXPAND_FREE);
mustfree = true;
}
#else
@@ -688,7 +685,7 @@ void expand_env_esc(char_u *restrict srcp,
// If 'shellslash' is set change backslashes to forward slashes.
// Can't use slash_adjust(), p_ssl may be set temporarily.
if (p_ssl && var != NULL && vim_strchr(var, '\\') != NULL) {
- char_u *p = vim_strsave(var);
+ char_u *p = vim_strsave(var);
if (mustfree) {
xfree(var);
@@ -702,7 +699,7 @@ void expand_env_esc(char_u *restrict srcp,
// If "var" contains white space, escape it with a backslash.
// Required for ":e ~/tt" when $HOME includes a space.
if (esc && var != NULL && vim_strpbrk(var, (char_u *)" \t") != NULL) {
- char_u *p = vim_strsave_escaped(var, (char_u *)" \t");
+ char_u *p = vim_strsave_escaped(var, (char_u *)" \t");
if (mustfree) {
xfree(var);
@@ -722,8 +719,9 @@ void expand_env_esc(char_u *restrict srcp,
#if defined(BACKSLASH_IN_FILENAME)
&& dst[-1] != ':'
#endif
- && vim_ispathsep(*tail))
+ && vim_ispathsep(*tail)) {
++tail;
+ }
dst += c;
src = tail;
copy_char = false;
@@ -827,14 +825,11 @@ static char *remove_tail(char *path, char *pend, char *dirname)
/// @param[out] len Location where current directory length should be saved.
///
/// @return Next iter argument value or NULL when iteration should stop.
-const void *vim_env_iter(const char delim,
- const char *const val,
- const void *const iter,
- const char **const dir,
- size_t *const len)
+const void *vim_env_iter(const char delim, const char *const val, const void *const iter,
+ const char **const dir, size_t *const len)
FUNC_ATTR_NONNULL_ARG(2, 4, 5) FUNC_ATTR_WARN_UNUSED_RESULT
{
- const char *varval = (const char *) iter;
+ const char *varval = (const char *)iter;
if (varval == NULL) {
varval = val;
}
@@ -844,7 +839,7 @@ const void *vim_env_iter(const char delim,
*len = strlen(varval);
return NULL;
} else {
- *len = (size_t) (dirend - varval);
+ *len = (size_t)(dirend - varval);
return dirend + 1;
}
}
@@ -862,14 +857,11 @@ const void *vim_env_iter(const char delim,
/// @param[out] len Location where current directory length should be saved.
///
/// @return Next iter argument value or NULL when iteration should stop.
-const void *vim_env_iter_rev(const char delim,
- const char *const val,
- const void *const iter,
- const char **const dir,
- size_t *const len)
+const void *vim_env_iter_rev(const char delim, const char *const val, const void *const iter,
+ const char **const dir, size_t *const len)
FUNC_ATTR_NONNULL_ARG(2, 4, 5) FUNC_ATTR_WARN_UNUSED_RESULT
{
- const char *varend = (const char *) iter;
+ const char *varend = (const char *)iter;
if (varend == NULL) {
varend = val + strlen(val) - 1;
}
@@ -881,7 +873,7 @@ const void *vim_env_iter_rev(const char delim,
return NULL;
} else {
*dir = colon + 1;
- *len = (size_t) (varend - colon);
+ *len = (size_t)(varend - colon);
return colon - 1;
}
}
@@ -956,10 +948,9 @@ char *vim_getenv(const char *name)
// Find runtime path relative to the nvim binary: ../share/nvim/runtime
if (vim_path == NULL) {
vim_get_prefix_from_exepath(exe_name);
- if (append_path(
- exe_name,
- "share" _PATHSEPSTR "nvim" _PATHSEPSTR "runtime" _PATHSEPSTR,
- MAXPATHL) == OK) {
+ if (append_path(exe_name,
+ "share" _PATHSEPSTR "nvim" _PATHSEPSTR "runtime" _PATHSEPSTR,
+ MAXPATHL) == OK) {
vim_path = exe_name; // -V507
}
}
@@ -1044,8 +1035,8 @@ char *vim_getenv(const char *name)
/// a list of them.
///
/// @return length of the string put into dst, does not include NUL byte.
-size_t home_replace(const buf_T *const buf, const char_u *src,
- char_u *const dst, size_t dstlen, const bool one)
+size_t home_replace(const buf_T *const buf, const char_u *src, char_u *const dst, size_t dstlen,
+ const bool one)
FUNC_ATTR_NONNULL_ARG(3)
{
size_t dirlen = 0;
@@ -1155,7 +1146,7 @@ size_t home_replace(const buf_T *const buf, const char_u *src,
/// Like home_replace, store the replaced string in allocated memory.
/// @param buf When not NULL, check for help files
/// @param src Input file name
-char_u * home_replace_save(buf_T *buf, char_u *src) FUNC_ATTR_NONNULL_RET
+char_u *home_replace_save(buf_T *buf, char_u *src) FUNC_ATTR_NONNULL_RET
{
size_t len = 3; // space for "~/" and trailing NUL
if (src != NULL) { // just in case
@@ -1170,7 +1161,7 @@ char_u * home_replace_save(buf_T *buf, char_u *src) FUNC_ATTR_NONNULL_RET
/// Function given to ExpandGeneric() to obtain an environment variable name.
char_u *get_env_name(expand_T *xp, int idx)
{
-# define ENVNAMELEN 100
+#define ENVNAMELEN 100
// this static buffer is needed to avoid a memory leak in ExpandGeneric
static char_u name[ENVNAMELEN];
assert(idx >= 0);
diff --git a/src/nvim/os/fileio.c b/src/nvim/os/fileio.c
index bb68326a03..1ae6ca4244 100644
--- a/src/nvim/os/fileio.c
+++ b/src/nvim/os/fileio.c
@@ -4,13 +4,13 @@
/// @file fileio.c
///
/// Buffered reading/writing to a file. Unlike fileio.c this is not dealing with
-/// Nvim stuctures for buffer, with autocommands, etc: just fopen/fread/fwrite
+/// Nvim structures for buffer, with autocommands, etc: just fopen/fread/fwrite
/// replacement.
#include <assert.h>
-#include <stddef.h>
-#include <stdbool.h>
#include <fcntl.h>
+#include <stdbool.h>
+#include <stddef.h>
#include "auto/config.h"
@@ -20,13 +20,13 @@
#include <uv.h>
-#include "nvim/os/fileio.h"
-#include "nvim/memory.h"
-#include "nvim/os/os.h"
#include "nvim/globals.h"
-#include "nvim/rbuffer.h"
#include "nvim/macros.h"
+#include "nvim/memory.h"
#include "nvim/message.h"
+#include "nvim/os/fileio.h"
+#include "nvim/os/os.h"
+#include "nvim/rbuffer.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "os/fileio.c.generated.h"
@@ -44,8 +44,8 @@
/// does not have kFileCreate\*).
///
/// @return Error code, or 0 on success. @see os_strerror()
-int file_open(FileDescriptor *const ret_fp, const char *const fname,
- const int flags, const int mode)
+int file_open(FileDescriptor *const ret_fp, const char *const fname, const int flags,
+ const int mode)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
int os_open_flags = 0;
@@ -99,8 +99,7 @@ int file_open(FileDescriptor *const ret_fp, const char *const fname,
/// FILE_WRITE_ONLY or FILE_READ_ONLY is required.
///
/// @return Error code (@see os_strerror()) or 0. Currently always returns 0.
-int file_open_fd(FileDescriptor *const ret_fp, const int fd,
- const int flags)
+int file_open_fd(FileDescriptor *const ret_fp, const int fd, const int flags)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
ret_fp->wr = !!(flags & (kFileCreate
@@ -131,8 +130,8 @@ int file_open_fd(FileDescriptor *const ret_fp, const int fd,
/// does not have kFileCreate\*).
///
/// @return [allocated] Opened file or NULL in case of error.
-FileDescriptor *file_open_new(int *const error, const char *const fname,
- const int flags, const int mode)
+FileDescriptor *file_open_new(int *const error, const char *const fname, const int flags,
+ const int mode)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
FileDescriptor *const fp = xmalloc(sizeof(*fp));
@@ -152,8 +151,7 @@ FileDescriptor *file_open_new(int *const error, const char *const fname,
/// does not have FILE_CREATE\*).
///
/// @return [allocated] Opened file or NULL in case of error.
-FileDescriptor *file_open_fd_new(int *const error, const int fd,
- const int flags)
+FileDescriptor *file_open_fd_new(int *const error, const int fd, const int flags)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT
{
FileDescriptor *const fp = xmalloc(sizeof(*fp));
@@ -277,8 +275,7 @@ static void file_rb_write_full_cb(RBuffer *const rv, FileDescriptor *const fp)
/// bytes.
///
/// @return error_code (< 0) or number of bytes read.
-ptrdiff_t file_read(FileDescriptor *const fp, char *const ret_buf,
- const size_t size)
+ptrdiff_t file_read(FileDescriptor *const fp, char *const ret_buf, const size_t size)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
assert(!fp->wr);
@@ -362,8 +359,7 @@ ptrdiff_t file_read(FileDescriptor *const fp, char *const ret_buf,
/// @param[in] size Amount of bytes to write.
///
/// @return Number of bytes written or libuv error code (< 0).
-ptrdiff_t file_write(FileDescriptor *const fp, const char *const buf,
- const size_t size)
+ptrdiff_t file_write(FileDescriptor *const fp, const char *const buf, const size_t size)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ARG(1)
{
assert(fp->wr);
@@ -392,8 +388,8 @@ ptrdiff_t file_skip(FileDescriptor *const fp, const size_t size)
assert(!fp->wr);
size_t read_bytes = 0;
do {
- const ptrdiff_t new_read_bytes = file_read(
- fp, skipbuf, MIN(size - read_bytes, sizeof(skipbuf)));
+ const ptrdiff_t new_read_bytes =
+ file_read(fp, skipbuf, MIN(size - read_bytes, sizeof(skipbuf)));
if (new_read_bytes < 0) {
return new_read_bytes;
} else if (new_read_bytes == 0) {
diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c
index d0fa74a77f..bbf70a4830 100644
--- a/src/nvim/os/fs.c
+++ b/src/nvim/os/fs.c
@@ -2,12 +2,12 @@
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
// fs.c -- filesystem access
-#include <stdbool.h>
-#include <stddef.h>
#include <assert.h>
-#include <limits.h>
-#include <fcntl.h>
#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <stddef.h>
#include "auto/config.h"
@@ -17,19 +17,19 @@
#include <uv.h>
-#include "nvim/os/os.h"
-#include "nvim/os/os_defs.h"
#include "nvim/ascii.h"
+#include "nvim/assert.h"
#include "nvim/memory.h"
#include "nvim/message.h"
-#include "nvim/assert.h"
#include "nvim/misc1.h"
#include "nvim/option.h"
+#include "nvim/os/os.h"
+#include "nvim/os/os_defs.h"
#include "nvim/path.h"
#include "nvim/strings.h"
#ifdef WIN32
-#include "nvim/mbyte.h" // for utf8_to_utf16, utf16_to_utf8
+# include "nvim/mbyte.h" // for utf8_to_utf16, utf16_to_utf8
#endif
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -37,18 +37,18 @@
#endif
#define RUN_UV_FS_FUNC(ret, func, ...) \
- do { \
- bool did_try_to_free = false; \
+ do { \
+ bool did_try_to_free = false; \
uv_call_start: {} \
- uv_fs_t req; \
- ret = func(&fs_loop, &req, __VA_ARGS__); \
- uv_fs_req_cleanup(&req); \
- if (ret == UV_ENOMEM && !did_try_to_free) { \
- try_to_free_memory(); \
- did_try_to_free = true; \
- goto uv_call_start; \
- } \
- } while (0)
+ uv_fs_t req; \
+ ret = func(&fs_loop, &req, __VA_ARGS__); \
+ uv_fs_req_cleanup(&req); \
+ if (ret == UV_ENOMEM && !did_try_to_free) { \
+ try_to_free_memory(); \
+ did_try_to_free = true; \
+ goto uv_call_start; \
+ } \
+ } while (0)
// Many fs functions from libuv return that value on success.
static const int kLibuvSuccess = 0;
@@ -199,16 +199,16 @@ int os_nodetype(const char *name)
}
switch (guess) {
- case UV_TTY: // FILE_TYPE_CHAR
- return NODE_WRITABLE;
- case UV_FILE: // FILE_TYPE_DISK
- return NODE_NORMAL;
- case UV_NAMED_PIPE: // not handled explicitly in Vim os_win32.c
- case UV_UDP: // unix only
- case UV_TCP: // unix only
- case UV_UNKNOWN_HANDLE:
- default:
- return NODE_OTHER; // Vim os_win32.c default
+ case UV_TTY: // FILE_TYPE_CHAR
+ return NODE_WRITABLE;
+ case UV_FILE: // FILE_TYPE_DISK
+ return NODE_NORMAL;
+ case UV_NAMED_PIPE: // not handled explicitly in Vim os_win32.c
+ case UV_UDP: // unix only
+ case UV_TCP: // unix only
+ case UV_UNKNOWN_HANDLE:
+ default:
+ return NODE_OTHER; // Vim os_win32.c default
}
#endif
}
@@ -326,7 +326,7 @@ static bool is_executable_ext(const char *name, char **abspath)
sizeof(os_buf) - (size_t)(buf_end - os_buf), ENV_SEPSTR);
if (ext_len != 0) {
bool in_pathext = nameext_len == ext_len
- && 0 == mb_strnicmp((char_u *)nameext, (char_u *)ext, ext_len);
+ && 0 == mb_strnicmp((char_u *)nameext, (char_u *)ext, ext_len);
if (((in_pathext || is_unix_shell) && is_executable(name, abspath))
|| is_executable(os_buf, abspath)) {
@@ -436,17 +436,17 @@ FILE *os_fopen(const char *path, const char *flags)
// Per table in fopen(3) manpage.
if (flags[1] == '\0' || flags[1] == 'b') {
switch (flags[0]) {
- case 'r':
- iflags = O_RDONLY;
- break;
- case 'w':
- iflags = O_WRONLY | O_CREAT | O_TRUNC;
- break;
- case 'a':
- iflags = O_WRONLY | O_CREAT | O_APPEND;
- break;
- default:
- abort();
+ case 'r':
+ iflags = O_RDONLY;
+ break;
+ case 'w':
+ iflags = O_WRONLY | O_CREAT | O_TRUNC;
+ break;
+ case 'a':
+ iflags = O_WRONLY | O_CREAT | O_APPEND;
+ break;
+ default:
+ abort();
}
#ifdef WIN32
if (flags[1] == 'b') {
@@ -458,17 +458,17 @@ FILE *os_fopen(const char *path, const char *flags)
// char 1 is always '+' ('b' is handled above).
assert(flags[1] == '+');
switch (flags[0]) {
- case 'r':
- iflags = O_RDWR;
- break;
- case 'w':
- iflags = O_RDWR | O_CREAT | O_TRUNC;
- break;
- case 'a':
- iflags = O_RDWR | O_CREAT | O_APPEND;
- break;
- default:
- abort();
+ case 'r':
+ iflags = O_RDWR;
+ break;
+ case 'w':
+ iflags = O_RDWR | O_CREAT | O_TRUNC;
+ break;
+ case 'a':
+ iflags = O_RDWR | O_CREAT | O_APPEND;
+ break;
+ default:
+ abort();
}
}
// Per fopen(3) manpage: default to 0666, it will be umask-adjusted.
@@ -553,8 +553,8 @@ os_dup_dup:
/// @param[in] non_blocking Do not restart syscall if EAGAIN was encountered.
///
/// @return Number of bytes read or libuv error code (< 0).
-ptrdiff_t os_read(const int fd, bool *const ret_eof, char *const ret_buf,
- const size_t size, const bool non_blocking)
+ptrdiff_t os_read(const int fd, bool *const ret_eof, char *const ret_buf, const size_t size,
+ const bool non_blocking)
FUNC_ATTR_WARN_UNUSED_RESULT
{
*ret_eof = false;
@@ -609,8 +609,8 @@ ptrdiff_t os_read(const int fd, bool *const ret_eof, char *const ret_buf,
/// @param[in] non_blocking Do not restart syscall if EAGAIN was encountered.
///
/// @return Number of bytes read or libuv error code (< 0).
-ptrdiff_t os_readv(const int fd, bool *const ret_eof, struct iovec *iov,
- size_t iov_size, const bool non_blocking)
+ptrdiff_t os_readv(const int fd, bool *const ret_eof, struct iovec *iov, size_t iov_size,
+ const bool non_blocking)
FUNC_ATTR_NONNULL_ALL
{
*ret_eof = false;
@@ -668,8 +668,7 @@ ptrdiff_t os_readv(const int fd, bool *const ret_eof, struct iovec *iov,
/// @param[in] non_blocking Do not restart syscall if EAGAIN was encountered.
///
/// @return Number of bytes written or libuv error code (< 0).
-ptrdiff_t os_write(const int fd, const char *const buf, const size_t size,
- const bool non_blocking)
+ptrdiff_t os_write(const int fd, const char *const buf, const size_t size, const bool non_blocking)
FUNC_ATTR_WARN_UNUSED_RESULT
{
if (buf == NULL) {
@@ -884,8 +883,7 @@ int os_mkdir(const char *path, int32_t mode)
/// of the higher level directories.
///
/// @return `0` for success, libuv error code for failure.
-int os_mkdir_recurse(const char *const dir, int32_t mode,
- char **const failed_dir)
+int os_mkdir_recurse(const char *const dir, int32_t mode, char **const failed_dir)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
// Get end of directory name in "dir".
@@ -1058,8 +1056,7 @@ bool os_fileinfo_fd(int file_descriptor, FileInfo *file_info)
/// Compare the inodes of two FileInfos
///
/// @return `true` if the two FileInfos represent the same file.
-bool os_fileinfo_id_equal(const FileInfo *file_info_1,
- const FileInfo *file_info_2)
+bool os_fileinfo_id_equal(const FileInfo *file_info_1, const FileInfo *file_info_2)
FUNC_ATTR_NONNULL_ALL
{
return file_info_1->stat.st_ino == file_info_2->stat.st_ino
@@ -1119,7 +1116,7 @@ uint64_t os_fileinfo_blocksize(const FileInfo *file_info)
///
/// @param path Path to the file.
/// @param[out] file_info Pointer to a `FileID` to fill in.
-/// @return `true` on sucess, `false` for failure.
+/// @return `true` on success, `false` for failure.
bool os_fileid(const char *path, FileID *file_id)
FUNC_ATTR_NONNULL_ALL
{
@@ -1149,8 +1146,7 @@ bool os_fileid_equal(const FileID *file_id_1, const FileID *file_id_2)
/// @param file_id Pointer to a `FileID`
/// @param file_info Pointer to a `FileInfo`
/// @return `true` if the `FileID` and the `FileInfo` represent te same file.
-bool os_fileid_equal_fileinfo(const FileID *file_id,
- const FileInfo *file_info)
+bool os_fileid_equal_fileinfo(const FileID *file_id, const FileInfo *file_info)
FUNC_ATTR_NONNULL_ALL
{
return file_id->inode == file_info->stat.st_ino
@@ -1219,8 +1215,7 @@ char *os_resolve_shortcut(const char *fname)
EMSG2("utf8_to_utf16 failed: %d", r);
} else if (p != NULL) {
// Get a pointer to the IPersistFile interface.
- hr = pslw->lpVtbl->QueryInterface(
- pslw, &IID_IPersistFile, (void **)&ppf);
+ hr = pslw->lpVtbl->QueryInterface(pslw, &IID_IPersistFile, (void **)&ppf);
if (hr != S_OK) {
goto shortcut_errorw;
}
@@ -1231,12 +1226,12 @@ char *os_resolve_shortcut(const char *fname)
goto shortcut_errorw;
}
-# if 0 // This makes Vim wait a long time if the target does not exist.
+# if 0 // This makes Vim wait a long time if the target does not exist.
hr = pslw->lpVtbl->Resolve(pslw, NULL, SLR_NO_UI);
if (hr != S_OK) {
goto shortcut_errorw;
}
-# endif
+# endif
// Get the path to the link target.
ZeroMemory(wsz, MAX_PATH * sizeof(wchar_t));
@@ -1267,7 +1262,7 @@ shortcut_end:
return rfname;
}
-#define is_path_sep(c) ((c) == L'\\' || (c) == L'/')
+# define is_path_sep(c) ((c) == L'\\' || (c) == L'/')
/// Returns true if the path contains a reparse point (junction or symbolic
/// link). Otherwise false in returned.
bool os_is_reparse_point_include(const char *path)
diff --git a/src/nvim/os/input.c b/src/nvim/os/input.c
index eca245650a..4c6e9ee4d3 100644
--- a/src/nvim/os/input.c
+++ b/src/nvim/os/input.c
@@ -2,28 +2,27 @@
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
#include <assert.h>
-#include <string.h>
#include <stdbool.h>
-
+#include <string.h>
#include <uv.h>
#include "nvim/api/private/defs.h"
-#include "nvim/os/input.h"
+#include "nvim/ascii.h"
#include "nvim/event/loop.h"
#include "nvim/event/rstream.h"
-#include "nvim/ascii.h"
-#include "nvim/vim.h"
-#include "nvim/ui.h"
-#include "nvim/memory.h"
-#include "nvim/keymap.h"
-#include "nvim/mbyte.h"
-#include "nvim/fileio.h"
#include "nvim/ex_cmds2.h"
+#include "nvim/fileio.h"
#include "nvim/getchar.h"
+#include "nvim/keymap.h"
#include "nvim/main.h"
+#include "nvim/mbyte.h"
+#include "nvim/memory.h"
#include "nvim/misc1.h"
-#include "nvim/state.h"
#include "nvim/msgpack_rpc/channel.h"
+#include "nvim/os/input.h"
+#include "nvim/state.h"
+#include "nvim/ui.h"
+#include "nvim/vim.h"
#define READ_BUFFER_SIZE 0xfff
#define INPUT_BUFFER_SIZE (READ_BUFFER_SIZE * 4)
@@ -102,8 +101,7 @@ static void create_cursorhold_event(bool events_enabled)
///
/// wait until either the input buffer is non-empty or , if `events` is not NULL
/// until `events` is non-empty.
-int os_inchar(uint8_t *buf, int maxlen, int ms, int tb_change_cnt,
- MultiQueue *events)
+int os_inchar(uint8_t *buf, int maxlen, int ms, int tb_change_cnt, MultiQueue *events)
{
if (maxlen && rbuffer_size(input_buffer)) {
return (int)rbuffer_read(input_buffer, (char *)buf, (size_t)maxlen);
@@ -192,7 +190,7 @@ void os_breakcheck(void)
/// @return `true` if file descriptor refers to a terminal.
bool os_isatty(int fd)
{
- return uv_guess_handle(fd) == UV_TTY;
+ return uv_guess_handle(fd) == UV_TTY;
}
size_t input_enqueue(String keys)
@@ -208,8 +206,8 @@ size_t input_enqueue(String keys)
// K_SPECIAL(0x80) or CSI(0x9B).
uint8_t buf[19] = { 0 };
unsigned int new_size
- = trans_special((const uint8_t **)&ptr, (size_t)(end - ptr), buf, true,
- false);
+ = trans_special((const uint8_t **)&ptr, (size_t)(end - ptr), buf, true,
+ false);
if (new_size) {
new_size = handle_mouse_event(&ptr, buf, new_size);
@@ -234,13 +232,13 @@ size_t input_enqueue(String keys)
// copy the character, escaping CSI and K_SPECIAL
if ((uint8_t)*ptr == CSI) {
- rbuffer_write(input_buffer, (char *)&(uint8_t){K_SPECIAL}, 1);
- rbuffer_write(input_buffer, (char *)&(uint8_t){KS_EXTRA}, 1);
- rbuffer_write(input_buffer, (char *)&(uint8_t){KE_CSI}, 1);
+ rbuffer_write(input_buffer, (char *)&(uint8_t){ K_SPECIAL }, 1);
+ rbuffer_write(input_buffer, (char *)&(uint8_t){ KS_EXTRA }, 1);
+ rbuffer_write(input_buffer, (char *)&(uint8_t){ KE_CSI }, 1);
} else if ((uint8_t)*ptr == K_SPECIAL) {
- rbuffer_write(input_buffer, (char *)&(uint8_t){K_SPECIAL}, 1);
- rbuffer_write(input_buffer, (char *)&(uint8_t){KS_SPECIAL}, 1);
- rbuffer_write(input_buffer, (char *)&(uint8_t){KE_FILLER}, 1);
+ rbuffer_write(input_buffer, (char *)&(uint8_t){ K_SPECIAL }, 1);
+ rbuffer_write(input_buffer, (char *)&(uint8_t){ KS_SPECIAL }, 1);
+ rbuffer_write(input_buffer, (char *)&(uint8_t){ KE_FILLER }, 1);
} else {
rbuffer_write(input_buffer, ptr, 1);
}
@@ -301,8 +299,7 @@ static uint8_t check_multiclick(int code, int grid, int row, int col)
// Mouse event handling code(Extract row/col if available and detect multiple
// clicks)
-static unsigned int handle_mouse_event(char **ptr, uint8_t *buf,
- unsigned int bufsize)
+static unsigned int handle_mouse_event(char **ptr, uint8_t *buf, unsigned int bufsize)
{
int mouse_code = 0;
int type = 0;
@@ -318,7 +315,7 @@ static unsigned int handle_mouse_event(char **ptr, uint8_t *buf,
if (type != KS_EXTRA
|| !((mouse_code >= KE_LEFTMOUSE && mouse_code <= KE_RIGHTRELEASE)
- || (mouse_code >= KE_MOUSEDOWN && mouse_code <= KE_MOUSERIGHT))) {
+ || (mouse_code >= KE_MOUSEDOWN && mouse_code <= KE_MOUSERIGHT))) {
return bufsize;
}
@@ -364,8 +361,7 @@ static unsigned int handle_mouse_event(char **ptr, uint8_t *buf,
return bufsize;
}
-size_t input_enqueue_mouse(int code, uint8_t modifier,
- int grid, int row, int col)
+size_t input_enqueue_mouse(int code, uint8_t modifier, int grid, int row, int col)
{
modifier |= check_multiclick(code, grid, row, col);
uint8_t buf[7], *p = buf;
@@ -437,8 +433,7 @@ bool input_available(void)
return rbuffer_size(input_buffer) != 0;
}
-static void input_read_cb(Stream *stream, RBuffer *buf, size_t c, void *data,
- bool at_eof)
+static void input_read_cb(Stream *stream, RBuffer *buf, size_t c, void *data, bool at_eof)
{
if (at_eof) {
input_done();
diff --git a/src/nvim/os/os_win_console.c b/src/nvim/os/os_win_console.c
index 18dcfeafa0..2c9cb699fc 100644
--- a/src/nvim/os/os_win_console.c
+++ b/src/nvim/os/os_win_console.c
@@ -1,9 +1,9 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
-#include "nvim/vim.h"
#include "nvim/os/input.h"
#include "nvim/os/os_win_console.h"
+#include "nvim/vim.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "os/os_win_console.c.generated.h"
diff --git a/src/nvim/os/process.c b/src/nvim/os/process.c
index c7b473a012..e70bc71961 100644
--- a/src/nvim/os/process.c
+++ b/src/nvim/os/process.c
@@ -23,16 +23,16 @@
#endif
#if defined(__APPLE__) || defined(BSD)
-# include <sys/sysctl.h>
# include <pwd.h>
+# include <sys/sysctl.h>
#endif
+#include "nvim/api/private/helpers.h"
#include "nvim/globals.h"
#include "nvim/log.h"
-#include "nvim/os/process.h"
#include "nvim/os/os.h"
#include "nvim/os/os_defs.h"
-#include "nvim/api/private/helpers.h"
+#include "nvim/os/process.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "os/process.c.generated.h"
diff --git a/src/nvim/os/pty_conpty_win.c b/src/nvim/os/pty_conpty_win.c
index 5bcadd6490..0625d6994e 100644
--- a/src/nvim/os/pty_conpty_win.c
+++ b/src/nvim/os/pty_conpty_win.c
@@ -3,9 +3,9 @@
#include <uv.h>
-#include "nvim/vim.h"
#include "nvim/os/os.h"
#include "nvim/os/pty_conpty_win.h"
+#include "nvim/vim.h"
#ifndef EXTENDED_STARTUPINFO_PRESENT
# define EXTENDED_STARTUPINFO_PRESENT 0x00080000
@@ -54,8 +54,7 @@ TriState os_dyn_conpty_init(void)
return kTrue;
}
-conpty_t *os_conpty_init(char **in_name, char **out_name,
- uint16_t width, uint16_t height)
+conpty_t *os_conpty_init(char **in_name, char **out_name, uint16_t width, uint16_t height)
{
static int count = 0;
conpty_t *conpty_object = xcalloc(1, sizeof(*conpty_object));
@@ -65,36 +64,34 @@ conpty_t *os_conpty_init(char **in_name, char **out_name,
char buf[MAXPATHL];
SECURITY_ATTRIBUTES sa = { 0 };
const DWORD mode = PIPE_ACCESS_INBOUND
- | PIPE_ACCESS_OUTBOUND | FILE_FLAG_FIRST_PIPE_INSTANCE;
+ | PIPE_ACCESS_OUTBOUND | FILE_FLAG_FIRST_PIPE_INSTANCE;
sa.nLength = sizeof(sa);
snprintf(buf, sizeof(buf), "\\\\.\\pipe\\nvim-term-in-%d-%d",
os_get_pid(), count);
*in_name = xstrdup(buf);
- if ((in_read = CreateNamedPipeA(
- *in_name,
- mode,
- PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
- 1,
- 0,
- 0,
- 30000,
- &sa)) == INVALID_HANDLE_VALUE) {
+ if ((in_read = CreateNamedPipeA(*in_name,
+ mode,
+ PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
+ 1,
+ 0,
+ 0,
+ 30000,
+ &sa)) == INVALID_HANDLE_VALUE) {
emsg = "create input pipe failed";
goto failed;
}
snprintf(buf, sizeof(buf), "\\\\.\\pipe\\nvim-term-out-%d-%d",
os_get_pid(), count);
*out_name = xstrdup(buf);
- if ((out_write = CreateNamedPipeA(
- *out_name,
- mode,
- PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
- 1,
- 0,
- 0,
- 30000,
- &sa)) == INVALID_HANDLE_VALUE) {
+ if ((out_write = CreateNamedPipeA(*out_name,
+ mode,
+ PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
+ 1,
+ 0,
+ 0,
+ 30000,
+ &sa)) == INVALID_HANDLE_VALUE) {
emsg = "create output pipe failed";
goto failed;
}
@@ -104,7 +101,7 @@ conpty_t *os_conpty_init(char **in_name, char **out_name,
HRESULT hr;
hr = pCreatePseudoConsole(size, in_read, out_write, 0, &conpty_object->pty);
if (FAILED(hr)) {
- emsg = "create psudo console failed";
+ emsg = "create pseudo console failed";
goto failed;
}
@@ -113,22 +110,20 @@ conpty_t *os_conpty_init(char **in_name, char **out_name,
InitializeProcThreadAttributeList(NULL, 1, 0, & bytes_required);
conpty_object->si_ex.lpAttributeList =
(PPROC_THREAD_ATTRIBUTE_LIST)xmalloc(bytes_required);
- if (!InitializeProcThreadAttributeList(
- conpty_object->si_ex.lpAttributeList,
- 1,
- 0,
- &bytes_required)) {
+ if (!InitializeProcThreadAttributeList(conpty_object->si_ex.lpAttributeList,
+ 1,
+ 0,
+ &bytes_required)) {
emsg = "InitializeProcThreadAttributeList failed";
goto failed;
}
- if (!UpdateProcThreadAttribute(
- conpty_object->si_ex.lpAttributeList,
- 0,
- PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE,
- conpty_object->pty,
- sizeof(conpty_object->pty),
- NULL,
- NULL)) {
+ if (!UpdateProcThreadAttribute(conpty_object->si_ex.lpAttributeList,
+ 0,
+ PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE,
+ conpty_object->pty,
+ sizeof(conpty_object->pty),
+ NULL,
+ NULL)) {
emsg = "UpdateProcThreadAttribute failed";
goto failed;
}
@@ -150,38 +145,35 @@ finished:
return conpty_object;
}
-bool os_conpty_spawn(conpty_t *conpty_object, HANDLE *process_handle,
- wchar_t *name, wchar_t *cmd_line, wchar_t *cwd,
- wchar_t *env)
+bool os_conpty_spawn(conpty_t *conpty_object, HANDLE *process_handle, wchar_t *name,
+ wchar_t *cmd_line, wchar_t *cwd, wchar_t *env)
{
PROCESS_INFORMATION pi = { 0 };
- if (!CreateProcessW(
- name,
- cmd_line,
- NULL,
- NULL,
- false,
- EXTENDED_STARTUPINFO_PRESENT | CREATE_UNICODE_ENVIRONMENT,
- env,
- cwd,
- &conpty_object->si_ex.StartupInfo,
- &pi)) {
+ if (!CreateProcessW(name,
+ cmd_line,
+ NULL,
+ NULL,
+ false,
+ EXTENDED_STARTUPINFO_PRESENT | CREATE_UNICODE_ENVIRONMENT,
+ env,
+ cwd,
+ &conpty_object->si_ex.StartupInfo,
+ &pi)) {
return false;
}
*process_handle = pi.hProcess;
return true;
}
-void os_conpty_set_size(conpty_t *conpty_object,
- uint16_t width, uint16_t height)
+void os_conpty_set_size(conpty_t *conpty_object, uint16_t width, uint16_t height)
{
- assert(width <= SHRT_MAX);
- assert(height <= SHRT_MAX);
- COORD size = { (int16_t)width, (int16_t)height };
- if (pResizePseudoConsole(conpty_object->pty, size) != S_OK) {
- ELOG("ResizePseudoConsoel failed: error code: %d",
- os_translate_sys_error((int)GetLastError()));
- }
+ assert(width <= SHRT_MAX);
+ assert(height <= SHRT_MAX);
+ COORD size = { (int16_t)width, (int16_t)height };
+ if (pResizePseudoConsole(conpty_object->pty, size) != S_OK) {
+ ELOG("ResizePseudoConsoel failed: error code: %d",
+ os_translate_sys_error((int)GetLastError()));
+ }
}
void os_conpty_free(conpty_t *conpty_object)
diff --git a/src/nvim/os/pty_process_unix.c b/src/nvim/os/pty_process_unix.c
index 36d6dbe2db..24ecf5c24f 100644
--- a/src/nvim/os/pty_process_unix.c
+++ b/src/nvim/os/pty_process_unix.c
@@ -5,11 +5,10 @@
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
-
-#include <termios.h>
+#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/wait.h>
-#include <sys/ioctl.h>
+#include <termios.h>
// forkpty is not in POSIX, so headers are platform-specific
#if defined(__FreeBSD__) || defined(__DragonFly__)
@@ -26,15 +25,14 @@
#include <uv.h>
-#include "nvim/lib/klist.h"
-
#include "nvim/event/loop.h"
+#include "nvim/event/process.h"
#include "nvim/event/rstream.h"
#include "nvim/event/wstream.h"
-#include "nvim/event/process.h"
-#include "nvim/os/pty_process_unix.h"
+#include "nvim/lib/klist.h"
#include "nvim/log.h"
#include "nvim/os/os.h"
+#include "nvim/os/pty_process_unix.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "os/pty_process_unix.c.generated.h"
@@ -159,7 +157,7 @@ static void init_child(PtyProcess *ptyproc)
FUNC_ATTR_NONNULL_ALL
{
#if defined(HAVE__NSGETENVIRON)
-#define environ (*_NSGetEnviron())
+# define environ (*_NSGetEnviron())
#else
extern char **environ;
#endif
diff --git a/src/nvim/os/pty_process_win.c b/src/nvim/os/pty_process_win.c
index 2bf73d08e6..f78f3e66f5 100644
--- a/src/nvim/os/pty_process_win.c
+++ b/src/nvim/os/pty_process_win.c
@@ -4,15 +4,14 @@
#include <assert.h>
#include <stdbool.h>
#include <stdlib.h>
-
#include <winpty_constants.h>
-#include "nvim/os/os.h"
#include "nvim/ascii.h"
-#include "nvim/memory.h"
#include "nvim/mbyte.h" // for utf8_to_utf16, utf16_to_utf8
-#include "nvim/os/pty_process_win.h"
+#include "nvim/memory.h"
+#include "nvim/os/os.h"
#include "nvim/os/pty_conpty_win.h"
+#include "nvim/os/pty_process_win.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "os/pty_process_win.c.generated.h"
@@ -59,8 +58,8 @@ int pty_process_spawn(PtyProcess *ptyproc)
if (os_has_conpty_working()) {
if ((conpty_object =
- os_conpty_init(&in_name, &out_name,
- ptyproc->width, ptyproc->height)) != NULL) {
+ os_conpty_init(&in_name, &out_name,
+ ptyproc->width, ptyproc->height)) != NULL) {
ptyproc->type = kConpty;
}
}
@@ -94,20 +93,18 @@ int pty_process_spawn(PtyProcess *ptyproc)
if (!proc->in.closed) {
in_req = xmalloc(sizeof(uv_connect_t));
- uv_pipe_connect(
- in_req,
- &proc->in.uv.pipe,
- in_name,
- pty_process_connect_cb);
+ uv_pipe_connect(in_req,
+ &proc->in.uv.pipe,
+ in_name,
+ pty_process_connect_cb);
}
if (!proc->out.closed) {
out_req = xmalloc(sizeof(uv_connect_t));
- uv_pipe_connect(
- out_req,
- &proc->out.uv.pipe,
- out_name,
- pty_process_connect_cb);
+ uv_pipe_connect(out_req,
+ &proc->out.uv.pipe,
+ out_name,
+ pty_process_connect_cb);
}
if (proc->cwd != NULL) {
@@ -146,13 +143,12 @@ int pty_process_spawn(PtyProcess *ptyproc)
goto cleanup;
}
} else {
- spawncfg = winpty_spawn_config_new(
- WINPTY_SPAWN_FLAG_AUTO_SHUTDOWN,
- NULL, // Optional application name
- cmd_line,
- cwd,
- env,
- &err);
+ spawncfg = winpty_spawn_config_new(WINPTY_SPAWN_FLAG_AUTO_SHUTDOWN,
+ NULL, // Optional application name
+ cmd_line,
+ cwd,
+ env,
+ &err);
if (spawncfg == NULL) {
emsg = "winpty_spawn_config_new failed";
goto cleanup;
@@ -176,13 +172,12 @@ int pty_process_spawn(PtyProcess *ptyproc)
}
proc->pid = (int)GetProcessId(process_handle);
- if (!RegisterWaitForSingleObject(
- &ptyproc->finish_wait,
- process_handle,
- pty_process_finish1,
- ptyproc,
- INFINITE,
- WT_EXECUTEDEFAULT | WT_EXECUTEONLYONCE)) {
+ if (!RegisterWaitForSingleObject(&ptyproc->finish_wait,
+ process_handle,
+ pty_process_finish1,
+ ptyproc,
+ INFINITE,
+ WT_EXECUTEDEFAULT | WT_EXECUTEONLYONCE)) {
abort();
}
@@ -193,8 +188,8 @@ int pty_process_spawn(PtyProcess *ptyproc)
}
(ptyproc->type == kConpty) ?
- (void *)(ptyproc->object.conpty = conpty_object) :
- (void *)(ptyproc->object.winpty = winpty_object);
+ (void *)(ptyproc->object.conpty = conpty_object) :
+ (void *)(ptyproc->object.winpty = winpty_object);
ptyproc->process_handle = process_handle;
winpty_object = NULL;
conpty_object = NULL;
@@ -235,8 +230,7 @@ const char *pty_process_tty_name(PtyProcess *ptyproc)
return "?";
}
-void pty_process_resize(PtyProcess *ptyproc, uint16_t width,
- uint16_t height)
+void pty_process_resize(PtyProcess *ptyproc, uint16_t width, uint16_t height)
FUNC_ATTR_NONNULL_ALL
{
if (ptyproc->type == kConpty
@@ -454,15 +448,24 @@ int translate_winpty_error(int winpty_errno)
}
switch (winpty_errno) {
- case WINPTY_ERROR_OUT_OF_MEMORY: return UV_ENOMEM;
- case WINPTY_ERROR_SPAWN_CREATE_PROCESS_FAILED: return UV_EAI_FAIL;
- case WINPTY_ERROR_LOST_CONNECTION: return UV_ENOTCONN;
- case WINPTY_ERROR_AGENT_EXE_MISSING: return UV_ENOENT;
- case WINPTY_ERROR_UNSPECIFIED: return UV_UNKNOWN;
- case WINPTY_ERROR_AGENT_DIED: return UV_ESRCH;
- case WINPTY_ERROR_AGENT_TIMEOUT: return UV_ETIMEDOUT;
- case WINPTY_ERROR_AGENT_CREATION_FAILED: return UV_EAI_FAIL;
- default: return UV_UNKNOWN;
+ case WINPTY_ERROR_OUT_OF_MEMORY:
+ return UV_ENOMEM;
+ case WINPTY_ERROR_SPAWN_CREATE_PROCESS_FAILED:
+ return UV_EAI_FAIL;
+ case WINPTY_ERROR_LOST_CONNECTION:
+ return UV_ENOTCONN;
+ case WINPTY_ERROR_AGENT_EXE_MISSING:
+ return UV_ENOENT;
+ case WINPTY_ERROR_UNSPECIFIED:
+ return UV_UNKNOWN;
+ case WINPTY_ERROR_AGENT_DIED:
+ return UV_ESRCH;
+ case WINPTY_ERROR_AGENT_TIMEOUT:
+ return UV_ETIMEDOUT;
+ case WINPTY_ERROR_AGENT_CREATION_FAILED:
+ return UV_EAI_FAIL;
+ default:
+ return UV_UNKNOWN;
}
}
diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c
index 2974245857..2bff65b241 100644
--- a/src/nvim/os/shell.c
+++ b/src/nvim/os/shell.c
@@ -1,36 +1,35 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
-#include <string.h>
#include <assert.h>
#include <stdbool.h>
#include <stdlib.h>
-
+#include <string.h>
#include <uv.h>
#include "nvim/ascii.h"
-#include "nvim/fileio.h"
-#include "nvim/lib/kvec.h"
-#include "nvim/log.h"
-#include "nvim/event/loop.h"
+#include "nvim/charset.h"
#include "nvim/event/libuv_process.h"
+#include "nvim/event/loop.h"
#include "nvim/event/rstream.h"
#include "nvim/ex_cmds.h"
+#include "nvim/fileio.h"
+#include "nvim/lib/kvec.h"
+#include "nvim/log.h"
+#include "nvim/main.h"
+#include "nvim/memline.h"
+#include "nvim/memory.h"
+#include "nvim/message.h"
#include "nvim/misc1.h"
+#include "nvim/option_defs.h"
#include "nvim/os/shell.h"
#include "nvim/os/signal.h"
#include "nvim/path.h"
-#include "nvim/types.h"
-#include "nvim/main.h"
-#include "nvim/vim.h"
-#include "nvim/message.h"
-#include "nvim/memory.h"
-#include "nvim/ui.h"
#include "nvim/screen.h"
-#include "nvim/memline.h"
-#include "nvim/option_defs.h"
-#include "nvim/charset.h"
#include "nvim/strings.h"
+#include "nvim/types.h"
+#include "nvim/ui.h"
+#include "nvim/vim.h"
#define DYNAMIC_BUFFER_INIT { NULL, 0, 0 }
#define NS_1_SECOND 1000000000U // 1 second, in nanoseconds
@@ -47,8 +46,7 @@ typedef struct {
# include "os/shell.c.generated.h"
#endif
-static void save_patterns(int num_pat, char_u **pat, int *num_file,
- char_u ***file)
+static void save_patterns(int num_pat, char_u **pat, int *num_file, char_u ***file)
{
*file = xmalloc((size_t)num_pat * sizeof(char_u *));
for (int i = 0; i < num_pat; i++) {
@@ -99,22 +97,21 @@ static bool have_dollars(int num, char_u **file)
/// copied into *file.
///
/// @returns OK for success or FAIL for error.
-int os_expand_wildcards(int num_pat, char_u **pat, int *num_file,
- char_u ***file, int flags)
+int os_expand_wildcards(int num_pat, char_u **pat, int *num_file, char_u ***file, int flags)
FUNC_ATTR_NONNULL_ARG(3)
FUNC_ATTR_NONNULL_ARG(4)
{
int i;
size_t len;
- char_u *p;
+ char_u *p;
bool dir;
char_u *extra_shell_arg = NULL;
ShellOpts shellopts = kShellOptExpand | kShellOptSilent;
int j;
- char_u *tempname;
- char_u *command;
- FILE *fd;
- char_u *buffer;
+ char_u *tempname;
+ char_u *command;
+ FILE *fd;
+ char_u *buffer;
#define STYLE_ECHO 0 // use "echo", the default
#define STYLE_GLOB 1 // use "glob", for csh
#define STYLE_VIMGLOB 2 // use "vimglob", for Posix sh
@@ -215,7 +212,7 @@ int os_expand_wildcards(int num_pat, char_u **pat, int *num_file,
}
if (is_fish_shell) {
- len += sizeof("egin;"" end") - 1;
+ len += sizeof("egin;" " end") - 1;
}
command = xmalloc(len);
@@ -319,9 +316,9 @@ int os_expand_wildcards(int num_pat, char_u **pat, int *num_file,
if (shell_style == STYLE_PRINT) {
extra_shell_arg = (char_u *)"-G"; // Use zsh NULL_GLOB option
- // If we use -f then shell variables set in .cshrc won't get expanded.
- // vi can do it, so we will too, but it is only necessary if there is a "$"
- // in one of the patterns, otherwise we can still use the fast option.
+ // If we use -f then shell variables set in .cshrc won't get expanded.
+ // vi can do it, so we will too, but it is only necessary if there is a "$"
+ // in one of the patterns, otherwise we can still use the fast option.
} else if (shell_style == STYLE_GLOB && !have_dollars(num_pat, pat)) {
extra_shell_arg = (char_u *)"-f"; // Use csh fast option
}
@@ -409,7 +406,7 @@ int os_expand_wildcards(int num_pat, char_u **pat, int *num_file,
}
p = skipwhite(p); // skip to next entry
}
- // file names are separated with NL
+ // file names are separated with NL
} else if (shell_style == STYLE_BT || shell_style == STYLE_VIMGLOB) {
buffer[len] = NUL; // make sure the buffer ends in NUL
p = buffer;
@@ -422,7 +419,7 @@ int os_expand_wildcards(int num_pat, char_u **pat, int *num_file,
}
p = skipwhite(p); // skip leading white space
}
- // file names are separated with NUL
+ // file names are separated with NUL
} else {
// Some versions of zsh use spaces instead of NULs to separate
// results. Only do this when there is no NUL before the end of the
@@ -705,22 +702,14 @@ int os_call_shell(char_u *cmd, ShellOpts opts, char_u *extra_args)
/// returned buffer is not NULL)
/// @return the return code of the process, -1 if the process couldn't be
/// started properly
-int os_system(char **argv,
- const char *input,
- size_t len,
- char **output,
+int os_system(char **argv, const char *input, size_t len, char **output,
size_t *nread) FUNC_ATTR_NONNULL_ARG(1)
{
return do_os_system(argv, input, len, output, nread, true, false);
}
-static int do_os_system(char **argv,
- const char *input,
- size_t len,
- char **output,
- size_t *nread,
- bool silent,
- bool forward_output)
+static int do_os_system(char **argv, const char *input, size_t len, char **output, size_t *nread,
+ bool silent, bool forward_output)
{
out_data_decide_throttle(0); // Initialize throttle decider.
out_data_ring(NULL, 0); // Initialize output ring-buffer.
@@ -851,8 +840,7 @@ static void dynamic_buffer_ensure(DynamicBuffer *buf, size_t desired)
buf->data = xrealloc(buf->data, buf->cap);
}
-static void system_data_cb(Stream *stream, RBuffer *buf, size_t count,
- void *data, bool eof)
+static void system_data_cb(Stream *stream, RBuffer *buf, size_t count, void *data, bool eof)
{
DynamicBuffer *dbuf = data;
@@ -885,10 +873,10 @@ static void system_data_cb(Stream *stream, RBuffer *buf, size_t count,
/// Returns the previous decision if size=0.
static bool out_data_decide_throttle(size_t size)
{
- static uint64_t started = 0; // Start time of the current throttle.
- static size_t received = 0; // Bytes observed since last throttle.
- static size_t visit = 0; // "Pulse" count of the current throttle.
- static char pulse_msg[] = { ' ', ' ', ' ', '\0' };
+ static uint64_t started = 0; // Start time of the current throttle.
+ static size_t received = 0; // Bytes observed since last throttle.
+ static size_t visit = 0; // "Pulse" count of the current throttle.
+ static char pulse_msg[] = { ' ', ' ', ' ', '\0' };
if (!size) {
bool previous_decision = (visit > 0);
@@ -945,8 +933,8 @@ static bool out_data_decide_throttle(size_t size)
static void out_data_ring(char *output, size_t size)
{
#define MAX_CHUNK_SIZE (OUT_DATA_THRESHOLD / 2)
- static char last_skipped[MAX_CHUNK_SIZE]; // Saved output.
- static size_t last_skipped_len = 0;
+ static char last_skipped[MAX_CHUNK_SIZE]; // Saved output.
+ static size_t last_skipped_len = 0;
assert(output != NULL || (size == 0 || size == SIZE_MAX));
@@ -1015,8 +1003,7 @@ end:
ui_flush();
}
-static void out_data_cb(Stream *stream, RBuffer *buf, size_t count, void *data,
- bool eof)
+static void out_data_cb(Stream *stream, RBuffer *buf, size_t count, void *data, bool eof)
{
size_t cnt;
char *ptr = rbuffer_read_ptr(buf, &cnt);
@@ -1049,10 +1036,10 @@ static size_t tokenize(const char_u *const str, char **const argv)
FUNC_ATTR_NONNULL_ARG(1)
{
size_t argc = 0;
- const char *p = (const char *) str;
+ const char *p = (const char *)str;
while (*p != NUL) {
- const size_t len = word_length((const char_u *) p);
+ const size_t len = word_length((const char_u *)p);
if (argv != NULL) {
// Fill the slot
@@ -1060,7 +1047,7 @@ static size_t tokenize(const char_u *const str, char **const argv)
}
argc++;
- p = (const char *) skipwhite((char_u *) (p + len));
+ p = (const char *)skipwhite((char_u *)(p + len));
}
return argc;
@@ -1115,7 +1102,7 @@ static void read_input(DynamicBuffer *buf)
dynamic_buffer_ensure(buf, buf->len + len);
buf->data[buf->len++] = NUL;
} else {
- char_u *s = vim_strchr(lp + written, NL);
+ char_u *s = vim_strchr(lp + written, NL);
len = s == NULL ? l : (size_t)(s - (lp + written));
dynamic_buffer_ensure(buf, buf->len + len);
memcpy(buf->data + buf->len, lp + written, len);
diff --git a/src/nvim/os/signal.c b/src/nvim/os/signal.c
index bc774b8ebc..0d125ec964 100644
--- a/src/nvim/os/signal.c
+++ b/src/nvim/os/signal.c
@@ -3,25 +3,24 @@
#include <assert.h>
#include <stdbool.h>
-
#include <uv.h>
#ifndef WIN32
# include <signal.h> // for sigset_t
#endif
#include "nvim/ascii.h"
-#include "nvim/log.h"
-#include "nvim/vim.h"
-#include "nvim/globals.h"
-#include "nvim/memline.h"
#include "nvim/eval.h"
+#include "nvim/event/loop.h"
+#include "nvim/event/signal.h"
#include "nvim/fileio.h"
+#include "nvim/globals.h"
+#include "nvim/log.h"
#include "nvim/main.h"
+#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/misc1.h"
-#include "nvim/event/signal.h"
#include "nvim/os/signal.h"
-#include "nvim/event/loop.h"
+#include "nvim/vim.h"
static SignalWatcher spipe, shup, squit, sterm, susr1;
#ifdef SIGPWR
@@ -120,31 +119,31 @@ void signal_accept_deadly(void)
rejecting_deadly = false;
}
-static char * signal_name(int signum)
+static char *signal_name(int signum)
{
switch (signum) {
#ifdef SIGPWR
- case SIGPWR:
- return "SIGPWR";
+ case SIGPWR:
+ return "SIGPWR";
#endif
#ifdef SIGPIPE
- case SIGPIPE:
- return "SIGPIPE";
+ case SIGPIPE:
+ return "SIGPIPE";
#endif
- case SIGTERM:
- return "SIGTERM";
+ case SIGTERM:
+ return "SIGTERM";
#ifdef SIGQUIT
- case SIGQUIT:
- return "SIGQUIT";
+ case SIGQUIT:
+ return "SIGQUIT";
#endif
- case SIGHUP:
- return "SIGHUP";
+ case SIGHUP:
+ return "SIGHUP";
#ifdef SIGUSR1
- case SIGUSR1:
- return "SIGUSR1";
+ case SIGUSR1:
+ return "SIGUSR1";
#endif
- default:
- return "Unknown";
+ default:
+ return "Unknown";
}
}
@@ -173,34 +172,34 @@ static void on_signal(SignalWatcher *handle, int signum, void *data)
assert(signum >= 0);
switch (signum) {
#ifdef SIGPWR
- case SIGPWR:
- // Signal of a power failure(eg batteries low), flush the swap files to
- // be safe
- ml_sync_all(false, false, true);
- break;
+ case SIGPWR:
+ // Signal of a power failure(eg batteries low), flush the swap files to
+ // be safe
+ ml_sync_all(false, false, true);
+ break;
#endif
#ifdef SIGPIPE
- case SIGPIPE:
- // Ignore
- break;
+ case SIGPIPE:
+ // Ignore
+ break;
#endif
- case SIGTERM:
+ case SIGTERM:
#ifdef SIGQUIT
- case SIGQUIT:
+ case SIGQUIT:
#endif
- case SIGHUP:
- if (!rejecting_deadly) {
- deadly_signal(signum);
- }
- break;
+ case SIGHUP:
+ if (!rejecting_deadly) {
+ deadly_signal(signum);
+ }
+ break;
#ifdef SIGUSR1
- case SIGUSR1:
- apply_autocmds(EVENT_SIGNAL, (char_u *)"SIGUSR1", curbuf->b_fname, true,
- curbuf);
- break;
-#endif
- default:
- ELOG("invalid signal: %d", signum);
- break;
+ case SIGUSR1:
+ apply_autocmds(EVENT_SIGNAL, (char_u *)"SIGUSR1", curbuf->b_fname, true,
+ curbuf);
+ break;
+#endif
+ default:
+ ELOG("invalid signal: %d", signum);
+ break;
}
}
diff --git a/src/nvim/os/stdpaths.c b/src/nvim/os/stdpaths.c
index 93b8d5ca12..10b0d391bf 100644
--- a/src/nvim/os/stdpaths.c
+++ b/src/nvim/os/stdpaths.c
@@ -3,11 +3,11 @@
#include <stdbool.h>
-#include "nvim/os/stdpaths_defs.h"
+#include "nvim/ascii.h"
+#include "nvim/memory.h"
#include "nvim/os/os.h"
+#include "nvim/os/stdpaths_defs.h"
#include "nvim/path.h"
-#include "nvim/memory.h"
-#include "nvim/ascii.h"
/// Names of the environment variables, mapped to XDGVarType values
static const char *xdg_env_vars[] = {
@@ -137,8 +137,7 @@ char *stdpaths_user_conf_subpath(const char *fname)
/// @param[in] escape_commas If true, all commas will be escaped.
///
/// @return [allocated] `$XDG_DATA_HOME/nvim/{fname}`.
-char *stdpaths_user_data_subpath(const char *fname,
- const size_t trailing_pathseps,
+char *stdpaths_user_data_subpath(const char *fname, const size_t trailing_pathseps,
const bool escape_commas)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET
{
diff --git a/src/nvim/os/time.c b/src/nvim/os/time.c
index 9ea74716aa..d9f4fe9e37 100644
--- a/src/nvim/os/time.c
+++ b/src/nvim/os/time.c
@@ -3,15 +3,14 @@
#include <assert.h>
#include <limits.h>
-
#include <uv.h>
#include "nvim/assert.h"
-#include "nvim/os/time.h"
-#include "nvim/os/input.h"
#include "nvim/event/loop.h"
-#include "nvim/os/os.h"
#include "nvim/main.h"
+#include "nvim/os/input.h"
+#include "nvim/os/os.h"
+#include "nvim/os/time.h"
static uv_mutex_t delay_mutex;
static uv_cond_t delay_cond;
@@ -169,8 +168,7 @@ struct tm *os_localtime(struct tm *result) FUNC_ATTR_NONNULL_ALL
/// @param result[out] Pointer to a 'char' where the result should be placed
/// @param result_len length of result buffer
/// @return human-readable string of current local time
-char *os_ctime_r(const time_t *restrict clock, char *restrict result,
- size_t result_len)
+char *os_ctime_r(const time_t *restrict clock, char *restrict result, size_t result_len)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET
{
struct tm clock_local;
@@ -219,5 +217,5 @@ char *os_strptime(const char *str, const char *format, struct tm *tm)
Timestamp os_time(void)
FUNC_ATTR_WARN_UNUSED_RESULT
{
- return (Timestamp) time(NULL);
+ return (Timestamp)time(NULL);
}
diff --git a/src/nvim/os/tty.c b/src/nvim/os/tty.c
index c80ef99084..126b1b0044 100644
--- a/src/nvim/os/tty.c
+++ b/src/nvim/os/tty.c
@@ -23,15 +23,6 @@
/// @param out_fd stdout file descriptor
void os_tty_guess_term(const char **term, int out_fd)
{
- bool winpty = (os_getenv("NVIM") != NULL);
-
- if (winpty) {
- // Force TERM=win32con when running in winpty.
- *term = "win32con";
- uv_tty_set_vterm_state(UV_TTY_UNSUPPORTED);
- return;
- }
-
bool conemu_ansi = strequal(os_getenv("ConEmuANSI"), "ON");
bool vtp = false;
diff --git a/src/nvim/os/users.c b/src/nvim/os/users.c
index 16e17a9c60..fd7ead68da 100644
--- a/src/nvim/os/users.c
+++ b/src/nvim/os/users.c
@@ -6,11 +6,10 @@
#include <uv.h>
#include "auto/config.h"
-
#include "nvim/ascii.h"
-#include "nvim/os/os.h"
#include "nvim/garray.h"
#include "nvim/memory.h"
+#include "nvim/os/os.h"
#include "nvim/strings.h"
#ifdef HAVE_PWD_H
# include <pwd.h>
@@ -44,7 +43,7 @@ int os_get_usernames(garray_T *users)
}
ga_init(users, sizeof(char *), 20);
-# if defined(HAVE_GETPWENT) && defined(HAVE_PWD_H)
+#if defined(HAVE_GETPWENT) && defined(HAVE_PWD_H)
{
struct passwd *pw;
@@ -54,7 +53,7 @@ int os_get_usernames(garray_T *users)
}
endpwent();
}
-# elif defined(WIN32)
+#elif defined(WIN32)
{
DWORD nusers = 0, ntotal = 0, i;
PUSER_INFO_0 uinfo;
@@ -74,8 +73,8 @@ int os_get_usernames(garray_T *users)
NetApiBufferFree(uinfo);
}
}
-# endif
-# if defined(HAVE_GETPWNAM)
+#endif
+#if defined(HAVE_GETPWNAM)
{
const char *user_env = os_getenv("USER");
@@ -105,7 +104,7 @@ int os_get_usernames(garray_T *users)
}
}
}
-# endif
+#endif
return OK;
}
diff --git a/src/nvim/os_unix.c b/src/nvim/os_unix.c
index be4bd9709b..9396a5896a 100644
--- a/src/nvim/os_unix.c
+++ b/src/nvim/os_unix.c
@@ -7,15 +7,13 @@
#include <stdbool.h>
#include <string.h>
-#include "nvim/api/private/handle.h"
-#include "nvim/vim.h"
#include "nvim/ascii.h"
-#include "nvim/os_unix.h"
#include "nvim/buffer.h"
#include "nvim/charset.h"
#include "nvim/eval.h"
#include "nvim/ex_cmds.h"
#include "nvim/fileio.h"
+#include "nvim/garray.h"
#include "nvim/getchar.h"
#include "nvim/main.h"
#include "nvim/mbyte.h"
@@ -24,19 +22,20 @@
#include "nvim/message.h"
#include "nvim/misc1.h"
#include "nvim/mouse.h"
-#include "nvim/garray.h"
+#include "nvim/msgpack_rpc/helpers.h"
+#include "nvim/os/input.h"
+#include "nvim/os/os.h"
+#include "nvim/os/shell.h"
+#include "nvim/os/signal.h"
+#include "nvim/os/time.h"
+#include "nvim/os_unix.h"
#include "nvim/path.h"
#include "nvim/screen.h"
#include "nvim/strings.h"
#include "nvim/syntax.h"
-#include "nvim/ui.h"
#include "nvim/types.h"
-#include "nvim/os/os.h"
-#include "nvim/os/time.h"
-#include "nvim/os/input.h"
-#include "nvim/os/shell.h"
-#include "nvim/os/signal.h"
-#include "nvim/msgpack_rpc/helpers.h"
+#include "nvim/ui.h"
+#include "nvim/vim.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "os_unix.c.generated.h"
@@ -62,13 +61,15 @@ vim_acl_T mch_get_acl(const char_u *fname)
// Set the ACL of file "fname" to "acl" (unless it's NULL).
void mch_set_acl(const char_u *fname, vim_acl_T aclent)
{
- if (aclent == NULL)
+ if (aclent == NULL) {
return;
+ }
}
void mch_free_acl(vim_acl_T aclent)
{
- if (aclent == NULL)
+ if (aclent == NULL) {
return;
+ }
}
#endif
diff --git a/src/nvim/path.c b/src/nvim/path.c
index 6ac24182cc..60c7ea7fa4 100644
--- a/src/nvim/path.c
+++ b/src/nvim/path.c
@@ -6,15 +6,13 @@
#include <stdbool.h>
#include <stdlib.h>
-#include "nvim/vim.h"
#include "nvim/ascii.h"
-#include "nvim/path.h"
#include "nvim/charset.h"
#include "nvim/eval.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_getln.h"
-#include "nvim/fileio.h"
#include "nvim/file_search.h"
+#include "nvim/fileio.h"
#include "nvim/garray.h"
#include "nvim/memfile.h"
#include "nvim/memline.h"
@@ -22,20 +20,22 @@
#include "nvim/message.h"
#include "nvim/misc1.h"
#include "nvim/option.h"
+#include "nvim/os/input.h"
#include "nvim/os/os.h"
#include "nvim/os/shell.h"
#include "nvim/os_unix.h"
+#include "nvim/path.h"
#include "nvim/quickfix.h"
#include "nvim/regexp.h"
#include "nvim/screen.h"
#include "nvim/strings.h"
#include "nvim/tag.h"
#include "nvim/types.h"
-#include "nvim/os/input.h"
+#include "nvim/vim.h"
#include "nvim/window.h"
-#define URL_SLASH 1 /* path_is_url() has found "://" */
-#define URL_BACKSLASH 2 /* path_is_url() has found ":\\" */
+#define URL_SLASH 1 // path_is_url() has found "://"
+#define URL_BACKSLASH 2 // path_is_url() has found ":\\"
#ifdef gen_expand_wildcards
# undef gen_expand_wildcards
@@ -53,8 +53,8 @@
/// @param checkname When both files don't exist, only compare their names.
/// @param expandenv Whether to expand environment variables in file names.
/// @return Enum of type FileComparison. @see FileComparison.
-FileComparison path_full_compare(char_u *const s1, char_u *const s2,
- const bool checkname, const bool expandenv)
+FileComparison path_full_compare(char_u *const s1, char_u *const s2, const bool checkname,
+ const bool expandenv)
{
assert(s1 && s2);
char_u exp1[MAXPATHL];
@@ -63,9 +63,9 @@ FileComparison path_full_compare(char_u *const s1, char_u *const s2,
FileID file_id_1, file_id_2;
if (expandenv) {
- expand_env(s1, exp1, MAXPATHL);
+ expand_env(s1, exp1, MAXPATHL);
} else {
- xstrlcpy((char *)exp1, (const char *)s1, MAXPATHL);
+ xstrlcpy((char *)exp1, (const char *)s1, MAXPATHL);
}
bool id_ok_1 = os_fileid((char *)exp1, &file_id_1);
bool id_ok_2 = os_fileid((char *)s2, &file_id_2);
@@ -146,7 +146,7 @@ char_u *path_tail_with_sep(char_u *fname)
const char_u *invocation_path_tail(const char_u *invocation, size_t *len)
FUNC_ATTR_NONNULL_RET FUNC_ATTR_NONNULL_ARG(1)
{
- const char_u *tail = get_past_head((char_u *) invocation);
+ const char_u *tail = get_past_head((char_u *)invocation);
const char_u *p = tail;
while (*p != NUL && *p != ' ') {
bool was_sep = vim_ispathsep_nocolon(*p);
@@ -266,7 +266,7 @@ int vim_ispathlistsep(int c)
#ifdef UNIX
return c == ':';
#else
- return c == ';'; /* might not be right for every system... */
+ return c == ';'; // might not be right for every system...
#endif
}
@@ -280,11 +280,12 @@ char_u *shorten_dir(char_u *str)
char_u *d = str;
bool skip = false;
for (char_u *s = str;; ++s) {
- if (s >= tail) { /* copy the whole tail */
+ if (s >= tail) { // copy the whole tail
*d++ = *s;
- if (*s == NUL)
+ if (*s == NUL) {
break;
- } else if (vim_ispathsep(*s)) { /* copy '/' and next char */
+ }
+ } else if (vim_ispathsep(*s)) { // copy '/' and next char
*d++ = *s;
skip = false;
} else if (!skip) {
@@ -348,8 +349,7 @@ int path_fnamecmp(const char *fname1, const char *fname2)
/// @param[in] len Compare at most len bytes.
///
/// @return 0 if they are equal, non-zero otherwise.
-int path_fnamencmp(const char *const fname1, const char *const fname2,
- size_t len)
+int path_fnamencmp(const char *const fname1, const char *const fname2, size_t len)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
#ifdef BACKSLASH_IN_FILENAME
@@ -383,15 +383,14 @@ int path_fnamencmp(const char *const fname1, const char *const fname2,
///
/// @param[in] fname1 First fname to append to.
/// @param[in] len1 Length of fname1.
-/// @param[in] fname2 Secord part of the file name.
+/// @param[in] fname2 Second part of the file name.
/// @param[in] len2 Length of fname2.
/// @param[in] sep If true and fname1 does not end with a path separator,
/// add a path separator before fname2.
///
/// @return fname1
-static inline char *do_concat_fnames(char *fname1, const size_t len1,
- const char *fname2, const size_t len2,
- const bool sep)
+static inline char *do_concat_fnames(char *fname1, const size_t len1, const char *fname2,
+ const size_t len2, const bool sep)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET
{
if (sep && *fname1 && !after_pathsep(fname1, fname1 + len1)) {
@@ -548,7 +547,7 @@ bool path_has_exp_wildcard(const char_u *p)
#else
const char *wildcards = "*?["; // Windows.
#endif
- if (vim_strchr((char_u *) wildcards, *p) != NULL) {
+ if (vim_strchr((char_u *)wildcards, *p) != NULL) {
return true;
}
}
@@ -590,8 +589,8 @@ static const char *scandir_next_with_dots(Directory *dir)
/// Implementation of path_expand().
///
/// Chars before `path + wildoff` do not get expanded.
-static size_t do_path_expand(garray_T *gap, const char_u *path,
- size_t wildoff, int flags, bool didstar)
+static size_t do_path_expand(garray_T *gap, const char_u *path, size_t wildoff, int flags,
+ bool didstar)
FUNC_ATTR_NONNULL_ALL
{
int start_len = gap->ga_len;
@@ -599,11 +598,12 @@ static size_t do_path_expand(garray_T *gap, const char_u *path,
bool starstar = false;
static int stardepth = 0; // depth for "**" expansion
- /* Expanding "**" may take a long time, check for CTRL-C. */
+ // Expanding "**" may take a long time, check for CTRL-C.
if (stardepth > 0) {
os_breakcheck();
- if (got_int)
+ if (got_int) {
return 0;
+ }
}
// Make room for file name. When doing encoding conversion the actual
@@ -633,7 +633,7 @@ static size_t do_path_expand(garray_T *gap, const char_u *path,
|| (!p_fic && (flags & EW_ICASE)
&& isalpha(PTR2CHAR(path_end)))
#endif
- )) {
+ )) {
e = p;
}
len = (size_t)(utfc_ptr2len(path_end));
@@ -644,20 +644,23 @@ static size_t do_path_expand(garray_T *gap, const char_u *path,
e = p;
*e = NUL;
- /* Now we have one wildcard component between "s" and "e". */
+ // Now we have one wildcard component between "s" and "e".
/* Remove backslashes between "wildoff" and the start of the wildcard
* component. */
- for (p = buf + wildoff; p < s; ++p)
+ for (p = buf + wildoff; p < s; ++p) {
if (rem_backslash(p)) {
STRMOVE(p, p + 1);
--e;
--s;
}
+ }
- /* Check for "**" between "s" and "e". */
- for (p = s; p < e; ++p)
- if (p[0] == '*' && p[1] == '*')
+ // Check for "**" between "s" and "e".
+ for (p = s; p < e; ++p) {
+ if (p[0] == '*' && p[1] == '*') {
starstar = true;
+ }
+ }
// convert the file pattern to a regexp pattern
int starts_with_dot = *s == '.';
@@ -675,11 +678,13 @@ static size_t do_path_expand(garray_T *gap, const char_u *path,
#else
regmatch.rm_ic = true; // Always ignore case on Windows.
#endif
- if (flags & (EW_NOERROR | EW_NOTWILD))
+ if (flags & (EW_NOERROR | EW_NOTWILD)) {
++emsg_silent;
+ }
regmatch.regprog = vim_regcomp(pat, RE_MAGIC);
- if (flags & (EW_NOERROR | EW_NOTWILD))
+ if (flags & (EW_NOERROR | EW_NOTWILD)) {
--emsg_silent;
+ }
xfree(pat);
if (regmatch.regprog == NULL && (flags & EW_NOTWILD) == 0) {
@@ -727,9 +732,9 @@ static size_t do_path_expand(garray_T *gap, const char_u *path,
}
STRCPY(buf + len, path_end);
- if (path_has_exp_wildcard(path_end)) { /* handle more wildcards */
- /* need to expand another component of the path */
- /* remove backslashes for the remaining components only */
+ if (path_has_exp_wildcard(path_end)) { // handle more wildcards
+ // need to expand another component of the path
+ // remove backslashes for the remaining components only
(void)do_path_expand(gap, buf, len + 1, flags, false);
} else {
FileInfo file_info;
@@ -741,7 +746,7 @@ static size_t do_path_expand(garray_T *gap, const char_u *path,
}
// add existing file or symbolic link
if ((flags & EW_ALLLINKS) ? os_fileinfo_link((char *)buf, &file_info)
- : os_path_exists(buf)) {
+ : os_path_exists(buf)) {
addfile(gap, buf, flags);
}
}
@@ -767,14 +772,16 @@ static size_t do_path_expand(garray_T *gap, const char_u *path,
*/
static int find_previous_pathsep(char_u *path, char_u **psep)
{
- /* skip the current separator */
- if (*psep > path && vim_ispathsep(**psep))
+ // skip the current separator
+ if (*psep > path && vim_ispathsep(**psep)) {
--*psep;
+ }
- /* find the previous separator */
+ // find the previous separator
while (*psep > path) {
- if (vim_ispathsep(**psep))
+ if (vim_ispathsep(**psep)) {
return OK;
+ }
MB_PTR_BACK(path, *psep);
}
@@ -828,8 +835,9 @@ static void expand_path_option(char_u *curdir, garray_T *gap)
/* Relative to current buffer:
* "/path/file" + "." -> "/path/"
* "/path/file" + "./subdir" -> "/path/subdir" */
- if (curbuf->b_ffname == NULL)
+ if (curbuf->b_ffname == NULL) {
continue;
+ }
char_u *p = path_tail(curbuf->b_ffname);
size_t len = (size_t)(p - curbuf->b_ffname);
if (len + STRLEN(buf) >= MAXPATHL) {
@@ -870,13 +878,13 @@ static void expand_path_option(char_u *curdir, garray_T *gap)
*
* path: /foo/bar/baz
* fname: /foo/bar/baz/quux.txt
- * returns: ^this
+ * returns: ^this
*/
static char_u *get_path_cutoff(char_u *fname, garray_T *gap)
{
int maxlen = 0;
- char_u **path_part = (char_u **)gap->ga_data;
- char_u *cutoff = NULL;
+ char_u **path_part = (char_u **)gap->ga_data;
+ char_u *cutoff = NULL;
for (int i = 0; i < gap->ga_len; i++) {
int j = 0;
@@ -932,14 +940,16 @@ static void uniquefy_paths(garray_T *gap, char_u *pattern)
STRCAT(file_pattern, pattern);
char_u *pat = file_pat_to_reg_pat(file_pattern, NULL, NULL, true);
xfree(file_pattern);
- if (pat == NULL)
+ if (pat == NULL) {
return;
+ }
- regmatch.rm_ic = TRUE; /* always ignore case */
+ regmatch.rm_ic = TRUE; // always ignore case
regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
xfree(pat);
- if (regmatch.regprog == NULL)
+ if (regmatch.regprog == NULL) {
return;
+ }
char_u *curdir = xmalloc(MAXPATHL);
os_dirname(curdir, MAXPATHL);
@@ -951,16 +961,17 @@ static void uniquefy_paths(garray_T *gap, char_u *pattern)
char_u *path = fnames[i];
int is_in_curdir;
char_u *dir_end = (char_u *)gettail_dir((const char *)path);
- char_u *pathsep_p;
- char_u *path_cutoff;
+ char_u *pathsep_p;
+ char_u *path_cutoff;
len = STRLEN(path);
is_in_curdir = fnamencmp(curdir, path, dir_end - path) == 0
&& curdir[dir_end - path] == NUL;
- if (is_in_curdir)
+ if (is_in_curdir) {
in_curdir[i] = vim_strsave(path);
+ }
- /* Shorten the filename while maintaining its uniqueness */
+ // Shorten the filename while maintaining its uniqueness
path_cutoff = get_path_cutoff(path, &path_ga);
// Don't assume all files can be reached without path when search
@@ -1010,19 +1021,21 @@ static void uniquefy_paths(garray_T *gap, char_u *pattern)
os_breakcheck();
}
- /* Shorten filenames in /in/current/directory/{filename} */
+ // Shorten filenames in /in/current/directory/{filename}
for (int i = 0; i < gap->ga_len && !got_int; i++) {
char_u *rel_path;
char_u *path = in_curdir[i];
- if (path == NULL)
+ if (path == NULL) {
continue;
+ }
/* If the {filename} is not unique, change it to ./{filename}.
* Else reduce it to {filename} */
short_name = path_shorten_fname(path, curdir);
- if (short_name == NULL)
+ if (short_name == NULL) {
short_name = path;
+ }
if (is_unique(short_name, gap, i)) {
STRCPY(fnames[i], short_name);
continue;
@@ -1040,14 +1053,16 @@ static void uniquefy_paths(garray_T *gap, char_u *pattern)
}
xfree(curdir);
- for (int i = 0; i < gap->ga_len; i++)
+ for (int i = 0; i < gap->ga_len; i++) {
xfree(in_curdir[i]);
+ }
xfree(in_curdir);
ga_clear_strings(&path_ga);
vim_regfree(regmatch.regprog);
- if (sort_again)
+ if (sort_again) {
ga_remove_duplicate_strings(gap);
+ }
}
/// Find end of the directory name
@@ -1072,8 +1087,9 @@ const char *gettail_dir(const char *const fname)
look_for_sep = false;
}
} else {
- if (!look_for_sep)
+ if (!look_for_sep) {
dir_end = next_dir_end;
+ }
look_for_sep = true;
}
MB_PTR_ADV(p);
@@ -1082,16 +1098,12 @@ const char *gettail_dir(const char *const fname)
}
-/*
- * Calls globpath() with 'path' values for the given pattern and stores the
- * result in "gap".
- * Returns the total number of matches.
- */
-static int expand_in_path(
- garray_T *const gap,
- char_u *const pattern,
- const int flags // EW_* flags
-)
+/// Calls globpath() with 'path' values for the given pattern and stores the
+/// result in "gap".
+/// Returns the total number of matches.
+///
+/// @param flags EW_* flags
+static int expand_in_path(garray_T *const gap, char_u *const pattern, const int flags)
{
garray_T path_ga;
@@ -1131,7 +1143,7 @@ static bool has_env_var(char_u *p)
for (; *p; MB_PTR_ADV(p)) {
if (*p == '\\' && p[1] != NUL) {
p++;
- } else if (vim_strchr((char_u *) "$" , *p) != NULL) {
+ } else if (vim_strchr((char_u *)"$", *p) != NULL) {
return true;
}
}
@@ -1186,8 +1198,7 @@ static bool has_special_wildchar(char_u *p)
/// If FAIL is returned, *num_file and *file are either
/// unchanged or *num_file is set to 0 and *file is set
/// to NULL or points to "".
-int gen_expand_wildcards(int num_pat, char_u **pat, int *num_file,
- char_u ***file, int flags)
+int gen_expand_wildcards(int num_pat, char_u **pat, int *num_file, char_u ***file, int flags)
{
garray_T ga;
char_u *p;
@@ -1203,9 +1214,9 @@ int gen_expand_wildcards(int num_pat, char_u **pat, int *num_file,
*/
if (recursive)
#ifdef SPECIAL_WILDCHAR
- return os_expand_wildcards(num_pat, pat, num_file, file, flags);
+ { return os_expand_wildcards(num_pat, pat, num_file, file, flags); }
#else
- return FAIL;
+ { return FAIL; }
#endif
#ifdef SPECIAL_WILDCHAR
@@ -1247,8 +1258,9 @@ int gen_expand_wildcards(int num_pat, char_u **pat, int *num_file,
// First expand environment variables, "~/" and "~user/".
if ((has_env_var(p) && !(flags & EW_NOTENV)) || *p == '~') {
p = expand_env_save_opt(p, true);
- if (p == NULL)
+ if (p == NULL) {
p = pat[i];
+ }
#ifdef UNIX
/*
* On Unix, if expand_env() can't expand an environment
@@ -1278,8 +1290,8 @@ int gen_expand_wildcards(int num_pat, char_u **pat, int *num_file,
&& !path_is_absolute(p)
&& !(p[0] == '.'
&& (vim_ispathsep(p[1])
- || (p[1] == '.' && vim_ispathsep(p[2]))))
- ) {
+ || (p[1] == '.' &&
+ vim_ispathsep(p[2]))))) {
/* :find completion where 'path' is used.
* Recursiveness is OK here. */
recursive = false;
@@ -1295,7 +1307,7 @@ int gen_expand_wildcards(int num_pat, char_u **pat, int *num_file,
}
if (add_pat == -1 || (add_pat == 0 && (flags & EW_NOTFOUND))) {
- char_u *t = backslash_halve_save(p);
+ char_u *t = backslash_halve_save(p);
/* When EW_NOTFOUND is used, always add files and dirs. Makes
* "vim c:/" work. */
@@ -1310,10 +1322,12 @@ int gen_expand_wildcards(int num_pat, char_u **pat, int *num_file,
}
}
- if (did_expand_in_path && !GA_EMPTY(&ga) && (flags & EW_PATH))
+ if (did_expand_in_path && !GA_EMPTY(&ga) && (flags & EW_PATH)) {
uniquefy_paths(&ga, p);
- if (p != pat[i])
+ }
+ if (p != pat[i]) {
xfree(p);
+ }
}
*num_file = ga.ga_len;
@@ -1333,14 +1347,12 @@ static int vim_backtick(char_u *p)
return *p == '`' && *(p + 1) != NUL && *(p + STRLEN(p) - 1) == '`';
}
-// Expand an item in `backticks` by executing it as a command.
-// Currently only works when pat[] starts and ends with a `.
-// Returns number of file names found, -1 if an error is encountered.
-static int expand_backtick(
- garray_T *gap,
- char_u *pat,
- int flags /* EW_* flags */
-)
+/// Expand an item in `backticks` by executing it as a command.
+/// Currently only works when pat[] starts and ends with a `.
+/// Returns number of file names found, -1 if an error is encountered.
+///
+/// @param flags EW_* flags
+static int expand_backtick(garray_T *gap, char_u *pat, int flags)
{
char_u *p;
char_u *buffer;
@@ -1349,11 +1361,11 @@ static int expand_backtick(
// Create the command: lop off the backticks.
char_u *cmd = vim_strnsave(pat + 1, STRLEN(pat) - 2);
- if (*cmd == '=') /* `={expr}`: Expand expression */
- buffer = eval_to_string(cmd + 1, &p, TRUE);
- else
- buffer = get_cmd_output(cmd, NULL,
- (flags & EW_SILENT) ? kShellOptSilent : 0, NULL);
+ if (*cmd == '=') { // `={expr}`: Expand expression
+ buffer = eval_to_string(cmd + 1, &p, true);
+ } else {
+ buffer = get_cmd_output(cmd, NULL, (flags & EW_SILENT) ? kShellOptSilent : 0, NULL);
+ }
xfree(cmd);
if (buffer == NULL) {
return -1;
@@ -1361,11 +1373,12 @@ static int expand_backtick(
cmd = buffer;
while (*cmd != NUL) {
- cmd = skipwhite(cmd); /* skip over white space */
+ cmd = skipwhite(cmd); // skip over white space
p = cmd;
- while (*p != NUL && *p != '\r' && *p != '\n') /* skip over entry */
+ while (*p != NUL && *p != '\r' && *p != '\n') { // skip over entry
++p;
- /* add an entry if it is not empty */
+ }
+ // add an entry if it is not empty
if (p > cmd) {
char_u i = *p;
*p = NUL;
@@ -1374,8 +1387,9 @@ static int expand_backtick(
++cnt;
}
cmd = p;
- while (*cmd != NUL && (*cmd == '\r' || *cmd == '\n'))
+ while (*cmd != NUL && (*cmd == '\r' || *cmd == '\n')) {
++cmd;
+ }
}
xfree(buffer);
@@ -1414,18 +1428,16 @@ void slash_adjust(char_u *p)
}
#endif
-// Add a file to a file list. Accepted flags:
-// EW_DIR add directories
-// EW_FILE add files
-// EW_EXEC add executable files
-// EW_NOTFOUND add even when it doesn't exist
-// EW_ADDSLASH add slash after directory name
-// EW_ALLLINKS add symlink also when the referred file does not exist
-void addfile(
- garray_T *gap,
- char_u *f, /* filename */
- int flags
-)
+/// Add a file to a file list. Accepted flags:
+/// EW_DIR add directories
+/// EW_FILE add files
+/// EW_EXEC add executable files
+/// EW_NOTFOUND add even when it doesn't exist
+/// EW_ADDSLASH add slash after directory name
+/// EW_ALLLINKS add symlink also when the referred file does not exist
+///
+/// @param f filename
+void addfile(garray_T *gap, char_u *f, int flags)
{
bool isdir;
FileInfo file_info;
@@ -1439,14 +1451,16 @@ void addfile(
}
#ifdef FNAME_ILLEGAL
- /* if the file/dir contains illegal characters, don't add it */
- if (vim_strpbrk(f, (char_u *)FNAME_ILLEGAL) != NULL)
+ // if the file/dir contains illegal characters, don't add it
+ if (vim_strpbrk(f, (char_u *)FNAME_ILLEGAL) != NULL) {
return;
+ }
#endif
isdir = os_isdir(f);
- if ((isdir && !(flags & EW_DIR)) || (!isdir && !(flags & EW_FILE)))
+ if ((isdir && !(flags & EW_DIR)) || (!isdir && !(flags & EW_FILE))) {
return;
+ }
// If the file isn't executable, may not add it. Do accept directories.
// When invoked from expand_shellcmd() do not use $PATH.
@@ -1464,8 +1478,9 @@ void addfile(
/*
* Append a slash or backslash after directory names if none is present.
*/
- if (isdir && (flags & EW_ADDSLASH))
+ if (isdir && (flags & EW_ADDSLASH)) {
add_pathsep((char *)p);
+ }
GA_APPEND(char_u *, gap, p);
}
@@ -1478,14 +1493,15 @@ void addfile(
void simplify_filename(char_u *filename)
{
int components = 0;
- char_u *p, *tail, *start;
+ char_u *p, *tail, *start;
bool stripping_disabled = false;
bool relative = true;
p = filename;
#ifdef BACKSLASH_IN_FILENAME
- if (p[1] == ':') /* skip "x:" */
+ if (p[1] == ':') { // skip "x:"
p += 2;
+ }
#endif
if (vim_ispathsep(*p)) {
@@ -1494,17 +1510,18 @@ void simplify_filename(char_u *filename)
++p;
while (vim_ispathsep(*p));
}
- start = p; /* remember start after "c:/" or "/" or "///" */
+ start = p; // remember start after "c:/" or "/" or "///"
do {
/* At this point "p" is pointing to the char following a single "/"
* or "p" is at the "start" of the (absolute or relative) path name. */
- if (vim_ispathsep(*p))
- STRMOVE(p, p + 1); /* remove duplicate "/" */
- else if (p[0] == '.' && (vim_ispathsep(p[1]) || p[1] == NUL)) {
- if (p == start && relative)
- p += 1 + (p[1] != NUL); /* keep single "." or leading "./" */
- else {
+ if (vim_ispathsep(*p)) {
+ STRMOVE(p, p + 1); // remove duplicate "/"
+ } else if (p[0] == '.' &&
+ (vim_ispathsep(p[1]) || p[1] == NUL)) {
+ if (p == start && relative) {
+ p += 1 + (p[1] != NUL); // keep single "." or leading "./"
+ } else {
/* Strip "./" or ".///". If we are at the end of the file name
* and there is no trailing path separator, either strip "/." if
* we are after "start", or strip "." if we are at the beginning
@@ -1527,11 +1544,11 @@ void simplify_filename(char_u *filename)
MB_PTR_ADV(tail);
}
- if (components > 0) { /* strip one preceding component */
+ if (components > 0) { // strip one preceding component
bool do_strip = false;
char_u saved_char;
- /* Don't strip for an erroneous file name. */
+ // Don't strip for an erroneous file name.
if (!stripping_disabled) {
/* If the preceding component does not exist in the file
* system, we strip it. On Unix, we don't accept a symbolic
@@ -1613,21 +1630,22 @@ void simplify_filename(char_u *filename)
*p++ = '.';
*p = NUL;
} else {
- if (p > start && tail[-1] == '.')
+ if (p > start && tail[-1] == '.') {
--p;
- STRMOVE(p, tail); /* strip previous component */
+ }
+ STRMOVE(p, tail); // strip previous component
}
--components;
}
- } else if (p == start && !relative) /* leading "/.." or "/../" */
- STRMOVE(p, tail); /* strip ".." or "../" */
- else {
- if (p == start + 2 && p[-2] == '.') { /* leading "./../" */
- STRMOVE(p - 2, p); /* strip leading "./" */
+ } else if (p == start && !relative) { // leading "/.." or "/../"
+ STRMOVE(p, tail); // strip ".." or "../"
+ } else {
+ if (p == start + 2 && p[-2] == '.') { // leading "./../"
+ STRMOVE(p - 2, p); // strip leading "./"
tail -= 2;
}
- p = tail; /* skip to char after ".." or "../" */
+ p = tail; // skip to char after ".." or "../"
}
} else {
components++; // Simple path component.
@@ -1639,31 +1657,24 @@ void simplify_filename(char_u *filename)
static char *eval_includeexpr(const char *const ptr, const size_t len)
{
set_vim_var_string(VV_FNAME, ptr, (ptrdiff_t)len);
- char *res = (char *)eval_to_string_safe(
- curbuf->b_p_inex, NULL,
- was_set_insecurely(curwin, (char_u *)"includeexpr", OPT_LOCAL));
+ char *res = (char *)eval_to_string_safe(curbuf->b_p_inex, NULL,
+ was_set_insecurely(curwin, (char_u *)"includeexpr",
+ OPT_LOCAL));
set_vim_var_string(VV_FNAME, NULL, 0);
return res;
}
-/*
- * Return the name of the file ptr[len] in 'path'.
- * Otherwise like file_name_at_cursor().
- */
-char_u *
-find_file_name_in_path (
- char_u *ptr,
- size_t len,
- int options,
- long count,
- char_u *rel_fname /* file we are searching relative to */
-)
+/// Return the name of the file ptr[len] in 'path'.
+/// Otherwise like file_name_at_cursor().
+///
+/// @param rel_fname file we are searching relative to
+char_u *find_file_name_in_path(char_u *ptr, size_t len, int options, long count, char_u *rel_fname)
{
char_u *file_name;
char_u *tofree = NULL;
if ((options & FNAME_INCL) && *curbuf->b_p_inex != NUL) {
- tofree = (char_u *) eval_includeexpr((char *) ptr, len);
+ tofree = (char_u *)eval_includeexpr((char *)ptr, len);
if (tofree != NULL) {
ptr = tofree;
len = STRLEN(ptr);
@@ -1680,7 +1691,7 @@ find_file_name_in_path (
*/
if (file_name == NULL
&& !(options & FNAME_INCL) && *curbuf->b_p_inex != NUL) {
- tofree = (char_u *) eval_includeexpr((char *) ptr, len);
+ tofree = (char_u *)eval_includeexpr((char *)ptr, len);
if (tofree != NULL) {
ptr = tofree;
len = STRLEN(ptr);
@@ -1701,8 +1712,9 @@ find_file_name_in_path (
xfree(file_name);
file_name = find_file_in_path(ptr, len, options, FALSE, rel_fname);
}
- } else
+ } else {
file_name = vim_strnsave(ptr, len);
+ }
xfree(tofree);
@@ -1714,10 +1726,11 @@ find_file_name_in_path (
// URL_BACKSLASH.
int path_is_url(const char *p)
{
- if (strncmp(p, "://", 3) == 0)
+ if (strncmp(p, "://", 3) == 0) {
return URL_SLASH;
- else if (strncmp(p, ":\\\\", 3) == 0)
+ } else if (strncmp(p, ":\\\\", 3) == 0) {
return URL_BACKSLASH;
+ }
return 0;
}
@@ -1735,7 +1748,9 @@ int path_with_url(const char *fname)
bool path_with_extension(const char *path, const char *extension)
{
const char *last_dot = strrchr(path, '.');
- if (!last_dot) { return false; }
+ if (!last_dot) {
+ return false;
+ }
return strcmp(last_dot + 1, extension) == 0;
}
@@ -1809,8 +1824,9 @@ char *fix_fname(const char *fname)
# ifdef BACKSLASH_IN_FILENAME
|| strstr(fname, "\\\\") != NULL
# endif
- )
+ ) {
return FullName_save(fname, false);
+ }
fname = xstrdup(fname);
@@ -1845,7 +1861,7 @@ void path_fix_case(char_u *name)
tail = name;
} else {
*slash = NUL;
- ok = os_scandir(&dir, (char *) name);
+ ok = os_scandir(&dir, (char *)name);
*slash = '/';
tail = slash + 1;
}
@@ -1855,7 +1871,7 @@ void path_fix_case(char_u *name)
}
char_u *entry;
- while ((entry = (char_u *) os_scandir_next(&dir))) {
+ while ((entry = (char_u *)os_scandir_next(&dir))) {
// Only accept names that differ in case and are the same byte
// length. TODO: accept different length name.
if (STRICMP(tail, entry) == 0 && STRLEN(tail) == STRLEN(entry)) {
@@ -1895,12 +1911,13 @@ int after_pathsep(const char *b, const char *p)
bool same_directory(char_u *f1, char_u *f2)
{
char_u ffname[MAXPATHL];
- char_u *t1;
- char_u *t2;
+ char_u *t1;
+ char_u *t2;
- /* safety check */
- if (f1 == NULL || f2 == NULL)
+ // safety check
+ if (f1 == NULL || f2 == NULL) {
return false;
+ }
(void)vim_FullName((char *)f1, (char *)ffname, MAXPATHL, FALSE);
t1 = path_tail_with_sep(ffname);
@@ -1918,22 +1935,23 @@ int pathcmp(const char *p, const char *q, int maxlen)
{
int i, j;
int c1, c2;
- const char *s = NULL;
+ const char *s = NULL;
for (i = 0, j = 0; maxlen < 0 || (i < maxlen && j < maxlen);) {
c1 = PTR2CHAR((char_u *)p + i);
c2 = PTR2CHAR((char_u *)q + j);
- /* End of "p": check if "q" also ends or just has a slash. */
+ // End of "p": check if "q" also ends or just has a slash.
if (c1 == NUL) {
- if (c2 == NUL) /* full match */
+ if (c2 == NUL) { // full match
return 0;
+ }
s = q;
i = j;
break;
}
- /* End of "q": check if "p" just has a slash. */
+ // End of "q": check if "p" just has a slash.
if (c2 == NUL) {
s = p;
break;
@@ -1941,15 +1959,17 @@ int pathcmp(const char *p, const char *q, int maxlen)
if ((p_fic ? mb_toupper(c1) != mb_toupper(c2) : c1 != c2)
#ifdef BACKSLASH_IN_FILENAME
- /* consider '/' and '\\' to be equal */
+ // consider '/' and '\\' to be equal
&& !((c1 == '/' && c2 == '\\')
|| (c1 == '\\' && c2 == '/'))
#endif
) {
- if (vim_ispathsep(c1))
+ if (vim_ispathsep(c1)) {
return -1;
- if (vim_ispathsep(c2))
+ }
+ if (vim_ispathsep(c2)) {
return 1;
+ }
return p_fic ? mb_toupper(c1) - mb_toupper(c2)
: c1 - c2; // no match
}
@@ -2057,26 +2077,27 @@ char_u *path_shorten_fname(char_u *full_path, char_u *dir_name)
/// If FAIL is returned, *num_file and *file are either
/// unchanged or *num_file is set to 0 and *file is set
/// to NULL or points to "".
-int expand_wildcards_eval(char_u **pat, int *num_file, char_u ***file,
- int flags)
+int expand_wildcards_eval(char_u **pat, int *num_file, char_u ***file, int flags)
{
int ret = FAIL;
- char_u *eval_pat = NULL;
- char_u *exp_pat = *pat;
- char_u *ignored_msg;
+ char_u *eval_pat = NULL;
+ char_u *exp_pat = *pat;
+ char_u *ignored_msg;
size_t usedlen;
if (*exp_pat == '%' || *exp_pat == '#' || *exp_pat == '<') {
++emsg_off;
eval_pat = eval_vars(exp_pat, exp_pat, &usedlen,
- NULL, &ignored_msg, NULL);
+ NULL, &ignored_msg, NULL);
--emsg_off;
- if (eval_pat != NULL)
+ if (eval_pat != NULL) {
exp_pat = concat_str(eval_pat, exp_pat + usedlen);
+ }
}
- if (exp_pat != NULL)
+ if (exp_pat != NULL) {
ret = expand_wildcards(1, &exp_pat, num_file, file, flags);
+ }
if (eval_pat != NULL) {
xfree(exp_pat);
@@ -2100,25 +2121,25 @@ int expand_wildcards_eval(char_u **pat, int *num_file, char_u ***file,
/// If FAIL is returned, *num_file and *file are either
/// unchanged or *num_file is set to 0 and *file is set to
/// NULL or points to "".
-int expand_wildcards(int num_pat, char_u **pat, int *num_files, char_u ***files,
- int flags)
+int expand_wildcards(int num_pat, char_u **pat, int *num_files, char_u ***files, int flags)
{
int retval;
int i, j;
- char_u *p;
- int non_suf_match; /* number without matching suffix */
+ char_u *p;
+ int non_suf_match; // number without matching suffix
retval = gen_expand_wildcards(num_pat, pat, num_files, files, flags);
- /* When keeping all matches, return here */
- if ((flags & EW_KEEPALL) || retval == FAIL)
+ // When keeping all matches, return here
+ if ((flags & EW_KEEPALL) || retval == FAIL) {
return retval;
+ }
/*
* Remove names that match 'wildignore'.
*/
if (*p_wig) {
- char_u *ffname;
+ char_u *ffname;
// check all files in (*files)[]
assert(*num_files == 0 || *files != NULL);
@@ -2183,7 +2204,7 @@ int match_suffix(char_u *fname)
if (setsuflen == 0) {
char_u *tail = path_tail(fname);
- /* empty entry: match name without a '.' */
+ // empty entry: match name without a '.'
if (vim_strchr(tail, '.') == NULL) {
setsuflen = 1;
break;
@@ -2209,13 +2230,13 @@ int path_full_dir_name(char *directory, char *buffer, size_t len)
int retval = OK;
if (STRLEN(directory) == 0) {
- return os_dirname((char_u *) buffer, len);
+ return os_dirname((char_u *)buffer, len);
}
char old_dir[MAXPATHL];
// Get current directory name.
- if (os_dirname((char_u *) old_dir, MAXPATHL) == FAIL) {
+ if (os_dirname((char_u *)old_dir, MAXPATHL) == FAIL) {
return FAIL;
}
@@ -2229,7 +2250,7 @@ int path_full_dir_name(char *directory, char *buffer, size_t len)
retval = FAIL;
}
- if (retval == FAIL || os_dirname((char_u *) buffer, len) == FAIL) {
+ if (retval == FAIL || os_dirname((char_u *)buffer, len) == FAIL) {
// Do not return immediately since we are in the wrong directory.
retval = FAIL;
}
@@ -2283,14 +2304,13 @@ int append_path(char *path, const char *to_append, size_t max_len)
/// @param force also expand when "fname" is already absolute.
///
/// @return FAIL for failure, OK for success.
-static int path_to_absolute(const char_u *fname, char_u *buf, size_t len,
- int force)
+static int path_to_absolute(const char_u *fname, char_u *buf, size_t len, int force)
{
char_u *p;
*buf = NUL;
char *relative_directory = xmalloc(len);
- char *end_of_path = (char *) fname;
+ char *end_of_path = (char *)fname;
// expand it if forced or not an absolute path
if (force || !path_is_absolute(fname)) {
@@ -2311,13 +2331,13 @@ static int path_to_absolute(const char_u *fname, char_u *buf, size_t len,
memcpy(relative_directory, fname, (size_t)(p - fname));
relative_directory[p-fname] = NUL;
}
- end_of_path = (char *) (p + 1);
+ end_of_path = (char *)(p + 1);
} else {
relative_directory[0] = NUL;
- end_of_path = (char *) fname;
+ end_of_path = (char *)fname;
}
- if (FAIL == path_full_dir_name(relative_directory, (char *) buf, len)) {
+ if (FAIL == path_full_dir_name(relative_directory, (char *)buf, len)) {
xfree(relative_directory);
return FAIL;
}
diff --git a/src/nvim/plines.c b/src/nvim/plines.c
new file mode 100644
index 0000000000..5b0418ed92
--- /dev/null
+++ b/src/nvim/plines.c
@@ -0,0 +1,510 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
+// plines.c: calculate the vertical and horizontal size of text in a window
+
+#include <assert.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include "nvim/ascii.h"
+#include "nvim/buffer.h"
+#include "nvim/charset.h"
+#include "nvim/cursor.h"
+#include "nvim/decoration.h"
+#include "nvim/diff.h"
+#include "nvim/fold.h"
+#include "nvim/func_attr.h"
+#include "nvim/indent.h"
+#include "nvim/main.h"
+#include "nvim/mbyte.h"
+#include "nvim/memline.h"
+#include "nvim/memory.h"
+#include "nvim/move.h"
+#include "nvim/option.h"
+#include "nvim/plines.h"
+#include "nvim/screen.h"
+#include "nvim/strings.h"
+#include "nvim/vim.h"
+#include "nvim/window.h"
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "plines.c.generated.h"
+#endif
+
+/// Functions calculating vertical size of text when displayed inside a window.
+/// Calls horizontal size functions defined below.
+
+/// @param winheight when true limit to window height
+int plines_win(win_T *wp, linenr_T lnum, bool winheight)
+{
+ // Check for filler lines above this buffer line. When folded the result
+ // is one line anyway.
+ return plines_win_nofill(wp, lnum, winheight) + win_get_fill(wp, lnum);
+}
+
+
+/// Return the number of filler lines above "lnum".
+///
+/// @param wp
+/// @param lnum
+///
+/// @return Number of filler lines above lnum
+int win_get_fill(win_T *wp, linenr_T lnum)
+{
+ int virt_lines = decor_virtual_lines(wp, lnum);
+
+ // be quick when there are no filler lines
+ if (diffopt_filler()) {
+ int n = diff_check(wp, lnum);
+
+ if (n > 0) {
+ return virt_lines+n;
+ }
+ }
+ return virt_lines;
+}
+
+bool win_may_fill(win_T *wp)
+{
+ return (wp->w_p_diff && diffopt_filler()) || wp->w_buffer->b_virt_line_mark;
+}
+
+/// @param winheight when true limit to window height
+int plines_win_nofill(win_T *wp, linenr_T lnum, bool winheight)
+{
+ if (!wp->w_p_wrap) {
+ return 1;
+ }
+
+ if (wp->w_width_inner == 0) {
+ return 1;
+ }
+
+ // A folded lines is handled just like an empty line.
+ if (lineFolded(wp, lnum)) {
+ return 1;
+ }
+
+ const int lines = plines_win_nofold(wp, lnum);
+ if (winheight && lines > wp->w_height_inner) {
+ return wp->w_height_inner;
+ }
+ return lines;
+}
+
+/// @Return number of window lines physical line "lnum" will occupy in window
+/// "wp". Does not care about folding, 'wrap' or 'diff'.
+int plines_win_nofold(win_T *wp, linenr_T lnum)
+{
+ char_u *s;
+ unsigned int col;
+ int width;
+
+ s = ml_get_buf(wp->w_buffer, lnum, false);
+ if (*s == NUL) { // empty line
+ return 1;
+ }
+ col = win_linetabsize(wp, s, MAXCOL);
+
+ // If list mode is on, then the '$' at the end of the line may take up one
+ // extra column.
+ if (wp->w_p_list && wp->w_p_lcs_chars.eol != NUL) {
+ col += 1;
+ }
+
+ // Add column offset for 'number', 'relativenumber' and 'foldcolumn'.
+ width = wp->w_width_inner - win_col_off(wp);
+ if (width <= 0 || col > 32000) {
+ return 32000; // bigger than the number of screen columns
+ }
+ if (col <= (unsigned int)width) {
+ return 1;
+ }
+ col -= (unsigned int)width;
+ width += win_col_off2(wp);
+ assert(col <= INT_MAX && (int)col < INT_MAX - (width -1));
+ return ((int)col + (width - 1)) / width + 1;
+}
+
+/// Like plines_win(), but only reports the number of physical screen lines
+/// used from the start of the line to the given column number.
+int plines_win_col(win_T *wp, linenr_T lnum, long column)
+{
+ // Check for filler lines above this buffer line. When folded the result
+ // is one line anyway.
+ int lines = win_get_fill(wp, lnum);
+
+ if (!wp->w_p_wrap) {
+ return lines + 1;
+ }
+
+ if (wp->w_width_inner == 0) {
+ return lines + 1;
+ }
+
+ char_u *line = ml_get_buf(wp->w_buffer, lnum, false);
+ char_u *s = line;
+
+ colnr_T col = 0;
+ while (*s != NUL && --column >= 0) {
+ col += win_lbr_chartabsize(wp, line, s, col, NULL);
+ MB_PTR_ADV(s);
+ }
+
+ // If *s is a TAB, and the TAB is not displayed as ^I, and we're not in
+ // INSERT mode, then col must be adjusted so that it represents the last
+ // screen position of the TAB. This only fixes an error when the TAB wraps
+ // from one screen line to the next (when 'columns' is not a multiple of
+ // 'ts') -- webb.
+ if (*s == TAB && (State & NORMAL)
+ && (!wp->w_p_list || wp->w_p_lcs_chars.tab1)) {
+ col += win_lbr_chartabsize(wp, line, s, col, NULL) - 1;
+ }
+
+ // Add column offset for 'number', 'relativenumber', 'foldcolumn', etc.
+ int width = wp->w_width_inner - win_col_off(wp);
+ if (width <= 0) {
+ return 9999;
+ }
+
+ lines += 1;
+ if (col > width) {
+ lines += (col - width) / (width + win_col_off2(wp)) + 1;
+ }
+ return lines;
+}
+
+/// Get the number of screen lines lnum takes up. This takes care of
+/// both folds and topfill, and limits to the current window height.
+///
+/// @param[in] wp window line is in
+/// @param[in] lnum line number
+/// @param[out] nextp if not NULL, the line after a fold
+/// @param[out] foldedp if not NULL, whether lnum is on a fold
+/// @param[in] cache whether to use the window's cache for folds
+///
+/// @return the total number of screen lines
+int plines_win_full(win_T *wp, linenr_T lnum, linenr_T *const nextp, bool *const foldedp,
+ const bool cache)
+{
+ bool folded = hasFoldingWin(wp, lnum, NULL, nextp, cache, NULL);
+ if (foldedp) {
+ *foldedp = folded;
+ }
+ if (folded) {
+ return 1;
+ } else if (lnum == wp->w_topline) {
+ return plines_win_nofill(wp, lnum, true) + wp->w_topfill;
+ }
+ return plines_win(wp, lnum, true);
+}
+
+int plines_m_win(win_T *wp, linenr_T first, linenr_T last)
+{
+ int count = 0;
+
+ while (first <= last) {
+ linenr_T next = first;
+ count += plines_win_full(wp, first, &next, NULL, false);
+ first = next + 1;
+ }
+ return count;
+}
+
+/// Functions calculating horizontal size of text, when displayed in a window.
+
+/// Return the number of characters 'c' will take on the screen, taking
+/// into account the size of a tab.
+/// Also see getvcol()
+///
+/// @param p
+/// @param col
+///
+/// @return Number of characters.
+int win_chartabsize(win_T *wp, char_u *p, colnr_T col)
+{
+ buf_T *buf = wp->w_buffer;
+ if (*p == TAB && (!wp->w_p_list || wp->w_p_lcs_chars.tab1)) {
+ return tabstop_padding(col, buf->b_p_ts, buf->b_p_vts_array);
+ } else {
+ return ptr2cells(p);
+ }
+}
+
+/// Return the number of characters the string 's' will take on the screen,
+/// taking into account the size of a tab.
+///
+/// @param s
+///
+/// @return Number of characters the string will take on the screen.
+int linetabsize(char_u *s)
+{
+ return linetabsize_col(0, s);
+}
+
+/// Like linetabsize(), but starting at column "startcol".
+///
+/// @param startcol
+/// @param s
+///
+/// @return Number of characters the string will take on the screen.
+int linetabsize_col(int startcol, char_u *s)
+{
+ colnr_T col = startcol;
+ char_u *line = s; // pointer to start of line, for breakindent
+
+ while (*s != NUL) {
+ col += lbr_chartabsize_adv(line, &s, col);
+ }
+ return (int)col;
+}
+
+/// Like linetabsize(), but for a given window instead of the current one.
+///
+/// @param wp
+/// @param line
+/// @param len
+///
+/// @return Number of characters the string will take on the screen.
+unsigned int win_linetabsize(win_T *wp, char_u *line, colnr_T len)
+{
+ colnr_T col = 0;
+
+ for (char_u *s = line;
+ *s != NUL && (len == MAXCOL || s < line + len);
+ MB_PTR_ADV(s)) {
+ col += win_lbr_chartabsize(wp, line, s, col, NULL);
+ }
+
+ return (unsigned int)col;
+}
+
+/// like win_chartabsize(), but also check for line breaks on the screen
+///
+/// @param line
+/// @param s
+/// @param col
+///
+/// @return The number of characters taken up on the screen.
+int lbr_chartabsize(char_u *line, unsigned char *s, colnr_T col)
+{
+ if (!curwin->w_p_lbr && *get_showbreak_value(curwin) == NUL
+ && !curwin->w_p_bri) {
+ if (curwin->w_p_wrap) {
+ return win_nolbr_chartabsize(curwin, s, col, NULL);
+ }
+ return win_chartabsize(curwin, s, col);
+ }
+ return win_lbr_chartabsize(curwin, line == NULL ? s: line, s, col, NULL);
+}
+
+/// Call lbr_chartabsize() and advance the pointer.
+///
+/// @param line
+/// @param s
+/// @param col
+///
+/// @return The number of characters take up on the screen.
+int lbr_chartabsize_adv(char_u *line, char_u **s, colnr_T col)
+{
+ int retval;
+
+ retval = lbr_chartabsize(line, *s, col);
+ MB_PTR_ADV(*s);
+ return retval;
+}
+
+/// This function is used very often, keep it fast!!!!
+///
+/// If "headp" not NULL, set *headp to the size of what we for 'showbreak'
+/// string at start of line. Warning: *headp is only set if it's a non-zero
+/// value, init to 0 before calling.
+///
+/// @param wp
+/// @param line
+/// @param s
+/// @param col
+/// @param headp
+///
+/// @return The number of characters taken up on the screen.
+int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s, colnr_T col, int *headp)
+{
+ colnr_T col2;
+ colnr_T col_adj = 0; // col + screen size of tab
+ colnr_T colmax;
+ int added;
+ int mb_added = 0;
+ int numberextra;
+ char_u *ps;
+ int n;
+
+ // No 'linebreak', 'showbreak' and 'breakindent': return quickly.
+ if (!wp->w_p_lbr && !wp->w_p_bri && *get_showbreak_value(wp) == NUL) {
+ if (wp->w_p_wrap) {
+ return win_nolbr_chartabsize(wp, s, col, headp);
+ }
+ return win_chartabsize(wp, s, col);
+ }
+
+ // First get normal size, without 'linebreak'
+ int size = win_chartabsize(wp, s, col);
+ int c = *s;
+ if (*s == TAB) {
+ col_adj = size - 1;
+ }
+
+ // If 'linebreak' set check at a blank before a non-blank if the line
+ // needs a break here
+ if (wp->w_p_lbr
+ && vim_isbreak(c)
+ && !vim_isbreak((int)s[1])
+ && wp->w_p_wrap
+ && (wp->w_width_inner != 0)) {
+ // Count all characters from first non-blank after a blank up to next
+ // non-blank after a blank.
+ numberextra = win_col_off(wp);
+ col2 = col;
+ colmax = (colnr_T)(wp->w_width_inner - numberextra - col_adj);
+
+ if (col >= colmax) {
+ colmax += col_adj;
+ n = colmax + win_col_off2(wp);
+
+ if (n > 0) {
+ colmax += (((col - colmax) / n) + 1) * n - col_adj;
+ }
+ }
+
+ for (;;) {
+ ps = s;
+ MB_PTR_ADV(s);
+ c = *s;
+
+ if (!(c != NUL
+ && (vim_isbreak(c) || col2 == col || !vim_isbreak((int)(*ps))))) {
+ break;
+ }
+
+ col2 += win_chartabsize(wp, s, col2);
+
+ if (col2 >= colmax) { // doesn't fit
+ size = colmax - col + col_adj;
+ break;
+ }
+ }
+ } else if ((size == 2)
+ && (MB_BYTE2LEN(*s) > 1)
+ && wp->w_p_wrap
+ && in_win_border(wp, col)) {
+ // Count the ">" in the last column.
+ size++;
+ mb_added = 1;
+ }
+
+ // May have to add something for 'breakindent' and/or 'showbreak'
+ // string at start of line.
+ // Set *headp to the size of what we add.
+ added = 0;
+
+ char_u *const sbr = get_showbreak_value(wp);
+ if ((*sbr != NUL || wp->w_p_bri) && wp->w_p_wrap && col != 0) {
+ colnr_T sbrlen = 0;
+ int numberwidth = win_col_off(wp);
+
+ numberextra = numberwidth;
+ col += numberextra + mb_added;
+
+ if (col >= (colnr_T)wp->w_width_inner) {
+ col -= wp->w_width_inner;
+ numberextra = wp->w_width_inner - (numberextra - win_col_off2(wp));
+ if (col >= numberextra && numberextra > 0) {
+ col %= numberextra;
+ }
+ if (*sbr != NUL) {
+ sbrlen = (colnr_T)MB_CHARLEN(sbr);
+ if (col >= sbrlen) {
+ col -= sbrlen;
+ }
+ }
+ if (col >= numberextra && numberextra > 0) {
+ col %= numberextra;
+ } else if (col > 0 && numberextra > 0) {
+ col += numberwidth - win_col_off2(wp);
+ }
+
+ numberwidth -= win_col_off2(wp);
+ }
+
+ if (col == 0 || (col + size + sbrlen > (colnr_T)wp->w_width_inner)) {
+ if (*sbr != NUL) {
+ if (size + sbrlen + numberwidth > (colnr_T)wp->w_width_inner) {
+ // Calculate effective window width.
+ int width = (colnr_T)wp->w_width_inner - sbrlen - numberwidth;
+ int prev_width = col ? ((colnr_T)wp->w_width_inner - (sbrlen + col))
+ : 0;
+
+ if (width <= 0) {
+ width = 1;
+ }
+ added += ((size - prev_width) / width) * vim_strsize(sbr);
+ if ((size - prev_width) % width) {
+ // Wrapped, add another length of 'sbr'.
+ added += vim_strsize(sbr);
+ }
+ } else {
+ added += vim_strsize(sbr);
+ }
+ }
+
+ if (wp->w_p_bri) {
+ added += get_breakindent_win(wp, line);
+ }
+
+ size += added;
+ if (col != 0) {
+ added = 0;
+ }
+ }
+ }
+
+ if (headp != NULL) {
+ *headp = added + mb_added;
+ }
+ return size;
+}
+
+/// Like win_lbr_chartabsize(), except that we know 'linebreak' is off and
+/// 'wrap' is on. This means we need to check for a double-byte character that
+/// doesn't fit at the end of the screen line.
+///
+/// @param wp
+/// @param s
+/// @param col
+/// @param headp
+///
+/// @return The number of characters take up on the screen.
+static int win_nolbr_chartabsize(win_T *wp, char_u *s, colnr_T col, int *headp)
+{
+ int n;
+
+ if ((*s == TAB) && (!wp->w_p_list || wp->w_p_lcs_chars.tab1)) {
+ return tabstop_padding(col,
+ wp->w_buffer->b_p_ts,
+ wp->w_buffer->b_p_vts_array);
+ }
+ n = ptr2cells(s);
+
+ // Add one cell for a double-width character in the last column of the
+ // window, displayed with a ">".
+ if ((n == 2) && (MB_BYTE2LEN(*s) > 1) && in_win_border(wp, col)) {
+ if (headp != NULL) {
+ *headp = 1;
+ }
+ return 3;
+ }
+ return n;
+}
+
diff --git a/src/nvim/plines.h b/src/nvim/plines.h
new file mode 100644
index 0000000000..32778b69f1
--- /dev/null
+++ b/src/nvim/plines.h
@@ -0,0 +1,9 @@
+#ifndef NVIM_PLINES_H
+#define NVIM_PLINES_H
+
+#include "nvim/vim.h"
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "plines.h.generated.h"
+#endif
+#endif // NVIM_PLINES_H
diff --git a/src/nvim/po/sr.po b/src/nvim/po/sr.po
index 1450ab5164..d34c1c3100 100644
--- a/src/nvim/po/sr.po
+++ b/src/nvim/po/sr.po
@@ -2,7 +2,7 @@
#
# Do ":help uganda" in Vim to read copying and usage conditions.
# Do ":help credits" in Vim to see a list of people who contributed.
-# Copyright (C) 2017
+# Copyright (C) 2021
# This file is distributed under the same license as the Vim package.
# FIRST AUTHOR Ivan Pešić <ivan.pesic@gmail.com>, 2017.
#
@@ -10,8 +10,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Vim(Serbian)\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-02-14 01:49+0400\n"
-"PO-Revision-Date: 2021-02-14 01:54+0400\n"
+"POT-Creation-Date: 2021-06-13 13:16+0400\n"
+"PO-Revision-Date: 2021-06-13 13:50+0400\n"
"Last-Translator: Ivan Pešić <ivan.pesic@gmail.com>\n"
"Language-Team: Serbian\n"
"Language: sr\n"
@@ -97,6 +97,9 @@ msgstr "Извршавање %s"
msgid "autocommand %s"
msgstr "аутокоманда %s"
+msgid "E972: Blob value does not have the right number of bytes"
+msgstr "E972: Блоб вредност нема одговарајући број бајтова"
+
msgid "E831: bf_key_init() called with empty password"
msgstr "E831: bf_key_init() је позвана са празном лозинком"
@@ -866,7 +869,7 @@ msgid "E976: using Blob as a String"
msgstr "E976: коришћење Blob као String"
msgid "E908: using an invalid value as a String"
-msgstr "E908: користи се недозвољена вредност као String"
+msgstr "E908: Користи се неважећа вредност као Стринг: %s"
msgid "E698: variable nested too deep for making a copy"
msgstr "E698: променљива је предубоко угњеждена да би се направила копија"
@@ -913,7 +916,7 @@ msgid "E928: String required"
msgstr "E928: Захтева се String"
msgid "E808: Number or Float required"
-msgstr "E808: Захтева се Number или Float"
+msgstr "E808: Захтева се Број или Покретни"
msgid "add() argument"
msgstr "add() аргумент"
@@ -1130,6 +1133,9 @@ msgstr ""
"\n"
"# Преградне линије, копиране дословно:\n"
+msgid "E503: \"%s\" is not a file or writable device"
+msgstr "E503: „%s” није фајл или уређај на који може да се уписује"
+
msgid "Save As"
msgstr "Сачувај као"
@@ -4635,12 +4641,12 @@ msgstr "E531: Користите \":gui\" да покренете GUI"
msgid "E589: 'backupext' and 'patchmode' are equal"
msgstr "E589: 'backupext' и 'patchmode' су истоветни"
-msgid "E834: Conflicts with value of 'listchars'"
-msgstr "E834: У конфликту са вредношћу 'listchars'"
-
msgid "E835: Conflicts with value of 'fillchars'"
msgstr "E835: У конфликту са вредношћу 'fillchars'"
+msgid "E834: Conflicts with value of 'listchars'"
+msgstr "E834: У конфликту са вредношћу 'listchars'"
+
msgid "E617: Cannot be changed in the GTK+ 2 GUI"
msgstr "E617: Не може да се промени у GTK+ 2 GUI"
@@ -5064,7 +5070,7 @@ msgstr "E554: Синтаксна грешка у %s{...}"
#, c-format
msgid "E888: (NFA regexp) cannot repeat %s"
-msgstr "E888: (NFA regexp) не може да се понови %s"
+msgstr "E888: (НКА регуларни израз) не може да се понови %s"
msgid ""
"E864: \\%#= can only be followed by 0, 1, or 2. The automatic engine will be "
@@ -5130,15 +5136,15 @@ msgid "External submatches:\n"
msgstr "Спољна подпоклапања:\n"
msgid "E865: (NFA) Regexp end encountered prematurely"
-msgstr "E865: Крај (NFA) Regexp израза је достигнут прерано"
+msgstr "E865: (НКА) прерано је достигнут крај регуларног израза"
#, c-format
msgid "E866: (NFA regexp) Misplaced %c"
-msgstr "E866: (NFA regexp) %c је на погрешном месту"
+msgstr "E866: (НКА регуларни израз) %c је на погрешном месту"
#, c-format
msgid "E877: (NFA regexp) Invalid character class: %d"
-msgstr "E877: (NFA regexp) Неважећа карактер класа: %d"
+msgstr "E877: (НКА регуларни израз) Неважећа карактер класа: %d"
#, c-format
msgid "E867: (NFA) Unknown operator '\\z%c'"
@@ -6422,6 +6428,13 @@ msgstr "E853: Име аргумента је дуплирано: %s"
msgid "E989: Non-default argument follows default argument"
msgstr "E989: Неподразумевани аргумент следи иза подразумеваног аргумента"
+msgid "E126: Missing :endfunction"
+msgstr "E126: Недостаје :endfunction"
+
+#, c-format
+msgid "W22: Text found after :endfunction: %s"
+msgstr "W22: Пронађен текст након :endfunction: %s"
+
#, c-format
msgid "E451: Expected }: %s"
msgstr "E451: Очекује се }: %s"
@@ -6497,17 +6510,6 @@ msgstr "E862: Овде не може да се користи g:"
msgid "E932: Closure function should not be at top level: %s"
msgstr "E932: Затварајућа функција не би требало да буде на највишем нивоу: %s"
-msgid "E126: Missing :endfunction"
-msgstr "E126: Недостаје :endfunction"
-
-#, c-format
-msgid "W1001: Text found after :enddef: %s"
-msgstr "W1001: Пронађен је текст након :enddef: %s"
-
-#, c-format
-msgid "W22: Text found after :endfunction: %s"
-msgstr "W22: Пронађен текст након :endfunction: %s"
-
#, c-format
msgid "E707: Function name conflicts with variable: %s"
msgstr "E707: Име функције је у конфликту са променљивом: %s"
@@ -6983,8 +6985,8 @@ msgid "E475: Invalid value for argument %s: %s"
msgstr "E475: Неважећа вредност за аргумент %s: %s"
#, c-format
-msgid "E15: Invalid expression: %s"
-msgstr "E15: Неважећи израз: %s"
+msgid "E15: Invalid expression: \"%s\""
+msgstr "E15: Неважећи израз: „%s”"
msgid "E16: Invalid range"
msgstr "E16: Неважећи опсег"
diff --git a/src/nvim/po/tr.po b/src/nvim/po/tr.po
index 3db3cbfef0..e1fef00863 100644
--- a/src/nvim/po/tr.po
+++ b/src/nvim/po/tr.po
@@ -1,16 +1,16 @@
# Turkish translations for Vim
# Vim Türkçe çevirileri
-# Copyright (C) 2020 Emir SARI <bitigchi@me.com>
+# Copyright (C) 2021 Emir SARI <emir_sari@msn.com>
# This file is distributed under the same license as the Vim package.
-# Emir SARI <bitigchi@me.com>, 2019-2020
+# Emir SARI <emir_sari@msn.com>, 2019-2021
#
msgid ""
msgstr ""
"Project-Id-Version: Vim Turkish Localization Project\n"
-"Report-Msgid-Bugs-To: Emir SARI <bitigchi@me.com>\n"
-"POT-Creation-Date: 2020-11-29 00:20+0300\n"
-"PO-Revision-Date: 2020-11-29 20:00+0300\n"
-"Last-Translator: Emir SARI <bitigchi@me.com>\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2021-07-16 17:56+0300\n"
+"PO-Revision-Date: 2021-07-16 20:00+0300\n"
+"Last-Translator: Emir SARI <emir_sari@msn.com>\n"
"Language-Team: Turkish <https://github.com/bitigchi/vim>\n"
"Language: tr\n"
"MIME-Version: 1.0\n"
@@ -28,7 +28,7 @@ msgid "E165: Cannot go beyond last file"
msgstr "E165: Son dosyadan öteye gidilemez"
msgid "E610: No argument to delete"
-msgstr "E610: Silinecek bir değişken yok"
+msgstr "E610: Silinecek bir argüman yok"
msgid "E249: window layout changed unexpectedly"
msgstr "E249: Pencere yerleşimi beklenmedik bir biçimde değişti"
@@ -94,6 +94,9 @@ msgstr "%s çalıştırılıyor"
msgid "autocommand %s"
msgstr "%s otokomutu"
+msgid "E972: Blob value does not have the right number of bytes"
+msgstr "E972: İkili geniş nesne değeri doğru bayt sayısına sahip değil"
+
msgid "E831: bf_key_init() called with empty password"
msgstr "E831: bf_key_init() boş bir şifre ile çağrıldı"
@@ -131,6 +134,27 @@ msgstr "E931: Arabellek kaydedilemedi"
msgid "E937: Attempt to delete a buffer that is in use: %s"
msgstr "E937: Kullanımda olan bir arabellek silinmeye çalışılıyor: %s"
+msgid "E90: Cannot unload last buffer"
+msgstr "E90: Son arabellek bellekten kaldırılamıyor"
+
+msgid "E84: No modified buffer found"
+msgstr "E84: Değiştirilmiş bir arabellek bulunamadı"
+
+msgid "E85: There is no listed buffer"
+msgstr "E85: Listelenmiş bir arabellek yok"
+
+msgid "E87: Cannot go beyond last buffer"
+msgstr "E87: Son arabellekten öteye gidilemez"
+
+msgid "E88: Cannot go before first buffer"
+msgstr "E88: İlk arabellekten öncesine gidilemez"
+
+#, c-format
+msgid "E89: No write since last change for buffer %d (add ! to override)"
+msgstr ""
+"E89: %d numaralı arabellek son değişiklikten sonra yazılmadı (geçersiz "
+"kılmak için ! ekleyin)"
+
msgid "E515: No buffers were unloaded"
msgstr "E515: Hiçbir arabellek bellekten kaldırılmadı"
@@ -158,27 +182,6 @@ msgid_plural "%d buffers wiped out"
msgstr[0] "%d arabellek yok edildi"
msgstr[1] "%d arabellek yok edildi"
-msgid "E90: Cannot unload last buffer"
-msgstr "E90: Son arabellek bellekten kaldırılamıyor"
-
-msgid "E84: No modified buffer found"
-msgstr "E84: Değiştirilmiş bir arabellek bulunamadı"
-
-msgid "E85: There is no listed buffer"
-msgstr "E85: Listelenmiş bir arabellek yok"
-
-msgid "E87: Cannot go beyond last buffer"
-msgstr "E87: Son arabellekten öteye gidilemez"
-
-msgid "E88: Cannot go before first buffer"
-msgstr "E88: İlk arabellekten öncesine gidilemez"
-
-#, c-format
-msgid "E89: No write since last change for buffer %d (add ! to override)"
-msgstr ""
-"E89: %d numaralı arabellek son değişiklikten sonra yazılmadı (geçersiz "
-"kılmak için ! ekleyin)"
-
msgid "E948: Job still running (add ! to end the job)"
msgstr "E948: İş hâlâ sürüyor (bitirmek için ! ekleyin)"
@@ -424,13 +427,13 @@ msgid "E901: gethostbyname() in channel_open()"
msgstr "E901: channel_open() içinde gethostbyname()"
msgid "E903: received command with non-string argument"
-msgstr "E903: Dizi olmayan değişken içeren komut alındı"
+msgstr "E903: Dizi olmayan argüman içeren komut alındı"
msgid "E904: last argument for expr/call must be a number"
-msgstr "E904: İfadenin/çağrının son değişkeni bir sayı olmalıdır"
+msgstr "E904: İfadenin/çağrının son argüman bir sayı olmalıdır"
msgid "E904: third argument for call must be a list"
-msgstr "E904: Çağrının üçüncü değişkeni bir liste olmalıdır"
+msgstr "E904: Çağrının üçüncü argümanı bir liste olmalıdır"
#, c-format
msgid "E905: received unknown command: %s"
@@ -449,7 +452,7 @@ msgstr "E631: %s(): Yazma başarısız"
#, c-format
msgid "E917: Cannot use a callback with %s()"
-msgstr "E917: %s() ile geri çağırma kullanılamaz"
+msgstr "E917: %s() ile geri çağırma kullanılamıyor"
msgid "E912: cannot use ch_evalexpr()/ch_sendexpr() with a raw or nl channel"
msgstr "E912: ch_evalexpr()/ch_sendexpr() raw/nl kanalları ile kullanılamaz"
@@ -511,6 +514,11 @@ msgid "Warning: Using a weak encryption method; see :help 'cm'"
msgstr ""
"Uyarı: Zayıf bir şifreleme yöntemi kullanılıyor; bilgi için: :help 'cm'"
+msgid ""
+"Note: Encryption of swapfile not supported, disabling swap- and undofile"
+msgstr "Takas dosyası şifrelemesi desteklenmiyor, takas ve geri al dosyası "
+"devre dışı bırakılıyor"
+
msgid "Enter encryption key: "
msgstr "Şifreleme anahtarı girin: "
@@ -570,7 +578,7 @@ msgid "%3d expr %s"
msgstr "%3d ifade %s"
msgid "extend() argument"
-msgstr "extend() değişkeni"
+msgstr "extend() argümanı"
#, c-format
msgid "E737: Key already exists: %s"
@@ -728,9 +736,6 @@ msgstr "E708: [:] en son gelmelidir"
msgid "E709: [:] requires a List or Blob value"
msgstr "E709: [:] bir liste veya ikili geniş nesne değeri gerektirir"
-msgid "E972: Blob value does not have the right number of bytes"
-msgstr "E972: İkili geniş nesne değeri doğru bayt sayısına sahip değil"
-
msgid "E996: Cannot lock a range"
msgstr "E996: Erim kilitlenemiyor"
@@ -741,7 +746,7 @@ msgid "E260: Missing name after ->"
msgstr "E260: -> sonrası ad eksik"
msgid "E695: Cannot index a Funcref"
-msgstr "E695: Bir Funcref dizinlenemez"
+msgstr "E695: Bir Funcref dizinlenemiyor"
msgid "Not enough memory to set references, garbage collection aborted!"
msgstr "Referansları ayarlamak için yetersiz bellek, atık toplama durduruldu"
@@ -759,9 +764,6 @@ msgstr ""
"\n"
"\tEn son şuradan ayarlandı: "
-msgid "E808: Number or Float required"
-msgstr "E808: Sayı veya kayan noktalı değer gerekiyor"
-
#, c-format
msgid "E158: Invalid buffer name: %s"
msgstr "E158: Geçersiz arabellek adı: %s"
@@ -780,7 +782,7 @@ msgid "E922: expected a dict"
msgstr "E922: Bir sözlük bekleniyordu"
msgid "E923: Second argument of function() must be a list or a dict"
-msgstr "E923: function() ikinci değişkeni bir liste veya sözlük olmalıdır"
+msgstr "E923: function() ikinci argümanı bir liste veya sözlük olmalıdır"
msgid ""
"&OK\n"
@@ -882,7 +884,7 @@ msgid "E742: Cannot change value of %s"
msgstr "E742: %s değeri değiştirilemiyor"
msgid "E921: Invalid callback argument"
-msgstr "E921: Geçersiz geri çağırma değişkeni"
+msgstr "E921: Geçersiz geri çağırma argümanı"
#, c-format
msgid "<%s>%s%s %d, Hex %02x, Oct %03o, Digr %s"
@@ -927,6 +929,10 @@ msgstr "E135: *Süzgeç* otokomutları şu anki arabelleği değiştirmemelidir"
msgid "[No write since last change]\n"
msgstr "[Son değişiklikten sonra yazılmadı]\n"
+#, c-format
+msgid "E503: \"%s\" is not a file or writable device"
+msgstr "E503: \"%s\", bir dosya veya yazılabilir aygıt değil"
+
msgid "Save As"
msgstr "Farklı Kaydet"
@@ -985,7 +991,7 @@ msgid "E143: Autocommands unexpectedly deleted new buffer %s"
msgstr "E143: yeni %s arabelleğini otokomutlar beklenmedik bir biçimde sildi"
msgid "E144: non-numeric argument to :z"
-msgstr "E144: :z için sayısal olmayan değişken"
+msgstr "E144: :z için sayısal olmayan argüman"
msgid "E145: Shell commands and some functionality not allowed in rvim"
msgstr "E145: rvim içinde kabuk komutları ve bazı işlevselliğe izin verilmez"
@@ -1091,9 +1097,6 @@ msgstr "Kaynak alınan dosyanın sonu"
msgid "End of function"
msgstr "İşlevin sonu"
-msgid "E464: Ambiguous use of user-defined command"
-msgstr "E464: Kullanıcı tanımlı komutun belirsiz kullanımı"
-
msgid "E492: Not an editor command"
msgstr "E492: Bir düzenleyici komutu değil"
@@ -1178,7 +1181,7 @@ msgid "E187: Unknown"
msgstr "E187: Bilinmeyen"
msgid "E465: :winsize requires two number arguments"
-msgstr "E465: :winsize iki adet sayı değişken gerektirir"
+msgstr "E465: :winsize iki adet sayı argüman gerektirir"
#, c-format
msgid "Window position: X %d, Y %d"
@@ -1188,7 +1191,7 @@ msgid "E188: Obtaining window position not implemented for this platform"
msgstr "E188: Pencere konumunu alma özelliği bu platformda mevcut değil"
msgid "E466: :winpos requires two number arguments"
-msgstr "E466: :winpos iki adet sayı değişken gerektirir"
+msgstr "E466: :winpos iki adet sayı argüman gerektirir"
msgid "E930: Cannot use :redir inside execute()"
msgstr "E930: :redir, execute() içinde kullanılamaz"
@@ -1340,6 +1343,9 @@ msgstr "E788: Şu anda başka bir arabellek düzenlenemez"
msgid "E811: Not allowed to change buffer information now"
msgstr "E811: Şu anda arabellek bilgisi değiştirilemez"
+msgid "[Command Line]"
+msgstr "[Komut Satırı]"
+
msgid "E199: Active window or buffer deleted"
msgstr "E199: Etkin pencere veya arabellek silinmiş"
@@ -1530,7 +1536,7 @@ msgid "E655: Too many symbolic links (cycle?)"
msgstr "E655: Çok fazla sembolik bağlantı (çevrim?)"
msgid "writefile() first argument must be a List or a Blob"
-msgstr "writefile() ilk değişkeni bir liste veya ikili geniş nesne olmalıdır"
+msgstr "writefile() ilk argümanı bir liste veya ikili geniş nesne olmalıdır"
msgid "Select Directory dialog"
msgstr "Dizin Seç iletişim kutusu"
@@ -1581,6 +1587,9 @@ msgstr "E446: İmleç altında bir dosya adı yok"
msgid "E447: Can't find file \"%s\" in path"
msgstr "E447: \"%s\" dosyası yol içinde bulunamadı"
+msgid "E808: Number or Float required"
+msgstr "E808: Sayı veya kayan noktalı değer gerekiyor"
+
msgid "E490: No fold found"
msgstr "E490: Kıvırma bulunamadı"
@@ -1805,7 +1814,7 @@ msgstr "E671: Pencere başlığı \"%s\" bulunamıyor"
#, c-format
msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
-msgstr "E243: \"-%s\" değişkeni desteklenmiyor; OLE sürümünü kullanın."
+msgstr "E243: \"-%s\" argümanı desteklenmiyor; OLE sürümünü kullanın."
msgid "E988: GUI cannot be used. Cannot execute gvim.exe."
msgstr "E988: Grafik arabirim kullanılamaz. gvim.exe çalıştırılamadı."
@@ -2042,11 +2051,11 @@ msgstr "E411: Vurgulama grubu bulunamadı: %s"
#, c-format
msgid "E412: Not enough arguments: \":highlight link %s\""
-msgstr "E412: Yetersiz sayıda değişken: \":highlight link %s\""
+msgstr "E412: Yetersiz sayıda argüman: \":highlight link %s\""
#, c-format
msgid "E413: Too many arguments: \":highlight link %s\""
-msgstr "E413: Çok fazla değişken: \":highlight link %s\""
+msgstr "E413: Çok fazla argüman: \":highlight link %s\""
msgid "E414: group has settings, highlight link ignored"
msgstr "E414: Grup ayarları mevcut, vurgulama bağlantısı yok sayıldı"
@@ -2061,7 +2070,7 @@ msgstr "E416: Eksik eşittir imi: %s"
#, c-format
msgid "E417: missing argument: %s"
-msgstr "E417: Eksik değişkenler: %s"
+msgstr "E417: Argüman eksik: %s"
#, c-format
msgid "E418: Illegal value: %s"
@@ -2086,7 +2095,7 @@ msgstr "E422: Uçbirim kodu çok uzun: %s"
#, c-format
msgid "E423: Illegal argument: %s"
-msgstr "E423: İzin verilmeyen değişken: %s"
+msgstr "E423: İzin verilmeyen argüman: %s"
msgid "E424: Too many different highlighting attributes in use"
msgstr "E424: Çok fazla değişik vurgulama kuralları kullanılıyor"
@@ -2295,7 +2304,7 @@ msgid "unknown option"
msgstr "bilinmeyen seçenek"
msgid "window index is out of range"
-msgstr "pencere dizini erimin dışında"
+msgstr "pencere sırası erimin dışında"
msgid "couldn't open buffer"
msgstr "arabellek açılamadı"
@@ -2513,9 +2522,6 @@ msgstr " Dahili anahtar sözcük tamamlaması (^N^P)"
msgid "Hit end of paragraph"
msgstr "Paragrafın sonuna varıldı"
-msgid "E839: Completion function changed window"
-msgstr "E839: Tamamlama işlevi pencereyi değiştirdi"
-
msgid "E840: Completion function deleted text"
msgstr "E840: Tamamlama işlevi metni sildi"
@@ -2594,23 +2600,23 @@ msgstr "E938: JSON'da yinelenmiş anahtar: \"%s\""
#, c-format
msgid "E899: Argument of %s must be a List or Blob"
-msgstr "E899: %s değişkeni bir liste veya ikili geniş nesne olmalıdır"
+msgstr "E899: %s argümanı bir liste veya ikili geniş nesne olmalıdır"
msgid "E900: maxdepth must be non-negative number"
msgstr "E900: maxdepth negatif olmayan bir sayı olmalı"
msgid "flatten() argument"
-msgstr "flatten() değişkeni"
+msgstr "flatten() argümanı"
#, c-format
msgid "E696: Missing comma in List: %s"
msgstr "E696: Listede virgül eksik: %s"
msgid "sort() argument"
-msgstr "sort() değişkeni"
+msgstr "sort() argümanı"
msgid "uniq() argument"
-msgstr "uniq() değişkeni"
+msgstr "uniq() argümanı"
msgid "E702: Sort compare function failed"
msgstr "E702: Sıralayıp karşılaştırma işlevi başarısız oldu"
@@ -2619,25 +2625,28 @@ msgid "E882: Uniq compare function failed"
msgstr "E882: Benzersizlik karşılaştırma işlevi başarısız oldu"
msgid "map() argument"
-msgstr "map() değişkeni"
+msgstr "map() argümanı"
msgid "mapnew() argument"
-msgstr "mapnew() değişkeni"
+msgstr "mapnew() argümanı"
msgid "filter() argument"
-msgstr "filter() değişkeni"
+msgstr "filter() argümanı"
msgid "add() argument"
-msgstr "add() değişkeni"
+msgstr "add() argümanı"
+
+msgid "extendnew() argument"
+msgstr "extendnew() argümanı"
msgid "insert() argument"
-msgstr "insert() değişkeni"
+msgstr "insert() argümanı"
msgid "remove() argument"
-msgstr "remove() değişkeni"
+msgstr "remove() argümanı"
msgid "reverse() argument"
-msgstr "reverse() değişkeni"
+msgstr "reverse() argümanı"
#, c-format
msgid "Current %slanguage: \"%s\""
@@ -2648,22 +2657,22 @@ msgid "E197: Cannot set language to \"%s\""
msgstr "E197: \"%s\" diline ayarlanamıyor"
msgid "Unknown option argument"
-msgstr "Bilinmeyen seçenek değişkeni"
+msgstr "Bilinmeyen seçenek argümanı"
msgid "Too many edit arguments"
-msgstr "Çok fazla düzenleme değişkeni"
+msgstr "Çok fazla düzenleme argümanı"
msgid "Argument missing after"
-msgstr "Şundan sonra değişken eksik:"
+msgstr "Şundan sonra argüman eksik:"
msgid "Garbage after option argument"
-msgstr "Seçenek değişkeninden sonra anlamsız veri"
+msgstr "Seçenek argümanından sonra anlamsız veri"
msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
-msgstr "Çok fazla \"+komut\", \"-c komut\" veya \"--cmd komut\" değişkeni"
+msgstr "Çok fazla \"+komut\", \"-c komut\" veya \"--cmd komut\" argümanı"
msgid "Invalid argument for"
-msgstr "Şunun için geçersiz değişken:"
+msgstr "Şunun için geçersiz argüman:"
#, c-format
msgid "%d files to edit\n"
@@ -2735,7 +2744,7 @@ msgstr ""
"Kullanım:"
msgid " vim [arguments] "
-msgstr " vim [değişkenler] "
+msgstr " vim [argümanlar] "
msgid ""
"\n"
@@ -2967,21 +2976,21 @@ msgid ""
"Arguments recognised by gvim (Motif version):\n"
msgstr ""
"\n"
-"gvim tarafından tanınan değişkenler (Motif sürümü):\n"
+"gvim tarafından tanınan argümanlar (Motif sürümü):\n"
msgid ""
"\n"
"Arguments recognised by gvim (neXtaw version):\n"
msgstr ""
"\n"
-"gvim tarafından tanınan değişkenler (neXtaw sürümü):\n"
+"gvim tarafından tanınan argümanlar (neXtaw sürümü):\n"
msgid ""
"\n"
"Arguments recognised by gvim (Athena version):\n"
msgstr ""
"\n"
-"gvim tarafından tanınan değişkenler (Athena sürümü):\n"
+"gvim tarafından tanınan argümanlar (Athena sürümü):\n"
msgid "-display <display>\tRun Vim on <display>"
msgstr "-display <ekran>\tVim'i <ekran>'da çalıştır"
@@ -3032,7 +3041,7 @@ msgid ""
"Arguments recognised by gvim (GTK+ version):\n"
msgstr ""
"\n"
-"gvim tarafından tanınan değişkenler (GTK+ sürümü):\n"
+"gvim tarafından tanınan argümanlar (GTK+ sürümü):\n"
msgid "-display <display>\tRun Vim on <display> (also: --display)"
msgstr "-display <ekran>\tVim'i <ekran>'da çalıştır (veya: --display)"
@@ -3078,7 +3087,7 @@ msgid "E228: makemap: Illegal mode"
msgstr "E228: makemap: İzin verilmeyen kip"
msgid "E460: entries missing in mapset() dict argument"
-msgstr "E460: mapset() sözlük değişkeninde eksik girdiler"
+msgstr "E460: mapset() sözlük argümanında eksik girdiler"
#, c-format
msgid "E357: 'langmap': Matching character missing for %s"
@@ -3716,13 +3725,13 @@ msgstr ""
"İ&ptal"
msgid "E766: Insufficient arguments for printf()"
-msgstr "E766: printf() için yetersiz değişkenler"
+msgstr "E766: printf() için yetersiz argüman"
msgid "E807: Expected Float argument for printf()"
-msgstr "E807: printf() için kayan noktalı değer türünde değişken bekleniyordu"
+msgstr "E807: printf() için kayan noktalı değer türünde argüman bekleniyordu"
msgid "E767: Too many arguments to printf()"
-msgstr "E767: printf() için çok fazla değişken"
+msgstr "E767: printf() için çok fazla argüman"
msgid "Type number and <Enter> or click with the mouse (q or empty cancels): "
msgstr ""
@@ -4014,12 +4023,12 @@ msgstr "E531: Grafik arabirimi başlatmak için \":gui\" yazın"
msgid "E589: 'backupext' and 'patchmode' are equal"
msgstr "E589: 'backupext' ve 'patchmode' birbirine eşit"
-msgid "E834: Conflicts with value of 'listchars'"
-msgstr "E834: 'listchars' değeriyle çakışmalar var"
-
msgid "E835: Conflicts with value of 'fillchars'"
msgstr "E835: 'fillchars' değeriyle çakışmalar var"
+msgid "E834: Conflicts with value of 'listchars'"
+msgstr "E834: 'listchars' değeriyle çakışmalar var"
+
msgid "E617: Cannot be changed in the GTK+ 2 GUI"
msgstr "E617: GTK+ 2 grafik arabiriminde değiştirilemez"
@@ -4392,7 +4401,7 @@ msgid "Cannot open file \"%s\""
msgstr "\"%s\" dosyası açılamıyor"
msgid "cannot have both a list and a \"what\" argument"
-msgstr "ya birinci ya da son değişken belirtilmelidir"
+msgstr "ya birinci ya da son argüman belirtilmelidir"
msgid "E681: Buffer is not loaded"
msgstr "E681: Arabellek yüklenemedi"
@@ -4725,10 +4734,10 @@ msgid "modeline"
msgstr "kip satırı"
msgid "--cmd argument"
-msgstr "--cmd değişkeni"
+msgstr "--cmd argümanı"
msgid "-c argument"
-msgstr "-c değişkeni"
+msgstr "-c argümanı"
msgid "environment variable"
msgstr "ortam değişkeni"
@@ -4736,6 +4745,9 @@ msgstr "ortam değişkeni"
msgid "error handler"
msgstr "hata işleyicisi"
+msgid "changed window size"
+msgstr "değiştirilen pencere boyutu"
+
msgid "W15: Warning: Wrong line separator, ^M may be missing"
msgstr "W15: Uyarı: Yanlış satır ayırıcısı, ^M eksik olabilir"
@@ -5215,6 +5227,9 @@ msgstr "E765: 'spellfile' içinde %d adet girdi yok"
msgid "Word '%.*s' removed from %s"
msgstr "'%.*s' sözcüğü %s içinden çıkartıldı"
+msgid "Seek error in spellfile"
+msgstr "Yazım dosyasında arama hatası"
+
#, c-format
msgid "Word '%.*s' added to %s"
msgstr "'%.*s' sözcüğü %s dosyasına eklendi"
@@ -5242,7 +5257,7 @@ msgstr " < \"%.*s\""
#, c-format
msgid "E390: Illegal argument: %s"
-msgstr "E390: İzin verilmeyen değişken: %s"
+msgstr "E390: İzin verilmeyen argüman: %s"
msgid "No Syntax items defined for this buffer"
msgstr "Bu arabellek için sözdizim ögeleri tanımlanmamış"
@@ -5343,7 +5358,7 @@ msgid " line breaks"
msgstr " satır sonu"
msgid "E395: contains argument not accepted here"
-msgstr "E395: Burada kabul edilmeyen bir değişken içeriyor"
+msgstr "E395: Burada kabul edilmeyen bir argüman içeriyor"
msgid "E844: invalid cchar value"
msgstr "E844: Geçersiz cchar değeri"
@@ -5375,7 +5390,7 @@ msgstr "E398: '=' eksik: %s"
#, c-format
msgid "E399: Not enough arguments: syntax region %s"
-msgstr "E399: Yetersiz değişken: %s sözdizim bölgesi"
+msgstr "E399: Yetersiz sayıda argüman: %s sözdizim bölgesi"
msgid "E848: Too many syntax clusters"
msgstr "E848: Çok fazla sözdizim kümesi"
@@ -5396,7 +5411,7 @@ msgstr "E403: Sözdizim eşitlemesi: Satır devamları dizgisi iki kez tanımlan
#, c-format
msgid "E404: Illegal arguments: %s"
-msgstr "E404: İzin verilmeyen değişkenler: %s"
+msgstr "E404: İzin verilmeyen argümanlar: %s"
#, c-format
msgid "E405: Missing equal sign: %s"
@@ -5404,7 +5419,7 @@ msgstr "E405: Eşittir imi eksik: %s"
#, c-format
msgid "E406: Empty argument: %s"
-msgstr "E406: Boş değişken: %s"
+msgstr "E406: Boş argüman: %s"
#, c-format
msgid "E407: %s not allowed here"
@@ -5539,7 +5554,7 @@ msgid "E436: No \"%s\" entry in termcap"
msgstr "E436: termcap içinde \"%s\" girdisi yok"
msgid "E437: terminal capability \"cm\" required"
-msgstr "E437: \"cm\" uçbirim kabiliyeti gerekiyor"
+msgstr "E437: \"cm\" uçbirim yeteneği gerekiyor"
msgid ""
"\n"
@@ -5688,16 +5703,16 @@ msgstr "E914: Bir Kanal, Kayan Noktalı Değer yerine kullanılıyor"
msgid "E975: Using a Blob as a Float"
msgstr "E975: Bir İkili Geniş Nesne, Kayan Noktalı Değer yerine kullanılıyor"
-msgid "E729: using Funcref as a String"
+msgid "E729: Using a Funcref as a String"
msgstr "E729: Funcref bir Dizi yerine kullanılıyor"
-msgid "E730: using List as a String"
+msgid "E730: Using a List as a String"
msgstr "E730: Liste bir Dizi yerine kullanılıyor"
-msgid "E731: using Dictionary as a String"
+msgid "E731: Using a Dictionary as a String"
msgstr "E731: Sözlük bir Dizi yerine kullanılıyor"
-msgid "E976: using Blob as a String"
+msgid "E976: Using a Blob as a String"
msgstr "E976: İkili Geniş Nesne bir Dizi yerine kullanılıyor"
msgid "E977: Can only compare Blob with Blob"
@@ -5892,16 +5907,16 @@ msgid "E180: Invalid complete value: %s"
msgstr "E180: Geçersiz tam değer: %s"
msgid "E468: Completion argument only allowed for custom completion"
-msgstr "E468: Tamamlama değişkenine yalnızca özel tamamlamalarda izin verilir"
+msgstr "E468: Tamamlama argümanına yalnızca özel tamamlamalarda izin verilir"
msgid "E467: Custom completion requires a function argument"
-msgstr "E467: Özel tamamlama bir işlev değişkeni gerektirir"
+msgstr "E467: Özel tamamlama bir işlev argümanı gerektirir"
msgid "E175: No attribute specified"
msgstr "E175: Bir öznitelik belirtilmemiş"
msgid "E176: Invalid number of arguments"
-msgstr "E176: Geçersiz değişken sayısı"
+msgstr "E176: Geçersiz argüman sayısı"
msgid "E177: Count cannot be specified twice"
msgstr "E177: Sayım iki defa belirtilemez"
@@ -5910,10 +5925,10 @@ msgid "E178: Invalid default value for count"
msgstr "E178: Sayım için geçersiz öntanımlı değer"
msgid "E179: argument required for -complete"
-msgstr "E179: -complete için değişken gerekiyor"
+msgstr "E179: -complete için argüman gerekiyor"
msgid "E179: argument required for -addr"
-msgstr "E179: -addr için değişken gerekiyor"
+msgstr "E179: -addr için argüman gerekiyor"
#, c-format
msgid "E174: Command already exists: add ! to replace it: %s"
@@ -5948,14 +5963,21 @@ msgstr "E130: Bilinmeyen işlev: %s"
#, c-format
msgid "E125: Illegal argument: %s"
-msgstr "E125: İzin verilmeyen değişken: %s"
+msgstr "E125: İzin verilmeyen argüman: %s"
#, c-format
msgid "E853: Duplicate argument name: %s"
-msgstr "E853: Yinelenen değişken adı: %s"
+msgstr "E853: Yinelenen argüman adı: %s"
msgid "E989: Non-default argument follows default argument"
-msgstr "E989: Öntanımlı olmayan değişken öntanımlı değişkenden sonra"
+msgstr "E989: Öntanımlı olmayan argüman öntanımlı argümandan sonra"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: :endfunction eksik"
+
+#, c-format
+msgid "W22: Text found after :endfunction: %s"
+msgstr "W22: :endfunction sonrası metin bulundu: %s"
#, c-format
msgid "E451: Expected }: %s"
@@ -5963,11 +5985,11 @@ msgstr "E451: } bekleniyordu: %s"
#, c-format
msgid "E740: Too many arguments for function %s"
-msgstr "E740: %s işlevi için çok fazla değişken"
+msgstr "E740: %s işlevi için çok fazla argüman"
#, c-format
msgid "E116: Invalid arguments for function %s"
-msgstr "E116: %s işlevi için geçersiz değişkenler"
+msgstr "E116: %s işlevi için geçersiz argümanlar"
msgid "E132: Function call depth is higher than 'maxfuncdepth'"
msgstr "E132: İşlevin çağırdığı derinlik 'maxfuncdepth'ten daha yüksek"
@@ -5989,7 +6011,7 @@ msgid "%s returning %s"
msgstr "%s, %s döndürüyor"
msgid "E699: Too many arguments"
-msgstr "E699: Çok fazla değişken"
+msgstr "E699: Çok fazla argüman"
#, c-format
msgid "E276: Cannot use function as a method: %s"
@@ -6032,17 +6054,6 @@ msgstr "E862: g: burada kullanılamaz"
msgid "E932: Closure function should not be at top level: %s"
msgstr "E932: Kapatma işlevi en üst düzeyde olmamalıdır: %s"
-msgid "E126: Missing :endfunction"
-msgstr "E126: :endfunction eksik"
-
-#, c-format
-msgid "W1001: Text found after :enddef: %s"
-msgstr "W1001: :enddef sonrası metin bulundu: %s"
-
-#, c-format
-msgid "W22: Text found after :endfunction: %s"
-msgstr "W22: :endfunction sonrası metin bulundu: %s"
-
#, c-format
msgid "E707: Function name conflicts with variable: %s"
msgstr "E707: İşlev adı şu değişken ile çakışıyor: %s"
@@ -6605,6 +6616,55 @@ msgstr "gvimext.dll hatası"
msgid "Path length too long!"
msgstr "Yol çok uzun!"
+msgid "E10: \\ should be followed by /, ? or &"
+msgstr "E10: \\ sonrasında /, ? veya & gelmeli"
+
+msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
+msgstr "E11: Komut satırı penceresinde geçersiz; <CR> çalıştırır, CTRL-C çıkar"
+
+msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
+msgstr ""
+"E12: Geçerli dizin veya etiket aramasında exrc veya vimrc'den komutlara izin "
+"verilmiyor"
+
+msgid "E13: File exists (add ! to override)"
+msgstr "E13: Dosya mevcut (geçersiz kılmak için ! ekleyin)"
+
+#, c-format
+msgid "E15: Invalid expression: \"%s\""
+msgstr "E15: Geçersiz ifade: \"%s\""
+
+msgid "E16: Invalid range"
+msgstr "E16: Geçersiz erim"
+
+#, c-format
+msgid "E17: \"%s\" is a directory"
+msgstr "E17: \"%s\" bir dizin"
+
+msgid "E18: Unexpected characters in :let"
+msgstr "E18: :let içinde beklenmeyen karakter"
+
+msgid "E18: Unexpected characters in assignment"
+msgstr "E18: Atama içerisinde beklenmedik karakterler"
+
+msgid "E19: Mark has invalid line number"
+msgstr "E19: İm satır numarası geçersiz"
+
+msgid "E20: Mark not set"
+msgstr "E20: İm ayarlanmamış"
+
+msgid "E21: Cannot make changes, 'modifiable' is off"
+msgstr "E21: Değişiklik yapılamıyor, 'modifiable' kapalı"
+
+msgid "E22: Scripts nested too deep"
+msgstr "E22: Betikler çok iç içe geçmiş"
+
+msgid "E23: No alternate file"
+msgstr "E23: Başka bir dosya yok"
+
+msgid "E24: No such abbreviation"
+msgstr "E24: Böyle bir kısaltma yok"
+
#, c-format
msgid "E121: Undefined variable: %s"
msgstr "E121: Tanımlanmamış değişken: %s"
@@ -6613,6 +6673,9 @@ msgstr "E121: Tanımlanmamış değişken: %s"
msgid "E121: Undefined variable: %c:%s"
msgstr "E121: Tanımlanmamış değişken: %c:%s"
+msgid "E464: Ambiguous use of user-defined command"
+msgstr "E464: Kullanıcı tanımlı komutun belirsiz kullanımı"
+
msgid "E476: Invalid command"
msgstr "E476: Geçersiz komut"
@@ -6633,15 +6696,19 @@ msgid ""
"E856: \"assert_fails()\" second argument must be a string or a list with one "
"or two strings"
msgstr ""
-"E856: \"assert_fails()\" ikinci değişkeni bir dizi veya bir veya iki dizili "
+"E856: \"assert_fails()\" ikinci argüman bir dizi veya bir veya iki dizili "
"bir liste olmalıdır"
+#, c-format
+msgid "E908: using an invalid value as a String: %s"
+msgstr "E908: Geçersiz bir değer bir Dizi yerine kullanılıyor: %s"
+
msgid "E909: Cannot index a special variable"
msgstr "E909: Özel bir değişken dizinlenemiyor"
#, c-format
-msgid "E1100: Missing :var: %s"
-msgstr "E1100: :var eksik: %s"
+msgid "E1100: Command not supported in Vim9 script (missing :var?): %s"
+msgstr "E1100: Komut Vim9 betiğinde desteklenmiyor (:var? eksik): %s"
#, c-format
msgid "E1001: Variable not found: %s"
@@ -6655,18 +6722,18 @@ msgid "E1003: Missing return value"
msgstr "E1003: Dönüş değeri eksik"
#, c-format
-msgid "E1004: White space required before and after '%s'"
-msgstr "E1004: '%s' öncesinde ve sonrasında boşluk gerekiyor"
+msgid "E1004: White space required before and after '%s' at \"%s\""
+msgstr "E1004: Şu konumda '%s' öncesinde ve sonrasında boşluk gerekiyor: \"%s\""
msgid "E1005: Too many argument types"
-msgstr "E1005: Çok fazla değişken türü"
+msgstr "E1005: Çok fazla argüman türü"
#, c-format
msgid "E1006: %s is used as an argument"
-msgstr "E1006: %s bir değişken olarak kullanılıyor"
+msgstr "E1006: %s bir argüman olarak kullanılıyor"
msgid "E1007: Mandatory argument after optional argument"
-msgstr "E1007: İsteğe bağlı değişken sonrasında zorunlu değişken"
+msgstr "E1007: İsteğe bağlı argüman sonrasında zorunlu argüman"
msgid "E1008: Missing <type>"
msgstr "E1008: <tür> eksik"
@@ -6688,7 +6755,7 @@ msgstr "E1012: Tür uyumsuzluğu, %s bekleniyordu, ancak %s alındı"
#, c-format
msgid "E1013: Argument %d: type mismatch, expected %s but got %s"
-msgstr "E1013: %d değişkeni: Tür uyumsuzluğu, %s bekleniyordu, ancak %s alındı"
+msgstr "E1013: %d argümanı: Tür uyumsuzluğu, %s bekleniyordu, ancak %s alındı"
#, c-format
msgid "E1014: Invalid key: %s"
@@ -6728,8 +6795,8 @@ msgid "E1022: Type or initialization required"
msgstr "E1022: Tür veya ilklendirme gerekiyor"
#, c-format
-msgid "E1023: Using a Number as a Bool: %d"
-msgstr "E1023: Bir Sayı, bir Bool yerine kullanılıyor: %d"
+msgid "E1023: Using a Number as a Bool: %lld"
+msgstr "E1023: Bir Sayı, bir Boole yerine kullanılıyor: %lld"
msgid "E1024: Using a Number as a String"
msgstr "E1024: Bir Sayı, bir Dizi yerine kullanılıyor"
@@ -6768,11 +6835,11 @@ msgid "E1034: Cannot use reserved name %s"
msgstr "E1034: Ayrılmış ad %s kullanılamaz"
msgid "E1035: % requires number arguments"
-msgstr "E1035: %, sayı değişkenler gerektirir"
+msgstr "E1035: %, sayı argümanları gerektirir"
#, c-format
msgid "E1036: %c requires number or float arguments"
-msgstr "E1036: %c, sayı veya kayan noktalı değer değişkenler gerektirir"
+msgstr "E1036: %c, sayı veya kayan noktalı değer argümanları gerektirir"
#, c-format
msgid "E1037: Cannot use \"%s\" with %s"
@@ -6798,7 +6865,7 @@ msgid "E1043: Invalid command after :export"
msgstr "E1043: :export sonrası geçersiz komut"
msgid "E1044: Export with invalid argument"
-msgstr "E1044: Geçersiz değişkenle dışa aktarım"
+msgstr "E1044: Geçersiz argümanla dışa aktarım"
msgid "E1045: Missing \"as\" after *"
msgstr "E1045: * sonrası \"as\" eksik"
@@ -6817,11 +6884,12 @@ msgstr "E1048: Betikte öge bulunamadı: %s"
msgid "E1049: Item not exported in script: %s"
msgstr "E1049: Betikte öge dışa aktarılmadı: %s"
-msgid "E1050: Colon required before a range"
-msgstr "E1050: Bir erim öncesi iki nokta gerekiyor"
+#, c-format
+msgid "E1050: Colon required before a range: %s"
+msgstr "E1050: Bir erim öncesi iki nokta gerekiyor: %s"
msgid "E1051: Wrong argument type for +"
-msgstr "E1051: + için hatalı değişken türü"
+msgstr "E1051: + için hatalı argüman türü"
#, c-format
msgid "E1052: Cannot declare an option: %s"
@@ -6875,12 +6943,12 @@ msgid "E1067: Separator mismatch: %s"
msgstr "E1067: Ayırıcı uyumsuzluğu: %s"
#, c-format
-msgid "E1068: No white space allowed before '%s'"
-msgstr "E1068: '%s' önce boşluğa izin verilmiyor"
+msgid "E1068: No white space allowed before '%s': %s"
+msgstr "E1068: '%s' önce boşluğa izin verilmiyor: %s"
#, c-format
-msgid "E1069: White space required after '%s'"
-msgstr "E1069: '%s' sonrası boşluk gerekiyor"
+msgid "E1069: White space required after '%s': %s"
+msgstr "E1069: '%s' sonrası boşluk gerekiyor: %s"
msgid "E1070: Missing \"from\""
msgstr "E1070: \"from\" eksik"
@@ -6908,7 +6976,7 @@ msgstr "E1076: Bu Vim kayan noktalı değer desteği ile derlenmemiş"
#, c-format
msgid "E1077: Missing argument type for %s"
-msgstr "E1077: %s için değişken türü eksik"
+msgstr "E1077: %s için argüman türü eksik"
#, c-format
msgid "E1081: Cannot unlet %s"
@@ -6933,7 +7001,7 @@ msgid "E1086: Cannot use :function inside :def"
msgstr "E1086: :def içinde :function kullanılamaz"
msgid "E1087: Cannot use an index when declaring a variable"
-msgstr "E1087: Bir değişken tanımlarken indeks kullanılamaz"
+msgstr "E1087: Bir değişken tanımlarken dizinleme kullanılamaz"
#, c-format
msgid "E1089: Unknown variable: %s"
@@ -6941,7 +7009,7 @@ msgstr "E1089: Bilinmeyen değişken: %s"
#, c-format
msgid "E1090: Cannot assign to argument %s"
-msgstr "E1090: %s değişkenine atanamıyor"
+msgstr "E1090: %s argümanına atanamıyor"
#, c-format
msgid "E1091: Function is not compiled: %s"
@@ -6989,11 +7057,11 @@ msgid "E1105: Cannot convert %s to string"
msgstr "E1105: %s bir diziye dönüştürülemiyor"
msgid "E1106: One argument too many"
-msgstr "E1106: Bir değişken fazladan"
+msgstr "E1106: Bir argüman fazladan"
#, c-format
msgid "E1106: %d arguments too many"
-msgstr "E1106: %d değişken fazladan"
+msgstr "E1106: %d argüman fazladan"
msgid "E1107: String, List, Dict or Blob required"
msgstr "E1107: Dizi, Liste, Sözlük veya İkili Nesne gerekiyor"
@@ -7026,10 +7094,10 @@ msgid "E1114: Only values of 0x100 and higher supported"
msgstr "E1114: Yalnızca 0x100 ve daha yüksek değerler destekleniyor"
msgid "E1115: \"assert_fails()\" fourth argument must be a number"
-msgstr "E1115: \"assert_fails()\" dördüncü değişkeni bir sayı olmalıdır"
+msgstr "E1115: \"assert_fails()\" dördüncü argüman bir sayı olmalıdır"
msgid "E1116: \"assert_fails()\" fifth argument must be a string"
-msgstr "E1116: \"assert_fails()\" beşinci değişkeni bir dizi olmalıdır"
+msgstr "E1116: \"assert_fails()\" beşinci argüman bir dizi olmalıdır"
msgid "E1117: Cannot use ! with nested :def"
msgstr "E1117: !, iç içe geçmiş :def ile kullanılamaz"
@@ -7080,7 +7148,7 @@ msgid "E1131: Cannot add to null blob"
msgstr "E1131: Null ikili geniş nesnesine ekleme yapılamaz"
msgid "E1132: Missing function argument"
-msgstr "E1132: İşlev değişkeni eksik"
+msgstr "E1132: İşlev argümanı eksik"
msgid "E1133: Cannot extend a null dict"
msgstr "E1133: Bir null sözlük genişletilemez"
@@ -7108,12 +7176,259 @@ msgstr "E1138: Bir Boole, Sayı yerine kullanılıyor"
msgid "E1139: Missing matching bracket after dict key"
msgstr "E1139: Sözlük anahtarı sonrası eşleşen ayraç eksik"
-msgid "E1140: For argument must be a sequence of lists"
-msgstr "E1140: For değişkeni listelerin bir sıralaması olmalıdır"
+msgid "E1140: :for argument must be a sequence of lists"
+msgstr "E1140: :for argümanı listelerin bir sıralaması olmalıdır"
msgid "E1141: Indexable type required"
msgstr "E1141: İndekslenebilir tür gerekiyor"
+msgid "E1142: Non-empty string required"
+msgstr "E1142: Boş olmayan dizi gerekiyor"
+
+#, c-format
+msgid "E1143: Empty expression: \"%s\""
+msgstr "E1143: Boş ifade: \"%s\""
+
+#, c-format
+msgid "E1144: Command \"%s\" is not followed by white space: %s"
+msgstr "E1144: \"%s\" komutu sonrasında boşluk gelmiyor: %s"
+
+#, c-format
+msgid "E1145: Missing heredoc end marker: %s"
+msgstr "E1145: Son imleyicisi eksik: %s"
+
+#, c-format
+msgid "E1146: Command not recognized: %s"
+msgstr "E1146: Komut tanınamadı: %s"
+
+msgid "E1147: List not set"
+msgstr "E1147: Liste ayarlanmamış"
+
+#, c-format
+msgid "E1148: Cannot index a %s"
+msgstr "E1148: Bir %s dizinlenemiyor"
+
+#, c-format
+msgid "E1149: Script variable is invalid after reload in function %s"
+msgstr "E1149: %s işlevindeki yeniden yüklemeden sonra betik değişkeni geçersiz"
+
+msgid "E1150: Script variable type changed"
+msgstr "E1150: Betik değişkeni türü değiştirildi"
+
+msgid "E1151: Mismatched endfunction"
+msgstr "E1151: Eşleşmeyen endfunction"
+
+msgid "E1152: Mismatched enddef"
+msgstr "E1152: Eşleşmeyen enddef"
+
+msgid "E1153: Invalid operation for bool"
+msgstr "E1153: Boole için geçersiz işlem"
+
+msgid "E1154: Divide by zero"
+msgstr "E1154: Sıfır ile bölüm"
+
+msgid "E1155: Cannot define autocommands for ALL events"
+msgstr "E1155: Otokomutlar TÜM olaylar için tanımlanamıyor"
+
+msgid "E1156: Cannot change the argument list recursively"
+msgstr "E1156: Değişken listesi özyineli olarak değiştirilemiyor"
+
+msgid "E1157: Missing return type"
+msgstr "E1157: Dönüş türü eksik"
+
+msgid "E1158: Cannot use flatten() in Vim9 script"
+msgstr "E1158: flatten(), Vim9 betiğinde kullanılamaz"
+
+msgid "E1159: Cannot split a window when closing the buffer"
+msgstr "E1159: Arabellek kapatılırken bir pencere bölünemez"
+
+msgid "E1160: Cannot use a default for variable arguments"
+msgstr "E1160: Değişken argümanları için bir öntanımlı kullanılamaz"
+
+#, c-format
+msgid "E1161: Cannot json encode a %s"
+msgstr "E1161: Bir %s JSON olarak kodlanamıyor"
+
+#, c-format
+msgid "E1162: Register name must be one character: %s"
+msgstr "E1162: Yazmaç adı tek bir karakter olmalıdır: %s"
+
+#, c-format
+msgid "E1163: Variable %d: type mismatch, expected %s but got %s"
+msgstr "E1163: %d değişkeni: Tür uyumsuzluğu, %s bekleniyordu, ancak %s alındı"
+
+msgid "E1164: vim9cmd must be followed by a command"
+msgstr "E1164: vim9cmd sonrasında bir komut gelmelidir"
+
+#, c-format
+msgid "E1165: Cannot use a range with an assignment: %s"
+msgstr "E1165: Bir atama ile bir erim kullanılamıyor: %s"
+
+msgid "E1166: Cannot use a range with a dictionary"
+msgstr "E1166: Bir sözlük ile bir erim kullanılamıyor"
+
+#, c-format
+msgid "E1167: Argument name shadows existing variable: %s"
+msgstr "E1167: Argüman adı var olan değişkeni gölgeliyor: %s"
+
+#, c-format
+msgid "E1168: Argument already declared in the script: %s"
+msgstr "E1168: Betikte argüman halihazırda tanımlanmış: %s"
+
+msgid "E1169: 'import * as {name}' not supported here"
+msgstr "E1169: 'import * as {name} burada desteklenmiyor"
+
+msgid "E1170: Cannot use #{ to start a comment"
+msgstr "E1170: Bir yorum başlatmak için #{ kullanılamaz"
+
+msgid "E1171: Missing } after inline function"
+msgstr "E1171: Satıriçi işlevden sonra } eksik"
+
+msgid "E1172: Cannot use default values in a lambda"
+msgstr "E1172: Bir lambda içerisinde öntanımlı değerler kullanılamıyor"
+
+#, c-format
+msgid "E1173: Text found after enddef: %s"
+msgstr "E1173: :enddef sonrası metin bulundu: %s"
+
+#, c-format
+msgid "E1174: String required for argument %d"
+msgstr "E1174: %d argümanı için dizi gerekiyor"
+
+#, c-format
+msgid "E1175: Non-empty string required for argument %d"
+msgstr "E1175: %d argümanı için boş olmayan dizi gerekiyor"
+
+msgid "E1176: Misplaced command modifier"
+msgstr "E1176: Yanlış yere konulmuş komut değiştiricisi"
+
+#, c-format
+msgid "E1177: For loop on %s not supported"
+msgstr "E1177: %s üzerinde for döngüsü desteklenmiyor"
+
+msgid "E1178: Cannot lock or unlock a local variable"
+msgstr "E1178: Bir yerel değişken kilitlenemiyor/kilidi açılamıyor"
+
+#, c-format
+msgid ""
+"E1179: Failed to extract PWD from %s, check your shell's config related to "
+"OSC 7"
+msgstr ""
+"E1179: %s içinden PWD çıkarılamadı, kabuğunuzun OSC 7 ile ilgili "
+"yapılandırmasını denetleyin"
+
+#, c-format
+msgid "E1180: Variable arguments type must be a list: %s"
+msgstr "E1180: Değişken argümanları türü bir liste olmalıdır: %s"
+
+msgid "E1181: Cannot use an underscore here"
+msgstr "E1181: Alt çizgi burada kullanılamaz"
+
+msgid "E1182: Blob required"
+msgstr "E1182: İkili geniş nesne gerekiyor"
+
+#, c-format
+msgid "E1183: Cannot use a range with an assignment operator: %s"
+msgstr "E1183: Bir atama işleci ile bir erim kullanılamıyor: %s"
+
+msgid "E1184: Blob not set"
+msgstr "E1184: İkili geniş nesne ayarlanmamış"
+
+msgid "E1185: Cannot nest :redir"
+msgstr "E1185: :redir içe geçirilemiyor"
+
+msgid "E1185: Missing :redir END"
+msgstr "E1185: :redir END eksik"
+
+#, c-format
+msgid "E1186: Expression does not result in a value: %s"
+msgstr "E1186: İfade bir değer sonucu vermiyor: %s"
+
+msgid "E1187: Failed to source defaults.vim"
+msgstr "E1187: defaults.vim kaynaklanamadı"
+
+msgid "E1188: Cannot open a terminal from the command line window"
+msgstr "E1188: Komut satırı penceresinden bir uçbirim açılamıyor"
+
+#, c-format
+msgid "E1189: Cannot use :legacy with this command: %s"
+msgstr "E1189: :legacy, bu komut ile kullanılamıyor: %s"
+
+msgid "E1190: One argument too few"
+msgstr "E1190: Bir argüman daha gerekiyor"
+
+#, c-format
+msgid "E1190: %d arguments too few"
+msgstr "E1190: %d argüman daha gerekiyor"
+
+#, c-format
+msgid "E1191: Call to function that failed to compile: %s"
+msgstr "E1191: Derlenemeyen işlev çağrısı: %s"
+
+msgid "E1192: Empty function name"
+msgstr "E1192: Boş işlev adı"
+
+msgid "E1193: cryptmethod xchacha20 not built into this Vim"
+msgstr "E1193: cryptmethod xchacha20 bu Vim ile kullanılamıyor"
+
+msgid "E1194: Cannot encrypt header, not enough space"
+msgstr "E1194: Üstbilgi şifrelenemiyor, yetersiz alan"
+
+msgid "E1195: Cannot encrypt buffer, not enough space"
+msgstr "E1195: Arabellek şifrelenemiyor, yetersiz alan"
+
+msgid "E1196: Cannot decrypt header, not enough space"
+msgstr "E1196: Üstbilgi şifresi çözülemiyor, yetersiz alan"
+
+msgid "E1197: Cannot allocate_buffer for encryption"
+msgstr "E1197: Şifreleme için allocate_buffer yapılamıyor"
+
+msgid "E1198: Decryption failed: Header incomplete!"
+msgstr "E1198: Şifre çözümü başarısız: Üstbilgi tam değil!"
+
+msgid "E1199: Cannot decrypt buffer, not enough space"
+msgstr "E1199: Arabellek şifresi çözülemiyor, yetersiz alan"
+
+msgid "E1200: Decryption failed!"
+msgstr "E1200: Şifre çözümü başarısız!"
+
+msgid "E1201: Decryption failed: pre-mature end of file!"
+msgstr "E1201: Şifre çözümü başarısız: Beklenmedik dosya sonu!"
+
+#, c-format
+msgid "E1202: No white space allowed after '%s': %s"
+msgstr "E1202: '%s' sonrası boşluğa izin verilmiyor: %s"
+
+#, c-format
+msgid "E1203: Dot can only be used on a dictionary: %s"
+msgstr "E1203: Nokta yalnızca bir sözlükte kullanılabilir: %s"
+
+#, c-format
+msgid "E1204: No Number allowed after .: '\\%%%c'"
+msgstr "E1204: . sonrası Sayıya izin verilmiyor: '\\%%%c'"
+
+msgid "E1205: No white space allowed between option and"
+msgstr "E1205: and seçeneği arasında boşluğa izin verilmiyor"
+
+#, c-format
+msgid "E1206: Dictionary required for argument %d"
+msgstr "E1206: %d argümanı için sözlük gerekiyor"
+
+#, c-format
+msgid "E1207: Expression without an effect: %s"
+msgstr "E1207: Bir efekt olmadan ifade: %s"
+
+msgid "E1208: -complete used without -nargs"
+msgstr "E1208: -complete, -nargs olmadan kullanıldı"
+
+#, c-format
+msgid "E1209: Invalid value for a line number: \"%s\""
+msgstr "E1209: Satır numarası için geçersiz değer: \"%s\""
+
+#, c-format
+msgid "E1210: Number required for argument %d"
+msgstr "E1210: %d argümanı için sayı gerekiyor"
+
msgid "--No lines in buffer--"
msgstr "--Arabellek içinde satır yok--"
@@ -7123,17 +7438,6 @@ msgstr "E470: Komut durduruldu"
msgid "E471: Argument required"
msgstr "E471: Değişken gerekiyor"
-msgid "E10: \\ should be followed by /, ? or &"
-msgstr "E10: \\ sonrasında /, ? veya & gelmeli"
-
-msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
-msgstr "E11: Komut satırı penceresinde geçersiz; <CR> çalıştırır, CTRL-C çıkar"
-
-msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
-msgstr ""
-"E12: Geçerli dizin veya etiket aramasında exrc veya vimrc'den komutlara izin "
-"verilmiyor"
-
msgid "E171: Missing :endif"
msgstr "E171: :endif eksik"
@@ -7164,9 +7468,6 @@ msgstr "E588: :while olmadan :endwhile"
msgid "E588: :endfor without :for"
msgstr "E588: :for olmadan :endfor"
-msgid "E13: File exists (add ! to override)"
-msgstr "E13: Dosya mevcut (geçersiz kılmak için ! ekleyin)"
-
msgid "E472: Command failed"
msgstr "E472: Komut başarısız oldu"
@@ -7193,34 +7494,23 @@ msgid "Interrupted"
msgstr "Yarıda kesildi"
msgid "E474: Invalid argument"
-msgstr "E474: Geçersiz değişken"
+msgstr "E474: Geçersiz argüman"
#, c-format
msgid "E475: Invalid argument: %s"
-msgstr "E475: Geçersiz değişken: %s"
+msgstr "E475: Geçersiz argüman: %s"
#, c-format
msgid "E983: Duplicate argument: %s"
-msgstr "E983: Yinelenen değişken: %s"
+msgstr "E983: Yinelenen argüman: %s"
#, c-format
msgid "E475: Invalid value for argument %s"
-msgstr "E475: %s değişkeni için geçersiz değer"
+msgstr "E475: %s argümanı için geçersiz değer"
#, c-format
msgid "E475: Invalid value for argument %s: %s"
-msgstr "E475: %s değişkeni için geçersiz değer: %s"
-
-#, c-format
-msgid "E15: Invalid expression: %s"
-msgstr "E15: Geçersiz ifade: %s"
-
-msgid "E16: Invalid range"
-msgstr "E16: Geçersiz erim"
-
-#, c-format
-msgid "E17: \"%s\" is a directory"
-msgstr "E17: \"%s\" bir dizin"
+msgstr "E475: %s argümanı için geçersiz değer: %s"
msgid "E756: Spell checking is not possible"
msgstr "E756: Yazım denetimi olanaklı değil"
@@ -7236,24 +7526,6 @@ msgstr "E667: Fsync başarısız oldu"
msgid "E448: Could not load library function %s"
msgstr "E448: %s kitaplık işlevi yüklenemedi"
-msgid "E19: Mark has invalid line number"
-msgstr "E19: İm satır numarası geçersiz"
-
-msgid "E20: Mark not set"
-msgstr "E20: İm ayarlanmamış"
-
-msgid "E21: Cannot make changes, 'modifiable' is off"
-msgstr "E21: Değişiklik yapılamıyor, 'modifiable' kapalı"
-
-msgid "E22: Scripts nested too deep"
-msgstr "E22: Betikler çok iç içe geçmiş"
-
-msgid "E23: No alternate file"
-msgstr "E23: Başka bir dosya yok"
-
-msgid "E24: No such abbreviation"
-msgstr "E24: Böyle bir kısaltma yok"
-
msgid "E477: No ! allowed"
msgstr "E477: ! imine izin verilmiyor"
@@ -7327,7 +7599,7 @@ msgid "E485: Can't read file %s"
msgstr "E485: %s dosyası okunamıyor"
msgid "E38: Null argument"
-msgstr "E38: Anlamsız değişken"
+msgstr "E38: Anlamsız argüman"
msgid "E39: Number expected"
msgstr "E39: Sayı bekleniyordu"
@@ -7392,6 +7664,9 @@ msgstr "E794: Değişken kum havuzunda ayarlanamıyor: \"%s\""
msgid "E928: String required"
msgstr "E928: Dizi gerekiyor"
+msgid "E889: Number required"
+msgstr "E889: Sayı gerekiyor"
+
msgid "E713: Cannot use empty key for Dictionary"
msgstr "E713: Sözlük için boş anahtar kullanılamaz"
@@ -7411,11 +7686,11 @@ msgstr "E978: İkili geniş nesne için geçersiz işlem"
#, c-format
msgid "E118: Too many arguments for function: %s"
-msgstr "E118: İşlev için çok fazla değişken: %s"
+msgstr "E118: İşlev için çok fazla argüman: %s"
#, c-format
msgid "E119: Not enough arguments for function: %s"
-msgstr "E119: Şu işlev için yetersiz sayıda değişken: %s"
+msgstr "E119: Şu işlev için yetersiz sayıda argüman: %s"
#, c-format
msgid "E933: Function was deleted: %s"
@@ -7437,18 +7712,15 @@ msgstr "E697: Liste sonunda ']' eksik: %s"
#, c-format
msgid "E712: Argument of %s must be a List or Dictionary"
-msgstr "E712: %s ögesinin değişkeni bir liste veya sözlük olmalıdır"
+msgstr "E712: %s ögesinin argümanı bir liste veya sözlük olmalıdır"
#, c-format
msgid "E896: Argument of %s must be a List, Dictionary or Blob"
-msgstr "E896: %s değişkeni bir liste, sözlük veya ikili geniş nesne olmalıdır"
+msgstr "E896: %s argümanı bir liste, sözlük veya ikili geniş nesne olmalıdır"
msgid "E804: Cannot use '%' with Float"
msgstr "E804: Bir kayan noktalı değer ile '%' kullanılamaz"
-msgid "E908: using an invalid value as a String"
-msgstr "E908: Geçersiz bir değer bir Dizi yerine kullanılıyor"
-
msgid "E996: Cannot lock an option"
msgstr "E996: Seçenek kilitlenemiyor"
@@ -7456,9 +7728,6 @@ msgstr "E996: Seçenek kilitlenemiyor"
msgid "E113: Unknown option: %s"
msgstr "E113: Bilinmeyen seçenek: %s"
-msgid "E18: Unexpected characters in :let"
-msgstr "E18: :let içinde beklenmeyen karakter"
-
#, c-format
msgid "E998: Reduce of an empty %s with no initial value"
msgstr "E998: Başlangıç değeri olmayan boş bir %s için reduce() yapılamıyor"
@@ -7616,7 +7885,7 @@ msgstr "E957: Geçersiz pencere numarası"
#, c-format
msgid "E686: Argument of %s must be a List"
-msgstr "E686: %s değişkeni bir liste olmalı"
+msgstr "E686: %s argümanı bir liste olmalı"
msgid "E109: Missing ':' after '?'"
msgstr "E109: '?' sonrası ':' eksik"
@@ -7685,7 +7954,7 @@ msgstr "'%s' anahtarı sözlüğe eklenemedi"
#, c-format
msgid "index must be int or slice, not %s"
-msgstr "dizin bir tamsayı veya dilim olmalıdır, %s olamaz"
+msgstr "sıra bir tamsayı veya dilim olmalıdır, %s olamaz"
#, c-format
msgid "expected str() or unicode() instance, but got %s"
@@ -7762,10 +8031,10 @@ msgid "expected sequence element of size 2, but got sequence of size %d"
msgstr "2 boyut bir sıralama bekleniyordu, ancak %d boyut bir sıralama geldi"
msgid "list constructor does not accept keyword arguments"
-msgstr "liste yapıcısı anahtar sözcük değişkenleri kabul etmez"
+msgstr "liste yapıcısı anahtar sözcük argümanları kabul etmez"
msgid "list index out of range"
-msgstr "liste dizini erimin dışında"
+msgstr "liste sırası erimin dışında"
#, c-format
msgid "internal error: failed to get Vim list item %d"
@@ -8013,8 +8282,7 @@ msgstr ""
"düzenleyebilirsiniz."
msgid "\" Hit <Enter> on a help line to open a help window on this option."
-msgstr ""
-"\" Yardım penceresini açmak için seçenek adı üzerinde <Enter>'a basın."
+msgstr "\" Yardım penceresini açmak için seçenek adı üzerinde <Enter>'a basın."
msgid "\" Hit <Enter> on an index line to jump there."
msgstr ""
@@ -8056,7 +8324,8 @@ msgid "moving around, searching and patterns"
msgstr "dolaşma, arama ve dizgeler"
msgid "list of flags specifying which commands wrap to another line"
-msgstr "hangi komutların diğer satıra kaydırıldığını belirleyen bayraklar\n"
+msgstr ""
+"hangi komutların diğer satıra kaydırıldığını belirleyen bayraklar\n"
"listesi"
msgid ""
@@ -8081,6 +8350,9 @@ msgstr ":cd için kullanılan dizin adları listesi"
msgid "change to directory of file in buffer"
msgstr "arabellekteki dosyanın olduğu dizine değiştir"
+msgid "change to pwd of shell in terminal buffer"
+msgstr "uçbirim arabelleğindeki kabuğun pwd'sine geç"
+
msgid "search commands wrap around the end of the buffer"
msgstr "arama komutları, arabelleğin sonunda kaydırılır"
@@ -8320,7 +8592,8 @@ msgid "multiple windows"
msgstr "çoklu pencereler"
msgid "0, 1 or 2; when to use a status line for the last window"
-msgstr "0, 1 veya 2; son pencere için ne zaman bir durum satırı\n"
+msgstr ""
+"0, 1 veya 2; son pencere için ne zaman bir durum satırı\n"
"kullanılacağı"
msgid "alternate format to be used for a status line"
@@ -8382,7 +8655,8 @@ msgid "this window scrolls together with other bound windows"
msgstr "bu pencere, bağlı diğer pencerelerle birlikte kayar"
msgid "\"ver\", \"hor\" and/or \"jump\"; list of options for 'scrollbind'"
-msgstr "\"ver\", \"hor\" ve/veya \"jump\"; 'scrollbind' için seçenekler listesi"
+msgstr ""
+"\"ver\", \"hor\" ve/veya \"jump\"; 'scrollbind' için seçenekler listesi"
msgid "this window's cursor moves together with other bound windows"
msgstr "bu pencerenin imleci bağlı diğer pencerelerle birlikte kayar"
@@ -8394,7 +8668,8 @@ msgid "key that precedes Vim commands in a terminal window"
msgstr "bir uçbirim penceresinde Vim komutlarından önce gelen düğme"
msgid "max number of lines to keep for scrollback in a terminal window"
-msgstr "bir uçbirim penceresinde geri kaydırma için kullanılacak\n"
+msgstr ""
+"bir uçbirim penceresinde geri kaydırma için kullanılacak\n"
"en çok satır sayısı"
msgid "type of pty to use for a terminal window"
@@ -8522,8 +8797,7 @@ msgid "list of flags that specify how the GUI works"
msgstr "grafik arabirimin nice çalıştığını belirleyen bayraklar listesi"
msgid "\"icons\", \"text\" and/or \"tooltips\"; how to show the toolbar"
-msgstr ""
-"\"icons\", \"text\" ve/veya \"tooltips\"; araç çubuğu kipleri "
+msgstr "\"icons\", \"text\" ve/veya \"tooltips\"; araç çubuğu kipleri "
msgid "size of toolbar icons"
msgstr "araç çubuğu simgelerinin boyutu"
@@ -8679,7 +8953,8 @@ msgid "list of directories for undo files"
msgstr "geri al dosyaları için dizinler listesi"
msgid "maximum number lines to save for undo on a buffer reload"
-msgstr "arabellek yeniden yüklemesinde geri al için kaydedilecek\n"
+msgstr ""
+"arabellek yeniden yüklemesinde geri al için kaydedilecek\n"
"en çok satır sayısı"
msgid "changes have been made and not written to a file"
@@ -8704,7 +8979,8 @@ msgid "definition of what comment lines look like"
msgstr "yorum satırlarının nice görüneceğinin tanımı"
msgid "list of flags that tell how automatic formatting works"
-msgstr "kendiliğinden biçimlendirmenin nice çalıştığını anlatan\n"
+msgstr ""
+"kendiliğinden biçimlendirmenin nice çalıştığını anlatan\n"
"bayraklar listesi"
msgid "pattern to recognize a numbered list"
@@ -8714,7 +8990,8 @@ msgid "expression used for \"gq\" to format lines"
msgstr "satırları biçimlendirmek için \"gq\" için kullanılan ifade"
msgid "specifies how Insert mode completion works for CTRL-N and CTRL-P"
-msgstr "Ekleme kipi tamamlamasının CTRL-N ve CTRL-P için nice çalıştığını\n"
+msgstr ""
+"Ekleme kipi tamamlamasının CTRL-N ve CTRL-P için nice çalıştığını\n"
"belirler"
msgid "whether to use a popup menu for Insert mode completion"
@@ -8739,7 +9016,8 @@ msgid "list of dictionary files for keyword completion"
msgstr "anahtar sözcük tamamlaması için sözlük dosyaları listesi"
msgid "list of thesaurus files for keyword completion"
-msgstr "anahtar sözcük tamamlaması için eşanlamlılar sözlüğü dosyaları\n"
+msgstr ""
+"anahtar sözcük tamamlaması için eşanlamlılar sözlüğü dosyaları\n"
"listesi"
msgid "adjust case of a keyword completion match"
@@ -8883,7 +9161,8 @@ msgid "markers used when 'foldmethod' is \"marker\""
msgstr "'foldmethod' \"marker\" olduğunda kullanılan imleyiciler"
msgid "maximum fold depth for when 'foldmethod' is \"indent\" or \"syntax\""
-msgstr "'foldmethod' \"indent\" veya \"syntax\" olduğunda kullanılan en çok\n"
+msgstr ""
+"'foldmethod' \"indent\" veya \"syntax\" olduğunda kullanılan en çok\n"
"kıvırma derinliği"
msgid "diff mode"
@@ -9013,7 +9292,8 @@ msgid "use a swap file for this buffer"
msgstr "bu arabellek için bir takas dosyası kullan"
msgid "\"sync\", \"fsync\" or empty; how to flush a swap file to disk"
-msgstr "\"sync\", \"fsync\", veya boş; bir takas dosyasının diske\n"
+msgstr ""
+"\"sync\", \"fsync\", veya boş; bir takas dosyasının diske\n"
"nice floşlanacağı"
msgid "number of characters typed to cause a swap file update"
@@ -9089,13 +9369,14 @@ msgid "characters to escape when 'shellxquote' is ("
msgstr "'shellxquote' ( iken kaçırılacak karakterler"
msgid "argument for 'shell' to execute a command"
-msgstr "bir komut çalıştırmak için 'shell' için değişken"
+msgstr "bir komut çalıştırmak için 'shell' için argüman"
msgid "used to redirect command output to a file"
msgstr "komut çıktısını bir dosyaya yeniden yönlendirmek için kullanılır"
msgid "use a temp file for shell commands instead of using a pipe"
-msgstr "bir veri yolu kullanımı yerine kabuk komutları için geçici\n"
+msgstr ""
+"bir veri yolu kullanımı yerine kabuk komutları için geçici\n"
"bir dosya kullan"
msgid "program used for \"=\" command"
@@ -9108,7 +9389,8 @@ msgid "program used for the \"K\" command"
msgstr "\"K\" komutu için kullanılan program"
msgid "warn when using a shell command and a buffer has changes"
-msgstr "bir kabuk komutu kullanılıyorsa ve arabellekte değişiklikler\n"
+msgstr ""
+"bir kabuk komutu kullanılıyorsa ve arabellekte değişiklikler\n"
"varsa uyar"
msgid "running make and jumping to errors (quickfix)"
@@ -9124,7 +9406,8 @@ msgid "program used for the \":make\" command"
msgstr "\":make\" komutu için kullanılan program"
msgid "string used to put the output of \":make\" in the error file"
-msgstr "\":make\" komutunun çıktısını hata dosyasına koymak için\n"
+msgstr ""
+"\":make\" komutunun çıktısını hata dosyasına koymak için\n"
"kullanılan dizi"
msgid "name of the errorfile for the 'makeprg' command"
@@ -9179,7 +9462,8 @@ msgid "insert characters backwards"
msgstr "karakterleri geriye doğru ekle"
msgid "allow CTRL-_ in Insert and Command-line mode to toggle 'revins'"
-msgstr "'revins' açıp kapatmak için Ekleme ve Komut Satırı kipinde\n"
+msgstr ""
+"'revins' açıp kapatmak için Ekleme ve Komut Satırı kipinde\n"
"CTRL-_ izin ver"
msgid "the ASCII code for the first letter of the Hebrew alphabet"
@@ -9210,8 +9494,9 @@ msgid "apply 'langmap' to mapped characters"
msgstr "eşlemlenen karakterlere 'langmap' uygula"
msgid "when set never use IM; overrules following IM options"
-msgstr "ayarlandığında hiçbir zaman IM kullanma; aşağıdaki IM seçeneklerini "
-"geçersiz kılar"
+msgstr ""
+"ayarlandığında hiçbir zaman IM kullanma; aşağıdaki IM seçeneklerini geçersiz "
+"kılar"
msgid "in Insert mode: 1: use :lmap; 2: use IM; 0: neither"
msgstr "Ekleme kipinde: 1: :lmap kullan; 2; IM kullan; 0: hiçbiri"
diff --git a/src/nvim/popupmnu.c b/src/nvim/popupmnu.c
index f620517aff..606c03f838 100644
--- a/src/nvim/popupmnu.c
+++ b/src/nvim/popupmnu.c
@@ -9,26 +9,27 @@
#include <inttypes.h>
#include <stdbool.h>
-#include "nvim/vim.h"
#include "nvim/api/private/helpers.h"
#include "nvim/ascii.h"
-#include "nvim/eval/typval.h"
-#include "nvim/popupmnu.h"
+#include "nvim/buffer.h"
#include "nvim/charset.h"
+#include "nvim/edit.h"
+#include "nvim/eval/typval.h"
#include "nvim/ex_cmds.h"
#include "nvim/memline.h"
+#include "nvim/memory.h"
#include "nvim/move.h"
#include "nvim/option.h"
+#include "nvim/popupmnu.h"
#include "nvim/screen.h"
-#include "nvim/ui_compositor.h"
#include "nvim/search.h"
#include "nvim/strings.h"
-#include "nvim/memory.h"
-#include "nvim/window.h"
-#include "nvim/edit.h"
#include "nvim/ui.h"
+#include "nvim/ui_compositor.h"
+#include "nvim/vim.h"
+#include "nvim/window.h"
-static pumitem_T *pum_array = NULL; // items of displayed pum
+static pumitem_T *pum_array = NULL; // items of displayed pum
static int pum_size; // nr of items in "pum_array"
static int pum_selected; // index of selected item or -1
static int pum_first = 0; // index of top item
@@ -97,8 +98,7 @@ static void pum_compute_size(void)
/// if false, a new item is selected, but the array
/// is the same
/// @param cmd_startcol only for cmdline mode: column of completed match
-void pum_display(pumitem_T *array, int size, int selected, bool array_changed,
- int cmd_startcol)
+void pum_display(pumitem_T *array, int size, int selected, bool array_changed, int cmd_startcol)
{
int context_lines;
int above_row;
@@ -233,7 +233,7 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed,
context_lines = 3;
} else {
context_lines = curwin->w_cline_row
- + curwin->w_cline_height - curwin->w_wrow;
+ + curwin->w_cline_height - curwin->w_wrow;
}
pum_row = pum_win_row + context_lines;
@@ -487,17 +487,17 @@ void pum_redraw(void)
s = NULL;
switch (round) {
- case 1:
- p = pum_array[idx].pum_text;
- break;
+ case 1:
+ p = pum_array[idx].pum_text;
+ break;
- case 2:
- p = pum_array[idx].pum_kind;
- break;
+ case 2:
+ p = pum_array[idx].pum_kind;
+ break;
- case 3:
- p = pum_array[idx].pum_extra;
- break;
+ case 3:
+ p = pum_array[idx].pum_extra;
+ break;
}
if (p != NULL) {
@@ -514,7 +514,7 @@ void pum_redraw(void)
char_u saved = *p;
*p = NUL;
- st = (char_u *)transstr((const char *)s);
+ st = (char_u *)transstr((const char *)s, true);
*p = saved;
if (pum_rl) {
@@ -735,7 +735,7 @@ static int pum_set_selected(int n, int repeat)
&& (curbuf->b_p_bt[2] == 'f')
&& (curbuf->b_p_bh[0] == 'w')) {
// Already a "wipeout" buffer, make it empty.
- while (!BUFEMPTY()) {
+ while (!buf_is_empty(curbuf)) {
ml_delete((linenr_T)1, false);
}
} else {
diff --git a/src/nvim/profile.c b/src/nvim/profile.c
index 0a5030edae..fe7bd2e912 100644
--- a/src/nvim/profile.c
+++ b/src/nvim/profile.c
@@ -1,17 +1,16 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
-#include <stdio.h>
-#include <math.h>
#include <assert.h>
+#include <math.h>
+#include <stdio.h>
#include "nvim/assert.h"
-#include "nvim/profile.h"
-#include "nvim/os/time.h"
#include "nvim/func_attr.h"
-#include "nvim/os/os_defs.h"
-
#include "nvim/globals.h" // for the global `time_fd` (startuptime)
+#include "nvim/os/os_defs.h"
+#include "nvim/os/time.h"
+#include "nvim/profile.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "profile.c.generated.h"
@@ -97,7 +96,7 @@ proftime_T profile_divide(proftime_T tm, int count) FUNC_ATTR_CONST
return profile_zero();
}
- return (proftime_T) round((double) tm / (double) count);
+ return (proftime_T)round((double)tm / (double)count);
}
/// Adds time `tm2` to `tm1`.
@@ -250,7 +249,7 @@ void time_start(const char *message)
return;
}
- // intialize the global variables
+ // initialize the global variables
g_prev_time = g_start_time = profile_start();
fprintf(time_fd, "\n\ntimes in msec\n");
diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c
index 71624baaf4..eb0ba874f4 100644
--- a/src/nvim/quickfix.c
+++ b/src/nvim/quickfix.c
@@ -8,9 +8,8 @@
#include <stdbool.h>
#include <string.h>
-#include "nvim/vim.h"
+#include "nvim/api/private/helpers.h"
#include "nvim/ascii.h"
-#include "nvim/quickfix.h"
#include "nvim/buffer.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
@@ -26,48 +25,52 @@
#include "nvim/mark.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
+#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/memory.h"
#include "nvim/move.h"
#include "nvim/normal.h"
#include "nvim/option.h"
+#include "nvim/os/input.h"
+#include "nvim/os/os.h"
#include "nvim/os_unix.h"
#include "nvim/path.h"
+#include "nvim/quickfix.h"
#include "nvim/regexp.h"
#include "nvim/screen.h"
#include "nvim/search.h"
#include "nvim/strings.h"
#include "nvim/syntax.h"
#include "nvim/ui.h"
+#include "nvim/vim.h"
#include "nvim/window.h"
-#include "nvim/os/os.h"
-#include "nvim/os/input.h"
-#include "nvim/api/private/helpers.h"
struct dir_stack_T {
- struct dir_stack_T *next;
- char_u *dirname;
+ struct dir_stack_T *next;
+ char_u *dirname;
};
// For each error the next struct is allocated and linked in a list.
typedef struct qfline_S qfline_T;
struct qfline_S {
- qfline_T *qf_next; ///< pointer to next error in the list
- qfline_T *qf_prev; ///< pointer to previous error in the list
- linenr_T qf_lnum; ///< line number where the error occurred
- int qf_fnum; ///< file number for the line
- int qf_col; ///< column where the error occurred
- int qf_nr; ///< error number
- char_u *qf_module; ///< module name for this error
- char_u *qf_pattern; ///< search pattern for the error
- char_u *qf_text; ///< description of the error
- char_u qf_viscol; ///< set to TRUE if qf_col is screen column
- char_u qf_cleared; ///< set to TRUE if line has been deleted
- char_u qf_type; ///< type of the error (mostly 'E'); 1 for
- // :helpgrep
- char_u qf_valid; ///< valid error message detected
+ qfline_T *qf_next; ///< pointer to next error in the list
+ qfline_T *qf_prev; ///< pointer to previous error in the list
+ linenr_T qf_lnum; ///< line number where the error occurred
+ linenr_T qf_end_lnum; ///< line number when the error has range or zero
+
+ int qf_fnum; ///< file number for the line
+ int qf_col; ///< column where the error occurred
+ int qf_end_col; ///< column when the error has range or zero
+ int qf_nr; ///< error number
+ char_u *qf_module; ///< module name for this error
+ char_u *qf_pattern; ///< search pattern for the error
+ char_u *qf_text; ///< description of the error
+ char_u qf_viscol; ///< set to TRUE if qf_col and qf_end_col is
+ // screen column
+ char_u qf_cleared; ///< set to TRUE if line has been deleted
+ char_u qf_type; ///< type of the error (mostly 'E'); 1 for :helpgrep
+ char_u qf_valid; ///< valid error message detected
};
// There is a stack of error lists.
@@ -80,7 +83,7 @@ typedef enum
QFLT_QUICKFIX, ///< Quickfix list - global list
QFLT_LOCATION, ///< Location list - per window list
QFLT_INTERNAL ///< Internal - Temporary list used by
- // getqflist()/getloclist()
+ // getqflist()/getloclist()
} qfltype_T;
/// Quickfix/Location list definition
@@ -90,17 +93,17 @@ typedef enum
/// information and entries can be added later using setqflist()/setloclist().
typedef struct qf_list_S {
unsigned qf_id; ///< Unique identifier for this list
- qfltype_T qfl_type;
- qfline_T *qf_start; ///< pointer to the first error
- qfline_T *qf_last; ///< pointer to the last error
- qfline_T *qf_ptr; ///< pointer to the current error
+ qfltype_T qfl_type;
+ qfline_T *qf_start; ///< pointer to the first error
+ qfline_T *qf_last; ///< pointer to the last error
+ qfline_T *qf_ptr; ///< pointer to the current error
int qf_count; ///< number of errors (0 means empty list)
int qf_index; ///< current index in the error list
int qf_nonevalid; ///< TRUE if not a single valid entry found
- char_u *qf_title; ///< title derived from the command that created
- ///< the error list or set by setqflist
- typval_T *qf_ctx; ///< context set by setqflist/setloclist
- Callback qftf_cb; ///< 'quickfixtextfunc' callback function
+ char_u *qf_title; ///< title derived from the command that created
+ ///< the error list or set by setqflist
+ typval_T *qf_ctx; ///< context set by setqflist/setloclist
+ Callback qftf_cb; ///< 'quickfixtextfunc' callback function
struct dir_stack_T *qf_dir_stack;
char_u *qf_directory;
@@ -134,8 +137,8 @@ static unsigned last_qf_id = 0; // Last Used quickfix list id
// Structure used to hold the info of one part of 'errorformat'
typedef struct efm_S efm_T;
struct efm_S {
- regprog_T *prog; // pre-formatted part of 'errorformat'
- efm_T *next; // pointer to next (NULL if last)
+ regprog_T *prog; // pre-formatted part of 'errorformat'
+ efm_T *next; // pointer to next (NULL if last)
char_u addr[FMT_PATTERNS]; // indices of used % patterns
char_u prefix; // prefix of this format line:
// 'D' enter directory
@@ -180,12 +183,12 @@ typedef struct {
size_t linelen;
char_u *growbuf;
size_t growbufsiz;
- FILE *fd;
- typval_T *tv;
- char_u *p_str;
- list_T *p_list;
+ FILE *fd;
+ typval_T *tv;
+ char_u *p_str;
+ list_T *p_list;
listitem_T *p_li;
- buf_T *buf;
+ buf_T *buf;
linenr_T buflnum;
linenr_T lnumlast;
vimconv_T vc;
@@ -197,12 +200,14 @@ typedef struct {
char_u *errmsg;
size_t errmsglen;
long lnum;
- int col;
+ long end_lnum;
+ int col;
+ int end_col;
bool use_viscol;
char_u *pattern;
- int enr;
+ int enr;
char_u type;
- bool valid;
+ bool valid;
} qffields_T;
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -231,7 +236,7 @@ static char_u *e_no_more_items = (char_u *)N_("E553: No more items");
// Macro to loop through all the items in a quickfix list
// Quickfix item index starts from 1, so i below starts at 1
#define FOR_ALL_QFL_ITEMS(qfl, qfp, i) \
- for (i = 1, qfp = qfl->qf_start; /* NOLINT(readability/braces) */ \
+ for (i = 1, qfp = qfl->qf_start; /* NOLINT(readability/braces) */ \
!got_int && i <= qfl->qf_count && qfp != NULL; \
i++, qfp = qfp->qf_next)
@@ -239,7 +244,7 @@ static char_u *e_no_more_items = (char_u *)N_("E553: No more items");
// Looking up a buffer can be slow if there are many. Remember the last one
// to make this a lot faster if there are multiple matches in the same file.
static char_u *qf_last_bufname = NULL;
-static bufref_T qf_last_bufref = { NULL, 0, 0 };
+static bufref_T qf_last_bufref = { NULL, 0, 0 };
static char *e_current_quickfix_list_was_changed =
N_("E925: Current quickfix list was changed");
@@ -253,9 +258,7 @@ static qf_delq_T *qf_delq_head = NULL;
/// Process the next line from a file/buffer/list/string and add it
/// to the quickfix list 'qfl'.
-static int qf_init_process_nextline(qf_list_T *qfl,
- efm_T *fmt_first,
- qfstate_T *state,
+static int qf_init_process_nextline(qf_list_T *qfl, efm_T *fmt_first, qfstate_T *state,
qffields_T *fields)
{
int status;
@@ -282,7 +285,9 @@ static int qf_init_process_nextline(qf_list_T *qfl,
0,
fields->errmsg,
fields->lnum,
+ fields->end_lnum,
fields->col,
+ fields->end_col,
fields->use_viscol,
fields->pattern,
fields->enr,
@@ -301,11 +306,10 @@ static int qf_init_process_nextline(qf_list_T *qfl,
/// @params enc If non-NULL, encoding used to parse errors
///
/// @returns -1 for error, number of errors for success.
-int qf_init(win_T *wp, const char_u *restrict efile,
- char_u *restrict errorformat, int newlist,
+int qf_init(win_T *wp, const char_u *restrict efile, char_u *restrict errorformat, int newlist,
const char_u *restrict qf_title, char_u *restrict enc)
{
- qf_info_T *qi = &ql_info;
+ qf_info_T *qi = &ql_info;
if (wp != NULL) {
qi = ll_get_or_alloc_list(wp);
@@ -331,7 +335,7 @@ static struct fmtpattern
{ 't', "." },
{ 'm', ".\\+" },
{ 'r', ".*" },
- { 'p', "[- .]*" }, // NOLINT(whitespace/tab)
+ { 'p', "[- .]*"}, // NOLINT(whitespace/tab)
{ 'v', "\\d\\+" },
{ 's', ".\\+" },
{ 'o', ".\\+" }
@@ -341,14 +345,8 @@ static struct fmtpattern
/// See fmt_pat definition above for the list of supported patterns. The
/// pattern specifier is supplied in "efmpat". The converted pattern is stored
/// in "regpat". Returns a pointer to the location after the pattern.
-static char_u * efmpat_to_regpat(
- const char_u *efmpat,
- char_u *regpat,
- efm_T *efminfo,
- int idx,
- int round,
- char_u *errmsg,
- size_t errmsglen)
+static char_u *efmpat_to_regpat(const char_u *efmpat, char_u *regpat, efm_T *efminfo, int idx,
+ int round, char_u *errmsg, size_t errmsglen)
FUNC_ATTR_NONNULL_ALL
{
if (efminfo->addr[idx]) {
@@ -367,7 +365,7 @@ static char_u * efmpat_to_regpat(
EMSG(errmsg);
return NULL;
}
- efminfo->addr[idx] = (char_u)++round;
+ efminfo->addr[idx] = (char_u)++ round;
*regpat++ = '\\';
*regpat++ = '(';
#ifdef BACKSLASH_IN_FILENAME
@@ -408,13 +406,8 @@ static char_u * efmpat_to_regpat(
/// Convert a scanf like format in 'errorformat' to a regular expression.
/// Returns a pointer to the location after the pattern.
-static char_u * scanf_fmt_to_regpat(
- const char_u **pefmp,
- const char_u *efm,
- int len,
- char_u *regpat,
- char_u *errmsg,
- size_t errmsglen)
+static char_u *scanf_fmt_to_regpat(const char_u **pefmp, const char_u *efm, int len, char_u *regpat,
+ char_u *errmsg, size_t errmsglen)
FUNC_ATTR_NONNULL_ALL
{
const char_u *efmp = *pefmp;
@@ -452,8 +445,8 @@ static char_u * scanf_fmt_to_regpat(
}
/// Analyze/parse an errorformat prefix.
-static const char_u *efm_analyze_prefix(const char_u *efmp, efm_T *efminfo,
- char_u *errmsg, size_t errmsglen)
+static const char_u *efm_analyze_prefix(const char_u *efmp, efm_T *efminfo, char_u *errmsg,
+ size_t errmsglen)
FUNC_ATTR_NONNULL_ALL
{
if (vim_strchr((char_u *)"+-", *efmp) != NULL) {
@@ -473,8 +466,8 @@ static const char_u *efm_analyze_prefix(const char_u *efmp, efm_T *efminfo,
// Converts a 'errorformat' string to regular expression pattern
-static int efm_to_regpat(const char_u *efm, int len, efm_T *fmt_ptr,
- char_u *regpat, char_u *errmsg, size_t errmsglen)
+static int efm_to_regpat(const char_u *efm, int len, efm_T *fmt_ptr, char_u *regpat, char_u *errmsg,
+ size_t errmsglen)
FUNC_ATTR_NONNULL_ALL
{
// Build regexp pattern from current 'errorformat' option
@@ -591,7 +584,7 @@ static int efm_option_part_len(char_u *efm)
/// Parse the 'errorformat' option. Multiple parts in the 'errorformat' option
/// are parsed and converted to regular expressions. Returns information about
/// the parsed 'errorformat' option.
-static efm_T * parse_efm_option(char_u *efm)
+static efm_T *parse_efm_option(char_u *efm)
{
efm_T *fmt_ptr = NULL;
efm_T *fmt_first = NULL;
@@ -762,7 +755,7 @@ retry:
errno = 0;
if (fgets((char *)IObuff, IOSIZE, state->fd) == NULL) {
if (errno == EINTR) {
- goto retry;
+ goto retry;
}
return QF_END_OF_INPUT;
}
@@ -908,7 +901,7 @@ static bool qf_list_has_valid_entries(qf_list_T *qfl)
}
/// Return a pointer to a list in the specified quickfix stack
-static qf_list_T * qf_get_list(qf_info_T *qi, int idx)
+static qf_list_T *qf_get_list(qf_info_T *qi, int idx)
FUNC_ATTR_NONNULL_ALL
{
return &qi->qf_lists[idx];
@@ -916,11 +909,11 @@ static qf_list_T * qf_get_list(qf_info_T *qi, int idx)
/// Parse a line and get the quickfix fields.
/// Return the QF_ status.
-static int qf_parse_line(qf_list_T *qfl, char_u *linebuf,
- size_t linelen, efm_T *fmt_first, qffields_T *fields)
+static int qf_parse_line(qf_list_T *qfl, char_u *linebuf, size_t linelen, efm_T *fmt_first,
+ qffields_T *fields)
{
efm_T *fmt_ptr;
- int idx = 0;
+ int idx = 0;
char_u *tail = NULL;
int status;
@@ -1023,14 +1016,8 @@ static void qf_free_fields(qffields_T *pfields)
// Setup the state information used for parsing lines and populating a
// quickfix list.
-static int qf_setup_state(
- qfstate_T *pstate,
- char_u *restrict enc,
- const char_u *restrict efile,
- typval_T *tv,
- buf_T *buf,
- linenr_T lnumfirst,
- linenr_T lnumlast)
+static int qf_setup_state(qfstate_T *pstate, char_u *restrict enc, const char_u *restrict efile,
+ typval_T *tv, buf_T *buf, linenr_T lnumfirst, linenr_T lnumlast)
FUNC_ATTR_NONNULL_ARG(1)
{
pstate->vc.vc_type = CONV_NONE;
@@ -1073,38 +1060,32 @@ static void qf_cleanup_state(qfstate_T *pstate)
}
}
-// Read the errorfile "efile" into memory, line by line, building the error
-// list.
-// Alternative: when "efile" is NULL read errors from buffer "buf".
-// Alternative: when "tv" is not NULL get errors from the string or list.
-// Always use 'errorformat' from "buf" if there is a local value.
-// Then "lnumfirst" and "lnumlast" specify the range of lines to use.
-// Set the title of the list to "qf_title".
-// Return -1 for error, number of errors for success.
-static int
-qf_init_ext(
- qf_info_T *qi,
- int qf_idx,
- const char_u *restrict efile,
- buf_T *buf,
- typval_T *tv,
- char_u *restrict errorformat,
- bool newlist, // true: start a new error list
- linenr_T lnumfirst, // first line number to use
- linenr_T lnumlast, // last line number to use
- const char_u *restrict qf_title,
- char_u *restrict enc
-)
+/// Read the errorfile "efile" into memory, line by line, building the error
+/// list.
+/// Alternative: when "efile" is NULL read errors from buffer "buf".
+/// Alternative: when "tv" is not NULL get errors from the string or list.
+/// Always use 'errorformat' from "buf" if there is a local value.
+/// Then "lnumfirst" and "lnumlast" specify the range of lines to use.
+/// Set the title of the list to "qf_title".
+///
+/// @param newlist true: start a new error list
+/// @param lnumfirst first line number to use
+/// @param lnumlast last line number to use
+///
+/// @return -1 for error, number of errors for success.
+static int qf_init_ext(qf_info_T *qi, int qf_idx, const char_u *restrict efile, buf_T *buf,
+ typval_T *tv, char_u *restrict errorformat, bool newlist, linenr_T lnumfirst,
+ linenr_T lnumlast, const char_u *restrict qf_title, char_u *restrict enc)
FUNC_ATTR_NONNULL_ARG(1)
{
qf_list_T *qfl;
qfstate_T state = { 0 };
qffields_T fields = { 0 };
- qfline_T *old_last = NULL;
+ qfline_T *old_last = NULL;
bool adding = false;
- static efm_T *fmt_first = NULL;
- char_u *efm;
- static char_u *last_efm = NULL;
+ static efm_T *fmt_first = NULL;
+ char_u *efm;
+ static char_u *last_efm = NULL;
int retval = -1; // default: return error flag
int status;
@@ -1230,7 +1211,7 @@ static void qf_store_title(qf_list_T *qfl, const char_u *title)
/// that created the quickfix list with the ":" prefix.
/// Create a quickfix list title string by prepending ":" to a user command.
/// Returns a pointer to a static buffer with the title.
-static char_u * qf_cmdtitle(char_u *cmd)
+static char_u *qf_cmdtitle(char_u *cmd)
{
static char_u qftitle_str[IOSIZE];
@@ -1240,7 +1221,7 @@ static char_u * qf_cmdtitle(char_u *cmd)
}
/// Return a pointer to the current list in the specified quickfix stack
-static qf_list_T * qf_get_curlist(qf_info_T *qi)
+static qf_list_T *qf_get_curlist(qf_info_T *qi)
FUNC_ATTR_NONNULL_ALL
{
return qf_get_list(qi, qi->qf_curlist);
@@ -1269,8 +1250,9 @@ static void qf_new_list(qf_info_T *qi, const char_u *qf_title)
qi->qf_lists[i - 1] = qi->qf_lists[i];
}
qi->qf_curlist = LISTCOUNT - 1;
- } else
+ } else {
qi->qf_curlist = qi->qf_listcount++;
+ }
qfl = qf_get_curlist(qi);
memset(qfl, 0, sizeof(qf_list_T));
qf_store_title(qfl, qf_title);
@@ -1280,10 +1262,7 @@ static void qf_new_list(qf_info_T *qi, const char_u *qf_title)
/// Parse the match for filename ('%f') pattern in regmatch.
/// Return the matched value in "fields->namebuf".
-static int qf_parse_fmt_f(regmatch_T *rmp,
- int midx,
- qffields_T *fields,
- int prefix)
+static int qf_parse_fmt_f(regmatch_T *rmp, int midx, qffields_T *fields, int prefix)
{
char_u c;
@@ -1353,9 +1332,7 @@ static int qf_parse_fmt_t(regmatch_T *rmp, int midx, qffields_T *fields)
/// Parse the match for '%+' format pattern. The whole matching line is included
/// in the error string. Return the matched line in "fields->errmsg".
-static void qf_parse_fmt_plus(const char_u *linebuf,
- size_t linelen,
- qffields_T *fields)
+static void qf_parse_fmt_plus(const char_u *linebuf, size_t linelen, qffields_T *fields)
FUNC_ATTR_NONNULL_ALL
{
if (linelen >= fields->errmsglen) {
@@ -1492,9 +1469,8 @@ static int (*qf_parse_fmt[FMT_PATTERNS])(regmatch_T *, int, qffields_T *) = {
/// fmt_ptr contains the 'efm' format specifiers/prefixes that have a match.
/// Returns QF_OK if all the matches are successfully parsed. On failure,
/// returns QF_FAIL or QF_NOMEM.
-static int qf_parse_match(char_u *linebuf, size_t linelen, efm_T *fmt_ptr,
- regmatch_T *regmatch, qffields_T *fields,
- int qf_multiline, int qf_multiscan, char_u **tail)
+static int qf_parse_match(char_u *linebuf, size_t linelen, efm_T *fmt_ptr, regmatch_T *regmatch,
+ qffields_T *fields, int qf_multiline, int qf_multiscan, char_u **tail)
{
char_u idx = fmt_ptr->prefix;
int i;
@@ -1542,9 +1518,8 @@ static int qf_parse_match(char_u *linebuf, size_t linelen, efm_T *fmt_ptr,
/// 'fmt_ptr->prog' and return the matching values in 'fields'.
/// Returns QF_OK if the efm format matches completely and the fields are
/// successfully copied. Otherwise returns QF_FAIL or QF_NOMEM.
-static int qf_parse_get_fields(char_u *linebuf, size_t linelen, efm_T *fmt_ptr,
- qffields_T *fields, int qf_multiline,
- int qf_multiscan, char_u **tail)
+static int qf_parse_get_fields(char_u *linebuf, size_t linelen, efm_T *fmt_ptr, qffields_T *fields,
+ int qf_multiline, int qf_multiscan, char_u **tail)
{
regmatch_T regmatch;
int status = QF_FAIL;
@@ -1561,7 +1536,9 @@ static int qf_parse_get_fields(char_u *linebuf, size_t linelen, efm_T *fmt_ptr,
fields->errmsg[0] = NUL;
}
fields->lnum = 0;
+ fields->end_lnum = 0;
fields->col = 0;
+ fields->end_col = 0;
fields->use_viscol = false;
fields->enr = -1;
fields->type = 0;
@@ -1602,8 +1579,7 @@ static int qf_parse_dir_pfx(int idx, qffields_T *fields, qf_list_T *qfl)
}
/// Parse global file name error format prefixes (%O, %P and %Q).
-static int qf_parse_file_pfx(int idx, qffields_T *fields, qf_list_T *qfl,
- char_u *tail)
+static int qf_parse_file_pfx(int idx, qffields_T *fields, qf_list_T *qfl, char_u *tail)
{
fields->valid = false;
if (*fields->namebuf == NUL || os_path_exists(fields->namebuf)) {
@@ -1626,8 +1602,7 @@ static int qf_parse_file_pfx(int idx, qffields_T *fields, qf_list_T *qfl,
/// Parse a non-error line (a line which doesn't match any of the error
/// format in 'efm').
-static int qf_parse_line_nomatch(char_u *linebuf, size_t linelen,
- qffields_T *fields)
+static int qf_parse_line_nomatch(char_u *linebuf, size_t linelen, qffields_T *fields)
{
fields->namebuf[0] = NUL; // no match found, remove file name
fields->lnum = 0; // don't jump to this line
@@ -1705,11 +1680,12 @@ static void locstack_queue_delreq(qf_info_T *qi)
static void ll_free_all(qf_info_T **pqi)
{
int i;
- qf_info_T *qi;
+ qf_info_T *qi;
qi = *pqi;
- if (qi == NULL)
+ if (qi == NULL) {
return;
+ }
*pqi = NULL; // Remove reference to this list
qi->qf_refcount--;
@@ -1732,7 +1708,7 @@ static void ll_free_all(qf_info_T **pqi)
void qf_free_all(win_T *wp)
{
int i;
- qf_info_T *qi = &ql_info;
+ qf_info_T *qi = &ql_info;
if (wp != NULL) {
// location list
@@ -1752,7 +1728,7 @@ void qf_free_all(win_T *wp)
/// Must always call decr_quickfix_busy() exactly once after this.
static void incr_quickfix_busy(void)
{
- quickfix_busy++;
+ quickfix_busy++;
}
/// Safe to free location list stacks. Process any delayed delete requests.
@@ -1799,7 +1775,9 @@ void check_quickfix_busy(void)
/// @param bufnum buffer number or zero
/// @param mesg message
/// @param lnum line number
+/// @param end_lnum line number for end
/// @param col column
+/// @param end_col column for end
/// @param vis_col using visual column
/// @param pattern search pattern
/// @param nr error number
@@ -1807,10 +1785,9 @@ void check_quickfix_busy(void)
/// @param valid valid entry
///
/// @returns QF_OK or QF_FAIL.
-static int qf_add_entry(qf_list_T *qfl, char_u *dir, char_u *fname,
- char_u *module, int bufnum, char_u *mesg, long lnum,
- int col, char_u vis_col, char_u *pattern, int nr,
- char_u type, char_u valid)
+static int qf_add_entry(qf_list_T *qfl, char_u *dir, char_u *fname, char_u *module, int bufnum,
+ char_u *mesg, long lnum, long end_lnum, int col, int end_col,
+ char_u vis_col, char_u *pattern, int nr, char_u type, char_u valid)
{
qfline_T *qfp = xmalloc(sizeof(qfline_T));
qfline_T **lastp; // pointer to qf_last or NULL
@@ -1828,7 +1805,9 @@ static int qf_add_entry(qf_list_T *qfl, char_u *dir, char_u *fname,
}
qfp->qf_text = vim_strsave(mesg);
qfp->qf_lnum = lnum;
+ qfp->qf_end_lnum = end_lnum;
qfp->qf_col = col;
+ qfp->qf_end_col = end_col;
qfp->qf_viscol = vis_col;
if (pattern == NULL || *pattern == NUL) {
qfp->qf_pattern = NULL;
@@ -1907,7 +1886,7 @@ static qf_info_T *ll_get_or_alloc_list(win_T *wp)
/// For a location list command, returns the stack for the current window. If
/// the location list is not found, then returns NULL and prints an error
/// message if 'print_emsg' is TRUE.
-static qf_info_T * qf_cmd_get_stack(exarg_T *eap, int print_emsg)
+static qf_info_T *qf_cmd_get_stack(exarg_T *eap, int print_emsg)
{
qf_info_T *qi = &ql_info;
@@ -1957,7 +1936,9 @@ static int copy_loclist_entries(const qf_list_T *from_qfl, qf_list_T *to_qfl)
0,
from_qfp->qf_text,
from_qfp->qf_lnum,
+ from_qfp->qf_end_lnum,
from_qfp->qf_col,
+ from_qfp->qf_end_col,
from_qfp->qf_viscol,
from_qfp->qf_pattern,
from_qfp->qf_nr,
@@ -2124,10 +2105,9 @@ static int qf_get_fnum(qf_list_T *qfl, char_u *directory, char_u *fname )
// Push dirbuf onto the directory stack and return pointer to actual dir or
// NULL on error.
-static char_u *qf_push_dir(char_u *dirbuf, struct dir_stack_T **stackptr,
- bool is_file_stack)
+static char_u *qf_push_dir(char_u *dirbuf, struct dir_stack_T **stackptr, bool is_file_stack)
{
- struct dir_stack_T *ds_ptr;
+ struct dir_stack_T *ds_ptr;
// allocate new stack element and hook it in
struct dir_stack_T *ds_new = xmalloc(sizeof(struct dir_stack_T));
@@ -2149,9 +2129,10 @@ static char_u *qf_push_dir(char_u *dirbuf, struct dir_stack_T **stackptr,
while (ds_new) {
xfree((*stackptr)->dirname);
(*stackptr)->dirname = (char_u *)concat_fnames((char *)ds_new->dirname,
- (char *)dirbuf, TRUE);
- if (os_isdir((*stackptr)->dirname))
+ (char *)dirbuf, TRUE);
+ if (os_isdir((*stackptr)->dirname)) {
break;
+ }
ds_new = ds_new->next;
}
@@ -2171,9 +2152,9 @@ static char_u *qf_push_dir(char_u *dirbuf, struct dir_stack_T **stackptr,
}
}
- if ((*stackptr)->dirname != NULL)
+ if ((*stackptr)->dirname != NULL) {
return (*stackptr)->dirname;
- else {
+ } else {
ds_ptr = *stackptr;
*stackptr = (*stackptr)->next;
xfree(ds_ptr);
@@ -2186,7 +2167,7 @@ static char_u *qf_push_dir(char_u *dirbuf, struct dir_stack_T **stackptr,
// stack is empty
static char_u *qf_pop_dir(struct dir_stack_T **stackptr)
{
- struct dir_stack_T *ds_ptr;
+ struct dir_stack_T *ds_ptr;
// TODO(vim): Should we check if dirbuf is the directory on top of the stack?
// What to do if it isn't?
@@ -2206,7 +2187,7 @@ static char_u *qf_pop_dir(struct dir_stack_T **stackptr)
// clean up directory stack
static void qf_clean_dir_stack(struct dir_stack_T **stackptr)
{
- struct dir_stack_T *ds_ptr;
+ struct dir_stack_T *ds_ptr;
while ((ds_ptr = *stackptr) != NULL) {
*stackptr = (*stackptr)->next;
@@ -2235,9 +2216,9 @@ static void qf_clean_dir_stack(struct dir_stack_T **stackptr)
/// qf_guess_filepath will return NULL.
static char_u *qf_guess_filepath(qf_list_T *qfl, char_u *filename)
{
- struct dir_stack_T *ds_ptr;
- struct dir_stack_T *ds_tmp;
- char_u *fullname;
+ struct dir_stack_T *ds_ptr;
+ struct dir_stack_T *ds_tmp;
+ char_u *fullname;
// no dirs on the stack - there's nothing we can do
if (qfl->qf_dir_stack == NULL) {
@@ -2316,8 +2297,7 @@ static bool is_qf_entry_present(qf_list_T *qfl, qfline_T *qf_ptr)
/// Get the next valid entry in the current quickfix/location list. The search
/// starts from the current entry. Returns NULL on failure.
-static qfline_T *get_next_valid_entry(qf_list_T *qfl, qfline_T *qf_ptr,
- int *qf_index, int dir)
+static qfline_T *get_next_valid_entry(qf_list_T *qfl, qfline_T *qf_ptr, int *qf_index, int dir)
{
int idx = *qf_index;
int old_qf_fnum = qf_ptr->qf_fnum;
@@ -2337,8 +2317,7 @@ static qfline_T *get_next_valid_entry(qf_list_T *qfl, qfline_T *qf_ptr,
/// Get the previous valid entry in the current quickfix/location list. The
/// search starts from the current entry. Returns NULL on failure.
-static qfline_T *get_prev_valid_entry(qf_list_T *qfl, qfline_T *qf_ptr,
- int *qf_index, int dir)
+static qfline_T *get_prev_valid_entry(qf_list_T *qfl, qfline_T *qf_ptr, int *qf_index, int dir)
{
int idx = *qf_index;
int old_qf_fnum = qf_ptr->qf_fnum;
@@ -2360,8 +2339,7 @@ static qfline_T *get_prev_valid_entry(qf_list_T *qfl, qfline_T *qf_ptr,
/// the quickfix list.
/// dir == FORWARD or FORWARD_FILE: next valid entry
/// dir == BACKWARD or BACKWARD_FILE: previous valid entry
-static qfline_T *get_nth_valid_entry(qf_list_T *qfl, int errornr,
- int dir, int *new_qfidx)
+static qfline_T *get_nth_valid_entry(qf_list_T *qfl, int errornr, int dir, int *new_qfidx)
{
qfline_T *qf_ptr = qfl->qf_ptr;
int qf_idx = qfl->qf_index;
@@ -2421,25 +2399,24 @@ static qfline_T *get_nth_entry(qf_list_T *qfl, int errornr, int *new_qfidx)
return qf_ptr;
}
-/// Get a entry specied by 'errornr' and 'dir' from the current
+/// Get a entry specified by 'errornr' and 'dir' from the current
/// quickfix/location list. 'errornr' specifies the index of the entry and 'dir'
/// specifies the direction (FORWARD/BACKWARD/FORWARD_FILE/BACKWARD_FILE).
/// Returns a pointer to the entry and the index of the new entry is stored in
/// 'new_qfidx'.
-static qfline_T * qf_get_entry(qf_list_T *qfl, int errornr,
- int dir, int *new_qfidx)
+static qfline_T *qf_get_entry(qf_list_T *qfl, int errornr, int dir, int *new_qfidx)
{
- qfline_T *qf_ptr = qfl->qf_ptr;
- int qfidx = qfl->qf_index;
+ qfline_T *qf_ptr = qfl->qf_ptr;
+ int qfidx = qfl->qf_index;
- if (dir != 0) { // next/prev valid entry
- qf_ptr = get_nth_valid_entry(qfl, errornr, dir, &qfidx);
- } else if (errornr != 0) { // go to specified number
- qf_ptr = get_nth_entry(qfl, errornr, &qfidx);
- }
+ if (dir != 0) { // next/prev valid entry
+ qf_ptr = get_nth_valid_entry(qfl, errornr, dir, &qfidx);
+ } else if (errornr != 0) { // go to specified number
+ qf_ptr = get_nth_entry(qfl, errornr, &qfidx);
+ }
- *new_qfidx = qfidx;
- return qf_ptr;
+ *new_qfidx = qfidx;
+ return qf_ptr;
}
// Find a window displaying a Vim help file.
@@ -2580,8 +2557,7 @@ static int qf_open_new_file_win(qf_info_T *ll_ref)
// to the window just above the location list window. This is used for opening
// a file from a location window and not from a quickfix window. If some usable
// window is previously found, then it is supplied in 'use_win'.
-static void qf_goto_win_with_ll_file(win_T *use_win, int qf_fnum,
- qf_info_T *ll_ref)
+static void qf_goto_win_with_ll_file(win_T *use_win, int qf_fnum, qf_info_T *ll_ref)
{
win_T *win = use_win;
@@ -2668,8 +2644,7 @@ static void qf_goto_win_with_qfl_file(int qf_fnum)
// window, jump to it. Otherwise open a new window to display the file. If
// 'newwin' is true, then always open a new window. This is called from either
// a quickfix or a location list window.
-static int qf_jump_to_usable_window(int qf_fnum, bool newwin,
- int *opened_window)
+static int qf_jump_to_usable_window(int qf_fnum, bool newwin, int *opened_window)
{
win_T *usable_wp = NULL;
bool usable_win = false;
@@ -2719,8 +2694,8 @@ static int qf_jump_to_usable_window(int qf_fnum, bool newwin,
}
/// Edit the selected file or help file.
-static int qf_jump_edit_buffer(qf_info_T *qi, qfline_T *qf_ptr, int forceit,
- win_T *oldwin, int *opened_window)
+static int qf_jump_edit_buffer(qf_info_T *qi, qfline_T *qf_ptr, int forceit, win_T *oldwin,
+ int *opened_window)
{
qf_list_T *qfl = qf_get_curlist(qi);
long old_changetick = qfl->qf_changedtick;
@@ -2773,8 +2748,7 @@ static int qf_jump_edit_buffer(qf_info_T *qi, qfline_T *qf_ptr, int forceit,
/// Go to the error line in the current file using either line/column number or
/// a search pattern.
-static void qf_jump_goto_line(linenr_T qf_lnum, int qf_col, char_u qf_viscol,
- char_u *qf_pattern)
+static void qf_jump_goto_line(linenr_T qf_lnum, int qf_col, char_u qf_viscol, char_u *qf_pattern)
{
linenr_T i;
@@ -2810,8 +2784,8 @@ static void qf_jump_goto_line(linenr_T qf_lnum, int qf_col, char_u qf_viscol,
}
/// Display quickfix list index and size message
-static void qf_jump_print_msg(qf_info_T *qi, int qf_index, qfline_T *qf_ptr,
- buf_T *old_curbuf, linenr_T old_lnum)
+static void qf_jump_print_msg(qf_info_T *qi, int qf_index, qfline_T *qf_ptr, buf_T *old_curbuf,
+ linenr_T old_lnum)
{
// Update the screen before showing the message, unless the screen
// scrolled up.
@@ -2846,15 +2820,14 @@ static void qf_jump_print_msg(qf_info_T *qi, int qf_index, qfline_T *qf_ptr,
/// Returns OK if successfully jumped or opened a window. Returns FAIL if not
/// able to jump/open a window. Returns NOTDONE if a file is not associated
/// with the entry.
-static int qf_jump_open_window(qf_info_T *qi, qfline_T *qf_ptr, bool newwin,
- int *opened_window)
+static int qf_jump_open_window(qf_info_T *qi, qfline_T *qf_ptr, bool newwin, int *opened_window)
{
qf_list_T *qfl = qf_get_curlist(qi);
long old_changetick = qfl->qf_changedtick;
int old_qf_curlist = qi->qf_curlist;
qfltype_T qfl_type = qfl->qfl_type;
- // For ":helpgrep" find a help window or open one.
+ // For ":helpgrep" find a help window or open one.
if (qf_ptr->qf_type == 1 && (!bt_help(curwin->w_buffer) || cmdmod.tab != 0)) {
if (jump_to_help_window(qi, newwin, opened_window) == FAIL) {
return FAIL;
@@ -2905,9 +2878,8 @@ static int qf_jump_open_window(qf_info_T *qi, qfline_T *qf_ptr, bool newwin,
/// Returns OK on success and FAIL on failing to open the file/buffer. Returns
/// NOTDONE if the quickfix/location list is freed by an autocmd when opening
/// the file.
-static int qf_jump_to_buffer(qf_info_T *qi, int qf_index, qfline_T *qf_ptr,
- int forceit, win_T *oldwin, int *opened_window,
- int openfold, int print_message)
+static int qf_jump_to_buffer(qf_info_T *qi, int qf_index, qfline_T *qf_ptr, int forceit,
+ win_T *oldwin, int *opened_window, int openfold, int print_message)
{
buf_T *old_curbuf;
linenr_T old_lnum;
@@ -2959,8 +2931,7 @@ void qf_jump(qf_info_T *qi, int dir, int errornr, int forceit)
// else if "errornr" is zero, redisplay the same line
// If 'forceit' is true, then can discard changes to the current buffer.
// If 'newwin' is true, then open the file in a new window.
-static void qf_jump_newwin(qf_info_T *qi, int dir, int errornr, int forceit,
- bool newwin)
+static void qf_jump_newwin(qf_info_T *qi, int dir, int errornr, int forceit, bool newwin)
{
qf_list_T *qfl;
qfline_T *qf_ptr;
@@ -2975,8 +2946,9 @@ static void qf_jump_newwin(qf_info_T *qi, int dir, int errornr, int forceit,
const bool old_KeyTyped = KeyTyped; // getting file may reset it
int retval = OK;
- if (qi == NULL)
+ if (qi == NULL) {
qi = &ql_info;
+ }
if (qf_stack_empty(qi) || qf_list_empty(qf_get_curlist(qi))) {
EMSG(_(e_quickfix));
@@ -2998,6 +2970,7 @@ static void qf_jump_newwin(qf_info_T *qi, int dir, int errornr, int forceit,
}
qfl->qf_index = qf_index;
+ qfl->qf_ptr = qf_ptr;
if (qf_win_pos_update(qi, old_qf_index)) {
// No need to print the error message if it's visible in the error
// window
@@ -3025,8 +2998,8 @@ static void qf_jump_newwin(qf_info_T *qi, int dir, int errornr, int forceit,
win_close(curwin, true); // Close opened window
}
if (qf_ptr != NULL && qf_ptr->qf_fnum != 0) {
- // Couldn't open file, so put index back where it was. This could
- // happen if the file was readonly and we changed something.
+ // Couldn't open file, so put index back where it was. This could
+ // happen if the file was readonly and we changed something.
failed:
qf_ptr = old_qf_ptr;
qf_index = old_qf_index;
@@ -3108,11 +3081,8 @@ static void qf_list_entry(qfline_T *qfp, int qf_idx, bool cursel)
}
if (qfp->qf_lnum == 0) {
IObuff[0] = NUL;
- } else if (qfp->qf_col == 0) {
- vim_snprintf((char *)IObuff, IOSIZE, "%" PRIdLINENR, qfp->qf_lnum);
} else {
- vim_snprintf((char *)IObuff, IOSIZE, "%" PRIdLINENR " col %d",
- qfp->qf_lnum, qfp->qf_col);
+ qf_range_text(qfp, IObuff, IOSIZE);
}
vim_snprintf((char *)IObuff + STRLEN(IObuff), IOSIZE, "%s",
(char *)qf_types(qfp->qf_type, qfp->qf_nr));
@@ -3144,9 +3114,9 @@ void qf_list(exarg_T *eap)
int i;
int idx1 = 1;
int idx2 = -1;
- char_u *arg = eap->arg;
- int all = eap->forceit; // if not :cl!, only show
- // recognised errors
+ char_u *arg = eap->arg;
+ int all = eap->forceit; // if not :cl!, only show
+ // recognised errors
qf_info_T *qi;
if ((qi = qf_cmd_get_stack(eap, true)) == NULL) {
@@ -3189,15 +3159,15 @@ void qf_list(exarg_T *eap)
// that this depends on syntax items defined in the qf.vim syntax file
qfFileAttr = syn_name2attr((char_u *)"qfFileName");
if (qfFileAttr == 0) {
- qfFileAttr = HL_ATTR(HLF_D);
+ qfFileAttr = HL_ATTR(HLF_D);
}
qfSepAttr = syn_name2attr((char_u *)"qfSeparator");
if (qfSepAttr == 0) {
- qfSepAttr = HL_ATTR(HLF_D);
+ qfSepAttr = HL_ATTR(HLF_D);
}
qfLineAttr = syn_name2attr((char_u *)"qfLineNr");
if (qfLineAttr == 0) {
- qfLineAttr = HL_ATTR(HLF_N);
+ qfLineAttr = HL_ATTR(HLF_N);
}
if (qfl->qf_nonevalid) {
@@ -3213,8 +3183,7 @@ void qf_list(exarg_T *eap)
// Remove newlines and leading whitespace from an error message.
// Put the result in "buf[bufsize]".
-static void qf_fmt_text(const char_u *restrict text, char_u *restrict buf,
- int bufsize)
+static void qf_fmt_text(const char_u *restrict text, char_u *restrict buf, int bufsize)
FUNC_ATTR_NONNULL_ALL
{
int i;
@@ -3223,15 +3192,44 @@ static void qf_fmt_text(const char_u *restrict text, char_u *restrict buf,
for (i = 0; *p != NUL && i < bufsize - 1; ++i) {
if (*p == '\n') {
buf[i] = ' ';
- while (*++p != NUL)
- if (!ascii_iswhite(*p) && *p != '\n')
+ while (*++p != NUL) {
+ if (!ascii_iswhite(*p) && *p != '\n') {
break;
- } else
+ }
+ }
+ } else {
buf[i] = *p++;
+ }
}
buf[i] = NUL;
}
+// Range information from lnum, col, end_lnum, and end_col.
+// Put the result in "buf[bufsize]".
+static void qf_range_text(const qfline_T *qfp, char_u *buf, int bufsize)
+{
+ vim_snprintf((char *)buf, (size_t)bufsize, "%" PRIdLINENR, qfp->qf_lnum);
+ int len = (int)STRLEN(buf);
+
+ if (qfp->qf_end_lnum > 0 && qfp->qf_lnum != qfp->qf_end_lnum) {
+ vim_snprintf((char *)buf + len, (size_t)(bufsize - len),
+ "-%" PRIdLINENR, qfp->qf_end_lnum);
+ len += (int)STRLEN(buf + len);
+ }
+ if (qfp->qf_col > 0) {
+ vim_snprintf((char *)buf + len, (size_t)(bufsize - len),
+ " col %d", qfp->qf_col);
+ len += (int)STRLEN(buf + len);
+ if (qfp->qf_end_col > 0 && qfp->qf_col != qfp->qf_end_col) {
+ vim_snprintf((char *)buf + len, (size_t)(bufsize - len),
+ "-%d", qfp->qf_end_col);
+ len += (int)STRLEN(buf + len);
+ }
+ }
+ buf[len] = NUL;
+}
+
+
/// Display information (list number, list size and the title) about a
/// quickfix/location list.
static void qf_msg(qf_info_T *qi, int which, char *lead)
@@ -3250,8 +3248,8 @@ static void qf_msg(qf_info_T *qi, int which, char *lead)
size_t len = STRLEN(buf);
if (len < 34) {
- memset(buf + len, ' ', 34 - len);
- buf[34] = NUL;
+ memset(buf + len, ' ', 34 - len);
+ buf[34] = NUL;
}
xstrlcat((char *)buf, title, IOSIZE);
}
@@ -3334,8 +3332,8 @@ void qf_history(exarg_T *eap)
/// associated with the list like context and title are not freed.
static void qf_free_items(qf_list_T *qfl)
{
- qfline_T *qfp;
- qfline_T *qfpnext;
+ qfline_T *qfp;
+ qfline_T *qfpnext;
bool stop = false;
while (qfl->qf_count && qfl->qf_start != NULL) {
@@ -3390,13 +3388,12 @@ static void qf_free(qf_list_T *qfl)
}
// qf_mark_adjust: adjust marks
-bool qf_mark_adjust(win_T *wp, linenr_T line1, linenr_T line2, long amount,
- long amount_after)
+bool qf_mark_adjust(win_T *wp, linenr_T line1, linenr_T line2, long amount, long amount_after)
{
int i;
- qfline_T *qfp;
+ qfline_T *qfp;
int idx;
- qf_info_T *qi = &ql_info;
+ qf_info_T *qi = &ql_info;
bool found_one = false;
int buf_has_flag = wp == NULL ? BUF_HAS_QF_ENTRY : BUF_HAS_LL_ENTRY;
@@ -3417,12 +3414,14 @@ bool qf_mark_adjust(win_T *wp, linenr_T line1, linenr_T line2, long amount,
if (qfp->qf_fnum == curbuf->b_fnum) {
found_one = true;
if (qfp->qf_lnum >= line1 && qfp->qf_lnum <= line2) {
- if (amount == MAXLNUM)
+ if (amount == MAXLNUM) {
qfp->qf_cleared = TRUE;
- else
+ } else {
qfp->qf_lnum += amount;
- } else if (amount_after && qfp->qf_lnum > line2)
+ }
+ } else if (amount_after && qfp->qf_lnum > line2) {
qfp->qf_lnum += amount_after;
+ }
}
}
}
@@ -3450,7 +3449,7 @@ static char_u *qf_types(int c, int nr)
{
static char_u buf[20];
static char_u cc[3];
- char_u *p;
+ char_u *p;
if (c == 'W' || c == 'w') {
p = (char_u *)" warning";
@@ -3469,8 +3468,9 @@ static char_u *qf_types(int c, int nr)
p = cc;
}
- if (nr <= 0)
+ if (nr <= 0) {
return p;
+ }
sprintf((char *)buf, "%s %3d", (char *)p, nr);
return buf;
@@ -3480,7 +3480,7 @@ static char_u *qf_types(int c, int nr)
// When "split" is true: Open the entry/result under the cursor in a new window.
void qf_view_result(bool split)
{
- qf_info_T *qi = &ql_info;
+ qf_info_T *qi = &ql_info;
if (!bt_quickfix(curbuf)) {
return;
@@ -3509,9 +3509,9 @@ void qf_view_result(bool split)
// close it if not.
void ex_cwindow(exarg_T *eap)
{
- qf_info_T *qi;
- qf_list_T *qfl;
- win_T *win;
+ qf_info_T *qi;
+ qf_list_T *qfl;
+ win_T *win;
if ((qi = qf_cmd_get_stack(eap, true)) == NULL) {
return;
@@ -3556,8 +3556,7 @@ void ex_cclose(exarg_T *eap)
// Goto a quickfix or location list window (if present).
// Returns OK if the window is found, FAIL otherwise.
-static int qf_goto_cwindow(const qf_info_T *qi, bool resize, int sz,
- bool vertsplit)
+static int qf_goto_cwindow(const qf_info_T *qi, bool resize, int sz, bool vertsplit)
{
win_T *const win = qf_find_win(qi);
if (win == NULL) {
@@ -3685,8 +3684,8 @@ static void qf_set_title_var(qf_list_T *qfl)
/// ":lopen": open a window that shows the location list.
void ex_copen(exarg_T *eap)
{
- qf_info_T *qi;
- qf_list_T *qfl;
+ qf_info_T *qi;
+ qf_list_T *qfl;
int height;
int status = FAIL;
int lnum;
@@ -3772,7 +3771,7 @@ void ex_cbottom(exarg_T *eap)
// window).
linenr_T qf_current_entry(win_T *wp)
{
- qf_info_T *qi = &ql_info;
+ qf_info_T *qi = &ql_info;
if (IS_LL_WINDOW(wp)) {
// In the location list window, use the referenced location list
@@ -3782,14 +3781,13 @@ linenr_T qf_current_entry(win_T *wp)
return qf_get_curlist(qi)->qf_index;
}
-// Update the cursor position in the quickfix window to the current error.
-// Return TRUE if there is a quickfix window.
-static int qf_win_pos_update(
- qf_info_T *qi,
- int old_qf_index // previous qf_index or zero
-)
+/// Update the cursor position in the quickfix window to the current error.
+/// Return TRUE if there is a quickfix window.
+///
+/// @param old_qf_index previous qf_index or zero
+static int qf_win_pos_update(qf_info_T *qi, int old_qf_index)
{
- win_T *win;
+ win_T *win;
int qf_index = qf_get_curlist(qi)->qf_index;
// Put the cursor on the current error in the quickfix window, so that
@@ -3914,8 +3912,8 @@ static void qf_update_win_titlevar(qf_info_T *qi)
// Find the quickfix buffer. If it exists, update the contents.
static void qf_update_buffer(qf_info_T *qi, qfline_T *old_last)
{
- buf_T *buf;
- win_T *win;
+ buf_T *buf;
+ win_T *win;
aco_save_T aco;
// Check if a buffer for the quickfix list exists. Update it.
@@ -3962,9 +3960,8 @@ static void qf_update_buffer(qf_info_T *qi, qfline_T *old_last)
}
// Add an error line to the quickfix buffer.
-static int qf_buf_add_line(qf_list_T *qfl, buf_T *buf, linenr_T lnum,
- const qfline_T *qfp, char_u *dirname,
- char_u *qftf_str, bool first_bufline)
+static int qf_buf_add_line(qf_list_T *qfl, buf_T *buf, linenr_T lnum, const qfline_T *qfp,
+ char_u *dirname, char_u *qftf_str, bool first_bufline)
FUNC_ATTR_NONNULL_ARG(1, 2, 4, 5)
{
int len;
@@ -4005,16 +4002,9 @@ static int qf_buf_add_line(qf_list_T *qfl, buf_T *buf, linenr_T lnum,
IObuff[len++] = '|';
}
if (qfp->qf_lnum > 0) {
- snprintf((char *)IObuff + len, (size_t)(IOSIZE - len), "%" PRId64,
- (int64_t)qfp->qf_lnum);
+ qf_range_text(qfp, IObuff + len, IOSIZE - len);
len += (int)STRLEN(IObuff + len);
- if (qfp->qf_col > 0) {
- snprintf((char *)IObuff + len, (size_t)(IOSIZE - len), " col %d",
- qfp->qf_col);
- len += (int)STRLEN(IObuff + len);
- }
-
snprintf((char *)IObuff + len, (size_t)(IOSIZE - len), "%s",
(char *)qf_types(qfp->qf_type, qfp->qf_nr));
len += (int)STRLEN(IObuff + len);
@@ -4043,10 +4033,7 @@ static int qf_buf_add_line(qf_list_T *qfl, buf_T *buf, linenr_T lnum,
// Call the 'quickfixtextfunc' function to get the list of lines to display in
// the quickfix window for the entries 'start_idx' to 'end_idx'.
-static list_T *call_qftf_func(qf_list_T *qfl,
- int qf_winid,
- long start_idx,
- long end_idx)
+static list_T *call_qftf_func(qf_list_T *qfl, int qf_winid, long start_idx, long end_idx)
{
Callback *cb = &qftf_cb;
list_T *qftf_list = NULL;
@@ -4093,12 +4080,11 @@ static list_T *call_qftf_func(qf_list_T *qfl,
/// If "old_last" is not NULL append the items after this one.
/// When "old_last" is NULL then "buf" must equal "curbuf"! Because ml_delete()
/// is used and autocommands will be triggered.
-static void qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last,
- int qf_winid)
+static void qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last, int qf_winid)
FUNC_ATTR_NONNULL_ARG(2)
{
linenr_T lnum;
- qfline_T *qfp;
+ qfline_T *qfp;
const bool old_KeyTyped = KeyTyped;
list_T *qftf_list = NULL;
listitem_T *qftf_li = NULL;
@@ -4117,11 +4103,11 @@ static void qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last,
// Check if there is anything to display
if (qfl != NULL) {
- char_u dirname[MAXPATHL];
- int prev_bufnr = -1;
- bool invalid_val = false;
+ char_u dirname[MAXPATHL];
+ int prev_bufnr = -1;
+ bool invalid_val = false;
- *dirname = NUL;
+ *dirname = NUL;
// Add one line for each error
if (old_last == NULL) {
@@ -4180,7 +4166,7 @@ static void qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last,
// Set the 'filetype' to "qf" each time after filling the buffer. This
// resembles reading a file into a buffer, it's more logical when using
// autocommands.
- curbuf_lock++;
+ curbuf->b_ro_locked++;
set_option_value("ft", 0L, "qf", OPT_LOCAL);
curbuf->b_p_ma = false;
@@ -4190,7 +4176,7 @@ static void qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last,
apply_autocmds(EVENT_BUFWINENTER, (char_u *)"quickfix", NULL,
false, curbuf);
keep_filetype = false;
- curbuf_lock--;
+ curbuf->b_ro_locked--;
// make sure it will be redrawn
redraw_curbuf_later(NOT_VALID);
@@ -4202,7 +4188,7 @@ static void qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last,
static void qf_list_changed(qf_list_T *qfl)
{
- qfl->qf_changedtick++;
+ qfl->qf_changedtick++;
}
/// Return the quickfix/location list number with the given identifier.
@@ -4258,7 +4244,7 @@ int grep_internal(cmdidx_T cmdidx)
|| cmdidx == CMD_grepadd
|| cmdidx == CMD_lgrepadd)
&& STRCMP("internal",
- *curbuf->b_p_gp == NUL ? p_gp : curbuf->b_p_gp) == 0;
+ *curbuf->b_p_gp == NUL ? p_gp : curbuf->b_p_gp) == 0;
}
// Return the make/grep autocmd name.
@@ -4266,20 +4252,20 @@ static char_u *make_get_auname(cmdidx_T cmdidx)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
switch (cmdidx) {
- case CMD_make:
- return (char_u *)"make";
- case CMD_lmake:
- return (char_u *)"lmake";
- case CMD_grep:
- return (char_u *)"grep";
- case CMD_lgrep:
- return (char_u *)"lgrep";
- case CMD_grepadd:
- return (char_u *)"grepadd";
- case CMD_lgrepadd:
- return (char_u *)"lgrepadd";
- default:
- return NULL;
+ case CMD_make:
+ return (char_u *)"make";
+ case CMD_lmake:
+ return (char_u *)"lmake";
+ case CMD_grep:
+ return (char_u *)"grep";
+ case CMD_lgrep:
+ return (char_u *)"lgrep";
+ case CMD_grepadd:
+ return (char_u *)"grepadd";
+ case CMD_lgrepadd:
+ return (char_u *)"lgrepadd";
+ default:
+ return NULL;
}
}
@@ -4316,9 +4302,9 @@ static char *make_get_fullcmd(const char_u *makecmd, const char_u *fname)
// Used for ":make", ":lmake", ":grep", ":lgrep", ":grepadd", and ":lgrepadd"
void ex_make(exarg_T *eap)
{
- char_u *fname;
- win_T *wp = NULL;
- qf_info_T *qi = &ql_info;
+ char_u *fname;
+ win_T *wp = NULL;
+ qf_info_T *qi = &ql_info;
int res;
char_u *enc = (*curbuf->b_p_menc != NUL) ? curbuf->b_p_menc : p_menc;
@@ -4342,8 +4328,9 @@ void ex_make(exarg_T *eap)
autowrite_all();
fname = get_mef_name();
- if (fname == NULL)
+ if (fname == NULL) {
return;
+ }
os_remove((char *)fname); // in case it's not unique
char *const cmd = make_get_fullcmd(eap->arg, fname);
@@ -4389,24 +4376,28 @@ cleanup:
// Returns NULL for error.
static char_u *get_mef_name(void)
{
- char_u *p;
- char_u *name;
+ char_u *p;
+ char_u *name;
static int start = -1;
static int off = 0;
if (*p_mef == NUL) {
name = vim_tempname();
- if (name == NULL)
+ if (name == NULL) {
EMSG(_(e_notmp));
+ }
return name;
}
- for (p = p_mef; *p; ++p)
- if (p[0] == '#' && p[1] == '#')
+ for (p = p_mef; *p; ++p) {
+ if (p[0] == '#' && p[1] == '#') {
break;
+ }
+ }
- if (*p == NUL)
+ if (*p == NUL) {
return vim_strsave(p_mef);
+ }
// Keep trying until the name doesn't exist yet.
for (;; ) {
@@ -4580,7 +4571,7 @@ static size_t qf_get_nth_valid_entry(qf_list_T *qfl, size_t n, int fdo)
/// ":cdo", ":ldo", ":cfdo" and ":lfdo".
void ex_cc(exarg_T *eap)
{
- qf_info_T *qi;
+ qf_info_T *qi;
if ((qi = qf_cmd_get_stack(eap, true)) == NULL) {
return;
@@ -4591,19 +4582,19 @@ void ex_cc(exarg_T *eap)
errornr = (int)eap->line2;
} else {
switch (eap->cmdidx) {
- case CMD_cc:
- case CMD_ll:
- errornr = 0;
- break;
- case CMD_crewind:
- case CMD_lrewind:
- case CMD_cfirst:
- case CMD_lfirst:
- errornr = 1;
- break;
- default:
- errornr = 32767;
- break;
+ case CMD_cc:
+ case CMD_ll:
+ errornr = 0;
+ break;
+ case CMD_crewind:
+ case CMD_lrewind:
+ case CMD_cfirst:
+ case CMD_lfirst:
+ errornr = 1;
+ break;
+ default:
+ errornr = 32767;
+ break;
}
}
@@ -4618,9 +4609,8 @@ void ex_cc(exarg_T *eap)
} else {
n = 1;
}
- size_t valid_entry = qf_get_nth_valid_entry(
- qf_get_curlist(qi), n,
- eap->cmdidx == CMD_cfdo || eap->cmdidx == CMD_lfdo);
+ size_t valid_entry = qf_get_nth_valid_entry(qf_get_curlist(qi), n,
+ eap->cmdidx == CMD_cfdo || eap->cmdidx == CMD_lfdo);
assert(valid_entry <= INT_MAX);
errornr = (int)valid_entry;
}
@@ -4633,7 +4623,7 @@ void ex_cc(exarg_T *eap)
/// ":cdo", ":ldo", ":cfdo" and ":lfdo".
void ex_cnext(exarg_T *eap)
{
- qf_info_T *qi;
+ qf_info_T *qi;
if ((qi = qf_cmd_get_stack(eap, true)) == NULL) {
return;
@@ -4651,31 +4641,31 @@ void ex_cnext(exarg_T *eap)
// Depending on the command jump to either next or previous entry/file.
Direction dir;
switch (eap->cmdidx) {
- case CMD_cprevious:
- case CMD_lprevious:
- case CMD_cNext:
- case CMD_lNext:
- dir = BACKWARD;
- break;
- case CMD_cnfile:
- case CMD_lnfile:
- case CMD_cfdo:
- case CMD_lfdo:
- dir = FORWARD_FILE;
- break;
- case CMD_cpfile:
- case CMD_lpfile:
- case CMD_cNfile:
- case CMD_lNfile:
- dir = BACKWARD_FILE;
- break;
- case CMD_cnext:
- case CMD_lnext:
- case CMD_cdo:
- case CMD_ldo:
- default:
- dir = FORWARD;
- break;
+ case CMD_cprevious:
+ case CMD_lprevious:
+ case CMD_cNext:
+ case CMD_lNext:
+ dir = BACKWARD;
+ break;
+ case CMD_cnfile:
+ case CMD_lnfile:
+ case CMD_cfdo:
+ case CMD_lfdo:
+ dir = FORWARD_FILE;
+ break;
+ case CMD_cpfile:
+ case CMD_lpfile:
+ case CMD_cNfile:
+ case CMD_lNfile:
+ dir = BACKWARD_FILE;
+ break;
+ case CMD_cnext:
+ case CMD_lnext:
+ case CMD_cdo:
+ case CMD_ldo:
+ default:
+ dir = FORWARD;
+ break;
}
qf_jump(qi, dir, errornr, eap->forceit);
@@ -4684,9 +4674,7 @@ void ex_cnext(exarg_T *eap)
/// Find the first entry in the quickfix list 'qfl' from buffer 'bnr'.
/// The index of the entry is stored in 'errornr'.
/// Returns NULL if an entry is not found.
-static qfline_T *qf_find_first_entry_in_buf(qf_list_T *qfl,
- int bnr,
- int *errornr)
+static qfline_T *qf_find_first_entry_in_buf(qf_list_T *qfl, int bnr, int *errornr)
{
qfline_T *qfp = NULL;
int idx = 0;
@@ -4705,7 +4693,7 @@ static qfline_T *qf_find_first_entry_in_buf(qf_list_T *qfl,
/// Find the first quickfix entry on the same line as 'entry'. Updates 'errornr'
/// with the error number for the first entry. Assumes the entries are sorted in
/// the quickfix list by line number.
-static qfline_T * qf_find_first_entry_on_line(qfline_T *entry, int *errornr)
+static qfline_T *qf_find_first_entry_on_line(qfline_T *entry, int *errornr)
{
while (!got_int
&& entry->qf_prev != NULL
@@ -4721,7 +4709,7 @@ static qfline_T * qf_find_first_entry_on_line(qfline_T *entry, int *errornr)
/// Find the last quickfix entry on the same line as 'entry'. Updates 'errornr'
/// with the error number for the last entry. Assumes the entries are sorted in
/// the quickfix list by line number.
-static qfline_T * qf_find_last_entry_on_line(qfline_T *entry, int *errornr)
+static qfline_T *qf_find_last_entry_on_line(qfline_T *entry, int *errornr)
{
while (!got_int
&& entry->qf_next != NULL
@@ -4737,57 +4725,53 @@ static qfline_T * qf_find_last_entry_on_line(qfline_T *entry, int *errornr)
// Returns true if the specified quickfix entry is
// after the given line (linewise is true)
// or after the line and column.
-static bool qf_entry_after_pos(const qfline_T *qfp, const pos_T *pos,
- bool linewise)
+static bool qf_entry_after_pos(const qfline_T *qfp, const pos_T *pos, bool linewise)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
if (linewise) {
return qfp->qf_lnum > pos->lnum;
}
return qfp->qf_lnum > pos->lnum
- || (qfp->qf_lnum == pos->lnum && qfp->qf_col > pos->col);
+ || (qfp->qf_lnum == pos->lnum && qfp->qf_col > pos->col);
}
// Returns true if the specified quickfix entry is
// before the given line (linewise is true)
// or before the line and column.
-static bool qf_entry_before_pos(const qfline_T *qfp, const pos_T *pos,
- bool linewise)
+static bool qf_entry_before_pos(const qfline_T *qfp, const pos_T *pos, bool linewise)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
if (linewise) {
return qfp->qf_lnum < pos->lnum;
}
return qfp->qf_lnum < pos->lnum
- || (qfp->qf_lnum == pos->lnum && qfp->qf_col < pos->col);
+ || (qfp->qf_lnum == pos->lnum && qfp->qf_col < pos->col);
}
// Returns true if the specified quickfix entry is
// on or after the given line (linewise is true)
// or on or after the line and column.
-static bool qf_entry_on_or_after_pos(const qfline_T *qfp, const pos_T *pos,
- bool linewise)
+static bool qf_entry_on_or_after_pos(const qfline_T *qfp, const pos_T *pos, bool linewise)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
if (linewise) {
return qfp->qf_lnum >= pos->lnum;
}
return qfp->qf_lnum > pos->lnum
- || (qfp->qf_lnum == pos->lnum && qfp->qf_col >= pos->col);
+ || (qfp->qf_lnum == pos->lnum && qfp->qf_col >= pos->col);
}
// Returns true if the specified quickfix entry is
// on or before the given line (linewise is true)
// or on or before the line and column.
-static bool qf_entry_on_or_before_pos(const qfline_T *qfp, const pos_T *pos,
- bool linewise)
+static bool qf_entry_on_or_before_pos(const qfline_T *qfp, const pos_T *pos, bool linewise)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
if (linewise) {
return qfp->qf_lnum <= pos->lnum;
}
return qfp->qf_lnum < pos->lnum
- || (qfp->qf_lnum == pos->lnum && qfp->qf_col <= pos->col);
+ || (qfp->qf_lnum == pos->lnum && qfp->qf_col <= pos->col);
}
/// Find the first quickfix entry after position 'pos' in buffer 'bnr'.
@@ -4797,17 +4781,12 @@ static bool qf_entry_on_or_before_pos(const qfline_T *qfp, const pos_T *pos,
/// 'qfp' points to the very first entry in the buffer and 'errornr' is the
/// index of the very first entry in the quickfix list.
/// Returns NULL if an entry is not found after 'pos'.
-static qfline_T *qf_find_entry_after_pos(
- int bnr,
- const pos_T *pos,
- bool linewise,
- qfline_T *qfp,
- int *errornr
-)
+static qfline_T *qf_find_entry_after_pos(int bnr, const pos_T *pos, bool linewise, qfline_T *qfp,
+ int *errornr)
FUNC_ATTR_NONNULL_ALL
{
if (qf_entry_after_pos(qfp, pos, linewise)) {
- // First entry is after postion 'pos'
+ // First entry is after position 'pos'
return qfp;
}
@@ -4838,13 +4817,8 @@ static qfline_T *qf_find_entry_after_pos(
/// 'qfp' points to the very first entry in the buffer and 'errornr' is the
/// index of the very first entry in the quickfix list.
/// Returns NULL if an entry is not found before 'pos'.
-static qfline_T *qf_find_entry_before_pos(
- int bnr,
- const pos_T *pos,
- bool linewise,
- qfline_T *qfp,
- int *errornr
-)
+static qfline_T *qf_find_entry_before_pos(int bnr, const pos_T *pos, bool linewise, qfline_T *qfp,
+ int *errornr)
FUNC_ATTR_NONNULL_ALL
{
// Find the entry just before the position 'pos'
@@ -4869,14 +4843,8 @@ static qfline_T *qf_find_entry_before_pos(
/// Find a quickfix entry in 'qfl' closest to position 'pos' in buffer 'bnr' in
/// the direction 'dir'.
-static qfline_T *qf_find_closest_entry(
- qf_list_T *qfl,
- int bnr,
- const pos_T *pos,
- Direction dir,
- bool linewise,
- int *errornr
-)
+static qfline_T *qf_find_closest_entry(qf_list_T *qfl, int bnr, const pos_T *pos, Direction dir,
+ bool linewise, int *errornr)
FUNC_ATTR_NONNULL_ALL
{
qfline_T *qfp;
@@ -4901,8 +4869,7 @@ static qfline_T *qf_find_closest_entry(
/// Get the nth quickfix entry below the specified entry. Searches forward in
/// the list. If linewise is true, then treat multiple entries on a single line
/// as one.
-static void qf_get_nth_below_entry(qfline_T *entry, linenr_T n,
- bool linewise, int *errornr)
+static void qf_get_nth_below_entry(qfline_T *entry, linenr_T n, bool linewise, int *errornr)
FUNC_ATTR_NONNULL_ALL
{
while (n-- > 0 && !got_int) {
@@ -4933,8 +4900,7 @@ static void qf_get_nth_below_entry(qfline_T *entry, linenr_T n,
/// Get the nth quickfix entry above the specified entry. Searches backwards in
/// the list. If linewise is TRUE, then treat multiple entries on a single line
/// as one.
-static void qf_get_nth_above_entry(qfline_T *entry, linenr_T n,
- bool linewise, int *errornr)
+static void qf_get_nth_above_entry(qfline_T *entry, linenr_T n, bool linewise, int *errornr)
FUNC_ATTR_NONNULL_ALL
{
while (n-- > 0 && !got_int) {
@@ -4955,14 +4921,8 @@ static void qf_get_nth_above_entry(qfline_T *entry, linenr_T n,
/// Find the n'th quickfix entry adjacent to position 'pos' in buffer 'bnr' in
/// the specified direction. Returns the error number in the quickfix list or 0
/// if an entry is not found.
-static int qf_find_nth_adj_entry(
- qf_list_T *qfl,
- int bnr,
- pos_T *pos,
- linenr_T n,
- Direction dir,
- bool linewise
-)
+static int qf_find_nth_adj_entry(qf_list_T *qfl, int bnr, pos_T *pos, linenr_T n, Direction dir,
+ bool linewise)
FUNC_ATTR_NONNULL_ALL
{
int errornr;
@@ -5039,16 +4999,15 @@ void ex_cbelow(exarg_T *eap)
// A quickfix entry column number is 1 based whereas cursor column
// number is 0 based. Adjust the column number.
pos.col++;
- const int errornr = qf_find_nth_adj_entry(
- qfl,
- curbuf->b_fnum,
- &pos,
- eap->addr_count > 0 ? eap->line2 : 0,
- dir,
- eap->cmdidx == CMD_cbelow
- || eap->cmdidx == CMD_lbelow
- || eap->cmdidx == CMD_cabove
- || eap->cmdidx == CMD_labove);
+ const int errornr = qf_find_nth_adj_entry(qfl,
+ curbuf->b_fnum,
+ &pos,
+ eap->addr_count > 0 ? eap->line2 : 0,
+ dir,
+ eap->cmdidx == CMD_cbelow
+ || eap->cmdidx == CMD_lbelow
+ || eap->cmdidx == CMD_cabove
+ || eap->cmdidx == CMD_labove);
if (errornr > 0) {
qf_jump(qi, 0, errornr, false);
@@ -5059,16 +5018,23 @@ void ex_cbelow(exarg_T *eap)
/// Return the autocmd name for the :cfile Ex commands
-static char_u * cfile_get_auname(cmdidx_T cmdidx)
+static char_u *cfile_get_auname(cmdidx_T cmdidx)
{
switch (cmdidx) {
- case CMD_cfile: return (char_u *)"cfile";
- case CMD_cgetfile: return (char_u *)"cgetfile";
- case CMD_caddfile: return (char_u *)"caddfile";
- case CMD_lfile: return (char_u *)"lfile";
- case CMD_lgetfile: return (char_u *)"lgetfile";
- case CMD_laddfile: return (char_u *)"laddfile";
- default: return NULL;
+ case CMD_cfile:
+ return (char_u *)"cfile";
+ case CMD_cgetfile:
+ return (char_u *)"cgetfile";
+ case CMD_caddfile:
+ return (char_u *)"caddfile";
+ case CMD_lfile:
+ return (char_u *)"lfile";
+ case CMD_lgetfile:
+ return (char_u *)"lgetfile";
+ case CMD_laddfile:
+ return (char_u *)"laddfile";
+ default:
+ return NULL;
}
}
@@ -5077,9 +5043,9 @@ static char_u * cfile_get_auname(cmdidx_T cmdidx)
// ":lfile"/":lgetfile"/":laddfile" commands.
void ex_cfile(exarg_T *eap)
{
- win_T *wp = NULL;
- qf_info_T *qi = &ql_info;
- char_u *au_name = NULL;
+ win_T *wp = NULL;
+ qf_info_T *qi = &ql_info;
+ char_u *au_name = NULL;
au_name = cfile_get_auname(eap->cmdidx);
if (au_name != NULL
@@ -5140,15 +5106,24 @@ void ex_cfile(exarg_T *eap)
static char_u *vgr_get_auname(cmdidx_T cmdidx)
{
switch (cmdidx) {
- case CMD_vimgrep: return (char_u *)"vimgrep";
- case CMD_lvimgrep: return (char_u *)"lvimgrep";
- case CMD_vimgrepadd: return (char_u *)"vimgrepadd";
- case CMD_lvimgrepadd: return (char_u *)"lvimgrepadd";
- case CMD_grep: return (char_u *)"grep";
- case CMD_lgrep: return (char_u *)"lgrep";
- case CMD_grepadd: return (char_u *)"grepadd";
- case CMD_lgrepadd: return (char_u *)"lgrepadd";
- default: return NULL;
+ case CMD_vimgrep:
+ return (char_u *)"vimgrep";
+ case CMD_lvimgrep:
+ return (char_u *)"lvimgrep";
+ case CMD_vimgrepadd:
+ return (char_u *)"vimgrepadd";
+ case CMD_lvimgrepadd:
+ return (char_u *)"lvimgrepadd";
+ case CMD_grep:
+ return (char_u *)"grep";
+ case CMD_lgrep:
+ return (char_u *)"lgrep";
+ case CMD_grepadd:
+ return (char_u *)"grepadd";
+ case CMD_lgrepadd:
+ return (char_u *)"lgrepadd";
+ default:
+ return NULL;
}
}
@@ -5193,8 +5168,7 @@ static void vgr_display_fname(char_u *fname)
}
/// Load a dummy buffer to search for a pattern using vimgrep.
-static buf_T *vgr_load_dummy_buf(char_u *fname, char_u *dirname_start,
- char_u *dirname_now)
+static buf_T *vgr_load_dummy_buf(char_u *fname, char_u *dirname_start, char_u *dirname_now)
{
// Don't do Filetype autocommands to avoid loading syntax and
// indent scripts, a great speed improvement.
@@ -5216,8 +5190,7 @@ static buf_T *vgr_load_dummy_buf(char_u *fname, char_u *dirname_start,
/// Check whether a quickfix/location list is valid. Autocmds may remove or
/// change a quickfix list when vimgrep is running. If the list is not found,
/// create a new list.
-static bool vgr_qflist_valid(win_T *wp, qf_info_T *qi, unsigned qfid,
- char_u *title)
+static bool vgr_qflist_valid(win_T *wp, qf_info_T *qi, unsigned qfid, char_u *title)
{
// Verify that the quickfix/location list was not freed by an autocmd
if (!qflist_valid(wp, qfid)) {
@@ -5241,9 +5214,8 @@ static bool vgr_qflist_valid(win_T *wp, qf_info_T *qi, unsigned qfid,
/// Search for a pattern in all the lines in a buffer and add the matching lines
/// to a quickfix list.
-static bool vgr_match_buflines(qf_list_T *qfl, char_u *fname, buf_T *buf,
- regmmatch_T *regmatch, long *tomatch,
- int duplicate_name, int flags)
+static bool vgr_match_buflines(qf_list_T *qfl, char_u *fname, buf_T *buf, regmmatch_T *regmatch,
+ long *tomatch, int duplicate_name, int flags)
FUNC_ATTR_NONNULL_ARG(1, 3, 4, 5)
{
bool found_match = false;
@@ -5263,7 +5235,9 @@ static bool vgr_match_buflines(qf_list_T *qfl, char_u *fname, buf_T *buf,
ml_get_buf(buf, regmatch->startpos[0].lnum + lnum,
false),
regmatch->startpos[0].lnum + lnum,
+ regmatch->endpos[0].lnum + lnum,
regmatch->startpos[0].col + 1,
+ regmatch->endpos[0].col + 1,
false, // vis_col
NULL, // search pattern
0, // nr
@@ -5338,27 +5312,27 @@ void ex_vimgrep(exarg_T *eap)
{
regmmatch_T regmatch;
int fcount;
- char_u **fnames;
- char_u *fname;
- char_u *s;
- char_u *p;
+ char_u **fnames;
+ char_u *fname;
+ char_u *s;
+ char_u *p;
int fi;
- qf_list_T *qfl;
+ qf_list_T *qfl;
win_T *wp = NULL;
- buf_T *buf;
+ buf_T *buf;
int duplicate_name = FALSE;
int using_dummy;
int redraw_for_dummy = FALSE;
int found_match;
- buf_T *first_match_buf = NULL;
+ buf_T *first_match_buf = NULL;
time_t seconds = 0;
aco_save_T aco;
int flags = 0;
long tomatch;
- char_u *dirname_start = NULL;
- char_u *dirname_now = NULL;
- char_u *target_dir = NULL;
- char_u *au_name = NULL;
+ char_u *dirname_start = NULL;
+ char_u *dirname_now = NULL;
+ char_u *target_dir = NULL;
+ char_u *au_name = NULL;
au_name = vgr_get_auname(eap->cmdidx);
if (au_name != NULL && apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name,
@@ -5370,10 +5344,11 @@ void ex_vimgrep(exarg_T *eap)
qf_info_T *qi = qf_cmd_get_or_alloc_stack(eap, &wp);
- if (eap->addr_count > 0)
+ if (eap->addr_count > 0) {
tomatch = eap->line2;
- else
+ } else {
tomatch = MAXLNUM;
+ }
// Get the search pattern: either white-separated or enclosed in //
regmatch.regprog = NULL;
@@ -5457,8 +5432,9 @@ void ex_vimgrep(exarg_T *eap)
save_qfid = qf_get_curlist(qi)->qf_id;
if (buf == NULL) {
- if (!got_int)
+ if (!got_int) {
smsg(_("Cannot open file \"%s\""), fname);
+ }
} else {
// Try for a match in all lines of the buffer.
// For ":1vimgrep" look for first match only.
@@ -5467,8 +5443,9 @@ void ex_vimgrep(exarg_T *eap)
duplicate_name, flags);
if (using_dummy) {
- if (found_match && first_match_buf == NULL)
+ if (found_match && first_match_buf == NULL) {
first_match_buf = buf;
+ }
if (duplicate_name) {
// Never keep a dummy buffer if there is another buffer
// with the same name.
@@ -5514,8 +5491,7 @@ void ex_vimgrep(exarg_T *eap)
// need to be done (again). But not the window-local
// options!
aucmd_prepbuf(&aco, buf);
- apply_autocmds(EVENT_FILETYPE, buf->b_p_ft,
- buf->b_fname, TRUE, buf);
+ apply_autocmds(EVENT_FILETYPE, buf->b_p_ft, buf->b_fname, true, buf);
do_modelines(OPT_NOWIN);
aucmd_restbuf(&aco);
}
@@ -5533,9 +5509,9 @@ void ex_vimgrep(exarg_T *eap)
qf_update_buffer(qi, NULL);
- if (au_name != NULL)
- apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name,
- curbuf->b_fname, TRUE, curbuf);
+ if (au_name != NULL) {
+ apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name, curbuf->b_fname, true, curbuf);
+ }
// The QuickFixCmdPost autocmd may free the quickfix list. Check the list
// is still valid.
@@ -5551,8 +5527,9 @@ void ex_vimgrep(exarg_T *eap)
vgr_jump_to_match(qi, eap->forceit, &redraw_for_dummy, first_match_buf,
target_dir);
}
- } else
+ } else {
EMSG2(_(e_nomatch2), s);
+ }
decr_quickfix_busy();
@@ -5590,24 +5567,22 @@ static void restore_start_dir(char_u *dirname_start)
xfree(dirname_now);
}
-// Load file "fname" into a dummy buffer and return the buffer pointer,
-// placing the directory resulting from the buffer load into the
-// "resulting_dir" pointer. "resulting_dir" must be allocated by the caller
-// prior to calling this function. Restores directory to "dirname_start" prior
-// to returning, if autocmds or the 'autochdir' option have changed it.
-//
-// If creating the dummy buffer does not fail, must call unload_dummy_buffer()
-// or wipe_dummy_buffer() later!
-//
-// Returns NULL if it fails.
-static buf_T *
-load_dummy_buffer (
- char_u *fname,
- char_u *dirname_start, // in: old directory
- char_u *resulting_dir // out: new directory
-)
-{
- buf_T *newbuf;
+/// Load file "fname" into a dummy buffer and return the buffer pointer,
+/// placing the directory resulting from the buffer load into the
+/// "resulting_dir" pointer. "resulting_dir" must be allocated by the caller
+/// prior to calling this function. Restores directory to "dirname_start" prior
+/// to returning, if autocmds or the 'autochdir' option have changed it.
+///
+/// If creating the dummy buffer does not fail, must call unload_dummy_buffer()
+/// or wipe_dummy_buffer() later!
+///
+/// @param dirname_start in: old directory
+/// @param resulting_dir out: new directory
+///
+/// @return NULL if it fails.
+static buf_T *load_dummy_buffer(char_u *fname, char_u *dirname_start, char_u *resulting_dir)
+{
+ buf_T *newbuf;
bufref_T newbufref;
bufref_T newbuf_to_wipe;
int failed = true;
@@ -5744,7 +5719,7 @@ static void unload_dummy_buffer(buf_T *buf, char_u *dirname_start)
}
}
-/// Copy the specified quickfix entry items into a new dict and appened the dict
+/// Copy the specified quickfix entry items into a new dict and append the dict
/// to 'list'. Returns OK on success.
static int get_qfline_items(qfline_T *qfp, list_T *list)
{
@@ -5765,21 +5740,22 @@ static int get_qfline_items(qfline_T *qfp, list_T *list)
if (tv_dict_add_nr(dict, S_LEN("bufnr"), (varnumber_T)bufnum) == FAIL
|| (tv_dict_add_nr(dict, S_LEN("lnum"), (varnumber_T)qfp->qf_lnum)
== FAIL)
+ || (tv_dict_add_nr(dict, S_LEN("end_lnum"), (varnumber_T)qfp->qf_end_lnum)
+ == FAIL)
|| (tv_dict_add_nr(dict, S_LEN("col"), (varnumber_T)qfp->qf_col) == FAIL)
+ || (tv_dict_add_nr(dict, S_LEN("end_col"), (varnumber_T)qfp->qf_end_col)
+ == FAIL)
|| (tv_dict_add_nr(dict, S_LEN("vcol"), (varnumber_T)qfp->qf_viscol)
== FAIL)
|| (tv_dict_add_nr(dict, S_LEN("nr"), (varnumber_T)qfp->qf_nr) == FAIL)
- || (tv_dict_add_str(
- dict, S_LEN("module"),
- (qfp->qf_module == NULL ? "" : (const char *)qfp->qf_module))
+ || (tv_dict_add_str(dict, S_LEN("module"),
+ (qfp->qf_module == NULL ? "" : (const char *)qfp->qf_module))
== FAIL)
- || (tv_dict_add_str(
- dict, S_LEN("pattern"),
- (qfp->qf_pattern == NULL ? "" : (const char *)qfp->qf_pattern))
+ || (tv_dict_add_str(dict, S_LEN("pattern"),
+ (qfp->qf_pattern == NULL ? "" : (const char *)qfp->qf_pattern))
== FAIL)
- || (tv_dict_add_str(
- dict, S_LEN("text"),
- (qfp->qf_text == NULL ? "" : (const char *)qfp->qf_text))
+ || (tv_dict_add_str(dict, S_LEN("text"),
+ (qfp->qf_text == NULL ? "" : (const char *)qfp->qf_text))
== FAIL)
|| (tv_dict_add_str(dict, S_LEN("type"), (const char *)buf) == FAIL)
|| (tv_dict_add_nr(dict, S_LEN("valid"), (varnumber_T)qfp->qf_valid)
@@ -5796,12 +5772,11 @@ static int get_qfline_items(qfline_T *qfp, list_T *list)
/// If qf_idx is -1, use the current list. Otherwise, use the specified list.
/// If eidx is not 0, then return only the specified entry. Otherwise return
/// all the entries.
-int get_errorlist(qf_info_T *qi_arg, win_T *wp, int qf_idx, int eidx,
- list_T *list)
+int get_errorlist(qf_info_T *qi_arg, win_T *wp, int qf_idx, int eidx, list_T *list)
{
qf_info_T *qi = qi_arg;
qf_list_T *qfl;
- qfline_T *qfp;
+ qfline_T *qfp;
int i;
if (qi == NULL) {
@@ -5837,7 +5812,7 @@ int get_errorlist(qf_info_T *qi_arg, win_T *wp, int qf_idx, int eidx,
return get_qfline_items(qfp, list);
}
} else if (get_qfline_items(qfp, list) == FAIL) {
- return FAIL;
+ return FAIL;
}
}
@@ -6000,7 +5975,7 @@ static int qf_getprop_qfidx(qf_info_T *qi, dict_T *what)
if ((di = tv_dict_find(what, S_LEN("id"))) != NULL) {
// Look for a list with the specified id
if (di->di_tv.v_type == VAR_NUMBER) {
- // For zero, use the current list or the list specifed by 'nr'
+ // For zero, use the current list or the list specified by 'nr'
if (di->di_tv.vval.v_number != 0) {
qf_idx = qf_id2nr(qi, (unsigned)di->di_tv.vval.v_number);
}
@@ -6013,10 +5988,7 @@ static int qf_getprop_qfidx(qf_info_T *qi, dict_T *what)
}
/// Return default values for quickfix list properties in retdict.
-static int qf_getprop_defaults(qf_info_T *qi,
- int flags,
- int locstack,
- dict_T *retdict)
+static int qf_getprop_defaults(qf_info_T *qi, int flags, int locstack, dict_T *retdict)
{
int status = OK;
@@ -6061,15 +6033,14 @@ static int qf_getprop_defaults(qf_info_T *qi,
/// Return the quickfix list title as 'title' in retdict
static int qf_getprop_title(qf_list_T *qfl, dict_T *retdict)
{
- return tv_dict_add_str(retdict, S_LEN("title"),
- (const char *)qfl->qf_title);
+ return tv_dict_add_str(retdict, S_LEN("title"),
+ (const char *)qfl->qf_title);
}
// Returns the identifier of the window used to display files from a location
// list. If there is no associated window, then returns 0. Useful only when
// called from a location list window.
-static int qf_getprop_filewinid(const win_T *wp, const qf_info_T *qi,
- dict_T *retdict)
+static int qf_getprop_filewinid(const win_T *wp, const qf_info_T *qi, dict_T *retdict)
FUNC_ATTR_NONNULL_ARG(3)
{
handle_T winid = 0;
@@ -6086,8 +6057,7 @@ static int qf_getprop_filewinid(const win_T *wp, const qf_info_T *qi,
/// Return the quickfix list items/entries as 'items' in retdict.
/// If eidx is not 0, then return the item at the specified index.
-static int qf_getprop_items(qf_info_T *qi, int qf_idx, int eidx,
- dict_T *retdict)
+static int qf_getprop_items(qf_info_T *qi, int qf_idx, int eidx, dict_T *retdict)
{
list_T *l = tv_list_alloc(kListLenMayKnow);
get_errorlist(qi, NULL, qf_idx, eidx, l);
@@ -6246,11 +6216,8 @@ static int qf_setprop_qftf(qf_list_T *qfl, dictitem_T *di)
/// Add a new quickfix entry to list at 'qf_idx' in the stack 'qi' from the
/// items in the dict 'd'. If it is a valid error entry, then set 'valid_entry'
/// to true.
-static int qf_add_entry_from_dict(
- qf_list_T *qfl,
- const dict_T *d,
- bool first_entry,
- bool *valid_entry)
+static int qf_add_entry_from_dict(qf_list_T *qfl, const dict_T *d, bool first_entry,
+ bool *valid_entry)
FUNC_ATTR_NONNULL_ALL
{
static bool did_bufnr_emsg;
@@ -6263,7 +6230,9 @@ static int qf_add_entry_from_dict(
char *const module = tv_dict_get_string(d, "module", true);
int bufnum = (int)tv_dict_get_number(d, "bufnr");
const long lnum = (long)tv_dict_get_number(d, "lnum");
+ const long end_lnum = (long)tv_dict_get_number(d, "end_lnum");
const int col = (int)tv_dict_get_number(d, "col");
+ const int end_col = (int)tv_dict_get_number(d, "end_col");
const char_u vcol = (char_u)tv_dict_get_number(d, "vcol");
const int nr = (int)tv_dict_get_number(d, "nr");
const char *const type = tv_dict_get_string(d, "type", false);
@@ -6301,7 +6270,9 @@ static int qf_add_entry_from_dict(
bufnum,
(char_u *)text,
lnum,
+ end_lnum,
col,
+ end_col,
vcol, // vis_col
(char_u *)pattern, // search pattern
nr,
@@ -6322,8 +6293,7 @@ static int qf_add_entry_from_dict(
/// Add list of entries to quickfix/location list. Each list entry is
/// a dictionary with item information.
-static int qf_add_entries(qf_info_T *qi, int qf_idx, list_T *list,
- char_u *title, int action)
+static int qf_add_entries(qf_info_T *qi, int qf_idx, list_T *list, char_u *title, int action)
{
qf_list_T *qfl = qf_get_list(qi, qf_idx);
qfline_T *old_last = NULL;
@@ -6386,11 +6356,7 @@ static int qf_add_entries(qf_info_T *qi, int qf_idx, list_T *list,
}
/// Get the quickfix list index from 'nr' or 'id'
-static int qf_setprop_get_qfidx(
- const qf_info_T *qi,
- const dict_T *what,
- int action,
- bool *newlist)
+static int qf_setprop_get_qfidx(const qf_info_T *qi, const dict_T *what, int action, bool *newlist)
FUNC_ATTR_NONNULL_ALL
{
dictitem_T *di;
@@ -6441,8 +6407,7 @@ static int qf_setprop_get_qfidx(
}
// Set the quickfix list title.
-static int qf_setprop_title(qf_info_T *qi, int qf_idx, const dict_T *what,
- const dictitem_T *di)
+static int qf_setprop_title(qf_info_T *qi, int qf_idx, const dict_T *what, const dictitem_T *di)
FUNC_ATTR_NONNULL_ALL
{
qf_list_T *qfl = qf_get_list(qi, qf_idx);
@@ -6460,8 +6425,7 @@ static int qf_setprop_title(qf_info_T *qi, int qf_idx, const dict_T *what,
}
// Set quickfix list items/entries.
-static int qf_setprop_items(qf_info_T *qi, int qf_idx, dictitem_T *di,
- int action)
+static int qf_setprop_items(qf_info_T *qi, int qf_idx, dictitem_T *di, int action)
FUNC_ATTR_NONNULL_ALL
{
if (di->di_tv.v_type != VAR_LIST) {
@@ -6478,17 +6442,13 @@ static int qf_setprop_items(qf_info_T *qi, int qf_idx, dictitem_T *di,
}
// Set quickfix list items/entries from a list of lines.
-static int qf_setprop_items_from_lines(
- qf_info_T *qi,
- int qf_idx,
- const dict_T *what,
- dictitem_T *di,
- int action)
+static int qf_setprop_items_from_lines(qf_info_T *qi, int qf_idx, const dict_T *what,
+ dictitem_T *di, int action)
FUNC_ATTR_NONNULL_ALL
{
char_u *errorformat = p_efm;
dictitem_T *efm_di;
- int retval = FAIL;
+ int retval = FAIL;
// Use the user supplied errorformat settings (if present)
if ((efm_di = tv_dict_find(what, S_LEN("efm"))) != NULL) {
@@ -6528,11 +6488,10 @@ static int qf_setprop_context(qf_list_T *qfl, dictitem_T *di)
}
// Set the current index in the specified quickfix list
-static int qf_setprop_curidx(qf_info_T *qi, qf_list_T *qfl,
- const dictitem_T *di)
+static int qf_setprop_curidx(qf_info_T *qi, qf_list_T *qfl, const dictitem_T *di)
FUNC_ATTR_NONNULL_ALL
{
- int newidx;
+ int newidx;
// If the specified index is '$', then use the last entry
if (di->di_tv.v_type == VAR_STRING
@@ -6573,13 +6532,12 @@ static int qf_setprop_curidx(qf_info_T *qi, qf_list_T *qfl,
/// Set quickfix/location list properties (title, items, context).
/// Also used to add items from parsing a list of lines.
/// Used by the setqflist() and setloclist() Vim script functions.
-static int qf_set_properties(qf_info_T *qi, const dict_T *what, int action,
- char_u *title)
+static int qf_set_properties(qf_info_T *qi, const dict_T *what, int action, char_u *title)
FUNC_ATTR_NONNULL_ALL
{
qf_list_T *qfl;
dictitem_T *di;
- int retval = FAIL;
+ int retval = FAIL;
bool newlist = action == ' ' || qf_stack_empty(qi);
int qf_idx = qf_setprop_get_qfidx(qi, what, action, &newlist);
if (qf_idx == INVALID_QFIDX) { // List not found
@@ -6685,8 +6643,7 @@ static void qf_free_stack(win_T *wp, qf_info_T *qi)
// of dictionaries. "title" will be copied to w:quickfix_title
// "action" is 'a' for add, 'r' for replace. Otherwise create a new list.
// When "what" is not NULL then only set some properties.
-int set_errorlist(win_T *wp, list_T *list, int action, char_u *title,
- dict_T *what)
+int set_errorlist(win_T *wp, list_T *list, int action, char_u *title, dict_T *what)
{
qf_info_T *qi = &ql_info;
int retval = OK;
@@ -6771,32 +6728,37 @@ bool set_ref_in_quickfix(int copyID)
}
/// Return the autocmd name for the :cbuffer Ex commands
-static char_u * cbuffer_get_auname(cmdidx_T cmdidx)
+static char_u *cbuffer_get_auname(cmdidx_T cmdidx)
{
switch (cmdidx) {
- case CMD_cbuffer: return (char_u *)"cbuffer";
- case CMD_cgetbuffer: return (char_u *)"cgetbuffer";
- case CMD_caddbuffer: return (char_u *)"caddbuffer";
- case CMD_lbuffer: return (char_u *)"lbuffer";
- case CMD_lgetbuffer: return (char_u *)"lgetbuffer";
- case CMD_laddbuffer: return (char_u *)"laddbuffer";
- default: return NULL;
+ case CMD_cbuffer:
+ return (char_u *)"cbuffer";
+ case CMD_cgetbuffer:
+ return (char_u *)"cgetbuffer";
+ case CMD_caddbuffer:
+ return (char_u *)"caddbuffer";
+ case CMD_lbuffer:
+ return (char_u *)"lbuffer";
+ case CMD_lgetbuffer:
+ return (char_u *)"lgetbuffer";
+ case CMD_laddbuffer:
+ return (char_u *)"laddbuffer";
+ default:
+ return NULL;
}
}
/// Process and validate the arguments passed to the :cbuffer, :caddbuffer,
/// :cgetbuffer, :lbuffer, :laddbuffer, :lgetbuffer Ex commands.
-static int cbuffer_process_args(exarg_T *eap,
- buf_T **bufp,
- linenr_T *line1,
- linenr_T *line2)
+static int cbuffer_process_args(exarg_T *eap, buf_T **bufp, linenr_T *line1, linenr_T *line2)
{
buf_T *buf = NULL;
- if (*eap->arg == NUL)
+ if (*eap->arg == NUL) {
buf = curbuf;
- else if (*skipwhite(skipdigits(eap->arg)) == NUL)
+ } else if (*skipwhite(skipdigits(eap->arg)) == NUL) {
buf = buflist_findnr(atoi((char *)eap->arg));
+ }
if (buf == NULL) {
EMSG(_(e_invarg));
@@ -6902,16 +6864,23 @@ void ex_cbuffer(exarg_T *eap)
}
/// Return the autocmd name for the :cexpr Ex commands.
-static char_u * cexpr_get_auname(cmdidx_T cmdidx)
+static char_u *cexpr_get_auname(cmdidx_T cmdidx)
{
switch (cmdidx) {
- case CMD_cexpr: return (char_u *)"cexpr";
- case CMD_cgetexpr: return (char_u *)"cgetexpr";
- case CMD_caddexpr: return (char_u *)"caddexpr";
- case CMD_lexpr: return (char_u *)"lexpr";
- case CMD_lgetexpr: return (char_u *)"lgetexpr";
- case CMD_laddexpr: return (char_u *)"laddexpr";
- default: return NULL;
+ case CMD_cexpr:
+ return (char_u *)"cexpr";
+ case CMD_cgetexpr:
+ return (char_u *)"cgetexpr";
+ case CMD_caddexpr:
+ return (char_u *)"caddexpr";
+ case CMD_lexpr:
+ return (char_u *)"lexpr";
+ case CMD_lgetexpr:
+ return (char_u *)"lgetexpr";
+ case CMD_laddexpr:
+ return (char_u *)"laddexpr";
+ default:
+ return NULL;
}
}
@@ -7005,10 +6974,7 @@ static qf_info_T *hgr_get_ll(bool *new_ll)
}
// Search for a pattern in a help file.
-static void hgr_search_file(
- qf_list_T *qfl,
- char_u *fname,
- regmatch_T *p_regmatch)
+static void hgr_search_file(qf_list_T *qfl, char_u *fname, regmatch_T *p_regmatch)
FUNC_ATTR_NONNULL_ARG(1, 3)
{
FILE *const fd = os_fopen((char *)fname, "r");
@@ -7035,7 +7001,10 @@ static void hgr_search_file(
0,
line,
lnum,
+ 0,
(int)(p_regmatch->startp[0] - line) + 1, // col
+ (int)(p_regmatch->endp[0] - line)
+ + 1, // end_col
false, // vis_col
NULL, // search pattern
0, // nr
@@ -7060,11 +7029,8 @@ static void hgr_search_file(
// Search for a pattern in all the help files in the doc directory under
// the given directory.
-static void hgr_search_files_in_dir(
- qf_list_T *qfl,
- char_u *dirname,
- regmatch_T *p_regmatch,
- const char_u *lang)
+static void hgr_search_files_in_dir(qf_list_T *qfl, char_u *dirname, regmatch_T *p_regmatch,
+ const char_u *lang)
FUNC_ATTR_NONNULL_ARG(1, 2, 3)
{
int fcount;
@@ -7096,8 +7062,7 @@ static void hgr_search_files_in_dir(
// and add the matches to a quickfix list.
// 'lang' is the language specifier. If supplied, then only matches in the
// specified language are found.
-static void hgr_search_in_rtp(qf_list_T *qfl, regmatch_T *p_regmatch,
- const char_u *lang)
+static void hgr_search_in_rtp(qf_list_T *qfl, regmatch_T *p_regmatch, const char_u *lang)
FUNC_ATTR_NONNULL_ARG(1, 2)
{
// Go through all directories in 'runtimepath'
@@ -7117,9 +7082,12 @@ void ex_helpgrep(exarg_T *eap)
char_u *au_name = NULL;
switch (eap->cmdidx) {
- case CMD_helpgrep: au_name = (char_u *)"helpgrep"; break;
- case CMD_lhelpgrep: au_name = (char_u *)"lhelpgrep"; break;
- default: break;
+ case CMD_helpgrep:
+ au_name = (char_u *)"helpgrep"; break;
+ case CMD_lhelpgrep:
+ au_name = (char_u *)"lhelpgrep"; break;
+ default:
+ break;
}
if (au_name != NULL && apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name,
curbuf->b_fname, true, curbuf)) {
diff --git a/src/nvim/rbuffer.c b/src/nvim/rbuffer.c
index df9394fbb2..4ac50095b3 100644
--- a/src/nvim/rbuffer.c
+++ b/src/nvim/rbuffer.c
@@ -6,8 +6,8 @@
#include <string.h>
#include "nvim/memory.h"
-#include "nvim/vim.h"
#include "nvim/rbuffer.h"
+#include "nvim/vim.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "rbuffer.c.generated.h"
@@ -144,7 +144,7 @@ void rbuffer_consumed(RBuffer *buf, size_t count)
buf->read_ptr += count;
if (buf->read_ptr >= buf->end_ptr) {
- buf->read_ptr -= rbuffer_capacity(buf);
+ buf->read_ptr -= rbuffer_capacity(buf);
}
bool was_full = buf->size == rbuffer_capacity(buf);
diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c
index c2ef217638..98a46cf781 100644
--- a/src/nvim/regexp.c
+++ b/src/nvim/regexp.c
@@ -63,6 +63,7 @@
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
+#include "nvim/plines.h"
#include "nvim/garray.h"
#include "nvim/strings.h"
@@ -6725,26 +6726,24 @@ static int vim_regsub_both(char_u *source, typval_T *expr, char_u *dest,
if (expr != NULL) {
typval_T argv[2];
- int dummy;
typval_T rettv;
staticList10_T matchList = TV_LIST_STATIC10_INIT;
-
rettv.v_type = VAR_STRING;
rettv.vval.v_string = NULL;
argv[0].v_type = VAR_LIST;
argv[0].vval.v_list = &matchList.sl_list;
+ funcexe_T funcexe = FUNCEXE_INIT;
+ funcexe.argv_func = fill_submatch_list;
+ funcexe.evaluate = true;
if (expr->v_type == VAR_FUNC) {
s = expr->vval.v_string;
- call_func(s, -1, &rettv, 1, argv,
- fill_submatch_list, 0L, 0L, &dummy,
- true, NULL, NULL);
+ call_func(s, -1, &rettv, 1, argv, &funcexe);
} else if (expr->v_type == VAR_PARTIAL) {
partial_T *partial = expr->vval.v_partial;
s = partial_name(partial);
- call_func(s, -1, &rettv, 1, argv,
- fill_submatch_list, 0L, 0L, &dummy,
- true, partial, NULL);
+ funcexe.partial = partial;
+ call_func(s, -1, &rettv, 1, argv, &funcexe);
}
if (tv_list_len(&matchList.sl_list) > 0) {
// fill_submatch_list() was called.
diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c
index 35c3285cda..039f9b4675 100644
--- a/src/nvim/regexp_nfa.c
+++ b/src/nvim/regexp_nfa.c
@@ -1161,8 +1161,6 @@ static int nfa_regatom(void)
int emit_range;
int negated;
int startc = -1;
- int endc = -1;
- int oldstartc = -1;
int save_prev_at_start = prev_at_start;
c = getchr();
@@ -1572,7 +1570,7 @@ collection:
* Failed to recognize a character class. Use the simple
* version that turns [abc] into 'a' OR 'b' OR 'c'
*/
- startc = endc = oldstartc = -1;
+ startc = -1;
negated = false;
if (*regparse == '^') { // negated range
negated = true;
@@ -1589,7 +1587,7 @@ collection:
// Emit the OR branches for each character in the []
emit_range = false;
while (regparse < endp) {
- oldstartc = startc;
+ int oldstartc = startc;
startc = -1;
got_coll_char = false;
if (*regparse == '[') {
@@ -1729,7 +1727,7 @@ collection:
/* Previous char was '-', so this char is end of range. */
if (emit_range) {
- endc = startc;
+ int endc = startc;
startc = oldstartc;
if (startc > endc) {
EMSG_RET_FAIL(_(e_reverse_range));
diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c
index c3cd210538..7b72efce23 100644
--- a/src/nvim/runtime.c
+++ b/src/nvim/runtime.c
@@ -5,21 +5,25 @@
///
/// Management of runtime files (including packages)
-#include "nvim/vim.h"
#include "nvim/ascii.h"
+#include "nvim/api/private/helpers.h"
#include "nvim/charset.h"
#include "nvim/eval.h"
-#include "nvim/option.h"
#include "nvim/ex_cmds.h"
#include "nvim/ex_cmds2.h"
#include "nvim/misc1.h"
+#include "nvim/option.h"
#include "nvim/os/os.h"
#include "nvim/runtime.h"
+#include "nvim/vim.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "runtime.c.generated.h"
#endif
+static bool runtime_search_path_valid = false;
+static int *runtime_search_path_ref = NULL;
+static RuntimeSearchPath runtime_search_path;
/// ":runtime [what] {name}"
void ex_runtime(exarg_T *eap)
@@ -60,12 +64,11 @@ static void source_callback(char_u *fname, void *cookie)
/// When "flags" has DIP_ERR: give an error message if there is no match.
///
/// return FAIL when no file could be sourced, OK otherwise.
-int do_in_path(char_u *path, char_u *name, int flags,
- DoInRuntimepathCB callback, void *cookie)
+int do_in_path(char_u *path, char_u *name, int flags, DoInRuntimepathCB callback, void *cookie)
{
- char_u *tail;
+ char_u *tail;
int num_files;
- char_u **files;
+ char_u **files;
int i;
bool did_one = false;
@@ -90,8 +93,7 @@ int do_in_path(char_u *path, char_u *name, int flags,
// Skip after or non-after directories.
if (flags & (DIP_NOAFTER | DIP_AFTER)) {
- bool is_after = buflen >= 5
- && STRCMP(buf + buflen - 5, "after") == 0;
+ bool is_after = path_is_after(buf, buflen);
if ((is_after && (flags & DIP_NOAFTER))
|| (!is_after && (flags & DIP_AFTER))) {
@@ -100,10 +102,8 @@ int do_in_path(char_u *path, char_u *name, int flags,
}
if (name == NULL) {
- (*callback)(buf, (void *)&cookie);
- if (!did_one) {
- did_one = (cookie == NULL);
- }
+ (*callback)(buf, cookie);
+ did_one = true;
} else if (buflen + STRLEN(name) + 2 < MAXPATHL) {
add_pathsep((char *)buf);
tail = buf + STRLEN(buf);
@@ -122,10 +122,11 @@ int do_in_path(char_u *path, char_u *name, int flags,
verbose_leave();
}
+ int ew_flags = ((flags & DIP_DIR) ? EW_DIR : EW_FILE)
+ | (flags & DIP_DIRFILE) ? (EW_DIR|EW_FILE) : 0;
+
// Expand wildcards, invoke the callback for each match.
- if (gen_expand_wildcards(1, &buf, &num_files, &files,
- (flags & DIP_DIR) ? EW_DIR : EW_FILE)
- == OK) {
+ if (gen_expand_wildcards(1, &buf, &num_files, &files, ew_flags) == OK) {
for (i = 0; i < num_files; i++) {
(*callback)(files[i], cookie);
did_one = true;
@@ -157,6 +158,115 @@ int do_in_path(char_u *path, char_u *name, int flags,
return did_one ? OK : FAIL;
}
+/// Find the file "name" in all directories in "path" and invoke
+/// "callback(fname, cookie)".
+/// "name" can contain wildcards.
+/// When "flags" has DIP_ALL: source all files, otherwise only the first one.
+/// When "flags" has DIP_DIR: find directories instead of files.
+/// When "flags" has DIP_ERR: give an error message if there is no match.
+///
+/// return FAIL when no file could be sourced, OK otherwise.
+int do_in_cached_path(char_u *name, int flags, DoInRuntimepathCB callback, void *cookie)
+{
+ runtime_search_path_validate();
+ char_u *tail;
+ int num_files;
+ char_u **files;
+ int i;
+ bool did_one = false;
+
+ char_u buf[MAXPATHL];
+
+ if (p_verbose > 10 && name != NULL) {
+ verbose_enter();
+ smsg(_("Searching for \"%s\" in runtime path"), (char *)name);
+ verbose_leave();
+ }
+
+ RuntimeSearchPath path = runtime_search_path;
+ int ref = 0;
+ if (runtime_search_path_ref == NULL) {
+ // cached path was unreferenced. keep a ref to
+ // prevent runtime_search_path() to freeing it too early
+ ref++;
+ runtime_search_path_ref = &ref;
+ }
+
+ // Loop over all entries in cached path
+ for (size_t j = 0; j < kv_size(path); j++) {
+ SearchPathItem item = kv_A(path, j);
+ size_t buflen = strlen(item.path);
+
+ // Skip after or non-after directories.
+ if (flags & (DIP_NOAFTER | DIP_AFTER)) {
+ if ((item.after && (flags & DIP_NOAFTER))
+ || (!item.after && (flags & DIP_AFTER))) {
+ continue;
+ }
+ }
+
+ if (name == NULL) {
+ (*callback)((char_u *)item.path, cookie);
+ did_one = true;
+ } else if (buflen + STRLEN(name) + 2 < MAXPATHL) {
+ STRCPY(buf, item.path);
+ add_pathsep((char *)buf);
+ tail = buf + STRLEN(buf);
+
+ // Loop over all patterns in "name"
+ char_u *np = name;
+ while (*np != NUL && ((flags & DIP_ALL) || !did_one)) {
+ // Append the pattern from "name" to buf[].
+ assert(MAXPATHL >= (tail - buf));
+ copy_option_part(&np, tail, (size_t)(MAXPATHL - (tail - buf)),
+ "\t ");
+
+ if (p_verbose > 10) {
+ verbose_enter();
+ smsg(_("Searching for \"%s\""), buf);
+ verbose_leave();
+ }
+
+ int ew_flags = ((flags & DIP_DIR) ? EW_DIR : EW_FILE)
+ | (flags & DIP_DIRFILE) ? (EW_DIR|EW_FILE) : 0;
+
+ // Expand wildcards, invoke the callback for each match.
+ char_u *(pat[]) = { buf };
+ if (gen_expand_wildcards(1, pat, &num_files, &files, ew_flags) == OK) {
+ for (i = 0; i < num_files; i++) {
+ (*callback)(files[i], cookie);
+ did_one = true;
+ if (!(flags & DIP_ALL)) {
+ break;
+ }
+ }
+ FreeWild(num_files, files);
+ }
+ }
+ }
+ }
+
+ if (!did_one && name != NULL) {
+ if (flags & DIP_ERR) {
+ EMSG3(_(e_dirnotf), "runtime path", name);
+ } else if (p_verbose > 0) {
+ verbose_enter();
+ smsg(_("not found in runtime path: \"%s\""), name);
+ verbose_leave();
+ }
+ }
+
+ if (ref) {
+ if (runtime_search_path_ref == &ref) {
+ runtime_search_path_ref = NULL;
+ } else {
+ runtime_search_path_free(path);
+ }
+ }
+
+
+ return did_one ? OK : FAIL;
+}
/// Find "name" in "path". When found, invoke the callback function for
/// it: callback(fname, "cookie")
/// When "flags" has DIP_ALL repeat for all matches, otherwise only the first
@@ -165,32 +275,33 @@ int do_in_path(char_u *path, char_u *name, int flags,
/// If "name" is NULL calls callback for each entry in "path". Cookie is
/// passed by reference in this case, setting it to NULL indicates that callback
/// has done its job.
-int do_in_path_and_pp(char_u *path, char_u *name, int flags,
- DoInRuntimepathCB callback, void *cookie)
+int do_in_path_and_pp(char_u *path, char_u *name, int flags, DoInRuntimepathCB callback,
+ void *cookie)
{
int done = FAIL;
if ((flags & DIP_NORTP) == 0) {
- done = do_in_path(path, name, flags, callback, cookie);
+ done |= do_in_path(path, (name && !*name) ? NULL : name, flags, callback, cookie);
}
if ((done == FAIL || (flags & DIP_ALL)) && (flags & DIP_START)) {
- char *start_dir = "pack/*/start/*/%s"; // NOLINT
- size_t len = STRLEN(start_dir) + STRLEN(name);
- char_u *s = xmallocz(len);
+ char *start_dir = "pack/*/start/*/%s%s"; // NOLINT
+ size_t len = STRLEN(start_dir) + STRLEN(name) + 6;
+ char_u *s = xmallocz(len); // TODO(bfredl): get rid of random allocations
+ char *suffix = (flags & DIP_AFTER) ? "after/" : "";
- vim_snprintf((char *)s, len, start_dir, name);
- done = do_in_path(p_pp, s, flags, callback, cookie);
+ vim_snprintf((char *)s, len, start_dir, suffix, name);
+ done |= do_in_path(p_pp, s, flags & ~DIP_AFTER, callback, cookie);
xfree(s);
- if (done == FAIL|| (flags & DIP_ALL)) {
- start_dir = "start/*/%s"; // NOLINT
- len = STRLEN(start_dir) + STRLEN(name);
+ if (done == FAIL || (flags & DIP_ALL)) {
+ start_dir = "start/*/%s%s"; // NOLINT
+ len = STRLEN(start_dir) + STRLEN(name) + 6;
s = xmallocz(len);
- vim_snprintf((char *)s, len, start_dir, name);
- done = do_in_path(p_pp, s, flags, callback, cookie);
+ vim_snprintf((char *)s, len, start_dir, suffix, name);
+ done |= do_in_path(p_pp, s, flags & ~DIP_AFTER, callback, cookie);
xfree(s);
}
@@ -202,7 +313,7 @@ int do_in_path_and_pp(char_u *path, char_u *name, int flags,
char_u *s = xmallocz(len);
vim_snprintf((char *)s, len, opt_dir, name);
- done = do_in_path(p_pp, s, flags, callback, cookie);
+ done |= do_in_path(p_pp, s, flags, callback, cookie);
xfree(s);
@@ -212,7 +323,7 @@ int do_in_path_and_pp(char_u *path, char_u *name, int flags,
s = xmallocz(len);
vim_snprintf((char *)s, len, opt_dir, name);
- done = do_in_path(p_pp, s, flags, callback, cookie);
+ done |= do_in_path(p_pp, s, flags, callback, cookie);
xfree(s);
}
@@ -221,11 +332,161 @@ int do_in_path_and_pp(char_u *path, char_u *name, int flags,
return done;
}
+static void push_path(RuntimeSearchPath *search_path, char *entry, bool after)
+{
+ kv_push(*search_path, ((SearchPathItem){ entry, after }));
+}
+
+static void expand_pack_entry(RuntimeSearchPath *search_path, CharVec *after_path,
+ char_u *pack_entry)
+{
+ static char_u buf[MAXPATHL], buf2[MAXPATHL];
+ char *start_dir = "/pack/*/start/*"; // NOLINT
+ if (STRLEN(pack_entry) + STRLEN(start_dir) + 1 < MAXPATHL) {
+ xstrlcpy((char *)buf, (char *)pack_entry, MAXPATHL);
+ xstrlcpy((char *)buf2, (char *)pack_entry, MAXPATHL);
+ xstrlcat((char *)buf, start_dir, sizeof buf);
+ xstrlcat((char *)buf2, "/start/*", sizeof buf); // NOLINT
+ int num_files;
+ char_u **files;
+
+ char_u *(pat[]) = { buf, buf2 };
+ if (gen_expand_wildcards(2, pat, &num_files, &files, EW_DIR) == OK) {
+ for (int i = 0; i < num_files; i++) {
+ push_path(search_path, xstrdup((char *)files[i]), false);
+ size_t after_size = STRLEN(files[i])+7;
+ char *after = xmallocz(after_size);
+ xstrlcpy(after, (char *)files[i], after_size);
+ xstrlcat(after, "/after", after_size);
+ if (os_isdir((char_u *)after)) {
+ kv_push(*after_path, after);
+ } else {
+ xfree(after);
+ }
+ }
+ FreeWild(num_files, files);
+ }
+ }
+}
+
+static bool path_is_after(char_u *buf, size_t buflen)
+{
+ // NOTE: we only consider dirs exactly matching "after" to be an AFTER dir.
+ // vim8 considers all dirs like "foo/bar_after", "Xafter" etc, as an
+ // "after" dir in SOME codepaths not not in ALL codepaths.
+ return buflen >= 5
+ && (!(buflen >= 6) || vim_ispathsep(buf[buflen-6]))
+ && STRCMP(buf + buflen - 5, "after") == 0;
+}
+
+RuntimeSearchPath runtime_search_path_build(void)
+{
+ kvec_t(String) pack_entries = KV_INITIAL_VALUE;
+ Map(String, handle_T) pack_used = MAP_INIT;
+ // TODO(bfredl): add a set of existing rtp entries to not duplicate those
+ RuntimeSearchPath search_path = KV_INITIAL_VALUE;
+ CharVec after_path = KV_INITIAL_VALUE;
+
+ static char_u buf[MAXPATHL];
+ for (char *entry = (char *)p_pp; *entry != NUL; ) {
+ char *cur_entry = entry;
+ copy_option_part((char_u **)&entry, buf, MAXPATHL, ",");
+
+ String the_entry = { .data = cur_entry, .size = STRLEN(buf) };
+
+ kv_push(pack_entries, the_entry);
+ map_put(String, handle_T)(&pack_used, the_entry, 0);
+ }
+
+
+ char *rtp_entry;
+ for (rtp_entry = (char *)p_rtp; *rtp_entry != NUL; ) {
+ char *cur_entry = rtp_entry;
+ copy_option_part((char_u **)&rtp_entry, buf, MAXPATHL, ",");
+ size_t buflen = STRLEN(buf);
+
+ if (path_is_after(buf, buflen)) {
+ rtp_entry = cur_entry;
+ break;
+ }
+
+ push_path(&search_path, xstrdup((char *)buf), false);
+
+ handle_T *h = map_ref(String, handle_T)(&pack_used, cstr_as_string((char *)buf), false);
+ if (h) {
+ (*h)++;
+ expand_pack_entry(&search_path, &after_path, buf);
+ }
+ }
+
+ for (size_t i = 0; i < kv_size(pack_entries); i++) {
+ handle_T h = map_get(String, handle_T)(&pack_used, kv_A(pack_entries, i));
+ if (h == 0) {
+ expand_pack_entry(&search_path, &after_path, (char_u *)kv_A(pack_entries, i).data);
+ }
+ }
+
+ // "after" packages
+ for (size_t i = 0; i < kv_size(after_path); i++) {
+ push_path(&search_path, kv_A(after_path, i), true);
+ }
+
+ // "after" dirs in rtp
+ for (; *rtp_entry != NUL;) {
+ copy_option_part((char_u **)&rtp_entry, buf, MAXPATHL, ",");
+ push_path(&search_path, xstrdup((char *)buf), path_is_after(buf, STRLEN(buf)));
+ }
+
+ // strings are not owned
+ kv_destroy(pack_entries);
+ kv_destroy(after_path);
+ map_destroy(String, handle_T)(&pack_used);
+
+ return search_path;
+}
+
+void runtime_search_path_invalidate(void)
+{
+ runtime_search_path_valid = false;
+}
+
+void runtime_search_path_free(RuntimeSearchPath path)
+{
+ for (size_t j = 0; j < kv_size(path); j++) {
+ SearchPathItem item = kv_A(path, j);
+ xfree(item.path);
+ }
+ kv_destroy(path);
+}
+
+void runtime_search_path_validate(void)
+{
+ if (!runtime_search_path_valid) {
+ if (!runtime_search_path_ref) {
+ runtime_search_path_free(runtime_search_path);
+ }
+ runtime_search_path = runtime_search_path_build();
+ runtime_search_path_valid = true;
+ runtime_search_path_ref = NULL; // initially unowned
+ }
+}
+
+
+
/// Just like do_in_path_and_pp(), using 'runtimepath' for "path".
-int do_in_runtimepath(char_u *name, int flags, DoInRuntimepathCB callback,
- void *cookie)
+int do_in_runtimepath(char_u *name, int flags, DoInRuntimepathCB callback, void *cookie)
{
- return do_in_path_and_pp(p_rtp, name, flags, callback, cookie);
+ int success = FAIL;
+ if (!(flags & DIP_NORTP)) {
+ success |= do_in_cached_path((name && !*name) ? NULL : name, flags, callback, cookie);
+ flags = (flags & ~DIP_START) | DIP_NORTP;
+ }
+ // TODO(bfredl): we could integrate disabled OPT dirs into the cached path
+ // which would effectivize ":packadd myoptpack" as well
+ if ((flags & (DIP_START|DIP_OPT)) && (success == FAIL || (flags & DIP_ALL))) {
+ success |= do_in_path_and_pp(p_rtp, name, flags, callback, cookie);
+ }
+ return success;
}
/// Source the file "name" from all directories in 'runtimepath'.
@@ -235,8 +496,7 @@ int do_in_runtimepath(char_u *name, int flags, DoInRuntimepathCB callback,
/// return FAIL when no file could be sourced, OK otherwise.
int source_runtime(char_u *name, int flags)
{
- flags |= (flags & DIP_NORTP) ? 0 : DIP_START;
- return source_in_path(p_rtp, name, flags);
+ return do_in_runtimepath(name, flags, source_callback, NULL);
}
/// Just like source_runtime(), but use "path" instead of 'runtimepath'.
@@ -403,8 +663,10 @@ theend:
return retval;
}
-/// Load scripts in "plugin" and "ftdetect" directories of the package.
-static int load_pack_plugin(char_u *fname)
+/// Load scripts in "plugin" directory of the package.
+/// For opt packages, also load scripts in "ftdetect" (start packages already
+/// load these from filetype.vim)
+static int load_pack_plugin(bool opt, char_u *fname)
{
static const char *ftpat = "%s/ftdetect/*.vim"; // NOLINT
@@ -421,7 +683,7 @@ static int load_pack_plugin(char_u *fname)
// If runtime/filetype.vim wasn't loaded yet, the scripts will be
// found when it loads.
- if (eval_to_number(cmd) > 0) {
+ if (opt && eval_to_number(cmd) > 0) {
do_cmdline_cmd("augroup filetypedetect");
vim_snprintf((char *)pat, len, ftpat, ffname);
source_all_matches(pat);
@@ -441,7 +703,7 @@ static int APP_ADD_DIR;
static int APP_LOAD;
static int APP_BOTH;
-static void add_pack_plugin(char_u *fname, void *cookie)
+static void add_pack_plugin(bool opt, char_u *fname, void *cookie)
{
if (cookie != &APP_LOAD) {
char *buf = xmalloc(MAXPATHL);
@@ -465,17 +727,18 @@ static void add_pack_plugin(char_u *fname, void *cookie)
}
if (cookie != &APP_ADD_DIR) {
- load_pack_plugin(fname);
+ load_pack_plugin(opt, fname);
}
}
-/// Add all packages in the "start" directory to 'runtimepath'.
-void add_pack_start_dirs(void)
+static void add_start_pack_plugin(char_u *fname, void *cookie)
{
- do_in_path(p_pp, (char_u *)"pack/*/start/*", DIP_ALL + DIP_DIR, // NOLINT
- add_pack_plugin, &APP_ADD_DIR);
- do_in_path(p_pp, (char_u *)"start/*", DIP_ALL + DIP_DIR, // NOLINT
- add_pack_plugin, &APP_ADD_DIR);
+ add_pack_plugin(false, fname, cookie);
+}
+
+static void add_opt_pack_plugin(char_u *fname, void *cookie)
+{
+ add_pack_plugin(true, fname, cookie);
}
/// Load plugins from all packages in the "start" directory.
@@ -483,9 +746,9 @@ void load_start_packages(void)
{
did_source_packages = true;
do_in_path(p_pp, (char_u *)"pack/*/start/*", DIP_ALL + DIP_DIR, // NOLINT
- add_pack_plugin, &APP_LOAD);
+ add_start_pack_plugin, &APP_LOAD);
do_in_path(p_pp, (char_u *)"start/*", DIP_ALL + DIP_DIR, // NOLINT
- add_pack_plugin, &APP_LOAD);
+ add_start_pack_plugin, &APP_LOAD);
}
// ":packloadall"
@@ -496,7 +759,6 @@ void ex_packloadall(exarg_T *eap)
// First do a round to add all directories to 'runtimepath', then load
// the plugins. This allows for plugins to use an autoload directory
// of another plugin.
- add_pack_start_dirs();
load_start_packages();
}
}
@@ -522,7 +784,8 @@ void ex_packadd(exarg_T *eap)
res = do_in_path(p_pp, (char_u *)pat,
DIP_ALL + DIP_DIR
+ (round == 2 && res == FAIL ? DIP_ERR : 0),
- add_pack_plugin, eap->forceit ? &APP_ADD_DIR : &APP_BOTH);
+ round == 1 ? add_start_pack_plugin : add_opt_pack_plugin,
+ eap->forceit ? &APP_ADD_DIR : &APP_BOTH);
xfree(pat);
}
}
@@ -555,8 +818,7 @@ static char *strcpy_comma_escaped(char *dest, const char *src, const size_t len)
/// (common_suf is present after each new item, single_suf is present
/// after half of the new items) and with commas after each item, commas
/// inside the values are escaped.
-static inline size_t compute_double_env_sep_len(const char *const val,
- const size_t common_suf_len,
+static inline size_t compute_double_env_sep_len(const char *const val, const size_t common_suf_len,
const size_t single_suf_len)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE
{
@@ -599,9 +861,8 @@ static inline size_t compute_double_env_sep_len(const char *const val,
/// Otherwise in reverse.
///
/// @return (dest + appended_characters_length)
-static inline char *add_env_sep_dirs(char *dest, const char *const val,
- const char *const suf1, const size_t len1,
- const char *const suf2, const size_t len2,
+static inline char *add_env_sep_dirs(char *dest, const char *const val, const char *const suf1,
+ const size_t len1, const char *const suf2, const size_t len2,
const bool forward)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_RET FUNC_ATTR_NONNULL_ARG(1)
{
@@ -660,9 +921,8 @@ static inline char *add_env_sep_dirs(char *dest, const char *const val,
/// Otherwise in reverse.
///
/// @return (dest + appended_characters_length)
-static inline char *add_dir(char *dest, const char *const dir,
- const size_t dir_len, const XDGVarType type,
- const char *const suf1, const size_t len1,
+static inline char *add_dir(char *dest, const char *const dir, const size_t dir_len,
+ const XDGVarType type, const char *const suf1, const size_t len1,
const char *const suf2, const size_t len2)
FUNC_ATTR_NONNULL_RET FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_WARN_UNUSED_RESULT
{
diff --git a/src/nvim/runtime.h b/src/nvim/runtime.h
index b40c2b670e..db31ae4e1e 100644
--- a/src/nvim/runtime.h
+++ b/src/nvim/runtime.h
@@ -7,10 +7,30 @@
typedef void (*DoInRuntimepathCB)(char_u *, void *);
+typedef struct {
+ char *path;
+ bool after;
+} SearchPathItem;
+
+typedef kvec_t(SearchPathItem) RuntimeSearchPath;
+typedef kvec_t(char *) CharVec;
+
// last argument for do_source()
#define DOSO_NONE 0
#define DOSO_VIMRC 1 // loading vimrc file
+// Used for flags in do_in_path()
+#define DIP_ALL 0x01 // all matches, not just the first one
+#define DIP_DIR 0x02 // find directories instead of files
+#define DIP_ERR 0x04 // give an error message when none found
+#define DIP_START 0x08 // also use "start" directory in 'packpath'
+#define DIP_OPT 0x10 // also use "opt" directory in 'packpath'
+#define DIP_NORTP 0x20 // do not use 'runtimepath'
+#define DIP_NOAFTER 0x40 // skip "after" directories
+#define DIP_AFTER 0x80 // only use "after" directories
+#define DIP_LUA 0x100 // also use ".lua" files
+#define DIP_DIRFILE 0x200 // find both files and directories
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "runtime.h.generated.h"
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index 3446a944cd..98d8722ec8 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -65,45 +65,50 @@
#include <stdbool.h>
#include <string.h>
-#include "nvim/log.h"
-#include "nvim/vim.h"
-#include "nvim/ascii.h"
+#include "nvim/api/private/helpers.h"
+#include "nvim/api/vim.h"
#include "nvim/arabic.h"
-#include "nvim/screen.h"
+#include "nvim/ascii.h"
#include "nvim/buffer.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
#include "nvim/cursor_shape.h"
+#include "nvim/decoration.h"
#include "nvim/diff.h"
+#include "nvim/edit.h"
#include "nvim/eval.h"
#include "nvim/ex_cmds.h"
#include "nvim/ex_cmds2.h"
#include "nvim/ex_getln.h"
-#include "nvim/edit.h"
+#include "nvim/extmark.h"
#include "nvim/fileio.h"
#include "nvim/fold.h"
-#include "nvim/indent.h"
+#include "nvim/garray.h"
#include "nvim/getchar.h"
#include "nvim/highlight.h"
+#include "nvim/indent.h"
+#include "nvim/lib/kvec.h"
+#include "nvim/log.h"
+#include "nvim/lua/executor.h"
#include "nvim/main.h"
#include "nvim/mark.h"
-#include "nvim/extmark.h"
-#include "nvim/decoration.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/menu.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/garray.h"
#include "nvim/move.h"
#include "nvim/normal.h"
#include "nvim/option.h"
+#include "nvim/os/time.h"
#include "nvim/os_unix.h"
#include "nvim/path.h"
+#include "nvim/plines.h"
#include "nvim/popupmnu.h"
#include "nvim/quickfix.h"
#include "nvim/regexp.h"
+#include "nvim/screen.h"
#include "nvim/search.h"
#include "nvim/sign.h"
#include "nvim/spell.h"
@@ -115,12 +120,8 @@
#include "nvim/ui_compositor.h"
#include "nvim/undo.h"
#include "nvim/version.h"
+#include "nvim/vim.h"
#include "nvim/window.h"
-#include "nvim/os/time.h"
-#include "nvim/api/private/helpers.h"
-#include "nvim/api/vim.h"
-#include "nvim/lua/executor.h"
-#include "nvim/lib/kvec.h"
#define MB_FILLER_CHAR '<' /* character used when a double-width character
* doesn't fit. */
@@ -134,7 +135,7 @@ static size_t linebuf_size = 0;
static schar_T *linebuf_char = NULL;
static sattr_T *linebuf_attr = NULL;
-static match_T search_hl; /* used for 'hlsearch' highlight matching */
+static match_T search_hl; // used for 'hlsearch' highlight matching
StlClickDefinition *tab_page_click_defs = NULL;
@@ -165,10 +166,9 @@ static bool resizing = false;
#endif
#define SEARCH_HL_PRIORITY 0
-static char * provider_first_error = NULL;
+static char * provider_err = NULL;
-static bool provider_invoke(NS ns_id, const char *name, LuaRef ref,
- Array args, bool default_true)
+static bool provider_invoke(NS ns_id, const char *name, LuaRef ref, Array args, bool default_true)
{
Error err = ERROR_INIT;
@@ -187,10 +187,10 @@ static bool provider_invoke(NS ns_id, const char *name, LuaRef ref,
const char *ns_name = describe_ns(ns_id);
ELOG("error in provider %s:%s: %s", ns_name, name, err.msg);
bool verbose_errs = true; // TODO(bfredl):
- if (verbose_errs && provider_first_error == NULL) {
+ if (verbose_errs && provider_err == NULL) {
static char errbuf[IOSIZE];
snprintf(errbuf, sizeof errbuf, "%s: %s", ns_name, err.msg);
- provider_first_error = xstrdup(errbuf);
+ provider_err = xstrdup(errbuf);
}
}
@@ -207,10 +207,12 @@ void redraw_later(win_T *wp, int type)
{
if (!exiting && wp->w_redr_type < type) {
wp->w_redr_type = type;
- if (type >= NOT_VALID)
+ if (type >= NOT_VALID) {
wp->w_lines_valid = 0;
- if (must_redraw < type) /* must_redraw is the maximum of all windows */
+ }
+ if (must_redraw < type) { // must_redraw is the maximum of all windows
must_redraw = type;
+ }
}
}
@@ -269,10 +271,10 @@ void redraw_buf_range_later(buf_T *buf, linenr_T firstline, linenr_T lastline)
if (wp->w_buffer == buf
&& lastline >= wp->w_topline && firstline < wp->w_botline) {
if (wp->w_redraw_top == 0 || wp->w_redraw_top > firstline) {
- wp->w_redraw_top = firstline;
+ wp->w_redraw_top = firstline;
}
if (wp->w_redraw_bot == 0 || wp->w_redraw_bot < lastline) {
- wp->w_redraw_bot = lastline;
+ wp->w_redraw_bot = lastline;
}
redraw_later(wp, VALID);
}
@@ -287,20 +289,16 @@ void redraw_buf_range_later(buf_T *buf, linenr_T firstline, linenr_T lastline)
* Note that when also inserting/deleting lines w_redraw_top and w_redraw_bot
* may become invalid and the whole window will have to be redrawn.
*/
-void
-redrawWinline(
- win_T *wp,
- linenr_T lnum
-)
+void redrawWinline(win_T *wp, linenr_T lnum)
FUNC_ATTR_NONNULL_ALL
{
if (lnum >= wp->w_topline
&& lnum < wp->w_botline) {
if (wp->w_redraw_top == 0 || wp->w_redraw_top > lnum) {
- wp->w_redraw_top = lnum;
+ wp->w_redraw_top = lnum;
}
if (wp->w_redraw_bot == 0 || wp->w_redraw_bot < lnum) {
- wp->w_redraw_bot = lnum;
+ wp->w_redraw_bot = lnum;
}
redraw_later(wp, VALID);
}
@@ -323,8 +321,7 @@ void update_curbuf(int type)
/// @param type set to a NOT_VALID to force redraw of entire screen
int update_screen(int type)
{
- static int did_intro = FALSE;
- int did_one;
+ static bool did_intro = false;
// Don't do anything if the screen structures are (not yet) valid.
// A VimResized autocmd can invoke redrawing in the middle of a resize,
@@ -339,8 +336,9 @@ int update_screen(int type)
}
if (must_redraw) {
- if (type < must_redraw) /* use maximal type */
+ if (type < must_redraw) { // use maximal type
type = must_redraw;
+ }
/* must_redraw is reset here, so that when we run into some weird
* reason to redraw while busy redrawing (e.g., asynchronous
@@ -349,9 +347,10 @@ int update_screen(int type)
must_redraw = 0;
}
- /* Need to update w_lines[]. */
- if (curwin->w_lines_valid == 0 && type < NOT_VALID)
+ // Need to update w_lines[].
+ if (curwin->w_lines_valid == 0 && type < NOT_VALID) {
type = NOT_VALID;
+ }
/* Postpone the redrawing when it's not needed and when being called
* recursively. */
@@ -386,7 +385,7 @@ int update_screen(int type)
// non-displayed part of msg_grid is considered invalid.
for (int i = 0; i < MIN(msg_scrollsize(), msg_grid.Rows); i++) {
grid_clear_line(&msg_grid, msg_grid.line_offset[i],
- (int)msg_grid.Columns, false);
+ msg_grid.Columns, false);
}
}
if (msg_use_msgsep()) {
@@ -437,8 +436,8 @@ int update_screen(int type)
}
}
}
- redraw_cmdline = TRUE;
- redraw_tabline = TRUE;
+ redraw_cmdline = true;
+ redraw_tabline = true;
}
msg_scrolled = 0;
msg_scrolled_at_flush = 0;
@@ -448,12 +447,13 @@ int update_screen(int type)
win_ui_flush();
msg_ext_check_clear();
- /* reset cmdline_row now (may have been changed temporarily) */
+ // reset cmdline_row now (may have been changed temporarily)
compute_cmdrow();
- /* Check for changed highlighting */
- if (need_highlight_changed)
+ // Check for changed highlighting
+ if (need_highlight_changed) {
highlight_changed();
+ }
if (type == CLEAR) { // first clear screen
screenclear(); // will reset clear_cmdline
@@ -503,21 +503,24 @@ int update_screen(int type)
redraw_tabline = true;
}
- if (clear_cmdline) /* going to clear cmdline (done below) */
- check_for_delay(FALSE);
+ if (clear_cmdline) { // going to clear cmdline (done below)
+ check_for_delay(false);
+ }
/* Force redraw when width of 'number' or 'relativenumber' column
* changes. */
if (curwin->w_redr_type < NOT_VALID
&& curwin->w_nrwidth != ((curwin->w_p_nu || curwin->w_p_rnu)
- ? number_width(curwin) : 0))
+ ? number_width(curwin) : 0)) {
curwin->w_redr_type = NOT_VALID;
+ }
/*
* Only start redrawing if there is really something to do.
*/
- if (type == INVERTED)
+ if (type == INVERTED) {
update_curswant();
+ }
if (curwin->w_redr_type < type
&& !((type == VALID
&& curwin->w_lines[0].wl_valid
@@ -530,8 +533,9 @@ int update_screen(int type)
&& curwin->w_old_visual_mode == VIsual_mode
&& (curwin->w_valid & VALID_VIRTCOL)
&& curwin->w_old_curswant == curwin->w_curswant)
- ))
+ )) {
curwin->w_redr_type = type;
+ }
// Redraw the tab pages line if needed.
if (redraw_tabline || type >= NOT_VALID) {
@@ -577,7 +581,7 @@ int update_screen(int type)
* Go from top to bottom through the windows, redrawing the ones that need
* it.
*/
- did_one = FALSE;
+ bool did_one = false;
search_hl.rm.regprog = NULL;
@@ -596,13 +600,13 @@ int update_screen(int type)
if (wp->w_redr_type != 0) {
if (!did_one) {
- did_one = TRUE;
+ did_one = true;
start_search_hl();
}
win_update(wp, &providers);
}
- /* redraw status line after the window to minimize cursor movement */
+ // redraw status line after the window to minimize cursor movement
if (wp->w_redr_status) {
win_redr_status(wp);
}
@@ -631,10 +635,11 @@ int update_screen(int type)
showmode();
}
- /* May put up an introductory message when not editing a file */
- if (!did_intro)
+ // May put up an introductory message when not editing a file
+ if (!did_intro) {
maybe_intro_message();
- did_intro = TRUE;
+ }
+ did_intro = true;
for (size_t i = 0; i < kv_size(providers); i++) {
DecorProvider *p = kv_A(providers, i);
@@ -704,7 +709,7 @@ bool win_cursorline_standout(const win_T *wp)
FUNC_ATTR_NONNULL_ALL
{
return wp->w_p_cul
- || (wp->w_p_cole > 0 && (VIsual_active || !conceal_cursor_line(wp)));
+ || (wp->w_p_cole > 0 && (VIsual_active || !conceal_cursor_line(wp)));
}
/*
@@ -715,28 +720,28 @@ bool win_cursorline_standout(const win_T *wp)
*
* How the window is redrawn depends on wp->w_redr_type. Each type also
* implies the one below it.
- * NOT_VALID redraw the whole window
- * SOME_VALID redraw the whole window but do scroll when possible
- * REDRAW_TOP redraw the top w_upd_rows window lines, otherwise like VALID
- * INVERTED redraw the changed part of the Visual area
- * INVERTED_ALL redraw the whole Visual area
- * VALID 1. scroll up/down to adjust for a changed w_topline
- * 2. update lines at the top when scrolled down
- * 3. redraw changed text:
- * - if wp->w_buffer->b_mod_set set, update lines between
- * b_mod_top and b_mod_bot.
- * - if wp->w_redraw_top non-zero, redraw lines between
- * wp->w_redraw_top and wp->w_redr_bot.
- * - continue redrawing when syntax status is invalid.
- * 4. if scrolled up, update lines at the bottom.
+ * NOT_VALID redraw the whole window
+ * SOME_VALID redraw the whole window but do scroll when possible
+ * REDRAW_TOP redraw the top w_upd_rows window lines, otherwise like VALID
+ * INVERTED redraw the changed part of the Visual area
+ * INVERTED_ALL redraw the whole Visual area
+ * VALID 1. scroll up/down to adjust for a changed w_topline
+ * 2. update lines at the top when scrolled down
+ * 3. redraw changed text:
+ * - if wp->w_buffer->b_mod_set set, update lines between
+ * b_mod_top and b_mod_bot.
+ * - if wp->w_redraw_top non-zero, redraw lines between
+ * wp->w_redraw_top and wp->w_redr_bot.
+ * - continue redrawing when syntax status is invalid.
+ * 4. if scrolled up, update lines at the bottom.
* This results in three areas that may need updating:
- * top: from first row to top_end (when scrolled down)
+ * top: from first row to top_end (when scrolled down)
* mid: from mid_start to mid_end (update inversion or changed text)
* bot: from bot_start to last row (when scrolled up)
*/
static void win_update(win_T *wp, Providers *providers)
{
- buf_T *buf = wp->w_buffer;
+ buf_T *buf = wp->w_buffer;
int type;
int top_end = 0; /* Below last row of the top area that needs
updating. 0 when no top area updating. */
@@ -746,29 +751,26 @@ static void win_update(win_T *wp, Providers *providers)
updating. 0 when no mid area updating. */
int bot_start = 999; /* first row of the bot area that needs
updating. 999 when no bot area updating */
- int scrolled_down = FALSE; /* TRUE when scrolled down when
- w_topline got smaller a bit */
+ bool scrolled_down = false; // true when scrolled down when w_topline got smaller a bit
bool top_to_mod = false; // redraw above mod_top
- int row; /* current window row to display */
- linenr_T lnum; /* current buffer lnum to display */
- int idx; /* current index in w_lines[] */
- int srow; /* starting row of the current line */
+ int row; // current window row to display
+ linenr_T lnum; // current buffer lnum to display
+ int idx; // current index in w_lines[]
+ int srow; // starting row of the current line
- int eof = FALSE; /* if TRUE, we hit the end of the file */
- int didline = FALSE; /* if TRUE, we finished the last line */
+ bool eof = false; // if true, we hit the end of the file
+ bool didline = false; // if true, we finished the last line
int i;
long j;
static bool recursive = false; // being called recursively
const linenr_T old_botline = wp->w_botline;
- const int old_wrow = wp->w_wrow;
- const int old_wcol = wp->w_wcol;
// Remember what happened to the previous line.
#define DID_NONE 1 // didn't update a line
#define DID_LINE 2 // updated a normal line
#define DID_FOLD 3 // updated a folded line
int did_update = DID_NONE;
- linenr_T syntax_last_parsed = 0; /* last parsed text line */
+ linenr_T syntax_last_parsed = 0; // last parsed text line
linenr_T mod_top = 0;
linenr_T mod_bot = 0;
int save_got_int;
@@ -825,10 +827,11 @@ static void win_update(win_T *wp, Providers *providers)
* changes. Set mod_bot to the first line after the changes.
*/
mod_top = wp->w_redraw_top;
- if (wp->w_redraw_bot != 0)
+ if (wp->w_redraw_bot != 0) {
mod_bot = wp->w_redraw_bot + 1;
- else
+ } else {
mod_bot = 0;
+ }
if (buf->b_mod_set) {
if (mod_top == 0 || mod_top > buf->b_mod_top) {
mod_top = buf->b_mod_top;
@@ -836,12 +839,14 @@ static void win_update(win_T *wp, Providers *providers)
* in a pattern match. */
if (syntax_present(wp)) {
mod_top -= buf->b_s.b_syn_sync_linebreaks;
- if (mod_top < 1)
+ if (mod_top < 1) {
mod_top = 1;
+ }
}
}
- if (mod_bot == 0 || mod_bot < buf->b_mod_bot)
+ if (mod_bot == 0 || mod_bot < buf->b_mod_bot) {
mod_bot = buf->b_mod_bot;
+ }
// When 'hlsearch' is on and using a multi-line search pattern, a
// change in one line may make the Search highlighting in a
@@ -880,10 +885,11 @@ static void win_update(win_T *wp, Providers *providers)
* to this line. If there is no valid entry, use MAXLNUM. */
lnumt = wp->w_topline;
lnumb = MAXLNUM;
- for (i = 0; i < wp->w_lines_valid; ++i)
+ for (i = 0; i < wp->w_lines_valid; ++i) {
if (wp->w_lines[i].wl_valid) {
- if (wp->w_lines[i].wl_lastlnum < mod_top)
+ if (wp->w_lines[i].wl_lastlnum < mod_top) {
lnumt = wp->w_lines[i].wl_lastlnum + 1;
+ }
if (lnumb == MAXLNUM && wp->w_lines[i].wl_lnum >= mod_bot) {
lnumb = wp->w_lines[i].wl_lnum;
// When there is a fold column it might need updating
@@ -893,6 +899,7 @@ static void win_update(win_T *wp, Providers *providers)
}
}
}
+ }
(void)hasFoldingWin(wp, mod_top, &mod_top, NULL, true, NULL);
if (mod_top > lnumt) {
@@ -913,16 +920,18 @@ static void win_update(win_T *wp, Providers *providers)
* If the end of the change is above w_topline: do like no change was
* made, but redraw the first line to find changes in syntax. */
if (mod_top != 0 && mod_top < wp->w_topline) {
- if (mod_bot > wp->w_topline)
+ if (mod_bot > wp->w_topline) {
mod_top = wp->w_topline;
- else if (syntax_present(wp))
+ } else if (syntax_present(wp)) {
top_end = 1;
+ }
}
/* When line numbers are displayed need to redraw all lines below
* inserted/deleted lines. */
- if (mod_top != 0 && buf->b_mod_xlines != 0 && wp->w_p_nu)
+ if (mod_top != 0 && buf->b_mod_xlines != 0 && wp->w_p_nu) {
mod_bot = MAXLNUM;
+ }
}
wp->w_redraw_top = 0; // reset for next time
wp->w_redraw_bot = 0;
@@ -940,12 +949,13 @@ static void win_update(win_T *wp, Providers *providers)
break;
}
}
- if (top_end == 0)
- /* not found (cannot happen?): redraw everything */
+ if (top_end == 0) {
+ // not found (cannot happen?): redraw everything
type = NOT_VALID;
- else
- /* top area defined, the rest is VALID */
+ } else {
+ // top area defined, the rest is VALID
type = VALID;
+ }
}
/*
@@ -958,8 +968,7 @@ static void win_update(win_T *wp, Providers *providers)
*/
if ((type == VALID || type == SOME_VALID
|| type == INVERTED || type == INVERTED_ALL)
- && !wp->w_botfill && !wp->w_old_botfill
- ) {
+ && !wp->w_botfill && !wp->w_old_botfill) {
if (mod_top != 0
&& wp->w_topline == mod_top
&& (!wp->w_lines[0].wl_valid
@@ -987,14 +996,15 @@ static void win_update(win_T *wp, Providers *providers)
}
(void)hasFoldingWin(wp, ln, NULL, &ln, true, NULL);
}
- } else
+ } else {
j = wp->w_lines[0].wl_lnum - wp->w_topline;
+ }
if (j < wp->w_grid.Rows - 2) { // not too far off
i = plines_m_win(wp, wp->w_topline, wp->w_lines[0].wl_lnum - 1);
- /* insert extra lines for previously invisible filler lines */
- if (wp->w_lines[0].wl_lnum != wp->w_topline)
- i += diff_check_fill(wp, wp->w_lines[0].wl_lnum)
- - wp->w_old_topfill;
+ // insert extra lines for previously invisible filler lines
+ if (wp->w_lines[0].wl_lnum != wp->w_topline) {
+ i += win_get_fill(wp, wp->w_lines[0].wl_lnum) - wp->w_old_topfill;
+ }
if (i != 0 && i < wp->w_grid.Rows - 2) { // less than a screen off
// Try to insert the correct number of lines.
// If not the last window, delete the lines at the bottom.
@@ -1031,7 +1041,7 @@ static void win_update(win_T *wp, Providers *providers)
* needs updating.
*/
- /* try to find wp->w_topline in wp->w_lines[].wl_lnum */
+ // try to find wp->w_topline in wp->w_lines[].wl_lnum
j = -1;
row = 0;
for (i = 0; i < wp->w_lines_valid; i++) {
@@ -1053,11 +1063,12 @@ static void win_update(win_T *wp, Providers *providers)
*/
/* If the topline didn't change, delete old filler lines,
* otherwise delete filler lines of the new topline... */
- if (wp->w_lines[0].wl_lnum == wp->w_topline)
+ if (wp->w_lines[0].wl_lnum == wp->w_topline) {
row += wp->w_old_topfill;
- else
- row += diff_check_fill(wp, wp->w_topline);
- /* ... but don't delete new filler lines. */
+ } else {
+ row += win_get_fill(wp, wp->w_topline);
+ }
+ // ... but don't delete new filler lines.
row -= wp->w_topfill;
if (row > 0) {
win_scroll_lines(wp, 0, -row);
@@ -1066,7 +1077,7 @@ static void win_update(win_T *wp, Providers *providers)
if ((row == 0 || bot_start < 999) && wp->w_lines_valid != 0) {
/*
* Skip the lines (below the deleted lines) that are still
- * valid and don't need redrawing. Copy their info
+ * valid and don't need redrawing. Copy their info
* upwards, to compensate for the deleted lines. Set
* bot_start to the first row that needs redrawing.
*/
@@ -1083,18 +1094,19 @@ static void win_update(win_T *wp, Providers *providers)
}
bot_start += wp->w_lines[idx++].wl_size;
- /* stop at the last valid entry in w_lines[].wl_size */
+ // stop at the last valid entry in w_lines[].wl_size
if (++j >= wp->w_lines_valid) {
wp->w_lines_valid = idx;
break;
}
}
- /* Correct the first entry for filler lines at the top
- * when it won't get updated below. */
- if (wp->w_p_diff && bot_start > 0)
- wp->w_lines[0].wl_size =
- plines_win_nofill(wp, wp->w_topline, true)
- + wp->w_topfill;
+
+ // Correct the first entry for filler lines at the top
+ // when it won't get updated below.
+ if (win_may_fill(wp) && bot_start > 0) {
+ wp->w_lines[0].wl_size = (plines_win_nofill(wp, wp->w_topline, true)
+ + wp->w_topfill);
+ }
}
}
}
@@ -1104,19 +1116,19 @@ static void win_update(win_T *wp, Providers *providers)
mid_end = wp->w_grid.Rows;
}
} else {
- /* Not VALID or INVERTED: redraw all lines. */
+ // Not VALID or INVERTED: redraw all lines.
mid_start = 0;
mid_end = wp->w_grid.Rows;
}
if (type == SOME_VALID) {
- /* SOME_VALID: redraw all lines. */
+ // SOME_VALID: redraw all lines.
mid_start = 0;
mid_end = wp->w_grid.Rows;
type = NOT_VALID;
}
- /* check if we are updating or removing the inverted part */
+ // check if we are updating or removing the inverted part
if ((VIsual_active && buf == curwin->w_buffer)
|| (wp->w_old_cursor_lnum != 0 && type != NOT_VALID)) {
linenr_T from, to;
@@ -1133,15 +1145,19 @@ static void win_update(win_T *wp, Providers *providers)
from = VIsual.lnum;
to = curwin->w_cursor.lnum;
}
- /* redraw more when the cursor moved as well */
- if (wp->w_old_cursor_lnum < from)
+ // redraw more when the cursor moved as well
+ if (wp->w_old_cursor_lnum < from) {
from = wp->w_old_cursor_lnum;
- if (wp->w_old_cursor_lnum > to)
+ }
+ if (wp->w_old_cursor_lnum > to) {
to = wp->w_old_cursor_lnum;
- if (wp->w_old_visual_lnum < from)
+ }
+ if (wp->w_old_visual_lnum < from) {
from = wp->w_old_visual_lnum;
- if (wp->w_old_visual_lnum > to)
+ }
+ if (wp->w_old_visual_lnum > to) {
to = wp->w_old_visual_lnum;
+ }
} else {
/*
* Find the line numbers that need to be updated: The lines
@@ -1154,21 +1170,26 @@ static void win_update(win_T *wp, Providers *providers)
} else {
from = wp->w_old_cursor_lnum;
to = curwin->w_cursor.lnum;
- if (from == 0) /* Visual mode just started */
+ if (from == 0) { // Visual mode just started
from = to;
+ }
}
if (VIsual.lnum != wp->w_old_visual_lnum
|| VIsual.col != wp->w_old_visual_col) {
if (wp->w_old_visual_lnum < from
- && wp->w_old_visual_lnum != 0)
+ && wp->w_old_visual_lnum != 0) {
from = wp->w_old_visual_lnum;
- if (wp->w_old_visual_lnum > to)
+ }
+ if (wp->w_old_visual_lnum > to) {
to = wp->w_old_visual_lnum;
- if (VIsual.lnum < from)
+ }
+ if (VIsual.lnum < from) {
from = VIsual.lnum;
- if (VIsual.lnum > to)
+ }
+ if (VIsual.lnum > to) {
to = VIsual.lnum;
+ }
}
}
@@ -1181,27 +1202,33 @@ static void win_update(win_T *wp, Providers *providers)
colnr_T fromc, toc;
int save_ve_flags = ve_flags;
- if (curwin->w_p_lbr)
+ if (curwin->w_p_lbr) {
ve_flags = VE_ALL;
+ }
getvcols(wp, &VIsual, &curwin->w_cursor, &fromc, &toc);
ve_flags = save_ve_flags;
- ++toc;
- if (curwin->w_curswant == MAXCOL)
+ toc++;
+ // Highlight to the end of the line, unless 'virtualedit' has
+ // "block".
+ if (curwin->w_curswant == MAXCOL && !(ve_flags & VE_BLOCK)) {
toc = MAXCOL;
+ }
if (fromc != wp->w_old_cursor_fcol
|| toc != wp->w_old_cursor_lcol) {
- if (from > VIsual.lnum)
+ if (from > VIsual.lnum) {
from = VIsual.lnum;
- if (to < VIsual.lnum)
+ }
+ if (to < VIsual.lnum) {
to = VIsual.lnum;
+ }
}
wp->w_old_cursor_fcol = fromc;
wp->w_old_cursor_lcol = toc;
}
} else {
- /* Use the line numbers of the old Visual area. */
+ // Use the line numbers of the old Visual area.
if (wp->w_old_cursor_lnum < wp->w_old_visual_lnum) {
from = wp->w_old_cursor_lnum;
to = wp->w_old_visual_lnum;
@@ -1214,18 +1241,21 @@ static void win_update(win_T *wp, Providers *providers)
/*
* There is no need to update lines above the top of the window.
*/
- if (from < wp->w_topline)
+ if (from < wp->w_topline) {
from = wp->w_topline;
+ }
/*
* If we know the value of w_botline, use it to restrict the update to
* the lines that are visible in the window.
*/
if (wp->w_valid & VALID_BOTLINE) {
- if (from >= wp->w_botline)
+ if (from >= wp->w_botline) {
from = wp->w_botline - 1;
- if (to >= wp->w_botline)
+ }
+ if (to >= wp->w_botline) {
to = wp->w_botline - 1;
+ }
}
/*
@@ -1241,27 +1271,30 @@ static void win_update(win_T *wp, Providers *providers)
lnum = wp->w_topline;
idx = 0;
srow = 0;
- if (scrolled_down)
+ if (scrolled_down) {
mid_start = top_end;
- else
+ } else {
mid_start = 0;
- while (lnum < from && idx < wp->w_lines_valid) { /* find start */
- if (wp->w_lines[idx].wl_valid)
+ }
+ while (lnum < from && idx < wp->w_lines_valid) { // find start
+ if (wp->w_lines[idx].wl_valid) {
mid_start += wp->w_lines[idx].wl_size;
- else if (!scrolled_down)
+ } else if (!scrolled_down) {
srow += wp->w_lines[idx].wl_size;
+ }
++idx;
- if (idx < wp->w_lines_valid && wp->w_lines[idx].wl_valid)
+ if (idx < wp->w_lines_valid && wp->w_lines[idx].wl_valid) {
lnum = wp->w_lines[idx].wl_lnum;
- else
+ } else {
++lnum;
+ }
}
srow += mid_start;
mid_end = wp->w_grid.Rows;
for (; idx < wp->w_lines_valid; idx++) { // find end
if (wp->w_lines[idx].wl_valid
&& wp->w_lines[idx].wl_lnum >= to + 1) {
- /* Only update until first row of this line */
+ // Only update until first row of this line
mid_end = srow;
break;
}
@@ -1283,7 +1316,7 @@ static void win_update(win_T *wp, Providers *providers)
wp->w_old_visual_col = 0;
}
- /* reset got_int, otherwise regexp won't work */
+ // reset got_int, otherwise regexp won't work
save_got_int = got_int;
got_int = 0;
// Set the time limit to 'redrawtime'.
@@ -1293,7 +1326,7 @@ static void win_update(win_T *wp, Providers *providers)
/*
* Update all the window rows.
*/
- idx = 0; /* first entry in w_lines[].wl_size */
+ idx = 0; // first entry in w_lines[].wl_size
row = 0;
srow = 0;
lnum = wp->w_topline; // first line shown in window
@@ -1333,9 +1366,9 @@ static void win_update(win_T *wp, Providers *providers)
break;
}
- /* stop updating when hit the end of the file */
+ // stop updating when hit the end of the file
if (lnum > buf->b_ml.ml_line_count) {
- eof = TRUE;
+ eof = true;
break;
}
@@ -1368,7 +1401,9 @@ static void win_update(win_T *wp, Providers *providers)
// match in fixed position might need redraw
// if lines were inserted or deleted
|| (wp->w_match_head != NULL
- && buf->b_mod_xlines != 0)))))) {
+ && buf->b_mod_xlines != 0)))))
+ || (wp->w_p_cul && (lnum == wp->w_cursor.lnum
+ || lnum == wp->w_last_cursorline))) {
if (lnum == mod_top) {
top_to_mod = false;
}
@@ -1378,10 +1413,12 @@ static void win_update(win_T *wp, Providers *providers)
* up or down to minimize redrawing.
* Don't do this when the change continues until the end.
* Don't scroll when dollar_vcol >= 0, keep the "$".
+ * Don't scroll when redrawing the top, scrolled already above.
*/
if (lnum == mod_top
&& mod_bot != MAXLNUM
- && !(dollar_vcol >= 0 && mod_bot == mod_top + 1)) {
+ && !(dollar_vcol >= 0 && mod_bot == mod_top + 1)
+ && row >= top_end) {
int old_rows = 0;
int new_rows = 0;
int xtra_rows;
@@ -1394,8 +1431,9 @@ static void win_update(win_T *wp, Providers *providers)
/* Only valid lines have a meaningful wl_lnum. Invalid
* lines are part of the changed area. */
if (wp->w_lines[i].wl_valid
- && wp->w_lines[i].wl_lnum == mod_bot)
+ && wp->w_lines[i].wl_lnum == mod_bot) {
break;
+ }
old_rows += wp->w_lines[i].wl_size;
if (wp->w_lines[i].wl_valid
&& wp->w_lines[i].wl_lastlnum + 1 == mod_bot) {
@@ -1403,8 +1441,9 @@ static void win_update(win_T *wp, Providers *providers)
* Add following invalid entries. */
++i;
while (i < wp->w_lines_valid
- && !wp->w_lines[i].wl_valid)
+ && !wp->w_lines[i].wl_valid) {
old_rows += wp->w_lines[i++].wl_size;
+ }
break;
}
}
@@ -1467,15 +1506,15 @@ static void win_update(win_T *wp, Providers *providers)
if (j < i) {
int x = row + new_rows;
- /* move entries in w_lines[] upwards */
+ // move entries in w_lines[] upwards
for (;; ) {
- /* stop at last valid entry in w_lines[] */
+ // stop at last valid entry in w_lines[]
if (i >= wp->w_lines_valid) {
wp->w_lines_valid = j;
break;
}
wp->w_lines[j] = wp->w_lines[i];
- /* stop at a line that won't fit */
+ // stop at a line that won't fit
if (x + (int)wp->w_lines[j].wl_size
> wp->w_grid.Rows) {
wp->w_lines_valid = j + 1;
@@ -1484,10 +1523,11 @@ static void win_update(win_T *wp, Providers *providers)
x += wp->w_lines[j++].wl_size;
++i;
}
- if (bot_start > x)
+ if (bot_start > x) {
bot_start = x;
- } else { /* j > i */
- /* move entries in w_lines[] downwards */
+ }
+ } else { // j > i
+ // move entries in w_lines[] downwards
j -= i;
wp->w_lines_valid += j;
if (wp->w_lines_valid > wp->w_grid.Rows) {
@@ -1523,17 +1563,17 @@ static void win_update(win_T *wp, Providers *providers)
&& lnum > wp->w_topline
&& !(dy_flags & (DY_LASTLINE | DY_TRUNCATE))
&& srow + wp->w_lines[idx].wl_size > wp->w_grid.Rows
- && diff_check_fill(wp, lnum) == 0
- ) {
+ && win_get_fill(wp, lnum) == 0) {
// This line is not going to fit. Don't draw anything here,
// will draw "@ " lines below.
row = wp->w_grid.Rows + 1;
} else {
prepare_search_hl(wp, lnum);
- /* Let the syntax stuff know we skipped a few lines. */
+ // Let the syntax stuff know we skipped a few lines.
if (syntax_last_parsed != 0 && syntax_last_parsed + 1 < lnum
- && syntax_present(wp))
+ && syntax_present(wp)) {
syntax_end_parsing(syntax_last_parsed + 1);
+ }
// Display one line
row = win_line(wp, lnum, srow,
@@ -1588,7 +1628,7 @@ static void win_update(win_T *wp, Providers *providers)
}
if (lnum > buf->b_ml.ml_line_count) {
- eof = TRUE;
+ eof = true;
break;
}
}
@@ -1597,14 +1637,16 @@ static void win_update(win_T *wp, Providers *providers)
*/
- if (idx > wp->w_lines_valid)
+ if (idx > wp->w_lines_valid) {
wp->w_lines_valid = idx;
+ }
/*
* Let the syntax stuff know we stop parsing here.
*/
- if (syntax_last_parsed != 0 && syntax_present(wp))
+ if (syntax_last_parsed != 0 && syntax_present(wp)) {
syntax_end_parsing(syntax_last_parsed + 1);
+ }
/*
* If we didn't hit the end of the file, and we didn't finish the last
@@ -1621,7 +1663,7 @@ static void win_update(win_T *wp, Providers *providers)
* Don't overwrite it, it can be edited.
*/
wp->w_botline = lnum + 1;
- } else if (diff_check_fill(wp, lnum) >= wp->w_grid.Rows - srow) {
+ } else if (win_get_fill(wp, lnum) >= wp->w_grid.Rows - srow) {
// Window ends in filler lines.
wp->w_botline = lnum;
wp->w_filler_rows = wp->w_grid.Rows - srow;
@@ -1648,22 +1690,17 @@ static void win_update(win_T *wp, Providers *providers)
} else {
if (eof) { // we hit the end of the file
wp->w_botline = buf->b_ml.ml_line_count + 1;
- j = diff_check_fill(wp, wp->w_botline);
+ j = win_get_fill(wp, wp->w_botline);
if (j > 0 && !wp->w_botfill) {
- // display filler lines at the end of the file
- if (char2cells(wp->w_p_fcs_chars.diff) > 1) {
- i = '-';
- } else {
- i = wp->w_p_fcs_chars.diff;
- }
- if (row + j > wp->w_grid.Rows) {
- j = wp->w_grid.Rows - row;
- }
- win_draw_end(wp, i, i, true, row, row + (int)j, HLF_DED);
- row += j;
+ // Display filler text below last line. win_line() will check
+ // for ml_line_count+1 and only draw filler lines
+ foldinfo_T info = FOLDINFO_INIT;
+ row = win_line(wp, wp->w_botline, row, wp->w_grid.Rows,
+ false, false, info, &line_providers);
}
- } else if (dollar_vcol == -1)
+ } else if (dollar_vcol == -1) {
wp->w_botline = lnum;
+ }
// make sure the rest of the screen is blank
// write the 'eob' character to rows that aren't part of the file.
@@ -1678,7 +1715,7 @@ static void win_update(win_T *wp, Providers *providers)
}
syn_set_timeout(NULL);
- /* Reset the type of redrawing required, the window has been updated. */
+ // Reset the type of redrawing required, the window has been updated.
wp->w_redr_type = 0;
wp->w_old_topfill = wp->w_topfill;
wp->w_old_botfill = wp->w_botfill;
@@ -1687,7 +1724,7 @@ static void win_update(win_T *wp, Providers *providers)
/*
* There is a trick with w_botline. If we invalidate it on each
* change that might modify it, this will cause a lot of expensive
- * calls to plines() in update_topline() each time. Therefore the
+ * calls to plines_win() in update_topline() each time. Therefore the
* value of w_botline is often approximated, and this value is used to
* compute the value of w_topline. If the value of w_botline was
* wrong, check that the value of w_topline is correct (cursor is on
@@ -1699,58 +1736,26 @@ static void win_update(win_T *wp, Providers *providers)
wp->w_valid |= VALID_BOTLINE;
wp->w_viewport_invalid = true;
if (wp == curwin && wp->w_botline != old_botline && !recursive) {
- const linenr_T old_topline = wp->w_topline;
- const int new_wcol = wp->w_wcol;
recursive = true;
curwin->w_valid &= ~VALID_TOPLINE;
update_topline(curwin); // may invalidate w_botline again
-
- if (old_wcol != new_wcol
- && (wp->w_valid & (VALID_WCOL|VALID_WROW))
- != (VALID_WCOL|VALID_WROW)) {
- // A win_line() call applied a fix to screen cursor column to
- // accommodate concealment of cursor line, but in this call to
- // update_topline() the cursor's row or column got invalidated.
- // If they are left invalid, setcursor() will recompute them
- // but there won't be any further win_line() call to re-fix the
- // column and the cursor will end up misplaced. So we call
- // cursor validation now and reapply the fix again (or call
- // win_line() to do it for us).
- validate_cursor();
- if (wp->w_wcol == old_wcol
- && wp->w_wrow == old_wrow
- && old_topline == wp->w_topline) {
- wp->w_wcol = new_wcol;
- } else {
- redrawWinline(wp, wp->w_cursor.lnum);
- }
- }
- // New redraw either due to updated topline or due to wcol fix.
- if (wp->w_redr_type != 0) {
+ if (must_redraw != 0) {
// Don't update for changes in buffer again.
i = curbuf->b_mod_set;
curbuf->b_mod_set = false;
- j = curbuf->b_mod_xlines;
- curbuf->b_mod_xlines = 0;
win_update(curwin, providers);
+ must_redraw = 0;
curbuf->b_mod_set = i;
- curbuf->b_mod_xlines = j;
- }
- // Other windows might have w_redr_type raised in update_topline().
- must_redraw = 0;
- FOR_ALL_WINDOWS_IN_TAB(wwp, curtab) {
- if (wwp->w_redr_type > must_redraw) {
- must_redraw = wwp->w_redr_type;
- }
}
recursive = false;
}
}
- /* restore got_int, unless CTRL-C was hit while redrawing */
- if (!got_int)
+ // restore got_int, unless CTRL-C was hit while redrawing
+ if (!got_int) {
got_int = save_got_int;
+ }
} // NOLINT(readability/fn_size)
/// Returns width of the signcolumn that should be used for the whole window
@@ -1770,8 +1775,8 @@ int win_signcol_width(win_T *wp)
/// Call grid_fill() with columns adjusted for 'rightleft' if needed.
/// Return the new offset.
-static int win_fill_end(win_T *wp, int c1, int c2, int off, int width, int row,
- int endrow, int attr)
+static int win_fill_end(win_T *wp, int c1, int c2, int off, int width, int row, int endrow,
+ int attr)
{
int nn = off + width;
@@ -1792,8 +1797,7 @@ static int win_fill_end(win_T *wp, int c1, int c2, int off, int width, int row,
/// Clear lines near the end of the window and mark the unused lines with "c1".
/// Use "c2" as filler character.
/// When "draw_margin" is true, then draw the sign/fold/number columns.
-static void win_draw_end(win_T *wp, int c1, int c2, bool draw_margin, int row,
- int endrow, hlf_T hl)
+static void win_draw_end(win_T *wp, int c1, int c2, bool draw_margin, int row, int endrow, hlf_T hl)
{
assert(hl >= 0 && hl < HLF_COUNT);
int n = 0;
@@ -1833,13 +1837,14 @@ static void win_draw_end(win_T *wp, int c1, int c2, bool draw_margin, int row,
}
-/*
- * Advance **color_cols and return TRUE when there are columns to draw.
- */
-static int advance_color_col(int vcol, int **color_cols)
+/// Advance **color_cols
+///
+/// @return true when there are columns to draw.
+static bool advance_color_col(int vcol, int **color_cols)
{
- while (**color_cols >= 0 && vcol > **color_cols)
+ while (**color_cols >= 0 && vcol > **color_cols) {
++*color_cols;
+ }
return **color_cols >= 0;
}
@@ -1860,7 +1865,7 @@ static int compute_foldcolumn(win_T *wp, int col)
/// Put a single char from an UTF-8 buffer into a line buffer.
///
/// Handles composing chars and arabic shaping state.
-static int line_putchar(LineState *s, schar_T *dest, int maxcells, bool rl)
+static int line_putchar(buf_T *buf, LineState *s, schar_T *dest, int maxcells, bool rl, int vcol)
{
const char_u *p = (char_u *)s->p;
int cells = utf_ptr2cells(p);
@@ -1870,7 +1875,13 @@ static int line_putchar(LineState *s, schar_T *dest, int maxcells, bool rl)
return -1;
}
u8c = utfc_ptr2char(p, u8cc);
- if (*p < 0x80 && u8cc[0] == 0) {
+ if (*p == TAB) {
+ cells = MIN(tabstop_padding(vcol, buf->b_p_ts, buf->b_p_vts_array), maxcells);
+ for (int c = 0; c < cells; c++) {
+ schar_from_ascii(dest[c], ' ');
+ }
+ goto done;
+ } else if (*p < 0x80 && u8cc[0] == 0) {
schar_from_ascii(dest[0], *p);
s->prev_c = u8c;
} else {
@@ -1903,6 +1914,7 @@ static int line_putchar(LineState *s, schar_T *dest, int maxcells, bool rl)
if (cells > 1) {
dest[1][0] = 0;
}
+done:
s->p += c_len;
return cells;
}
@@ -1917,13 +1929,7 @@ static int line_putchar(LineState *s, schar_T *dest, int maxcells, bool rl)
///
/// Assume monocell characters
/// @return number of chars added to \param p
-static size_t
-fill_foldcolumn(
- char_u *p,
- win_T *wp,
- foldinfo_T foldinfo,
- linenr_T lnum
-)
+static size_t fill_foldcolumn(char_u *p, win_T *wp, foldinfo_T foldinfo, linenr_T lnum)
{
int i = 0;
int level;
@@ -1992,24 +1998,23 @@ fill_foldcolumn(
/// or explicitly return `false`.
///
/// @return the number of last row the line occupies.
-static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
- bool nochange, bool number_only, foldinfo_T foldinfo,
- Providers *providers)
+static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
+ bool number_only, foldinfo_T foldinfo, Providers *providers)
{
int c = 0; // init for GCC
long vcol = 0; // virtual column (for tabs)
long vcol_sbr = -1; // virtual column after showbreak
long vcol_prev = -1; // "vcol" of previous character
- char_u *line; // current line
- char_u *ptr; // current position in "line"
+ char_u *line; // current line
+ char_u *ptr; // current position in "line"
int row; // row in the window, excl w_winrow
- ScreenGrid *grid = &wp->w_grid; // grid specfic to the window
+ ScreenGrid *grid = &wp->w_grid; // grid specific to the window
char_u extra[57]; // sign, line number and 'fdc' must
// fit in here
int n_extra = 0; // number of extra chars
- char_u *p_extra = NULL; // string of extra chars, plus NUL
- char_u *p_extra_free = NULL; // p_extra needs to be freed
+ char_u *p_extra = NULL; // string of extra chars, plus NUL
+ char_u *p_extra_free = NULL; // p_extra needs to be freed
int c_extra = NUL; // extra chars, all the same
int c_final = NUL; // final char, mandatory if set
int extra_attr = 0; // attributes when n_extra != 0
@@ -2022,49 +2027,48 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
// saved "extra" items for when draw_state becomes WL_LINE (again)
int saved_n_extra = 0;
- char_u *saved_p_extra = NULL;
+ char_u *saved_p_extra = NULL;
int saved_c_extra = 0;
int saved_c_final = 0;
int saved_char_attr = 0;
- int n_attr = 0; /* chars with special attr */
- int saved_attr2 = 0; /* char_attr saved for n_attr */
- int n_attr3 = 0; /* chars with overruling special attr */
- int saved_attr3 = 0; /* char_attr saved for n_attr3 */
+ int n_attr = 0; // chars with special attr
+ int saved_attr2 = 0; // char_attr saved for n_attr
+ int n_attr3 = 0; // chars with overruling special attr
+ int saved_attr3 = 0; // char_attr saved for n_attr3
- int n_skip = 0; /* nr of chars to skip for 'nowrap' */
+ int n_skip = 0; // nr of chars to skip for 'nowrap'
int fromcol = -10; // start of inverting
int tocol = MAXCOL; // end of inverting
int fromcol_prev = -2; // start of inverting after cursor
bool noinvcur = false; // don't invert the cursor
- int lnum_in_visual_area = false;
+ bool lnum_in_visual_area = false;
pos_T pos;
long v;
- int char_attr = 0; /* attributes for next character */
- int attr_pri = FALSE; /* char_attr has priority */
- int area_highlighting = FALSE; /* Visual or incsearch highlighting
- in this line */
- int attr = 0; /* attributes for area highlighting */
- int area_attr = 0; /* attributes desired by highlighting */
- int search_attr = 0; /* attributes desired by 'hlsearch' */
- int vcol_save_attr = 0; /* saved attr for 'cursorcolumn' */
- int syntax_attr = 0; /* attributes desired by syntax */
- int has_syntax = FALSE; /* this buffer has syntax highl. */
+ int char_attr = 0; // attributes for next character
+ bool attr_pri = false; // char_attr has priority
+ bool area_highlighting = false; // Visual or incsearch highlighting in this line
+ int attr = 0; // attributes for area highlighting
+ int area_attr = 0; // attributes desired by highlighting
+ int search_attr = 0; // attributes desired by 'hlsearch'
+ int vcol_save_attr = 0; // saved attr for 'cursorcolumn'
+ int syntax_attr = 0; // attributes desired by syntax
+ int has_syntax = FALSE; // this buffer has syntax highl.
int save_did_emsg;
int eol_hl_off = 0; // 1 if highlighted char after EOL
- int draw_color_col = false; // highlight colorcolumn
+ bool draw_color_col = false; // highlight colorcolumn
int *color_cols = NULL; // pointer to according columns array
bool has_spell = false; // this buffer has spell checking
-# define SPWORDLEN 150
- char_u nextline[SPWORDLEN * 2]; /* text with start of the next line */
- int nextlinecol = 0; /* column where nextline[] starts */
+#define SPWORDLEN 150
+ char_u nextline[SPWORDLEN * 2]; // text with start of the next line
+ int nextlinecol = 0; // column where nextline[] starts
int nextline_idx = 0; /* index in nextline[] where next line
starts */
- int spell_attr = 0; /* attributes desired by spelling */
- int word_end = 0; /* last byte with same spell_attr */
- static linenr_T checked_lnum = 0; /* line number for "checked_col" */
+ int spell_attr = 0; // attributes desired by spelling
+ int word_end = 0; // last byte with same spell_attr
+ static linenr_T checked_lnum = 0; // line number for "checked_col"
static int checked_col = 0; /* column in "checked_lnum" up to which
* there are no spell errors */
static int cap_col = -1; // column to check for Cap word
@@ -2083,13 +2087,17 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
int change_end = -1; // last col of changed area
colnr_T trailcol = MAXCOL; // start of trailing spaces
colnr_T leadcol = 0; // start of leading spaces
+ bool in_multispace = false; // in multiple consecutive spaces
+ int multispace_pos = 0; // position in lcs-multispace string
bool need_showbreak = false; // overlong line, skip first x chars
sign_attrs_T sattrs[SIGN_SHOW_MAX]; // attributes for signs
int num_signs; // number of signs for line
int line_attr = 0; // attribute for the whole line
+ int line_attr_save;
int line_attr_lowprio = 0; // low-priority attribute for the line
+ int line_attr_lowprio_save;
matchitem_T *cur; // points to the match list
- match_T *shl; // points to search_hl or a match
+ match_T *shl; // points to search_hl or a match
bool shl_flag; // flag to indicate whether search_hl
// has been processed or not
bool prevcol_hl_flag; // flag to indicate whether prevcol
@@ -2100,37 +2108,44 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
bool search_attr_from_match = false; // if search_attr is from :match
bool has_decor = false; // this buffer has decoration
- bool do_virttext = false; // draw virtual text for this line
int win_col_offset = 0; // offset for window columns
char_u buf_fold[FOLD_TEXT_LEN + 1]; // Hold value returned by get_foldtext
bool area_active = false;
- /* draw_state: items that are drawn in sequence: */
-#define WL_START 0 /* nothing done yet */
-# define WL_CMDLINE WL_START + 1 /* cmdline window column */
-# define WL_FOLD WL_CMDLINE + 1 /* 'foldcolumn' */
-# define WL_SIGN WL_FOLD + 1 /* column for signs */
-#define WL_NR WL_SIGN + 1 /* line number */
-# define WL_BRI WL_NR + 1 /* 'breakindent' */
-# define WL_SBR WL_BRI + 1 /* 'showbreak' or 'diff' */
-#define WL_LINE WL_SBR + 1 /* text in the line */
- int draw_state = WL_START; /* what to draw next */
+ int cul_attr = 0; // set when 'cursorline' active
+ // 'cursorlineopt' has "screenline" and cursor is in this line
+ bool cul_screenline = false;
+ // margin columns for the screen line, needed for when 'cursorlineopt'
+ // contains "screenline"
+ int left_curline_col = 0;
+ int right_curline_col = 0;
+
+ // draw_state: items that are drawn in sequence:
+#define WL_START 0 // nothing done yet
+#define WL_CMDLINE WL_START + 1 // cmdline window column
+#define WL_FOLD WL_CMDLINE + 1 // 'foldcolumn'
+#define WL_SIGN WL_FOLD + 1 // column for signs
+#define WL_NR WL_SIGN + 1 // line number
+#define WL_BRI WL_NR + 1 // 'breakindent'
+#define WL_SBR WL_BRI + 1 // 'showbreak' or 'diff'
+#define WL_LINE WL_SBR + 1 // text in the line
+ int draw_state = WL_START; // what to draw next
int syntax_flags = 0;
int syntax_seqnr = 0;
int prev_syntax_id = 0;
int conceal_attr = win_hl_attr(wp, HLF_CONCEAL);
- int is_concealing = false;
+ bool is_concealing = false;
int boguscols = 0; ///< nonexistent columns added to
///< force wrapping
int vcol_off = 0; ///< offset for concealed characters
int did_wcol = false;
int match_conc = 0; ///< cchar for match functions
int old_boguscols = 0;
-# define VCOL_HLC (vcol - vcol_off)
-# define FIX_FOR_BOGUSCOLS \
+#define VCOL_HLC (vcol - vcol_off)
+#define FIX_FOR_BOGUSCOLS \
{ \
n_extra += vcol_off; \
vcol -= vcol_off; \
@@ -2140,14 +2155,14 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
boguscols = 0; \
}
- if (startrow > endrow) /* past the end already! */
+ if (startrow > endrow) { // past the end already!
return startrow;
+ }
row = startrow;
- char *err_text = NULL;
-
buf_T *buf = wp->w_buffer;
+ bool end_fill = (lnum == buf->b_ml.ml_line_count+1);
if (!number_only) {
// To speed up the loop below, set extra_check when there is linebreak,
@@ -2191,14 +2206,20 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
}
}
- if (has_decor) {
- extra_check = true;
+ if (provider_err) {
+ Decoration err_decor = DECORATION_INIT;
+ int hl_err = syn_check_group((char_u *)S_LEN("ErrorMsg"));
+ kv_push(err_decor.virt_text,
+ ((VirtTextChunk){ .text = provider_err,
+ .hl_id = hl_err }));
+ err_decor.virt_text_width = mb_string2cells((char_u *)provider_err);
+ decor_add_ephemeral(lnum-1, 0, lnum-1, 0, &err_decor);
+ provider_err = NULL;
+ has_decor = true;
}
- if (provider_first_error) {
- err_text = provider_first_error;
- provider_first_error = NULL;
- do_virttext = true;
+ if (has_decor) {
+ extra_check = true;
}
// Check for columns to display for 'colorcolumn'.
@@ -2209,6 +2230,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
if (wp->w_p_spell
&& !has_fold
+ && !end_fill
&& *wp->w_s->b_p_spl != NUL
&& !GA_EMPTY(&wp->w_s->b_langp)
&& *(char **)(wp->w_s->b_langp.ga_data) != NULL) {
@@ -2308,7 +2330,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
area_highlighting = true;
attr = win_hl_attr(wp, HLF_V);
}
- // handle 'incsearch' and ":s///c" highlighting
+ // handle 'incsearch' and ":s///c" highlighting
} else if (highlight_match
&& wp == curwin
&& !has_fold
@@ -2337,42 +2359,55 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
filler_lines = diff_check(wp, lnum);
if (filler_lines < 0) {
if (filler_lines == -1) {
- if (diff_find_change(wp, lnum, &change_start, &change_end))
- diff_hlf = HLF_ADD; /* added line */
- else if (change_start == 0)
- diff_hlf = HLF_TXD; /* changed text */
- else
- diff_hlf = HLF_CHD; /* changed line */
- } else
- diff_hlf = HLF_ADD; /* added line */
+ if (diff_find_change(wp, lnum, &change_start, &change_end)) {
+ diff_hlf = HLF_ADD; // added line
+ } else if (change_start == 0) {
+ diff_hlf = HLF_TXD; // changed text
+ } else {
+ diff_hlf = HLF_CHD; // changed line
+ }
+ } else {
+ diff_hlf = HLF_ADD; // added line
+ }
filler_lines = 0;
- area_highlighting = TRUE;
+ area_highlighting = true;
}
- if (lnum == wp->w_topline)
+ int virtual_lines = decor_virtual_lines(wp, lnum);
+ filler_lines += virtual_lines;
+ if (lnum == wp->w_topline) {
filler_lines = wp->w_topfill;
+ virtual_lines = MIN(virtual_lines, filler_lines);
+ }
filler_todo = filler_lines;
// Cursor line highlighting for 'cursorline' in the current window.
if (lnum == wp->w_cursor.lnum) {
- // Do not show the cursor line when Visual mode is active, because it's
- // not clear what is selected then.
- if (wp->w_p_cul && !(wp == curwin && VIsual_active)) {
- int cul_attr = win_hl_attr(wp, HLF_CUL);
- HlAttrs ae = syn_attr2entry(cul_attr);
-
- // We make a compromise here (#7383):
- // * low-priority CursorLine if fg is not set
- // * high-priority ("same as Vim" priority) CursorLine if fg is set
- if (ae.rgb_fg_color == -1 && ae.cterm_fg_color == 0) {
- line_attr_lowprio = cul_attr;
- } else {
- if (!(State & INSERT) && bt_quickfix(wp->w_buffer)
- && qf_current_entry(wp) == lnum) {
- line_attr = hl_combine_attr(cul_attr, line_attr);
+ // Do not show the cursor line in the text when Visual mode is active,
+ // because it's not clear what is selected then.
+ if (wp->w_p_cul && !(wp == curwin && VIsual_active)
+ && wp->w_p_culopt_flags != CULOPT_NBR) {
+ cul_screenline = (wp->w_p_wrap
+ && (wp->w_p_culopt_flags & CULOPT_SCRLINE));
+ if (!cul_screenline) {
+ cul_attr = win_hl_attr(wp, HLF_CUL);
+ HlAttrs ae = syn_attr2entry(cul_attr);
+ // We make a compromise here (#7383):
+ // * low-priority CursorLine if fg is not set
+ // * high-priority ("same as Vim" priority) CursorLine if fg is set
+ if (ae.rgb_fg_color == -1 && ae.cterm_fg_color == 0) {
+ line_attr_lowprio = cul_attr;
} else {
- line_attr = cul_attr;
+ if (!(State & INSERT) && bt_quickfix(wp->w_buffer)
+ && qf_current_entry(wp) == lnum) {
+ line_attr = hl_combine_attr(cul_attr, line_attr);
+ } else {
+ line_attr = cul_attr;
+ }
}
+ } else {
+ margin_columns_win(wp, &left_curline_col, &right_curline_col);
}
+ area_highlighting = true;
}
// Update w_last_cursorline even if Visual mode is active.
wp->w_last_cursorline = wp->w_cursor.lnum;
@@ -2397,7 +2432,12 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
area_highlighting = true;
}
- line = ml_get_buf(wp->w_buffer, lnum, FALSE);
+ if (cul_screenline) {
+ line_attr_save = line_attr;
+ line_attr_lowprio_save = line_attr_lowprio;
+ }
+
+ line = end_fill ? (char_u *)"" : ml_get_buf(wp->w_buffer, lnum, false);
ptr = line;
if (has_spell && !number_only) {
@@ -2410,7 +2450,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
* current line into nextline[]. Above the start of the next line was
* copied to nextline[SPWORDLEN]. */
if (nextline[SPWORDLEN] == NUL) {
- /* No next line or it is empty. */
+ // No next line or it is empty.
nextlinecol = MAXCOL;
nextline_idx = 0;
} else {
@@ -2423,7 +2463,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
STRMOVE(nextline + v, nextline + SPWORDLEN);
nextline_idx = v + 1;
} else {
- /* Long line, use only the last SPWORDLEN bytes. */
+ // Long line, use only the last SPWORDLEN bytes.
nextlinecol = v - SPWORDLEN;
memmove(nextline, line + nextlinecol, SPWORDLEN); // -V512
nextline_idx = SPWORDLEN + 1;
@@ -2431,8 +2471,9 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
}
}
- if (wp->w_p_list && !has_fold) {
+ if (wp->w_p_list && !has_fold && !end_fill) {
if (wp->w_p_lcs_chars.space
+ || wp->w_p_lcs_chars.multispace != NULL
|| wp->w_p_lcs_chars.trail
|| wp->w_p_lcs_chars.lead
|| wp->w_p_lcs_chars.nbsp) {
@@ -2444,7 +2485,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
while (trailcol > (colnr_T)0 && ascii_iswhite(ptr[trailcol - 1])) {
trailcol--;
}
- trailcol += (colnr_T) (ptr - line);
+ trailcol += (colnr_T)(ptr - line);
}
// find end of leading whitespace
if (wp->w_p_lcs_chars.lead) {
@@ -2466,12 +2507,13 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
* 'nowrap' or 'wrap' and a single line that doesn't fit: Advance to the
* first character to be displayed.
*/
- if (wp->w_p_wrap)
+ if (wp->w_p_wrap) {
v = wp->w_skipcol;
- else
+ } else {
v = wp->w_leftcol;
+ }
if (v > 0 && !number_only) {
- char_u *prev_ptr = ptr;
+ char_u *prev_ptr = ptr;
while (vcol < v && *ptr != NUL) {
c = win_lbr_chartabsize(wp, line, ptr, (colnr_T)vcol, NULL);
vcol += c;
@@ -2508,10 +2550,11 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
* Adjust for when the inverted text is before the screen,
* and when the start of the inverted text is before the screen.
*/
- if (tocol <= vcol)
+ if (tocol <= vcol) {
fromcol = 0;
- else if (fromcol >= 0 && fromcol < vcol)
+ } else if (fromcol >= 0 && fromcol < vcol) {
fromcol = vcol;
+ }
// When w_skipcol is non-zero, first line needs 'showbreak'
if (wp->w_p_wrap) {
@@ -2527,10 +2570,10 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
pos = wp->w_cursor;
wp->w_cursor.lnum = lnum;
wp->w_cursor.col = linecol;
- len = spell_move_to(wp, FORWARD, TRUE, TRUE, &spell_hlf);
+ len = spell_move_to(wp, FORWARD, true, true, &spell_hlf);
- /* spell_move_to() may call ml_get() and make "line" invalid */
- line = ml_get_buf(wp->w_buffer, lnum, FALSE);
+ // spell_move_to() may call ml_get() and make "line" invalid
+ line = ml_get_buf(wp->w_buffer, lnum, false);
ptr = line + linecol;
if (len == 0 || (int)wp->w_cursor.col > ptr - line) {
@@ -2539,13 +2582,14 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
spell_hlf = HLF_COUNT;
word_end = (int)(spell_to_word_end(ptr, wp) - line + 1);
} else {
- /* bad word found, use attributes until end of word */
+ // bad word found, use attributes until end of word
assert(len <= INT_MAX);
word_end = wp->w_cursor.col + (int)len + 1;
- /* Turn index into actual attributes. */
- if (spell_hlf != HLF_COUNT)
+ // Turn index into actual attributes.
+ if (spell_hlf != HLF_COUNT) {
spell_attr = highlight_attr[spell_hlf];
+ }
}
wp->w_cursor = pos;
@@ -2567,12 +2611,14 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
* cursor */
fromcol_prev = fromcol;
fromcol = -1;
- } else if ((colnr_T)fromcol < wp->w_virtcol)
- /* restart highlighting after the cursor */
+ } else if ((colnr_T)fromcol < wp->w_virtcol) {
+ // restart highlighting after the cursor
fromcol_prev = wp->w_virtcol;
+ }
}
- if (fromcol >= tocol)
+ if (fromcol >= tocol) {
fromcol = -1;
+ }
}
/*
@@ -2582,8 +2628,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
cur = wp->w_match_head;
shl_flag = false;
while ((cur != NULL || !shl_flag) && !number_only
- && !has_fold
- ) {
+ && !has_fold && !end_fill) {
if (!shl_flag) {
shl = &search_hl;
shl_flag = true;
@@ -2594,7 +2639,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
shl->endcol = MAXCOL;
shl->attr_cur = 0;
shl->is_addpos = false;
- v = (long)(ptr - line);
+ v = (ptr - line);
if (cur != NULL) {
cur->pos.cur = 0;
}
@@ -2616,18 +2661,18 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
shl->startcol = 0;
}
if (lnum == shl->lnum + shl->rm.endpos[0].lnum
- - shl->rm.startpos[0].lnum) {
- shl->endcol = shl->rm.endpos[0].col;
+ - shl->rm.startpos[0].lnum) {
+ shl->endcol = shl->rm.endpos[0].col;
} else {
- shl->endcol = MAXCOL;
+ shl->endcol = MAXCOL;
}
// Highlight one character for an empty match.
if (shl->startcol == shl->endcol) {
- if (line[shl->endcol] != NUL) {
- shl->endcol += (*mb_ptr2len)(line + shl->endcol);
- } else {
- ++shl->endcol;
- }
+ if (line[shl->endcol] != NUL) {
+ shl->endcol += (*mb_ptr2len)(line + shl->endcol);
+ } else {
+ ++shl->endcol;
+ }
}
if ((long)shl->startcol < v) { // match at leftcol
shl->attr_cur = shl->attr;
@@ -2636,8 +2681,9 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
}
area_highlighting = true;
}
- if (shl != &search_hl && cur != NULL)
+ if (shl != &search_hl && cur != NULL) {
cur = cur->next;
+ }
}
unsigned off = 0; // Offset relative start of line
@@ -2650,7 +2696,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
off += col;
}
- // wont highlight after TERM_ATTRS_MAX columns
+ // won't highlight after TERM_ATTRS_MAX columns
int term_attrs[TERM_ATTRS_MAX] = { 0 };
if (wp->w_buffer->terminal) {
terminal_get_line_attributes(wp->w_buffer->terminal, wp, lnum, term_attrs);
@@ -2665,10 +2711,16 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
// Skip this quickly when working on the text.
if (draw_state != WL_LINE) {
+ if (cul_screenline) {
+ cul_attr = 0;
+ line_attr = line_attr_save;
+ line_attr_lowprio = line_attr_lowprio_save;
+ }
+
if (draw_state == WL_CMDLINE - 1 && n_extra == 0) {
draw_state = WL_CMDLINE;
if (cmdwin_type != 0 && wp == curwin) {
- /* Draw the cmdline character. */
+ // Draw the cmdline character.
n_extra = 1;
c_extra = cmdwin_type;
c_final = NUL;
@@ -2696,18 +2748,17 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
// sign column, this is hit until sign_idx reaches count
if (draw_state == WL_SIGN - 1 && n_extra == 0) {
- draw_state = WL_SIGN;
- /* Show the sign column when there are any signs in this
- * buffer or when using Netbeans. */
- int count = win_signcol_count(wp);
- if (count > 0) {
- get_sign_display_info(
- false, wp, sattrs, row,
- startrow, filler_lines, filler_todo, count,
- &c_extra, &c_final, extra, sizeof(extra),
- &p_extra, &n_extra,
- &char_attr, &draw_state, &sign_idx);
- }
+ draw_state = WL_SIGN;
+ /* Show the sign column when there are any signs in this
+ * buffer or when using Netbeans. */
+ int count = win_signcol_count(wp);
+ if (count > 0) {
+ get_sign_display_info(false, wp, sattrs, row,
+ startrow, filler_lines, filler_todo, count,
+ &c_extra, &c_final, extra, sizeof(extra),
+ &p_extra, &n_extra,
+ &char_attr, &draw_state, &sign_idx);
+ }
}
if (draw_state == WL_NR - 1 && n_extra == 0) {
@@ -2723,12 +2774,11 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
if (*wp->w_p_scl == 'n' && *(wp->w_p_scl + 1) == 'u'
&& num_signs > 0) {
int count = win_signcol_count(wp);
- get_sign_display_info(
- true, wp, sattrs, row,
- startrow, filler_lines, filler_todo, count,
- &c_extra, &c_final, extra, sizeof(extra),
- &p_extra, &n_extra,
- &char_attr, &draw_state, &sign_idx);
+ get_sign_display_info(true, wp, sattrs, row,
+ startrow, filler_lines, filler_todo, count,
+ &c_extra, &c_final, extra, sizeof(extra),
+ &p_extra, &n_extra,
+ &char_attr, &draw_state, &sign_idx);
} else {
if (row == startrow + filler_lines) {
// Draw the line number (empty space after wrapping). */
@@ -2775,15 +2825,29 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
n_extra = number_width(wp) + 1;
char_attr = win_hl_attr(wp, HLF_N);
+ if (wp->w_p_rnu && lnum < wp->w_cursor.lnum) {
+ // Use LineNrAbove
+ char_attr = win_hl_attr(wp, HLF_LNA);
+ }
+ if (wp->w_p_rnu && lnum > wp->w_cursor.lnum) {
+ // Use LineNrBelow
+ char_attr = win_hl_attr(wp, HLF_LNB);
+ }
+
sign_attrs_T *num_sattr = sign_get_attr(SIGN_NUMHL, sattrs, 0, 1);
if (num_sattr != NULL) {
// :sign defined with "numhl" highlight.
char_attr = num_sattr->sat_numhl;
- } else if ((wp->w_p_cul || wp->w_p_rnu)
+ } else if (wp->w_p_cul
&& lnum == wp->w_cursor.lnum
+ && (wp->w_p_culopt_flags & CULOPT_NBR)
+ && (row == startrow
+ || wp->w_p_culopt_flags & CULOPT_LINE)
&& filler_todo == 0) {
// When 'cursorline' is set highlight the line number of
// the current line differently.
+ // When 'cursorlineopt' has "screenline" only highlight
+ // the line number itself.
// TODO(vim): Can we use CursorLine instead of CursorLineNr
// when CursorLineNr isn't set?
char_attr = win_hl_attr(wp, HLF_CLN);
@@ -2797,7 +2861,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
}
if (wp->w_briopt_sbr && draw_state == WL_BRI - 1
- && n_extra == 0 && *p_sbr != NUL) {
+ && n_extra == 0 && *get_showbreak_value(wp) != NUL) {
// draw indent after showbreak value
draw_state = WL_BRI;
} else if (wp->w_briopt_sbr && draw_state == WL_SBR && n_extra == 0) {
@@ -2815,9 +2879,6 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
if (diff_hlf != (hlf_T)0) {
char_attr = win_hl_attr(wp, diff_hlf);
- if (wp->w_p_cul && lnum == wp->w_cursor.lnum) {
- char_attr = hl_combine_attr(char_attr, win_hl_attr(wp, HLF_CUL));
- }
}
p_extra = NULL;
c_extra = ' ';
@@ -2843,7 +2904,18 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
if (draw_state == WL_SBR - 1 && n_extra == 0) {
draw_state = WL_SBR;
- if (filler_todo > 0) {
+ if (filler_todo > filler_lines - virtual_lines) {
+ // TODO(bfredl): check this doesn't inhibit TUI-style
+ // clear-to-end-of-line.
+ c_extra = ' ';
+ c_final = NUL;
+ if (wp->w_p_rl) {
+ n_extra = col + 1;
+ } else {
+ n_extra = grid->Columns - col;
+ }
+ char_attr = 0;
+ } else if (filler_todo > 0) {
// draw "deleted" diff line(s)
if (char2cells(wp->w_p_fcs_chars.diff) > 1) {
c_extra = '-';
@@ -2859,24 +2931,26 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
}
char_attr = win_hl_attr(wp, HLF_DED);
}
- if (*p_sbr != NUL && need_showbreak) {
- /* Draw 'showbreak' at the start of each broken line. */
- p_extra = p_sbr;
+ char_u *const sbr = get_showbreak_value(wp);
+ if (*sbr != NUL && need_showbreak) {
+ // Draw 'showbreak' at the start of each broken line.
+ p_extra = sbr;
c_extra = NUL;
c_final = NUL;
- n_extra = (int)STRLEN(p_sbr);
+ n_extra = (int)STRLEN(sbr);
char_attr = win_hl_attr(wp, HLF_AT);
if (wp->w_skipcol == 0 || !wp->w_p_wrap) {
need_showbreak = false;
}
- vcol_sbr = vcol + MB_CHARLEN(p_sbr);
- /* Correct end of highlighted area for 'showbreak',
- * required when 'linebreak' is also set. */
- if (tocol == vcol)
+ vcol_sbr = vcol + MB_CHARLEN(sbr);
+ // Correct end of highlighted area for 'showbreak',
+ // required when 'linebreak' is also set.
+ if (tocol == vcol) {
tocol += n_extra;
+ }
// Combine 'showbreak' with 'cursorline', prioritizing 'showbreak'.
- if (wp->w_p_cul && lnum == wp->w_cursor.lnum) {
- char_attr = hl_combine_attr(win_hl_attr(wp, HLF_CUL), char_attr);
+ if (cul_attr) {
+ char_attr = hl_combine_attr(cul_attr, char_attr);
}
}
}
@@ -2891,7 +2965,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
}
if (saved_n_extra) {
- /* Continue item from end of wrapped line. */
+ // Continue item from end of wrapped line.
n_extra = saved_n_extra;
c_extra = saved_c_extra;
c_final = saved_c_final;
@@ -2903,6 +2977,23 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
}
}
+ if (cul_screenline && draw_state == WL_LINE
+ && vcol >= left_curline_col
+ && vcol < right_curline_col) {
+ cul_attr = win_hl_attr(wp, HLF_CUL);
+ HlAttrs ae = syn_attr2entry(cul_attr);
+ if (ae.rgb_fg_color == -1 && ae.cterm_fg_color == 0) {
+ line_attr_lowprio = cul_attr;
+ } else {
+ if (!(State & INSERT) && bt_quickfix(wp->w_buffer)
+ && qf_current_entry(wp) == lnum) {
+ line_attr = hl_combine_attr(cul_attr, line_attr);
+ } else {
+ line_attr = cul_attr;
+ }
+ }
+ }
+
// When still displaying '$' of change command, stop at cursor
if (((dollar_vcol >= 0
&& wp == curwin
@@ -2928,20 +3019,20 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
&& vcol == 0
&& n_extra == 0
&& row == startrow) {
- char_attr = win_hl_attr(wp, HLF_FL);
+ char_attr = win_hl_attr(wp, HLF_FL);
- linenr_T lnume = lnum + foldinfo.fi_lines - 1;
- memset(buf_fold, ' ', FOLD_TEXT_LEN);
- p_extra = get_foldtext(wp, lnum, lnume, foldinfo, buf_fold);
- n_extra = STRLEN(p_extra);
+ linenr_T lnume = lnum + foldinfo.fi_lines - 1;
+ memset(buf_fold, ' ', FOLD_TEXT_LEN);
+ p_extra = get_foldtext(wp, lnum, lnume, foldinfo, buf_fold);
+ n_extra = STRLEN(p_extra);
- if (p_extra != buf_fold) {
- xfree(p_extra_free);
- p_extra_free = p_extra;
- }
- c_extra = NUL;
- c_final = NUL;
- p_extra[n_extra] = NUL;
+ if (p_extra != buf_fold) {
+ xfree(p_extra_free);
+ p_extra_free = p_extra;
+ }
+ c_extra = NUL;
+ c_final = NUL;
+ p_extra[n_extra] = NUL;
}
if (draw_state == WL_LINE
@@ -2982,7 +3073,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
&& (colnr_T)vcol == wp->w_virtcol))) {
area_attr = 0; // stop highlighting
area_active = false;
- }
+ }
if (!n_extra) {
/*
@@ -2993,7 +3084,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
* Do this for 'search_hl' and the match list (ordered by
* priority).
*/
- v = (long)(ptr - line);
+ v = (ptr - line);
cur = wp->w_match_head;
shl_flag = false;
while (cur != NULL || !shl_flag) {
@@ -3007,10 +3098,10 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
if (cur != NULL) {
cur->pos.cur = 0;
}
- bool pos_inprogress = true; // mark that a position match search is
- // in progress
+ bool pos_inprogress = true; // mark that a position match search is
+ // in progress
while (shl->rm.regprog != NULL
- || (cur != NULL && pos_inprogress)) {
+ || (cur != NULL && pos_inprogress)) {
if (shl->startcol != MAXCOL
&& v >= (long)shl->startcol
&& v < (long)shl->endcol) {
@@ -3037,17 +3128,18 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
shl == &search_hl ? NULL : cur);
pos_inprogress = !(cur == NULL || cur->pos.cur == 0);
- /* Need to get the line again, a multi-line regexp
- * may have made it invalid. */
- line = ml_get_buf(wp->w_buffer, lnum, FALSE);
+ // Need to get the line again, a multi-line regexp
+ // may have made it invalid.
+ line = ml_get_buf(wp->w_buffer, lnum, false);
ptr = line + v;
if (shl->lnum == lnum) {
shl->startcol = shl->rm.startpos[0].col;
- if (shl->rm.endpos[0].lnum == 0)
+ if (shl->rm.endpos[0].lnum == 0) {
shl->endcol = shl->rm.endpos[0].col;
- else
+ } else {
shl->endcol = MAXCOL;
+ }
if (shl->startcol == shl->endcol) {
// highlight empty match, try again after it
@@ -3061,8 +3153,9 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
}
break;
}
- if (shl != &search_hl && cur != NULL)
+ if (shl != &search_hl && cur != NULL) {
cur = cur->next;
+ }
}
/* Use attributes from match with highest priority among
@@ -3083,8 +3176,9 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
search_attr = shl->attr_cur;
search_attr_from_match = shl != &search_hl;
}
- if (shl != &search_hl && cur != NULL)
+ if (shl != &search_hl && cur != NULL) {
cur = cur->next;
+ }
}
// Only highlight one character after the last column.
if (*ptr == NUL
@@ -3110,12 +3204,11 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
}
line_attr = win_hl_attr(wp, diff_hlf);
// Overlay CursorLine onto diff-mode highlight.
- if (wp->w_p_cul && lnum == wp->w_cursor.lnum) {
+ if (cul_attr) {
line_attr = 0 != line_attr_lowprio // Low-priority CursorLine
- ? hl_combine_attr(hl_combine_attr(win_hl_attr(wp, HLF_CUL),
- line_attr),
+ ? hl_combine_attr(hl_combine_attr(cul_attr, line_attr),
hl_get_underline())
- : hl_combine_attr(line_attr, win_hl_attr(wp, HLF_CUL));
+ : hl_combine_attr(line_attr, cul_attr);
}
}
@@ -3191,6 +3284,12 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
(void)mb_l;
multi_attr = win_hl_attr(wp, HLF_AT);
+ if (cul_attr) {
+ multi_attr = 0 != line_attr_lowprio
+ ? hl_combine_attr(cul_attr, multi_attr)
+ : hl_combine_attr(multi_attr, cul_attr);
+ }
+
// put the pointer back to output the double-width
// character at the start of the next line.
n_extra++;
@@ -3329,7 +3428,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
/* Get syntax attribute, unless still at the start of the line
* (double-wide char that doesn't fit). */
- v = (long)(ptr - line);
+ v = (ptr - line);
if (has_syntax && v > 0) {
/* Get the syntax attribute for the character. If there
* is an error, disable syntax highlighting. */
@@ -3342,16 +3441,23 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
if (did_emsg) {
wp->w_s->b_syn_error = TRUE;
has_syntax = FALSE;
- } else
+ } else {
did_emsg = save_did_emsg;
+ }
- /* Need to get the line again, a multi-line regexp may
- * have made it invalid. */
- line = ml_get_buf(wp->w_buffer, lnum, FALSE);
+ // Need to get the line again, a multi-line regexp may
+ // have made it invalid.
+ line = ml_get_buf(wp->w_buffer, lnum, false);
ptr = line + v;
if (!attr_pri) {
- char_attr = syntax_attr;
+ if (cul_attr) {
+ char_attr = 0 != line_attr_lowprio
+ ? hl_combine_attr(cul_attr, syntax_attr)
+ : hl_combine_attr(syntax_attr, cul_attr);
+ } else {
+ char_attr = syntax_attr;
+ }
} else {
char_attr = hl_combine_attr(syntax_attr, char_attr);
}
@@ -3370,7 +3476,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
* Only do this when there is no syntax highlighting, the
* @Spell cluster is not used or the current syntax item
* contains the @Spell cluster. */
- v = (long)(ptr - line);
+ v = (ptr - line);
if (has_spell && v >= word_end && v > cur_checked_col) {
spell_attr = 0;
if (!attr_pri) {
@@ -3417,9 +3523,10 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
checked_col = (int)((p - nextline) + len - nextline_idx);
}
- /* Turn index into actual attributes. */
- if (spell_hlf != HLF_COUNT)
+ // Turn index into actual attributes.
+ if (spell_hlf != HLF_COUNT) {
spell_attr = highlight_attr[spell_hlf];
+ }
if (cap_col > 0) {
if (p != prev_ptr
@@ -3429,17 +3536,19 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
capcol_lnum = lnum + 1;
cap_col = (int)((p - nextline) + cap_col
- nextline_idx);
- } else
- /* Compute the actual column. */
+ } else {
+ // Compute the actual column.
cap_col += (int)(prev_ptr - line);
+ }
}
}
}
if (spell_attr != 0) {
- if (!attr_pri)
+ if (!attr_pri) {
char_attr = hl_combine_attr(char_attr, spell_attr);
- else
+ } else {
char_attr = hl_combine_attr(spell_attr, char_attr);
+ }
}
if (wp->w_buffer->terminal) {
@@ -3467,6 +3576,16 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
char_u *p = ptr - (mb_off + 1);
// TODO: is passing p for start of the line OK?
n_extra = win_lbr_chartabsize(wp, line, p, (colnr_T)vcol, NULL) - 1;
+
+ // We have just drawn the showbreak value, no need to add
+ // space for it again.
+ if (vcol == vcol_sbr) {
+ n_extra -= MB_CHARLEN(get_showbreak_value(wp));
+ if (n_extra < 0) {
+ n_extra = 0;
+ }
+ }
+
if (c == TAB && n_extra + col > grid->Columns) {
n_extra = tabstop_padding(vcol, wp->w_buffer->b_p_ts,
wp->w_buffer->b_p_vts_array) - 1;
@@ -3474,24 +3593,44 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
c_extra = mb_off > 0 ? MB_FILLER_CHAR : ' ';
c_final = NUL;
if (ascii_iswhite(c)) {
- if (c == TAB)
- /* See "Tab alignment" below. */
+ if (c == TAB) {
+ // See "Tab alignment" below.
FIX_FOR_BOGUSCOLS;
+ }
if (!wp->w_p_list) {
c = ' ';
}
}
}
- // 'list': change char 160 to 'nbsp' and space to 'space'.
+ in_multispace = c == ' ' && ((ptr > line + 1 && ptr[-2] == ' ') || *ptr == ' ');
+ if (!in_multispace) {
+ multispace_pos = 0;
+ }
+
+ // 'list': Change char 160 to 'nbsp' and space to 'space'.
+ // But not when the character is followed by a composing
+ // character (use mb_l to check that).
if (wp->w_p_list
- && (((c == 160
- || (mb_utf8 && (mb_c == 160 || mb_c == 0x202f)))
- && curwin->w_p_lcs_chars.nbsp)
- || (c == ' ' && curwin->w_p_lcs_chars.space
+ && ((((c == 160 && mb_l == 1)
+ || (mb_utf8
+ && ((mb_c == 160 && mb_l == 2)
+ || (mb_c == 0x202f && mb_l == 3))))
+ && wp->w_p_lcs_chars.nbsp)
+ || (c == ' '
+ && mb_l == 1
+ && (wp->w_p_lcs_chars.space
+ || (in_multispace && wp->w_p_lcs_chars.multispace != NULL))
&& ptr - line >= leadcol
&& ptr - line <= trailcol))) {
- c = (c == ' ') ? wp->w_p_lcs_chars.space : wp->w_p_lcs_chars.nbsp;
+ if (in_multispace && wp->w_p_lcs_chars.multispace != NULL) {
+ c = wp->w_p_lcs_chars.multispace[multispace_pos++];
+ if (wp->w_p_lcs_chars.multispace[multispace_pos] == NUL) {
+ multispace_pos = 0;
+ }
+ } else {
+ c = (c == ' ') ? wp->w_p_lcs_chars.space : wp->w_p_lcs_chars.nbsp;
+ }
n_attr = 1;
extra_attr = win_hl_attr(wp, HLF_0);
saved_attr2 = char_attr; // save current attr
@@ -3532,10 +3671,12 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
if (c == TAB && (!wp->w_p_list || wp->w_p_lcs_chars.tab1)) {
int tab_len = 0;
long vcol_adjusted = vcol; // removed showbreak length
+ char_u *const sbr = get_showbreak_value(wp);
+
// Only adjust the tab_len, when at the first column after the
// showbreak value was drawn.
- if (*p_sbr != NUL && vcol == vcol_sbr && wp->w_p_wrap) {
- vcol_adjusted = vcol - MB_CHARLEN(p_sbr);
+ if (*sbr != NUL && vcol == vcol_sbr && wp->w_p_wrap) {
+ vcol_adjusted = vcol - MB_CHARLEN(sbr);
}
// tab amount depends on current column
tab_len = tabstop_padding(vcol_adjusted,
@@ -3546,8 +3687,8 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
n_extra = tab_len;
} else {
char_u *p;
- int i;
- int saved_nextra = n_extra;
+ int i;
+ int saved_nextra = n_extra;
if (vcol_off > 0) {
// there are characters to conceal
@@ -3623,7 +3764,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
? wp->w_p_lcs_chars.tab3
: wp->w_p_lcs_chars.tab1;
if (wp->w_p_lbr) {
- c_extra = NUL; /* using p_extra from above */
+ c_extra = NUL; // using p_extra from above
} else {
c_extra = wp->w_p_lcs_chars.tab2;
}
@@ -3689,10 +3830,11 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
} else if (c != NUL) {
p_extra = transchar_buf(wp->w_buffer, c);
if (n_extra == 0) {
- n_extra = byte2cells(c) - 1;
+ n_extra = byte2cells(c) - 1;
+ }
+ if ((dy_flags & DY_UHEX) && wp->w_p_rl) {
+ rl_mirror(p_extra); // reverse "<12>"
}
- if ((dy_flags & DY_UHEX) && wp->w_p_rl)
- rl_mirror(p_extra); /* reverse "<12>" */
c_extra = NUL;
c_final = NUL;
if (wp->w_p_lbr) {
@@ -3750,8 +3892,9 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
prev_syntax_id = syntax_seqnr;
- if (n_extra > 0)
+ if (n_extra > 0) {
vcol_off += n_extra;
+ }
vcol += n_extra;
if (wp->w_p_wrap && n_extra > 0) {
if (wp->w_p_rl) {
@@ -3765,7 +3908,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
n_extra = 0;
n_attr = 0;
} else if (n_skip == 0) {
- is_concealing = TRUE;
+ is_concealing = true;
n_skip = 1;
}
mb_c = c;
@@ -3778,7 +3921,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
}
} else {
prev_syntax_id = 0;
- is_concealing = FALSE;
+ is_concealing = false;
}
if (n_skip > 0 && did_decrement_ptr) {
@@ -3843,7 +3986,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
// At end of the text line or just after the last character.
if (c == NUL && eol_hl_off == 0) {
- long prevcol = (long)(ptr - line) - 1;
+ long prevcol = (ptr - line) - 1;
// we're not really at that column when skipping some text
if ((long)(wp->w_p_wrap ? wp->w_skipcol : wp->w_leftcol) > prevcol) {
@@ -3877,8 +4020,9 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
int n = 0;
if (wp->w_p_rl) {
- if (col < 0)
+ if (col < 0) {
n = 1;
+ }
} else {
if (col >= grid->Columns) {
n = -1;
@@ -3918,8 +4062,8 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
}
int eol_attr = char_attr;
- if (wp->w_p_cul && lnum == wp->w_cursor.lnum) {
- eol_attr = hl_combine_attr(win_hl_attr(wp, HLF_CUL), eol_attr);
+ if (cul_attr) {
+ eol_attr = hl_combine_attr(cul_attr, eol_attr);
}
linebuf_attr[off] = eol_attr;
if (wp->w_p_rl) {
@@ -3939,30 +4083,28 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
v = wp->w_leftcol;
}
- /* check if line ends before left margin */
- if (vcol < v + col - win_col_off(wp))
+ // check if line ends before left margin
+ if (vcol < v + col - win_col_off(wp)) {
vcol = v + col - win_col_off(wp);
+ }
// Get rid of the boguscols now, we want to draw until the right
// edge for 'cursorcolumn'.
col -= boguscols;
// boguscols = 0; // Disabled because value never read after this
- if (draw_color_col)
+ if (draw_color_col) {
draw_color_col = advance_color_col(VCOL_HLC, &color_cols);
+ }
- VirtText virt_text = KV_INITIAL_VALUE;
- bool has_aligned = false;
- if (err_text) {
- int hl_err = syn_check_group((char_u *)S_LEN("ErrorMsg"));
- kv_push(virt_text, ((VirtTextChunk){ .text = err_text,
- .hl_id = hl_err }));
- do_virttext = true;
- } else if (has_decor) {
- virt_text = decor_redraw_eol(wp->w_buffer, &decor_state, &line_attr,
- &has_aligned);
- if (kv_size(virt_text)) {
- do_virttext = true;
- }
+ bool has_virttext = false;
+ // Make sure alignment is the same regardless
+ // if listchars=eol:X is used or not.
+ int eol_skip = (wp->w_p_lcs_chars.eol == lcs_eol_one && eol_hl_off == 0
+ ? 1 : 0);
+
+ if (has_decor) {
+ has_virttext = decor_redraw_eol(wp->w_buffer, &decor_state, &line_attr,
+ col + eol_skip);
}
if (((wp->w_p_cuc
@@ -3971,20 +4113,10 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
grid->Columns * (row - startrow + 1) + v
&& lnum != wp->w_cursor.lnum)
|| draw_color_col || line_attr_lowprio || line_attr
- || diff_hlf != (hlf_T)0 || do_virttext
- || has_aligned)) {
+ || diff_hlf != (hlf_T)0 || has_virttext)) {
int rightmost_vcol = 0;
int i;
- size_t virt_pos = 0;
- LineState s = LINE_STATE("");
- int virt_attr = 0;
-
- // Make sure alignment is the same regardless
- // if listchars=eol:X is used or not.
- bool delay_virttext = wp->w_p_lcs_chars.eol == lcs_eol_one
- && eol_hl_off == 0;
-
if (wp->w_p_cuc) {
rightmost_vcol = wp->w_virtcol;
}
@@ -4010,37 +4142,15 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
}
int base_attr = hl_combine_attr(line_attr_lowprio, diff_attr);
- if (base_attr || line_attr || has_aligned) {
+ if (base_attr || line_attr || has_virttext) {
rightmost_vcol = INT_MAX;
}
int col_stride = wp->w_p_rl ? -1 : 1;
while (wp->w_p_rl ? col >= 0 : col < grid->Columns) {
- int cells = -1;
- if (do_virttext && !delay_virttext) {
- if (*s.p == NUL) {
- if (virt_pos < virt_text.size) {
- s.p = kv_A(virt_text, virt_pos).text;
- int hl_id = kv_A(virt_text, virt_pos).hl_id;
- virt_attr = hl_id > 0 ? syn_id2attr(hl_id) : 0;
- virt_pos++;
- } else {
- do_virttext = false;
- }
- }
- if (*s.p != NUL) {
- cells = line_putchar(&s, &linebuf_char[off], grid->Columns - col,
- false);
- }
- }
- delay_virttext = false;
-
- if (cells == -1) {
- schar_from_ascii(linebuf_char[off], ' ');
- cells = 1;
- }
- col += cells * col_stride;
+ schar_from_ascii(linebuf_char[off], ' ');
+ col += col_stride;
if (draw_color_col) {
draw_color_col = advance_color_col(VCOL_HLC, &color_cols);
}
@@ -4053,24 +4163,16 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
col_attr = mc_attr;
}
- if (do_virttext) {
- col_attr = hl_combine_attr(col_attr, virt_attr);
- }
-
col_attr = hl_combine_attr(col_attr, line_attr);
linebuf_attr[off] = col_attr;
- if (cells == 2) {
- linebuf_attr[off+1] = col_attr;
- }
- off += cells * col_stride;
+ off += col_stride;
- if (VCOL_HLC >= rightmost_vcol && *s.p == NUL
- && virt_pos >= virt_text.size) {
+ if (VCOL_HLC >= rightmost_vcol) {
break;
}
- vcol += cells;
+ vcol += 1;
}
}
@@ -4095,7 +4197,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
/*
* Update w_cline_height and w_cline_folded if the cursor line was
- * updated (saves a call to plines() later).
+ * updated (saves a call to plines_win() later).
*/
if (wp == curwin && lnum == curwin->w_cursor.lnum) {
curwin->w_cline_row = startrow;
@@ -4203,7 +4305,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
tocol++;
}
if (wp->w_p_rl) {
- /* now it's time to backup one cell */
+ // now it's time to backup one cell
--off;
--col;
}
@@ -4218,8 +4320,9 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
} else if (wp->w_p_cole > 0 && is_concealing) {
--n_skip;
++vcol_off;
- if (n_extra > 0)
+ if (n_extra > 0) {
vcol_off += n_extra;
+ }
if (wp->w_p_wrap) {
/*
* Special voodoo required if 'wrap' is on.
@@ -4273,27 +4376,30 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
n_attr = 0;
}
}
-
- } else
+ } else {
--n_skip;
+ }
/* Only advance the "vcol" when after the 'number' or 'relativenumber'
* column. */
if (draw_state > WL_NR
- && filler_todo <= 0
- )
+ && filler_todo <= 0) {
++vcol;
+ }
- if (vcol_save_attr >= 0)
+ if (vcol_save_attr >= 0) {
char_attr = vcol_save_attr;
+ }
- /* restore attributes after "predeces" in 'listchars' */
- if (draw_state > WL_NR && n_attr3 > 0 && --n_attr3 == 0)
+ // restore attributes after "predeces" in 'listchars'
+ if (draw_state > WL_NR && n_attr3 > 0 && --n_attr3 == 0) {
char_attr = saved_attr3;
+ }
- /* restore attributes after last 'listchars' or 'number' char */
- if (n_attr > 0 && draw_state == WL_LINE && --n_attr == 0)
+ // restore attributes after last 'listchars' or 'number' char
+ if (n_attr > 0 && draw_state == WL_LINE && --n_attr == 0) {
char_attr = saved_attr2;
+ }
/*
* At end of screen line and there is more to come: Display the line
@@ -4305,18 +4411,30 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
|| filler_todo > 0
|| (wp->w_p_list && wp->w_p_lcs_chars.eol != NUL
&& p_extra != at_end_str)
- || (n_extra != 0 && (c_extra != NUL || *p_extra != NUL)))
- ) {
+ || (n_extra != 0 &&
+ (c_extra != NUL || *p_extra != NUL)))) {
bool wrap = wp->w_p_wrap // Wrapping enabled.
- && filler_todo <= 0 // Not drawing diff filler lines.
- && lcs_eol_one != -1 // Haven't printed the lcs_eol character.
- && row != endrow - 1 // Not the last line being displayed.
- && (grid->Columns == Columns // Window spans the width of the screen,
- || ui_has(kUIMultigrid)) // or has dedicated grid.
- && !wp->w_p_rl; // Not right-to-left.
+ && filler_todo <= 0 // Not drawing diff filler lines.
+ && lcs_eol_one != -1 // Haven't printed the lcs_eol character.
+ && row != endrow - 1 // Not the last line being displayed.
+ && (grid->Columns == Columns // Window spans the width of the screen,
+ || ui_has(kUIMultigrid)) // or has dedicated grid.
+ && !wp->w_p_rl; // Not right-to-left.
int draw_col = col - boguscols;
- draw_virt_text(buf, win_col_offset, &draw_col, grid->Columns);
+ if (filler_todo > 0) {
+ int index = filler_todo - (filler_lines - virtual_lines);
+ if (index > 0) {
+ int fpos = kv_size(buf->b_virt_lines) - index;
+ assert(fpos >= 0);
+ int offset = buf->b_virt_line_leftcol ? 0 : win_col_offset;
+ draw_virt_text_item(buf, offset, kv_A(buf->b_virt_lines, fpos),
+ kHlModeReplace, grid->Columns, offset);
+ }
+ } else {
+ draw_virt_text(buf, win_col_offset, &draw_col, grid->Columns);
+ }
+
grid_put_linebuf(grid, row, 0, draw_col, grid->Columns, wp->w_p_rl,
wp, wp->w_hl_attr_normal, wrap);
if (wrap) {
@@ -4338,8 +4456,9 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
* '$' and highlighting until last column, break here. */
if ((!wp->w_p_wrap
&& filler_todo <= 0
- ) || lcs_eol_one == -1)
+ ) || lcs_eol_one == -1) {
break;
+ }
// When the window is too narrow draw all "@" lines.
if (draw_state != WL_LINE && filler_todo <= 0) {
@@ -4347,7 +4466,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
row = endrow;
}
- /* When line got too long for screen break here. */
+ // When line got too long for screen break here.
if (row == endrow) {
++row;
break;
@@ -4360,7 +4479,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
off += col;
}
- /* reset the drawing state for the start of a wrapped line */
+ // reset the drawing state for the start of a wrapped line
draw_state = WL_START;
saved_n_extra = n_extra;
saved_p_extra = p_extra;
@@ -4375,21 +4494,19 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
filler_todo--;
// When the filler lines are actually below the last line of the
// file, don't draw the line itself, break here.
- if (filler_todo == 0 && wp->w_botfill) {
+ if (filler_todo == 0 && (wp->w_botfill || end_fill)) {
break;
}
}
+ } // for every character in the line
- } /* for every character in the line */
-
- /* After an empty line check first word for capital. */
+ // After an empty line check first word for capital.
if (*skipwhite(line) == NUL) {
capcol_lnum = lnum + 1;
cap_col = 0;
}
xfree(p_extra_free);
- xfree(err_text);
return row;
}
@@ -4397,60 +4514,83 @@ void draw_virt_text(buf_T *buf, int col_off, int *end_col, int max_col)
{
DecorState *state = &decor_state;
int right_pos = max_col;
+ bool do_eol = state->eol_col > -1;
for (size_t i = 0; i < kv_size(state->active); i++) {
DecorRange *item = &kv_A(state->active, i);
- if (item->start_row == state->row && kv_size(item->decor.virt_text)) {
- if (item->win_col == -1) {
- if (item->decor.virt_text_pos == kVTRightAlign) {
- right_pos -= item->decor.col;
- item->win_col = right_pos;
- } else if (item->decor.virt_text_pos == kVTWinCol) {
- item->win_col = MAX(item->decor.col+col_off, 0);
- }
- }
- if (item->win_col < 0) {
- continue;
- }
- VirtText vt = item->decor.virt_text;
- HlMode hl_mode = item->decor.hl_mode;
- LineState s = LINE_STATE("");
- int virt_attr = 0;
- int col = item->win_col;
- size_t virt_pos = 0;
- item->win_col = -2; // deactivate
-
- while (col < max_col) {
- if (!*s.p) {
- if (virt_pos == kv_size(vt)) {
- break;
- }
- s.p = kv_A(vt, virt_pos).text;
- int hl_id = kv_A(vt, virt_pos).hl_id;
- virt_attr = hl_id > 0 ? syn_id2attr(hl_id) : 0;
- virt_pos++;
- continue;
- }
- int attr;
- bool through = false;
- if (hl_mode == kHlModeCombine) {
- attr = hl_combine_attr(linebuf_attr[col], virt_attr);
- } else if (hl_mode == kHlModeBlend) {
- through = (*s.p == ' ');
- attr = hl_blend_attrs(linebuf_attr[col], virt_attr, &through);
- } else {
- attr = virt_attr;
- }
- schar_T dummy[2];
- int cells = line_putchar(&s, through ? dummy : &linebuf_char[col],
- max_col-col, false);
- linebuf_attr[col++] = attr;
- if (cells > 1) {
- linebuf_attr[col++] = attr;
- }
+ if (!(item->start_row == state->row && kv_size(item->decor.virt_text))) {
+ continue;
+ }
+ if (item->win_col == -1) {
+ if (item->decor.virt_text_pos == kVTRightAlign) {
+ right_pos -= item->decor.virt_text_width;
+ item->win_col = right_pos;
+ } else if (item->decor.virt_text_pos == kVTEndOfLine && do_eol) {
+ item->win_col = state->eol_col;
+ } else if (item->decor.virt_text_pos == kVTWinCol) {
+ item->win_col = MAX(item->decor.col+col_off, 0);
+ }
+ }
+ if (item->win_col < 0) {
+ continue;
+ }
+
+ int col = draw_virt_text_item(buf, item->win_col, item->decor.virt_text,
+ item->decor.hl_mode, max_col, item->win_col-col_off);
+ item->win_col = -2; // deactivate
+ if (item->decor.virt_text_pos == kVTEndOfLine && do_eol) {
+ state->eol_col = col+1;
+ }
+
+ *end_col = MAX(*end_col, col);
+ }
+}
+
+static int draw_virt_text_item(buf_T *buf, int col, VirtText vt, HlMode hl_mode,
+ int max_col, int vcol)
+{
+ LineState s = LINE_STATE("");
+ int virt_attr = 0;
+ size_t virt_pos = 0;
+
+ while (col < max_col) {
+ if (!*s.p) {
+ if (virt_pos >= kv_size(vt)) {
+ break;
}
- *end_col = MAX(*end_col, col);
+ virt_attr = 0;
+ do {
+ s.p = kv_A(vt, virt_pos).text;
+ int hl_id = kv_A(vt, virt_pos).hl_id;
+ virt_attr = hl_combine_attr(virt_attr,
+ hl_id > 0 ? syn_id2attr(hl_id) : 0);
+ virt_pos++;
+ } while (!s.p && virt_pos < kv_size(vt));
+ if (!s.p) {
+ break;
+ }
+ }
+ int attr;
+ bool through = false;
+ if (hl_mode == kHlModeCombine) {
+ attr = hl_combine_attr(linebuf_attr[col], virt_attr);
+ } else if (hl_mode == kHlModeBlend) {
+ through = (*s.p == ' ');
+ attr = hl_blend_attrs(linebuf_attr[col], virt_attr, &through);
+ } else {
+ attr = virt_attr;
}
+ schar_T dummy[2];
+ int cells = line_putchar(buf, &s, through ? dummy : &linebuf_char[col],
+ max_col-col, false, vcol);
+ // if we failed to emit a char, we still need to advance
+ cells = MAX(cells, 1);
+
+ for (int c = 0; c < cells; c++) {
+ linebuf_attr[col++] = attr;
+ }
+ vcol += cells;
}
+ return col;
}
/// Determine if dedicated window grid should be used or the default_grid
@@ -4479,25 +4619,11 @@ void screen_adjust_grid(ScreenGrid **grid, int *row_off, int *col_off)
// @param count max number of signs
// @param[out] n_extrap number of characters from pp_extra to display
// @param[in, out] sign_idxp Index of the displayed sign
-static void get_sign_display_info(
- bool nrcol,
- win_T *wp,
- sign_attrs_T sattrs[],
- int row,
- int startrow,
- int filler_lines,
- int filler_todo,
- int count,
- int *c_extrap,
- int *c_finalp,
- char_u *extra,
- size_t extra_size,
- char_u **pp_extra,
- int *n_extrap,
- int *char_attrp,
- int *draw_statep,
- int *sign_idxp
-)
+static void get_sign_display_info(bool nrcol, win_T *wp, sign_attrs_T sattrs[], int row,
+ int startrow, int filler_lines, int filler_todo, int count,
+ int *c_extrap, int *c_finalp, char_u *extra, size_t extra_size,
+ char_u **pp_extra, int *n_extrap, int *char_attrp,
+ int *draw_statep, int *sign_idxp)
{
// Draw cells with the sign value or blank.
*c_extrap = ' ';
@@ -4535,7 +4661,7 @@ static void get_sign_display_info(
assert((size_t)win_signcol_width(wp) >= mb_string2cells(*pp_extra));
// symbol(s) bytes + (filling spaces) (one byte each)
*n_extrap = symbol_blen +
- (win_signcol_width(wp) - mb_string2cells(*pp_extra));
+ (win_signcol_width(wp) - mb_string2cells(*pp_extra));
assert(extra_size > (size_t)symbol_blen);
memset(extra, ' ', extra_size);
@@ -4565,8 +4691,7 @@ static void get_sign_display_info(
* - the character is multi-byte and the next byte is different
* - the character is two cells wide and the second cell differs.
*/
-static int grid_char_needs_redraw(ScreenGrid *grid, int off_from, int off_to,
- int cols)
+static int grid_char_needs_redraw(ScreenGrid *grid, int off_from, int off_to, int cols)
{
return (cols > 0
&& ((schar_cmp(linebuf_char[off_from], grid->chars[off_to])
@@ -4588,9 +4713,8 @@ static int grid_char_needs_redraw(ScreenGrid *grid, int off_from, int off_to,
/// When FALSE and "clear_width" > 0, clear columns "endcol" to "clear_width"
/// If "wrap" is true, then hint to the UI that "row" contains a line
/// which has wrapped into the next row.
-static void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol,
- int clear_width, int rlflag, win_T *wp,
- int bg_attr, bool wrap)
+static void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol, int clear_width,
+ int rlflag, win_T *wp, int bg_attr, bool wrap)
{
unsigned off_from;
unsigned off_to;
@@ -4627,12 +4751,11 @@ static void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol,
max_off_to = grid->line_offset[row] + grid->Columns;
if (rlflag) {
- /* Clear rest first, because it's left of the text. */
+ // Clear rest first, because it's left of the text.
if (clear_width > 0) {
while (col <= endcol && grid->chars[off_to][0] == ' '
&& grid->chars[off_to][1] == NUL
- && grid->attrs[off_to] == bg_attr
- ) {
+ && grid->attrs[off_to] == bg_attr) {
++off_to;
++col;
}
@@ -4758,7 +4881,7 @@ static void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol,
*/
void rl_mirror(char_u *str)
{
- char_u *p1, *p2;
+ char_u *p1, *p2;
int t;
for (p1 = str, p2 = str + STRLEN(str) - 1; p1 < p2; ++p1, --p2) {
@@ -4773,7 +4896,6 @@ void rl_mirror(char_u *str)
*/
void status_redraw_all(void)
{
-
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
if (wp->w_status_height) {
wp->w_redr_status = true;
@@ -4809,8 +4931,9 @@ void redraw_statuslines(void)
win_redr_status(wp);
}
}
- if (redraw_tabline)
+ if (redraw_tabline) {
draw_tabline();
+ }
}
/*
@@ -4862,9 +4985,10 @@ static int status_match_len(expand_T *xp, char_u *s)
int emenu = (xp->xp_context == EXPAND_MENUS
|| xp->xp_context == EXPAND_MENUNAMES);
- /* Check for menu separators - replace with '|'. */
- if (emenu && menu_is_separator(s))
+ // Check for menu separators - replace with '|'.
+ if (emenu && menu_is_separator(s)) {
return 1;
+ }
while (*s != NUL) {
s += skip_status_match_char(xp, s);
@@ -4884,78 +5008,76 @@ static int skip_status_match_char(expand_T *xp, char_u *s)
if ((rem_backslash(s) && xp->xp_context != EXPAND_HELP)
|| ((xp->xp_context == EXPAND_MENUS
|| xp->xp_context == EXPAND_MENUNAMES)
- && (s[0] == '\t' || (s[0] == '\\' && s[1] != NUL)))
- ) {
+ && (s[0] == '\t' ||
+ (s[0] == '\\' && s[1] != NUL)))) {
#ifndef BACKSLASH_IN_FILENAME
- if (xp->xp_shell && csh_like_shell() && s[1] == '\\' && s[2] == '!')
+ if (xp->xp_shell && csh_like_shell() && s[1] == '\\' && s[2] == '!') {
return 2;
+ }
#endif
return 1;
}
return 0;
}
-/*
- * Show wildchar matches in the status line.
- * Show at least the "match" item.
- * We start at item 'first_match' in the list and show all matches that fit.
- *
- * If inversion is possible we use it. Else '=' characters are used.
- */
-void
-win_redr_status_matches (
- expand_T *xp,
- int num_matches,
- char_u **matches, /* list of matches */
- int match,
- int showtail
-)
+/// Show wildchar matches in the status line.
+/// Show at least the "match" item.
+/// We start at item 'first_match' in the list and show all matches that fit.
+///
+/// If inversion is possible we use it. Else '=' characters are used.
+///
+/// @param matches list of matches
+void win_redr_status_matches(expand_T *xp, int num_matches, char_u **matches, int match,
+ int showtail)
{
#define L_MATCH(m) (showtail ? sm_gettail(matches[m], false) : matches[m])
int row;
- char_u *buf;
+ char_u *buf;
int len;
- int clen; /* length in screen cells */
+ int clen; // length in screen cells
int fillchar;
int attr;
int i;
- int highlight = TRUE;
- char_u *selstart = NULL;
+ bool highlight = true;
+ char_u *selstart = NULL;
int selstart_col = 0;
- char_u *selend = NULL;
+ char_u *selend = NULL;
static int first_match = 0;
- int add_left = FALSE;
- char_u *s;
+ bool add_left = false;
+ char_u *s;
int emenu;
int l;
- if (matches == NULL) /* interrupted completion? */
+ if (matches == NULL) { // interrupted completion?
return;
+ }
buf = xmalloc(Columns * MB_MAXBYTES + 1);
- if (match == -1) { /* don't show match but original text */
+ if (match == -1) { // don't show match but original text
match = 0;
- highlight = FALSE;
+ highlight = false;
}
- /* count 1 for the ending ">" */
+ // count 1 for the ending ">"
clen = status_match_len(xp, L_MATCH(match)) + 3;
- if (match == 0)
+ if (match == 0) {
first_match = 0;
- else if (match < first_match) {
- /* jumping left, as far as we can go */
+ } else if (match < first_match) {
+ // jumping left, as far as we can go
first_match = match;
- add_left = TRUE;
+ add_left = true;
} else {
- /* check if match fits on the screen */
- for (i = first_match; i < match; ++i)
+ // check if match fits on the screen
+ for (i = first_match; i < match; ++i) {
clen += status_match_len(xp, L_MATCH(i)) + 2;
- if (first_match > 0)
+ }
+ if (first_match > 0) {
clen += 2;
+ }
// jumping right, put match at the left
if ((long)clen > Columns) {
first_match = match;
- /* if showing the last match, we can add some on the left */
+ // if showing the last match, we can add some on the left
clen = 2;
for (i = match; i < num_matches; ++i) {
clen += status_match_len(xp, L_MATCH(i)) + 2;
@@ -4963,11 +5085,12 @@ win_redr_status_matches (
break;
}
}
- if (i == num_matches)
- add_left = TRUE;
+ if (i == num_matches) {
+ add_left = true;
+ }
}
}
- if (add_left)
+ if (add_left) {
while (first_match > 0) {
clen += status_match_len(xp, L_MATCH(first_match - 1)) + 2;
if ((long)clen >= Columns) {
@@ -4975,6 +5098,7 @@ win_redr_status_matches (
}
first_match--;
}
+ }
fillchar = fillchar_status(&attr, curwin);
@@ -4995,7 +5119,7 @@ win_redr_status_matches (
}
s = L_MATCH(i);
- /* Check for menu separators - replace with '|' */
+ // Check for menu separators - replace with '|'
emenu = (xp->xp_context == EXPAND_MENUS
|| xp->xp_context == EXPAND_MENUNAMES);
if (emenu && menu_is_separator(s)) {
@@ -5003,7 +5127,7 @@ win_redr_status_matches (
l = (int)STRLEN(buf + len);
len += l;
clen += l;
- } else
+ } else {
for (; *s != NUL; ++s) {
s += skip_status_match_char(xp, s);
clen += ptr2cells(s);
@@ -5016,14 +5140,17 @@ win_redr_status_matches (
len += (int)STRLEN(buf + len);
}
}
- if (i == match)
+ }
+ if (i == match) {
selend = buf + len;
+ }
*(buf + len++) = ' ';
*(buf + len++) = ' ';
clen += 2;
- if (++i == num_matches)
+ if (++i == num_matches) {
break;
+ }
}
if (i != num_matches) {
@@ -5056,7 +5183,7 @@ win_redr_status_matches (
save_p_wmh = p_wmh;
p_ls = 2;
p_wmh = 0;
- last_status(FALSE);
+ last_status(false);
}
wild_menu_showing = WM_SHOWN;
}
@@ -5087,7 +5214,7 @@ win_redr_status_matches (
static void win_redr_status(win_T *wp)
{
int row;
- char_u *p;
+ char_u *p;
int len;
int fillchar;
int attr;
@@ -5112,7 +5239,7 @@ static void win_redr_status(win_T *wp)
// popup menu is visible and may be drawn over it
wp->w_redr_status = true;
} else if (*p_stl != NUL || *wp->w_p_stl != NUL) {
- /* redraw custom status line */
+ // redraw custom status line
redraw_custom_statusline(wp);
} else {
fillchar = fillchar_status(&attr, wp);
@@ -5177,11 +5304,12 @@ static void win_redr_status(win_T *wp)
this_ru_col + wp->w_wincol, fillchar, fillchar, attr);
if (get_keymap_str(wp, (char_u *)"<%s>", NameBuff, MAXPATHL)
- && this_ru_col - len > (int)(STRLEN(NameBuff) + 1))
+ && this_ru_col - len > (int)(STRLEN(NameBuff) + 1)) {
grid_puts(&default_grid, NameBuff, row,
(int)(this_ru_col - STRLEN(NameBuff) - 1), attr);
+ }
- win_redr_ruler(wp, TRUE);
+ win_redr_ruler(wp, true);
}
/*
@@ -5204,14 +5332,15 @@ static void win_redr_status(win_T *wp)
*/
static void redraw_custom_statusline(win_T *wp)
{
- static int entered = false;
+ static bool entered = false;
int saved_did_emsg = did_emsg;
/* When called recursively return. This can happen when the statusline
* contains an expression that triggers a redraw. */
- if (entered)
+ if (entered) {
return;
- entered = TRUE;
+ }
+ entered = true;
did_emsg = false;
win_redr_custom(wp, false);
@@ -5227,57 +5356,55 @@ static void redraw_custom_statusline(win_T *wp)
entered = false;
}
-/*
- * Return TRUE if the status line of window "wp" is connected to the status
- * line of the window right of it. If not, then it's a vertical separator.
- * Only call if (wp->w_vsep_width != 0).
- */
-int stl_connected(win_T *wp)
+/// Only call if (wp->w_vsep_width != 0).
+///
+/// @return true if the status line of window "wp" is connected to the status
+/// line of the window right of it. If not, then it's a vertical separator.
+bool stl_connected(win_T *wp)
{
- frame_T *fr;
+ frame_T *fr;
fr = wp->w_frame;
while (fr->fr_parent != NULL) {
if (fr->fr_parent->fr_layout == FR_COL) {
- if (fr->fr_next != NULL)
+ if (fr->fr_next != NULL) {
break;
+ }
} else {
- if (fr->fr_next != NULL)
- return TRUE;
+ if (fr->fr_next != NULL) {
+ return true;
+ }
}
fr = fr->fr_parent;
}
- return FALSE;
+ return false;
}
-/*
- * Get the value to show for the language mappings, active 'keymap'.
- */
-int
-get_keymap_str (
- win_T *wp,
- char_u *fmt, // format string containing one %s item
- char_u *buf, // buffer for the result
- int len // length of buffer
-)
+/// Get the value to show for the language mappings, active 'keymap'.
+///
+/// @param fmt format string containing one %s item
+/// @param buf buffer for the result
+/// @param len length of buffer
+bool get_keymap_str(win_T *wp, char_u *fmt, char_u *buf, int len)
{
- char_u *p;
+ char_u *p;
- if (wp->w_buffer->b_p_iminsert != B_IMODE_LMAP)
- return FALSE;
+ if (wp->w_buffer->b_p_iminsert != B_IMODE_LMAP) {
+ return false;
+ }
{
- buf_T *old_curbuf = curbuf;
- win_T *old_curwin = curwin;
- char_u *s;
+ buf_T *old_curbuf = curbuf;
+ win_T *old_curwin = curwin;
+ char_u *s;
curbuf = wp->w_buffer;
curwin = wp;
- STRCPY(buf, "b:keymap_name"); /* must be writable */
- ++emsg_skip;
- s = p = eval_to_string(buf, NULL, FALSE);
- --emsg_skip;
+ STRCPY(buf, "b:keymap_name"); // must be writable
+ emsg_skip++;
+ s = p = eval_to_string(buf, NULL, false);
+ emsg_skip--;
curbuf = old_curbuf;
curwin = old_curwin;
if (p == NULL || *p == NUL) {
@@ -5299,13 +5426,9 @@ get_keymap_str (
* Redraw the status line or ruler of window "wp".
* When "wp" is NULL redraw the tab pages line from 'tabline'.
*/
-static void
-win_redr_custom (
- win_T *wp,
- bool draw_ruler
-)
+static void win_redr_custom(win_T *wp, bool draw_ruler)
{
- static int entered = FALSE;
+ static bool entered = false;
int attr;
int curattr;
int row;
@@ -5316,12 +5439,12 @@ win_redr_custom (
int len;
int fillchar;
char_u buf[MAXPATHL];
- char_u *stl;
- char_u *p;
+ char_u *stl;
+ char_u *p;
stl_hlrec_t *hltab;
StlClickRecord *tabtab;
int use_sandbox = false;
- win_T *ewp;
+ win_T *ewp;
int p_crb_save;
ScreenGrid *grid = &default_grid;
@@ -5329,13 +5452,14 @@ win_redr_custom (
/* There is a tiny chance that this gets called recursively: When
* redrawing a status line triggers redrawing the ruler or tabline.
* Avoid trouble by not allowing recursion. */
- if (entered)
+ if (entered) {
return;
- entered = TRUE;
+ }
+ entered = true;
- /* setup environment for the task at hand */
+ // setup environment for the task at hand
if (wp == NULL) {
- /* Use 'tabline'. Always at the first line of the screen. */
+ // Use 'tabline'. Always at the first line of the screen.
stl = p_tal;
row = 0;
fillchar = ' ';
@@ -5349,15 +5473,19 @@ win_redr_custom (
if (draw_ruler) {
stl = p_ruf;
- /* advance past any leading group spec - implicit in ru_col */
+ // advance past any leading group spec - implicit in ru_col
if (*stl == '%') {
- if (*++stl == '-')
+ if (*++stl == '-') {
stl++;
- if (atoi((char *)stl))
- while (ascii_isdigit(*stl))
+ }
+ if (atoi((char *)stl)) {
+ while (ascii_isdigit(*stl)) {
stl++;
- if (*stl++ != '(')
+ }
+ }
+ if (*stl++ != '(') {
stl = p_ruf;
+ }
}
col = ru_col - (Columns - wp->w_width);
if (col < (wp->w_width + 1) / 2) {
@@ -5374,19 +5502,21 @@ win_redr_custom (
use_sandbox = was_set_insecurely(wp, (char_u *)"rulerformat", 0);
} else {
- if (*wp->w_p_stl != NUL)
+ if (*wp->w_p_stl != NUL) {
stl = wp->w_p_stl;
- else
+ } else {
stl = p_stl;
- use_sandbox = was_set_insecurely(
- wp, (char_u *)"statusline", *wp->w_p_stl == NUL ? 0 : OPT_LOCAL);
+ }
+ use_sandbox = was_set_insecurely(wp, (char_u *)"statusline",
+ *wp->w_p_stl == NUL ? 0 : OPT_LOCAL);
}
col += wp->w_wincol;
}
- if (maxwidth <= 0)
+ if (maxwidth <= 0) {
goto theend;
+ }
/* Temporarily reset 'cursorbind', we don't want a side effect from moving
* the cursor away and back. */
@@ -5404,12 +5534,12 @@ win_redr_custom (
ewp->w_p_crb = p_crb_save;
// Make all characters printable.
- p = (char_u *)transstr((const char *)buf);
+ p = (char_u *)transstr((const char *)buf, true);
len = STRLCPY(buf, p, sizeof(buf));
len = (size_t)len < sizeof(buf) ? len : (int)sizeof(buf) - 1;
xfree(p);
- /* fill up with "fillchar" */
+ // fill up with "fillchar"
while (width < maxwidth && len < (int)sizeof(buf) - 1) {
len += utf_char2bytes(fillchar, buf + len);
width++;
@@ -5429,14 +5559,15 @@ win_redr_custom (
col += vim_strnsize(p, textlen);
p = hltab[n].start;
- if (hltab[n].userhl == 0)
+ if (hltab[n].userhl == 0) {
curattr = attr;
- else if (hltab[n].userhl < 0)
+ } else if (hltab[n].userhl < 0) {
curattr = syn_id2attr(-hltab[n].userhl);
- else if (wp != NULL && wp != curwin && wp->w_status_height != 0)
+ } else if (wp != NULL && wp != curwin && wp->w_status_height != 0) {
curattr = highlight_stlnc[hltab[n].userhl - 1];
- else
+ } else {
curattr = highlight_user[hltab[n].userhl - 1];
+ }
}
// Make sure to use an empty string instead of p, if p is beyond buf + len.
grid_puts(grid, p >= buf + len ? (char_u *)"" : p, row, col,
@@ -5453,11 +5584,11 @@ win_redr_custom (
.type = kStlClickDisabled,
};
for (n = 0; tabtab[n].start != NULL; n++) {
- len += vim_strnsize(p, (int)(tabtab[n].start - (char *) p));
+ len += vim_strnsize(p, (int)(tabtab[n].start - (char *)p));
while (col < len) {
tab_page_click_defs[col++] = cur_click_def;
}
- p = (char_u *) tabtab[n].start;
+ p = (char_u *)tabtab[n].start;
cur_click_def = tabtab[n].def;
}
while (col < Columns) {
@@ -5466,7 +5597,7 @@ win_redr_custom (
}
theend:
- entered = FALSE;
+ entered = false;
}
static void win_redr_border(win_T *wp)
@@ -5527,7 +5658,7 @@ static void win_redr_border(win_T *wp)
}
}
-// Low-level functions to manipulate invidual character cells on the
+// Low-level functions to manipulate individual character cells on the
// screen grid.
/// Put a ASCII character in a screen cell.
@@ -5621,8 +5752,7 @@ void grid_putchar(ScreenGrid *grid, int c, int row, int col, int attr)
/// get a single character directly from grid.chars into "bytes[]".
/// Also return its attribute in *attrp;
-void grid_getbytes(ScreenGrid *grid, int row, int col, char_u *bytes,
- int *attrp)
+void grid_getbytes(ScreenGrid *grid, int row, int col, char_u *bytes, int *attrp)
{
unsigned off;
@@ -5669,22 +5799,21 @@ void grid_put_schar(ScreenGrid *grid, int row, int col, char_u *schar, int attr)
assert(put_dirty_row == row);
unsigned int off = grid->line_offset[row] + col;
if (grid->attrs[off] != attr || schar_cmp(grid->chars[off], schar)) {
- schar_copy(grid->chars[off], schar);
- grid->attrs[off] = attr;
+ schar_copy(grid->chars[off], schar);
+ grid->attrs[off] = attr;
- put_dirty_first = MIN(put_dirty_first, col);
- // TODO(bfredl): Y U NO DOUBLEWIDTH?
- put_dirty_last = MAX(put_dirty_last, col+1);
+ put_dirty_first = MIN(put_dirty_first, col);
+ // TODO(bfredl): Y U NO DOUBLEWIDTH?
+ put_dirty_last = MAX(put_dirty_last, col+1);
}
}
/// like grid_puts(), but output "text[len]". When "len" is -1 output up to
/// a NUL.
-void grid_puts_len(ScreenGrid *grid, char_u *text, int textlen, int row,
- int col, int attr)
+void grid_puts_len(ScreenGrid *grid, char_u *text, int textlen, int row, int col, int attr)
{
unsigned off;
- char_u *ptr = text;
+ char_u *ptr = text;
int len = textlen;
int c;
unsigned max_off;
@@ -5693,7 +5822,7 @@ void grid_puts_len(ScreenGrid *grid, char_u *text, int textlen, int row,
int u8c = 0;
int u8cc[MAX_MCO];
int clear_next_cell = FALSE;
- int prev_c = 0; /* previous Arabic character */
+ int prev_c = 0; // previous Arabic character
int pc, nc, nc1;
int pcc[MAX_MCO];
int need_redraw;
@@ -5786,7 +5915,7 @@ void grid_puts_len(ScreenGrid *grid, char_u *text, int textlen, int row,
if (clear_next_cell) {
clear_next_cell = false;
} else if ((len < 0 ? ptr[mbyte_blen] == NUL
- : ptr + mbyte_blen >= text + len)
+ : ptr + mbyte_blen >= text + len)
&& ((mbyte_cells == 1
&& grid_off2cells(grid, off, max_off) > 1)
|| (mbyte_cells == 2
@@ -5885,10 +6014,11 @@ static void init_search_hl(win_T *wp)
matchitem_T *cur = wp->w_match_head;
while (cur != NULL) {
cur->hl.rm = cur->match;
- if (cur->hlg_id == 0)
+ if (cur->hlg_id == 0) {
cur->hl.attr = 0;
- else
+ } else {
cur->hl.attr = syn_id2attr(cur->hlg_id);
+ }
cur->hl.buf = wp->w_buffer;
cur->hl.lnum = 0;
cur->hl.first_lnum = 0;
@@ -5911,7 +6041,7 @@ static void prepare_search_hl(win_T *wp, linenr_T lnum)
FUNC_ATTR_NONNULL_ALL
{
matchitem_T *cur; // points to the match list
- match_T *shl; // points to search_hl or a match
+ match_T *shl; // points to search_hl or a match
bool shl_flag; // flag to indicate whether search_hl
// has been processed or not
@@ -5942,8 +6072,8 @@ static void prepare_search_hl(win_T *wp, linenr_T lnum)
if (cur != NULL) {
cur->pos.cur = 0;
}
- bool pos_inprogress = true; // mark that a position match search is
- // in progress
+ bool pos_inprogress = true; // mark that a position match search is
+ // in progress
int n = 0;
while (shl->first_lnum < lnum && (shl->rm.regprog != NULL
|| (cur != NULL && pos_inprogress))) {
@@ -5961,27 +6091,24 @@ static void prepare_search_hl(win_T *wp, linenr_T lnum)
}
}
}
- if (shl != &search_hl && cur != NULL)
+ if (shl != &search_hl && cur != NULL) {
cur = cur->next;
+ }
}
}
-/*
- * Search for a next 'hlsearch' or match.
- * Uses shl->buf.
- * Sets shl->lnum and shl->rm contents.
- * Note: Assumes a previous match is always before "lnum", unless
- * shl->lnum is zero.
- * Careful: Any pointers for buffer lines will become invalid.
- */
-static void
-next_search_hl (
- win_T *win,
- match_T *shl, /* points to search_hl or a match */
- linenr_T lnum,
- colnr_T mincol, /* minimal column for a match */
- matchitem_T *cur /* to retrieve match positions if any */
-)
+/// Search for a next 'hlsearch' or match.
+/// Uses shl->buf.
+/// Sets shl->lnum and shl->rm contents.
+/// Note: Assumes a previous match is always before "lnum", unless
+/// shl->lnum is zero.
+/// Careful: Any pointers for buffer lines will become invalid.
+///
+/// @param shl points to search_hl or a match
+/// @param mincol minimal column for a match
+/// @param cur to retrieve match positions if any
+static void next_search_hl(win_T *win, match_T *shl, linenr_T lnum, colnr_T mincol,
+ matchitem_T *cur)
FUNC_ATTR_NONNULL_ARG(2)
{
linenr_T l;
@@ -6001,10 +6128,11 @@ next_search_hl (
// 2. If the previous match includes "mincol", use it.
// 3. Continue after the previous match.
l = shl->lnum + shl->rm.endpos[0].lnum - shl->rm.startpos[0].lnum;
- if (lnum > l)
+ if (lnum > l) {
shl->lnum = 0;
- else if (lnum < l || shl->rm.endpos[0].col > mincol)
+ } else if (lnum < l || shl->rm.endpos[0].col > mincol) {
return;
+ }
}
/*
@@ -6015,7 +6143,7 @@ next_search_hl (
for (;; ) {
// Stop searching after passing the time limit.
if (profile_passed_limit(shl->tm)) {
- shl->lnum = 0; /* no match found in time */
+ shl->lnum = 0; // no match found in time
break;
}
// Three situations:
@@ -6028,10 +6156,10 @@ next_search_hl (
} else if (vim_strchr(p_cpo, CPO_SEARCH) == NULL
|| (shl->rm.endpos[0].lnum == 0
&& shl->rm.endpos[0].col <= shl->rm.startpos[0].col)) {
- char_u *ml;
+ char_u *ml;
matchcol = shl->rm.startpos[0].col;
- ml = ml_get_buf(shl->buf, lnum, FALSE) + matchcol;
+ ml = ml_get_buf(shl->buf, lnum, false) + matchcol;
if (*ml == NUL) {
++matchcol;
shl->lnum = 0;
@@ -6067,7 +6195,7 @@ next_search_hl (
}
shl->rm.regprog = NULL;
shl->lnum = 0;
- got_int = FALSE; // avoid the "Type :quit to exit Vim" message
+ got_int = FALSE; // avoid the "Type :quit to exit Vim" message
break;
}
} else if (cur != NULL) {
@@ -6090,15 +6218,12 @@ next_search_hl (
}
}
-/// If there is a match fill "shl" and return one.
-/// Return zero otherwise.
-static int
-next_search_hl_pos(
- match_T *shl, // points to a match
- linenr_T lnum,
- posmatch_T *posmatch, // match positions
- colnr_T mincol // minimal column for a match
-)
+/// @param shl points to a match. Fill on match.
+/// @param posmatch match positions
+/// @param mincol minimal column for a match
+///
+/// @return one on match, otherwise return zero.
+static int next_search_hl_pos(match_T *shl, linenr_T lnum, posmatch_T *posmatch, colnr_T mincol)
FUNC_ATTR_NONNULL_ALL
{
int i;
@@ -6152,8 +6277,8 @@ next_search_hl_pos(
/// Fill the grid from 'start_row' to 'end_row', from 'start_col' to 'end_col'
/// with character 'c1' in first column followed by 'c2' in the other columns.
/// Use attributes 'attr'.
-void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col,
- int end_col, int c1, int c2, int attr)
+void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col, int end_col, int c1,
+ int c2, int attr)
{
schar_T sc;
@@ -6243,11 +6368,9 @@ void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col,
}
}
-/*
- * Check if there should be a delay. Used before clearing or redrawing the
- * screen or the command line.
- */
-void check_for_delay(int check_msg_scroll)
+/// Check if there should be a delay. Used before clearing or redrawing the
+/// screen or the command line.
+void check_for_delay(bool check_msg_scroll)
{
if ((emsg_on_display || (check_msg_scroll && msg_scroll))
&& !did_wait_return
@@ -6391,9 +6514,9 @@ retry:
msg_grid_invalid = true;
}
- win_new_shellsize(); /* fit the windows in the new sized shell */
+ win_new_shellsize(); // fit the windows in the new sized shell
- comp_col(); /* recompute columns for shown command and ruler */
+ comp_col(); // recompute columns for shown command and ruler
// We're changing the size of the screen.
// - Allocate new arrays for default_grid
@@ -6406,8 +6529,8 @@ retry:
// size is wrong.
grid_alloc(&default_grid, Rows, Columns, true, true);
- StlClickDefinition *new_tab_page_click_defs = xcalloc(
- (size_t)Columns, sizeof(*new_tab_page_click_defs));
+ StlClickDefinition *new_tab_page_click_defs =
+ xcalloc((size_t)Columns, sizeof(*new_tab_page_click_defs));
clear_tab_page_click_defs(tab_page_click_defs, tab_page_click_defs_size);
xfree(tab_page_click_defs);
@@ -6431,9 +6554,9 @@ retry:
* in case applying autocommands always changes Rows or Columns.
*/
if (starting == 0 && ++retry_count <= 3) {
- apply_autocmds(EVENT_VIMRESIZED, NULL, NULL, FALSE, curbuf);
- /* In rare cases, autocommands may have altered Rows or Columns,
- * jump back to check if we need to allocate the screen again. */
+ apply_autocmds(EVENT_VIMRESIZED, NULL, NULL, false, curbuf);
+ // In rare cases, autocommands may have altered Rows or Columns,
+ // jump back to check if we need to allocate the screen again.
goto retry;
}
@@ -6515,8 +6638,7 @@ void screen_free_all_mem(void)
///
/// @param[out] tpcd Table to clear.
/// @param[in] tpcd_size Size of the table.
-void clear_tab_page_click_defs(StlClickDefinition *const tpcd,
- const long tpcd_size)
+void clear_tab_page_click_defs(StlClickDefinition *const tpcd, const long tpcd_size)
{
if (tpcd != NULL) {
for (long i = 0; i < tpcd_size; i++) {
@@ -6524,7 +6646,7 @@ void clear_tab_page_click_defs(StlClickDefinition *const tpcd,
xfree(tpcd[i].func);
}
}
- memset(tpcd, 0, (size_t) tpcd_size * sizeof(tpcd[0]));
+ memset(tpcd, 0, (size_t)tpcd_size * sizeof(tpcd[0]));
}
}
@@ -6542,7 +6664,7 @@ void screenclear(void)
// blank out the default grid
for (i = 0; i < default_grid.Rows; i++) {
grid_clear_line(&default_grid, default_grid.line_offset[i],
- (int)default_grid.Columns, true);
+ default_grid.Columns, true);
default_grid.line_wraps[i] = false;
}
@@ -6629,8 +6751,8 @@ void setcursor(void)
// With 'rightleft' set and the cursor on a double-wide character,
// position it on the leftmost column.
col = curwin->w_width_inner - curwin->w_wcol
- - ((utf_ptr2cells(get_cursor_pos_ptr()) == 2
- && vim_isprintc(gchar_cursor())) ? 2 : 1);
+ - ((utf_ptr2cells(get_cursor_pos_ptr()) == 2
+ && vim_isprintc(gchar_cursor())) ? 2 : 1);
}
screen_adjust_grid(&grid, &row, &col);
@@ -6679,8 +6801,7 @@ void win_scroll_lines(win_T *wp, int row, int line_count)
/// 'col' is the column from with we start inserting.
//
/// 'row', 'col' and 'end' are relative to the start of the region.
-void grid_ins_lines(ScreenGrid *grid, int row, int line_count, int end, int col,
- int width)
+void grid_ins_lines(ScreenGrid *grid, int row, int line_count, int end, int col, int width)
{
int i;
int j;
@@ -6716,7 +6837,7 @@ void grid_ins_lines(ScreenGrid *grid, int row, int line_count, int end, int col,
}
grid->line_offset[j + line_count] = temp;
grid->line_wraps[j + line_count] = false;
- grid_clear_line(grid, temp, (int)grid->Columns, false);
+ grid_clear_line(grid, temp, grid->Columns, false);
}
}
@@ -6731,8 +6852,7 @@ void grid_ins_lines(ScreenGrid *grid, int row, int line_count, int end, int col,
/// 'end' is the line after the scrolled part. Normally it is Rows.
/// When scrolling region used 'off' is the offset from the top for the region.
/// 'row' and 'end' are relative to the start of the region.
-void grid_del_lines(ScreenGrid *grid, int row, int line_count, int end, int col,
- int width)
+void grid_del_lines(ScreenGrid *grid, int row, int line_count, int end, int col, int width)
{
int j;
int i;
@@ -6769,7 +6889,7 @@ void grid_del_lines(ScreenGrid *grid, int row, int line_count, int end, int col,
}
grid->line_offset[j - line_count] = temp;
grid->line_wraps[j - line_count] = false;
- grid_clear_line(grid, temp, (int)grid->Columns, false);
+ grid_clear_line(grid, temp, grid->Columns, false);
}
}
@@ -6783,8 +6903,8 @@ void grid_del_lines(ScreenGrid *grid, int row, int line_count, int end, int col,
// Show the current mode and ruler.
//
-// If clear_cmdline is TRUE, clear the rest of the cmdline.
-// If clear_cmdline is FALSE there may be a message there that needs to be
+// If clear_cmdline is true, clear the rest of the cmdline.
+// If clear_cmdline is false there may be a message there that needs to be
// cleared only if a mode is shown.
// Return the length of the message (0 if no message).
int showmode(void)
@@ -6793,7 +6913,6 @@ int showmode(void)
int length = 0;
int do_mode;
int attr;
- int nwr_save;
int sub_attr;
if (ui_has(kUIMessages) && clear_cmdline) {
@@ -6815,26 +6934,26 @@ int showmode(void)
// Call char_avail() only when we are going to show something, because
// it takes a bit of time.
if (!redrawing() || (char_avail() && !KeyTyped) || msg_silent != 0) {
- redraw_cmdline = TRUE; /* show mode later */
+ redraw_cmdline = true; // show mode later
return 0;
}
- nwr_save = need_wait_return;
+ bool nwr_save = need_wait_return;
- /* wait a bit before overwriting an important message */
- check_for_delay(FALSE);
+ // wait a bit before overwriting an important message
+ check_for_delay(false);
- /* if the cmdline is more than one line high, erase top lines */
+ // if the cmdline is more than one line high, erase top lines
need_clear = clear_cmdline;
if (clear_cmdline && cmdline_row < Rows - 1) {
msg_clr_cmdline(); // will reset clear_cmdline
}
- /* Position on the last line in the window, column 0 */
+ // Position on the last line in the window, column 0
msg_pos_mode();
attr = HL_ATTR(HLF_CM); // Highlight mode
- // When the screen is too narrow to show the entire mode messsage,
+ // When the screen is too narrow to show the entire mode message,
// avoid scrolling and truncate instead.
msg_no_more = true;
int save_lines_left = lines_left;
@@ -6856,8 +6975,9 @@ int showmode(void)
length -= vim_strsize(edit_submode_extra);
}
if (length > 0) {
- if (edit_submode_pre != NULL)
+ if (edit_submode_pre != NULL) {
length -= vim_strsize(edit_submode_pre);
+ }
if (length - vim_strsize(edit_submode) > 0) {
if (edit_submode_pre != NULL) {
msg_puts_attr((const char *)edit_submode_pre, attr);
@@ -6866,7 +6986,7 @@ int showmode(void)
}
if (edit_submode_extra != NULL) {
MSG_PUTS_ATTR(" ", attr); // Add a space in between.
- if ((int)edit_submode_highl < (int)HLF_COUNT) {
+ if ((int)edit_submode_highl < HLF_COUNT) {
sub_attr = win_hl_attr(curwin, edit_submode_highl);
} else {
sub_attr = attr;
@@ -6877,13 +6997,14 @@ int showmode(void)
} else {
if (State & TERM_FOCUS) {
MSG_PUTS_ATTR(_(" TERMINAL"), attr);
- } else if (State & VREPLACE_FLAG)
+ } else if (State & VREPLACE_FLAG) {
MSG_PUTS_ATTR(_(" VREPLACE"), attr);
- else if (State & REPLACE_FLAG)
+ } else if (State & REPLACE_FLAG) {
MSG_PUTS_ATTR(_(" REPLACE"), attr);
- else if (State & INSERT) {
- if (p_ri)
+ } else if (State & INSERT) {
+ if (p_ri) {
MSG_PUTS_ATTR(_(" REVERSE"), attr);
+ }
MSG_PUTS_ATTR(_(" INSERT"), attr);
} else if (restart_edit == 'I' || restart_edit == 'i'
|| restart_edit == 'a') {
@@ -6904,8 +7025,9 @@ int showmode(void)
MSG_PUTS_ATTR(NameBuff, attr);
}
}
- if ((State & INSERT) && p_paste)
+ if ((State & INSERT) && p_paste) {
MSG_PUTS_ATTR(_(" (paste)"), attr);
+ }
if (VIsual_active) {
char *p;
@@ -6915,12 +7037,18 @@ int showmode(void)
switch ((VIsual_select ? 4 : 0)
+ (VIsual_mode == Ctrl_V) * 2
+ (VIsual_mode == 'V')) {
- case 0: p = N_(" VISUAL"); break;
- case 1: p = N_(" VISUAL LINE"); break;
- case 2: p = N_(" VISUAL BLOCK"); break;
- case 4: p = N_(" SELECT"); break;
- case 5: p = N_(" SELECT LINE"); break;
- default: p = N_(" SELECT BLOCK"); break;
+ case 0:
+ p = N_(" VISUAL"); break;
+ case 1:
+ p = N_(" VISUAL LINE"); break;
+ case 2:
+ p = N_(" VISUAL BLOCK"); break;
+ case 4:
+ p = N_(" SELECT"); break;
+ case 5:
+ p = N_(" SELECT LINE"); break;
+ default:
+ p = N_(" SELECT BLOCK"); break;
}
MSG_PUTS_ATTR(_(p), attr);
}
@@ -6936,10 +7064,11 @@ int showmode(void)
need_clear = true;
}
- mode_displayed = TRUE;
- if (need_clear || clear_cmdline)
+ mode_displayed = true;
+ if (need_clear || clear_cmdline) {
msg_clr_eos();
- msg_didout = FALSE; /* overwrite this message */
+ }
+ msg_didout = false; // overwrite this message
length = msg_col;
msg_col = 0;
msg_no_more = false;
@@ -6950,12 +7079,13 @@ int showmode(void)
msg_clr_cmdline();
}
- // NB: also handles clearing the showmode if it was emtpy or disabled
+ // NB: also handles clearing the showmode if it was empty or disabled
msg_ext_flush_showmode();
- /* In Visual mode the size of the selected area must be redrawn. */
- if (VIsual_active)
+ // In Visual mode the size of the selected area must be redrawn.
+ if (VIsual_active) {
clear_showcmd();
+ }
// If the last window has no status line, the ruler is after the mode
// message and must be redrawn
@@ -7029,15 +7159,15 @@ void draw_tabline(void)
int col = 0;
int scol = 0;
int attr;
- win_T *wp;
- win_T *cwp;
+ win_T *wp;
+ win_T *cwp;
int wincount;
int modified;
int c;
int len;
int attr_nosel = HL_ATTR(HLF_TP);
int attr_fill = HL_ATTR(HLF_TPF);
- char_u *p;
+ char_u *p;
int room;
int use_sep_chars = (t_colors < 8
);
@@ -7052,15 +7182,16 @@ void draw_tabline(void)
return;
}
- if (tabline_height() < 1)
+ if (tabline_height() < 1) {
return;
+ }
// Init TabPageIdxs[] to zero: Clicking outside of tabs has no effect.
assert(Columns == tab_page_click_defs_size);
clear_tab_page_click_defs(tab_page_click_defs, tab_page_click_defs_size);
- /* Use the 'tabline' option if it's set. */
+ // Use the 'tabline' option if it's set.
if (*p_tal != NUL) {
int saved_did_emsg = did_emsg;
@@ -7146,7 +7277,7 @@ void draw_tabline(void)
room = scol - col + tabwidth - 1;
if (room > 0) {
- /* Get buffer name in NameBuff[] */
+ // Get buffer name in NameBuff[]
get_trans_bufname(cwp->w_buffer);
(void)shorten_dir(NameBuff);
len = vim_strsize(NameBuff);
@@ -7176,13 +7307,14 @@ void draw_tabline(void)
}
}
- if (use_sep_chars)
+ if (use_sep_chars) {
c = '_';
- else
+ } else {
c = ' ';
+ }
grid_fill(&default_grid, 0, 1, col, Columns, c, c, attr_fill);
- /* Put an "X" for closing the current tab if there are several. */
+ // Put an "X" for closing the current tab if there are several.
if (first_tabpage->tp_next != NULL) {
grid_putchar(&default_grid, 'X', 0, Columns - 1, attr_nosel);
tab_page_click_defs[Columns - 1] = (StlClickDefinition) {
@@ -7195,7 +7327,7 @@ void draw_tabline(void)
/* Reset the flag here again, in case evaluating 'tabline' causes it to be
* set. */
- redraw_tabline = FALSE;
+ redraw_tabline = false;
}
void ui_ext_tabline_update(void)
@@ -7237,10 +7369,11 @@ void ui_ext_tabline_update(void)
*/
void get_trans_bufname(buf_T *buf)
{
- if (buf_spname(buf) != NULL)
+ if (buf_spname(buf) != NULL) {
STRLCPY(NameBuff, buf_spname(buf), MAXPATHL);
- else
+ } else {
home_replace(buf, buf->b_fname, NameBuff, MAXPATHL, TRUE);
+ }
trans_characters(NameBuff, MAXPATHL);
}
@@ -7299,14 +7432,14 @@ int messaging(void)
return !(p_lz && char_avail() && !KeyTyped);
}
-/*
- * Show current status info in ruler and various other places
- * If always is FALSE, only show ruler if position has changed.
- */
-void showruler(int always)
+/// Show current status info in ruler and various other places
+///
+/// @param always if false, only show ruler if position has changed.
+void showruler(bool always)
{
- if (!always && !redrawing())
+ if (!always && !redrawing()) {
return;
+ }
if ((*p_stl != NUL || *curwin->w_p_stl != NUL) && curwin->w_status_height) {
redraw_custom_statusline(curwin);
} else {
@@ -7315,15 +7448,16 @@ void showruler(int always)
if (need_maketitle
|| (p_icon && (stl_syntax & STL_IN_ICON))
- || (p_title && (stl_syntax & STL_IN_TITLE))
- )
+ || (p_title && (stl_syntax & STL_IN_TITLE))) {
maketitle();
- /* Redraw the tab pages line if needed. */
- if (redraw_tabline)
+ }
+ // Redraw the tab pages line if needed.
+ if (redraw_tabline) {
draw_tabline();
+ }
}
-static void win_redr_ruler(win_T *wp, int always)
+static void win_redr_ruler(win_T *wp, bool always)
{
static bool did_show_ext_ruler = false;
@@ -7336,8 +7470,9 @@ static void win_redr_ruler(win_T *wp, int always)
* Check if cursor.lnum is valid, since win_redr_ruler() may be called
* after deleting lines, before cursor.lnum is corrected.
*/
- if (wp->w_cursor.lnum > wp->w_buffer->b_ml.ml_line_count)
+ if (wp->w_cursor.lnum > wp->w_buffer->b_ml.ml_line_count) {
return;
+ }
// Don't draw the ruler while doing insert-completion, it might overwrite
// the (long) mode message.
@@ -7365,24 +7500,24 @@ static void win_redr_ruler(win_T *wp, int always)
*/
int empty_line = FALSE;
if (!(State & INSERT)
- && *ml_get_buf(wp->w_buffer, wp->w_cursor.lnum, FALSE) == NUL)
+ && *ml_get_buf(wp->w_buffer, wp->w_cursor.lnum, FALSE) == NUL) {
empty_line = TRUE;
+ }
/*
* Only draw the ruler when something changed.
*/
validate_virtcol_win(wp);
- if ( redraw_cmdline
- || always
- || wp->w_cursor.lnum != wp->w_ru_cursor.lnum
- || wp->w_cursor.col != wp->w_ru_cursor.col
- || wp->w_virtcol != wp->w_ru_virtcol
- || wp->w_cursor.coladd != wp->w_ru_cursor.coladd
- || wp->w_topline != wp->w_ru_topline
- || wp->w_buffer->b_ml.ml_line_count != wp->w_ru_line_count
- || wp->w_topfill != wp->w_ru_topfill
- || empty_line != wp->w_ru_empty) {
-
+ if (redraw_cmdline
+ || always
+ || wp->w_cursor.lnum != wp->w_ru_cursor.lnum
+ || wp->w_cursor.col != wp->w_ru_cursor.col
+ || wp->w_virtcol != wp->w_ru_virtcol
+ || wp->w_cursor.coladd != wp->w_ru_cursor.coladd
+ || wp->w_topline != wp->w_ru_topline
+ || wp->w_buffer->b_ml.ml_line_count != wp->w_ru_line_count
+ || wp->w_topfill != wp->w_ru_topfill
+ || empty_line != wp->w_ru_empty) {
int width;
int row;
int fillchar;
@@ -7420,12 +7555,12 @@ static void win_redr_ruler(win_T *wp, int always)
* To avoid portability problems we use strlen() here.
*/
vim_snprintf((char *)buffer, RULER_BUF_LEN, "%" PRId64 ",",
- (wp->w_buffer->b_ml.ml_flags & ML_EMPTY) ? (int64_t)0L
- : (int64_t)wp->w_cursor.lnum);
+ (wp->w_buffer->b_ml.ml_flags & ML_EMPTY) ? (int64_t)0L
+ : (int64_t)wp->w_cursor.lnum);
size_t len = STRLEN(buffer);
col_print(buffer + len, RULER_BUF_LEN - len,
- empty_line ? 0 : (int)wp->w_cursor.col + 1,
- (int)virtcol + 1);
+ empty_line ? 0 : (int)wp->w_cursor.col + 1,
+ (int)virtcol + 1);
/*
* Add a "50%" if there is room for it.
@@ -7513,8 +7648,9 @@ int number_width(win_T *wp)
lnum = wp->w_buffer->b_ml.ml_line_count;
}
- if (lnum == wp->w_nrwidth_line_count)
+ if (lnum == wp->w_nrwidth_line_count) {
return wp->w_nrwidth_width;
+ }
wp->w_nrwidth_line_count = lnum;
n = 0;
@@ -7539,22 +7675,66 @@ int number_width(win_T *wp)
return n;
}
+/// Used when 'cursorlineopt' contains "screenline": compute the margins between
+/// which the highlighting is used.
+static void margin_columns_win(win_T *wp, int *left_col, int *right_col)
+{
+ // cache previous calculations depending on w_virtcol
+ static int saved_w_virtcol;
+ static win_T *prev_wp;
+ static int prev_left_col;
+ static int prev_right_col;
+ static int prev_col_off;
+
+ int cur_col_off = win_col_off(wp);
+ int width1;
+ int width2;
+
+ if (saved_w_virtcol == wp->w_virtcol && prev_wp == wp
+ && prev_col_off == cur_col_off) {
+ *right_col = prev_right_col;
+ *left_col = prev_left_col;
+ return;
+ }
+
+ width1 = wp->w_width - cur_col_off;
+ width2 = width1 + win_col_off2(wp);
+
+ *left_col = 0;
+ *right_col = width1;
+
+ if (wp->w_virtcol >= (colnr_T)width1) {
+ *right_col = width1 + ((wp->w_virtcol - width1) / width2 + 1) * width2;
+ }
+ if (wp->w_virtcol >= (colnr_T)width1 && width2 > 0) {
+ *left_col = (wp->w_virtcol - width1) / width2 * width2 + width1;
+ }
+
+ // cache values
+ prev_left_col = *left_col;
+ prev_right_col = *right_col;
+ prev_wp = wp;
+ saved_w_virtcol = wp->w_virtcol;
+ prev_col_off = cur_col_off;
+}
+
/// Set dimensions of the Nvim application "shell".
void screen_resize(int width, int height)
{
- static int busy = FALSE;
+ static bool recursive = false;
// Avoid recursiveness, can happen when setting the window size causes
// another window-changed signal.
- if (updating_screen || busy) {
+ if (updating_screen || recursive) {
return;
}
- if (width < 0 || height < 0) /* just checking... */
+ if (width < 0 || height < 0) { // just checking...
return;
+ }
if (State == HITRETURN || State == SETWSIZE) {
- /* postpone the resizing */
+ // postpone the resizing
State = SETWSIZE;
return;
}
@@ -7563,10 +7743,11 @@ void screen_resize(int width, int height)
* buffer has already been closed and removing a scrollbar causes a resize
* event. Don't resize then, it will happen after entering another buffer.
*/
- if (curwin->w_buffer == NULL)
+ if (curwin->w_buffer == NULL) {
return;
+ }
- ++busy;
+ recursive = true;
Rows = height;
Columns = width;
@@ -7585,7 +7766,7 @@ void screen_resize(int width, int height)
/* The window layout used to be adjusted here, but it now happens in
* screenalloc() (also invoked from screenclear()). That is because the
- * "busy" check above may skip this, but not screenalloc(). */
+ * "recursive" check above may skip this, but not screenalloc(). */
if (State != ASKMORE && State != EXTERNCMD && State != CONFIRM) {
screenclear();
@@ -7617,8 +7798,9 @@ void screen_resize(int width, int height)
ui_comp_set_screen_valid(true);
repeat_message();
} else {
- if (curwin->w_p_scb)
- do_check_scrollbind(TRUE);
+ if (curwin->w_p_scb) {
+ do_check_scrollbind(true);
+ }
if (State & CMDLINE) {
redraw_popupmenu = false;
update_screen(NOT_VALID);
@@ -7643,7 +7825,7 @@ void screen_resize(int width, int height)
}
ui_flush();
}
- busy--;
+ recursive = false;
}
/// Check if the new Nvim application "shell" dimensions are valid.
@@ -7701,4 +7883,3 @@ win_T *get_win_by_grid_handle(handle_T handle)
return NULL;
}
-
diff --git a/src/nvim/search.c b/src/nvim/search.c
index 82fc0f9d8e..3d30932d69 100644
--- a/src/nvim/search.c
+++ b/src/nvim/search.c
@@ -7,13 +7,11 @@
#include <assert.h>
#include <inttypes.h>
+#include <limits.h> // for INT_MAX on MSVC
#include <stdbool.h>
#include <string.h>
-#include <limits.h> /* for INT_MAX on MSVC */
#include "nvim/ascii.h"
-#include "nvim/vim.h"
-#include "nvim/search.h"
#include "nvim/buffer.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
@@ -34,17 +32,19 @@
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/move.h"
#include "nvim/mouse.h"
+#include "nvim/move.h"
#include "nvim/normal.h"
#include "nvim/option.h"
+#include "nvim/os/time.h"
#include "nvim/path.h"
#include "nvim/regexp.h"
#include "nvim/screen.h"
+#include "nvim/search.h"
#include "nvim/strings.h"
#include "nvim/ui.h"
+#include "nvim/vim.h"
#include "nvim/window.h"
-#include "nvim/os/time.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "search.c.generated.h"
@@ -79,12 +79,12 @@
static struct spat spats[2] =
{
// Last used search pattern
- [0] = {NULL, true, false, 0, {'/', false, false, 0L}, NULL},
+ [0] = { NULL, true, false, 0, { '/', false, false, 0L }, NULL },
// Last used substitute pattern
- [1] = {NULL, true, false, 0, {'/', false, false, 0L}, NULL}
+ [1] = { NULL, true, false, 0, { '/', false, false, 0L }, NULL }
};
-static int last_idx = 0; /* index in spats[] for RE_LAST */
+static int last_idx = 0; // index in spats[] for RE_LAST
static char_u lastc[2] = { NUL, NUL }; // last character searched for
static Direction lastcdir = FORWARD; // last direction of character search
@@ -97,100 +97,100 @@ static struct spat saved_spats[2];
static int saved_spats_last_idx = 0;
static bool saved_spats_no_hlsearch = false;
-static char_u *mr_pattern = NULL; // pattern used by search_regcomp()
-static int mr_pattern_alloced = false; // mr_pattern was allocated
+static char_u *mr_pattern = NULL; // pattern used by search_regcomp()
+static bool mr_pattern_alloced = false; // mr_pattern was allocated
/*
* Type used by find_pattern_in_path() to remember which included files have
* been searched already.
*/
typedef struct SearchedFile {
- FILE *fp; /* File pointer */
- char_u *name; /* Full name of file */
- linenr_T lnum; /* Line we were up to in file */
- int matched; /* Found a match in this file */
+ FILE *fp; // File pointer
+ char_u *name; // Full name of file
+ linenr_T lnum; // Line we were up to in file
+ int matched; // Found a match in this file
} SearchedFile;
-/*
- * translate search pattern for vim_regcomp()
- *
- * pat_save == RE_SEARCH: save pat in spats[RE_SEARCH].pat (normal search cmd)
- * pat_save == RE_SUBST: save pat in spats[RE_SUBST].pat (:substitute command)
- * pat_save == RE_BOTH: save pat in both patterns (:global command)
- * pat_use == RE_SEARCH: use previous search pattern if "pat" is NULL
- * pat_use == RE_SUBST: use previous substitute pattern if "pat" is NULL
- * pat_use == RE_LAST: use last used pattern if "pat" is NULL
- * options & SEARCH_HIS: put search string in history
- * options & SEARCH_KEEP: keep previous search pattern
- *
- * returns FAIL if failed, OK otherwise.
- */
-int
-search_regcomp(
- char_u *pat,
- int pat_save,
- int pat_use,
- int options,
- regmmatch_T *regmatch /* return: pattern and ignore-case flag */
-)
+/// translate search pattern for vim_regcomp()
+///
+/// pat_save == RE_SEARCH: save pat in spats[RE_SEARCH].pat (normal search cmd)
+/// pat_save == RE_SUBST: save pat in spats[RE_SUBST].pat (:substitute command)
+/// pat_save == RE_BOTH: save pat in both patterns (:global command)
+/// pat_use == RE_SEARCH: use previous search pattern if "pat" is NULL
+/// pat_use == RE_SUBST: use previous substitute pattern if "pat" is NULL
+/// pat_use == RE_LAST: use last used pattern if "pat" is NULL
+/// options & SEARCH_HIS: put search string in history
+/// options & SEARCH_KEEP: keep previous search pattern
+///
+/// @param regmatch return: pattern and ignore-case flag
+///
+/// @return FAIL if failed, OK otherwise.
+int search_regcomp(char_u *pat, int pat_save, int pat_use, int options, regmmatch_T *regmatch)
{
int magic;
int i;
- rc_did_emsg = FALSE;
+ rc_did_emsg = false;
magic = p_magic;
/*
* If no pattern given, use a previously defined pattern.
*/
if (pat == NULL || *pat == NUL) {
- if (pat_use == RE_LAST)
+ if (pat_use == RE_LAST) {
i = last_idx;
- else
+ } else {
i = pat_use;
- if (spats[i].pat == NULL) { /* pattern was never defined */
- if (pat_use == RE_SUBST)
+ }
+ if (spats[i].pat == NULL) { // pattern was never defined
+ if (pat_use == RE_SUBST) {
EMSG(_(e_nopresub));
- else
+ } else {
EMSG(_(e_noprevre));
- rc_did_emsg = TRUE;
+ }
+ rc_did_emsg = true;
return FAIL;
}
pat = spats[i].pat;
magic = spats[i].magic;
no_smartcase = spats[i].no_scs;
- } else if (options & SEARCH_HIS) /* put new pattern in history */
- add_to_history(HIST_SEARCH, pat, TRUE, NUL);
+ } else if (options & SEARCH_HIS) { // put new pattern in history
+ add_to_history(HIST_SEARCH, pat, true, NUL);
+ }
if (mr_pattern_alloced) {
xfree(mr_pattern);
- mr_pattern_alloced = FALSE;
+ mr_pattern_alloced = false;
}
if (curwin->w_p_rl && *curwin->w_p_rlc == 's') {
mr_pattern = reverse_text(pat);
- mr_pattern_alloced = TRUE;
- } else
+ mr_pattern_alloced = true;
+ } else {
mr_pattern = pat;
+ }
/*
* Save the currently used pattern in the appropriate place,
* unless the pattern should not be remembered.
*/
if (!(options & SEARCH_KEEP) && !cmdmod.keeppatterns) {
- /* search or global command */
- if (pat_save == RE_SEARCH || pat_save == RE_BOTH)
+ // search or global command
+ if (pat_save == RE_SEARCH || pat_save == RE_BOTH) {
save_re_pat(RE_SEARCH, pat, magic);
- /* substitute or global command */
- if (pat_save == RE_SUBST || pat_save == RE_BOTH)
+ }
+ // substitute or global command
+ if (pat_save == RE_SUBST || pat_save == RE_BOTH) {
save_re_pat(RE_SUBST, pat, magic);
+ }
}
regmatch->rmm_ic = ignorecase(pat);
regmatch->rmm_maxcol = 0;
regmatch->regprog = vim_regcomp(pat, magic ? RE_MAGIC : 0);
- if (regmatch->regprog == NULL)
+ if (regmatch->regprog == NULL) {
return FAIL;
+ }
return OK;
}
@@ -237,9 +237,10 @@ void save_re_pat(int idx, char_u *pat, int magic)
spats[idx].timestamp = os_time();
spats[idx].additional_data = NULL;
last_idx = idx;
- /* If 'hlsearch' set and search pat changed: need redraw. */
- if (p_hls)
+ // If 'hlsearch' set and search pat changed: need redraw.
+ if (p_hls) {
redraw_all_later(SOME_VALID);
+ }
set_no_hlsearch(false);
}
}
@@ -254,11 +255,13 @@ void save_search_patterns(void)
{
if (save_level++ == 0) {
saved_spats[0] = spats[0];
- if (spats[0].pat != NULL)
+ if (spats[0].pat != NULL) {
saved_spats[0].pat = vim_strsave(spats[0].pat);
+ }
saved_spats[1] = spats[1];
- if (spats[1].pat != NULL)
+ if (spats[1].pat != NULL) {
saved_spats[1].pat = vim_strsave(spats[1].pat);
+ }
saved_spats_last_idx = last_idx;
saved_spats_no_hlsearch = no_hlsearch;
}
@@ -293,7 +296,7 @@ void free_search_patterns(void)
if (mr_pattern_alloced) {
xfree(mr_pattern);
- mr_pattern_alloced = FALSE;
+ mr_pattern_alloced = false;
mr_pattern = NULL;
}
}
@@ -367,8 +370,8 @@ int ignorecase_opt(char_u *pat, int ic_in, int scs)
{
int ic = ic_in;
if (ic && !no_smartcase && scs
- && !(ctrl_x_mode_not_default() && curbuf->b_p_inf)
- ) {
+ && !(ctrl_x_mode_not_default() &&
+ curbuf->b_p_inf)) {
ic = !pat_has_uppercase(pat);
}
no_smartcase = false;
@@ -429,10 +432,11 @@ void set_last_csearch(int c, char_u *s, int len)
{
*lastc = c;
lastc_bytelen = len;
- if (len)
+ if (len) {
memcpy(lastc_bytes, s, len);
- else
+ } else {
memset(lastc_bytes, 0, sizeof(lastc_bytes));
+ }
}
void set_csearch_direction(Direction cdir)
@@ -466,34 +470,38 @@ void reset_search_dir(void)
void set_last_search_pat(const char_u *s, int idx, int magic, int setlast)
{
free_spat(&spats[idx]);
- /* An empty string means that nothing should be matched. */
- if (*s == NUL)
+ // An empty string means that nothing should be matched.
+ if (*s == NUL) {
spats[idx].pat = NULL;
- else
- spats[idx].pat = (char_u *) xstrdup((char *) s);
+ } else {
+ spats[idx].pat = (char_u *)xstrdup((char *)s);
+ }
spats[idx].timestamp = os_time();
spats[idx].additional_data = NULL;
spats[idx].magic = magic;
- spats[idx].no_scs = FALSE;
+ spats[idx].no_scs = false;
spats[idx].off.dir = '/';
set_vv_searchforward();
spats[idx].off.line = FALSE;
spats[idx].off.end = FALSE;
spats[idx].off.off = 0;
- if (setlast)
+ if (setlast) {
last_idx = idx;
+ }
if (save_level) {
free_spat(&saved_spats[idx]);
saved_spats[idx] = spats[0];
- if (spats[idx].pat == NULL)
+ if (spats[idx].pat == NULL) {
saved_spats[idx].pat = NULL;
- else
+ } else {
saved_spats[idx].pat = vim_strsave(spats[idx].pat);
+ }
saved_spats_last_idx = last_idx;
}
- /* If 'hlsearch' set and search pat changed: need redraw. */
- if (p_hls && idx == last_idx && !no_hlsearch)
+ // If 'hlsearch' set and search pat changed: need redraw.
+ if (p_hls && idx == last_idx && !no_hlsearch) {
redraw_all_later(SOME_VALID);
+ }
}
/*
@@ -507,7 +515,7 @@ void last_pat_prog(regmmatch_T *regmatch)
regmatch->regprog = NULL;
return;
}
- ++emsg_off; /* So it doesn't beep if bad expr */
+ ++emsg_off; // So it doesn't beep if bad expr
(void)search_regcomp((char_u *)"", 0, last_idx, SEARCH_KEEP, regmatch);
--emsg_off;
}
@@ -527,27 +535,21 @@ void last_pat_prog(regmmatch_T *regmatch)
/// if (options & SEARCH_PEEK) check for typed char, cancel search
/// if (options & SEARCH_COL) start at pos->col instead of zero
///
-/// @returns FAIL (zero) for failure, non-zero for success.
-/// the index of the first matching
-/// subpattern plus one; one if there was none.
-int searchit(
- win_T *win, // window to search in; can be NULL for a
- // buffer without a window!
- buf_T *buf,
- pos_T *pos,
- pos_T *end_pos, // set to end of the match, unless NULL
- Direction dir,
- char_u *pat,
- long count,
- int options,
- int pat_use, // which pattern to use when "pat" is empty
- searchit_arg_T *extra_arg // optional extra arguments, can be NULL
-)
+/// @param win window to search in; can be NULL for a buffer without a window!
+/// @param end_pos set to end of the match, unless NULL
+/// @param pat_use which pattern to use when "pat" is empty
+/// @param extra_arg optional extra arguments, can be NULL
+///
+/// @returns FAIL (zero) for failure, non-zero for success.
+/// the index of the first matching
+/// subpattern plus one; one if there was none.
+int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir, char_u *pat,
+ long count, int options, int pat_use, searchit_arg_T *extra_arg)
{
int found;
- linenr_T lnum; /* no init to shut up Apollo cc */
+ linenr_T lnum; // no init to shut up Apollo cc
regmmatch_T regmatch;
- char_u *ptr;
+ char_u *ptr;
colnr_T matchcol;
lpos_T endpos;
lpos_T matchpos;
@@ -556,26 +558,27 @@ int searchit(
int at_first_line;
int extra_col;
int start_char_len;
- int match_ok;
+ bool match_ok;
long nmatched;
int submatch = 0;
bool first_match = true;
int save_called_emsg = called_emsg;
- int break_loop = false;
+ bool break_loop = false;
linenr_T stop_lnum = 0; // stop after this line number when != 0
proftime_T *tm = NULL; // timeout limit or NULL
int *timed_out = NULL; // set when timed out or NULL
if (extra_arg != NULL) {
- stop_lnum = extra_arg->sa_stop_lnum;
- tm = extra_arg->sa_tm;
- timed_out = &extra_arg->sa_timed_out;
+ stop_lnum = extra_arg->sa_stop_lnum;
+ tm = extra_arg->sa_tm;
+ timed_out = &extra_arg->sa_timed_out;
}
if (search_regcomp(pat, RE_SEARCH, pat_use,
- (options & (SEARCH_HIS + SEARCH_KEEP)), &regmatch) == FAIL) {
- if ((options & SEARCH_MSG) && !rc_did_emsg)
+ (options & (SEARCH_HIS + SEARCH_KEEP)), &regmatch) == FAIL) {
+ if ((options & SEARCH_MSG) && !rc_did_emsg) {
EMSG2(_("E383: Invalid search string: %s"), mr_pattern);
+ }
return FAIL;
}
@@ -583,7 +586,7 @@ int searchit(
* find the string
*/
called_emsg = FALSE;
- do { /* loop for count */
+ do { // loop for count
// When not accepting a match at the start position set "extra_col" to a
// non-zero value. Don't do that when starting at MAXCOL, since MAXCOL + 1
// is zero.
@@ -608,13 +611,13 @@ int searchit(
extra_col = (options & SEARCH_START) ? start_char_len : 0;
}
- start_pos = *pos; /* remember start pos for detecting no match */
- found = 0; /* default: not found */
- at_first_line = TRUE; /* default: start in first line */
- if (pos->lnum == 0) { /* correct lnum for when starting in line 0 */
+ start_pos = *pos; // remember start pos for detecting no match
+ found = 0; // default: not found
+ at_first_line = TRUE; // default: start in first line
+ if (pos->lnum == 0) { // correct lnum for when starting in line 0
pos->lnum = 1;
pos->col = 0;
- at_first_line = FALSE; /* not in first line now */
+ at_first_line = FALSE; // not in first line now
}
/*
@@ -628,19 +631,22 @@ int searchit(
&& (options & SEARCH_START) == 0) {
lnum = pos->lnum - 1;
at_first_line = FALSE;
- } else
+ } else {
lnum = pos->lnum;
+ }
- for (loop = 0; loop <= 1; ++loop) { /* loop twice if 'wrapscan' set */
+ for (loop = 0; loop <= 1; ++loop) { // loop twice if 'wrapscan' set
for (; lnum > 0 && lnum <= buf->b_ml.ml_line_count;
lnum += dir, at_first_line = FALSE) {
- /* Stop after checking "stop_lnum", if it's set. */
+ // Stop after checking "stop_lnum", if it's set.
if (stop_lnum != 0 && (dir == FORWARD
- ? lnum > stop_lnum : lnum < stop_lnum))
+ ? lnum > stop_lnum : lnum < stop_lnum)) {
break;
- /* Stop after passing the "tm" time limit. */
- if (tm != NULL && profile_passed_limit(*tm))
+ }
+ // Stop after passing the "tm" time limit.
+ if (tm != NULL && profile_passed_limit(*tm)) {
break;
+ }
// Look for a match somewhere in line "lnum".
colnr_T col = at_first_line && (options & SEARCH_COL) ? pos->col : 0;
@@ -655,15 +661,16 @@ int searchit(
break;
}
if (nmatched > 0) {
- /* match may actually be in another line when using \zs */
+ // match may actually be in another line when using \zs
matchpos = regmatch.startpos[0];
endpos = regmatch.endpos[0];
submatch = first_submatch(&regmatch);
- /* "lnum" may be past end of buffer for "\n\zs". */
- if (lnum + matchpos.lnum > buf->b_ml.ml_line_count)
+ // "lnum" may be past end of buffer for "\n\zs".
+ if (lnum + matchpos.lnum > buf->b_ml.ml_line_count) {
ptr = (char_u *)"";
- else
- ptr = ml_get_buf(buf, lnum + matchpos.lnum, FALSE);
+ } else {
+ ptr = ml_get_buf(buf, lnum + matchpos.lnum, false);
+ }
/*
* Forward search in the first line: match should be after
@@ -671,14 +678,12 @@ int searchit(
* match (this is vi compatible) or on the next char.
*/
if (dir == FORWARD && at_first_line) {
- match_ok = TRUE;
- /*
- * When the match starts in a next line it's certainly
- * past the start position.
- * When match lands on a NUL the cursor will be put
- * one back afterwards, compare with that position,
- * otherwise "/$" will get stuck on end of line.
- */
+ match_ok = true;
+ // When the match starts in a next line it's certainly
+ // past the start position.
+ // When match lands on a NUL the cursor will be put
+ // one back afterwards, compare with that position,
+ // otherwise "/$" will get stuck on end of line.
while (matchpos.lnum == 0
&& (((options & SEARCH_END) && first_match)
? (nmatched == 1
@@ -696,7 +701,7 @@ int searchit(
if (nmatched > 1) {
/* end is in next line, thus no match in
* this line */
- match_ok = FALSE;
+ match_ok = false;
break;
}
matchcol = endpos.col;
@@ -739,8 +744,9 @@ int searchit(
// have made it invalid.
ptr = ml_get_buf(buf, lnum, false);
}
- if (!match_ok)
+ if (!match_ok) {
continue;
+ }
}
if (dir == BACKWARD) {
/*
@@ -750,7 +756,7 @@ int searchit(
* When putting the new cursor at the end, compare
* relative to the end of the match.
*/
- match_ok = FALSE;
+ match_ok = false;
for (;; ) {
/* Remember a position that is before the start
* position, we use it if it's the last match in
@@ -774,8 +780,9 @@ int searchit(
matchpos = regmatch.startpos[0];
endpos = regmatch.endpos[0];
submatch = first_submatch(&regmatch);
- } else
+ } else {
break;
+ }
// We found a valid match, now check if there is
// another one after it.
@@ -803,16 +810,16 @@ int searchit(
}
}
if (ptr[matchcol] == NUL
- || (nmatched = vim_regexec_multi(
- &regmatch, win, buf, lnum + matchpos.lnum, matchcol,
- tm, timed_out)) == 0) {
- // If the search timed out, we did find a match
- // but it might be the wrong one, so that's not
- // OK.
- if (tm != NULL && profile_passed_limit(*tm)) {
- match_ok = false;
- }
- break;
+ || (nmatched =
+ vim_regexec_multi(&regmatch, win, buf, lnum + matchpos.lnum, matchcol,
+ tm, timed_out)) == 0) {
+ // If the search timed out, we did find a match
+ // but it might be the wrong one, so that's not
+ // OK.
+ if (tm != NULL && profile_passed_limit(*tm)) {
+ match_ok = false;
+ }
+ break;
}
// vim_regexec_multi() may clear "regprog"
if (regmatch.regprog == NULL) {
@@ -827,8 +834,9 @@ int searchit(
* If there is only a match after the cursor, skip
* this match.
*/
- if (!match_ok)
+ if (!match_ok) {
continue;
+ }
}
/* With the SEARCH_END option move to the last character
@@ -842,10 +850,9 @@ int searchit(
pos->lnum = lnum + endpos.lnum;
pos->col = endpos.col;
if (endpos.col == 0) {
- if (pos->lnum > 1) { /* just in case */
- --pos->lnum;
- pos->col = (colnr_T)STRLEN(ml_get_buf(buf,
- pos->lnum, FALSE));
+ if (pos->lnum > 1) { // just in case
+ pos->lnum--;
+ pos->col = (colnr_T)STRLEN(ml_get_buf(buf, pos->lnum, false));
}
} else {
pos->col--;
@@ -873,14 +880,15 @@ int searchit(
found = 1;
first_match = false;
- /* Set variables used for 'incsearch' highlighting. */
+ // Set variables used for 'incsearch' highlighting.
search_match_lines = endpos.lnum - matchpos.lnum;
search_match_endcol = endpos.col;
break;
}
- line_breakcheck(); /* stop if ctrl-C typed */
- if (got_int)
+ line_breakcheck(); // stop if ctrl-C typed
+ if (got_int) {
break;
+ }
/* Cancel searching if a character was typed. Used for
* 'incsearch'. Don't check too often, that would slowdown
@@ -888,12 +896,13 @@ int searchit(
if ((options & SEARCH_PEEK)
&& ((lnum - pos->lnum) & 0x3f) == 0
&& char_avail()) {
- break_loop = TRUE;
+ break_loop = true;
break;
}
- if (loop && lnum == start_pos.lnum)
- break; /* if second loop, stop where started */
+ if (loop && lnum == start_pos.lnum) {
+ break; // if second loop, stop where started
+ }
}
at_first_line = FALSE;
@@ -933,8 +942,7 @@ int searchit(
}
if (got_int || called_emsg
|| (timed_out != NULL && *timed_out)
- || break_loop
- ) {
+ || break_loop) {
break;
}
} while (--count > 0 && found); // stop after count matches or no match
@@ -943,28 +951,30 @@ int searchit(
called_emsg |= save_called_emsg;
- if (!found) { /* did not find it */
- if (got_int)
+ if (!found) { // did not find it
+ if (got_int) {
EMSG(_(e_interr));
- else if ((options & SEARCH_MSG) == SEARCH_MSG) {
- if (p_ws)
+ } else if ((options & SEARCH_MSG) == SEARCH_MSG) {
+ if (p_ws) {
EMSG2(_(e_patnotf2), mr_pattern);
- else if (lnum == 0)
+ } else if (lnum == 0) {
EMSG2(_("E384: search hit TOP without match for: %s"),
- mr_pattern);
- else
+ mr_pattern);
+ } else {
EMSG2(_("E385: search hit BOTTOM without match for: %s"),
- mr_pattern);
+ mr_pattern);
+ }
}
return FAIL;
}
- /* A pattern like "\n\zs" may go past the last line. */
+ // A pattern like "\n\zs" may go past the last line.
if (pos->lnum > buf->b_ml.ml_line_count) {
pos->lnum = buf->b_ml.ml_line_count;
- pos->col = (int)STRLEN(ml_get_buf(buf, pos->lnum, FALSE));
- if (pos->col > 0)
- --pos->col;
+ pos->col = (int)STRLEN(ml_get_buf(buf, pos->lnum, false));
+ if (pos->col > 0) {
+ pos->col--;
+ }
}
return submatch + 1;
@@ -987,8 +997,9 @@ static int first_submatch(regmmatch_T *rp)
int submatch;
for (submatch = 1;; ++submatch) {
- if (rp->startpos[submatch].lnum >= 0)
+ if (rp->startpos[submatch].lnum >= 0) {
break;
+ }
if (submatch == 9) {
submatch = 0;
break;
@@ -997,49 +1008,46 @@ static int first_submatch(regmmatch_T *rp)
return submatch;
}
-/*
- * Highest level string search function.
- * Search for the 'count'th occurrence of pattern 'pat' in direction 'dirc'
- * If 'dirc' is 0: use previous dir.
- * If 'pat' is NULL or empty : use previous string.
- * If 'options & SEARCH_REV' : go in reverse of previous dir.
- * If 'options & SEARCH_ECHO': echo the search command and handle options
- * If 'options & SEARCH_MSG' : may give error message
- * If 'options & SEARCH_OPT' : interpret optional flags
- * If 'options & SEARCH_HIS' : put search pattern in history
- * If 'options & SEARCH_NOOF': don't add offset to position
- * If 'options & SEARCH_MARK': set previous context mark
- * If 'options & SEARCH_KEEP': keep previous search pattern
- * If 'options & SEARCH_START': accept match at curpos itself
- * If 'options & SEARCH_PEEK': check for typed char, cancel search
- *
- * Careful: If spats[0].off.line == TRUE and spats[0].off.off == 0 this
- * makes the movement linewise without moving the match position.
- *
- * Return 0 for failure, 1 for found, 2 for found and line offset added.
- */
-int do_search(
- oparg_T *oap, // can be NULL
- int dirc, // '/' or '?'
- int search_delim, // delimiter for search, e.g. '%' in s%regex%replacement
- char_u *pat,
- long count,
- int options,
- searchit_arg_T *sia // optional arguments or NULL
-)
+/// Highest level string search function.
+/// Search for the 'count'th occurrence of pattern 'pat' in direction 'dirc'
+///
+/// Careful: If spats[0].off.line == TRUE and spats[0].off.off == 0 this
+/// makes the movement linewise without moving the match position.
+///
+/// @param dirc if 0: use previous dir.
+/// @param pat NULL or empty : use previous string.
+/// @param options if TRUE and
+/// SEARCH_REV == TRUE : go in reverse of previous dir.
+/// SEARCH_ECHO == TRUE : echo the search command and handle options
+/// SEARCH_MSG == TRUE : may give error message
+/// SEARCH_OPT == TRUE : interpret optional flags
+/// SEARCH_HIS == TRUE : put search pattern in history
+/// SEARCH_NOOF == TRUE : don't add offset to position
+/// SEARCH_MARK == TRUE : set previous context mark
+/// SEARCH_KEEP == TRUE : keep previous search pattern
+/// SEARCH_START == TRUE : accept match at curpos itself
+/// SEARCH_PEEK == TRUE : check for typed char, cancel search
+/// @param oap can be NULL
+/// @param dirc '/' or '?'
+/// @param search_delim delimiter for search, e.g. '%' in s%regex%replacement
+/// @param sia optional arguments or NULL
+///
+/// @return 0 for failure, 1 for found, 2 for found and line offset added.
+int do_search(oparg_T *oap, int dirc, int search_delim, char_u *pat, long count, int options,
+ searchit_arg_T *sia)
{
- pos_T pos; /* position of the last match */
- char_u *searchstr;
+ pos_T pos; // position of the last match
+ char_u *searchstr;
struct soffset old_off;
- int retval; /* Return value */
- char_u *p;
+ int retval; // Return value
+ char_u *p;
long c;
- char_u *dircp;
- char_u *strcopy = NULL;
- char_u *ps;
- char_u *msgbuf = NULL;
- size_t len;
- bool has_offset = false;
+ char_u *dircp;
+ char_u *strcopy = NULL;
+ char_u *ps;
+ char_u *msgbuf = NULL;
+ size_t len;
+ bool has_offset = false;
/*
* A line offset is not remembered, this is vi compatible.
@@ -1055,32 +1063,35 @@ int do_search(
*/
old_off = spats[0].off;
- pos = curwin->w_cursor; /* start searching at the cursor position */
+ pos = curwin->w_cursor; // start searching at the cursor position
/*
* Find out the direction of the search.
*/
- if (dirc == 0)
+ if (dirc == 0) {
dirc = spats[0].off.dir;
- else {
+ } else {
spats[0].off.dir = dirc;
set_vv_searchforward();
}
if (options & SEARCH_REV) {
- if (dirc == '/')
+ if (dirc == '/') {
dirc = '?';
- else
+ } else {
dirc = '/';
+ }
}
/* If the cursor is in a closed fold, don't find another match in the same
* fold. */
if (dirc == '/') {
- if (hasFolding(pos.lnum, NULL, &pos.lnum))
- pos.col = MAXCOL - 2; /* avoid overflow when adding 1 */
+ if (hasFolding(pos.lnum, NULL, &pos.lnum)) {
+ pos.col = MAXCOL - 2; // avoid overflow when adding 1
+ }
} else {
- if (hasFolding(pos.lnum, &pos.lnum, NULL))
+ if (hasFolding(pos.lnum, &pos.lnum, NULL)) {
pos.col = 0;
+ }
}
/*
@@ -1109,12 +1120,12 @@ int do_search(
goto end_do_search;
}
} else {
- /* make search_regcomp() use spats[RE_SEARCH].pat */
+ // make search_regcomp() use spats[RE_SEARCH].pat
searchstr = (char_u *)"";
}
}
- if (pat != NULL && *pat != NUL) { /* look for (new) offset */
+ if (pat != NULL && *pat != NUL) { // look for (new) offset
/*
* Find end of regular expression.
* If there is a matching '/' or '?', toss it.
@@ -1122,7 +1133,7 @@ int do_search(
ps = strcopy;
p = skip_regexp(pat, search_delim, p_magic, &strcopy);
if (strcopy != ps) {
- /* made a copy of "pat" to change "\?" to "?" */
+ // made a copy of "pat" to change "\?" to "?"
searchcmdlen += (int)(STRLEN(pat) - STRLEN(strcopy));
pat = strcopy;
searchstr = strcopy;
@@ -1147,30 +1158,32 @@ int do_search(
}
p++;
}
- if (ascii_isdigit(*p) || *p == '+' || *p == '-') { /* got an offset */
- /* 'nr' or '+nr' or '-nr' */
- if (ascii_isdigit(*p) || ascii_isdigit(*(p + 1)))
+ if (ascii_isdigit(*p) || *p == '+' || *p == '-') { // got an offset
+ // 'nr' or '+nr' or '-nr'
+ if (ascii_isdigit(*p) || ascii_isdigit(*(p + 1))) {
spats[0].off.off = atol((char *)p);
- else if (*p == '-') /* single '-' */
+ } else if (*p == '-') { // single '-'
spats[0].off.off = -1;
- else /* single '+' */
+ } else { // single '+'
spats[0].off.off = 1;
+ }
++p;
- while (ascii_isdigit(*p)) /* skip number */
+ while (ascii_isdigit(*p)) { // skip number
++p;
+ }
}
- /* compute length of search command for get_address() */
+ // compute length of search command for get_address()
searchcmdlen += (int)(p - pat);
- pat = p; /* put pat after search command */
+ pat = p; // put pat after search command
}
if ((options & SEARCH_ECHO) && messaging() && !msg_silent
&& (!cmd_silent || !shortmess(SHM_SEARCHCOUNT))) {
- char_u *trunc;
- char_u off_buf[40];
- size_t off_len = 0;
+ char_u *trunc;
+ char_u off_buf[40];
+ size_t off_len = 0;
// Compute msg_row early.
msg_start();
@@ -1290,18 +1303,22 @@ int do_search(
*/
if (!spats[0].off.line && spats[0].off.off && pos.col < MAXCOL - 2) {
if (spats[0].off.off > 0) {
- for (c = spats[0].off.off; c; --c)
- if (decl(&pos) == -1)
+ for (c = spats[0].off.off; c; --c) {
+ if (decl(&pos) == -1) {
break;
- if (c) { /* at start of buffer */
- pos.lnum = 0; /* allow lnum == 0 here */
+ }
+ }
+ if (c) { // at start of buffer
+ pos.lnum = 0; // allow lnum == 0 here
pos.col = MAXCOL;
}
} else {
- for (c = spats[0].off.off; c; ++c)
- if (incl(&pos) == -1)
+ for (c = spats[0].off.off; c; ++c) {
+ if (incl(&pos) == -1) {
break;
- if (c) { /* at end of buffer */
+ }
+ }
+ if (c) { // at end of buffer
pos.lnum = curbuf->b_ml.ml_line_count + 1;
pos.col = 0;
}
@@ -1331,10 +1348,10 @@ int do_search(
retval = 0;
goto end_do_search;
}
- if (spats[0].off.end && oap != NULL)
- oap->inclusive = true; /* 'e' includes last character */
-
- retval = 1; /* pattern found */
+ if (spats[0].off.end && oap != NULL) {
+ oap->inclusive = true; // 'e' includes last character
+ }
+ retval = 1; // pattern found
/*
* Add character and/or line offset
@@ -1344,28 +1361,33 @@ int do_search(
if (spats[0].off.line) { // Add the offset to the line number.
c = pos.lnum + spats[0].off.off;
- if (c < 1)
+ if (c < 1) {
pos.lnum = 1;
- else if (c > curbuf->b_ml.ml_line_count)
+ } else if (c > curbuf->b_ml.ml_line_count) {
pos.lnum = curbuf->b_ml.ml_line_count;
- else
+ } else {
pos.lnum = c;
+ }
pos.col = 0;
- retval = 2; /* pattern found, line offset added */
- } else if (pos.col < MAXCOL - 2) { /* just in case */
- /* to the right, check for end of file */
+ retval = 2; // pattern found, line offset added
+ } else if (pos.col < MAXCOL - 2) { // just in case
+ // to the right, check for end of file
c = spats[0].off.off;
if (c > 0) {
- while (c-- > 0)
- if (incl(&pos) == -1)
+ while (c-- > 0) {
+ if (incl(&pos) == -1) {
break;
+ }
+ }
}
- /* to the left, check for start of file */
+ // to the left, check for start of file
else {
- while (c++ < 0)
- if (decl(&pos) == -1)
+ while (c++ < 0) {
+ if (decl(&pos) == -1) {
break;
+ }
+ }
}
}
if (!equalpos(pos, org_pos)) {
@@ -1410,14 +1432,16 @@ int do_search(
++pat;
}
- if (options & SEARCH_MARK)
+ if (options & SEARCH_MARK) {
setpcmark();
+ }
curwin->w_cursor = pos;
curwin->w_set_curswant = TRUE;
end_do_search:
- if ((options & SEARCH_KEEP) || cmdmod.keeppatterns)
+ if ((options & SEARCH_KEEP) || cmdmod.keeppatterns) {
spats[0].off = old_off;
+ }
xfree(msgbuf);
return retval;
@@ -1435,18 +1459,20 @@ end_do_search:
int search_for_exact_line(buf_T *buf, pos_T *pos, Direction dir, char_u *pat)
{
linenr_T start = 0;
- char_u *ptr;
- char_u *p;
+ char_u *ptr;
+ char_u *p;
- if (buf->b_ml.ml_line_count == 0)
+ if (buf->b_ml.ml_line_count == 0) {
return FAIL;
+ }
for (;; ) {
pos->lnum += dir;
if (pos->lnum < 1) {
if (p_ws) {
pos->lnum = buf->b_ml.ml_line_count;
- if (!shortmess(SHM_SEARCH))
+ if (!shortmess(SHM_SEARCH)) {
give_warning((char_u *)_(top_bot_msg), true);
+ }
} else {
pos->lnum = 1;
break;
@@ -1454,20 +1480,23 @@ int search_for_exact_line(buf_T *buf, pos_T *pos, Direction dir, char_u *pat)
} else if (pos->lnum > buf->b_ml.ml_line_count) {
if (p_ws) {
pos->lnum = 1;
- if (!shortmess(SHM_SEARCH))
+ if (!shortmess(SHM_SEARCH)) {
give_warning((char_u *)_(bot_top_msg), true);
+ }
} else {
pos->lnum = 1;
break;
}
}
- if (pos->lnum == start)
+ if (pos->lnum == start) {
break;
- if (start == 0)
+ }
+ if (start == 0) {
start = pos->lnum;
- ptr = ml_get_buf(buf, pos->lnum, FALSE);
+ }
+ ptr = ml_get_buf(buf, pos->lnum, false);
p = skipwhite(ptr);
- pos->col = (colnr_T) (p - ptr);
+ pos->col = (colnr_T)(p - ptr);
/* when adding lines the matching line may be empty but it is not
* ignored because we are interested in the next line -- Acevedo */
@@ -1480,8 +1509,9 @@ int search_for_exact_line(buf_T *buf, pos_T *pos, Direction dir, char_u *pat)
// Expanding lines or words.
assert(compl_length >= 0);
if ((p_ic ? mb_strnicmp(p, pat, (size_t)compl_length)
- : STRNCMP(p, pat, compl_length)) == 0)
+ : STRNCMP(p, pat, compl_length)) == 0) {
return OK;
+ }
}
}
return FAIL;
@@ -1501,15 +1531,15 @@ int searchc(cmdarg_T *cap, int t_cmd)
FUNC_ATTR_NONNULL_ALL
{
int c = cap->nchar; // char to search for
- Direction dir = cap->arg; // TRUE for searching forward
+ int dir = cap->arg; // true for searching forward
long count = cap->count1; // repeat count
int col;
- char_u *p;
+ char_u *p;
int len;
- int stop = TRUE;
+ bool stop = true;
- if (c != NUL) { /* normal search: remember args for repeat */
- if (!KeyStuffed) { /* don't remember when redoing */
+ if (c != NUL) { // normal search: remember args for repeat
+ if (!KeyStuffed) { // don't remember when redoing
*lastc = c;
set_csearch_direction(dir);
set_csearch_until(t_cmd);
@@ -1534,19 +1564,21 @@ int searchc(cmdarg_T *cap, int t_cmd)
}
t_cmd = last_t_cmd;
c = *lastc;
- /* For multi-byte re-use last lastc_bytes[] and lastc_bytelen. */
+ // For multi-byte re-use last lastc_bytes[] and lastc_bytelen.
/* Force a move of at least one char, so ";" and "," will move the
* cursor, even if the cursor is right in front of char we are looking
* at. */
- if (vim_strchr(p_cpo, CPO_SCOLON) == NULL && count == 1 && t_cmd)
- stop = FALSE;
+ if (vim_strchr(p_cpo, CPO_SCOLON) == NULL && count == 1 && t_cmd) {
+ stop = false;
+ }
}
- if (dir == BACKWARD)
+ if (dir == BACKWARD) {
cap->oap->inclusive = false;
- else
+ } else {
cap->oap->inclusive = true;
+ }
p = get_cursor_line_ptr();
col = curwin->w_cursor.col;
@@ -1620,7 +1652,7 @@ static bool check_prevcol(char_u *linep, int col, int ch, int *prevcol)
if (prevcol) {
*prevcol = col;
}
- return (col >= 0 && linep[col] == ch) ? true : false;
+ return col >= 0 && linep[col] == ch;
}
/*
@@ -1665,8 +1697,7 @@ static bool find_rawstring_end(char_u *linep, pos_T *startpos, pos_T *endpos)
/// If there is a match set "*initc" to the matching character and "*findc" to
/// the opposite character. Set "*backwards" to the direction.
/// When "switchit" is true swap the direction.
-static void find_mps_values(int *initc, int *findc, bool *backwards,
- bool switchit)
+static void find_mps_values(int *initc, int *findc, bool *backwards, bool switchit)
FUNC_ATTR_NONNULL_ALL
{
char_u *ptr = curbuf->b_p_mps;
@@ -1732,7 +1763,7 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
bool backwards = false; // init for gcc
bool raw_string = false; // search for raw string
bool inquote = false; // true when inside quotes
- char_u *ptr;
+ char_u *ptr;
int hash_dir = 0; // Direction searched for # things
int comment_dir = 0; // Direction searched for comments
int traveled = 0; // how far we've searched so far
@@ -1752,13 +1783,14 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
// don't recognize backslashes
bool cpo_bsl = (vim_strchr(p_cpo, CPO_MATCHBSL) != NULL);
- /* Direction to search when initc is '/', '*' or '#' */
- if (flags & FM_BACKWARD)
+ // Direction to search when initc is '/', '*' or '#'
+ if (flags & FM_BACKWARD) {
dir = BACKWARD;
- else if (flags & FM_FORWARD)
+ } else if (flags & FM_FORWARD) {
dir = FORWARD;
- else
+ } else {
dir = 0;
+ }
/*
* if initc given, look in the table for the matching character
@@ -1768,8 +1800,9 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
*/
if (initc == '/' || initc == '*' || initc == 'R') {
comment_dir = dir;
- if (initc == '/')
+ if (initc == '/') {
ignore_cend = true;
+ }
backwards = (dir == FORWARD) ? false : true;
raw_string = (initc == 'R');
initc = NUL;
@@ -1792,16 +1825,17 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
* Only check for special things when 'cpo' doesn't have '%'.
*/
if (!cpo_match) {
- /* Are we before or at #if, #else etc.? */
+ // Are we before or at #if, #else etc.?
ptr = skipwhite(linep);
if (*ptr == '#' && pos.col <= (colnr_T)(ptr - linep)) {
ptr = skipwhite(ptr + 1);
- if ( STRNCMP(ptr, "if", 2) == 0
- || STRNCMP(ptr, "endif", 5) == 0
- || STRNCMP(ptr, "el", 2) == 0)
+ if (STRNCMP(ptr, "if", 2) == 0
+ || STRNCMP(ptr, "endif", 5) == 0
+ || STRNCMP(ptr, "el", 2) == 0) {
hash_dir = 1;
+ }
}
- /* Are we on a comment? */
+ // Are we on a comment?
else if (linep[pos.col] == '/') {
if (linep[pos.col + 1] == '*') {
comment_dir = FORWARD;
@@ -1833,12 +1867,14 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
* If beyond the end of the line, use the last character in
* the line.
*/
- if (linep[pos.col] == NUL && pos.col)
+ if (linep[pos.col] == NUL && pos.col) {
--pos.col;
+ }
for (;; ) {
initc = PTR2CHAR(linep + pos.col);
- if (initc == NUL)
+ if (initc == NUL) {
break;
+ }
find_mps_values(&initc, &findc, &backwards, false);
if (findc) {
@@ -1847,18 +1883,20 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
pos.col += utfc_ptr2len(linep + pos.col);
}
if (!findc) {
- /* no brace in the line, maybe use " #if" then */
- if (!cpo_match && *skipwhite(linep) == '#')
+ // no brace in the line, maybe use " #if" then
+ if (!cpo_match && *skipwhite(linep) == '#') {
hash_dir = 1;
- else
+ } else {
return NULL;
+ }
} else if (!cpo_bsl) {
int col, bslcnt = 0;
/* Set "match_escaped" if there are an odd number of
* backslashes. */
- for (col = pos.col; check_prevcol(linep, col, '\\', &col); )
+ for (col = pos.col; check_prevcol(linep, col, '\\', &col); ) {
bslcnt++;
+ }
match_escaped = (bslcnt & 1);
}
}
@@ -1872,49 +1910,58 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
}
if (initc != '#') {
ptr = skipwhite(skipwhite(linep) + 1);
- if (STRNCMP(ptr, "if", 2) == 0 || STRNCMP(ptr, "el", 2) == 0)
+ if (STRNCMP(ptr, "if", 2) == 0 || STRNCMP(ptr, "el", 2) == 0) {
hash_dir = 1;
- else if (STRNCMP(ptr, "endif", 5) == 0)
+ } else if (STRNCMP(ptr, "endif", 5) == 0) {
hash_dir = -1;
- else
+ } else {
return NULL;
+ }
}
pos.col = 0;
while (!got_int) {
if (hash_dir > 0) {
- if (pos.lnum == curbuf->b_ml.ml_line_count)
+ if (pos.lnum == curbuf->b_ml.ml_line_count) {
break;
- } else if (pos.lnum == 1)
+ }
+ } else if (pos.lnum == 1) {
break;
+ }
pos.lnum += hash_dir;
linep = ml_get(pos.lnum);
- line_breakcheck(); /* check for CTRL-C typed */
+ line_breakcheck(); // check for CTRL-C typed
ptr = skipwhite(linep);
- if (*ptr != '#')
+ if (*ptr != '#') {
continue;
- pos.col = (colnr_T) (ptr - linep);
+ }
+ pos.col = (colnr_T)(ptr - linep);
ptr = skipwhite(ptr + 1);
if (hash_dir > 0) {
- if (STRNCMP(ptr, "if", 2) == 0)
+ if (STRNCMP(ptr, "if", 2) == 0) {
count++;
- else if (STRNCMP(ptr, "el", 2) == 0) {
- if (count == 0)
+ } else if (STRNCMP(ptr, "el", 2) == 0) {
+ if (count == 0) {
return &pos;
+ }
} else if (STRNCMP(ptr, "endif", 5) == 0) {
- if (count == 0)
+ if (count == 0) {
return &pos;
+ }
count--;
}
} else {
if (STRNCMP(ptr, "if", 2) == 0) {
- if (count == 0)
+ if (count == 0) {
return &pos;
+ }
count--;
} else if (initc == '#' && STRNCMP(ptr, "el", 2) == 0) {
- if (count == 0)
+ if (count == 0) {
return &pos;
- } else if (STRNCMP(ptr, "endif", 5) == 0)
+ }
+ } else if (STRNCMP(ptr, "endif", 5) == 0) {
count++;
+ }
}
}
return NULL;
@@ -1933,11 +1980,11 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
pos_T match_pos; // Where last slash-star was found
clearpos(&match_pos);
- /* backward search: Check if this line contains a single-line comment */
+ // backward search: Check if this line contains a single-line comment
if ((backwards && comment_dir)
- || lisp
- )
+ || lisp) {
comment_col = check_linecomment(linep);
+ }
if (lisp && comment_col != MAXCOL && pos.col > (colnr_T)comment_col) {
lispcomm = true; // find match inside this comment
}
@@ -1947,58 +1994,63 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
* inc() and dec() here, but that is much slower
*/
if (backwards) {
- /* char to match is inside of comment, don't search outside */
- if (lispcomm && pos.col < (colnr_T)comment_col)
+ // char to match is inside of comment, don't search outside
+ if (lispcomm && pos.col < (colnr_T)comment_col) {
break;
- if (pos.col == 0) { /* at start of line, go to prev. one */
- if (pos.lnum == 1) /* start of file */
+ }
+ if (pos.col == 0) { // at start of line, go to prev. one
+ if (pos.lnum == 1) { // start of file
break;
+ }
--pos.lnum;
- if (maxtravel > 0 && ++traveled > maxtravel)
+ if (maxtravel > 0 && ++traveled > maxtravel) {
break;
+ }
linep = ml_get(pos.lnum);
- pos.col = (colnr_T)STRLEN(linep); /* pos.col on trailing NUL */
+ pos.col = (colnr_T)STRLEN(linep); // pos.col on trailing NUL
do_quotes = -1;
line_breakcheck();
- /* Check if this line contains a single-line comment */
+ // Check if this line contains a single-line comment
if (comment_dir
- || lisp
- )
+ || lisp) {
comment_col = check_linecomment(linep);
- /* skip comment */
- if (lisp && comment_col != MAXCOL)
+ }
+ // skip comment
+ if (lisp && comment_col != MAXCOL) {
pos.col = comment_col;
+ }
} else {
pos.col--;
pos.col -= utf_head_off(linep, linep + pos.col);
}
- } else { /* forward search */
+ } else { // forward search
if (linep[pos.col] == NUL
- /* at end of line, go to next one */
- /* don't search for match in comment */
+ // at end of line, go to next one
+ // don't search for match in comment
|| (lisp && comment_col != MAXCOL
- && pos.col == (colnr_T)comment_col)
- ) {
- if (pos.lnum == curbuf->b_ml.ml_line_count /* end of file */
+ && pos.col == (colnr_T)comment_col)) {
+ if (pos.lnum == curbuf->b_ml.ml_line_count // end of file
/* line is exhausted and comment with it,
* don't search for match in code */
- || lispcomm
- )
+ || lispcomm) {
break;
+ }
++pos.lnum;
- if (maxtravel && traveled++ > maxtravel)
+ if (maxtravel && traveled++ > maxtravel) {
break;
+ }
linep = ml_get(pos.lnum);
pos.col = 0;
do_quotes = -1;
line_breakcheck();
- if (lisp) /* find comment pos in new line */
+ if (lisp) { // find comment pos in new line
comment_col = check_linecomment(linep);
+ }
} else {
pos.col += utfc_ptr2len(linep + pos.col);
}
@@ -2014,40 +2066,37 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
}
if (comment_dir) {
- /* Note: comments do not nest, and we ignore quotes in them */
- /* TODO: ignore comment brackets inside strings */
+ // Note: comments do not nest, and we ignore quotes in them
+ // TODO: ignore comment brackets inside strings
if (comment_dir == FORWARD) {
if (linep[pos.col] == '*' && linep[pos.col + 1] == '/') {
pos.col++;
return &pos;
}
- } else { /* Searching backwards */
+ } else { // Searching backwards
/*
* A comment may contain / * or / /, it may also start or end
* with / * /. Ignore a / * after / / and after *.
*/
- if (pos.col == 0)
+ if (pos.col == 0) {
continue;
- else if (raw_string)
- {
+ } else if (raw_string) {
if (linep[pos.col - 1] == 'R'
&& linep[pos.col] == '"'
- && vim_strchr(linep + pos.col + 1, '(') != NULL)
- {
+ && vim_strchr(linep + pos.col + 1, '(') != NULL) {
/* Possible start of raw string. Now that we have the
* delimiter we can check if it ends before where we
* started searching, or before the previously found
* raw string start. */
if (!find_rawstring_end(linep, &pos,
- count > 0 ? &match_pos : &curwin->w_cursor))
- {
+ count > 0 ? &match_pos : &curwin->w_cursor)) {
count++;
match_pos = pos;
match_pos.col--;
}
- linep = ml_get(pos.lnum); /* may have been released */
+ linep = ml_get(pos.lnum); // may have been released
}
- } else if ( linep[pos.col - 1] == '/'
+ } else if (linep[pos.col - 1] == '/'
&& linep[pos.col] == '*'
&& (pos.col == 1 || linep[pos.col - 2] != '*')
&& (int)pos.col < comment_col) {
@@ -2055,15 +2104,16 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
match_pos = pos;
match_pos.col--;
} else if (linep[pos.col - 1] == '*' && linep[pos.col] == '/') {
- if (count > 0)
+ if (count > 0) {
pos = match_pos;
- else if (pos.col > 1 && linep[pos.col - 2] == '/'
- && (int)pos.col <= comment_col)
+ } else if (pos.col > 1 && linep[pos.col - 2] == '/'
+ && (int)pos.col <= comment_col) {
pos.col -= 2;
- else if (ignore_cend)
+ } else if (ignore_cend) {
continue;
- else
+ } else {
return NULL;
+ }
return &pos;
}
}
@@ -2075,24 +2125,27 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
* of quotes are ignored, but only if there is an even number of
* quotes in the line.
*/
- if (cpo_match)
+ if (cpo_match) {
do_quotes = 0;
- else if (do_quotes == -1) {
+ } else if (do_quotes == -1) {
/*
* Count the number of quotes in the line, skipping \" and '"'.
* Watch out for "\\".
*/
at_start = do_quotes;
for (ptr = linep; *ptr; ++ptr) {
- if (ptr == linep + pos.col + backwards)
+ if (ptr == linep + pos.col + backwards) {
at_start = (do_quotes & 1);
+ }
if (*ptr == '"'
- && (ptr == linep || ptr[-1] != '\'' || ptr[1] != '\''))
+ && (ptr == linep || ptr[-1] != '\'' || ptr[1] != '\'')) {
++do_quotes;
- if (*ptr == '\\' && ptr[1] != NUL)
+ }
+ if (*ptr == '\\' && ptr[1] != NUL) {
++ptr;
+ }
}
- do_quotes &= 1; /* result is 1 with even number of quotes */
+ do_quotes &= 1; // result is 1 with even number of quotes
/*
* If we find an uneven count, check current line and previous
@@ -2124,7 +2177,7 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
}
}
- /* ml_get() only keeps one line, need to get linep again */
+ // ml_get() only keeps one line, need to get linep again
linep = ml_get(pos.lnum);
}
}
@@ -2147,7 +2200,7 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
const int c = PTR2CHAR(linep + pos.col);
switch (c) {
case NUL:
- /* at end of line without trailing backslash, reset inquote */
+ // at end of line without trailing backslash, reset inquote
if (pos.col == 0 || linep[pos.col - 1] != '\\') {
inquote = false;
start_in_quotes = kFalse;
@@ -2160,9 +2213,11 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
if (do_quotes) {
int col;
- for (col = pos.col - 1; col >= 0; --col)
- if (linep[col] != '\\')
+ for (col = pos.col - 1; col >= 0; --col) {
+ if (linep[col] != '\\') {
break;
+ }
+ }
if ((((int)pos.col - 1 - col) & 1) == 0) {
inquote = !inquote;
start_in_quotes = kFalse;
@@ -2212,8 +2267,9 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
&& vim_strchr((char_u *)"(){}[]", c) != NULL
&& pos.col > 1
&& check_prevcol(linep, pos.col, '\\', NULL)
- && check_prevcol(linep, pos.col - 1, '#', NULL))
+ && check_prevcol(linep, pos.col - 1, '#', NULL)) {
break;
+ }
/* Check for match outside of quotes, and inside of
* quotes when the start is also inside of quotes. */
@@ -2222,17 +2278,19 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
int col, bslcnt = 0;
if (!cpo_bsl) {
- for (col = pos.col; check_prevcol(linep, col, '\\', &col); )
+ for (col = pos.col; check_prevcol(linep, col, '\\', &col); ) {
bslcnt++;
+ }
}
/* Only accept a match when 'M' is in 'cpo' or when escaping
* is what we expect. */
if (cpo_bsl || (bslcnt & 1) == match_escaped) {
- if (c == initc)
+ if (c == initc) {
count++;
- else {
- if (count == 0)
+ } else {
+ if (count == 0) {
return &pos;
+ }
count--;
}
}
@@ -2244,7 +2302,7 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
pos = match_pos;
return &pos;
}
- return (pos_T *)NULL; /* never found it */
+ return (pos_T *)NULL; // never found it
}
/*
@@ -2257,51 +2315,55 @@ static int check_linecomment(const char_u *line)
const char_u *p = line; // scan from start
// skip Lispish one-line comments
if (curbuf->b_p_lisp) {
- if (vim_strchr(p, ';') != NULL) { /* there may be comments */
- int in_str = FALSE; /* inside of string */
+ if (vim_strchr(p, ';') != NULL) { // there may be comments
+ bool in_str = false; // inside of string
while ((p = vim_strpbrk(p, (char_u *)"\";")) != NULL) {
if (*p == '"') {
if (in_str) {
- if (*(p - 1) != '\\') /* skip escaped quote */
- in_str = FALSE;
+ if (*(p - 1) != '\\') { // skip escaped quote
+ in_str = false;
+ }
} else if (p == line || ((p - line) >= 2
- /* skip #\" form */
- && *(p - 1) != '\\' && *(p - 2) != '#'))
- in_str = TRUE;
+ // skip #\" form
+ && *(p - 1) != '\\' && *(p - 2) != '#')) {
+ in_str = true;
+ }
} else if (!in_str && ((p - line) < 2
- || (*(p - 1) != '\\' && *(p - 2) != '#')))
- break; /* found! */
- ++p;
+ || (*(p - 1) != '\\' && *(p - 2) != '#'))) {
+ break; // found!
+ }
+ p++;
}
- } else
+ } else {
p = NULL;
- } else
+ }
+ } else {
while ((p = vim_strchr(p, '/')) != NULL) {
/* accept a double /, unless it's preceded with * and followed by *,
* because * / / * is an end and start of a C comment */
- if (p[1] == '/' && (p == line || p[-1] != '*' || p[2] != '*'))
+ if (p[1] == '/' && (p == line || p[-1] != '*' || p[2] != '*')) {
break;
+ }
++p;
}
+ }
- if (p == NULL)
+ if (p == NULL) {
return MAXCOL;
+ }
return (int)(p - line);
}
-/*
- * Move cursor briefly to character matching the one under the cursor.
- * Used for Insert mode and "r" command.
- * Show the match only if it is visible on the screen.
- * If there isn't a match, then beep.
- */
-void
-showmatch(
- int c // char to show match for
-)
+/// Move cursor briefly to character matching the one under the cursor.
+/// Used for Insert mode and "r" command.
+/// Show the match only if it is visible on the screen.
+/// If there isn't a match, then beep.
+///
+/// @param c char to show match for
+void showmatch(int c)
{
- pos_T *lpos, save_cursor;
+ pos_T *lpos, save_cursor;
pos_T mpos;
colnr_T vcol;
long *so = curwin->w_p_so >= 0 ? &curwin->w_p_so : &p_so;
@@ -2310,15 +2372,16 @@ showmatch(
long save_siso;
int save_state;
colnr_T save_dollar_vcol;
- char_u *p;
+ char_u *p;
/*
* Only show match for chars in the 'matchpairs' option.
*/
- /* 'matchpairs' is "x:y,x:y" */
+ // 'matchpairs' is "x:y,x:y"
for (p = curbuf->b_p_mps; *p != NUL; ++p) {
- if (PTR2CHAR(p) == c && (curwin->w_p_rl ^ p_ri))
+ if (PTR2CHAR(p) == c && (curwin->w_p_rl ^ p_ri)) {
break;
+ }
p += utfc_ptr2len(p) + 1;
if (PTR2CHAR(p) == c && !(curwin->w_p_rl ^ p_ri)) {
break;
@@ -2335,7 +2398,7 @@ showmatch(
if ((lpos = findmatch(NULL, NUL)) == NULL) { // no match, so beep
vim_beep(BO_MATCH);
} else if (lpos->lnum >= curwin->w_topline
- && lpos->lnum < curwin->w_botline) {
+ && lpos->lnum < curwin->w_botline) {
if (!curwin->w_p_wrap) {
getvcol(curwin, lpos, NULL, &vcol, NULL);
}
@@ -2396,14 +2459,15 @@ int findsent(Direction dir, long count)
{
pos_T pos, tpos;
int c;
- int (*func)(pos_T *);
+ int (*func)(pos_T *);
bool noskip = false; // do not skip blanks
pos = curwin->w_cursor;
- if (dir == FORWARD)
+ if (dir == FORWARD) {
func = incl;
- else
+ } else {
func = decl;
+ }
while (count--) {
const pos_T prev_pos = pos;
@@ -2418,8 +2482,8 @@ int findsent(Direction dir, long count)
if (dir == FORWARD) {
goto found;
}
- // if on the start of a paragraph or a section and searching forward,
- // go to the next line
+ // if on the start of a paragraph or a section and searching forward,
+ // go to the next line
} else if (dir == FORWARD && pos.col == 0
&& startPS(pos.lnum, NUL, false)) {
if (pos.lnum == curbuf->b_ml.ml_line_count) {
@@ -2442,11 +2506,11 @@ int findsent(Direction dir, long count)
if (found_dot) {
break;
}
- if (vim_strchr((char_u *) ".!?", c) != NULL) {
+ if (vim_strchr((char_u *)".!?", c) != NULL) {
found_dot = true;
}
- if (vim_strchr((char_u *) ")]\"'", c) != NULL
- && vim_strchr((char_u *) ".!?)]\"'", gchar_pos(&tpos)) == NULL) {
+ if (vim_strchr((char_u *)")]\"'", c) != NULL
+ && vim_strchr((char_u *)".!?)]\"'", gchar_pos(&tpos)) == NULL) {
break;
}
decl(&pos);
@@ -2456,41 +2520,47 @@ int findsent(Direction dir, long count)
const int startlnum = pos.lnum;
const bool cpo_J = vim_strchr(p_cpo, CPO_ENDOFSENT) != NULL;
- for (;; ) { /* find end of sentence */
+ for (;; ) { // find end of sentence
c = gchar_pos(&pos);
if (c == NUL || (pos.col == 0 && startPS(pos.lnum, NUL, FALSE))) {
- if (dir == BACKWARD && pos.lnum != startlnum)
+ if (dir == BACKWARD && pos.lnum != startlnum) {
++pos.lnum;
+ }
break;
}
if (c == '.' || c == '!' || c == '?') {
tpos = pos;
do
- if ((c = inc(&tpos)) == -1)
+ if ((c = inc(&tpos)) == -1) {
break;
+ }
while (vim_strchr((char_u *)")]\"'", c = gchar_pos(&tpos))
!= NULL);
if (c == -1 || (!cpo_J && (c == ' ' || c == '\t')) || c == NUL
|| (cpo_J && (c == ' ' && inc(&tpos) >= 0
&& gchar_pos(&tpos) == ' '))) {
pos = tpos;
- if (gchar_pos(&pos) == NUL) /* skip NUL at EOL */
+ if (gchar_pos(&pos) == NUL) { // skip NUL at EOL
inc(&pos);
+ }
break;
}
}
if ((*func)(&pos) == -1) {
- if (count)
+ if (count) {
return FAIL;
+ }
noskip = true;
break;
}
}
found:
- /* skip white space */
- while (!noskip && ((c = gchar_pos(&pos)) == ' ' || c == '\t'))
- if (incl(&pos) == -1)
+ // skip white space
+ while (!noskip && ((c = gchar_pos(&pos)) == ' ' || c == '\t')) {
+ if (incl(&pos) == -1) {
break;
+ }
+ }
if (equalpos(prev_pos, pos)) {
// didn't actually move, advance one character and try again
@@ -2509,28 +2579,22 @@ found:
return OK;
}
-/*
- * Find the next paragraph or section in direction 'dir'.
- * Paragraphs are currently supposed to be separated by empty lines.
- * If 'what' is NUL we go to the next paragraph.
- * If 'what' is '{' or '}' we go to the next section.
- * If 'both' is TRUE also stop at '}'.
- * Return TRUE if the next paragraph or section was found.
- */
-bool
-findpar (
- bool *pincl, /* Return: true if last char is to be included */
- int dir,
- long count,
- int what,
- int both
-)
+/// Find the next paragraph or section in direction 'dir'.
+/// Paragraphs are currently supposed to be separated by empty lines.
+/// If 'what' is NUL we go to the next paragraph.
+/// If 'what' is '{' or '}' we go to the next section.
+/// If 'both' is TRUE also stop at '}'.
+///
+/// @param pincl Return: true if last char is to be included
+///
+/// @return TRUE if the next paragraph or section was found.
+bool findpar(bool *pincl, int dir, long count, int what, int both)
{
linenr_T curr;
- bool did_skip; /* true after separating lines have been skipped */
- bool first; /* true on first line */
- linenr_T fold_first; /* first line of a closed fold */
- linenr_T fold_last; /* last line of a closed fold */
+ bool did_skip; // true after separating lines have been skipped
+ bool first; // true on first line
+ linenr_T fold_first; // first line of a closed fold
+ linenr_T fold_last; // last line of a closed fold
bool fold_skipped; /* true if a closed fold was skipped this
iteration */
@@ -2539,32 +2603,37 @@ findpar (
while (count--) {
did_skip = false;
for (first = true;; first = false) {
- if (*ml_get(curr) != NUL)
+ if (*ml_get(curr) != NUL) {
did_skip = true;
+ }
- /* skip folded lines */
+ // skip folded lines
fold_skipped = false;
if (first && hasFolding(curr, &fold_first, &fold_last)) {
curr = ((dir > 0) ? fold_last : fold_first) + dir;
fold_skipped = true;
}
- if (!first && did_skip && startPS(curr, what, both))
+ if (!first && did_skip && startPS(curr, what, both)) {
break;
+ }
- if (fold_skipped)
+ if (fold_skipped) {
curr -= dir;
+ }
if ((curr += dir) < 1 || curr > curbuf->b_ml.ml_line_count) {
- if (count)
+ if (count) {
return false;
+ }
curr -= dir;
break;
}
}
}
setpcmark();
- if (both && *ml_get(curr) == '}') /* include line with '}' */
+ if (both && *ml_get(curr) == '}') { // include line with '}'
++curr;
+ }
curwin->w_cursor.lnum = curr;
if (curr == curbuf->b_ml.ml_line_count && what != '}') {
char_u *line = ml_get(curr);
@@ -2576,8 +2645,9 @@ findpar (
curwin->w_cursor.col -= utf_head_off(line, line + curwin->w_cursor.col);
*pincl = true;
}
- } else
+ } else {
curwin->w_cursor.col = 0;
+ }
return true;
}
@@ -2586,7 +2656,7 @@ findpar (
*/
static int inmacro(char_u *opt, char_u *s)
{
- char_u *macro;
+ char_u *macro;
for (macro = opt; macro[0]; ++macro) {
/* Accept two characters in the option being equal to two characters
@@ -2597,11 +2667,13 @@ static int inmacro(char_u *opt, char_u *s)
&& (s[0] == NUL || s[0] == ' ')))
&& (macro[1] == s[1]
|| ((macro[1] == NUL || macro[1] == ' ')
- && (s[0] == NUL || s[1] == NUL || s[1] == ' '))))
+ && (s[0] == NUL || s[1] == NUL || s[1] == ' ')))) {
break;
+ }
++macro;
- if (macro[0] == NUL)
+ if (macro[0] == NUL) {
break;
+ }
}
return macro[0] != NUL;
}
@@ -2613,7 +2685,7 @@ static int inmacro(char_u *opt, char_u *s)
*/
int startPS(linenr_T lnum, int para, int both)
{
- char_u *s;
+ char_u *s;
s = ml_get(lnum);
if (*s == para || *s == '\f' || (both && *s == '}')) {
@@ -2642,7 +2714,7 @@ int startPS(linenr_T lnum, int para, int both)
* 2 or higher - keyword characters (letters, digits and underscore)
*/
-static int cls_bigword; /* TRUE for "W", "B" or "E" */
+static int cls_bigword; // TRUE for "W", "B" or "E"
/*
* cls() - returns the class of character at curwin->w_cursor
@@ -2669,20 +2741,15 @@ static int cls(void)
return c;
}
-/*
- * fwd_word(count, type, eol) - move forward one word
- *
- * Returns FAIL if the cursor was already at the end of the file.
- * If eol is TRUE, last word stops at end of line (for operators).
- */
-int
-fwd_word(
- long count,
- int bigword, /* "W", "E" or "B" */
- int eol
-)
+/// fwd_word(count, type, eol) - move forward one word
+///
+/// @return FAIL if the cursor was already at the end of the file.
+/// If eol is TRUE, last word stops at end of line (for operators).
+///
+/// @param bigword "W", "E" or "B"
+int fwd_word(long count, int bigword, int eol)
{
- int sclass; /* starting class */
+ int sclass; // starting class
int i;
int last_line;
@@ -2702,20 +2769,24 @@ fwd_word(
*/
last_line = (curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count);
i = inc_cursor();
- if (i == -1 || (i >= 1 && last_line)) /* started at last char in file */
+ if (i == -1 || (i >= 1 && last_line)) { // started at last char in file
return FAIL;
- if (i >= 1 && eol && count == 0) /* started at last char in line */
+ }
+ if (i >= 1 && eol && count == 0) { // started at last char in line
return OK;
+ }
/*
* Go one char past end of current word (if any)
*/
- if (sclass != 0)
+ if (sclass != 0) {
while (cls() == sclass) {
i = inc_cursor();
- if (i == -1 || (i >= 1 && eol && count == 0))
+ if (i == -1 || (i >= 1 && eol && count == 0)) {
return OK;
+ }
}
+ }
/*
* go to next non-white
@@ -2724,12 +2795,14 @@ fwd_word(
/*
* We'll stop if we land on a blank line
*/
- if (curwin->w_cursor.col == 0 && *get_cursor_line_ptr() == NUL)
+ if (curwin->w_cursor.col == 0 && *get_cursor_line_ptr() == NUL) {
break;
+ }
i = inc_cursor();
- if (i == -1 || (i >= 1 && eol && count == 0))
+ if (i == -1 || (i >= 1 && eol && count == 0)) {
return OK;
+ }
}
}
return OK;
@@ -2744,18 +2817,20 @@ fwd_word(
*/
int bck_word(long count, int bigword, int stop)
{
- int sclass; /* starting class */
+ int sclass; // starting class
curwin->w_cursor.coladd = 0;
cls_bigword = bigword;
while (--count >= 0) {
/* When inside a range of folded lines, move to the first char of the
* first line. */
- if (hasFolding(curwin->w_cursor.lnum, &curwin->w_cursor.lnum, NULL))
+ if (hasFolding(curwin->w_cursor.lnum, &curwin->w_cursor.lnum, NULL)) {
curwin->w_cursor.col = 0;
+ }
sclass = cls();
- if (dec_cursor() == -1) /* started at start of file */
+ if (dec_cursor() == -1) { // started at start of file
return FAIL;
+ }
if (!stop || sclass == cls() || sclass == 0) {
/*
@@ -2775,11 +2850,12 @@ int bck_word(long count, int bigword, int stop)
/*
* Move backward to start of this word.
*/
- if (skip_chars(cls(), BACKWARD))
+ if (skip_chars(cls(), BACKWARD)) {
return OK;
+ }
}
- inc_cursor(); /* overshot - forward one */
+ inc_cursor(); // overshot - forward one
finished:
stop = FALSE;
}
@@ -2803,7 +2879,7 @@ finished:
*/
int end_word(long count, int bigword, int stop, int empty)
{
- int sclass; /* starting class */
+ int sclass; // starting class
curwin->w_cursor.coladd = 0;
cls_bigword = bigword;
@@ -2814,8 +2890,9 @@ int end_word(long count, int bigword, int stop, int empty)
coladvance(MAXCOL);
}
sclass = cls();
- if (inc_cursor() == -1)
+ if (inc_cursor() == -1) {
return FAIL;
+ }
/*
* If we're in the middle of a word, we just have to move to the end
@@ -2825,8 +2902,9 @@ int end_word(long count, int bigword, int stop, int empty)
/*
* Move forward to end of the current word
*/
- if (skip_chars(sclass, FORWARD))
+ if (skip_chars(sclass, FORWARD)) {
return FAIL;
+ }
} else if (!stop || sclass == 0) {
/*
* We were at the end of a word. Go to the end of the next word.
@@ -2845,47 +2923,48 @@ int end_word(long count, int bigword, int stop, int empty)
/*
* Move forward to the end of this word.
*/
- if (skip_chars(cls(), FORWARD))
+ if (skip_chars(cls(), FORWARD)) {
return FAIL;
+ }
}
- dec_cursor(); /* overshot - one char backward */
+ dec_cursor(); // overshot - one char backward
finished:
- stop = FALSE; /* we move only one word less */
+ stop = FALSE; // we move only one word less
}
return OK;
}
-/*
- * Move back to the end of the word.
- *
- * Returns FAIL if start of the file was reached.
- */
-int
-bckend_word(
- long count,
- int bigword, /* TRUE for "B" */
- int eol /* TRUE: stop at end of line. */
-)
+/// Move back to the end of the word.
+///
+/// @param bigword TRUE for "B"
+/// @param eol if true, then stop at end of line.
+///
+/// @return FAIL if start of the file was reached.
+int bckend_word(long count, int bigword, bool eol)
{
- int sclass; /* starting class */
+ int sclass; // starting class
int i;
curwin->w_cursor.coladd = 0;
cls_bigword = bigword;
while (--count >= 0) {
sclass = cls();
- if ((i = dec_cursor()) == -1)
+ if ((i = dec_cursor()) == -1) {
return FAIL;
- if (eol && i == 1)
+ }
+ if (eol && i == 1) {
return OK;
+ }
/*
* Move backward to before the start of this word.
*/
if (sclass != 0) {
- while (cls() == sclass)
- if ((i = dec_cursor()) == -1 || (eol && i == 1))
+ while (cls() == sclass) {
+ if ((i = dec_cursor()) == -1 || (eol && i == 1)) {
return OK;
+ }
+ }
}
/*
@@ -2903,16 +2982,17 @@ bckend_word(
return OK;
}
-/*
- * Skip a row of characters of the same class.
- * Return TRUE when end-of-file reached, FALSE otherwise.
- */
-static int skip_chars(int cclass, int dir)
+/// Skip a row of characters of the same class.
+///
+/// @return true when end-of-file reached, false otherwise.
+static bool skip_chars(int cclass, int dir)
{
- while (cls() == cclass)
- if ((dir == FORWARD ? inc_cursor() : dec_cursor()) == -1)
- return TRUE;
- return FALSE;
+ while (cls() == cclass) {
+ if ((dir == FORWARD ? inc_cursor() : dec_cursor()) == -1) {
+ return true;
+ }
+ }
+ return false;
}
/*
@@ -2920,14 +3000,15 @@ static int skip_chars(int cclass, int dir)
*/
static void back_in_line(void)
{
- int sclass; /* starting class */
+ int sclass; // starting class
sclass = cls();
for (;; ) {
- if (curwin->w_cursor.col == 0) /* stop at start of line */
+ if (curwin->w_cursor.col == 0) { // stop at start of line
break;
+ }
dec_cursor();
- if (cls() != sclass) { /* stop at start of word */
+ if (cls() != sclass) { // stop at start of word
inc_cursor();
break;
}
@@ -2947,36 +3028,29 @@ static void find_first_blank(pos_T *posp)
}
}
-/*
- * Skip count/2 sentences and count/2 separating white spaces.
- */
-static void
-findsent_forward(
- long count,
- int at_start_sent /* cursor is at start of sentence */
-)
+/// Skip count/2 sentences and count/2 separating white spaces.
+///
+/// @param at_start_sent cursor is at start of sentence
+static void findsent_forward(long count, bool at_start_sent)
{
while (count--) {
findsent(FORWARD, 1L);
- if (at_start_sent)
+ if (at_start_sent) {
find_first_blank(&curwin->w_cursor);
- if (count == 0 || at_start_sent)
+ }
+ if (count == 0 || at_start_sent) {
decl(&curwin->w_cursor);
+ }
at_start_sent = !at_start_sent;
}
}
-/*
- * Find word under cursor, cursor at end.
- * Used while an operator is pending, and in Visual mode.
- */
-int
-current_word(
- oparg_T *oap,
- long count,
- int include, /* TRUE: include word and white space */
- int bigword /* FALSE == word, TRUE == WORD */
-)
+/// Find word under cursor, cursor at end.
+/// Used while an operator is pending, and in Visual mode.
+///
+/// @param include TRUE: include word and white space
+/// @param bigword FALSE == word, TRUE == WORD
+int current_word(oparg_T *oap, long count, int include, int bigword)
{
pos_T start_pos;
pos_T pos;
@@ -2986,9 +3060,10 @@ current_word(
cls_bigword = bigword;
clearpos(&start_pos);
- /* Correct cursor when 'selection' is exclusive */
- if (VIsual_active && *p_sel == 'e' && lt(VIsual, curwin->w_cursor))
+ // Correct cursor when 'selection' is exclusive
+ if (VIsual_active && *p_sel == 'e' && lt(VIsual, curwin->w_cursor)) {
dec_cursor();
+ }
/*
* When Visual mode is not active, or when the VIsual area is only one
@@ -3007,8 +3082,9 @@ current_word(
* not be included ("word"), find end of word.
*/
if ((cls() == 0) == include) {
- if (end_word(1L, bigword, TRUE, TRUE) == FAIL)
+ if (end_word(1L, bigword, TRUE, TRUE) == FAIL) {
return FAIL;
+ }
} else {
/*
* If the start is not on white space, and white space should be
@@ -3018,19 +3094,21 @@ current_word(
* word) back up to end of the line.
*/
fwd_word(1L, bigword, TRUE);
- if (curwin->w_cursor.col == 0)
+ if (curwin->w_cursor.col == 0) {
decl(&curwin->w_cursor);
- else
+ } else {
oneleft();
+ }
- if (include)
+ if (include) {
include_white = TRUE;
+ }
}
if (VIsual_active) {
- /* should do something when inclusive == false ! */
+ // should do something when inclusive == false !
VIsual = start_pos;
- redraw_curbuf_later(INVERTED); /* update the inversion */
+ redraw_curbuf_later(INVERTED); // update the inversion
} else {
oap->start = start_pos;
oap->motion_type = kMTCharWise;
@@ -3047,35 +3125,42 @@ current_word(
/*
* In Visual mode, with cursor at start: move cursor back.
*/
- if (decl(&curwin->w_cursor) == -1)
+ if (decl(&curwin->w_cursor) == -1) {
return FAIL;
+ }
if (include != (cls() != 0)) {
- if (bck_word(1L, bigword, TRUE) == FAIL)
+ if (bck_word(1L, bigword, TRUE) == FAIL) {
return FAIL;
+ }
} else {
- if (bckend_word(1L, bigword, TRUE) == FAIL)
+ if (bckend_word(1L, bigword, true) == FAIL) {
return FAIL;
+ }
(void)incl(&curwin->w_cursor);
}
} else {
/*
* Move cursor forward one word and/or white area.
*/
- if (incl(&curwin->w_cursor) == -1)
+ if (incl(&curwin->w_cursor) == -1) {
return FAIL;
+ }
if (include != (cls() == 0)) {
- if (fwd_word(1L, bigword, TRUE) == FAIL && count > 1)
+ if (fwd_word(1L, bigword, TRUE) == FAIL && count > 1) {
return FAIL;
+ }
/*
* If end is just past a new-line, we don't want to include
* the first character on the line.
* Put cursor on last char of white.
*/
- if (oneleft() == FAIL)
+ if (oneleft() == FAIL) {
inclusive = false;
+ }
} else {
- if (end_word(1L, bigword, TRUE, TRUE) == FAIL)
+ if (end_word(1L, bigword, TRUE, TRUE) == FAIL) {
return FAIL;
+ }
}
}
--count;
@@ -3091,29 +3176,32 @@ current_word(
* (cursor is at start of next line).
* But don't delete white space at start of line (indent).
*/
- pos = curwin->w_cursor; /* save cursor position */
+ pos = curwin->w_cursor; // save cursor position
curwin->w_cursor = start_pos;
if (oneleft() == OK) {
back_in_line();
if (cls() == 0 && curwin->w_cursor.col > 0) {
- if (VIsual_active)
+ if (VIsual_active) {
VIsual = curwin->w_cursor;
- else
+ } else {
oap->start = curwin->w_cursor;
+ }
}
}
- curwin->w_cursor = pos; /* put cursor back at end */
+ curwin->w_cursor = pos; // put cursor back at end
}
if (VIsual_active) {
- if (*p_sel == 'e' && inclusive && ltoreq(VIsual, curwin->w_cursor))
+ if (*p_sel == 'e' && inclusive && ltoreq(VIsual, curwin->w_cursor)) {
inc_cursor();
+ }
if (VIsual_mode == 'V') {
VIsual_mode = 'v';
- redraw_cmdline = TRUE; /* show mode later */
+ redraw_cmdline = true; // show mode later
}
- } else
+ } else {
oap->inclusive = inclusive;
+ }
return OK;
}
@@ -3126,14 +3214,14 @@ int current_sent(oparg_T *oap, long count, int include)
{
pos_T start_pos;
pos_T pos;
- int start_blank;
+ bool start_blank;
int c;
- int at_start_sent;
+ bool at_start_sent;
long ncount;
start_pos = curwin->w_cursor;
pos = start_pos;
- findsent(FORWARD, 1L); /* Find start of next sentence. */
+ findsent(FORWARD, 1L); // Find start of next sentence.
/*
* When the Visual area is bigger than one character: Extend it.
@@ -3148,32 +3236,36 @@ extend:
* - in a sentence or just after it
* - at the start of a sentence
*/
- at_start_sent = TRUE;
+ at_start_sent = true;
decl(&pos);
while (lt(pos, curwin->w_cursor)) {
c = gchar_pos(&pos);
if (!ascii_iswhite(c)) {
- at_start_sent = FALSE;
+ at_start_sent = false;
break;
}
incl(&pos);
}
if (!at_start_sent) {
findsent(BACKWARD, 1L);
- if (equalpos(curwin->w_cursor, start_pos))
- at_start_sent = TRUE; /* exactly at start of sentence */
- else
- /* inside a sentence, go to its end (start of next) */
+ if (equalpos(curwin->w_cursor, start_pos)) {
+ at_start_sent = true; // exactly at start of sentence
+ } else {
+ // inside a sentence, go to its end (start of next)
findsent(FORWARD, 1L);
+ }
}
- if (include) /* "as" gets twice as much as "is" */
+ if (include) { // "as" gets twice as much as "is"
count *= 2;
+ }
while (count--) {
- if (at_start_sent)
+ if (at_start_sent) {
find_first_blank(&curwin->w_cursor);
+ }
c = gchar_cursor();
- if (!at_start_sent || (!include && !ascii_iswhite(c)))
+ if (!at_start_sent || (!include && !ascii_iswhite(c))) {
findsent(BACKWARD, 1L);
+ }
at_start_sent = !at_start_sent;
}
} else {
@@ -3185,28 +3277,31 @@ extend:
* - in a sentence
*/
incl(&pos);
- at_start_sent = TRUE;
- if (!equalpos(pos, curwin->w_cursor)) { /* not just before a sentence */
- at_start_sent = FALSE;
+ at_start_sent = true;
+ if (!equalpos(pos, curwin->w_cursor)) { // not just before a sentence
+ at_start_sent = false;
while (lt(pos, curwin->w_cursor)) {
c = gchar_pos(&pos);
if (!ascii_iswhite(c)) {
- at_start_sent = TRUE;
+ at_start_sent = true;
break;
}
incl(&pos);
}
- if (at_start_sent) /* in the sentence */
+ if (at_start_sent) { // in the sentence
findsent(BACKWARD, 1L);
- else /* in/before white before a sentence */
+ } else { // in/before white before a sentence
curwin->w_cursor = start_pos;
+ }
}
- if (include) /* "as" gets twice as much as "is" */
+ if (include) { // "as" gets twice as much as "is"
count *= 2;
+ }
findsent_forward(count, at_start_sent);
- if (*p_sel == 'e')
+ if (*p_sel == 'e') {
++curwin->w_cursor.col;
+ }
}
return OK;
}
@@ -3215,27 +3310,30 @@ extend:
* If the cursor started on a blank, check if it is just before the start
* of the next sentence.
*/
- while (c = gchar_pos(&pos), ascii_iswhite(c))
+ while (c = gchar_pos(&pos), ascii_iswhite(c)) {
incl(&pos);
+ }
if (equalpos(pos, curwin->w_cursor)) {
- start_blank = TRUE;
- find_first_blank(&start_pos); /* go back to first blank */
+ start_blank = true;
+ find_first_blank(&start_pos); // go back to first blank
} else {
- start_blank = FALSE;
+ start_blank = false;
findsent(BACKWARD, 1L);
start_pos = curwin->w_cursor;
}
- if (include)
+ if (include) {
ncount = count * 2;
- else {
+ } else {
ncount = count;
- if (start_blank)
+ if (start_blank) {
--ncount;
+ }
}
- if (ncount > 0)
- findsent_forward(ncount, TRUE);
- else
+ if (ncount > 0) {
+ findsent_forward(ncount, true);
+ } else {
decl(&curwin->w_cursor);
+ }
if (include) {
/*
@@ -3246,57 +3344,57 @@ extend:
if (start_blank) {
find_first_blank(&curwin->w_cursor);
c = gchar_pos(&curwin->w_cursor);
- if (ascii_iswhite(c))
+ if (ascii_iswhite(c)) {
decl(&curwin->w_cursor);
- } else if (c = gchar_cursor(), !ascii_iswhite(c))
+ }
+ } else if (c = gchar_cursor(), !ascii_iswhite(c)) {
find_first_blank(&start_pos);
+ }
}
if (VIsual_active) {
- /* Avoid getting stuck with "is" on a single space before a sentence. */
- if (equalpos(start_pos, curwin->w_cursor))
+ // Avoid getting stuck with "is" on a single space before a sentence.
+ if (equalpos(start_pos, curwin->w_cursor)) {
goto extend;
- if (*p_sel == 'e')
+ }
+ if (*p_sel == 'e') {
++curwin->w_cursor.col;
+ }
VIsual = start_pos;
VIsual_mode = 'v';
redraw_cmdline = true; // show mode later
redraw_curbuf_later(INVERTED); // update the inversion
} else {
- /* include a newline after the sentence, if there is one */
- if (incl(&curwin->w_cursor) == -1)
+ // include a newline after the sentence, if there is one
+ if (incl(&curwin->w_cursor) == -1) {
oap->inclusive = true;
- else
+ } else {
oap->inclusive = false;
+ }
oap->start = start_pos;
oap->motion_type = kMTCharWise;
}
return OK;
}
-/*
- * Find block under the cursor, cursor at end.
- * "what" and "other" are two matching parenthesis/brace/etc.
- */
-int
-current_block(
- oparg_T *oap,
- long count,
- int include, /* TRUE == include white space */
- int what, /* '(', '{', etc. */
- int other /* ')', '}', etc. */
-)
+/// Find block under the cursor, cursor at end.
+/// "what" and "other" are two matching parenthesis/brace/etc.
+///
+/// @param include TRUE == include white space
+/// @param what '(', '{', etc.
+/// @param other ')', '}', etc.
+int current_block(oparg_T *oap, long count, int include, int what, int other)
{
pos_T old_pos;
- pos_T *pos = NULL;
+ pos_T *pos = NULL;
pos_T start_pos;
- pos_T *end_pos;
+ pos_T *end_pos;
pos_T old_start, old_end;
- char_u *save_cpo;
- int sol = FALSE; /* '{' at start of line */
+ char_u *save_cpo;
+ bool sol = false; // '{' at start of line
old_pos = curwin->w_cursor;
- old_end = curwin->w_cursor; /* remember where we started */
+ old_end = curwin->w_cursor; // remember where we started
old_start = old_end;
/*
@@ -3304,18 +3402,23 @@ current_block(
*/
if (!VIsual_active || equalpos(VIsual, curwin->w_cursor)) {
setpcmark();
- if (what == '{') /* ignore indent */
- while (inindent(1))
- if (inc_cursor() != 0)
+ if (what == '{') { // ignore indent
+ while (inindent(1)) {
+ if (inc_cursor() != 0) {
break;
- if (gchar_cursor() == what)
- /* cursor on '(' or '{', move cursor just after it */
+ }
+ }
+ }
+ if (gchar_cursor() == what) {
+ // cursor on '(' or '{', move cursor just after it
++curwin->w_cursor.col;
+ }
} else if (lt(VIsual, curwin->w_cursor)) {
old_start = VIsual;
- curwin->w_cursor = VIsual; /* cursor at low end of Visual */
- } else
+ curwin->w_cursor = VIsual; // cursor at low end of Visual
+ } else {
old_end = VIsual;
+ }
// Search backwards for unclosed '(', '{', etc..
// Put this position in start_pos.
@@ -3351,7 +3454,7 @@ current_block(
sol = (curwin->w_cursor.col == 0);
decl(&curwin->w_cursor);
while (inindent(1)) {
- sol = TRUE;
+ sol = true;
if (decl(&curwin->w_cursor) != 0) {
break;
}
@@ -3376,8 +3479,9 @@ current_block(
return FAIL;
}
curwin->w_cursor = *end_pos;
- } else
+ } else {
break;
+ }
}
if (VIsual_active) {
@@ -3389,35 +3493,35 @@ current_block(
}
VIsual = start_pos;
VIsual_mode = 'v';
- redraw_curbuf_later(INVERTED); /* update the inversion */
+ redraw_curbuf_later(INVERTED); // update the inversion
showmode();
} else {
oap->start = start_pos;
oap->motion_type = kMTCharWise;
oap->inclusive = false;
- if (sol)
+ if (sol) {
incl(&curwin->w_cursor);
- else if (ltoreq(start_pos, curwin->w_cursor))
- /* Include the character under the cursor. */
+ } else if (ltoreq(start_pos, curwin->w_cursor)) {
+ // Include the character under the cursor.
oap->inclusive = true;
- else
+ } else {
/* End is before the start (no text in between <>, [], etc.): don't
* operate on any text. */
curwin->w_cursor = start_pos;
+ }
}
return OK;
}
-/*
- * Return TRUE if the cursor is on a "<aaa>" tag. Ignore "<aaa/>".
- * When "end_tag" is TRUE return TRUE if the cursor is on "</aaa>".
- */
-static int in_html_tag(int end_tag)
+/// @param end_tag when true, return true if the cursor is on "</aaa>".
+///
+/// @return true if the cursor is on a "<aaa>" tag. Ignore "<aaa/>".
+static bool in_html_tag(bool end_tag)
{
- char_u *line = get_cursor_line_ptr();
- char_u *p;
+ char_u *line = get_cursor_line_ptr();
+ char_u *p;
int c;
int lc = NUL;
pos_T pos;
@@ -3444,39 +3548,37 @@ static int in_html_tag(int end_tag)
return *p == '/';
}
- /* check that there is no '/' after the '<' */
- if (*p == '/')
- return FALSE;
+ // check that there is no '/' after the '<'
+ if (*p == '/') {
+ return false;
+ }
- /* check that the matching '>' is not preceded by '/' */
+ // check that the matching '>' is not preceded by '/'
for (;; ) {
- if (inc(&pos) < 0)
- return FALSE;
+ if (inc(&pos) < 0) {
+ return false;
+ }
c = *ml_get_pos(&pos);
- if (c == '>')
+ if (c == '>') {
break;
+ }
lc = c;
}
return lc != '/';
}
-/*
- * Find tag block under the cursor, cursor at end.
- */
-int
-current_tagblock(
- oparg_T *oap,
- long count_arg,
- bool include // true == include white space
-)
+/// Find tag block under the cursor, cursor at end.
+///
+/// @param include true == include white space
+int current_tagblock(oparg_T *oap, long count_arg, bool include)
{
long count = count_arg;
pos_T old_pos;
pos_T start_pos;
pos_T end_pos;
pos_T old_start, old_end;
- char_u *p;
- char_u *cp;
+ char_u *p;
+ char_u *cp;
int len;
bool do_include = include;
bool save_p_ws = p_ws;
@@ -3486,40 +3588,47 @@ current_tagblock(
p_ws = false;
old_pos = curwin->w_cursor;
- old_end = curwin->w_cursor; /* remember where we started */
+ old_end = curwin->w_cursor; // remember where we started
old_start = old_end;
- if (!VIsual_active || *p_sel == 'e')
- decl(&old_end); /* old_end is inclusive */
-
+ if (!VIsual_active || *p_sel == 'e') {
+ decl(&old_end); // old_end is inclusive
+ }
/*
* If we start on "<aaa>" select that block.
*/
if (!VIsual_active || equalpos(VIsual, curwin->w_cursor)) {
setpcmark();
- /* ignore indent */
- while (inindent(1))
- if (inc_cursor() != 0)
+ // ignore indent
+ while (inindent(1)) {
+ if (inc_cursor() != 0) {
break;
+ }
+ }
- if (in_html_tag(FALSE)) {
- /* cursor on start tag, move to its '>' */
- while (*get_cursor_pos_ptr() != '>')
- if (inc_cursor() < 0)
+ if (in_html_tag(false)) {
+ // cursor on start tag, move to its '>'
+ while (*get_cursor_pos_ptr() != '>') {
+ if (inc_cursor() < 0) {
break;
- } else if (in_html_tag(TRUE)) {
- /* cursor on end tag, move to just before it */
- while (*get_cursor_pos_ptr() != '<')
- if (dec_cursor() < 0)
+ }
+ }
+ } else if (in_html_tag(true)) {
+ // cursor on end tag, move to just before it
+ while (*get_cursor_pos_ptr() != '<') {
+ if (dec_cursor() < 0) {
break;
+ }
+ }
dec_cursor();
old_end = curwin->w_cursor;
}
} else if (lt(VIsual, curwin->w_cursor)) {
old_start = VIsual;
- curwin->w_cursor = VIsual; /* cursor at low end of Visual */
- } else
+ curwin->w_cursor = VIsual; // cursor at low end of Visual
+ } else {
old_end = VIsual;
+ }
again:
/*
@@ -3527,11 +3636,10 @@ again:
* Put this position in start_pos.
*/
for (long n = 0; n < count; n++) {
- if (do_searchpair(
- "<[^ \t>/!]\\+\\%(\\_s\\_[^>]\\{-}[^/]>\\|$\\|\\_s\\=>\\)",
- "",
- "</[^>]*>", BACKWARD, NULL, 0,
- NULL, (linenr_T)0, 0L) <= 0) {
+ if (do_searchpair("<[^ \t>/!]\\+\\%(\\_s\\_[^>]\\{-}[^/]>\\|$\\|\\_s\\=>\\)",
+ "",
+ "</[^>]*>", BACKWARD, NULL, 0,
+ NULL, (linenr_T)0, 0L) <= 0) {
curwin->w_cursor = old_pos;
goto theend;
}
@@ -3597,14 +3705,15 @@ again:
end_pos = curwin->w_cursor;
if (!do_include) {
- /* Exclude the start tag. */
+ // Exclude the start tag.
curwin->w_cursor = start_pos;
- while (inc_cursor() >= 0)
+ while (inc_cursor() >= 0) {
if (*get_cursor_pos_ptr() == '>') {
inc_cursor();
start_pos = curwin->w_cursor;
break;
}
+ }
curwin->w_cursor = end_pos;
// If we are in Visual mode and now have the same text as before set
@@ -3629,7 +3738,7 @@ again:
}
VIsual = start_pos;
VIsual_mode = 'v';
- redraw_curbuf_later(INVERTED); /* update the inversion */
+ redraw_curbuf_later(INVERTED); // update the inversion
showmode();
} else {
oap->start = start_pos;
@@ -3650,13 +3759,9 @@ theend:
return retval;
}
-int
-current_par(
- oparg_T *oap,
- long count,
- int include, /* TRUE == include white space */
- int type /* 'p' for paragraph, 'S' for section */
-)
+/// @param include TRUE == include white space
+/// @param type 'p' for paragraph, 'S' for section
+int current_par(oparg_T *oap, long count, int include, int type)
{
linenr_T start_lnum;
linenr_T end_lnum;
@@ -3669,8 +3774,9 @@ current_par(
int t;
int i;
- if (type == 'S') /* not implemented yet */
+ if (type == 'S') { // not implemented yet
return FAIL;
+ }
start_lnum = curwin->w_cursor.lnum;
@@ -3679,10 +3785,11 @@ current_par(
*/
if (VIsual_active && start_lnum != VIsual.lnum) {
extend:
- if (start_lnum < VIsual.lnum)
+ if (start_lnum < VIsual.lnum) {
dir = BACKWARD;
- else
+ } else {
dir = FORWARD;
+ }
for (i = count; --i >= 0; ) {
if (start_lnum ==
(dir == BACKWARD ? 1 : curbuf->b_ml.ml_line_count)) {
@@ -3700,20 +3807,24 @@ extend:
}
for (;; ) {
if (start_lnum == (dir == BACKWARD
- ? 1 : curbuf->b_ml.ml_line_count))
+ ? 1 : curbuf->b_ml.ml_line_count)) {
break;
+ }
if (start_is_white != linewhite(start_lnum + dir)
|| (!start_is_white
&& startPS(start_lnum + (dir > 0
- ? 1 : 0), 0, 0)))
+ ? 1 : 0), 0, 0))) {
break;
+ }
start_lnum += dir;
}
- if (!include)
+ if (!include) {
break;
+ }
if (start_lnum == (dir == BACKWARD
- ? 1 : curbuf->b_ml.ml_line_count))
+ ? 1 : curbuf->b_ml.ml_line_count)) {
break;
+ }
prev_start_is_white = start_is_white;
}
}
@@ -3727,12 +3838,14 @@ extend:
*/
white_in_front = linewhite(start_lnum);
while (start_lnum > 1) {
- if (white_in_front) { /* stop at first white line */
- if (!linewhite(start_lnum - 1))
+ if (white_in_front) { // stop at first white line
+ if (!linewhite(start_lnum - 1)) {
break;
- } else { /* stop at first non-white line of start of paragraph */
- if (linewhite(start_lnum - 1) || startPS(start_lnum, 0, 0))
+ }
+ } else { // stop at first non-white line of start of paragraph
+ if (linewhite(start_lnum - 1) || startPS(start_lnum, 0, 0)) {
break;
+ }
}
--start_lnum;
}
@@ -3741,19 +3854,23 @@ extend:
* Move past the end of any white lines.
*/
end_lnum = start_lnum;
- while (end_lnum <= curbuf->b_ml.ml_line_count && linewhite(end_lnum))
+ while (end_lnum <= curbuf->b_ml.ml_line_count && linewhite(end_lnum)) {
++end_lnum;
+ }
--end_lnum;
i = count;
- if (!include && white_in_front)
+ if (!include && white_in_front) {
--i;
+ }
while (i--) {
- if (end_lnum == curbuf->b_ml.ml_line_count)
+ if (end_lnum == curbuf->b_ml.ml_line_count) {
return FAIL;
+ }
- if (!include)
+ if (!include) {
do_white = linewhite(end_lnum + 1);
+ }
if (include || !do_white) {
++end_lnum;
@@ -3762,29 +3879,35 @@ extend:
*/
while (end_lnum < curbuf->b_ml.ml_line_count
&& !linewhite(end_lnum + 1)
- && !startPS(end_lnum + 1, 0, 0))
+ && !startPS(end_lnum + 1, 0, 0)) {
++end_lnum;
+ }
}
- if (i == 0 && white_in_front && include)
+ if (i == 0 && white_in_front && include) {
break;
+ }
/*
* skip to end of white lines after paragraph
*/
- if (include || do_white)
+ if (include || do_white) {
while (end_lnum < curbuf->b_ml.ml_line_count
- && linewhite(end_lnum + 1))
+ && linewhite(end_lnum + 1)) {
++end_lnum;
+ }
+ }
}
/*
* If there are no empty lines at the end, try to find some empty lines at
* the start (unless that has been done already).
*/
- if (!white_in_front && !linewhite(end_lnum) && include)
- while (start_lnum > 1 && linewhite(start_lnum - 1))
+ if (!white_in_front && !linewhite(end_lnum) && include) {
+ while (start_lnum > 1 && linewhite(start_lnum - 1)) {
--start_lnum;
+ }
+ }
if (VIsual_active) {
// Problem: when doing "Vipipip" nothing happens in a single white
@@ -3793,11 +3916,11 @@ extend:
goto extend;
}
if (VIsual.lnum != start_lnum) {
- VIsual.lnum = start_lnum;
- VIsual.col = 0;
+ VIsual.lnum = start_lnum;
+ VIsual.col = 0;
}
VIsual_mode = 'V';
- redraw_curbuf_later(INVERTED); /* update the inversion */
+ redraw_curbuf_later(INVERTED); // update the inversion
showmode();
} else {
oap->start.lnum = start_lnum;
@@ -3811,19 +3934,14 @@ extend:
}
-/*
- * Search quote char from string line[col].
- * Quote character escaped by one of the characters in "escape" is not counted
- * as a quote.
- * Returns column number of "quotechar" or -1 when not found.
- */
-static int
-find_next_quote(
- char_u *line,
- int col,
- int quotechar,
- char_u *escape /* escape characters, can be NULL */
-)
+/// Search quote char from string line[col].
+/// Quote character escaped by one of the characters in "escape" is not counted
+/// as a quote.
+///
+/// @param escape escape characters, can be NULL
+///
+/// @return column number of "quotechar" or -1 when not found.
+static int find_next_quote(char_u *line, int col, int quotechar, char_u *escape)
{
int c;
@@ -3841,19 +3959,14 @@ find_next_quote(
return col;
}
-/*
- * Search backwards in "line" from column "col_start" to find "quotechar".
- * Quote character escaped by one of the characters in "escape" is not counted
- * as a quote.
- * Return the found column or zero.
- */
-static int
-find_prev_quote(
- char_u *line,
- int col_start,
- int quotechar,
- char_u *escape /* escape characters, can be NULL */
-)
+/// Search backwards in "line" from column "col_start" to find "quotechar".
+/// Quote character escaped by one of the characters in "escape" is not counted
+/// as a quote.
+///
+/// @param escape escape characters, can be NULL
+///
+/// @return the found column or zero.
+static int find_prev_quote(char_u *line, int col_start, int quotechar, char_u *escape)
{
int n;
@@ -3861,29 +3974,32 @@ find_prev_quote(
col_start--;
col_start -= utf_head_off(line, line + col_start);
n = 0;
- if (escape != NULL)
+ if (escape != NULL) {
while (col_start - n > 0 && vim_strchr(escape,
- line[col_start - n - 1]) != NULL)
+ line[col_start - n - 1]) != NULL) {
++n;
- if (n & 1)
- col_start -= n; /* uneven number of escape chars, skip it */
- else if (line[col_start] == quotechar)
+ }
+ }
+ if (n & 1) {
+ col_start -= n; // uneven number of escape chars, skip it
+ } else if (line[col_start] ==
+ quotechar) {
break;
+ }
}
return col_start;
}
-// Find quote under the cursor, cursor at end.
-// Returns true if found, else false.
-bool current_quote(
- oparg_T *oap,
- long count,
- bool include, // true == include quote char
- int quotechar // Quote character
-)
+/// Find quote under the cursor, cursor at end.
+///
+/// @param include true == include quote char
+/// @param quotechar Quote character
+///
+/// @return true if found, else false.
+bool current_quote(oparg_T *oap, long count, bool include, int quotechar)
FUNC_ATTR_NONNULL_ALL
{
- char_u *line = get_cursor_line_ptr();
+ char_u *line = get_cursor_line_ptr();
int col_end;
int col_start = curwin->w_cursor.col;
bool inclusive = false;
@@ -3901,7 +4017,7 @@ bool current_quote(
if (VIsual_active) {
// this only works within one line
if (VIsual.lnum != curwin->w_cursor.lnum) {
- return false;
+ return false;
}
vis_bef_curs = lt(VIsual, curwin->w_cursor);
@@ -3946,12 +4062,13 @@ bool current_quote(
col_end = VIsual.col;
}
- /* Find out if we have a quote in the selection. */
- while (i <= col_end)
+ // Find out if we have a quote in the selection.
+ while (i <= col_end) {
if (line[i++] == quotechar) {
selected_quote = true;
break;
}
+ }
}
if (!vis_empty && line[col_start] == quotechar) {
@@ -3965,9 +4082,9 @@ bool current_quote(
goto abort_search;
}
col_end = find_next_quote(line, col_start + 1, quotechar,
- curbuf->b_p_qe);
+ curbuf->b_p_qe);
if (col_end < 0) {
- /* We were on a starting quote perhaps? */
+ // We were on a starting quote perhaps?
col_end = col_start;
col_start = curwin->w_cursor.col;
}
@@ -3977,23 +4094,23 @@ bool current_quote(
goto abort_search;
}
col_start = find_prev_quote(line, col_end, quotechar,
- curbuf->b_p_qe);
+ curbuf->b_p_qe);
if (line[col_start] != quotechar) {
- /* We were on an ending quote perhaps? */
+ // We were on an ending quote perhaps?
col_start = col_end;
col_end = curwin->w_cursor.col;
}
}
} else if (line[col_start] == quotechar
- || !vis_empty
- ) {
+ || !vis_empty) {
int first_col = col_start;
if (!vis_empty) {
- if (vis_bef_curs)
+ if (vis_bef_curs) {
first_col = find_next_quote(line, col_start, quotechar, NULL);
- else
+ } else {
first_col = find_prev_quote(line, col_start, quotechar, NULL);
+ }
}
/* The cursor is on a quote, we don't know if it's the opening or
* closing quote. Search from the start of the line to find out.
@@ -4001,14 +4118,14 @@ bool current_quote(
* in between two strings. */
col_start = 0;
for (;; ) {
- /* Find open quote character. */
+ // Find open quote character.
col_start = find_next_quote(line, col_start, quotechar, NULL);
if (col_start < 0 || col_start > first_col) {
goto abort_search;
}
// Find close quote character.
col_end = find_next_quote(line, col_start + 1, quotechar,
- curbuf->b_p_qe);
+ curbuf->b_p_qe);
if (col_end < 0) {
goto abort_search;
}
@@ -4020,17 +4137,17 @@ bool current_quote(
col_start = col_end + 1;
}
} else {
- /* Search backward for a starting quote. */
+ // Search backward for a starting quote.
col_start = find_prev_quote(line, col_start, quotechar, curbuf->b_p_qe);
if (line[col_start] != quotechar) {
- /* No quote before the cursor, look after the cursor. */
+ // No quote before the cursor, look after the cursor.
col_start = find_next_quote(line, col_start, quotechar, NULL);
if (col_start < 0) {
goto abort_search;
}
}
- /* Find close quote character. */
+ // Find close quote character.
col_end = find_next_quote(line, col_start + 1, quotechar,
curbuf->b_p_qe);
if (col_end < 0) {
@@ -4041,20 +4158,23 @@ bool current_quote(
// When "include" is true, include spaces after closing quote or before
// the starting quote.
if (include) {
- if (ascii_iswhite(line[col_end + 1]))
- while (ascii_iswhite(line[col_end + 1]))
+ if (ascii_iswhite(line[col_end + 1])) {
+ while (ascii_iswhite(line[col_end + 1])) {
++col_end;
- else
- while (col_start > 0 && ascii_iswhite(line[col_start - 1]))
+ }
+ } else {
+ while (col_start > 0 && ascii_iswhite(line[col_start - 1])) {
--col_start;
+ }
+ }
}
/* Set start position. After vi" another i" must include the ".
* For v2i" include the quotes. */
if (!include && count < 2
- && (vis_empty || !inside_quotes)
- )
+ && (vis_empty || !inside_quotes)) {
++col_start;
+ }
curwin->w_cursor.col = col_start;
if (VIsual_active) {
/* Set the start of the Visual area when the Visual area was empty, we
@@ -4076,13 +4196,14 @@ bool current_quote(
oap->motion_type = kMTCharWise;
}
- /* Set end position. */
+ // Set end position.
curwin->w_cursor.col = col_end;
if ((include || count > 1
- /* After vi" another i" must include the ". */
+ // After vi" another i" must include the ".
|| (!vis_empty && inside_quotes)
- ) && inc_cursor() == 2)
+ ) && inc_cursor() == 2) {
inclusive = true;
+ }
if (VIsual_active) {
if (vis_empty || vis_bef_curs) {
// decrement cursor when 'selection' is not exclusive
@@ -4105,10 +4226,10 @@ bool current_quote(
}
if (VIsual_mode == 'V') {
VIsual_mode = 'v';
- redraw_cmdline = TRUE; /* show mode later */
+ redraw_cmdline = true; // show mode later
}
} else {
- /* Set inclusive and other oap's flags. */
+ // Set inclusive and other oap's flags.
oap->inclusive = inclusive;
}
@@ -4120,10 +4241,10 @@ abort_search:
inc_cursor();
}
if (restore_vis_bef) {
- pos_T t = curwin->w_cursor;
+ pos_T t = curwin->w_cursor;
- curwin->w_cursor = VIsual;
- VIsual = t;
+ curwin->w_cursor = VIsual;
+ VIsual = t;
}
}
return false;
@@ -4131,22 +4252,19 @@ abort_search:
-/*
- * Find next search match under cursor, cursor at end.
- * Used while an operator is pending, and in Visual mode.
- */
-int
-current_search(
- long count,
- bool forward // true for forward, false for backward
-)
+/// Find next search match under cursor, cursor at end.
+/// Used while an operator is pending, and in Visual mode.
+///
+/// @param forward true for forward, false for backward
+int current_search(long count, bool forward)
{
bool old_p_ws = p_ws;
pos_T save_VIsual = VIsual;
- /* Correct cursor when 'selection' is exclusive */
- if (VIsual_active && *p_sel == 'e' && lt(VIsual, curwin->w_cursor))
+ // Correct cursor when 'selection' is exclusive
+ if (VIsual_active && *p_sel == 'e' && lt(VIsual, curwin->w_cursor)) {
dec_cursor();
+ }
pos_T end_pos; // end position of the pattern match
pos_T orig_pos; // position of the cursor at beginning
@@ -4156,7 +4274,7 @@ current_search(
// When searching forward and the cursor is at the start of the Visual
// area, skip the first search backward, otherwise it doesn't move.
const bool skip_first_backward = forward && VIsual_active
- && lt(curwin->w_cursor, VIsual);
+ && lt(curwin->w_cursor, VIsual);
orig_pos = pos = curwin->w_cursor;
if (VIsual_active) {
@@ -4214,8 +4332,9 @@ current_search(
// selection works.
if (i == 1 && !result) { // not found, abort */
curwin->w_cursor = orig_pos;
- if (VIsual_active)
+ if (VIsual_active) {
VIsual = save_VIsual;
+ }
return FAIL;
} else if (i == 0 && !result) {
if (forward) { // try again from start of buffer
@@ -4223,8 +4342,7 @@ current_search(
} else { // try again from end of buffer
// searching backwards, so set pos to last line and col
pos.lnum = curwin->w_buffer->b_ml.ml_line_count;
- pos.col = (colnr_T)STRLEN(
- ml_get(curwin->w_buffer->b_ml.ml_line_count));
+ pos.col = (colnr_T)STRLEN(ml_get(curwin->w_buffer->b_ml.ml_line_count));
}
}
}
@@ -4277,8 +4395,7 @@ current_search(
/// else from position "cur".
/// "direction" is FORWARD or BACKWARD.
/// Returns TRUE, FALSE or -1 for failure.
-static int
-is_zero_width(char_u *pattern, int move, pos_T *cur, Direction direction)
+static int is_zero_width(char_u *pattern, int move, pos_T *cur, Direction direction)
{
regmmatch_T regmatch;
int nmatched = 0;
@@ -4292,8 +4409,9 @@ is_zero_width(char_u *pattern, int move, pos_T *cur, Direction direction)
}
if (search_regcomp(pattern, RE_SEARCH, RE_SEARCH,
- SEARCH_KEEP, &regmatch) == FAIL)
+ SEARCH_KEEP, &regmatch) == FAIL) {
return -1;
+ }
// init startcol correctly
regmatch.startpos[0].col = -1;
@@ -4340,7 +4458,7 @@ is_zero_width(char_u *pattern, int move, pos_T *cur, Direction direction)
*/
int linewhite(linenr_T lnum)
{
- char_u *p;
+ char_u *p;
p = skipwhite(ml_get(lnum));
return *p == NUL;
@@ -4348,64 +4466,63 @@ int linewhite(linenr_T lnum)
// Add the search count "[3/19]" to "msgbuf".
// See update_search_stat() for other arguments.
-static void cmdline_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos,
- bool show_top_bot_msg, char_u *msgbuf,
- bool recompute, int maxcount, long timeout)
+static void cmdline_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, bool show_top_bot_msg,
+ char_u *msgbuf, bool recompute, int maxcount, long timeout)
{
- searchstat_T stat;
-
- update_search_stat(dirc, pos, cursor_pos, &stat, recompute, maxcount,
- timeout);
- if (stat.cur > 0) {
- char t[SEARCH_STAT_BUF_LEN];
-
- if (curwin->w_p_rl && *curwin->w_p_rlc == 's') {
- if (stat.incomplete == 1) {
- vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[?/??]");
- } else if (stat.cnt > maxcount && stat.cur > maxcount) {
- vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[>%d/>%d]",
- maxcount, maxcount);
- } else if (stat.cnt > maxcount) {
- vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[>%d/%d]",
- maxcount, stat.cur);
- } else {
- vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[%d/%d]",
- stat.cnt, stat.cur);
- }
+ searchstat_T stat;
+
+ update_search_stat(dirc, pos, cursor_pos, &stat, recompute, maxcount,
+ timeout);
+ if (stat.cur > 0) {
+ char t[SEARCH_STAT_BUF_LEN];
+
+ if (curwin->w_p_rl && *curwin->w_p_rlc == 's') {
+ if (stat.incomplete == 1) {
+ vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[?/??]");
+ } else if (stat.cnt > maxcount && stat.cur > maxcount) {
+ vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[>%d/>%d]",
+ maxcount, maxcount);
+ } else if (stat.cnt > maxcount) {
+ vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[>%d/%d]",
+ maxcount, stat.cur);
} else {
- if (stat.incomplete == 1) {
- vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[?/??]");
- } else if (stat.cnt > maxcount && stat.cur > maxcount) {
- vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[>%d/>%d]",
- maxcount, maxcount);
- } else if (stat.cnt > maxcount) {
- vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[%d/>%d]",
- stat.cur, maxcount);
- } else {
- vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[%d/%d]",
- stat.cur, stat.cnt);
- }
+ vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[%d/%d]",
+ stat.cnt, stat.cur);
}
-
- size_t len = strlen(t);
- if (show_top_bot_msg && len + 2 < SEARCH_STAT_BUF_LEN) {
- memmove(t + 2, t, len);
- t[0] = 'W';
- t[1] = ' ';
- len += 2;
+ } else {
+ if (stat.incomplete == 1) {
+ vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[?/??]");
+ } else if (stat.cnt > maxcount && stat.cur > maxcount) {
+ vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[>%d/>%d]",
+ maxcount, maxcount);
+ } else if (stat.cnt > maxcount) {
+ vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[%d/>%d]",
+ stat.cur, maxcount);
+ } else {
+ vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[%d/%d]",
+ stat.cur, stat.cnt);
}
+ }
- memmove(msgbuf + STRLEN(msgbuf) - len, t, len);
- if (dirc == '?' && stat.cur == maxcount + 1) {
- stat.cur = -1;
- }
+ size_t len = strlen(t);
+ if (show_top_bot_msg && len + 2 < SEARCH_STAT_BUF_LEN) {
+ memmove(t + 2, t, len);
+ t[0] = 'W';
+ t[1] = ' ';
+ len += 2;
+ }
- // keep the message even after redraw, but don't put in history
- msg_hist_off = true;
- msg_ext_set_kind("search_count");
- give_warning(msgbuf, false);
- msg_hist_off = false;
+ memmove(msgbuf + STRLEN(msgbuf) - len, t, len);
+ if (dirc == '?' && stat.cur == maxcount + 1) {
+ stat.cur = -1;
}
+
+ // keep the message even after redraw, but don't put in history
+ msg_hist_off = true;
+ msg_ext_set_kind("search_count");
+ give_warning(msgbuf, false);
+ msg_hist_off = false;
+ }
}
// Add the search count information to "stat".
@@ -4414,260 +4531,255 @@ static void cmdline_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos,
// dirc == 0: don't find the next/previous match (only set the result to "stat")
// dirc == '/': find the next match
// dirc == '?': find the previous match
-static void update_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos,
- searchstat_T *stat, bool recompute, int maxcount,
- long timeout)
+static void update_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, searchstat_T *stat,
+ bool recompute, int maxcount, long timeout)
{
- int save_ws = p_ws;
- bool wraparound = false;
- pos_T p = (*pos);
- static pos_T lastpos = { 0, 0, 0 };
- static int cur = 0;
- static int cnt = 0;
- static bool exact_match = false;
- static int incomplete = 0;
- static int last_maxcount = SEARCH_STAT_DEF_MAX_COUNT;
- static int chgtick = 0;
- static char_u *lastpat = NULL;
- static buf_T *lbuf = NULL;
- proftime_T start;
-
- memset(stat, 0, sizeof(searchstat_T));
-
- if (dirc == 0 && !recompute && !EMPTY_POS(lastpos)) {
- stat->cur = cur;
- stat->cnt = cnt;
- stat->exact_match = exact_match;
- stat->incomplete = incomplete;
- stat->last_maxcount = last_maxcount;
- return;
- }
- last_maxcount = maxcount;
- wraparound = ((dirc == '?' && lt(lastpos, p))
- || (dirc == '/' && lt(p, lastpos)));
-
- // If anything relevant changed the count has to be recomputed.
- // STRNICMP ignores case, but we should not ignore case.
- // Unfortunately, there is no STRNICMP function.
- // XXX: above comment should be "no MB_STRCMP function" ?
- if (!(chgtick == buf_get_changedtick(curbuf)
- && lastpat != NULL // supress clang/NULL passed as nonnull parameter
- && STRNICMP(lastpat, spats[last_idx].pat, STRLEN(lastpat)) == 0
- && STRLEN(lastpat) == STRLEN(spats[last_idx].pat)
- && equalpos(lastpos, *cursor_pos)
- && lbuf == curbuf)
- || wraparound || cur < 0 || (maxcount > 0 && cur > maxcount)
- || recompute) {
- cur = 0;
- cnt = 0;
- exact_match = false;
- incomplete = 0;
- clearpos(&lastpos);
- lbuf = curbuf;
- }
-
- if (equalpos(lastpos, *cursor_pos) && !wraparound
- && (dirc == 0 || dirc == '/' ? cur < cnt : cur > 0)) {
- cur += dirc == 0 ? 0 : dirc == '/' ? 1 : -1;
- } else {
- bool done_search = false;
- pos_T endpos = { 0, 0, 0 };
- p_ws = false;
- if (timeout > 0) {
- start = profile_setlimit(timeout);
- }
- while (!got_int && searchit(curwin, curbuf, &lastpos, &endpos,
- FORWARD, NULL, 1, SEARCH_KEEP, RE_LAST,
- NULL) != FAIL) {
- done_search = true;
- // Stop after passing the time limit.
- if (timeout > 0 && profile_passed_limit(start)) {
- incomplete = 1;
- break;
- }
- cnt++;
- if (ltoreq(lastpos, p)) {
- cur = cnt;
- if (lt(p, endpos)) {
- exact_match = true;
- }
- }
- fast_breakcheck();
- if (maxcount > 0 && cnt > maxcount) {
- incomplete = 2; // max count exceeded
- break;
- }
- }
- if (got_int) {
- cur = -1; // abort
- }
- if (done_search) {
- xfree(lastpat);
- lastpat = vim_strsave(spats[last_idx].pat);
- chgtick = buf_get_changedtick(curbuf);
- lbuf = curbuf;
- lastpos = p;
- }
- }
+ int save_ws = p_ws;
+ bool wraparound = false;
+ pos_T p = (*pos);
+ static pos_T lastpos = { 0, 0, 0 };
+ static int cur = 0;
+ static int cnt = 0;
+ static bool exact_match = false;
+ static int incomplete = 0;
+ static int last_maxcount = SEARCH_STAT_DEF_MAX_COUNT;
+ static int chgtick = 0;
+ static char_u *lastpat = NULL;
+ static buf_T *lbuf = NULL;
+ proftime_T start;
+
+ memset(stat, 0, sizeof(searchstat_T));
+
+ if (dirc == 0 && !recompute && !EMPTY_POS(lastpos)) {
stat->cur = cur;
stat->cnt = cnt;
stat->exact_match = exact_match;
stat->incomplete = incomplete;
stat->last_maxcount = last_maxcount;
- p_ws = save_ws;
+ return;
+ }
+ last_maxcount = maxcount;
+ wraparound = ((dirc == '?' && lt(lastpos, p))
+ || (dirc == '/' && lt(p, lastpos)));
+
+ // If anything relevant changed the count has to be recomputed.
+ // STRNICMP ignores case, but we should not ignore case.
+ // Unfortunately, there is no STRNICMP function.
+ // XXX: above comment should be "no MB_STRCMP function" ?
+ if (!(chgtick == buf_get_changedtick(curbuf)
+ && lastpat != NULL // suppress clang/NULL passed as nonnull parameter
+ && STRNICMP(lastpat, spats[last_idx].pat, STRLEN(lastpat)) == 0
+ && STRLEN(lastpat) == STRLEN(spats[last_idx].pat)
+ && equalpos(lastpos, *cursor_pos)
+ && lbuf == curbuf)
+ || wraparound || cur < 0 || (maxcount > 0 && cur > maxcount)
+ || recompute) {
+ cur = 0;
+ cnt = 0;
+ exact_match = false;
+ incomplete = 0;
+ clearpos(&lastpos);
+ lbuf = curbuf;
+ }
+
+ if (equalpos(lastpos, *cursor_pos) && !wraparound
+ && (dirc == 0 || dirc == '/' ? cur < cnt : cur > 0)) {
+ cur += dirc == 0 ? 0 : dirc == '/' ? 1 : -1;
+ } else {
+ bool done_search = false;
+ pos_T endpos = { 0, 0, 0 };
+ p_ws = false;
+ if (timeout > 0) {
+ start = profile_setlimit(timeout);
+ }
+ while (!got_int && searchit(curwin, curbuf, &lastpos, &endpos,
+ FORWARD, NULL, 1, SEARCH_KEEP, RE_LAST,
+ NULL) != FAIL) {
+ done_search = true;
+ // Stop after passing the time limit.
+ if (timeout > 0 && profile_passed_limit(start)) {
+ incomplete = 1;
+ break;
+ }
+ cnt++;
+ if (ltoreq(lastpos, p)) {
+ cur = cnt;
+ if (lt(p, endpos)) {
+ exact_match = true;
+ }
+ }
+ fast_breakcheck();
+ if (maxcount > 0 && cnt > maxcount) {
+ incomplete = 2; // max count exceeded
+ break;
+ }
+ }
+ if (got_int) {
+ cur = -1; // abort
+ }
+ if (done_search) {
+ xfree(lastpat);
+ lastpat = vim_strsave(spats[last_idx].pat);
+ chgtick = buf_get_changedtick(curbuf);
+ lbuf = curbuf;
+ lastpos = p;
+ }
+ }
+ stat->cur = cur;
+ stat->cnt = cnt;
+ stat->exact_match = exact_match;
+ stat->incomplete = incomplete;
+ stat->last_maxcount = last_maxcount;
+ p_ws = save_ws;
}
// "searchcount()" function
void f_searchcount(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- pos_T pos = curwin->w_cursor;
- char_u *pattern = NULL;
- int maxcount = SEARCH_STAT_DEF_MAX_COUNT;
- long timeout = SEARCH_STAT_DEF_TIMEOUT;
- bool recompute = true;
- searchstat_T stat;
+ pos_T pos = curwin->w_cursor;
+ char_u *pattern = NULL;
+ int maxcount = SEARCH_STAT_DEF_MAX_COUNT;
+ long timeout = SEARCH_STAT_DEF_TIMEOUT;
+ bool recompute = true;
+ searchstat_T stat;
- tv_dict_alloc_ret(rettv);
+ tv_dict_alloc_ret(rettv);
- if (shortmess(SHM_SEARCHCOUNT)) { // 'shortmess' contains 'S' flag
- recompute = true;
- }
+ if (shortmess(SHM_SEARCHCOUNT)) { // 'shortmess' contains 'S' flag
+ recompute = true;
+ }
- if (argvars[0].v_type != VAR_UNKNOWN) {
- dict_T *dict;
- dictitem_T *di;
- listitem_T *li;
- bool error = false;
+ if (argvars[0].v_type != VAR_UNKNOWN) {
+ dict_T *dict;
+ dictitem_T *di;
+ listitem_T *li;
+ bool error = false;
- if (argvars[0].v_type != VAR_DICT || argvars[0].vval.v_dict == NULL) {
- EMSG(_(e_dictreq));
+ if (argvars[0].v_type != VAR_DICT || argvars[0].vval.v_dict == NULL) {
+ EMSG(_(e_dictreq));
+ return;
+ }
+ dict = argvars[0].vval.v_dict;
+ di = tv_dict_find(dict, (const char *)"timeout", -1);
+ if (di != NULL) {
+ timeout = (long)tv_get_number_chk(&di->di_tv, &error);
+ if (error) {
return;
}
- dict = argvars[0].vval.v_dict;
- di = tv_dict_find(dict, (const char *)"timeout", -1);
- if (di != NULL) {
- timeout = (long)tv_get_number_chk(&di->di_tv, &error);
- if (error) {
- return;
- }
+ }
+ di = tv_dict_find(dict, (const char *)"maxcount", -1);
+ if (di != NULL) {
+ maxcount = (int)tv_get_number_chk(&di->di_tv, &error);
+ if (error) {
+ return;
}
- di = tv_dict_find(dict, (const char *)"maxcount", -1);
- if (di != NULL) {
- maxcount = (int)tv_get_number_chk(&di->di_tv, &error);
- if (error) {
- return;
- }
+ }
+ di = tv_dict_find(dict, (const char *)"recompute", -1);
+ if (di != NULL) {
+ recompute = tv_get_number_chk(&di->di_tv, &error);
+ if (error) {
+ return;
+ }
+ }
+ di = tv_dict_find(dict, (const char *)"pattern", -1);
+ if (di != NULL) {
+ pattern = (char_u *)tv_get_string_chk(&di->di_tv);
+ if (pattern == NULL) {
+ return;
}
- di = tv_dict_find(dict, (const char *)"recompute", -1);
- if (di != NULL) {
- recompute = tv_get_number_chk(&di->di_tv, &error);
+ }
+ di = tv_dict_find(dict, (const char *)"pos", -1);
+ if (di != NULL) {
+ if (di->di_tv.v_type != VAR_LIST) {
+ EMSG2(_(e_invarg2), "pos");
+ return;
+ }
+ if (tv_list_len(di->di_tv.vval.v_list) != 3) {
+ EMSG2(_(e_invarg2), "List format should be [lnum, col, off]");
+ return;
+ }
+ li = tv_list_find(di->di_tv.vval.v_list, 0L);
+ if (li != NULL) {
+ pos.lnum = tv_get_number_chk(TV_LIST_ITEM_TV(li), &error);
if (error) {
return;
}
}
- di = tv_dict_find(dict, (const char *)"pattern", -1);
- if (di != NULL) {
- pattern = (char_u *)tv_get_string_chk(&di->di_tv);
- if (pattern == NULL) {
+ li = tv_list_find(di->di_tv.vval.v_list, 1L);
+ if (li != NULL) {
+ pos.col = tv_get_number_chk(TV_LIST_ITEM_TV(li), &error) - 1;
+ if (error) {
return;
}
}
- di = tv_dict_find(dict, (const char *)"pos", -1);
- if (di != NULL) {
- if (di->di_tv.v_type != VAR_LIST) {
- EMSG2(_(e_invarg2), "pos");
- return;
- }
- if (tv_list_len(di->di_tv.vval.v_list) != 3) {
- EMSG2(_(e_invarg2), "List format should be [lnum, col, off]");
+ li = tv_list_find(di->di_tv.vval.v_list, 2L);
+ if (li != NULL) {
+ pos.coladd = tv_get_number_chk(TV_LIST_ITEM_TV(li), &error);
+ if (error) {
return;
}
- li = tv_list_find(di->di_tv.vval.v_list, 0L);
- if (li != NULL) {
- pos.lnum = tv_get_number_chk(TV_LIST_ITEM_TV(li), &error);
- if (error) {
- return;
- }
- }
- li = tv_list_find(di->di_tv.vval.v_list, 1L);
- if (li != NULL) {
- pos.col = tv_get_number_chk(TV_LIST_ITEM_TV(li), &error) - 1;
- if (error) {
- return;
- }
- }
- li = tv_list_find(di->di_tv.vval.v_list, 2L);
- if (li != NULL) {
- pos.coladd = tv_get_number_chk(TV_LIST_ITEM_TV(li), &error);
- if (error) {
- return;
- }
- }
}
}
+ }
- save_last_search_pattern();
- if (pattern != NULL) {
- if (*pattern == NUL) {
- goto the_end;
- }
- xfree(spats[last_idx].pat);
- spats[last_idx].pat = vim_strsave(pattern);
- }
- if (spats[last_idx].pat == NULL || *spats[last_idx].pat == NUL) {
- goto the_end; // the previous pattern was never defined
+ save_last_search_pattern();
+ if (pattern != NULL) {
+ if (*pattern == NUL) {
+ goto the_end;
}
+ xfree(spats[last_idx].pat);
+ spats[last_idx].pat = vim_strsave(pattern);
+ }
+ if (spats[last_idx].pat == NULL || *spats[last_idx].pat == NUL) {
+ goto the_end; // the previous pattern was never defined
+ }
- update_search_stat(0, &pos, &pos, &stat, recompute, maxcount, timeout);
+ update_search_stat(0, &pos, &pos, &stat, recompute, maxcount, timeout);
- tv_dict_add_nr(rettv->vval.v_dict, S_LEN("current"), stat.cur);
- tv_dict_add_nr(rettv->vval.v_dict, S_LEN("total"), stat.cnt);
- tv_dict_add_nr(rettv->vval.v_dict, S_LEN("exact_match"), stat.exact_match);
- tv_dict_add_nr(rettv->vval.v_dict, S_LEN("incomplete"), stat.incomplete);
- tv_dict_add_nr(rettv->vval.v_dict, S_LEN("maxcount"), stat.last_maxcount);
+ tv_dict_add_nr(rettv->vval.v_dict, S_LEN("current"), stat.cur);
+ tv_dict_add_nr(rettv->vval.v_dict, S_LEN("total"), stat.cnt);
+ tv_dict_add_nr(rettv->vval.v_dict, S_LEN("exact_match"), stat.exact_match);
+ tv_dict_add_nr(rettv->vval.v_dict, S_LEN("incomplete"), stat.incomplete);
+ tv_dict_add_nr(rettv->vval.v_dict, S_LEN("maxcount"), stat.last_maxcount);
the_end:
- restore_last_search_pattern();
+ restore_last_search_pattern();
}
-/*
- * Find identifiers or defines in included files.
- * If p_ic && (compl_cont_status & CONT_SOL) then ptr must be in lowercase.
- */
-void
-find_pattern_in_path(
- char_u *ptr, // pointer to search pattern
- Direction dir, // direction of expansion
- size_t len, // length of search pattern
- bool whole, // match whole words only
- bool skip_comments, // don't match inside comments
- int type, // Type of search; are we looking for a type?
- // a macro?
- long count,
- int action, // What to do when we find it
- linenr_T start_lnum, // first line to start searching
- linenr_T end_lnum // last line for searching
-)
+/// Find identifiers or defines in included files.
+/// If p_ic && (compl_cont_status & CONT_SOL) then ptr must be in lowercase.
+///
+/// @param ptr pointer to search pattern
+/// @param dir direction of expansion
+/// @param len length of search pattern
+/// @param whole match whole words only
+/// @param skip_comments don't match inside comments
+/// @param type Type of search; are we looking for a type? a macro?
+/// @param action What to do when we find it
+/// @param start_lnum first line to start searching
+/// @param end_lnum last line for searching
+void find_pattern_in_path(char_u *ptr, Direction dir, size_t len, bool whole, bool skip_comments,
+ int type, long count, int action, linenr_T start_lnum, linenr_T end_lnum)
{
- SearchedFile *files; /* Stack of included files */
- SearchedFile *bigger; /* When we need more space */
+ SearchedFile *files; // Stack of included files
+ SearchedFile *bigger; // When we need more space
int max_path_depth = 50;
long match_count = 1;
- char_u *pat;
- char_u *new_fname;
- char_u *curr_fname = curbuf->b_fname;
- char_u *prev_fname = NULL;
+ char_u *pat;
+ char_u *new_fname;
+ char_u *curr_fname = curbuf->b_fname;
+ char_u *prev_fname = NULL;
linenr_T lnum;
int depth;
- int depth_displayed; /* For type==CHECK_PATH */
+ int depth_displayed; // For type==CHECK_PATH
int old_files;
int already_searched;
- char_u *file_line;
- char_u *line;
- char_u *p;
+ char_u *file_line;
+ char_u *line;
+ char_u *p;
char_u save_char;
- int define_matched;
+ bool define_matched;
regmatch_T regmatch;
regmatch_T incl_regmatch;
regmatch_T def_regmatch;
@@ -4675,10 +4787,10 @@ find_pattern_in_path(
bool did_show = false;
bool found = false;
int i;
- char_u *already = NULL;
- char_u *startp = NULL;
- char_u *inc_opt = NULL;
- win_T *curwin_save = NULL;
+ char_u *already = NULL;
+ char_u *startp = NULL;
+ char_u *inc_opt = NULL;
+ win_T *curwin_save = NULL;
const int l_g_do_tagpreview = g_do_tagpreview;
regmatch.regprog = NULL;
@@ -4690,41 +4802,45 @@ find_pattern_in_path(
if (type != CHECK_PATH && type != FIND_DEFINE
/* when CONT_SOL is set compare "ptr" with the beginning of the line
* is faster than quote_meta/regcomp/regexec "ptr" -- Acevedo */
- && !(compl_cont_status & CONT_SOL)
- ) {
+ && !(compl_cont_status & CONT_SOL)) {
pat = xmalloc(len + 5);
assert(len <= INT_MAX);
sprintf((char *)pat, whole ? "\\<%.*s\\>" : "%.*s", (int)len, ptr);
- /* ignore case according to p_ic, p_scs and pat */
+ // ignore case according to p_ic, p_scs and pat
regmatch.rm_ic = ignorecase(pat);
regmatch.regprog = vim_regcomp(pat, p_magic ? RE_MAGIC : 0);
xfree(pat);
- if (regmatch.regprog == NULL)
+ if (regmatch.regprog == NULL) {
goto fpip_end;
+ }
}
inc_opt = (*curbuf->b_p_inc == NUL) ? p_inc : curbuf->b_p_inc;
if (*inc_opt != NUL) {
incl_regmatch.regprog = vim_regcomp(inc_opt, p_magic ? RE_MAGIC : 0);
- if (incl_regmatch.regprog == NULL)
+ if (incl_regmatch.regprog == NULL) {
goto fpip_end;
- incl_regmatch.rm_ic = FALSE; /* don't ignore case in incl. pat. */
+ }
+ incl_regmatch.rm_ic = FALSE; // don't ignore case in incl. pat.
}
if (type == FIND_DEFINE && (*curbuf->b_p_def != NUL || *p_def != NUL)) {
def_regmatch.regprog = vim_regcomp(*curbuf->b_p_def == NUL
? p_def : curbuf->b_p_def, p_magic ? RE_MAGIC : 0);
- if (def_regmatch.regprog == NULL)
+ if (def_regmatch.regprog == NULL) {
goto fpip_end;
- def_regmatch.rm_ic = FALSE; /* don't ignore case in define pat. */
+ }
+ def_regmatch.rm_ic = FALSE; // don't ignore case in define pat.
}
files = xcalloc(max_path_depth, sizeof(SearchedFile));
old_files = max_path_depth;
depth = depth_displayed = -1;
lnum = start_lnum;
- if (end_lnum > curbuf->b_ml.ml_line_count)
+ if (end_lnum > curbuf->b_ml.ml_line_count) {
end_lnum = curbuf->b_ml.ml_line_count;
- if (lnum > end_lnum) /* do at least one line */
+ }
+ if (lnum > end_lnum) { // do at least one line
lnum = end_lnum;
+ }
line = ml_get(lnum);
for (;; ) {
@@ -4733,17 +4849,18 @@ find_pattern_in_path(
char_u *p_fname = (curr_fname == curbuf->b_fname)
? curbuf->b_ffname : curr_fname;
- if (inc_opt != NULL && strstr((char *)inc_opt, "\\zs") != NULL)
- /* Use text from '\zs' to '\ze' (or end) of 'include'. */
+ if (inc_opt != NULL && strstr((char *)inc_opt, "\\zs") != NULL) {
+ // Use text from '\zs' to '\ze' (or end) of 'include'.
new_fname = find_file_name_in_path(incl_regmatch.startp[0],
(size_t)(incl_regmatch.endp[0]
- incl_regmatch.startp[0]),
FNAME_EXP|FNAME_INCL|FNAME_REL,
1L, p_fname);
- else
- /* Use text after match with 'include'. */
+ } else {
+ // Use text after match with 'include'.
new_fname = file_name_in_line(incl_regmatch.endp[0], 0,
- FNAME_EXP|FNAME_INCL|FNAME_REL, 1L, p_fname, NULL);
+ FNAME_EXP|FNAME_INCL|FNAME_REL, 1L, p_fname, NULL);
+ }
already_searched = FALSE;
if (new_fname != NULL) {
// Check whether we have already searched in this file
@@ -4788,15 +4905,17 @@ find_pattern_in_path(
did_show = true;
while (depth_displayed < depth && !got_int) {
++depth_displayed;
- for (i = 0; i < depth_displayed; i++)
+ for (i = 0; i < depth_displayed; i++) {
MSG_PUTS(" ");
+ }
msg_home_replace(files[depth_displayed].name);
MSG_PUTS(" -->\n");
}
if (!got_int) { /* don't display if 'q' typed
for "--more--" message */
- for (i = 0; i <= depth_displayed; i++)
+ for (i = 0; i <= depth_displayed; i++) {
MSG_PUTS(" ");
+ }
if (new_fname != NULL) {
/* using "new_fname" is more reliable, e.g., when
* 'includeexpr' is set. */
@@ -4808,21 +4927,23 @@ find_pattern_in_path(
*/
if (inc_opt != NULL
&& strstr((char *)inc_opt, "\\zs") != NULL) {
- /* pattern contains \zs, use the match */
+ // pattern contains \zs, use the match
p = incl_regmatch.startp[0];
i = (int)(incl_regmatch.endp[0]
- incl_regmatch.startp[0]);
} else {
- /* find the file name after the end of the match */
+ // find the file name after the end of the match
for (p = incl_regmatch.endp[0];
- *p && !vim_isfilec(*p); p++)
+ *p && !vim_isfilec(*p); p++) {
;
- for (i = 0; vim_isfilec(p[i]); i++)
+ }
+ for (i = 0; vim_isfilec(p[i]); i++) {
;
+ }
}
if (i == 0) {
- /* Nothing found, use the rest of the line. */
+ // Nothing found, use the rest of the line.
p = incl_regmatch.endp[0];
i = (int)STRLEN(p);
}
@@ -4833,8 +4954,9 @@ find_pattern_in_path(
--p;
++i;
}
- if (p[i] == '"' || p[i] == '>')
+ if (p[i] == '"' || p[i] == '>') {
++i;
+ }
}
save_char = p[i];
p[i] = NUL;
@@ -4843,29 +4965,32 @@ find_pattern_in_path(
}
if (new_fname == NULL && action == ACTION_SHOW_ALL) {
- if (already_searched)
+ if (already_searched) {
MSG_PUTS(_(" (Already listed)"));
- else
+ } else {
MSG_PUTS(_(" NOT FOUND"));
+ }
}
}
- ui_flush(); /* output each line directly */
+ ui_flush(); // output each line directly
}
if (new_fname != NULL) {
- /* Push the new file onto the file stack */
+ // Push the new file onto the file stack
if (depth + 1 == old_files) {
bigger = xmalloc(max_path_depth * 2 * sizeof(SearchedFile));
- for (i = 0; i <= depth; i++)
+ for (i = 0; i <= depth; i++) {
bigger[i] = files[i];
+ }
for (i = depth + 1; i < old_files + max_path_depth; i++) {
bigger[i].fp = NULL;
bigger[i].name = NULL;
bigger[i].lnum = 0;
bigger[i].matched = FALSE;
}
- for (i = old_files; i < max_path_depth; i++)
+ for (i = old_files; i < max_path_depth; i++) {
bigger[i + max_path_depth] = files[i];
+ }
old_files += max_path_depth;
max_path_depth *= 2;
xfree(files);
@@ -4892,10 +5017,9 @@ find_pattern_in_path(
} else if (p_verbose >= 5) {
verbose_enter();
smsg(_("Searching included file %s"),
- (char *)new_fname);
+ (char *)new_fname);
verbose_leave();
}
-
}
}
} else {
@@ -4904,7 +5028,7 @@ find_pattern_in_path(
*/
p = line;
search_line:
- define_matched = FALSE;
+ define_matched = false;
if (def_regmatch.regprog != NULL
&& vim_regexec(&def_regmatch, line, (colnr_T)0)) {
/*
@@ -4913,9 +5037,10 @@ search_line:
* don't let it match beyond the end of this identifier.
*/
p = def_regmatch.endp[0];
- while (*p && !vim_iswordc(*p))
+ while (*p && !vim_iswordc(*p)) {
p++;
- define_matched = TRUE;
+ }
+ define_matched = true;
}
/*
@@ -4924,18 +5049,18 @@ search_line:
*/
if (def_regmatch.regprog == NULL || define_matched) {
if (define_matched
- || (compl_cont_status & CONT_SOL)
- ) {
- /* compare the first "len" chars from "ptr" */
+ || (compl_cont_status & CONT_SOL)) {
+ // compare the first "len" chars from "ptr"
startp = skipwhite(p);
if (p_ic) {
matched = !mb_strnicmp(startp, ptr, len);
- }
- else
+ } else {
matched = !STRNCMP(startp, ptr, len);
+ }
if (matched && define_matched && whole
- && vim_iswordc(startp[len]))
+ && vim_iswordc(startp[len])) {
matched = false;
+ }
} else if (regmatch.regprog != NULL
&& vim_regexec(&regmatch, line, (colnr_T)(p - line))) {
matched = true;
@@ -4958,7 +5083,7 @@ search_line:
*/
p = skipwhite(line);
if (matched
- || (p[0] == '/' && p[1] == '*') || p[0] == '*')
+ || (p[0] == '/' && p[1] == '*') || p[0] == '*') {
for (p = line; *p && p < startp; ++p) {
if (matched
&& p[0] == '/'
@@ -4975,6 +5100,7 @@ search_line:
p++;
}
}
+ }
}
}
}
@@ -4982,35 +5108,39 @@ search_line:
if (matched) {
if (action == ACTION_EXPAND) {
bool cont_s_ipos = false;
- char_u *aux;
+ char_u *aux;
- if (depth == -1 && lnum == curwin->w_cursor.lnum)
+ if (depth == -1 && lnum == curwin->w_cursor.lnum) {
break;
+ }
found = true;
aux = p = startp;
if (compl_cont_status & CONT_ADDING) {
p += compl_length;
- if (vim_iswordp(p))
+ if (vim_iswordp(p)) {
goto exit_matched;
+ }
p = find_word_start(p);
}
p = find_word_end(p);
i = (int)(p - aux);
if ((compl_cont_status & CONT_ADDING) && i == compl_length) {
- /* IOSIZE > compl_length, so the STRNCPY works */
+ // IOSIZE > compl_length, so the STRNCPY works
STRNCPY(IObuff, aux, i);
/* Get the next line: when "depth" < 0 from the current
* buffer, otherwise from the included file. Jump to
* exit_matched when past the last line. */
if (depth < 0) {
- if (lnum >= end_lnum)
+ if (lnum >= end_lnum) {
goto exit_matched;
+ }
line = ml_get(++lnum);
} else if (vim_fgets(line = file_line,
- LSIZE, files[depth].fp))
+ LSIZE, files[depth].fp)) {
goto exit_matched;
+ }
/* we read a line, set "already" to check this "line" later
* if depth >= 0 we'll increase files[depth].lnum far
@@ -5020,9 +5150,10 @@ search_line:
p = find_word_end(p);
if (p > aux) {
if (*aux != ')' && IObuff[i-1] != TAB) {
- if (IObuff[i-1] != ' ')
+ if (IObuff[i-1] != ' ') {
IObuff[i++] = ' ';
- /* IObuf =~ "\(\k\|\i\).* ", thus i >= 2*/
+ }
+ // IObuf =~ "\(\k\|\i\).* ", thus i >= 2
if (p_js
&& (IObuff[i-2] == '.'
|| IObuff[i-2] == '?'
@@ -5030,9 +5161,10 @@ search_line:
IObuff[i++] = ' ';
}
}
- /* copy as much as possible of the new word */
- if (p - aux >= IOSIZE - i)
+ // copy as much as possible of the new word
+ if (p - aux >= IOSIZE - i) {
p = aux + IOSIZE - i - 1;
+ }
STRNCPY(IObuff + i, aux, p - aux);
i += (int)(p - aux);
cont_s_ipos = true;
@@ -5040,13 +5172,14 @@ search_line:
IObuff[i] = NUL;
aux = IObuff;
- if (i == compl_length)
+ if (i == compl_length) {
goto exit_matched;
+ }
}
- const int add_r = ins_compl_add_infercase(
- aux, i, p_ic, curr_fname == curbuf->b_fname ? NULL : curr_fname,
- dir, cont_s_ipos);
+ const int add_r = ins_compl_add_infercase(aux, i, p_ic,
+ curr_fname == curbuf->b_fname ? NULL : curr_fname,
+ dir, cont_s_ipos);
if (add_r == OK) {
// if dir was BACKWARD then honor it just once
dir = FORWARD;
@@ -5059,11 +5192,13 @@ search_line:
gotocmdline(true); // cursor at status line
}
if (curr_fname != prev_fname) {
- if (did_show)
- msg_putchar('\n'); /* cursor below last one */
- if (!got_int) /* don't display if 'q' typed
+ if (did_show) {
+ msg_putchar('\n'); // cursor below last one
+ }
+ if (!got_int) { /* don't display if 'q' typed
at "--more--" message */
msg_home_replace_hl(curr_fname);
+ }
prev_fname = curr_fname;
}
did_show = true;
@@ -5076,8 +5211,9 @@ search_line:
/* Set matched flag for this file and all the ones that
* include it */
- for (i = 0; i <= depth; ++i)
+ for (i = 0; i <= depth; ++i) {
files[i].matched = TRUE;
+ }
} else if (--count <= 0) {
found = true;
if (depth == -1 && lnum == curwin->w_cursor.lnum
@@ -5089,14 +5225,15 @@ search_line:
(depth == -1) ? &lnum : &files[depth].lnum, 1L);
did_show = true;
} else {
- /* ":psearch" uses the preview window */
+ // ":psearch" uses the preview window
if (l_g_do_tagpreview != 0) {
curwin_save = curwin;
prepare_tagpreview(true);
}
if (action == ACTION_SPLIT) {
- if (win_split(0, 0) == FAIL)
+ if (win_split(0, 0) == FAIL) {
break;
+ }
RESET_BINDING(curwin);
}
if (depth == -1) {
@@ -5128,7 +5265,7 @@ search_line:
if (l_g_do_tagpreview != 0
&& curwin != curwin_save && win_valid(curwin_save)) {
- /* Return cursor to where we were */
+ // Return cursor to where we were
validate_cursor();
redraw_later(curwin, VALID);
win_enter(curwin_save, true);
@@ -5148,10 +5285,12 @@ exit_matched:
}
}
line_breakcheck();
- if (action == ACTION_EXPAND)
+ if (action == ACTION_EXPAND) {
ins_compl_check_keys(30, false);
- if (got_int || compl_interrupted)
+ }
+ if (got_int || compl_interrupted) {
break;
+ }
/*
* Read the next line. When reading an included file and encountering
@@ -5166,55 +5305,62 @@ exit_matched:
files[old_files].matched = files[depth].matched;
--depth;
curr_fname = (depth == -1) ? curbuf->b_fname
- : files[depth].name;
- if (depth < depth_displayed)
+ : files[depth].name;
+ if (depth < depth_displayed) {
depth_displayed = depth;
+ }
}
- if (depth >= 0) { /* we could read the line */
+ if (depth >= 0) { // we could read the line
files[depth].lnum++;
- /* Remove any CR and LF from the line. */
+ // Remove any CR and LF from the line.
i = (int)STRLEN(line);
- if (i > 0 && line[i - 1] == '\n')
+ if (i > 0 && line[i - 1] == '\n') {
line[--i] = NUL;
- if (i > 0 && line[i - 1] == '\r')
+ }
+ if (i > 0 && line[i - 1] == '\r') {
line[--i] = NUL;
+ }
} else if (!already) {
- if (++lnum > end_lnum)
+ if (++lnum > end_lnum) {
break;
+ }
line = ml_get(lnum);
}
already = NULL;
}
- /* End of big for (;;) loop. */
+ // End of big for (;;) loop.
- /* Close any files that are still open. */
+ // Close any files that are still open.
for (i = 0; i <= depth; i++) {
fclose(files[i].fp);
xfree(files[i].name);
}
- for (i = old_files; i < max_path_depth; i++)
+ for (i = old_files; i < max_path_depth; i++) {
xfree(files[i].name);
+ }
xfree(files);
if (type == CHECK_PATH) {
if (!did_show) {
- if (action != ACTION_SHOW_ALL)
+ if (action != ACTION_SHOW_ALL) {
MSG(_("All included files were found"));
- else
+ } else {
MSG(_("No included files"));
+ }
}
} else if (!found
- && action != ACTION_EXPAND
- ) {
- if (got_int || compl_interrupted)
+ && action != ACTION_EXPAND) {
+ if (got_int || compl_interrupted) {
EMSG(_(e_interr));
- else if (type == FIND_DEFINE)
+ } else if (type == FIND_DEFINE) {
EMSG(_("E388: Couldn't find definition"));
- else
+ } else {
EMSG(_("E389: Couldn't find pattern"));
+ }
}
- if (action == ACTION_SHOW || action == ACTION_SHOW_ALL)
+ if (action == ACTION_SHOW || action == ACTION_SHOW_ALL) {
msg_end();
+ }
fpip_end:
xfree(file_line);
@@ -5223,11 +5369,11 @@ fpip_end:
vim_regfree(def_regmatch.regprog);
}
-static void show_pat_in_path(char_u *line, int type, bool did_show, int action,
- FILE *fp, linenr_T *lnum, long count)
+static void show_pat_in_path(char_u *line, int type, bool did_show, int action, FILE *fp,
+ linenr_T *lnum, long count)
FUNC_ATTR_NONNULL_ARG(1, 6)
{
- char_u *p;
+ char_u *p;
if (did_show) {
msg_putchar('\n'); // cursor below last one
@@ -5240,11 +5386,13 @@ static void show_pat_in_path(char_u *line, int type, bool did_show, int action,
for (;; ) {
p = line + STRLEN(line) - 1;
if (fp != NULL) {
- /* We used fgets(), so get rid of newline at end */
- if (p >= line && *p == '\n')
+ // We used fgets(), so get rid of newline at end
+ if (p >= line && *p == '\n') {
--p;
- if (p >= line && *p == '\r')
+ }
+ if (p >= line && *p == '\r') {
--p;
+ }
*(p + 1) = NUL;
}
if (action == ACTION_SHOW_ALL) {
@@ -5256,19 +5404,22 @@ static void show_pat_in_path(char_u *line, int type, bool did_show, int action,
msg_puts(" ");
}
msg_prt_line(line, FALSE);
- ui_flush(); /* show one line at a time */
+ ui_flush(); // show one line at a time
- /* Definition continues until line that doesn't end with '\' */
- if (got_int || type != FIND_DEFINE || p < line || *p != '\\')
+ // Definition continues until line that doesn't end with '\'
+ if (got_int || type != FIND_DEFINE || p < line || *p != '\\') {
break;
+ }
if (fp != NULL) {
- if (vim_fgets(line, LSIZE, fp)) /* end of file */
+ if (vim_fgets(line, LSIZE, fp)) { // end of file
break;
+ }
++*lnum;
} else {
- if (++*lnum > curbuf->b_ml.ml_line_count)
+ if (++*lnum > curbuf->b_ml.ml_line_count) {
break;
+ }
line = ml_get(*lnum);
}
msg_putchar('\n');
diff --git a/src/nvim/search.h b/src/nvim/search.h
index 98ddaa5eeb..0dbaf79c37 100644
--- a/src/nvim/search.h
+++ b/src/nvim/search.h
@@ -88,7 +88,7 @@ typedef struct searchstat
{
int cur; // current position of found words
int cnt; // total count of found words
- int exact_match; // TRUE if matched exactly on specified position
+ bool exact_match; // true if matched exactly on specified position
int incomplete; // 0: search was fully completed
// 1: recomputing was timed out
// 2: max count exceeded
diff --git a/src/nvim/sha256.c b/src/nvim/sha256.c
index a2378cc202..9d6a2f2c41 100644
--- a/src/nvim/sha256.c
+++ b/src/nvim/sha256.c
@@ -51,8 +51,7 @@ void sha256_start(context_sha256_T *ctx)
ctx->state[7] = 0x5BE0CD19;
}
-static void sha256_process(context_sha256_T *ctx,
- const char_u data[SHA256_BUFFER_SIZE])
+static void sha256_process(context_sha256_T *ctx, const char_u data[SHA256_BUFFER_SIZE])
{
uint32_t temp1, temp2, W[SHA256_BUFFER_SIZE];
uint32_t A, B, C, D, E, F, G, H;
@@ -88,7 +87,7 @@ static void sha256_process(context_sha256_T *ctx,
#define R(t) \
(W[t] = S1(W[t - 2]) + W[t - 7] + \
- S0(W[t - 15]) + W[t - 16])
+ S0(W[t - 15]) + W[t - 16])
#define P(a, b, c, d, e, f, g, h, x, K) { \
temp1 = h + S3(e) + F1(e, f, g) + K + x; \
@@ -188,7 +187,7 @@ void sha256_update(context_sha256_T *ctx, const char_u *input, size_t length)
uint32_t left = ctx->total[0] & (SHA256_BUFFER_SIZE-1); // left < buf size
- ctx->total[0] += (uint32_t) length;
+ ctx->total[0] += (uint32_t)length;
ctx->total[0] &= 0xFFFFFFFF;
if (ctx->total[0] < length) {
@@ -262,8 +261,8 @@ void sha256_finish(context_sha256_T *ctx, char_u digest[SHA256_SUM_SIZE])
///
/// @returns hex digest of "buf[buf_len]" in a static array.
/// if "salt" is not NULL also do "salt[salt_len]".
-const char *sha256_bytes(const uint8_t *restrict buf, size_t buf_len,
- const uint8_t *restrict salt, size_t salt_len)
+const char *sha256_bytes(const uint8_t *restrict buf, size_t buf_len, const uint8_t *restrict salt,
+ size_t salt_len)
{
char_u sha256sum[SHA256_SUM_SIZE];
static char hexit[SHA256_BUFFER_SIZE + 1]; // buf size + NULL
diff --git a/src/nvim/shada.c b/src/nvim/shada.c
index c0e787380f..bf245bec51 100644
--- a/src/nvim/shada.c
+++ b/src/nvim/shada.c
@@ -1,51 +1,50 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
-#include <stdlib.h>
-#include <stddef.h>
-#include <stdbool.h>
-#include <string.h>
-#include <inttypes.h>
-#include <errno.h>
#include <assert.h>
-
+#include <errno.h>
+#include <inttypes.h>
#include <msgpack.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
#include <uv.h>
-#include "nvim/os/os.h"
-#include "nvim/os/time.h"
-#include "nvim/vim.h"
-#include "nvim/pos.h"
-#include "nvim/ascii.h"
-#include "nvim/shada.h"
-#include "nvim/message.h"
-#include "nvim/globals.h"
-#include "nvim/memory.h"
-#include "nvim/mark.h"
-#include "nvim/macros.h"
-#include "nvim/ops.h"
-#include "nvim/garray.h"
-#include "nvim/option.h"
-#include "nvim/msgpack_rpc/helpers.h"
#include "nvim/api/private/defs.h"
#include "nvim/api/private/helpers.h"
+#include "nvim/ascii.h"
#include "nvim/buffer.h"
#include "nvim/buffer_defs.h"
+#include "nvim/eval/decode.h"
+#include "nvim/eval/encode.h"
+#include "nvim/eval/typval.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_getln.h"
-#include "nvim/search.h"
-#include "nvim/regexp.h"
-#include "nvim/eval/typval.h"
-#include "nvim/version.h"
-#include "nvim/path.h"
#include "nvim/fileio.h"
-#include "nvim/os/fileio.h"
-#include "nvim/strings.h"
-#include "nvim/quickfix.h"
-#include "nvim/eval/encode.h"
-#include "nvim/eval/decode.h"
+#include "nvim/garray.h"
+#include "nvim/globals.h"
#include "nvim/lib/khash.h"
#include "nvim/lib/kvec.h"
+#include "nvim/macros.h"
+#include "nvim/mark.h"
+#include "nvim/memory.h"
+#include "nvim/message.h"
+#include "nvim/msgpack_rpc/helpers.h"
+#include "nvim/ops.h"
+#include "nvim/option.h"
+#include "nvim/os/fileio.h"
+#include "nvim/os/os.h"
+#include "nvim/os/time.h"
+#include "nvim/path.h"
+#include "nvim/pos.h"
+#include "nvim/quickfix.h"
+#include "nvim/regexp.h"
+#include "nvim/search.h"
+#include "nvim/shada.h"
+#include "nvim/strings.h"
+#include "nvim/version.h"
+#include "nvim/vim.h"
#ifdef HAVE_BE64TOH
# define _BSD_SOURCE 1
@@ -67,24 +66,24 @@ KHASH_MAP_INIT_STR(fnamebufs, buf_T *)
KHASH_SET_INIT_STR(strset)
#define copy_option_part(src, dest, ...) \
- ((char *) copy_option_part((char_u **) src, (char_u *) dest, __VA_ARGS__))
+ ((char *)copy_option_part((char_u **)src, (char_u *)dest, __VA_ARGS__))
#define find_shada_parameter(...) \
- ((const char *) find_shada_parameter(__VA_ARGS__))
+ ((const char *)find_shada_parameter(__VA_ARGS__))
#define home_replace_save(a, b) \
- ((char *)home_replace_save(a, (char_u *)b))
+ ((char *)home_replace_save(a, (char_u *)b))
#define home_replace(a, b, c, d, e) \
- home_replace(a, (char_u *)b, (char_u *)c, d, e)
+ home_replace(a, (char_u *)b, (char_u *)c, d, e)
#define vim_rename(a, b) \
- (vim_rename((char_u *)a, (char_u *)b))
+ (vim_rename((char_u *)a, (char_u *)b))
#define mb_strnicmp(a, b, c) \
- (mb_strnicmp((char_u *)a, (char_u *)b, c))
+ (mb_strnicmp((char_u *)a, (char_u *)b, c))
#define path_try_shorten_fname(b) \
- ((char *)path_try_shorten_fname((char_u *)b))
+ ((char *)path_try_shorten_fname((char_u *)b))
#define buflist_new(ffname, sfname, ...) \
- (buflist_new((char_u *)ffname, (char_u *)sfname, __VA_ARGS__))
-#define os_isdir(f) (os_isdir((char_u *) f))
-#define regtilde(s, m) ((char *) regtilde((char_u *) s, m))
-#define path_tail_with_sep(f) ((char *) path_tail_with_sep((char_u *)f))
+ (buflist_new((char_u *)ffname, (char_u *)sfname, __VA_ARGS__))
+#define os_isdir(f) (os_isdir((char_u *)f))
+#define regtilde(s, m) ((char *)regtilde((char_u *)s, m))
+#define path_tail_with_sep(f) ((char *)path_tail_with_sep((char_u *)f))
#define SEARCH_KEY_MAGIC "sm"
#define SEARCH_KEY_SMARTCASE "sc"
@@ -172,7 +171,7 @@ typedef enum {
kSDItemBufferList = 9, ///< Buffer list.
kSDItemLocalMark = 10, ///< Buffer-local mark.
kSDItemChange = 11, ///< Item from buffer change list.
-#define SHADA_LAST_ENTRY ((uint64_t) kSDItemChange)
+#define SHADA_LAST_ENTRY ((uint64_t)kSDItemChange)
} ShadaEntryType;
/// Possible results when reading ShaDa file
@@ -202,11 +201,11 @@ enum SRNIFlags {
kSDReadHeader = (1 << kSDItemHeader), ///< Determines whether header should
///< be read (it is usually ignored).
kSDReadUndisableableData = (
- (1 << kSDItemSearchPattern)
- | (1 << kSDItemSubString)
- | (1 << kSDItemJump)), ///< Data reading which cannot be disabled by
- ///< &shada or other options except for disabling
- ///< reading ShaDa as a whole.
+ (1 << kSDItemSearchPattern)
+ | (1 << kSDItemSubString)
+ | (1 << kSDItemJump)), ///< Data reading which cannot be disabled by
+ ///< &shada or other options except for disabling
+ ///< reading ShaDa as a whole.
kSDReadRegisters = (1 << kSDItemRegister), ///< Determines whether registers
///< should be read (may only be
///< disabled when writing, but
@@ -434,13 +433,13 @@ typedef struct sd_write_def {
#endif
#define DEF_SDE(name, attr, ...) \
- [kSDItem##name] = { \
- .timestamp = 0, \
- .type = kSDItem##name, \
- .data = { \
- .attr = { __VA_ARGS__ } \
- } \
- }
+ [kSDItem##name] = { \
+ .timestamp = 0, \
+ .type = kSDItem##name, \
+ .data = { \
+ .attr = { __VA_ARGS__ } \
+ } \
+ }
#define DEFAULT_POS { 1, 0, 0 }
static const pos_T default_pos = DEFAULT_POS;
static const ShadaEntry sd_default_values[] = {
@@ -475,9 +474,9 @@ static const ShadaEntry sd_default_values[] = {
DEF_SDE(Variable, global_var,
.name = NULL,
.value = {
- .v_type = VAR_UNKNOWN,
- .vval = { .v_string = NULL }
- },
+ .v_type = VAR_UNKNOWN,
+ .vval = { .v_string = NULL }
+ },
.additional_elements = NULL),
DEF_SDE(GlobalMark, filemark,
.name = '"',
@@ -533,17 +532,16 @@ static inline void hmll_init(HMLList *const hmll, const size_t size)
///
/// @return `for` cycle header (use `HMLL_FORALL(hmll, cur_entry) {body}`).
#define HMLL_FORALL(hmll, cur_entry, code) \
- for (HMLListEntry *cur_entry = (hmll)->first; cur_entry != NULL; \
- cur_entry = cur_entry->next) { \
- code \
- } \
+ for (HMLListEntry *cur_entry = (hmll)->first; cur_entry != NULL; \
+ cur_entry = cur_entry->next) { \
+ code \
+ } \
/// Remove entry from the linked list
///
/// @param hmll List to remove from.
/// @param hmll_entry Entry to remove.
-static inline void hmll_remove(HMLList *const hmll,
- HMLListEntry *const hmll_entry)
+static inline void hmll_remove(HMLList *const hmll, HMLListEntry *const hmll_entry)
FUNC_ATTR_NONNULL_ALL
{
if (hmll_entry == hmll->last_free_entry - 1) {
@@ -580,9 +578,7 @@ static inline void hmll_remove(HMLList *const hmll,
/// to insert at the first entry.
/// @param[in] data Data to insert.
/// @param[in] can_free_entry True if data can be freed.
-static inline void hmll_insert(HMLList *const hmll,
- HMLListEntry *hmll_entry,
- const ShadaEntry data,
+static inline void hmll_insert(HMLList *const hmll, HMLListEntry *hmll_entry, const ShadaEntry data,
const bool can_free_entry)
FUNC_ATTR_NONNULL_ARG(1)
{
@@ -595,11 +591,11 @@ static inline void hmll_insert(HMLList *const hmll,
}
HMLListEntry *target_entry;
if (hmll->free_entry == NULL) {
- assert((size_t) (hmll->last_free_entry - hmll->entries)
+ assert((size_t)(hmll->last_free_entry - hmll->entries)
== hmll->num_entries);
target_entry = hmll->last_free_entry++;
} else {
- assert((size_t) (hmll->last_free_entry - hmll->entries) - 1
+ assert((size_t)(hmll->last_free_entry - hmll->entries) - 1
== hmll->num_entries);
target_entry = hmll->free_entry;
hmll->free_entry = NULL;
@@ -637,10 +633,10 @@ static inline void hmll_insert(HMLList *const hmll,
///
/// @return `for` cycle header (use `HMLL_FORALL(hmll, cur_entry) {body}`).
#define HMLL_ITER_BACK(hmll, cur_entry, code) \
- for (cur_entry = (hmll)->last; cur_entry != NULL; \
- cur_entry = cur_entry->prev) { \
- code \
- }
+ for (cur_entry = (hmll)->last; cur_entry != NULL; \
+ cur_entry = cur_entry->prev) { \
+ code \
+ }
/// Free linked list
///
@@ -655,8 +651,7 @@ static inline void hmll_dealloc(HMLList *const hmll)
/// Wrapper for reading from file descriptors
///
/// @return -1 or number of bytes read.
-static ptrdiff_t read_file(ShaDaReadDef *const sd_reader, void *const dest,
- const size_t size)
+static ptrdiff_t read_file(ShaDaReadDef *const sd_reader, void *const dest, const size_t size)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
const ptrdiff_t ret = file_read(sd_reader->cookie, dest, size);
@@ -678,14 +673,13 @@ static int read_char(ShaDaReadDef *const sd_reader)
if (read_bytes != 1) {
return EOF;
}
- return (int) ret;
+ return (int)ret;
}
/// Wrapper for writing to file descriptors
///
/// @return -1 or number of bytes written.
-static ptrdiff_t write_file(ShaDaWriteDef *const sd_writer,
- const void *const dest,
+static ptrdiff_t write_file(ShaDaWriteDef *const sd_writer, const void *const dest,
const size_t size)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
@@ -720,8 +714,7 @@ static void close_sd_writer(ShaDaWriteDef *const sd_writer)
///
/// @return FAIL in case of failure, OK in case of success. May set
/// sd_reader->eof or sd_reader->error.
-static int sd_reader_skip_read(ShaDaReadDef *const sd_reader,
- const size_t offset)
+static int sd_reader_skip_read(ShaDaReadDef *const sd_reader, const size_t offset)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
const ptrdiff_t skip_bytes = file_skip(sd_reader->cookie, offset);
@@ -749,8 +742,7 @@ static int sd_reader_skip_read(ShaDaReadDef *const sd_reader,
///
/// @return kSDReadStatusReadError, kSDReadStatusNotShaDa or
/// kSDReadStatusSuccess.
-static ShaDaReadResult sd_reader_skip(ShaDaReadDef *const sd_reader,
- const size_t offset)
+static ShaDaReadResult sd_reader_skip(ShaDaReadDef *const sd_reader, const size_t offset)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
if (sd_reader->skip(sd_reader, offset) != OK) {
@@ -762,7 +754,7 @@ static ShaDaReadResult sd_reader_skip(ShaDaReadDef *const sd_reader,
emsgf(_(RCERR "Error while reading ShaDa file: "
"last entry specified that it occupies %" PRIu64 " bytes, "
"but file ended earlier"),
- (uint64_t) offset);
+ (uint64_t)offset);
return kSDReadStatusNotShaDa;
}
abort();
@@ -776,8 +768,7 @@ static ShaDaReadResult sd_reader_skip(ShaDaReadDef *const sd_reader,
/// @param[out] sd_reader Location where reader structure will be saved.
///
/// @return libuv error in case of error, 0 otherwise.
-static int open_shada_file_for_reading(const char *const fname,
- ShaDaReadDef *sd_reader)
+static int open_shada_file_for_reading(const char *const fname, ShaDaReadDef *sd_reader)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
int error;
@@ -819,7 +810,7 @@ static void close_file(void *cookie)
static inline bool in_bufset(const khash_t(bufset) *const set, const buf_T *buf)
FUNC_ATTR_PURE
{
- return kh_get(bufset, set, (uintptr_t) buf) != kh_end(set);
+ return kh_get(bufset, set, (uintptr_t)buf) != kh_end(set);
}
/// Check whether string is in the given set
@@ -837,7 +828,7 @@ static inline bool in_strset(const khash_t(strset) *const set, char *str)
/// Msgpack callback for writing to ShaDaWriteDef*
static int msgpack_sd_writer_write(void *data, const char *buf, size_t len)
{
- ShaDaWriteDef *const sd_writer = (ShaDaWriteDef *) data;
+ ShaDaWriteDef *const sd_writer = (ShaDaWriteDef *)data;
ptrdiff_t written_bytes = sd_writer->write(sd_writer, buf, len);
if (written_bytes == -1) {
emsgf(_(SERR "System error while writing ShaDa file: %s"),
@@ -910,10 +901,8 @@ static int shada_read_file(const char *const file, const int flags)
/// @param[out] hist Location where iteration results should be saved.
///
/// @return Next iteration state.
-static const void *shada_hist_iter(const void *const iter,
- const uint8_t history_type,
- const bool zero,
- ShadaEntry *const hist)
+static const void *shada_hist_iter(const void *const iter, const uint8_t history_type,
+ const bool zero, ShadaEntry *const hist)
FUNC_ATTR_NONNULL_ARG(4) FUNC_ATTR_WARN_UNUSED_RESULT
{
histentry_T hist_he;
@@ -927,9 +916,9 @@ static const void *shada_hist_iter(const void *const iter,
.data = {
.history_item = {
.histtype = history_type,
- .string = (char *) hist_he.hisstr,
- .sep = (char) (history_type == HIST_SEARCH
- ? (char) hist_he.hisstr[STRLEN(hist_he.hisstr) + 1]
+ .string = (char *)hist_he.hisstr,
+ .sep = (char)(history_type == HIST_SEARCH
+ ? (char)hist_he.hisstr[STRLEN(hist_he.hisstr) + 1]
: 0),
.additional_elements = hist_he.additional_elements,
}
@@ -954,8 +943,8 @@ static const void *shada_hist_iter(const void *const iter,
/// be used. Must be true only if inserting
/// entry from current Neovim history.
/// @param[in] can_free_entry True if entry can be freed.
-static void hms_insert(HistoryMergerState *const hms_p, const ShadaEntry entry,
- const bool do_iter, const bool can_free_entry)
+static void hms_insert(HistoryMergerState *const hms_p, const ShadaEntry entry, const bool do_iter,
+ const bool can_free_entry)
FUNC_ATTR_NONNULL_ALL
{
if (do_iter) {
@@ -1008,11 +997,8 @@ static void hms_insert(HistoryMergerState *const hms_p, const ShadaEntry entry,
/// @param[in] do_merge Prepare structure for merging elements.
/// @param[in] reading If true, then merger is reading history for use
/// in Neovim.
-static inline void hms_init(HistoryMergerState *const hms_p,
- const uint8_t history_type,
- const size_t num_elements,
- const bool do_merge,
- const bool reading)
+static inline void hms_init(HistoryMergerState *const hms_p, const uint8_t history_type,
+ const size_t num_elements, const bool do_merge, const bool reading)
FUNC_ATTR_NONNULL_ALL
{
hmll_init(&hms_p->hmll, num_elements);
@@ -1027,8 +1013,7 @@ static inline void hms_init(HistoryMergerState *const hms_p,
///
/// @param[in,out] hms_p Merger structure into which history should be
/// inserted.
-static inline void hms_insert_whole_neovim_history(
- HistoryMergerState *const hms_p)
+static inline void hms_insert_whole_neovim_history(HistoryMergerState *const hms_p)
FUNC_ATTR_NONNULL_ALL
{
while (hms_p->last_hist_entry.type != kSDItemMissing) {
@@ -1048,21 +1033,20 @@ static inline void hms_insert_whole_neovim_history(
/// @param[out] new_hisidx New last history entry index.
/// @param[out] new_hisnum Amount of history items in merger structure.
static inline void hms_to_he_array(const HistoryMergerState *const hms_p,
- histentry_T *const hist_array,
- int *const new_hisidx,
+ histentry_T *const hist_array, int *const new_hisidx,
int *const new_hisnum)
FUNC_ATTR_NONNULL_ALL
{
histentry_T *hist = hist_array;
HMLL_FORALL(&hms_p->hmll, cur_entry, {
hist->timestamp = cur_entry->data.timestamp;
- hist->hisnum = (int) (hist - hist_array) + 1;
- hist->hisstr = (char_u *) cur_entry->data.data.history_item.string;
+ hist->hisnum = (int)(hist - hist_array) + 1;
+ hist->hisstr = (char_u *)cur_entry->data.data.history_item.string;
hist->additional_elements =
- cur_entry->data.data.history_item.additional_elements;
+ cur_entry->data.data.history_item.additional_elements;
hist++;
})
- *new_hisnum = (int) (hist - hist_array);
+ *new_hisnum = (int)(hist - hist_array);
*new_hisidx = *new_hisnum - 1;
}
@@ -1083,7 +1067,7 @@ static inline void hms_dealloc(HistoryMergerState *const hms_p)
///
/// @return for cycle header. Use `HMS_ITER(hms_p, cur_entry) {body}`.
#define HMS_ITER(hms_p, cur_entry, code) \
- HMLL_FORALL(&((hms_p)->hmll), cur_entry, code)
+ HMLL_FORALL(&((hms_p)->hmll), cur_entry, code)
/// Find buffer for given buffer name (cached)
///
@@ -1091,8 +1075,7 @@ static inline void hms_dealloc(HistoryMergerState *const hms_p)
/// @param[in] fname File name to find.
///
/// @return Pointer to the buffer or NULL.
-static buf_T *find_buffer(khash_t(fnamebufs) *const fname_bufs,
- const char *const fname)
+static buf_T *find_buffer(khash_t(fnamebufs) *const fname_bufs, const char *const fname)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
int kh_ret;
@@ -1123,7 +1106,7 @@ static inline bool marks_equal(const pos_T a, const pos_T b)
entry, fname_cond, free_func, fin_func, \
idxadj_func, afterfree_func) \
do { \
- const int jl_len = (int) jumps_size; \
+ const int jl_len = (int)jumps_size; \
int i; \
for (i = jl_len; i > 0; i--) { \
const jumps_type jl_entry = jumps[i - 1]; \
@@ -1140,17 +1123,17 @@ static inline bool marks_equal(const pos_T a, const pos_T b)
free_func(jumps[0]); \
i--; \
if (i > 0) { \
- memmove(&jumps[0], &jumps[1], sizeof(jumps[1]) * (size_t) i); \
+ memmove(&jumps[0], &jumps[1], sizeof(jumps[1]) * (size_t)i); \
} \
} else if (i != jl_len) { \
memmove(&jumps[i + 1], &jumps[i], \
- sizeof(jumps[0]) * (size_t) (jl_len - i)); \
+ sizeof(jumps[0]) * (size_t)(jl_len - i)); \
} \
} else if (i == 0) { \
if (jl_len == JUMPLISTSIZE) { \
i = -1; \
} else if (jl_len > 0) { \
- memmove(&jumps[1], &jumps[0], sizeof(jumps[0]) * (size_t) jl_len); \
+ memmove(&jumps[1], &jumps[0], sizeof(jumps[0]) * (size_t)jl_len); \
} \
} \
if (i != -1) { \
@@ -1177,8 +1160,8 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags)
const bool get_old_files = (flags & (kShaDaGetOldfiles | kShaDaForceit)
&& (force || tv_list_len(oldfiles_list) == 0));
const bool want_marks = flags & kShaDaWantMarks;
- const unsigned srni_flags = (unsigned) (
- (flags & kShaDaWantInfo
+ const unsigned srni_flags = (unsigned)(
+ (flags & kShaDaWantInfo
? (kSDReadUndisableableData
| kSDReadRegisters
| kSDReadGlobalMarks
@@ -1190,11 +1173,11 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags)
&& ARGCOUNT == 0
? kSDReadBufferList
: 0))
- : 0)
- | (want_marks && get_shada_parameter('\'') > 0
+ : 0)
+ | (want_marks && get_shada_parameter('\'') > 0
? kSDReadLocalMarks | kSDReadChanges
: 0)
- | (get_old_files
+ | (get_old_files
? kSDReadLocalMarks
: 0));
if (srni_flags == 0) {
@@ -1204,7 +1187,7 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags)
HistoryMergerState hms[HIST_COUNT];
if (srni_flags & kSDReadHistory) {
for (uint8_t i = 0; i < HIST_COUNT; i++) {
- hms_init(&hms[i], i, (size_t) p_hi, true, true);
+ hms_init(&hms[i], i, (size_t)p_hi, true, true);
}
}
ShadaEntry cur_entry;
@@ -1219,253 +1202,237 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags)
while ((srni_ret = shada_read_next_item(sd_reader, &cur_entry, srni_flags, 0))
!= kSDReadStatusFinished) {
switch (srni_ret) {
- case kSDReadStatusSuccess: {
- break;
- }
- case kSDReadStatusFinished: {
- // Should be handled by the while condition.
- abort();
- }
- case kSDReadStatusNotShaDa:
- case kSDReadStatusReadError: {
- goto shada_read_main_cycle_end;
- }
- case kSDReadStatusMalformed: {
- continue;
- }
+ case kSDReadStatusSuccess:
+ break;
+ case kSDReadStatusFinished:
+ // Should be handled by the while condition.
+ abort();
+ case kSDReadStatusNotShaDa:
+ case kSDReadStatusReadError:
+ goto shada_read_main_cycle_end;
+ case kSDReadStatusMalformed:
+ continue;
}
switch (cur_entry.type) {
- case kSDItemMissing: {
- abort();
- }
- case kSDItemUnknown: {
- break;
- }
- case kSDItemHeader: {
- shada_free_shada_entry(&cur_entry);
- break;
- }
- case kSDItemSearchPattern: {
- if (!force) {
- SearchPattern pat;
- (cur_entry.data.search_pattern.is_substitute_pattern
+ case kSDItemMissing:
+ abort();
+ case kSDItemUnknown:
+ break;
+ case kSDItemHeader:
+ shada_free_shada_entry(&cur_entry);
+ break;
+ case kSDItemSearchPattern:
+ if (!force) {
+ SearchPattern pat;
+ (cur_entry.data.search_pattern.is_substitute_pattern
? &get_substitute_pattern
: &get_search_pattern)(&pat);
- if (pat.pat != NULL && pat.timestamp >= cur_entry.timestamp) {
- shada_free_shada_entry(&cur_entry);
- break;
- }
+ if (pat.pat != NULL && pat.timestamp >= cur_entry.timestamp) {
+ shada_free_shada_entry(&cur_entry);
+ break;
}
- (cur_entry.data.search_pattern.is_substitute_pattern
+ }
+ (cur_entry.data.search_pattern.is_substitute_pattern
? &set_substitute_pattern
: &set_search_pattern)((SearchPattern) {
- .magic = cur_entry.data.search_pattern.magic,
- .no_scs = !cur_entry.data.search_pattern.smartcase,
- .off = {
- .dir = cur_entry.data.search_pattern.search_backward ? '?' : '/',
- .line = cur_entry.data.search_pattern.has_line_offset,
- .end = cur_entry.data.search_pattern.place_cursor_at_end,
- .off = cur_entry.data.search_pattern.offset,
- },
- .pat = (char_u *) cur_entry.data.search_pattern.pat,
- .additional_data = cur_entry.data.search_pattern.additional_data,
- .timestamp = cur_entry.timestamp,
- });
- if (cur_entry.data.search_pattern.is_last_used) {
- set_last_used_pattern(
- cur_entry.data.search_pattern.is_substitute_pattern);
- set_no_hlsearch(!cur_entry.data.search_pattern.highlighted);
- }
- // Do not free shada entry: its allocated memory was saved above.
- break;
- }
- case kSDItemSubString: {
- if (!force) {
- SubReplacementString sub;
- sub_get_replacement(&sub);
- if (sub.sub != NULL && sub.timestamp >= cur_entry.timestamp) {
- shada_free_shada_entry(&cur_entry);
- break;
- }
- }
- sub_set_replacement((SubReplacementString) {
- .sub = cur_entry.data.sub_string.sub,
- .timestamp = cur_entry.timestamp,
- .additional_elements = cur_entry.data.sub_string.additional_elements,
- });
- // Without using regtilde and without / &cpo flag previous substitute
- // string is close to useless: you can only use it with :& or :~ and
- // that’s all because s//~ is not available until the first call to
- // regtilde. Vim was not calling this for some reason.
- (void) regtilde(cur_entry.data.sub_string.sub, p_magic);
- // Do not free shada entry: its allocated memory was saved above.
- break;
+ .magic = cur_entry.data.search_pattern.magic,
+ .no_scs = !cur_entry.data.search_pattern.smartcase,
+ .off = {
+ .dir = cur_entry.data.search_pattern.search_backward ? '?' : '/',
+ .line = cur_entry.data.search_pattern.has_line_offset,
+ .end = cur_entry.data.search_pattern.place_cursor_at_end,
+ .off = cur_entry.data.search_pattern.offset,
+ },
+ .pat = (char_u *)cur_entry.data.search_pattern.pat,
+ .additional_data = cur_entry.data.search_pattern.additional_data,
+ .timestamp = cur_entry.timestamp,
+ });
+ if (cur_entry.data.search_pattern.is_last_used) {
+ set_last_used_pattern(cur_entry.data.search_pattern.is_substitute_pattern);
+ set_no_hlsearch(!cur_entry.data.search_pattern.highlighted);
}
- case kSDItemHistoryEntry: {
- if (cur_entry.data.history_item.histtype >= HIST_COUNT) {
+ // Do not free shada entry: its allocated memory was saved above.
+ break;
+ case kSDItemSubString:
+ if (!force) {
+ SubReplacementString sub;
+ sub_get_replacement(&sub);
+ if (sub.sub != NULL && sub.timestamp >= cur_entry.timestamp) {
shada_free_shada_entry(&cur_entry);
break;
}
- hms_insert(hms + cur_entry.data.history_item.histtype, cur_entry, true,
- true);
- // Do not free shada entry: its allocated memory was saved above.
+ }
+ sub_set_replacement((SubReplacementString) {
+ .sub = cur_entry.data.sub_string.sub,
+ .timestamp = cur_entry.timestamp,
+ .additional_elements = cur_entry.data.sub_string.additional_elements,
+ });
+ // Without using regtilde and without / &cpo flag previous substitute
+ // string is close to useless: you can only use it with :& or :~ and
+ // that’s all because s//~ is not available until the first call to
+ // regtilde. Vim was not calling this for some reason.
+ (void)regtilde(cur_entry.data.sub_string.sub, p_magic);
+ // Do not free shada entry: its allocated memory was saved above.
+ break;
+ case kSDItemHistoryEntry:
+ if (cur_entry.data.history_item.histtype >= HIST_COUNT) {
+ shada_free_shada_entry(&cur_entry);
+ break;
+ }
+ hms_insert(hms + cur_entry.data.history_item.histtype, cur_entry, true,
+ true);
+ // Do not free shada entry: its allocated memory was saved above.
+ break;
+ case kSDItemRegister:
+ if (cur_entry.data.reg.type != kMTCharWise
+ && cur_entry.data.reg.type != kMTLineWise
+ && cur_entry.data.reg.type != kMTBlockWise) {
+ shada_free_shada_entry(&cur_entry);
break;
}
- case kSDItemRegister: {
- if (cur_entry.data.reg.type != kMTCharWise
- && cur_entry.data.reg.type != kMTLineWise
- && cur_entry.data.reg.type != kMTBlockWise) {
+ if (!force) {
+ const yankreg_T *const reg = op_reg_get(cur_entry.data.reg.name);
+ if (reg == NULL || reg->timestamp >= cur_entry.timestamp) {
shada_free_shada_entry(&cur_entry);
break;
}
- if (!force) {
- const yankreg_T *const reg = op_reg_get(cur_entry.data.reg.name);
- if (reg == NULL || reg->timestamp >= cur_entry.timestamp) {
- shada_free_shada_entry(&cur_entry);
- break;
- }
- }
- if (!op_reg_set(cur_entry.data.reg.name, (yankreg_T) {
- .y_array = (char_u **)cur_entry.data.reg.contents,
- .y_size = cur_entry.data.reg.contents_size,
- .y_type = cur_entry.data.reg.type,
- .y_width = (colnr_T) cur_entry.data.reg.width,
- .timestamp = cur_entry.timestamp,
- .additional_data = cur_entry.data.reg.additional_data,
- }, cur_entry.data.reg.is_unnamed)) {
- shada_free_shada_entry(&cur_entry);
- }
- // Do not free shada entry: its allocated memory was saved above.
- break;
}
- case kSDItemVariable: {
- var_set_global(cur_entry.data.global_var.name,
- cur_entry.data.global_var.value);
- cur_entry.data.global_var.value.v_type = VAR_UNKNOWN;
+ if (!op_reg_set(cur_entry.data.reg.name, (yankreg_T) {
+ .y_array = (char_u **)cur_entry.data.reg.contents,
+ .y_size = cur_entry.data.reg.contents_size,
+ .y_type = cur_entry.data.reg.type,
+ .y_width = (colnr_T)cur_entry.data.reg.width,
+ .timestamp = cur_entry.timestamp,
+ .additional_data = cur_entry.data.reg.additional_data,
+ }, cur_entry.data.reg.is_unnamed)) {
shada_free_shada_entry(&cur_entry);
- break;
}
- case kSDItemJump:
- case kSDItemGlobalMark: {
- buf_T *buf = find_buffer(&fname_bufs, cur_entry.data.filemark.fname);
- if (buf != NULL) {
- XFREE_CLEAR(cur_entry.data.filemark.fname);
- }
- xfmark_T fm = (xfmark_T) {
- .fname = (char_u *) (buf == NULL
+ // Do not free shada entry: its allocated memory was saved above.
+ break;
+ case kSDItemVariable:
+ var_set_global(cur_entry.data.global_var.name,
+ cur_entry.data.global_var.value);
+ cur_entry.data.global_var.value.v_type = VAR_UNKNOWN;
+ shada_free_shada_entry(&cur_entry);
+ break;
+ case kSDItemJump:
+ case kSDItemGlobalMark: {
+ buf_T *buf = find_buffer(&fname_bufs, cur_entry.data.filemark.fname);
+ if (buf != NULL) {
+ XFREE_CLEAR(cur_entry.data.filemark.fname);
+ }
+ xfmark_T fm = (xfmark_T) {
+ .fname = (char_u *)(buf == NULL
? cur_entry.data.filemark.fname
: NULL),
- .fmark = {
- .mark = cur_entry.data.filemark.mark,
- .fnum = (buf == NULL ? 0 : buf->b_fnum),
- .timestamp = cur_entry.timestamp,
- .additional_data = cur_entry.data.filemark.additional_data,
- },
- };
- if (cur_entry.type == kSDItemGlobalMark) {
- if (!mark_set_global(cur_entry.data.filemark.name, fm, !force)) {
- shada_free_shada_entry(&cur_entry);
- break;
- }
- } else {
+ .fmark = {
+ .mark = cur_entry.data.filemark.mark,
+ .fnum = (buf == NULL ? 0 : buf->b_fnum),
+ .timestamp = cur_entry.timestamp,
+ .additional_data = cur_entry.data.filemark.additional_data,
+ },
+ };
+ if (cur_entry.type == kSDItemGlobalMark) {
+ if (!mark_set_global(cur_entry.data.filemark.name, fm, !force)) {
+ shada_free_shada_entry(&cur_entry);
+ break;
+ }
+ } else {
#define SDE_TO_XFMARK(entry) fm
#define ADJUST_IDX(i) \
- if (curwin->w_jumplistidx >= i \
- && curwin->w_jumplistidx + 1 <= curwin->w_jumplistlen) { \
- curwin->w_jumplistidx++; \
- }
+ if (curwin->w_jumplistidx >= i \
+ && curwin->w_jumplistidx + 1 <= curwin->w_jumplistlen) { \
+ curwin->w_jumplistidx++; \
+ }
#define DUMMY_AFTERFREE(entry)
- MERGE_JUMPS(curwin->w_jumplistlen, curwin->w_jumplist, xfmark_T,
- fmark.timestamp, fmark.mark, cur_entry,
- (buf == NULL
+ MERGE_JUMPS(curwin->w_jumplistlen, curwin->w_jumplist, xfmark_T,
+ fmark.timestamp, fmark.mark, cur_entry,
+ (buf == NULL
? (jl_entry.fname != NULL
&& STRCMP(fm.fname, jl_entry.fname) == 0)
: fm.fmark.fnum == jl_entry.fmark.fnum),
- free_xfmark, SDE_TO_XFMARK, ADJUST_IDX, DUMMY_AFTERFREE);
+ free_xfmark, SDE_TO_XFMARK, ADJUST_IDX, DUMMY_AFTERFREE);
#undef SDE_TO_XFMARK
#undef ADJUST_IDX
#undef DUMMY_AFTERFREE
- }
- // Do not free shada entry: its allocated memory was saved above.
- break;
}
- case kSDItemBufferList: {
- for (size_t i = 0; i < cur_entry.data.buffer_list.size; i++) {
- char *const sfname = path_try_shorten_fname(
- cur_entry.data.buffer_list.buffers[i].fname);
- buf_T *const buf = buflist_new(
- cur_entry.data.buffer_list.buffers[i].fname, sfname, 0,
- BLN_LISTED);
- if (buf != NULL) {
- RESET_FMARK(&buf->b_last_cursor,
- cur_entry.data.buffer_list.buffers[i].pos, 0);
- buflist_setfpos(buf, curwin, buf->b_last_cursor.mark.lnum,
- buf->b_last_cursor.mark.col, false);
- buf->additional_data =
- cur_entry.data.buffer_list.buffers[i].additional_data;
- cur_entry.data.buffer_list.buffers[i].additional_data = NULL;
- }
+ // Do not free shada entry: its allocated memory was saved above.
+ break;
+ }
+ case kSDItemBufferList:
+ for (size_t i = 0; i < cur_entry.data.buffer_list.size; i++) {
+ char *const sfname = path_try_shorten_fname(cur_entry.data.buffer_list.buffers[i].fname);
+ buf_T *const buf = buflist_new(cur_entry.data.buffer_list.buffers[i].fname, sfname, 0,
+ BLN_LISTED);
+ if (buf != NULL) {
+ RESET_FMARK(&buf->b_last_cursor,
+ cur_entry.data.buffer_list.buffers[i].pos, 0);
+ buflist_setfpos(buf, curwin, buf->b_last_cursor.mark.lnum,
+ buf->b_last_cursor.mark.col, false);
+ buf->additional_data =
+ cur_entry.data.buffer_list.buffers[i].additional_data;
+ cur_entry.data.buffer_list.buffers[i].additional_data = NULL;
}
- shada_free_shada_entry(&cur_entry);
- break;
}
- case kSDItemChange:
- case kSDItemLocalMark: {
- if (get_old_files && !in_strset(&oldfiles_set,
- cur_entry.data.filemark.fname)) {
- char *fname = cur_entry.data.filemark.fname;
- if (want_marks) {
- // Do not bother with allocating memory for the string if already
- // allocated string from cur_entry can be used. It cannot be used if
- // want_marks is set because this way it may be used for a mark.
- fname = xstrdup(fname);
- }
- int kh_ret;
- (void)kh_put(strset, &oldfiles_set, fname, &kh_ret);
- tv_list_append_allocated_string(oldfiles_list, fname);
- if (!want_marks) {
- // Avoid free because this string was already used.
- cur_entry.data.filemark.fname = NULL;
- }
+ shada_free_shada_entry(&cur_entry);
+ break;
+ case kSDItemChange:
+ case kSDItemLocalMark: {
+ if (get_old_files && !in_strset(&oldfiles_set,
+ cur_entry.data.filemark.fname)) {
+ char *fname = cur_entry.data.filemark.fname;
+ if (want_marks) {
+ // Do not bother with allocating memory for the string if already
+ // allocated string from cur_entry can be used. It cannot be used if
+ // want_marks is set because this way it may be used for a mark.
+ fname = xstrdup(fname);
}
+ int kh_ret;
+ (void)kh_put(strset, &oldfiles_set, fname, &kh_ret);
+ tv_list_append_allocated_string(oldfiles_list, fname);
if (!want_marks) {
- shada_free_shada_entry(&cur_entry);
- break;
+ // Avoid free because this string was already used.
+ cur_entry.data.filemark.fname = NULL;
}
- buf_T *buf = find_buffer(&fname_bufs, cur_entry.data.filemark.fname);
- if (buf == NULL) {
+ }
+ if (!want_marks) {
+ shada_free_shada_entry(&cur_entry);
+ break;
+ }
+ buf_T *buf = find_buffer(&fname_bufs, cur_entry.data.filemark.fname);
+ if (buf == NULL) {
+ shada_free_shada_entry(&cur_entry);
+ break;
+ }
+ const fmark_T fm = (fmark_T) {
+ .mark = cur_entry.data.filemark.mark,
+ .fnum = 0,
+ .timestamp = cur_entry.timestamp,
+ .additional_data = cur_entry.data.filemark.additional_data,
+ };
+ if (cur_entry.type == kSDItemLocalMark) {
+ if (!mark_set_local(cur_entry.data.filemark.name, buf, fm, !force)) {
shada_free_shada_entry(&cur_entry);
break;
}
- const fmark_T fm = (fmark_T) {
- .mark = cur_entry.data.filemark.mark,
- .fnum = 0,
- .timestamp = cur_entry.timestamp,
- .additional_data = cur_entry.data.filemark.additional_data,
- };
- if (cur_entry.type == kSDItemLocalMark) {
- if (!mark_set_local(cur_entry.data.filemark.name, buf, fm, !force)) {
- shada_free_shada_entry(&cur_entry);
- break;
- }
- } else {
- int kh_ret;
- (void) kh_put(bufset, &cl_bufs, (uintptr_t) buf, &kh_ret);
+ } else {
+ int kh_ret;
+ (void)kh_put(bufset, &cl_bufs, (uintptr_t)buf, &kh_ret);
#define SDE_TO_FMARK(entry) fm
#define AFTERFREE(entry) (entry).data.filemark.fname = NULL
#define DUMMY_IDX_ADJ(i)
- MERGE_JUMPS(buf->b_changelistlen, buf->b_changelist, fmark_T,
- timestamp, mark, cur_entry, true,
- free_fmark, SDE_TO_FMARK, DUMMY_IDX_ADJ, AFTERFREE);
+ MERGE_JUMPS(buf->b_changelistlen, buf->b_changelist, fmark_T,
+ timestamp, mark, cur_entry, true,
+ free_fmark, SDE_TO_FMARK, DUMMY_IDX_ADJ, AFTERFREE);
#undef SDE_TO_FMARK
#undef AFTERFREE
#undef DUMMY_IDX_ADJ
- }
- // Do not free shada entry: except for fname, its allocated memory (i.e.
- // additional_data attribute contents if non-NULL) was saved above.
- xfree(cur_entry.data.filemark.fname);
- break;
}
+ // Do not free shada entry: except for fname, its allocated memory (i.e.
+ // additional_data attribute contents if non-NULL) was saved above.
+ xfree(cur_entry.data.filemark.fname);
+ break;
+ }
}
}
shada_read_main_cycle_end:
@@ -1490,7 +1457,7 @@ shada_read_main_cycle_end:
}
if (cl_bufs.n_occupied) {
FOR_ALL_TAB_WINDOWS(tp, wp) {
- (void) tp;
+ (void)tp;
if (in_bufset(&cl_bufs, wp->w_buffer)) {
wp->w_changelistidx = wp->w_buffer->b_changelistlen;
}
@@ -1499,7 +1466,7 @@ shada_read_main_cycle_end:
kh_dealloc(bufset, &cl_bufs);
const char *key;
kh_foreach_key(&fname_bufs, key, {
- xfree((void *) key);
+ xfree((void *)key);
})
kh_dealloc(fnamebufs, &fname_bufs);
kh_dealloc(strset, &oldfiles_set);
@@ -1544,33 +1511,33 @@ static char *shada_filename(const char *file)
// If shell is not performing them then they should be done in main.c
// where arguments are parsed, *not here*.
expand_env((char_u *)file, &(NameBuff[0]), MAXPATHL);
- file = (const char *) &(NameBuff[0]);
+ file = (const char *)&(NameBuff[0]);
}
}
return xstrdup(file);
}
#define PACK_STATIC_STR(s) \
- do { \
- msgpack_pack_str(spacker, sizeof(s) - 1); \
- msgpack_pack_str_body(spacker, s, sizeof(s) - 1); \
- } while (0)
+ do { \
+ msgpack_pack_str(spacker, sizeof(s) - 1); \
+ msgpack_pack_str_body(spacker, s, sizeof(s) - 1); \
+ } while (0)
#define PACK_STRING(s) \
- do { \
- const String s_ = (s); \
- msgpack_pack_str(spacker, s_.size); \
- if (s_.size) { \
- msgpack_pack_str_body(spacker, s_.data, s_.size); \
- } \
- } while (0)
+ do { \
+ const String s_ = (s); \
+ msgpack_pack_str(spacker, s_.size); \
+ if (s_.size) { \
+ msgpack_pack_str_body(spacker, s_.data, s_.size); \
+ } \
+ } while (0)
#define PACK_BIN(s) \
- do { \
- const String s_ = (s); \
- msgpack_pack_bin(spacker, s_.size); \
- if (s_.size > 0) { \
- msgpack_pack_bin_body(spacker, s_.data, s_.size); \
- } \
- } while (0)
+ do { \
+ const String s_ = (s); \
+ msgpack_pack_bin(spacker, s_.size); \
+ if (s_.size > 0) { \
+ msgpack_pack_bin_body(spacker, s_.data, s_.size); \
+ } \
+ } while (0)
/// Write single ShaDa entry
///
@@ -1580,8 +1547,7 @@ static char *shada_filename(const char *file)
/// restrictions.
///
/// @return kSDWriteSuccessfull, kSDWriteFailed or kSDWriteIgnError.
-static ShaDaWriteResult shada_pack_entry(msgpack_packer *const packer,
- ShadaEntry entry,
+static ShaDaWriteResult shada_pack_entry(msgpack_packer *const packer, ShadaEntry entry,
const size_t max_kbyte)
FUNC_ATTR_NONNULL_ALL
{
@@ -1625,237 +1591,239 @@ static ShaDaWriteResult shada_pack_entry(msgpack_packer *const packer,
#define CHECK_DEFAULT(entry, attr) \
(sd_default_values[entry.type].data.attr == entry.data.attr)
#define ONE_IF_NOT_DEFAULT(entry, attr) \
- ((size_t) (!CHECK_DEFAULT(entry, attr)))
+ ((size_t)(!CHECK_DEFAULT(entry, attr)))
switch (entry.type) {
- case kSDItemMissing: {
- abort();
- }
- case kSDItemUnknown: {
- if (spacker->callback(spacker->data, entry.data.unknown_item.contents,
- (unsigned) entry.data.unknown_item.size) == -1) {
- goto shada_pack_entry_error;
- }
- break;
+ case kSDItemMissing:
+ abort();
+ case kSDItemUnknown:
+ if (spacker->callback(spacker->data, entry.data.unknown_item.contents,
+ (unsigned)entry.data.unknown_item.size) == -1) {
+ goto shada_pack_entry_error;
}
- case kSDItemHistoryEntry: {
- const bool is_hist_search =
- entry.data.history_item.histtype == HIST_SEARCH;
- const size_t arr_size = 2 + (size_t)is_hist_search + (size_t)(
- tv_list_len(entry.data.history_item.additional_elements));
- msgpack_pack_array(spacker, arr_size);
- msgpack_pack_uint8(spacker, entry.data.history_item.histtype);
- PACK_BIN(cstr_as_string(entry.data.history_item.string));
- if (is_hist_search) {
- msgpack_pack_uint8(spacker, (uint8_t)entry.data.history_item.sep);
- }
- DUMP_ADDITIONAL_ELEMENTS(entry.data.history_item.additional_elements,
- "history entry item");
- break;
+ break;
+ case kSDItemHistoryEntry: {
+ const bool is_hist_search =
+ entry.data.history_item.histtype == HIST_SEARCH;
+ const size_t arr_size = 2 + (size_t)is_hist_search + (size_t)(
+ tv_list_len(entry.data.
+ history_item.
+ additional_elements));
+ msgpack_pack_array(spacker, arr_size);
+ msgpack_pack_uint8(spacker, entry.data.history_item.histtype);
+ PACK_BIN(cstr_as_string(entry.data.history_item.string));
+ if (is_hist_search) {
+ msgpack_pack_uint8(spacker, (uint8_t)entry.data.history_item.sep);
}
- case kSDItemVariable: {
- const size_t arr_size = 2 + (size_t)(
- tv_list_len(entry.data.global_var.additional_elements));
- msgpack_pack_array(spacker, arr_size);
- const String varname = cstr_as_string(entry.data.global_var.name);
- PACK_BIN(varname);
- char vardesc[256] = "variable g:";
- memcpy(&vardesc[sizeof("variable g:") - 1], varname.data,
- varname.size + 1);
- if (encode_vim_to_msgpack(spacker, &entry.data.global_var.value, vardesc)
- == FAIL) {
- ret = kSDWriteIgnError;
- EMSG2(_(WERR "Failed to write variable %s"),
- entry.data.global_var.name);
- goto shada_pack_entry_error;
- }
- DUMP_ADDITIONAL_ELEMENTS(entry.data.global_var.additional_elements,
- "variable item");
- break;
+ DUMP_ADDITIONAL_ELEMENTS(entry.data.history_item.additional_elements,
+ "history entry item");
+ break;
+ }
+ case kSDItemVariable: {
+ if (entry.data.global_var.value.v_type == VAR_TYPE_BLOB) {
+ // Strings and Blobs both pack as msgpack BINs; differentiate them by
+ // storing an additional VAR_TYPE_BLOB element alongside Blobs
+ list_T *const list = tv_list_alloc(1);
+ tv_list_append_number(list, VAR_TYPE_BLOB);
+ entry.data.global_var.additional_elements = list;
}
- case kSDItemSubString: {
- const size_t arr_size = 1 + (size_t)(
- tv_list_len(entry.data.sub_string.additional_elements));
- msgpack_pack_array(spacker, arr_size);
- PACK_BIN(cstr_as_string(entry.data.sub_string.sub));
- DUMP_ADDITIONAL_ELEMENTS(entry.data.sub_string.additional_elements,
- "sub string item");
- break;
+ const size_t arr_size = 2 + (size_t)(
+ tv_list_len(entry.data.global_var.additional_elements));
+ msgpack_pack_array(spacker, arr_size);
+ const String varname = cstr_as_string(entry.data.global_var.name);
+ PACK_BIN(varname);
+ char vardesc[256] = "variable g:";
+ memcpy(&vardesc[sizeof("variable g:") - 1], varname.data,
+ varname.size + 1);
+ if (encode_vim_to_msgpack(spacker, &entry.data.global_var.value, vardesc)
+ == FAIL) {
+ ret = kSDWriteIgnError;
+ EMSG2(_(WERR "Failed to write variable %s"),
+ entry.data.global_var.name);
+ goto shada_pack_entry_error;
}
- case kSDItemSearchPattern: {
- const size_t map_size = (size_t) (
- 1 // Search pattern is always present
- + ONE_IF_NOT_DEFAULT(entry, search_pattern.magic)
- + ONE_IF_NOT_DEFAULT(entry, search_pattern.is_last_used)
- + ONE_IF_NOT_DEFAULT(entry, search_pattern.smartcase)
- + ONE_IF_NOT_DEFAULT(entry, search_pattern.has_line_offset)
- + ONE_IF_NOT_DEFAULT(entry, search_pattern.place_cursor_at_end)
- + ONE_IF_NOT_DEFAULT(entry, search_pattern.is_substitute_pattern)
- + ONE_IF_NOT_DEFAULT(entry, search_pattern.highlighted)
- + ONE_IF_NOT_DEFAULT(entry, search_pattern.offset)
- + ONE_IF_NOT_DEFAULT(entry, search_pattern.search_backward)
- // finally, additional data:
- + (size_t) (
- entry.data.search_pattern.additional_data
+ DUMP_ADDITIONAL_ELEMENTS(entry.data.global_var.additional_elements,
+ "variable item");
+ break;
+ }
+ case kSDItemSubString: {
+ const size_t arr_size = 1 + (size_t)(
+ tv_list_len(entry.data.sub_string.additional_elements));
+ msgpack_pack_array(spacker, arr_size);
+ PACK_BIN(cstr_as_string(entry.data.sub_string.sub));
+ DUMP_ADDITIONAL_ELEMENTS(entry.data.sub_string.additional_elements,
+ "sub string item");
+ break;
+ }
+ case kSDItemSearchPattern: {
+ const size_t map_size = (size_t)(
+ 1 // Search pattern is always present
+ + ONE_IF_NOT_DEFAULT(entry, search_pattern.magic)
+ + ONE_IF_NOT_DEFAULT(entry, search_pattern.is_last_used)
+ + ONE_IF_NOT_DEFAULT(entry, search_pattern.smartcase)
+ + ONE_IF_NOT_DEFAULT(entry, search_pattern.has_line_offset)
+ + ONE_IF_NOT_DEFAULT(entry, search_pattern.place_cursor_at_end)
+ + ONE_IF_NOT_DEFAULT(entry,
+ search_pattern.is_substitute_pattern)
+ + ONE_IF_NOT_DEFAULT(entry, search_pattern.highlighted)
+ + ONE_IF_NOT_DEFAULT(entry, search_pattern.offset)
+ + ONE_IF_NOT_DEFAULT(entry, search_pattern.search_backward)
+ // finally, additional data:
+ + (size_t)(
+ entry.data.search_pattern.additional_data
? entry.data.search_pattern.additional_data->dv_hashtab.ht_used
: 0));
- msgpack_pack_map(spacker, map_size);
- PACK_STATIC_STR(SEARCH_KEY_PAT);
- PACK_BIN(cstr_as_string(entry.data.search_pattern.pat));
+ msgpack_pack_map(spacker, map_size);
+ PACK_STATIC_STR(SEARCH_KEY_PAT);
+ PACK_BIN(cstr_as_string(entry.data.search_pattern.pat));
#define PACK_BOOL(entry, name, attr) \
- do { \
- if (!CHECK_DEFAULT(entry, search_pattern.attr)) { \
- PACK_STATIC_STR(name); \
- if (sd_default_values[entry.type].data.search_pattern.attr) { \
- msgpack_pack_false(spacker); \
- } else { \
- msgpack_pack_true(spacker); \
- } \
- } \
- } while (0)
- PACK_BOOL(entry, SEARCH_KEY_MAGIC, magic);
- PACK_BOOL(entry, SEARCH_KEY_IS_LAST_USED, is_last_used);
- PACK_BOOL(entry, SEARCH_KEY_SMARTCASE, smartcase);
- PACK_BOOL(entry, SEARCH_KEY_HAS_LINE_OFFSET, has_line_offset);
- PACK_BOOL(entry, SEARCH_KEY_PLACE_CURSOR_AT_END, place_cursor_at_end);
- PACK_BOOL(entry, SEARCH_KEY_IS_SUBSTITUTE_PATTERN, is_substitute_pattern);
- PACK_BOOL(entry, SEARCH_KEY_HIGHLIGHTED, highlighted);
- PACK_BOOL(entry, SEARCH_KEY_BACKWARD, search_backward);
- if (!CHECK_DEFAULT(entry, search_pattern.offset)) {
- PACK_STATIC_STR(SEARCH_KEY_OFFSET);
- msgpack_pack_int64(spacker, entry.data.search_pattern.offset);
- }
-#undef PACK_BOOL
- DUMP_ADDITIONAL_DATA(entry.data.search_pattern.additional_data,
- "search pattern item");
- break;
+ do { \
+ if (!CHECK_DEFAULT(entry, search_pattern.attr)) { \
+ PACK_STATIC_STR(name); \
+ if (sd_default_values[entry.type].data.search_pattern.attr) { \
+ msgpack_pack_false(spacker); \
+ } else { \
+ msgpack_pack_true(spacker); \
+ } \
+ } \
+ } while (0)
+ PACK_BOOL(entry, SEARCH_KEY_MAGIC, magic);
+ PACK_BOOL(entry, SEARCH_KEY_IS_LAST_USED, is_last_used);
+ PACK_BOOL(entry, SEARCH_KEY_SMARTCASE, smartcase);
+ PACK_BOOL(entry, SEARCH_KEY_HAS_LINE_OFFSET, has_line_offset);
+ PACK_BOOL(entry, SEARCH_KEY_PLACE_CURSOR_AT_END, place_cursor_at_end);
+ PACK_BOOL(entry, SEARCH_KEY_IS_SUBSTITUTE_PATTERN, is_substitute_pattern);
+ PACK_BOOL(entry, SEARCH_KEY_HIGHLIGHTED, highlighted);
+ PACK_BOOL(entry, SEARCH_KEY_BACKWARD, search_backward);
+ if (!CHECK_DEFAULT(entry, search_pattern.offset)) {
+ PACK_STATIC_STR(SEARCH_KEY_OFFSET);
+ msgpack_pack_int64(spacker, entry.data.search_pattern.offset);
}
- case kSDItemChange:
- case kSDItemGlobalMark:
- case kSDItemLocalMark:
- case kSDItemJump: {
- const size_t map_size = (size_t) (
- 1 // File name
- + ONE_IF_NOT_DEFAULT(entry, filemark.mark.lnum)
- + ONE_IF_NOT_DEFAULT(entry, filemark.mark.col)
- + ONE_IF_NOT_DEFAULT(entry, filemark.name)
- // Additional entries, if any:
- + (size_t) (
- entry.data.filemark.additional_data == NULL
+#undef PACK_BOOL
+ DUMP_ADDITIONAL_DATA(entry.data.search_pattern.additional_data,
+ "search pattern item");
+ break;
+ }
+ case kSDItemChange:
+ case kSDItemGlobalMark:
+ case kSDItemLocalMark:
+ case kSDItemJump: {
+ const size_t map_size = (size_t)(
+ 1 // File name
+ + ONE_IF_NOT_DEFAULT(entry, filemark.mark.lnum)
+ + ONE_IF_NOT_DEFAULT(entry, filemark.mark.col)
+ + ONE_IF_NOT_DEFAULT(entry, filemark.name)
+ // Additional entries, if any:
+ + (size_t)(
+ entry.data.filemark.additional_data == NULL
? 0
: entry.data.filemark.additional_data->dv_hashtab.ht_used));
- msgpack_pack_map(spacker, map_size);
- PACK_STATIC_STR(KEY_FILE);
- PACK_BIN(cstr_as_string(entry.data.filemark.fname));
- if (!CHECK_DEFAULT(entry, filemark.mark.lnum)) {
- PACK_STATIC_STR(KEY_LNUM);
- msgpack_pack_long(spacker, entry.data.filemark.mark.lnum);
- }
- if (!CHECK_DEFAULT(entry, filemark.mark.col)) {
- PACK_STATIC_STR(KEY_COL);
- msgpack_pack_long(spacker, entry.data.filemark.mark.col);
- }
- assert(entry.type == kSDItemJump || entry.type == kSDItemChange
+ msgpack_pack_map(spacker, map_size);
+ PACK_STATIC_STR(KEY_FILE);
+ PACK_BIN(cstr_as_string(entry.data.filemark.fname));
+ if (!CHECK_DEFAULT(entry, filemark.mark.lnum)) {
+ PACK_STATIC_STR(KEY_LNUM);
+ msgpack_pack_long(spacker, entry.data.filemark.mark.lnum);
+ }
+ if (!CHECK_DEFAULT(entry, filemark.mark.col)) {
+ PACK_STATIC_STR(KEY_COL);
+ msgpack_pack_long(spacker, entry.data.filemark.mark.col);
+ }
+ assert(entry.type == kSDItemJump || entry.type == kSDItemChange
? CHECK_DEFAULT(entry, filemark.name)
: true);
- if (!CHECK_DEFAULT(entry, filemark.name)) {
- PACK_STATIC_STR(KEY_NAME_CHAR);
- msgpack_pack_uint8(spacker, (uint8_t) entry.data.filemark.name);
- }
- DUMP_ADDITIONAL_DATA(entry.data.filemark.additional_data,
- "mark (change, jump, global or local) item");
- break;
+ if (!CHECK_DEFAULT(entry, filemark.name)) {
+ PACK_STATIC_STR(KEY_NAME_CHAR);
+ msgpack_pack_uint8(spacker, (uint8_t)entry.data.filemark.name);
}
- case kSDItemRegister: {
- const size_t map_size = (size_t) (
- 2 // Register contents and name
- + ONE_IF_NOT_DEFAULT(entry, reg.type)
- + ONE_IF_NOT_DEFAULT(entry, reg.width)
- + ONE_IF_NOT_DEFAULT(entry, reg.is_unnamed)
- // Additional entries, if any:
- + (size_t) (entry.data.reg.additional_data == NULL
+ DUMP_ADDITIONAL_DATA(entry.data.filemark.additional_data,
+ "mark (change, jump, global or local) item");
+ break;
+ }
+ case kSDItemRegister: {
+ const size_t map_size = (size_t)(
+ 2 // Register contents and name
+ + ONE_IF_NOT_DEFAULT(entry, reg.type)
+ + ONE_IF_NOT_DEFAULT(entry, reg.width)
+ + ONE_IF_NOT_DEFAULT(entry, reg.is_unnamed)
+ // Additional entries, if any:
+ + (size_t)(entry.data.reg.additional_data == NULL
? 0
: entry.data.reg.additional_data->dv_hashtab.ht_used));
- msgpack_pack_map(spacker, map_size);
- PACK_STATIC_STR(REG_KEY_CONTENTS);
- msgpack_pack_array(spacker, entry.data.reg.contents_size);
- for (size_t i = 0; i < entry.data.reg.contents_size; i++) {
- PACK_BIN(cstr_as_string(entry.data.reg.contents[i]));
- }
- PACK_STATIC_STR(KEY_NAME_CHAR);
- msgpack_pack_char(spacker, entry.data.reg.name);
- if (!CHECK_DEFAULT(entry, reg.type)) {
- PACK_STATIC_STR(REG_KEY_TYPE);
- msgpack_pack_uint8(spacker, (uint8_t)entry.data.reg.type);
- }
- if (!CHECK_DEFAULT(entry, reg.width)) {
- PACK_STATIC_STR(REG_KEY_WIDTH);
- msgpack_pack_uint64(spacker, (uint64_t) entry.data.reg.width);
- }
- if (!CHECK_DEFAULT(entry, reg.is_unnamed)) {
- PACK_STATIC_STR(REG_KEY_UNNAMED);
- if (entry.data.reg.is_unnamed) {
- msgpack_pack_true(spacker);
- } else {
- msgpack_pack_false(spacker);
- }
+ msgpack_pack_map(spacker, map_size);
+ PACK_STATIC_STR(REG_KEY_CONTENTS);
+ msgpack_pack_array(spacker, entry.data.reg.contents_size);
+ for (size_t i = 0; i < entry.data.reg.contents_size; i++) {
+ PACK_BIN(cstr_as_string(entry.data.reg.contents[i]));
+ }
+ PACK_STATIC_STR(KEY_NAME_CHAR);
+ msgpack_pack_char(spacker, entry.data.reg.name);
+ if (!CHECK_DEFAULT(entry, reg.type)) {
+ PACK_STATIC_STR(REG_KEY_TYPE);
+ msgpack_pack_uint8(spacker, (uint8_t)entry.data.reg.type);
+ }
+ if (!CHECK_DEFAULT(entry, reg.width)) {
+ PACK_STATIC_STR(REG_KEY_WIDTH);
+ msgpack_pack_uint64(spacker, (uint64_t)entry.data.reg.width);
+ }
+ if (!CHECK_DEFAULT(entry, reg.is_unnamed)) {
+ PACK_STATIC_STR(REG_KEY_UNNAMED);
+ if (entry.data.reg.is_unnamed) {
+ msgpack_pack_true(spacker);
+ } else {
+ msgpack_pack_false(spacker);
}
- DUMP_ADDITIONAL_DATA(entry.data.reg.additional_data, "register item");
- break;
}
- case kSDItemBufferList: {
- msgpack_pack_array(spacker, entry.data.buffer_list.size);
- for (size_t i = 0; i < entry.data.buffer_list.size; i++) {
- const size_t map_size = (size_t) (
- 1 // Buffer name
- + (size_t) (entry.data.buffer_list.buffers[i].pos.lnum
- != default_pos.lnum)
- + (size_t) (entry.data.buffer_list.buffers[i].pos.col
- != default_pos.col)
- // Additional entries, if any:
- + (size_t) (
- entry.data.buffer_list.buffers[i].additional_data == NULL
+ DUMP_ADDITIONAL_DATA(entry.data.reg.additional_data, "register item");
+ break;
+ }
+ case kSDItemBufferList:
+ msgpack_pack_array(spacker, entry.data.buffer_list.size);
+ for (size_t i = 0; i < entry.data.buffer_list.size; i++) {
+ const size_t map_size = (size_t)(
+ 1 // Buffer name
+ + (size_t)(entry.data.buffer_list.buffers[i].pos.lnum
+ != default_pos.lnum)
+ + (size_t)(entry.data.buffer_list.buffers[i].pos.col
+ != default_pos.col)
+ // Additional entries, if any:
+ + (size_t)(
+ entry.data.buffer_list.buffers[i].additional_data
+ == NULL
? 0
: (entry.data.buffer_list.buffers[i].additional_data
->dv_hashtab.ht_used)));
- msgpack_pack_map(spacker, map_size);
- PACK_STATIC_STR(KEY_FILE);
- PACK_BIN(cstr_as_string(entry.data.buffer_list.buffers[i].fname));
- if (entry.data.buffer_list.buffers[i].pos.lnum != 1) {
- PACK_STATIC_STR(KEY_LNUM);
- msgpack_pack_uint64(
- spacker, (uint64_t) entry.data.buffer_list.buffers[i].pos.lnum);
- }
- if (entry.data.buffer_list.buffers[i].pos.col != 0) {
- PACK_STATIC_STR(KEY_COL);
- msgpack_pack_uint64(
- spacker, (uint64_t) entry.data.buffer_list.buffers[i].pos.col);
- }
- DUMP_ADDITIONAL_DATA(entry.data.buffer_list.buffers[i].additional_data,
- "buffer list subitem");
+ msgpack_pack_map(spacker, map_size);
+ PACK_STATIC_STR(KEY_FILE);
+ PACK_BIN(cstr_as_string(entry.data.buffer_list.buffers[i].fname));
+ if (entry.data.buffer_list.buffers[i].pos.lnum != 1) {
+ PACK_STATIC_STR(KEY_LNUM);
+ msgpack_pack_uint64(spacker, (uint64_t)entry.data.buffer_list.buffers[i].pos.lnum);
}
- break;
+ if (entry.data.buffer_list.buffers[i].pos.col != 0) {
+ PACK_STATIC_STR(KEY_COL);
+ msgpack_pack_uint64(spacker, (uint64_t)entry.data.buffer_list.buffers[i].pos.col);
+ }
+ DUMP_ADDITIONAL_DATA(entry.data.buffer_list.buffers[i].additional_data,
+ "buffer list subitem");
}
- case kSDItemHeader: {
- msgpack_pack_map(spacker, entry.data.header.size);
- for (size_t i = 0; i < entry.data.header.size; i++) {
- PACK_STRING(entry.data.header.items[i].key);
- const Object obj = entry.data.header.items[i].value;
- switch (obj.type) {
- case kObjectTypeString: {
- PACK_BIN(obj.data.string);
- break;
- }
- case kObjectTypeInteger: {
- msgpack_pack_int64(spacker, (int64_t) obj.data.integer);
- break;
- }
- default: {
- abort();
- }
- }
+ break;
+ case kSDItemHeader:
+ msgpack_pack_map(spacker, entry.data.header.size);
+ for (size_t i = 0; i < entry.data.header.size; i++) {
+ PACK_STRING(entry.data.header.items[i].key);
+ const Object obj = entry.data.header.items[i].value;
+ switch (obj.type) {
+ case kObjectTypeString:
+ PACK_BIN(obj.data.string);
+ break;
+ case kObjectTypeInteger:
+ msgpack_pack_int64(spacker, (int64_t)obj.data.integer);
+ break;
+ default:
+ abort();
}
- break;
}
+ break;
}
#undef CHECK_DEFAULT
#undef ONE_IF_NOT_DEFAULT
@@ -1865,17 +1833,17 @@ static ShaDaWriteResult shada_pack_entry(msgpack_packer *const packer,
goto shada_pack_entry_error;
}
} else {
- if (msgpack_pack_uint64(packer, (uint64_t) entry.type) == -1) {
+ if (msgpack_pack_uint64(packer, (uint64_t)entry.type) == -1) {
goto shada_pack_entry_error;
}
}
- if (msgpack_pack_uint64(packer, (uint64_t) entry.timestamp) == -1) {
+ if (msgpack_pack_uint64(packer, (uint64_t)entry.timestamp) == -1) {
goto shada_pack_entry_error;
}
if (sbuf.size > 0) {
- if ((msgpack_pack_uint64(packer, (uint64_t) sbuf.size) == -1)
+ if ((msgpack_pack_uint64(packer, (uint64_t)sbuf.size) == -1)
|| (packer->callback(packer->data, sbuf.data,
- (unsigned) sbuf.size) == -1)) {
+ (unsigned)sbuf.size) == -1)) {
goto shada_pack_entry_error;
}
}
@@ -1898,9 +1866,9 @@ shada_pack_entry_error:
/// @param[in] entry Entry written.
/// @param[in] max_kbyte Maximum size of an item in KiB. Zero means no
/// restrictions.
-static inline ShaDaWriteResult shada_pack_pfreed_entry(
- msgpack_packer *const packer, PossiblyFreedShadaEntry entry,
- const size_t max_kbyte)
+static inline ShaDaWriteResult shada_pack_pfreed_entry(msgpack_packer *const packer,
+ PossiblyFreedShadaEntry entry,
+ const size_t max_kbyte)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_ALWAYS_INLINE
{
ShaDaWriteResult ret = kSDWriteSuccessfull;
@@ -1938,9 +1906,10 @@ static int compare_file_marks(const void *a, const void *b)
///
/// @return kSDReadStatusNotShaDa, kSDReadStatusReadError or
/// kSDReadStatusSuccess.
-static inline ShaDaReadResult shada_parse_msgpack(
- ShaDaReadDef *const sd_reader, const size_t length,
- msgpack_unpacked *ret_unpacked, char **const ret_buf)
+static inline ShaDaReadResult shada_parse_msgpack(ShaDaReadDef *const sd_reader,
+ const size_t length,
+ msgpack_unpacked *ret_unpacked,
+ char **const ret_buf)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ARG(1)
{
const uintmax_t initial_fpos = sd_reader->fpos;
@@ -1957,47 +1926,42 @@ shada_parse_msgpack_read_next: {}
msgpack_unpacked unpacked;
msgpack_unpacked_init(&unpacked);
const msgpack_unpack_return result =
- msgpack_unpack_next(&unpacked, buf, length, &off);
+ msgpack_unpack_next(&unpacked, buf, length, &off);
ShaDaReadResult ret = kSDReadStatusSuccess;
switch (result) {
- case MSGPACK_UNPACK_SUCCESS: {
- if (off < length) {
- goto shada_parse_msgpack_extra_bytes;
- }
- break;
+ case MSGPACK_UNPACK_SUCCESS:
+ if (off < length) {
+ goto shada_parse_msgpack_extra_bytes;
}
- case MSGPACK_UNPACK_PARSE_ERROR: {
- emsgf(_(RCERR "Failed to parse ShaDa file due to a msgpack parser error "
- "at position %" PRIu64),
- (uint64_t) initial_fpos);
- ret = kSDReadStatusNotShaDa;
- break;
+ break;
+ case MSGPACK_UNPACK_PARSE_ERROR:
+ emsgf(_(RCERR "Failed to parse ShaDa file due to a msgpack parser error "
+ "at position %" PRIu64),
+ (uint64_t)initial_fpos);
+ ret = kSDReadStatusNotShaDa;
+ break;
+ case MSGPACK_UNPACK_NOMEM_ERROR:
+ if (!did_try_to_free) {
+ did_try_to_free = true;
+ try_to_free_memory();
+ goto shada_parse_msgpack_read_next;
}
- case MSGPACK_UNPACK_NOMEM_ERROR: {
- if (!did_try_to_free) {
- did_try_to_free = true;
- try_to_free_memory();
- goto shada_parse_msgpack_read_next;
- }
- EMSG(_(e_outofmem));
- ret = kSDReadStatusReadError;
- break;
- }
- case MSGPACK_UNPACK_CONTINUE: {
- emsgf(_(RCERR "Failed to parse ShaDa file: incomplete msgpack string "
- "at position %" PRIu64),
- (uint64_t) initial_fpos);
- ret = kSDReadStatusNotShaDa;
- break;
- }
- case MSGPACK_UNPACK_EXTRA_BYTES: {
+ EMSG(_(e_outofmem));
+ ret = kSDReadStatusReadError;
+ break;
+ case MSGPACK_UNPACK_CONTINUE:
+ emsgf(_(RCERR "Failed to parse ShaDa file: incomplete msgpack string "
+ "at position %" PRIu64),
+ (uint64_t)initial_fpos);
+ ret = kSDReadStatusNotShaDa;
+ break;
+ case MSGPACK_UNPACK_EXTRA_BYTES:
shada_parse_msgpack_extra_bytes:
- emsgf(_(RCERR "Failed to parse ShaDa file: extra bytes in msgpack string "
- "at position %" PRIu64),
- (uint64_t) initial_fpos);
- ret = kSDReadStatusNotShaDa;
- break;
- }
+ emsgf(_(RCERR "Failed to parse ShaDa file: extra bytes in msgpack string "
+ "at position %" PRIu64),
+ (uint64_t)initial_fpos);
+ ret = kSDReadStatusNotShaDa;
+ break;
}
if (ret_buf != NULL && ret == kSDReadStatusSuccess) {
if (ret_unpacked == NULL) {
@@ -2027,81 +1991,67 @@ static const char *shada_format_entry(const ShadaEntry entry)
vim_snprintf(S_LEN(ret), "%s", "[ ] ts=%" PRIu64 " ");
// ^ Space for `can_free_entry`
switch (entry.type) {
- case kSDItemMissing: {
- vim_snprintf_add(S_LEN(ret), "Missing");
- break;
- }
- case kSDItemHeader: {
- vim_snprintf_add(S_LEN(ret), "Header { TODO }");
- break;
- }
- case kSDItemBufferList: {
- vim_snprintf_add(S_LEN(ret), "BufferList { TODO }");
- break;
- }
- case kSDItemUnknown: {
- vim_snprintf_add(S_LEN(ret), "Unknown { TODO }");
- break;
- }
- case kSDItemSearchPattern: {
- vim_snprintf_add(S_LEN(ret), "SearchPattern { TODO }");
- break;
- }
- case kSDItemSubString: {
- vim_snprintf_add(S_LEN(ret), "SubString { TODO }");
- break;
- }
- case kSDItemHistoryEntry: {
- vim_snprintf_add(S_LEN(ret), "HistoryEntry { TODO }");
- break;
- }
- case kSDItemRegister: {
- vim_snprintf_add(S_LEN(ret), "Register { TODO }");
- break;
- }
- case kSDItemVariable: {
- vim_snprintf_add(S_LEN(ret), "Variable { TODO }");
- break;
- }
+ case kSDItemMissing:
+ vim_snprintf_add(S_LEN(ret), "Missing");
+ break;
+ case kSDItemHeader:
+ vim_snprintf_add(S_LEN(ret), "Header { TODO }");
+ break;
+ case kSDItemBufferList:
+ vim_snprintf_add(S_LEN(ret), "BufferList { TODO }");
+ break;
+ case kSDItemUnknown:
+ vim_snprintf_add(S_LEN(ret), "Unknown { TODO }");
+ break;
+ case kSDItemSearchPattern:
+ vim_snprintf_add(S_LEN(ret), "SearchPattern { TODO }");
+ break;
+ case kSDItemSubString:
+ vim_snprintf_add(S_LEN(ret), "SubString { TODO }");
+ break;
+ case kSDItemHistoryEntry:
+ vim_snprintf_add(S_LEN(ret), "HistoryEntry { TODO }");
+ break;
+ case kSDItemRegister:
+ vim_snprintf_add(S_LEN(ret), "Register { TODO }");
+ break;
+ case kSDItemVariable:
+ vim_snprintf_add(S_LEN(ret), "Variable { TODO }");
+ break;
#define FORMAT_MARK_ENTRY(entry_name, name_fmt, name_fmt_arg) \
- do { \
- typval_T ad_tv = { \
- .v_type = VAR_DICT, \
- .vval.v_dict = entry.data.filemark.additional_data \
- }; \
- size_t ad_len; \
- char *const ad = encode_tv2string(&ad_tv, &ad_len); \
- vim_snprintf_add( \
- S_LEN(ret), \
- entry_name " {" name_fmt " file=[%zu]\"%.512s\", " \
- "pos={l=%" PRIdLINENR ",c=%" PRIdCOLNR ",a=%" PRIdCOLNR "}, " \
- "ad={%p:[%zu]%.64s} }", \
- name_fmt_arg, \
- strlen(entry.data.filemark.fname), \
- entry.data.filemark.fname, \
- entry.data.filemark.mark.lnum, \
- entry.data.filemark.mark.col, \
- entry.data.filemark.mark.coladd, \
- (void *)entry.data.filemark.additional_data, \
- ad_len, \
- ad); \
- } while (0)
- case kSDItemGlobalMark: {
- FORMAT_MARK_ENTRY("GlobalMark", " name='%c',", entry.data.filemark.name);
- break;
- }
- case kSDItemChange: {
- FORMAT_MARK_ENTRY("Change", "%s", "");
- break;
- }
- case kSDItemLocalMark: {
- FORMAT_MARK_ENTRY("LocalMark", " name='%c',", entry.data.filemark.name);
- break;
- }
- case kSDItemJump: {
- FORMAT_MARK_ENTRY("Jump", "%s", "");
- break;
- }
+ do { \
+ typval_T ad_tv = { \
+ .v_type = VAR_DICT, \
+ .vval.v_dict = entry.data.filemark.additional_data \
+ }; \
+ size_t ad_len; \
+ char *const ad = encode_tv2string(&ad_tv, &ad_len); \
+ vim_snprintf_add(S_LEN(ret), \
+ entry_name " {" name_fmt " file=[%zu]\"%.512s\", " \
+ "pos={l=%" PRIdLINENR ",c=%" PRIdCOLNR ",a=%" PRIdCOLNR "}, " \
+ "ad={%p:[%zu]%.64s} }", \
+ name_fmt_arg, \
+ strlen(entry.data.filemark.fname), \
+ entry.data.filemark.fname, \
+ entry.data.filemark.mark.lnum, \
+ entry.data.filemark.mark.col, \
+ entry.data.filemark.mark.coladd, \
+ (void *)entry.data.filemark.additional_data, \
+ ad_len, \
+ ad); \
+ } while (0)
+ case kSDItemGlobalMark:
+ FORMAT_MARK_ENTRY("GlobalMark", " name='%c',", entry.data.filemark.name);
+ break;
+ case kSDItemChange:
+ FORMAT_MARK_ENTRY("Change", "%s", "");
+ break;
+ case kSDItemLocalMark:
+ FORMAT_MARK_ENTRY("LocalMark", " name='%c',", entry.data.filemark.name);
+ break;
+ case kSDItemJump:
+ FORMAT_MARK_ENTRY("Jump", "%s", "");
+ break;
#undef FORMAT_MARK_ENTRY
}
return ret;
@@ -2112,8 +2062,7 @@ static const char *shada_format_entry(const ShadaEntry entry)
/// @param[in] entry ShaDa entry to format.
///
/// @return string representing ShaDa entry in a static buffer.
-static const char *shada_format_pfreed_entry(
- const PossiblyFreedShadaEntry pfs_entry)
+static const char *shada_format_pfreed_entry(const PossiblyFreedShadaEntry pfs_entry)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_UNUSED FUNC_ATTR_NONNULL_RET
{
char *ret = (char *)shada_format_entry(pfs_entry.data);
@@ -2129,10 +2078,11 @@ static const char *shada_format_pfreed_entry(
/// @param[in,out] ret_wms Location where results are saved.
/// @param[out] packer MessagePack packer for entries which are not
/// merged.
-static inline ShaDaWriteResult shada_read_when_writing(
- ShaDaReadDef *const sd_reader, const unsigned srni_flags,
- const size_t max_kbyte, WriteMergerState *const wms,
- msgpack_packer *const packer)
+static inline ShaDaWriteResult shada_read_when_writing(ShaDaReadDef *const sd_reader,
+ const unsigned srni_flags,
+ const size_t max_kbyte,
+ WriteMergerState *const wms,
+ msgpack_packer *const packer)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
ShaDaWriteResult ret = kSDWriteSuccessfull;
@@ -2142,217 +2092,202 @@ static inline ShaDaWriteResult shada_read_when_writing(
max_kbyte))
!= kSDReadStatusFinished) {
switch (srni_ret) {
- case kSDReadStatusSuccess: {
- break;
- }
- case kSDReadStatusFinished: {
- // Should be handled by the while condition.
- abort();
- }
- case kSDReadStatusNotShaDa: {
- ret = kSDWriteReadNotShada;
- FALLTHROUGH;
- }
- case kSDReadStatusReadError: {
- return ret;
- }
- case kSDReadStatusMalformed: {
- continue;
- }
+ case kSDReadStatusSuccess:
+ break;
+ case kSDReadStatusFinished:
+ // Should be handled by the while condition.
+ abort();
+ case kSDReadStatusNotShaDa:
+ ret = kSDWriteReadNotShada;
+ FALLTHROUGH;
+ case kSDReadStatusReadError:
+ return ret;
+ case kSDReadStatusMalformed:
+ continue;
}
#define COMPARE_WITH_ENTRY(wms_entry_, entry) \
- do { \
- PossiblyFreedShadaEntry *const wms_entry = (wms_entry_); \
- if (wms_entry->data.type != kSDItemMissing) { \
- if (wms_entry->data.timestamp >= (entry).timestamp) { \
- shada_free_shada_entry(&(entry)); \
- break; \
- } \
- if (wms_entry->can_free_entry) { \
- shada_free_shada_entry(&wms_entry->data); \
- } \
+ do { \
+ PossiblyFreedShadaEntry *const wms_entry = (wms_entry_); \
+ if (wms_entry->data.type != kSDItemMissing) { \
+ if (wms_entry->data.timestamp >= (entry).timestamp) { \
+ shada_free_shada_entry(&(entry)); \
+ break; \
} \
- *wms_entry = pfs_entry; \
- } while (0)
+ if (wms_entry->can_free_entry) { \
+ shada_free_shada_entry(&wms_entry->data); \
+ } \
+ } \
+ *wms_entry = pfs_entry; \
+ } while (0)
const PossiblyFreedShadaEntry pfs_entry = {
.can_free_entry = true,
.data = entry,
};
switch (entry.type) {
- case kSDItemMissing: {
+ case kSDItemMissing:
+ break;
+ case kSDItemHeader:
+ case kSDItemBufferList:
+ abort();
+ case kSDItemUnknown:
+ ret = shada_pack_entry(packer, entry, 0);
+ shada_free_shada_entry(&entry);
+ break;
+ case kSDItemSearchPattern:
+ COMPARE_WITH_ENTRY((entry.data.search_pattern.is_substitute_pattern
+ ? &wms->sub_search_pattern
+ : &wms->search_pattern), entry);
+ break;
+ case kSDItemSubString:
+ COMPARE_WITH_ENTRY(&wms->replacement, entry);
+ break;
+ case kSDItemHistoryEntry:
+ if (entry.data.history_item.histtype >= HIST_COUNT) {
+ ret = shada_pack_entry(packer, entry, 0);
+ shada_free_shada_entry(&entry);
break;
}
- case kSDItemHeader:
- case kSDItemBufferList: {
- abort();
+ if (wms->hms[entry.data.history_item.histtype].hmll.size != 0) {
+ hms_insert(&wms->hms[entry.data.history_item.histtype], entry, true,
+ true);
+ } else {
+ shada_free_shada_entry(&entry);
}
- case kSDItemUnknown: {
+ break;
+ case kSDItemRegister: {
+ const int idx = op_reg_index(entry.data.reg.name);
+ if (idx < 0) {
ret = shada_pack_entry(packer, entry, 0);
shada_free_shada_entry(&entry);
break;
}
- case kSDItemSearchPattern: {
- COMPARE_WITH_ENTRY((entry.data.search_pattern.is_substitute_pattern
- ? &wms->sub_search_pattern
- : &wms->search_pattern), entry);
- break;
- }
- case kSDItemSubString: {
- COMPARE_WITH_ENTRY(&wms->replacement, entry);
- break;
+ COMPARE_WITH_ENTRY(&wms->registers[idx], entry);
+ break;
+ }
+ case kSDItemVariable:
+ if (!in_strset(&wms->dumped_variables, entry.data.global_var.name)) {
+ ret = shada_pack_entry(packer, entry, 0);
}
- case kSDItemHistoryEntry: {
- if (entry.data.history_item.histtype >= HIST_COUNT) {
- ret = shada_pack_entry(packer, entry, 0);
- shada_free_shada_entry(&entry);
- break;
+ shada_free_shada_entry(&entry);
+ break;
+ case kSDItemGlobalMark:
+ if (ascii_isdigit(entry.data.filemark.name)) {
+ bool processed_mark = false;
+ // Completely ignore numbered mark names, make a list sorted by
+ // timestamp.
+ for (size_t i = ARRAY_SIZE(wms->numbered_marks); i > 0; i--) {
+ ShadaEntry wms_entry = wms->numbered_marks[i - 1].data;
+ if (wms_entry.type != kSDItemGlobalMark) {
+ continue;
+ }
+ // Ignore duplicates.
+ if (wms_entry.timestamp == entry.timestamp
+ && (wms_entry.data.filemark.additional_data == NULL
+ && entry.data.filemark.additional_data == NULL)
+ && marks_equal(wms_entry.data.filemark.mark,
+ entry.data.filemark.mark)
+ && strcmp(wms_entry.data.filemark.fname,
+ entry.data.filemark.fname) == 0) {
+ shada_free_shada_entry(&entry);
+ processed_mark = true;
+ break;
+ }
+ if (wms_entry.timestamp >= entry.timestamp) {
+ processed_mark = true;
+ if (i < ARRAY_SIZE(wms->numbered_marks)) {
+ replace_numbered_mark(wms, i, pfs_entry);
+ } else {
+ shada_free_shada_entry(&entry);
+ }
+ break;
+ }
}
- if (wms->hms[entry.data.history_item.histtype].hmll.size != 0) {
- hms_insert(&wms->hms[entry.data.history_item.histtype], entry, true,
- true);
- } else {
- shada_free_shada_entry(&entry);
+ if (!processed_mark) {
+ replace_numbered_mark(wms, 0, pfs_entry);
}
- break;
- }
- case kSDItemRegister: {
- const int idx = op_reg_index(entry.data.reg.name);
+ } else {
+ const int idx = mark_global_index(entry.data.filemark.name);
if (idx < 0) {
ret = shada_pack_entry(packer, entry, 0);
shada_free_shada_entry(&entry);
break;
}
- COMPARE_WITH_ENTRY(&wms->registers[idx], entry);
- break;
+ COMPARE_WITH_ENTRY(&wms->global_marks[idx], entry);
}
- case kSDItemVariable: {
- if (!in_strset(&wms->dumped_variables, entry.data.global_var.name)) {
- ret = shada_pack_entry(packer, entry, 0);
- }
+ break;
+ case kSDItemChange:
+ case kSDItemLocalMark: {
+ if (shada_removable(entry.data.filemark.fname)) {
shada_free_shada_entry(&entry);
break;
}
- case kSDItemGlobalMark: {
- if (ascii_isdigit(entry.data.filemark.name)) {
- bool processed_mark = false;
- // Completely ignore numbered mark names, make a list sorted by
- // timestamp.
- for (size_t i = ARRAY_SIZE(wms->numbered_marks); i > 0; i--) {
- ShadaEntry wms_entry = wms->numbered_marks[i - 1].data;
- if (wms_entry.type != kSDItemGlobalMark) {
- continue;
- }
- // Ignore duplicates.
- if (wms_entry.timestamp == entry.timestamp
- && (wms_entry.data.filemark.additional_data == NULL
- && entry.data.filemark.additional_data == NULL)
- && marks_equal(wms_entry.data.filemark.mark,
- entry.data.filemark.mark)
- && strcmp(wms_entry.data.filemark.fname,
- entry.data.filemark.fname) == 0) {
+ const char *const fname = (const char *)entry.data.filemark.fname;
+ khiter_t k;
+ int kh_ret;
+ k = kh_put(file_marks, &wms->file_marks, fname, &kh_ret);
+ FileMarks *const filemarks = &kh_val(&wms->file_marks, k);
+ if (kh_ret > 0) {
+ memset(filemarks, 0, sizeof(*filemarks));
+ }
+ if (entry.timestamp > filemarks->greatest_timestamp) {
+ filemarks->greatest_timestamp = entry.timestamp;
+ }
+ if (entry.type == kSDItemLocalMark) {
+ const int idx = mark_local_index(entry.data.filemark.name);
+ if (idx < 0) {
+ filemarks->additional_marks = xrealloc(filemarks->additional_marks,
+ (++filemarks->additional_marks_size
+ * sizeof(filemarks->additional_marks[0])));
+ filemarks->additional_marks[filemarks->additional_marks_size - 1] =
+ entry;
+ } else {
+ PossiblyFreedShadaEntry *const wms_entry = &filemarks->marks[idx];
+ if (wms_entry->data.type != kSDItemMissing) {
+ if (wms_entry->data.timestamp >= entry.timestamp) {
shada_free_shada_entry(&entry);
- processed_mark = true;
break;
}
- if (wms_entry.timestamp >= entry.timestamp) {
- processed_mark = true;
- if (i < ARRAY_SIZE(wms->numbered_marks)) {
- replace_numbered_mark(wms, i, pfs_entry);
- } else {
- shada_free_shada_entry(&entry);
+ if (wms_entry->can_free_entry) {
+ if (kh_key(&wms->file_marks, k)
+ == wms_entry->data.data.filemark.fname) {
+ kh_key(&wms->file_marks, k) = entry.data.filemark.fname;
}
- break;
+ shada_free_shada_entry(&wms_entry->data);
}
}
- if (!processed_mark) {
- replace_numbered_mark(wms, 0, pfs_entry);
- }
- } else {
- const int idx = mark_global_index(entry.data.filemark.name);
- if (idx < 0) {
- ret = shada_pack_entry(packer, entry, 0);
- shada_free_shada_entry(&entry);
- break;
- }
- COMPARE_WITH_ENTRY(&wms->global_marks[idx], entry);
- }
- break;
- }
- case kSDItemChange:
- case kSDItemLocalMark: {
- if (shada_removable(entry.data.filemark.fname)) {
- shada_free_shada_entry(&entry);
- break;
+ *wms_entry = pfs_entry;
}
- const char *const fname = (const char *) entry.data.filemark.fname;
- khiter_t k;
- int kh_ret;
- k = kh_put(file_marks, &wms->file_marks, fname, &kh_ret);
- FileMarks *const filemarks = &kh_val(&wms->file_marks, k);
- if (kh_ret > 0) {
- memset(filemarks, 0, sizeof(*filemarks));
- }
- if (entry.timestamp > filemarks->greatest_timestamp) {
- filemarks->greatest_timestamp = entry.timestamp;
- }
- if (entry.type == kSDItemLocalMark) {
- const int idx = mark_local_index(entry.data.filemark.name);
- if (idx < 0) {
- filemarks->additional_marks = xrealloc(
- filemarks->additional_marks,
- (++filemarks->additional_marks_size
- * sizeof(filemarks->additional_marks[0])));
- filemarks->additional_marks[filemarks->additional_marks_size - 1] =
- entry;
- } else {
- PossiblyFreedShadaEntry *const wms_entry = &filemarks->marks[idx];
- if (wms_entry->data.type != kSDItemMissing) {
- if (wms_entry->data.timestamp >= entry.timestamp) {
- shada_free_shada_entry(&entry);
- break;
- }
- if (wms_entry->can_free_entry) {
- if (kh_key(&wms->file_marks, k)
- == wms_entry->data.data.filemark.fname) {
- kh_key(&wms->file_marks, k) = entry.data.filemark.fname;
- }
- shada_free_shada_entry(&wms_entry->data);
- }
- }
- *wms_entry = pfs_entry;
- }
- } else {
+ } else {
#define FREE_POSSIBLY_FREED_SHADA_ENTRY(entry) \
- do { \
- if (entry.can_free_entry) { \
- shada_free_shada_entry(&entry.data); \
- } \
- } while (0)
+ do { \
+ if (entry.can_free_entry) { \
+ shada_free_shada_entry(&entry.data); \
+ } \
+ } while (0)
#define SDE_TO_PFSDE(entry) \
- ((PossiblyFreedShadaEntry) { .can_free_entry = true, .data = entry })
+ ((PossiblyFreedShadaEntry) { .can_free_entry = true, .data = entry })
#define AFTERFREE_DUMMY(entry)
#define DUMMY_IDX_ADJ(i)
- MERGE_JUMPS(filemarks->changes_size, filemarks->changes,
- PossiblyFreedShadaEntry, data.timestamp,
- data.data.filemark.mark, entry, true,
- FREE_POSSIBLY_FREED_SHADA_ENTRY, SDE_TO_PFSDE,
- DUMMY_IDX_ADJ, AFTERFREE_DUMMY);
- }
- break;
- }
- case kSDItemJump: {
- MERGE_JUMPS(wms->jumps_size, wms->jumps, PossiblyFreedShadaEntry,
- data.timestamp, data.data.filemark.mark, entry,
- strcmp(jl_entry.data.data.filemark.fname,
- entry.data.filemark.fname) == 0,
+ MERGE_JUMPS(filemarks->changes_size, filemarks->changes,
+ PossiblyFreedShadaEntry, data.timestamp,
+ data.data.filemark.mark, entry, true,
FREE_POSSIBLY_FREED_SHADA_ENTRY, SDE_TO_PFSDE,
DUMMY_IDX_ADJ, AFTERFREE_DUMMY);
+ }
+ break;
+ }
+ case kSDItemJump:
+ MERGE_JUMPS(wms->jumps_size, wms->jumps, PossiblyFreedShadaEntry,
+ data.timestamp, data.data.filemark.mark, entry,
+ strcmp(jl_entry.data.data.filemark.fname,
+ entry.data.filemark.fname) == 0,
+ FREE_POSSIBLY_FREED_SHADA_ENTRY, SDE_TO_PFSDE,
+ DUMMY_IDX_ADJ, AFTERFREE_DUMMY);
#undef FREE_POSSIBLY_FREED_SHADA_ENTRY
#undef SDE_TO_PFSDE
#undef DUMMY_IDX_ADJ
#undef AFTERFREE_DUMMY
- break;
- }
+ break;
}
}
#undef COMPARE_WITH_ENTRY
@@ -2365,8 +2300,7 @@ static inline ShaDaWriteResult shada_read_when_writing(
/// @param[in] removable_bufs Cache of buffers ignored due to their location.
///
/// @return true or false.
-static inline bool ignore_buf(const buf_T *const buf,
- khash_t(bufset) *const removable_bufs)
+static inline bool ignore_buf(const buf_T *const buf, khash_t(bufset) *const removable_bufs)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_ALWAYS_INLINE
{
return (buf->b_ffname == NULL || !buf->b_p_bl || bt_quickfix(buf) \
@@ -2378,8 +2312,7 @@ static inline bool ignore_buf(const buf_T *const buf,
/// @param[in] removable_bufs Buffers which are ignored
///
/// @return ShadaEntry List of buffers to save, kSDItemBufferList entry.
-static inline ShadaEntry shada_get_buflist(
- khash_t(bufset) *const removable_bufs)
+static inline ShadaEntry shada_get_buflist(khash_t(bufset) *const removable_bufs)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_ALWAYS_INLINE
{
int max_bufs = get_shada_parameter('%');
@@ -2393,14 +2326,14 @@ static inline ShadaEntry shada_get_buflist(
ShadaEntry buflist_entry = (ShadaEntry) {
.type = kSDItemBufferList,
- .timestamp = os_time(),
- .data = {
- .buffer_list = {
- .size = buf_count,
- .buffers = xmalloc(buf_count
- * sizeof(*buflist_entry.data.buffer_list.buffers)),
- },
+ .timestamp = os_time(),
+ .data = {
+ .buffer_list = {
+ .size = buf_count,
+ .buffers = xmalloc(buf_count
+ * sizeof(*buflist_entry.data.buffer_list.buffers)),
},
+ },
};
size_t i = 0;
FOR_ALL_BUFFERS(buf) {
@@ -2412,8 +2345,8 @@ static inline ShadaEntry shada_get_buflist(
}
buflist_entry.data.buffer_list.buffers[i] = (struct buffer_list_buffer) {
.pos = buf->b_last_cursor.mark,
- .fname = (char *)buf->b_ffname,
- .additional_data = buf->additional_data,
+ .fname = (char *)buf->b_ffname,
+ .additional_data = buf->additional_data,
};
i++;
}
@@ -2435,8 +2368,7 @@ static inline ShadaEntry shada_get_buflist(
/// saved.
static inline void add_search_pattern(PossiblyFreedShadaEntry *const ret_pse,
const SearchPatternGetter get_pattern,
- const bool is_substitute_pattern,
- const bool search_last_used,
+ const bool is_substitute_pattern, const bool search_last_used,
const bool search_highlighted)
FUNC_ATTR_ALWAYS_INLINE
{
@@ -2457,7 +2389,7 @@ static inline void add_search_pattern(PossiblyFreedShadaEntry *const ret_pse,
? defaults.data.search_pattern.has_line_offset
: pat.off.line),
.place_cursor_at_end = (
- is_substitute_pattern
+ is_substitute_pattern
? defaults.data.search_pattern.place_cursor_at_end
: pat.off.end),
.offset = (is_substitute_pattern
@@ -2481,8 +2413,7 @@ static inline void add_search_pattern(PossiblyFreedShadaEntry *const ret_pse,
///
/// @param[in] wms The WriteMergerState used when writing.
/// @param[in] max_reg_lines The maximum number of register lines.
-static inline void shada_initialize_registers(WriteMergerState *const wms,
- int max_reg_lines)
+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;
@@ -2527,8 +2458,7 @@ static inline void shada_initialize_registers(WriteMergerState *const wms,
/// @param[out] wms Merger state to adjust.
/// @param[in] idx Index at which new mark should be placed.
/// @param[in] entry New mark.
-static inline void replace_numbered_mark(WriteMergerState *const wms,
- const size_t idx,
+static inline void replace_numbered_mark(WriteMergerState *const wms, const size_t idx,
const PossiblyFreedShadaEntry entry)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_ALWAYS_INLINE
{
@@ -2566,8 +2496,7 @@ static inline void find_removable_bufs(khash_t(bufset) *removable_bufs)
/// @param[in] sd_reader Structure containing file reader definition. If it is
/// not NULL then contents of this file will be merged
/// with current Neovim runtime.
-static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
- ShaDaReadDef *const sd_reader)
+static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, ShaDaReadDef *const sd_reader)
FUNC_ATTR_NONNULL_ARG(1)
{
ShaDaWriteResult ret = kSDWriteSuccessfull;
@@ -2588,8 +2517,8 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
}
const bool dump_registers = (max_reg_lines != 0);
khash_t(bufset) removable_bufs = KHASH_EMPTY_TABLE(bufset);
- const size_t max_kbyte = (size_t) max_kbyte_i;
- const size_t num_marked_files = (size_t) get_shada_parameter('\'');
+ const size_t max_kbyte = (size_t)max_kbyte_i;
+ const size_t num_marked_files = (size_t)get_shada_parameter('\'');
const bool dump_global_marks = get_shada_parameter('f') != 0;
bool dump_history = false;
@@ -2602,20 +2531,21 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
if (num_saved > 0) {
dump_history = true;
dump_one_history[i] = true;
- hms_init(&wms->hms[i], i, (size_t) num_saved, sd_reader != NULL, false);
+ hms_init(&wms->hms[i], i, (size_t)num_saved, sd_reader != NULL, false);
} else {
dump_one_history[i] = false;
}
}
- const unsigned srni_flags = (unsigned) (
- kSDReadUndisableableData
- | kSDReadUnknown
- | (dump_history ? kSDReadHistory : 0)
- | (dump_registers ? kSDReadRegisters : 0)
- | (dump_global_vars ? kSDReadVariables : 0)
- | (dump_global_marks ? kSDReadGlobalMarks : 0)
- | (num_marked_files ? kSDReadLocalMarks | kSDReadChanges : 0));
+ const unsigned srni_flags = (unsigned)(
+ kSDReadUndisableableData
+ | kSDReadUnknown
+ | (dump_history ? kSDReadHistory : 0)
+ | (dump_registers ? kSDReadRegisters : 0)
+ | (dump_global_vars ? kSDReadVariables : 0)
+ | (dump_global_marks ? kSDReadGlobalMarks : 0)
+ | (num_marked_files ? kSDReadLocalMarks |
+ kSDReadChanges : 0));
msgpack_packer *const packer = msgpack_packer_new(sd_writer,
&msgpack_sd_writer_write);
@@ -2645,11 +2575,11 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
{ STATIC_CSTR_AS_STRING("version"),
STRING_OBJ(cstr_as_string(longVersion)) },
{ STATIC_CSTR_AS_STRING("max_kbyte"),
- INTEGER_OBJ((Integer) max_kbyte) },
+ INTEGER_OBJ((Integer)max_kbyte) },
{ STATIC_CSTR_AS_STRING("pid"),
- INTEGER_OBJ((Integer) os_get_pid()) },
+ INTEGER_OBJ((Integer)os_get_pid()) },
{ STATIC_CSTR_AS_STRING("encoding"),
- STRING_OBJ(cstr_as_string((char *) p_enc)) },
+ STRING_OBJ(cstr_as_string((char *)p_enc)) },
}),
}
}
@@ -2681,34 +2611,32 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
break;
}
switch (vartv.v_type) {
- case VAR_FUNC:
- case VAR_PARTIAL:
+ case VAR_FUNC:
+ case VAR_PARTIAL:
+ tv_clear(&vartv);
+ continue;
+ case VAR_DICT: {
+ dict_T *di = vartv.vval.v_dict;
+ int copyID = get_copyID();
+ if (!set_ref_in_ht(&di->dv_hashtab, copyID, NULL)
+ && copyID == di->dv_copyID) {
tv_clear(&vartv);
continue;
- case VAR_DICT:
- {
- dict_T *di = vartv.vval.v_dict;
- int copyID = get_copyID();
- if (!set_ref_in_ht(&di->dv_hashtab, copyID, NULL)
- && copyID == di->dv_copyID) {
- tv_clear(&vartv);
- continue;
- }
- break;
- }
- case VAR_LIST:
- {
- list_T *l = vartv.vval.v_list;
- int copyID = get_copyID();
- if (!set_ref_in_list(l, copyID, NULL)
- && copyID == l->lv_copyID) {
- tv_clear(&vartv);
- continue;
- }
- break;
- }
- default:
- break;
+ }
+ break;
+ }
+ case VAR_LIST: {
+ list_T *l = vartv.vval.v_list;
+ int copyID = get_copyID();
+ if (!set_ref_in_list(l, copyID, NULL)
+ && copyID == l->lv_copyID) {
+ tv_clear(&vartv);
+ continue;
+ }
+ break;
+ }
+ default:
+ break;
}
typval_T tgttv;
tv_copy(&vartv, &tgttv);
@@ -2718,7 +2646,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
.timestamp = cur_timestamp,
.data = {
.global_var = {
- .name = (char *) name,
+ .name = (char *)name,
.value = tgttv,
.additional_elements = NULL,
}
@@ -2733,7 +2661,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
tv_clear(&tgttv);
if (spe_ret == kSDWriteSuccessfull) {
int kh_ret;
- (void) kh_put(strset, &wms->dumped_variables, name, &kh_ret);
+ (void)kh_put(strset, &wms->dumped_variables, name, &kh_ret);
}
} while (var_iter != NULL);
}
@@ -2766,7 +2694,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
.timestamp = sub.timestamp,
.data = {
.sub_string = {
- .sub = (char *) sub.sub,
+ .sub = (char *)sub.sub,
.additional_elements = sub.additional_elements,
}
}
@@ -2788,17 +2716,17 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
const char *fname;
if (fm.fmark.fnum == 0) {
assert(fm.fname != NULL);
- if (shada_removable((const char *) fm.fname)) {
+ if (shada_removable((const char *)fm.fname)) {
continue;
}
- fname = (const char *) fm.fname;
+ fname = (const char *)fm.fname;
} else {
const buf_T *const buf = buflist_findnr(fm.fmark.fnum);
if (buf == NULL || buf->b_ffname == NULL
|| in_bufset(&removable_bufs, buf)) {
continue;
}
- fname = (const char *) buf->b_ffname;
+ fname = (const char *)buf->b_ffname;
}
const PossiblyFreedShadaEntry pf_entry = {
.can_free_entry = false,
@@ -2835,7 +2763,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
continue;
}
const void *local_marks_iter = NULL;
- const char *const fname = (const char *) buf->b_ffname;
+ const char *const fname = (const char *)buf->b_ffname;
khiter_t k;
int kh_ret;
k = kh_put(file_marks, &wms->file_marks, fname, &kh_ret);
@@ -2859,7 +2787,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
.filemark = {
.mark = fm.mark,
.name = name,
- .fname = (char *) fname,
+ .fname = (char *)fname,
.additional_data = fm.additional_data,
}
}
@@ -2879,7 +2807,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
.data = {
.filemark = {
.mark = fm.mark,
- .fname = (char *) fname,
+ .fname = (char *)fname,
.additional_data = fm.additional_data,
}
}
@@ -2889,13 +2817,13 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
filemarks->greatest_timestamp = fm.timestamp;
}
}
- filemarks->changes_size = (size_t) buf->b_changelistlen;
+ filemarks->changes_size = (size_t)buf->b_changelistlen;
}
}
if (sd_reader != NULL) {
- const ShaDaWriteResult srww_ret = shada_read_when_writing(
- sd_reader, srni_flags, max_kbyte, wms, packer);
+ const ShaDaWriteResult srww_ret = shada_read_when_writing(sd_reader, srni_flags, max_kbyte, wms,
+ packer);
if (srww_ret != kSDWriteSuccessfull) {
ret = srww_ret;
}
@@ -2961,7 +2889,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
const size_t file_markss_size = kh_size(&wms->file_marks);
FileMarks **const all_file_markss =
- xmalloc(file_markss_size * sizeof(*all_file_markss));
+ xmalloc(file_markss_size * sizeof(*all_file_markss));
FileMarks **cur_file_marks = all_file_markss;
for (khint_t i = kh_begin(&wms->file_marks); i != kh_end(&wms->file_marks);
i++) {
@@ -2969,7 +2897,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
*cur_file_marks++ = &kh_val(&wms->file_marks, i);
}
}
- qsort((void *) all_file_markss, file_markss_size, sizeof(*all_file_markss),
+ qsort((void *)all_file_markss, file_markss_size, sizeof(*all_file_markss),
&compare_file_marks);
const size_t file_markss_to_dump = MIN(num_marked_files, file_markss_size);
for (size_t i = 0; i < file_markss_to_dump; i++) {
@@ -3000,11 +2928,10 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
if (dump_one_history[i]) {
hms_insert_whole_neovim_history(&wms->hms[i]);
HMS_ITER(&wms->hms[i], cur_entry, {
- if (shada_pack_pfreed_entry(
- packer, (PossiblyFreedShadaEntry) {
- .data = cur_entry->data,
- .can_free_entry = cur_entry->can_free_entry,
- }, max_kbyte) == kSDWriteFailed) {
+ if (shada_pack_pfreed_entry(packer, (PossiblyFreedShadaEntry) {
+ .data = cur_entry->data,
+ .can_free_entry = cur_entry->can_free_entry,
+ }, max_kbyte) == kSDWriteFailed) {
ret = kSDWriteFailed;
break;
}
@@ -3075,7 +3002,7 @@ int shada_write_file(const char *const file, bool nomerge)
}
// Save permissions from the original file, with modifications:
- int perm = (int) os_getperm(fname);
+ int perm = (int)os_getperm(fname);
perm = (perm >= 0) ? ((perm & 0777) | 0600) : 0600;
// ^3 ^1 ^2 ^2,3
// 1: Strip SUID bit if any.
@@ -3083,8 +3010,7 @@ int shada_write_file(const char *const file, bool nomerge)
// 3: If somebody happened to delete the file after it was opened for
// reading use u=rw permissions.
shada_write_file_open: {}
- sd_writer.cookie = file_open_new(
- &error, tempname, kFileCreateOnly|kFileNoSymlink, perm);
+ sd_writer.cookie = file_open_new(&error, tempname, kFileCreateOnly|kFileNoSymlink, perm);
if (sd_writer.cookie == NULL) {
if (error == UV_EEXIST || error == UV_ELOOP) {
// File already exists, try another name
@@ -3237,8 +3163,7 @@ int shada_read_marks(void)
/// @param[in] missing_ok If true, do not error out when file is missing.
///
/// @return OK in case of success, FAIL otherwise.
-int shada_read_everything(const char *const fname, const bool forceit,
- const bool missing_ok)
+int shada_read_everything(const char *const fname, const bool forceit, const bool missing_ok)
{
return shada_read_file(fname,
kShaDaWantInfo|kShaDaWantMarks|kShaDaGetOldfiles
@@ -3252,81 +3177,71 @@ static void shada_free_shada_entry(ShadaEntry *const entry)
return;
}
switch (entry->type) {
- case kSDItemMissing: {
- break;
- }
- case kSDItemUnknown: {
- xfree(entry->data.unknown_item.contents);
- break;
- }
- case kSDItemHeader: {
- api_free_dictionary(entry->data.header);
- break;
- }
- case kSDItemChange:
- case kSDItemJump:
- case kSDItemGlobalMark:
- case kSDItemLocalMark: {
- tv_dict_unref(entry->data.filemark.additional_data);
- xfree(entry->data.filemark.fname);
- break;
- }
- case kSDItemSearchPattern: {
- tv_dict_unref(entry->data.search_pattern.additional_data);
- xfree(entry->data.search_pattern.pat);
- break;
- }
- case kSDItemRegister: {
- tv_dict_unref(entry->data.reg.additional_data);
- for (size_t i = 0; i < entry->data.reg.contents_size; i++) {
- xfree(entry->data.reg.contents[i]);
- }
- xfree(entry->data.reg.contents);
- break;
+ case kSDItemMissing:
+ break;
+ case kSDItemUnknown:
+ xfree(entry->data.unknown_item.contents);
+ break;
+ case kSDItemHeader:
+ api_free_dictionary(entry->data.header);
+ break;
+ case kSDItemChange:
+ case kSDItemJump:
+ case kSDItemGlobalMark:
+ case kSDItemLocalMark:
+ tv_dict_unref(entry->data.filemark.additional_data);
+ xfree(entry->data.filemark.fname);
+ break;
+ case kSDItemSearchPattern:
+ tv_dict_unref(entry->data.search_pattern.additional_data);
+ xfree(entry->data.search_pattern.pat);
+ break;
+ case kSDItemRegister:
+ tv_dict_unref(entry->data.reg.additional_data);
+ for (size_t i = 0; i < entry->data.reg.contents_size; i++) {
+ xfree(entry->data.reg.contents[i]);
}
- case kSDItemHistoryEntry: {
- tv_list_unref(entry->data.history_item.additional_elements);
- xfree(entry->data.history_item.string);
- break;
- }
- case kSDItemVariable: {
- tv_list_unref(entry->data.global_var.additional_elements);
- xfree(entry->data.global_var.name);
- tv_clear(&entry->data.global_var.value);
- break;
- }
- case kSDItemSubString: {
- tv_list_unref(entry->data.sub_string.additional_elements);
- xfree(entry->data.sub_string.sub);
- break;
- }
- case kSDItemBufferList: {
- for (size_t i = 0; i < entry->data.buffer_list.size; i++) {
- xfree(entry->data.buffer_list.buffers[i].fname);
- tv_dict_unref(entry->data.buffer_list.buffers[i].additional_data);
- }
- xfree(entry->data.buffer_list.buffers);
- break;
+ xfree(entry->data.reg.contents);
+ break;
+ case kSDItemHistoryEntry:
+ tv_list_unref(entry->data.history_item.additional_elements);
+ xfree(entry->data.history_item.string);
+ break;
+ case kSDItemVariable:
+ tv_list_unref(entry->data.global_var.additional_elements);
+ xfree(entry->data.global_var.name);
+ tv_clear(&entry->data.global_var.value);
+ break;
+ case kSDItemSubString:
+ tv_list_unref(entry->data.sub_string.additional_elements);
+ xfree(entry->data.sub_string.sub);
+ break;
+ case kSDItemBufferList:
+ for (size_t i = 0; i < entry->data.buffer_list.size; i++) {
+ xfree(entry->data.buffer_list.buffers[i].fname);
+ tv_dict_unref(entry->data.buffer_list.buffers[i].additional_data);
}
+ xfree(entry->data.buffer_list.buffers);
+ break;
}
}
#ifndef HAVE_BE64TOH
static inline uint64_t be64toh(uint64_t big_endian_64_bits)
{
-#ifdef ORDER_BIG_ENDIAN
+# ifdef ORDER_BIG_ENDIAN
return big_endian_64_bits;
-#else
+# else
// It may appear that when !defined(ORDER_BIG_ENDIAN) actual order is big
// endian. This variant is suboptimal, but it works regardless of actual
// order.
- uint8_t *buf = (uint8_t *) &big_endian_64_bits;
+ uint8_t *buf = (uint8_t *)&big_endian_64_bits;
uint64_t ret = 0;
for (size_t i = 8; i; i--) {
- ret |= ((uint64_t) buf[i - 1]) << ((8 - i) * 8);
+ ret |= ((uint64_t)buf[i - 1]) << ((8 - i) * 8);
}
return ret;
-#endif
+# endif
}
#endif
@@ -3339,8 +3254,7 @@ static inline uint64_t be64toh(uint64_t big_endian_64_bits)
/// @return kSDReadStatusSuccess if everything was OK, kSDReadStatusNotShaDa if
/// there were not enough bytes to read or kSDReadStatusReadError if
/// there was some error while reading.
-static ShaDaReadResult fread_len(ShaDaReadDef *const sd_reader,
- char *const buffer,
+static ShaDaReadResult fread_len(ShaDaReadDef *const sd_reader, char *const buffer,
const size_t length)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
@@ -3378,8 +3292,7 @@ static ShaDaReadResult fread_len(ShaDaReadDef *const sd_reader,
/// @return kSDReadStatusSuccess if reading was successful,
/// kSDReadStatusNotShaDa if there were not enough bytes to read or
/// kSDReadStatusReadError if reading failed for whatever reason.
-static ShaDaReadResult msgpack_read_uint64(ShaDaReadDef *const sd_reader,
- const int first_char,
+static ShaDaReadResult msgpack_read_uint64(ShaDaReadDef *const sd_reader, const int first_char,
uint64_t *const result)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
@@ -3394,42 +3307,37 @@ static ShaDaReadResult msgpack_read_uint64(ShaDaReadDef *const sd_reader,
emsgf(_(RCERR "Error while reading ShaDa file: "
"expected positive integer at position %" PRIu64
", but got nothing"),
- (uint64_t) fpos);
+ (uint64_t)fpos);
return kSDReadStatusNotShaDa;
}
}
if (~first_char & 0x80) {
// Positive fixnum
- *result = (uint64_t) ((uint8_t) first_char);
+ *result = (uint64_t)((uint8_t)first_char);
} else {
size_t length = 0;
switch (first_char) {
- case 0xCC: { // uint8
- length = 1;
- break;
- }
- case 0xCD: { // uint16
- length = 2;
- break;
- }
- case 0xCE: { // uint32
- length = 4;
- break;
- }
- case 0xCF: { // uint64
- length = 8;
- break;
- }
- default: {
- emsgf(_(RCERR "Error while reading ShaDa file: "
- "expected positive integer at position %" PRIu64),
- (uint64_t) fpos);
- return kSDReadStatusNotShaDa;
- }
+ case 0xCC: // uint8
+ length = 1;
+ break;
+ case 0xCD: // uint16
+ length = 2;
+ break;
+ case 0xCE: // uint32
+ length = 4;
+ break;
+ case 0xCF: // uint64
+ length = 8;
+ break;
+ default:
+ emsgf(_(RCERR "Error while reading ShaDa file: "
+ "expected positive integer at position %" PRIu64),
+ (uint64_t)fpos);
+ return kSDReadStatusNotShaDa;
}
uint64_t buf = 0;
- char *buf_u8 = (char *) &buf;
+ char *buf_u8 = (char *)&buf;
ShaDaReadResult fl_ret;
if ((fl_ret = fread_len(sd_reader, &(buf_u8[sizeof(buf)-length]), length))
!= kSDReadStatusSuccess) {
@@ -3441,24 +3349,24 @@ static ShaDaReadResult msgpack_read_uint64(ShaDaReadDef *const sd_reader,
}
#define READERR(entry_name, error_desc) \
- RERR "Error while reading ShaDa file: " \
- entry_name " entry at position %" PRIu64 " " \
- error_desc
+ RERR "Error while reading ShaDa file: " \
+ entry_name " entry at position %" PRIu64 " " \
+ error_desc
#define CHECK_KEY(key, expected) ( \
- key.via.str.size == sizeof(expected) - 1 \
- && STRNCMP(key.via.str.ptr, expected, sizeof(expected) - 1) == 0)
+ key.via.str.size == sizeof(expected) - 1 \
+ && STRNCMP(key.via.str.ptr, expected, sizeof(expected) - 1) == 0)
#define CLEAR_GA_AND_ERROR_OUT(ga) \
- do { \
- ga_clear(&ga); \
- goto shada_read_next_item_error; \
- } while (0)
+ do { \
+ ga_clear(&ga); \
+ goto shada_read_next_item_error; \
+ } while (0)
#define ID(s) s
#define BINDUP(b) xmemdupz(b.ptr, b.size)
-#define TOINT(s) ((int) (s))
-#define TOLONG(s) ((long) (s))
-#define TOCHAR(s) ((char) (s))
-#define TOU8(s) ((uint8_t) (s))
-#define TOSIZE(s) ((size_t) (s))
+#define TOINT(s) ((int)(s))
+#define TOLONG(s) ((long)(s))
+#define TOCHAR(s) ((char)(s))
+#define TOU8(s) ((uint8_t)(s))
+#define TOSIZE(s) ((size_t)(s))
#define CHECKED_ENTRY(condition, error_desc, entry_name, obj, tgt, attr, \
proc) \
do { \
@@ -3479,18 +3387,16 @@ static ShaDaReadResult msgpack_read_uint64(ShaDaReadDef *const sd_reader,
}
#define CHECKED_KEY(un, entry_name, name, error_desc, tgt, condition, attr, \
proc) \
- else if (CHECK_KEY( /* NOLINT(readability/braces) */ \
- un.data.via.map.ptr[i].key, name)) { \
- CHECKED_ENTRY( \
- condition, "has " name " key value " error_desc, \
- entry_name, un.data.via.map.ptr[i].val, \
- tgt, attr, proc); \
+ else if (CHECK_KEY( /* NOLINT(readability/braces) */ \
+ un.data.via.map.ptr[i].key, name)) { \
+ CHECKED_ENTRY(condition, "has " name " key value " error_desc, \
+ entry_name, un.data.via.map.ptr[i].val, \
+ tgt, attr, proc); \
}
#define TYPED_KEY(un, entry_name, name, type_name, tgt, objtype, attr, proc) \
- CHECKED_KEY( \
- un, entry_name, name, "which is not " type_name, tgt, \
- un.data.via.map.ptr[i].val.type == MSGPACK_OBJECT_##objtype, \
- attr, proc)
+ CHECKED_KEY(un, entry_name, name, "which is not " type_name, tgt, \
+ un.data.via.map.ptr[i].val.type == MSGPACK_OBJECT_##objtype, \
+ attr, proc)
#define BOOLEAN_KEY(un, entry_name, name, tgt) \
TYPED_KEY(un, entry_name, name, "a boolean", tgt, BOOLEAN, boolean, ID)
#define STRING_KEY(un, entry_name, name, tgt) \
@@ -3499,19 +3405,18 @@ static ShaDaReadResult msgpack_read_uint64(ShaDaReadDef *const sd_reader,
TYPED_KEY(un, entry_name, name, "a binary", tgt, BIN, bin, \
BIN_CONVERTED)
#define INT_KEY(un, entry_name, name, tgt, proc) \
- CHECKED_KEY( \
- un, entry_name, name, "which is not an integer", tgt, \
- ((un.data.via.map.ptr[i].val.type \
- == MSGPACK_OBJECT_POSITIVE_INTEGER) \
- || (un.data.via.map.ptr[i].val.type \
- == MSGPACK_OBJECT_NEGATIVE_INTEGER)), \
- i64, proc)
+ CHECKED_KEY(un, entry_name, name, "which is not an integer", tgt, \
+ ((un.data.via.map.ptr[i].val.type \
+ == MSGPACK_OBJECT_POSITIVE_INTEGER) \
+ || (un.data.via.map.ptr[i].val.type \
+ == MSGPACK_OBJECT_NEGATIVE_INTEGER)), \
+ i64, proc)
#define INTEGER_KEY(un, entry_name, name, tgt) \
INT_KEY(un, entry_name, name, tgt, TOINT)
#define LONG_KEY(un, entry_name, name, tgt) \
INT_KEY(un, entry_name, name, tgt, TOLONG)
#define ADDITIONAL_KEY(un) \
- else { /* NOLINT(readability/braces) */ \
+ else { /* NOLINT(readability/braces) */ \
ga_grow(&ad_ga, 1); \
memcpy(((char *)ad_ga.ga_data) + ((size_t)ad_ga.ga_len \
* sizeof(*un.data.via.map.ptr)), \
@@ -3522,54 +3427,54 @@ static ShaDaReadResult msgpack_read_uint64(ShaDaReadDef *const sd_reader,
#define CONVERTED(str, len) (xmemdupz((str), (len)))
#define BIN_CONVERTED(b) CONVERTED(b.ptr, b.size)
#define SET_ADDITIONAL_DATA(tgt, name) \
- do { \
- if (ad_ga.ga_len) { \
- msgpack_object obj = { \
- .type = MSGPACK_OBJECT_MAP, \
- .via = { \
- .map = { \
- .size = (uint32_t) ad_ga.ga_len, \
- .ptr = ad_ga.ga_data, \
- } \
- } \
- }; \
- typval_T adtv; \
- if (msgpack_to_vim(obj, &adtv) == FAIL \
- || adtv.v_type != VAR_DICT) { \
- emsgf(_(READERR(name, \
- "cannot be converted to a VimL dictionary")), \
- initial_fpos); \
- ga_clear(&ad_ga); \
- tv_clear(&adtv); \
- goto shada_read_next_item_error; \
+ do { \
+ if (ad_ga.ga_len) { \
+ msgpack_object obj = { \
+ .type = MSGPACK_OBJECT_MAP, \
+ .via = { \
+ .map = { \
+ .size = (uint32_t)ad_ga.ga_len, \
+ .ptr = ad_ga.ga_data, \
} \
- tgt = adtv.vval.v_dict; \
} \
+ }; \
+ typval_T adtv; \
+ if (msgpack_to_vim(obj, &adtv) == FAIL \
+ || adtv.v_type != VAR_DICT) { \
+ emsgf(_(READERR(name, \
+ "cannot be converted to a VimL dictionary")), \
+ initial_fpos); \
ga_clear(&ad_ga); \
- } while (0)
+ tv_clear(&adtv); \
+ goto shada_read_next_item_error; \
+ } \
+ tgt = adtv.vval.v_dict; \
+ } \
+ ga_clear(&ad_ga); \
+ } while (0)
#define SET_ADDITIONAL_ELEMENTS(src, src_maxsize, tgt, name) \
- do { \
- if ((src).size > (size_t) (src_maxsize)) { \
- msgpack_object obj = { \
- .type = MSGPACK_OBJECT_ARRAY, \
- .via = { \
- .array = { \
- .size = ((src).size - (uint32_t) (src_maxsize)), \
- .ptr = (src).ptr + (src_maxsize), \
- } \
- } \
- }; \
- typval_T aetv; \
- if (msgpack_to_vim(obj, &aetv) == FAIL) { \
- emsgf(_(READERR(name, "cannot be converted to a VimL list")), \
- initial_fpos); \
- tv_clear(&aetv); \
- goto shada_read_next_item_error; \
+ do { \
+ if ((src).size > (size_t)(src_maxsize)) { \
+ msgpack_object obj = { \
+ .type = MSGPACK_OBJECT_ARRAY, \
+ .via = { \
+ .array = { \
+ .size = ((src).size - (uint32_t)(src_maxsize)), \
+ .ptr = (src).ptr + (src_maxsize), \
} \
- assert(aetv.v_type == VAR_LIST); \
- (tgt) = aetv.vval.v_list; \
} \
- } while (0)
+ }; \
+ typval_T aetv; \
+ if (msgpack_to_vim(obj, &aetv) == FAIL) { \
+ emsgf(_(READERR(name, "cannot be converted to a VimL list")), \
+ initial_fpos); \
+ tv_clear(&aetv); \
+ goto shada_read_next_item_error; \
+ } \
+ assert(aetv.v_type == VAR_LIST); \
+ (tgt) = aetv.vval.v_list; \
+ } \
+ } while (0)
/// Iterate over shada file contents
///
@@ -3581,10 +3486,8 @@ static ShaDaReadResult msgpack_read_uint64(ShaDaReadDef *const sd_reader,
/// greater then given.
///
/// @return Any value from ShaDaReadResult enum.
-static ShaDaReadResult shada_read_next_item(ShaDaReadDef *const sd_reader,
- ShadaEntry *const entry,
- const unsigned flags,
- const size_t max_kbyte)
+static ShaDaReadResult shada_read_next_item(ShaDaReadDef *const sd_reader, ShadaEntry *const entry,
+ const unsigned flags, const size_t max_kbyte)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
ShaDaReadResult ret = kSDReadStatusMalformed;
@@ -3600,11 +3503,11 @@ shada_read_next_item_start:
// First: manually unpack type, timestamp and length.
// This is needed to avoid both seeking and having to maintain a buffer.
- uint64_t type_u64 = (uint64_t) kSDItemMissing;
+ uint64_t type_u64 = (uint64_t)kSDItemMissing;
uint64_t timestamp_u64;
uint64_t length_u64;
- const uint64_t initial_fpos = (uint64_t) sd_reader->fpos;
+ const uint64_t initial_fpos = (uint64_t)sd_reader->fpos;
const int first_char = read_char(sd_reader);
if (first_char == EOF && sd_reader->eof) {
return kSDReadStatusFinished;
@@ -3647,7 +3550,7 @@ shada_read_next_item_start:
if ((type_u64 > SHADA_LAST_ENTRY
? !(flags & kSDReadUnknown)
- : !((unsigned) (1 << type_u64) & flags))
+ : !((unsigned)(1 << type_u64) & flags))
|| (max_kbyte && length > max_kbyte * 1024)) {
// First entry is unknown or equal to "\n" (10)? Most likely this means that
// current file is not a ShaDa file because first item should normally be
@@ -3675,16 +3578,16 @@ shada_read_next_item_start:
entry->data.unknown_item.size = length;
entry->data.unknown_item.type = type_u64;
if (initial_fpos == 0) {
- const ShaDaReadResult spm_ret = shada_parse_msgpack(
- sd_reader, length, NULL, &entry->data.unknown_item.contents);
+ const ShaDaReadResult spm_ret = shada_parse_msgpack(sd_reader, length, NULL,
+ &entry->data.unknown_item.contents);
if (spm_ret != kSDReadStatusSuccess) {
entry->type = kSDItemMissing;
}
return spm_ret;
} else {
entry->data.unknown_item.contents = xmalloc(length);
- const ShaDaReadResult fl_ret = fread_len(
- sd_reader, entry->data.unknown_item.contents, length);
+ const ShaDaReadResult fl_ret =
+ fread_len(sd_reader, entry->data.unknown_item.contents, length);
if (fl_ret != kSDReadStatusSuccess) {
shada_free_shada_entry(entry);
entry->type = kSDItemMissing;
@@ -3704,350 +3607,367 @@ shada_read_next_item_start:
}
ret = kSDReadStatusMalformed;
entry->data = sd_default_values[type_u64].data;
- switch ((ShadaEntryType) type_u64) {
- case kSDItemHeader: {
- if (!msgpack_rpc_to_dictionary(&(unpacked.data), &(entry->data.header))) {
- emsgf(_(READERR("header", "is not a dictionary")), initial_fpos);
- goto shada_read_next_item_error;
- }
- break;
+ switch ((ShadaEntryType)type_u64) {
+ case kSDItemHeader:
+ if (!msgpack_rpc_to_dictionary(&(unpacked.data), &(entry->data.header))) {
+ emsgf(_(READERR("header", "is not a dictionary")), initial_fpos);
+ goto shada_read_next_item_error;
}
- case kSDItemSearchPattern: {
- if (unpacked.data.type != MSGPACK_OBJECT_MAP) {
- emsgf(_(READERR("search pattern", "is not a dictionary")),
- initial_fpos);
- goto shada_read_next_item_error;
- }
- garray_T ad_ga;
- ga_init(&ad_ga, sizeof(*(unpacked.data.via.map.ptr)), 1);
- for (size_t i = 0; i < unpacked.data.via.map.size; i++) {
- CHECK_KEY_IS_STR(unpacked, "search pattern")
- BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_MAGIC,
- entry->data.search_pattern.magic)
- BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_SMARTCASE,
- entry->data.search_pattern.smartcase)
- BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_HAS_LINE_OFFSET,
- entry->data.search_pattern.has_line_offset)
- BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_PLACE_CURSOR_AT_END,
- entry->data.search_pattern.place_cursor_at_end)
- BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_IS_LAST_USED,
- entry->data.search_pattern.is_last_used)
- BOOLEAN_KEY(unpacked, "search pattern",
- SEARCH_KEY_IS_SUBSTITUTE_PATTERN,
- entry->data.search_pattern.is_substitute_pattern)
- BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_HIGHLIGHTED,
- entry->data.search_pattern.highlighted)
- BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_BACKWARD,
- entry->data.search_pattern.search_backward)
- INTEGER_KEY(unpacked, "search pattern", SEARCH_KEY_OFFSET,
- entry->data.search_pattern.offset)
- CONVERTED_STRING_KEY(unpacked, "search pattern", SEARCH_KEY_PAT,
- entry->data.search_pattern.pat)
- ADDITIONAL_KEY(unpacked)
- }
- if (entry->data.search_pattern.pat == NULL) {
- emsgf(_(READERR("search pattern", "has no pattern")), initial_fpos);
- CLEAR_GA_AND_ERROR_OUT(ad_ga);
- }
- SET_ADDITIONAL_DATA(entry->data.search_pattern.additional_data,
- "search pattern");
- break;
+ break;
+ case kSDItemSearchPattern: {
+ if (unpacked.data.type != MSGPACK_OBJECT_MAP) {
+ emsgf(_(READERR("search pattern", "is not a dictionary")),
+ initial_fpos);
+ goto shada_read_next_item_error;
}
- case kSDItemChange:
- case kSDItemJump:
- case kSDItemGlobalMark:
- case kSDItemLocalMark: {
- if (unpacked.data.type != MSGPACK_OBJECT_MAP) {
- emsgf(_(READERR("mark", "is not a dictionary")), initial_fpos);
- goto shada_read_next_item_error;
- }
- garray_T ad_ga;
- ga_init(&ad_ga, sizeof(*(unpacked.data.via.map.ptr)), 1);
- for (size_t i = 0; i < unpacked.data.via.map.size; i++) {
- CHECK_KEY_IS_STR(unpacked, "mark")
- if (CHECK_KEY(unpacked.data.via.map.ptr[i].key, KEY_NAME_CHAR)) {
- if (type_u64 == kSDItemJump || type_u64 == kSDItemChange) {
- emsgf(_(READERR("mark", "has n key which is only valid for "
- "local and global mark entries")), initial_fpos);
- CLEAR_GA_AND_ERROR_OUT(ad_ga);
- }
- CHECKED_ENTRY(
- (unpacked.data.via.map.ptr[i].val.type
- == MSGPACK_OBJECT_POSITIVE_INTEGER),
- "has n key value which is not an unsigned integer",
- "mark", unpacked.data.via.map.ptr[i].val,
- entry->data.filemark.name, u64, TOCHAR);
+ garray_T ad_ga;
+ ga_init(&ad_ga, sizeof(*(unpacked.data.via.map.ptr)), 1);
+ for (size_t i = 0; i < unpacked.data.via.map.size; i++) {
+ CHECK_KEY_IS_STR(unpacked, "search pattern")
+ BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_MAGIC,
+ entry->data.search_pattern.magic)
+ BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_SMARTCASE,
+ entry->data.search_pattern.smartcase)
+ BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_HAS_LINE_OFFSET,
+ entry->data.search_pattern.has_line_offset)
+ BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_PLACE_CURSOR_AT_END,
+ entry->data.search_pattern.place_cursor_at_end)
+ BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_IS_LAST_USED,
+ entry->data.search_pattern.is_last_used)
+ BOOLEAN_KEY(unpacked, "search pattern",
+ SEARCH_KEY_IS_SUBSTITUTE_PATTERN,
+ entry->data.search_pattern.is_substitute_pattern)
+ BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_HIGHLIGHTED,
+ entry->data.search_pattern.highlighted)
+ BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_BACKWARD,
+ entry->data.search_pattern.search_backward)
+ INTEGER_KEY(unpacked, "search pattern", SEARCH_KEY_OFFSET,
+ entry->data.search_pattern.offset)
+ CONVERTED_STRING_KEY(unpacked, "search pattern", SEARCH_KEY_PAT,
+ entry->data.search_pattern.pat)
+ ADDITIONAL_KEY(unpacked)
+ }
+ if (entry->data.search_pattern.pat == NULL) {
+ emsgf(_(READERR("search pattern", "has no pattern")), initial_fpos);
+ CLEAR_GA_AND_ERROR_OUT(ad_ga);
+ }
+ SET_ADDITIONAL_DATA(entry->data.search_pattern.additional_data,
+ "search pattern");
+ break;
+ }
+ case kSDItemChange:
+ case kSDItemJump:
+ case kSDItemGlobalMark:
+ case kSDItemLocalMark: {
+ if (unpacked.data.type != MSGPACK_OBJECT_MAP) {
+ emsgf(_(READERR("mark", "is not a dictionary")), initial_fpos);
+ goto shada_read_next_item_error;
+ }
+ garray_T ad_ga;
+ ga_init(&ad_ga, sizeof(*(unpacked.data.via.map.ptr)), 1);
+ for (size_t i = 0; i < unpacked.data.via.map.size; i++) {
+ CHECK_KEY_IS_STR(unpacked, "mark")
+ if (CHECK_KEY(unpacked.data.via.map.ptr[i].key, KEY_NAME_CHAR)) {
+ if (type_u64 == kSDItemJump || type_u64 == kSDItemChange) {
+ emsgf(_(READERR("mark", "has n key which is only valid for "
+ "local and global mark entries")), initial_fpos);
+ CLEAR_GA_AND_ERROR_OUT(ad_ga);
}
- LONG_KEY(unpacked, "mark", KEY_LNUM, entry->data.filemark.mark.lnum)
- INTEGER_KEY(unpacked, "mark", KEY_COL, entry->data.filemark.mark.col)
- STRING_KEY(unpacked, "mark", KEY_FILE, entry->data.filemark.fname)
- ADDITIONAL_KEY(unpacked)
- }
- if (entry->data.filemark.fname == NULL) {
- emsgf(_(READERR("mark", "is missing file name")), initial_fpos);
- CLEAR_GA_AND_ERROR_OUT(ad_ga);
- }
- if (entry->data.filemark.mark.lnum <= 0) {
- emsgf(_(READERR("mark", "has invalid line number")), initial_fpos);
- CLEAR_GA_AND_ERROR_OUT(ad_ga);
+ CHECKED_ENTRY((unpacked.data.via.map.ptr[i].val.type
+ == MSGPACK_OBJECT_POSITIVE_INTEGER),
+ "has n key value which is not an unsigned integer",
+ "mark", unpacked.data.via.map.ptr[i].val,
+ entry->data.filemark.name, u64, TOCHAR);
}
- if (entry->data.filemark.mark.col < 0) {
- emsgf(_(READERR("mark", "has invalid column number")), initial_fpos);
- CLEAR_GA_AND_ERROR_OUT(ad_ga);
- }
- SET_ADDITIONAL_DATA(entry->data.filemark.additional_data, "mark");
- break;
+ LONG_KEY(unpacked, "mark", KEY_LNUM, entry->data.filemark.mark.lnum)
+ INTEGER_KEY(unpacked, "mark", KEY_COL, entry->data.filemark.mark.col)
+ STRING_KEY(unpacked, "mark", KEY_FILE, entry->data.filemark.fname)
+ ADDITIONAL_KEY(unpacked)
}
- case kSDItemRegister: {
- if (unpacked.data.type != MSGPACK_OBJECT_MAP) {
- emsgf(_(READERR("register", "is not a dictionary")), initial_fpos);
- goto shada_read_next_item_error;
- }
- garray_T ad_ga;
- ga_init(&ad_ga, sizeof(*(unpacked.data.via.map.ptr)), 1);
- for (size_t i = 0; i < unpacked.data.via.map.size; i++) {
- CHECK_KEY_IS_STR(unpacked, "register")
- if (CHECK_KEY(unpacked.data.via.map.ptr[i].key,
- REG_KEY_CONTENTS)) {
- if (unpacked.data.via.map.ptr[i].val.type != MSGPACK_OBJECT_ARRAY) {
- emsgf(_(READERR("register",
- "has " REG_KEY_CONTENTS
- " key with non-array value")),
- initial_fpos);
- CLEAR_GA_AND_ERROR_OUT(ad_ga);
- }
- if (unpacked.data.via.map.ptr[i].val.via.array.size == 0) {
- emsgf(_(READERR("register",
- "has " REG_KEY_CONTENTS " key with empty array")),
- initial_fpos);
+ if (entry->data.filemark.fname == NULL) {
+ emsgf(_(READERR("mark", "is missing file name")), initial_fpos);
+ CLEAR_GA_AND_ERROR_OUT(ad_ga);
+ }
+ if (entry->data.filemark.mark.lnum <= 0) {
+ emsgf(_(READERR("mark", "has invalid line number")), initial_fpos);
+ CLEAR_GA_AND_ERROR_OUT(ad_ga);
+ }
+ if (entry->data.filemark.mark.col < 0) {
+ emsgf(_(READERR("mark", "has invalid column number")), initial_fpos);
+ CLEAR_GA_AND_ERROR_OUT(ad_ga);
+ }
+ SET_ADDITIONAL_DATA(entry->data.filemark.additional_data, "mark");
+ break;
+ }
+ case kSDItemRegister: {
+ if (unpacked.data.type != MSGPACK_OBJECT_MAP) {
+ emsgf(_(READERR("register", "is not a dictionary")), initial_fpos);
+ goto shada_read_next_item_error;
+ }
+ garray_T ad_ga;
+ ga_init(&ad_ga, sizeof(*(unpacked.data.via.map.ptr)), 1);
+ for (size_t i = 0; i < unpacked.data.via.map.size; i++) {
+ CHECK_KEY_IS_STR(unpacked, "register")
+ if (CHECK_KEY(unpacked.data.via.map.ptr[i].key,
+ REG_KEY_CONTENTS)) {
+ if (unpacked.data.via.map.ptr[i].val.type != MSGPACK_OBJECT_ARRAY) {
+ emsgf(_(READERR("register",
+ "has " REG_KEY_CONTENTS
+ " key with non-array value")),
+ initial_fpos);
+ CLEAR_GA_AND_ERROR_OUT(ad_ga);
+ }
+ if (unpacked.data.via.map.ptr[i].val.via.array.size == 0) {
+ emsgf(_(READERR("register",
+ "has " REG_KEY_CONTENTS " key with empty array")),
+ initial_fpos);
+ CLEAR_GA_AND_ERROR_OUT(ad_ga);
+ }
+ const msgpack_object_array arr =
+ unpacked.data.via.map.ptr[i].val.via.array;
+ for (size_t j = 0; j < arr.size; j++) {
+ if (arr.ptr[j].type != MSGPACK_OBJECT_BIN) {
+ emsgf(_(READERR("register", "has " REG_KEY_CONTENTS " array "
+ "with non-binary value")), initial_fpos);
CLEAR_GA_AND_ERROR_OUT(ad_ga);
}
- const msgpack_object_array arr =
- unpacked.data.via.map.ptr[i].val.via.array;
- for (size_t j = 0; j < arr.size; j++) {
- if (arr.ptr[j].type != MSGPACK_OBJECT_BIN) {
- emsgf(_(READERR("register", "has " REG_KEY_CONTENTS " array "
- "with non-binary value")), initial_fpos);
- CLEAR_GA_AND_ERROR_OUT(ad_ga);
- }
- }
- entry->data.reg.contents_size = arr.size;
- entry->data.reg.contents = xmalloc(arr.size * sizeof(char *));
- for (size_t j = 0; j < arr.size; j++) {
- entry->data.reg.contents[j] = BIN_CONVERTED(arr.ptr[j].via.bin);
- }
}
- BOOLEAN_KEY(unpacked, "register", REG_KEY_UNNAMED,
- entry->data.reg.is_unnamed)
- TYPED_KEY(unpacked, "register", REG_KEY_TYPE, "an unsigned integer",
- entry->data.reg.type, POSITIVE_INTEGER, u64, TOU8)
- TYPED_KEY(unpacked, "register", KEY_NAME_CHAR, "an unsigned integer",
- entry->data.reg.name, POSITIVE_INTEGER, u64, TOCHAR)
- TYPED_KEY(unpacked, "register", REG_KEY_WIDTH, "an unsigned integer",
- entry->data.reg.width, POSITIVE_INTEGER, u64, TOSIZE)
- ADDITIONAL_KEY(unpacked)
- }
- if (entry->data.reg.contents == NULL) {
- emsgf(_(READERR("register", "has missing " REG_KEY_CONTENTS " array")),
- initial_fpos);
- CLEAR_GA_AND_ERROR_OUT(ad_ga);
+ entry->data.reg.contents_size = arr.size;
+ entry->data.reg.contents = xmalloc(arr.size * sizeof(char *));
+ for (size_t j = 0; j < arr.size; j++) {
+ entry->data.reg.contents[j] = BIN_CONVERTED(arr.ptr[j].via.bin);
+ }
}
- SET_ADDITIONAL_DATA(entry->data.reg.additional_data, "register");
- break;
+ BOOLEAN_KEY(unpacked, "register", REG_KEY_UNNAMED,
+ entry->data.reg.is_unnamed)
+ TYPED_KEY(unpacked, "register", REG_KEY_TYPE, "an unsigned integer",
+ entry->data.reg.type, POSITIVE_INTEGER, u64, TOU8)
+ TYPED_KEY(unpacked, "register", KEY_NAME_CHAR, "an unsigned integer",
+ entry->data.reg.name, POSITIVE_INTEGER, u64, TOCHAR)
+ TYPED_KEY(unpacked, "register", REG_KEY_WIDTH, "an unsigned integer",
+ entry->data.reg.width, POSITIVE_INTEGER, u64, TOSIZE)
+ ADDITIONAL_KEY(unpacked)
}
- case kSDItemHistoryEntry: {
- if (unpacked.data.type != MSGPACK_OBJECT_ARRAY) {
- emsgf(_(READERR("history", "is not an array")), initial_fpos);
- goto shada_read_next_item_error;
- }
- if (unpacked.data.via.array.size < 2) {
- emsgf(_(READERR("history", "does not have enough elements")),
- initial_fpos);
+ if (entry->data.reg.contents == NULL) {
+ emsgf(_(READERR("register", "has missing " REG_KEY_CONTENTS " array")),
+ initial_fpos);
+ CLEAR_GA_AND_ERROR_OUT(ad_ga);
+ }
+ SET_ADDITIONAL_DATA(entry->data.reg.additional_data, "register");
+ break;
+ }
+ case kSDItemHistoryEntry: {
+ if (unpacked.data.type != MSGPACK_OBJECT_ARRAY) {
+ emsgf(_(READERR("history", "is not an array")), initial_fpos);
+ goto shada_read_next_item_error;
+ }
+ if (unpacked.data.via.array.size < 2) {
+ emsgf(_(READERR("history", "does not have enough elements")),
+ initial_fpos);
+ goto shada_read_next_item_error;
+ }
+ if (unpacked.data.via.array.ptr[0].type
+ != MSGPACK_OBJECT_POSITIVE_INTEGER) {
+ emsgf(_(READERR("history", "has wrong history type type")),
+ initial_fpos);
+ goto shada_read_next_item_error;
+ }
+ if (unpacked.data.via.array.ptr[1].type
+ != MSGPACK_OBJECT_BIN) {
+ emsgf(_(READERR("history", "has wrong history string type")),
+ initial_fpos);
+ goto shada_read_next_item_error;
+ }
+ if (memchr(unpacked.data.via.array.ptr[1].via.bin.ptr, 0,
+ unpacked.data.via.array.ptr[1].via.bin.size) != NULL) {
+ emsgf(_(READERR("history", "contains string with zero byte inside")),
+ initial_fpos);
+ goto shada_read_next_item_error;
+ }
+ entry->data.history_item.histtype =
+ (uint8_t)unpacked.data.via.array.ptr[0].via.u64;
+ const bool is_hist_search =
+ entry->data.history_item.histtype == HIST_SEARCH;
+ if (is_hist_search) {
+ if (unpacked.data.via.array.size < 3) {
+ emsgf(_(READERR("search history",
+ "does not have separator character")), initial_fpos);
goto shada_read_next_item_error;
}
- if (unpacked.data.via.array.ptr[0].type
+ if (unpacked.data.via.array.ptr[2].type
!= MSGPACK_OBJECT_POSITIVE_INTEGER) {
- emsgf(_(READERR("history", "has wrong history type type")),
- initial_fpos);
- goto shada_read_next_item_error;
- }
- if (unpacked.data.via.array.ptr[1].type
- != MSGPACK_OBJECT_BIN) {
- emsgf(_(READERR("history", "has wrong history string type")),
- initial_fpos);
- goto shada_read_next_item_error;
- }
- if (memchr(unpacked.data.via.array.ptr[1].via.bin.ptr, 0,
- unpacked.data.via.array.ptr[1].via.bin.size) != NULL) {
- emsgf(_(READERR("history", "contains string with zero byte inside")),
- initial_fpos);
+ emsgf(_(READERR("search history",
+ "has wrong history separator type")), initial_fpos);
goto shada_read_next_item_error;
}
- entry->data.history_item.histtype =
- (uint8_t) unpacked.data.via.array.ptr[0].via.u64;
- const bool is_hist_search =
- entry->data.history_item.histtype == HIST_SEARCH;
- if (is_hist_search) {
- if (unpacked.data.via.array.size < 3) {
- emsgf(_(READERR("search history",
- "does not have separator character")), initial_fpos);
- goto shada_read_next_item_error;
- }
- if (unpacked.data.via.array.ptr[2].type
- != MSGPACK_OBJECT_POSITIVE_INTEGER) {
- emsgf(_(READERR("search history",
- "has wrong history separator type")), initial_fpos);
+ entry->data.history_item.sep =
+ (char)unpacked.data.via.array.ptr[2].via.u64;
+ }
+ size_t strsize;
+ strsize = (
+ unpacked.data.via.array.ptr[1].via.bin.size
+ + 1 // Zero byte
+ + 1); // Separator character
+ entry->data.history_item.string = xmalloc(strsize);
+ memcpy(entry->data.history_item.string,
+ unpacked.data.via.array.ptr[1].via.bin.ptr,
+ unpacked.data.via.array.ptr[1].via.bin.size);
+ entry->data.history_item.string[strsize - 2] = 0;
+ entry->data.history_item.string[strsize - 1] =
+ entry->data.history_item.sep;
+ SET_ADDITIONAL_ELEMENTS(unpacked.data.via.array, (2 + is_hist_search),
+ entry->data.history_item.additional_elements,
+ "history");
+ break;
+ }
+ case kSDItemVariable: {
+ if (unpacked.data.type != MSGPACK_OBJECT_ARRAY) {
+ emsgf(_(READERR("variable", "is not an array")), initial_fpos);
+ goto shada_read_next_item_error;
+ }
+ if (unpacked.data.via.array.size < 2) {
+ emsgf(_(READERR("variable", "does not have enough elements")),
+ initial_fpos);
+ goto shada_read_next_item_error;
+ }
+ if (unpacked.data.via.array.ptr[0].type != MSGPACK_OBJECT_BIN) {
+ emsgf(_(READERR("variable", "has wrong variable name type")),
+ initial_fpos);
+ goto shada_read_next_item_error;
+ }
+ entry->data.global_var.name =
+ xmemdupz(unpacked.data.via.array.ptr[0].via.bin.ptr,
+ unpacked.data.via.array.ptr[0].via.bin.size);
+ SET_ADDITIONAL_ELEMENTS(unpacked.data.via.array, 2,
+ entry->data.global_var.additional_elements,
+ "variable");
+ bool is_blob = false;
+ // A msgpack BIN could be a String or Blob; an additional VAR_TYPE_BLOB
+ // element is stored with Blobs which can be used to differentiate them
+ if (unpacked.data.via.array.ptr[1].type == MSGPACK_OBJECT_BIN) {
+ const listitem_T *type_item
+ = tv_list_first(entry->data.global_var.additional_elements);
+ if (type_item != NULL) {
+ const typval_T *type_tv = TV_LIST_ITEM_TV(type_item);
+ if (type_tv->v_type != VAR_NUMBER
+ || type_tv->vval.v_number != VAR_TYPE_BLOB) {
+ emsgf(_(READERR("variable", "has wrong variable type")),
+ initial_fpos);
goto shada_read_next_item_error;
}
- entry->data.history_item.sep =
- (char) unpacked.data.via.array.ptr[2].via.u64;
+ is_blob = true;
}
- size_t strsize;
- strsize = (
- unpacked.data.via.array.ptr[1].via.bin.size
- + 1 // Zero byte
- + 1); // Separator character
- entry->data.history_item.string = xmalloc(strsize);
- memcpy(entry->data.history_item.string,
- unpacked.data.via.array.ptr[1].via.bin.ptr,
- unpacked.data.via.array.ptr[1].via.bin.size);
- entry->data.history_item.string[strsize - 2] = 0;
- entry->data.history_item.string[strsize - 1] =
- entry->data.history_item.sep;
- SET_ADDITIONAL_ELEMENTS(unpacked.data.via.array, (2 + is_hist_search),
- entry->data.history_item.additional_elements,
- "history");
- break;
}
- case kSDItemVariable: {
- if (unpacked.data.type != MSGPACK_OBJECT_ARRAY) {
- emsgf(_(READERR("variable", "is not an array")), initial_fpos);
- goto shada_read_next_item_error;
- }
- if (unpacked.data.via.array.size < 2) {
- emsgf(_(READERR("variable", "does not have enough elements")),
- initial_fpos);
- goto shada_read_next_item_error;
- }
- if (unpacked.data.via.array.ptr[0].type != MSGPACK_OBJECT_BIN) {
- emsgf(_(READERR("variable", "has wrong variable name type")),
- initial_fpos);
- goto shada_read_next_item_error;
- }
- entry->data.global_var.name =
- xmemdupz(unpacked.data.via.array.ptr[0].via.bin.ptr,
- unpacked.data.via.array.ptr[0].via.bin.size);
- if (msgpack_to_vim(unpacked.data.via.array.ptr[1],
- &(entry->data.global_var.value)) == FAIL) {
- emsgf(_(READERR("variable", "has value that cannot "
- "be converted to the VimL value")), initial_fpos);
- goto shada_read_next_item_error;
- }
- SET_ADDITIONAL_ELEMENTS(unpacked.data.via.array, 2,
- entry->data.global_var.additional_elements,
- "variable");
- break;
+ if (is_blob) {
+ const msgpack_object_bin *const bin
+ = &unpacked.data.via.array.ptr[1].via.bin;
+ blob_T *const blob = tv_blob_alloc();
+ ga_concat_len(&blob->bv_ga, bin->ptr, (size_t)bin->size);
+ tv_blob_set_ret(&entry->data.global_var.value, blob);
+ } else if (msgpack_to_vim(unpacked.data.via.array.ptr[1],
+ &(entry->data.global_var.value)) == FAIL) {
+ emsgf(_(READERR("variable", "has value that cannot "
+ "be converted to the VimL value")), initial_fpos);
+ goto shada_read_next_item_error;
}
- case kSDItemSubString: {
- if (unpacked.data.type != MSGPACK_OBJECT_ARRAY) {
- emsgf(_(READERR("sub string", "is not an array")), initial_fpos);
- goto shada_read_next_item_error;
- }
- if (unpacked.data.via.array.size < 1) {
- emsgf(_(READERR("sub string", "does not have enough elements")),
- initial_fpos);
- goto shada_read_next_item_error;
- }
- if (unpacked.data.via.array.ptr[0].type != MSGPACK_OBJECT_BIN) {
- emsgf(_(READERR("sub string", "has wrong sub string type")),
- initial_fpos);
- goto shada_read_next_item_error;
- }
- entry->data.sub_string.sub =
- BIN_CONVERTED(unpacked.data.via.array.ptr[0].via.bin);
- SET_ADDITIONAL_ELEMENTS(unpacked.data.via.array, 1,
- entry->data.sub_string.additional_elements,
- "sub string");
+ break;
+ }
+ case kSDItemSubString:
+ if (unpacked.data.type != MSGPACK_OBJECT_ARRAY) {
+ emsgf(_(READERR("sub string", "is not an array")), initial_fpos);
+ goto shada_read_next_item_error;
+ }
+ if (unpacked.data.via.array.size < 1) {
+ emsgf(_(READERR("sub string", "does not have enough elements")),
+ initial_fpos);
+ goto shada_read_next_item_error;
+ }
+ if (unpacked.data.via.array.ptr[0].type != MSGPACK_OBJECT_BIN) {
+ emsgf(_(READERR("sub string", "has wrong sub string type")),
+ initial_fpos);
+ goto shada_read_next_item_error;
+ }
+ entry->data.sub_string.sub =
+ BIN_CONVERTED(unpacked.data.via.array.ptr[0].via.bin);
+ SET_ADDITIONAL_ELEMENTS(unpacked.data.via.array, 1,
+ entry->data.sub_string.additional_elements,
+ "sub string");
+ break;
+ case kSDItemBufferList:
+ if (unpacked.data.type != MSGPACK_OBJECT_ARRAY) {
+ emsgf(_(READERR("buffer list", "is not an array")), initial_fpos);
+ goto shada_read_next_item_error;
+ }
+ if (unpacked.data.via.array.size == 0) {
break;
}
- case kSDItemBufferList: {
- if (unpacked.data.type != MSGPACK_OBJECT_ARRAY) {
- emsgf(_(READERR("buffer list", "is not an array")), initial_fpos);
- goto shada_read_next_item_error;
- }
- if (unpacked.data.via.array.size == 0) {
- break;
- }
- entry->data.buffer_list.buffers =
- xcalloc(unpacked.data.via.array.size,
- sizeof(*entry->data.buffer_list.buffers));
- for (size_t i = 0; i < unpacked.data.via.array.size; i++) {
- entry->data.buffer_list.size++;
- msgpack_unpacked unpacked_2 = (msgpack_unpacked) {
- .data = unpacked.data.via.array.ptr[i],
- };
+ entry->data.buffer_list.buffers =
+ xcalloc(unpacked.data.via.array.size,
+ sizeof(*entry->data.buffer_list.buffers));
+ for (size_t i = 0; i < unpacked.data.via.array.size; i++) {
+ entry->data.buffer_list.size++;
+ msgpack_unpacked unpacked_2 = (msgpack_unpacked) {
+ .data = unpacked.data.via.array.ptr[i],
+ };
+ {
+ if (unpacked_2.data.type != MSGPACK_OBJECT_MAP) {
+ emsgf(_(RERR "Error while reading ShaDa file: "
+ "buffer list at position %" PRIu64 " "
+ "contains entry that is not a dictionary"),
+ initial_fpos);
+ goto shada_read_next_item_error;
+ }
+ entry->data.buffer_list.buffers[i].pos = default_pos;
+ garray_T ad_ga;
+ ga_init(&ad_ga, sizeof(*(unpacked_2.data.via.map.ptr)), 1);
{
- if (unpacked_2.data.type != MSGPACK_OBJECT_MAP) {
- emsgf(_(RERR "Error while reading ShaDa file: "
- "buffer list at position %" PRIu64 " "
- "contains entry that is not a dictionary"),
- initial_fpos);
- goto shada_read_next_item_error;
- }
- entry->data.buffer_list.buffers[i].pos = default_pos;
- garray_T ad_ga;
- ga_init(&ad_ga, sizeof(*(unpacked_2.data.via.map.ptr)), 1);
+ // XXX: Temporarily reassign `i` because the macros depend on it.
+ const size_t j = i;
{
- // XXX: Temporarily reassign `i` because the macros depend on it.
- const size_t j = i;
- {
- for (i = 0; i < unpacked_2.data.via.map.size; i++) { // -V535
- CHECK_KEY_IS_STR(unpacked_2, "buffer list entry")
- LONG_KEY(unpacked_2, "buffer list entry", KEY_LNUM,
- entry->data.buffer_list.buffers[j].pos.lnum)
- INTEGER_KEY(unpacked_2, "buffer list entry", KEY_COL,
- entry->data.buffer_list.buffers[j].pos.col)
- STRING_KEY(unpacked_2, "buffer list entry", KEY_FILE,
- entry->data.buffer_list.buffers[j].fname)
- ADDITIONAL_KEY(unpacked_2)
- }
+ for (i = 0; i < unpacked_2.data.via.map.size; i++) { // -V535
+ CHECK_KEY_IS_STR(unpacked_2, "buffer list entry")
+ LONG_KEY(unpacked_2, "buffer list entry", KEY_LNUM,
+ entry->data.buffer_list.buffers[j].pos.lnum)
+ INTEGER_KEY(unpacked_2, "buffer list entry", KEY_COL,
+ entry->data.buffer_list.buffers[j].pos.col)
+ STRING_KEY(unpacked_2, "buffer list entry", KEY_FILE,
+ entry->data.buffer_list.buffers[j].fname)
+ ADDITIONAL_KEY(unpacked_2)
}
- i = j; // XXX: Restore `i`.
}
- if (entry->data.buffer_list.buffers[i].pos.lnum <= 0) {
- emsgf(_(RERR "Error while reading ShaDa file: "
- "buffer list at position %" PRIu64 " "
- "contains entry with invalid line number"),
- initial_fpos);
- CLEAR_GA_AND_ERROR_OUT(ad_ga);
- }
- if (entry->data.buffer_list.buffers[i].pos.col < 0) {
- emsgf(_(RERR "Error while reading ShaDa file: "
- "buffer list at position %" PRIu64 " "
- "contains entry with invalid column number"),
- initial_fpos);
- CLEAR_GA_AND_ERROR_OUT(ad_ga);
- }
- if (entry->data.buffer_list.buffers[i].fname == NULL) {
- emsgf(_(RERR "Error while reading ShaDa file: "
- "buffer list at position %" PRIu64 " "
- "contains entry that does not have a file name"),
- initial_fpos);
- CLEAR_GA_AND_ERROR_OUT(ad_ga);
- }
- SET_ADDITIONAL_DATA(
- entry->data.buffer_list.buffers[i].additional_data,
- "buffer list entry");
+ i = j; // XXX: Restore `i`.
+ }
+ if (entry->data.buffer_list.buffers[i].pos.lnum <= 0) {
+ emsgf(_(RERR "Error while reading ShaDa file: "
+ "buffer list at position %" PRIu64 " "
+ "contains entry with invalid line number"),
+ initial_fpos);
+ CLEAR_GA_AND_ERROR_OUT(ad_ga);
+ }
+ if (entry->data.buffer_list.buffers[i].pos.col < 0) {
+ emsgf(_(RERR "Error while reading ShaDa file: "
+ "buffer list at position %" PRIu64 " "
+ "contains entry with invalid column number"),
+ initial_fpos);
+ CLEAR_GA_AND_ERROR_OUT(ad_ga);
}
+ if (entry->data.buffer_list.buffers[i].fname == NULL) {
+ emsgf(_(RERR "Error while reading ShaDa file: "
+ "buffer list at position %" PRIu64 " "
+ "contains entry that does not have a file name"),
+ initial_fpos);
+ CLEAR_GA_AND_ERROR_OUT(ad_ga);
+ }
+ SET_ADDITIONAL_DATA(entry->data.buffer_list.buffers[i].additional_data,
+ "buffer list entry");
}
- break;
- }
- case kSDItemMissing:
- case kSDItemUnknown: {
- abort();
}
+ break;
+ case kSDItemMissing:
+ case kSDItemUnknown:
+ abort();
}
- entry->type = (ShadaEntryType) type_u64;
+ entry->type = (ShadaEntryType)type_u64;
ret = kSDReadStatusSuccess;
shada_read_next_item_end:
if (buf != NULL) {
@@ -4056,7 +3976,7 @@ shada_read_next_item_end:
}
return ret;
shada_read_next_item_error:
- entry->type = (ShadaEntryType) type_u64;
+ entry->type = (ShadaEntryType)type_u64;
shada_free_shada_entry(entry);
entry->type = kSDItemMissing;
goto shada_read_next_item_end;
@@ -4091,13 +4011,13 @@ shada_read_next_item_error:
static bool shada_removable(const char *name)
FUNC_ATTR_WARN_UNUSED_RESULT
{
- char *p;
+ char *p;
char part[MAXPATHL + 1];
bool retval = false;
char *new_name = home_replace_save(NULL, name);
- for (p = (char *) p_shada; *p; ) {
- (void) copy_option_part(&p, part, ARRAY_SIZE(part), ", ");
+ for (p = (char *)p_shada; *p; ) {
+ (void)copy_option_part(&p, part, ARRAY_SIZE(part), ", ");
if (part[0] == 'r') {
home_replace(NULL, part + 1, NameBuff, MAXPATHL, true);
size_t n = STRLEN(NameBuff);
@@ -4118,8 +4038,8 @@ static bool shada_removable(const char *name)
/// location.
///
/// @return number of jumplist entries
-static inline size_t shada_init_jumps(
- PossiblyFreedShadaEntry *jumps, khash_t(bufset) *const removable_bufs)
+static inline size_t shada_init_jumps(PossiblyFreedShadaEntry *jumps,
+ khash_t(bufset) *const removable_bufs)
{
if (!curwin->w_jumplistlen) {
return 0;
@@ -4146,9 +4066,9 @@ static inline size_t shada_init_jumps(
: fm.fmark.fnum != 0) {
continue;
}
- const char *const fname = (char *) (fm.fmark.fnum == 0
+ const char *const fname = (char *)(fm.fmark.fnum == 0
? (fm.fname == NULL ? NULL : fm.fname)
- : buf ? buf->b_ffname : NULL);
+ : buf ? buf->b_ffname : NULL);
if (fname == NULL) {
continue;
}
@@ -4161,7 +4081,7 @@ static inline size_t shada_init_jumps(
.filemark = {
.name = NUL,
.mark = fm.fmark.mark,
- .fname = (char *) fname,
+ .fname = (char *)fname,
.additional_data = fm.fmark.additional_data,
}
}
@@ -4242,9 +4162,8 @@ void shada_encode_gvars(msgpack_sbuffer *const sbuf)
do {
typval_T vartv;
const char *name = NULL;
- var_iter = var_shada_iter(
- var_iter, &name, &vartv,
- VAR_FLAVOUR_DEFAULT | VAR_FLAVOUR_SESSION | VAR_FLAVOUR_SHADA);
+ var_iter = var_shada_iter(var_iter, &name, &vartv,
+ VAR_FLAVOUR_DEFAULT | VAR_FLAVOUR_SESSION | VAR_FLAVOUR_SHADA);
if (name == NULL) {
break;
}
@@ -4274,8 +4193,7 @@ void shada_encode_gvars(msgpack_sbuffer *const sbuf)
/// Wrapper for reading from msgpack_sbuffer.
///
/// @return number of bytes read.
-static ptrdiff_t read_sbuf(ShaDaReadDef *const sd_reader, void *const dest,
- const size_t size)
+static ptrdiff_t read_sbuf(ShaDaReadDef *const sd_reader, void *const dest, const size_t size)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
msgpack_sbuffer *sbuf = (msgpack_sbuffer *)sd_reader->cookie;
@@ -4297,8 +4215,7 @@ static ptrdiff_t read_sbuf(ShaDaReadDef *const sd_reader, void *const dest,
///
/// @return FAIL in case of failure, OK in case of success. May set
/// sd_reader->eof.
-static int sd_sbuf_reader_skip_read(ShaDaReadDef *const sd_reader,
- const size_t offset)
+static int sd_sbuf_reader_skip_read(ShaDaReadDef *const sd_reader, const size_t offset)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
msgpack_sbuffer *sbuf = (msgpack_sbuffer *)sd_reader->cookie;
@@ -4316,8 +4233,7 @@ static int sd_sbuf_reader_skip_read(ShaDaReadDef *const sd_reader,
///
/// @param[in] sbuf msgpack_sbuffer to read from.
/// @param[out] sd_reader Location where reader structure will be saved.
-static void open_shada_sbuf_for_reading(const msgpack_sbuffer *const sbuf,
- ShaDaReadDef *sd_reader)
+static void open_shada_sbuf_for_reading(const msgpack_sbuffer *const sbuf, ShaDaReadDef *sd_reader)
FUNC_ATTR_NONNULL_ALL
{
*sd_reader = (ShaDaReadDef) {
diff --git a/src/nvim/sign.c b/src/nvim/sign.c
index 15fd25e096..25427de6bf 100644
--- a/src/nvim/sign.c
+++ b/src/nvim/sign.c
@@ -6,33 +6,33 @@
//
-#include "nvim/vim.h"
-#include "nvim/sign.h"
#include "nvim/ascii.h"
#include "nvim/buffer.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
-#include "nvim/ex_docmd.h"
#include "nvim/edit.h"
+#include "nvim/ex_docmd.h"
#include "nvim/fold.h"
#include "nvim/move.h"
+#include "nvim/option.h"
#include "nvim/screen.h"
+#include "nvim/sign.h"
#include "nvim/syntax.h"
-#include "nvim/option.h"
+#include "nvim/vim.h"
/// Struct to hold the sign properties.
typedef struct sign sign_T;
struct sign
{
- sign_T *sn_next; // next sign in list
- int sn_typenr; // type number of sign
- char_u *sn_name; // name of sign
- char_u *sn_icon; // name of pixmap
- char_u *sn_text; // text used instead of pixmap
- int sn_line_hl; // highlight ID for line
- int sn_text_hl; // highlight ID for text
- int sn_num_hl; // highlight ID for line number
+ sign_T *sn_next; // next sign in list
+ int sn_typenr; // type number of sign
+ char_u *sn_name; // name of sign
+ char_u *sn_icon; // name of pixmap
+ char_u *sn_text; // text used instead of pixmap
+ int sn_line_hl; // highlight ID for line
+ int sn_text_hl; // highlight ID for text
+ int sn_num_hl; // highlight ID for line number
};
static sign_T *first_sign = NULL;
@@ -42,19 +42,19 @@ static void sign_list_defined(sign_T *sp);
static void sign_undefine(sign_T *sp, sign_T *sp_prev);
static char *cmds[] = {
- "define",
+ "define",
#define SIGNCMD_DEFINE 0
- "undefine",
+ "undefine",
#define SIGNCMD_UNDEFINE 1
- "list",
+ "list",
#define SIGNCMD_LIST 2
- "place",
+ "place",
#define SIGNCMD_PLACE 3
- "unplace",
+ "unplace",
#define SIGNCMD_UNPLACE 4
- "jump",
+ "jump",
#define SIGNCMD_JUMP 5
- NULL
+ NULL
#define SIGNCMD_LAST 6
};
@@ -65,17 +65,17 @@ static int next_sign_id = 1; // next sign id in the global group
/// Initialize data needed for managing signs
void init_signs(void)
{
- hash_init(&sg_table); // sign group hash table
+ hash_init(&sg_table); // sign group hash table
}
/// A new sign in group 'groupname' is added. If the group is not present,
/// create it. Otherwise reference the group.
///
-static signgroup_T * sign_group_ref(const char_u *groupname)
+static signgroup_T *sign_group_ref(const char_u *groupname)
{
- hash_T hash;
- hashitem_T *hi;
- signgroup_T *group;
+ hash_T hash;
+ hashitem_T *hi;
+ signgroup_T *group;
hash = hash_hash(groupname);
hi = hash_lookup(&sg_table, (char *)groupname, STRLEN(groupname), hash);
@@ -100,7 +100,7 @@ static signgroup_T * sign_group_ref(const char_u *groupname)
/// removed, then remove the group.
static void sign_group_unref(char_u *groupname)
{
- hashitem_T *hi;
+ hashitem_T *hi;
signgroup_T *group;
hi = hash_find(&sg_table, groupname);
@@ -115,15 +115,15 @@ static void sign_group_unref(char_u *groupname)
}
}
-/// Returns TRUE if 'sign' is in 'group'.
+/// @return true if 'sign' is in 'group'.
/// A sign can either be in the global group (sign->group == NULL)
/// or in a named group. If 'group' is '*', then the sign is part of the group.
-int sign_in_group(sign_entry_T *sign, const char_u *group)
+bool sign_in_group(sign_entry_T *sign, const char_u *group)
{
- return ((group != NULL && STRCMP(group, "*") == 0)
- || (group == NULL && sign->se_group == NULL)
- || (group != NULL && sign->se_group != NULL
- && STRCMP(group, sign->se_group->sg_name) == 0));
+ return ((group != NULL && STRCMP(group, "*") == 0)
+ || (group == NULL && sign->se_group == NULL)
+ || (group != NULL && sign->se_group != NULL
+ && STRCMP(group, sign->se_group->sg_name) == 0));
}
/// Get the next free sign identifier in the specified group
@@ -143,7 +143,7 @@ int sign_group_get_next_signid(buf_T *buf, const char_u *groupname)
group = HI2SG(hi);
}
- // Search for the next usuable sign identifier
+ // Search for the next usable sign identifier
while (!found) {
if (group == NULL) {
id = next_sign_id++; // global group
@@ -166,17 +166,19 @@ int sign_group_get_next_signid(buf_T *buf, const char_u *groupname)
/// Insert a new sign into the signlist for buffer 'buf' between the 'prev' and
/// 'next' signs.
-static void insert_sign(
- buf_T *buf, // buffer to store sign in
- sign_entry_T *prev, // previous sign entry
- sign_entry_T *next, // next sign entry
- int id, // sign ID
- const char_u *group, // sign group; NULL for global group
- int prio, // sign priority
- linenr_T lnum, // line number which gets the mark
- int typenr, // typenr of sign we are adding
- bool has_text_or_icon // sign has text or icon
-)
+///
+/// @param buf buffer to store sign in
+/// @param prev previous sign entry
+/// @param next next sign entry
+/// @param id sign ID
+/// @param group sign group; NULL for global group
+/// @param prio sign priority
+/// @param lnum line number which gets the mark
+/// @param typenr typenr of sign we are adding
+/// @param has_text_or_icon sign has text or icon
+static void insert_sign(buf_T *buf, sign_entry_T *prev, sign_entry_T *next, int id,
+ const char_u *group, int prio, linenr_T lnum, int typenr,
+ bool has_text_or_icon)
{
sign_entry_T *newsign = xmalloc(sizeof(sign_entry_T));
newsign->se_id = id;
@@ -194,7 +196,7 @@ static void insert_sign(
if (next != NULL) {
next->se_prev = newsign;
}
- buf->b_signcols_max = -1;
+ buf->b_signcols_valid = false;
if (prev == NULL) {
// When adding first sign need to redraw the windows to create the
@@ -212,18 +214,19 @@ static void insert_sign(
}
/// Insert a new sign sorted by line number and sign priority.
-static void insert_sign_by_lnum_prio(
- buf_T *buf, // buffer to store sign in
- sign_entry_T *prev, // previous sign entry
- int id, // sign ID
- const char_u *group, // sign group; NULL for global group
- int prio, // sign priority
- linenr_T lnum, // line number which gets the mark
- int typenr, // typenr of sign we are adding
- bool has_text_or_icon // sign has text or icon
-)
+///
+/// @param buf buffer to store sign in
+/// @param prev previous sign entry
+/// @param id sign ID
+/// @param group sign group; NULL for global group
+/// @param prio sign priority
+/// @param lnum line number which gets the mark
+/// @param typenr typenr of sign we are adding
+/// @param has_text_or_icon sign has text or icon
+static void insert_sign_by_lnum_prio(buf_T *buf, sign_entry_T *prev, int id, const char_u *group,
+ int prio, linenr_T lnum, int typenr, bool has_text_or_icon)
{
- sign_entry_T *sign;
+ sign_entry_T *sign;
// keep signs sorted by lnum, priority and id: insert new sign at
// the proper position in the list for this lnum.
@@ -242,9 +245,9 @@ static void insert_sign_by_lnum_prio(
}
/// Get the name of a sign by its typenr.
-char_u * sign_typenr2name(int typenr)
+char_u *sign_typenr2name(int typenr)
{
- sign_T *sp;
+ sign_T *sp;
for (sp = first_sign; sp != NULL; sp = sp->sn_next) {
if (sp->sn_typenr == typenr) {
@@ -255,9 +258,9 @@ char_u * sign_typenr2name(int typenr)
}
/// Return information about a sign in a Dict
-dict_T * sign_get_info(sign_entry_T *sign)
+dict_T *sign_get_info(sign_entry_T *sign)
{
- dict_T *d = tv_dict_alloc();
+ dict_T *d = tv_dict_alloc();
tv_dict_add_nr(d, S_LEN("id"), sign->se_id);
tv_dict_add_str(d, S_LEN("group"), ((sign->se_group == NULL)
? (char *)""
@@ -345,15 +348,16 @@ static void sign_sort_by_prio_on_line(buf_T *buf, sign_entry_T *sign)
/// Add the sign into the signlist. Find the right spot to do it though.
-void buf_addsign(
- buf_T *buf, // buffer to store sign in
- int id, // sign ID
- const char_u *groupname, // sign group
- int prio, // sign priority
- linenr_T lnum, // line number which gets the mark
- int typenr, // typenr of sign we are adding
- bool has_text_or_icon // sign has text or icon
-)
+///
+/// @param buf buffer to store sign in
+/// @param id sign ID
+/// @param groupname sign group
+/// @param prio sign priority
+/// @param lnum line number which gets the mark
+/// @param typenr typenr of sign we are adding
+/// @param has_text_or_icon sign has text or icon
+void buf_addsign(buf_T *buf, int id, const char_u *groupname, int prio, linenr_T lnum, int typenr,
+ bool has_text_or_icon)
{
sign_entry_T *sign; // a sign in the signlist
sign_entry_T *prev; // the previous sign
@@ -368,53 +372,51 @@ void buf_addsign(
sign_sort_by_prio_on_line(buf, sign);
return;
} else if (lnum < sign->se_lnum) {
- insert_sign_by_lnum_prio(
- buf,
- prev,
- id,
- groupname,
- prio,
- lnum,
- typenr,
- has_text_or_icon);
+ insert_sign_by_lnum_prio(buf,
+ prev,
+ id,
+ groupname,
+ prio,
+ lnum,
+ typenr,
+ has_text_or_icon);
return;
}
prev = sign;
}
- insert_sign_by_lnum_prio(
- buf,
- prev,
- id,
- groupname,
- prio,
- lnum,
- typenr,
- has_text_or_icon);
+ insert_sign_by_lnum_prio(buf,
+ prev,
+ id,
+ groupname,
+ prio,
+ lnum,
+ typenr,
+ has_text_or_icon);
}
-// For an existing, placed sign "markId" change the type to "typenr".
-// Returns the line number of the sign, or zero if the sign is not found.
-linenr_T buf_change_sign_type(
- buf_T *buf, // buffer to store sign in
- int markId, // sign ID
- const char_u *group, // sign group
- int typenr, // typenr of sign we are adding
- int prio // sign priority
-)
+/// For an existing, placed sign "markId" change the type to "typenr".
+/// Returns the line number of the sign, or zero if the sign is not found.
+///
+/// @param buf buffer to store sign in
+/// @param markId sign ID
+/// @param group sign group
+/// @param typenr typenr of sign we are adding
+/// @param prio sign priority
+linenr_T buf_change_sign_type(buf_T *buf, int markId, const char_u *group, int typenr, int prio)
{
- sign_entry_T *sign; // a sign in the signlist
+ sign_entry_T *sign; // a sign in the signlist
- FOR_ALL_SIGNS_IN_BUF(buf, sign) {
- if (sign->se_id == markId && sign_in_group(sign, group)) {
- sign->se_typenr = typenr;
- sign->se_priority = prio;
- sign_sort_by_prio_on_line(buf, sign);
- return sign->se_lnum;
- }
+ FOR_ALL_SIGNS_IN_BUF(buf, sign) {
+ if (sign->se_id == markId && sign_in_group(sign, group)) {
+ sign->se_typenr = typenr;
+ sign->se_priority = prio;
+ sign_sort_by_prio_on_line(buf, sign);
+ return sign->se_lnum;
}
+ }
- return (linenr_T)0;
+ return (linenr_T)0;
}
/// Return the sign attrs which has the attribute specified by 'type'. Returns
@@ -426,44 +428,43 @@ linenr_T buf_change_sign_type(
/// @param max_signs the number of signs, with priority for the ones
/// with the highest Ids.
/// @return Attrs of the matching sign, or NULL
-sign_attrs_T * sign_get_attr(SignType type, sign_attrs_T sattrs[],
- int idx, int max_signs)
+sign_attrs_T *sign_get_attr(SignType type, sign_attrs_T sattrs[], int idx, int max_signs)
{
- sign_attrs_T *matches[SIGN_SHOW_MAX];
- int nr_matches = 0;
-
- for (int i = 0; i < SIGN_SHOW_MAX; i++) {
- if ( (type == SIGN_TEXT && sattrs[i].sat_text != NULL)
- || (type == SIGN_LINEHL && sattrs[i].sat_linehl != 0)
- || (type == SIGN_NUMHL && sattrs[i].sat_numhl != 0)) {
- matches[nr_matches] = &sattrs[i];
- nr_matches++;
- // attr list is sorted with most important (priority, id), thus we
- // may stop as soon as we have max_signs matches
- if (nr_matches >= max_signs) {
- break;
- }
- }
+ sign_attrs_T *matches[SIGN_SHOW_MAX];
+ int nr_matches = 0;
+
+ for (int i = 0; i < SIGN_SHOW_MAX; i++) {
+ if ( (type == SIGN_TEXT && sattrs[i].sat_text != NULL)
+ || (type == SIGN_LINEHL && sattrs[i].sat_linehl != 0)
+ || (type == SIGN_NUMHL && sattrs[i].sat_numhl != 0)) {
+ matches[nr_matches] = &sattrs[i];
+ nr_matches++;
+ // attr list is sorted with most important (priority, id), thus we
+ // may stop as soon as we have max_signs matches
+ if (nr_matches >= max_signs) {
+ break;
+ }
}
+ }
- if (nr_matches > idx) {
- return matches[nr_matches - idx - 1];
- }
+ if (nr_matches > idx) {
+ return matches[nr_matches - idx - 1];
+ }
- return NULL;
+ return NULL;
}
/// Lookup a sign by typenr. Returns NULL if sign is not found.
-static sign_T * find_sign_by_typenr(int typenr)
+static sign_T *find_sign_by_typenr(int typenr)
{
- sign_T *sp;
+ sign_T *sp;
- for (sp = first_sign; sp != NULL; sp = sp->sn_next) {
- if (sp->sn_typenr == typenr) {
- return sp;
- }
+ for (sp = first_sign; sp != NULL; sp = sp->sn_next) {
+ if (sp->sn_typenr == typenr) {
+ return sp;
}
- return NULL;
+ }
+ return NULL;
}
/// Return the attributes of all the signs placed on line 'lnum' in buffer
@@ -474,44 +475,44 @@ static sign_T * find_sign_by_typenr(int typenr)
/// @return Number of signs of which attrs were found
int buf_get_signattrs(buf_T *buf, linenr_T lnum, sign_attrs_T sattrs[])
{
- sign_entry_T *sign;
- sign_T *sp;
+ sign_entry_T *sign;
+ sign_T *sp;
- int nr_matches = 0;
+ int nr_matches = 0;
- FOR_ALL_SIGNS_IN_BUF(buf, sign) {
- if (sign->se_lnum > lnum) {
- // Signs are sorted by line number in the buffer. No need to check
- // for signs after the specified line number 'lnum'.
- break;
- }
+ FOR_ALL_SIGNS_IN_BUF(buf, sign) {
+ if (sign->se_lnum > lnum) {
+ // Signs are sorted by line number in the buffer. No need to check
+ // for signs after the specified line number 'lnum'.
+ break;
+ }
- if (sign->se_lnum == lnum) {
- sign_attrs_T sattr;
- memset(&sattr, 0, sizeof(sattr));
- sattr.sat_typenr = sign->se_typenr;
- sp = find_sign_by_typenr(sign->se_typenr);
- if (sp != NULL) {
- sattr.sat_text = sp->sn_text;
- if (sattr.sat_text != NULL && sp->sn_text_hl != 0) {
- sattr.sat_texthl = syn_id2attr(sp->sn_text_hl);
- }
- if (sp->sn_line_hl != 0) {
- sattr.sat_linehl = syn_id2attr(sp->sn_line_hl);
- }
- if (sp->sn_num_hl != 0) {
- sattr.sat_numhl = syn_id2attr(sp->sn_num_hl);
- }
- }
-
- sattrs[nr_matches] = sattr;
- nr_matches++;
- if (nr_matches == SIGN_SHOW_MAX) {
- break;
- }
+ if (sign->se_lnum == lnum) {
+ sign_attrs_T sattr;
+ memset(&sattr, 0, sizeof(sattr));
+ sattr.sat_typenr = sign->se_typenr;
+ sp = find_sign_by_typenr(sign->se_typenr);
+ if (sp != NULL) {
+ sattr.sat_text = sp->sn_text;
+ if (sattr.sat_text != NULL && sp->sn_text_hl != 0) {
+ sattr.sat_texthl = syn_id2attr(sp->sn_text_hl);
+ }
+ if (sp->sn_line_hl != 0) {
+ sattr.sat_linehl = syn_id2attr(sp->sn_line_hl);
+ }
+ if (sp->sn_num_hl != 0) {
+ sattr.sat_numhl = syn_id2attr(sp->sn_num_hl);
}
+ }
+
+ sattrs[nr_matches] = sattr;
+ nr_matches++;
+ if (nr_matches == SIGN_SHOW_MAX) {
+ break;
+ }
}
- return nr_matches;
+ }
+ return nr_matches;
}
/// Delete sign 'id' in group 'group' from buffer 'buf'.
@@ -520,21 +521,22 @@ int buf_get_signattrs(buf_T *buf, linenr_T lnum, sign_attrs_T sattrs[])
/// If 'group' is '*', then delete the sign in all the groups. If 'group' is
/// NULL, then delete the sign in the global group. Otherwise delete the sign in
/// the specified group.
-/// Returns the line number of the deleted sign. If multiple signs are deleted,
+///
+/// @param buf buffer sign is stored in
+/// @param atlnum sign at this line, 0 - at any line
+/// @param id sign id
+/// @param group sign group
+///
+/// @return the line number of the deleted sign. If multiple signs are deleted,
/// then returns the line number of the last sign deleted.
-linenr_T buf_delsign(
- buf_T *buf, // buffer sign is stored in
- linenr_T atlnum, // sign at this line, 0 - at any line
- int id, // sign id
- char_u *group // sign group
-)
+linenr_T buf_delsign(buf_T *buf, linenr_T atlnum, int id, char_u *group)
{
sign_entry_T **lastp; // pointer to pointer to current sign
sign_entry_T *sign; // a sign in a b_signlist
sign_entry_T *next; // the next sign in a b_signlist
linenr_T lnum; // line number whose sign was deleted
- buf->b_signcols_max = -1;
+ buf->b_signcols_valid = false;
lastp = &buf->b_signlist;
lnum = 0;
for (sign = buf->b_signlist; sign != NULL; sign = next) {
@@ -580,30 +582,30 @@ linenr_T buf_delsign(
/// Find the line number of the sign with the requested id in group 'group'. If
/// the sign does not exist, return 0 as the line number. This will still let
/// the correct file get loaded.
-int buf_findsign(
- buf_T *buf, // buffer to store sign in
- int id, // sign ID
- char_u *group // sign group
-)
+///
+/// @param buf buffer to store sign in
+/// @param id sign ID
+/// @param group sign group
+int buf_findsign(buf_T *buf, int id, char_u *group)
{
- sign_entry_T *sign; // a sign in the signlist
+ sign_entry_T *sign; // a sign in the signlist
- FOR_ALL_SIGNS_IN_BUF(buf, sign) {
- if (sign->se_id == id && sign_in_group(sign, group)) {
- return (int)sign->se_lnum;
- }
+ FOR_ALL_SIGNS_IN_BUF(buf, sign) {
+ if (sign->se_id == id && sign_in_group(sign, group)) {
+ return (int)sign->se_lnum;
}
+ }
- return 0;
+ return 0;
}
/// Return the sign at line 'lnum' in buffer 'buf'. Returns NULL if a sign is
/// not found at the line. If 'groupname' is NULL, searches in the global group.
-static sign_entry_T * buf_getsign_at_line(
- buf_T *buf, // buffer whose sign we are searching for
- linenr_T lnum, // line number of sign
- char_u *groupname // sign group name
-)
+///
+/// @param buf buffer whose sign we are searching for
+/// @param lnum line number of sign
+/// @param groupname sign group name
+static sign_entry_T *buf_getsign_at_line(buf_T *buf, linenr_T lnum, char_u *groupname)
{
sign_entry_T *sign; // a sign in the signlist
@@ -623,61 +625,61 @@ static sign_entry_T * buf_getsign_at_line(
}
/// Return the identifier of the sign at line number 'lnum' in buffer 'buf'.
-int buf_findsign_id(
- buf_T *buf, // buffer whose sign we are searching for
- linenr_T lnum, // line number of sign
- char_u *groupname // sign group name
-)
+///
+/// @param buf buffer whose sign we are searching for
+/// @param lnum line number of sign
+/// @param groupname sign group name
+int buf_findsign_id(buf_T *buf, linenr_T lnum, char_u *groupname)
{
- sign_entry_T *sign; // a sign in the signlist
+ sign_entry_T *sign; // a sign in the signlist
- sign = buf_getsign_at_line(buf, lnum, groupname);
- if (sign != NULL) {
- return sign->se_id;
- }
+ sign = buf_getsign_at_line(buf, lnum, groupname);
+ if (sign != NULL) {
+ return sign->se_id;
+ }
- return 0;
+ return 0;
}
/// Delete signs in buffer "buf".
void buf_delete_signs(buf_T *buf, char_u *group)
{
- sign_entry_T *sign;
- sign_entry_T **lastp; // pointer to pointer to current sign
- sign_entry_T *next;
+ sign_entry_T *sign;
+ sign_entry_T **lastp; // pointer to pointer to current sign
+ sign_entry_T *next;
- // When deleting the last sign need to redraw the windows to remove the
- // sign column. Not when curwin is NULL (this means we're exiting).
- if (buf->b_signlist != NULL && curwin != NULL) {
- changed_line_abv_curs();
- }
+ // When deleting the last sign need to redraw the windows to remove the
+ // sign column. Not when curwin is NULL (this means we're exiting).
+ if (buf->b_signlist != NULL && curwin != NULL) {
+ changed_line_abv_curs();
+ }
- lastp = &buf->b_signlist;
- for (sign = buf->b_signlist; sign != NULL; sign = next) {
- next = sign->se_next;
- if (sign_in_group(sign, group)) {
- *lastp = next;
- if (next != NULL) {
- next->se_prev = sign->se_prev;
- }
- if (sign->se_group != NULL) {
- sign_group_unref(sign->se_group->sg_name);
- }
- xfree(sign);
- } else {
- lastp = &sign->se_next;
+ lastp = &buf->b_signlist;
+ for (sign = buf->b_signlist; sign != NULL; sign = next) {
+ next = sign->se_next;
+ if (sign_in_group(sign, group)) {
+ *lastp = next;
+ if (next != NULL) {
+ next->se_prev = sign->se_prev;
+ }
+ if (sign->se_group != NULL) {
+ sign_group_unref(sign->se_group->sg_name);
}
+ xfree(sign);
+ } else {
+ lastp = &sign->se_next;
}
- buf->b_signcols_max = -1;
+ }
+ buf->b_signcols_valid = false;
}
/// List placed signs for "rbuf". If "rbuf" is NULL do it for all buffers.
void sign_list_placed(buf_T *rbuf, char_u *sign_group)
{
buf_T *buf;
- sign_entry_T *sign;
- char lbuf[MSG_BUF_LEN];
- char group[MSG_BUF_LEN];
+ sign_entry_T *sign;
+ char lbuf[MSG_BUF_LEN];
+ char group[MSG_BUF_LEN];
MSG_PUTS_TITLE(_("\n--- Signs ---"));
msg_putchar('\n');
@@ -720,12 +722,7 @@ void sign_list_placed(buf_T *rbuf, char_u *sign_group)
}
/// Adjust a placed sign for inserted/deleted lines.
-void sign_mark_adjust(
- linenr_T line1,
- linenr_T line2,
- long amount,
- long amount_after
-)
+void sign_mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after)
{
sign_entry_T *sign; // a sign in a b_signlist
sign_entry_T *next; // the next sign in a b_signlist
@@ -735,7 +732,7 @@ void sign_mark_adjust(
int is_fixed = 0;
int signcol = win_signcol_configured(curwin, &is_fixed);
- curbuf->b_signcols_max = -1;
+ curbuf->b_signcols_valid = false;
lastp = &curbuf->b_signlist;
for (sign = curbuf->b_signlist; sign != NULL; sign = next) {
@@ -769,26 +766,26 @@ void sign_mark_adjust(
/// Find index of a ":sign" subcmd from its name.
/// "*end_cmd" must be writable.
-static int sign_cmd_idx(
- char_u *begin_cmd, // begin of sign subcmd
- char_u *end_cmd // just after sign subcmd
-)
+///
+/// @param begin_cmd begin of sign subcmd
+/// @param end_cmd just after sign subcmd
+static int sign_cmd_idx(char_u *begin_cmd, char_u *end_cmd)
{
- int idx;
- char_u save = *end_cmd;
+ int idx;
+ char_u save = *end_cmd;
- *end_cmd = (char_u)NUL;
- for (idx = 0; ; idx++) {
- if (cmds[idx] == NULL || STRCMP(begin_cmd, cmds[idx]) == 0) {
- break;
- }
+ *end_cmd = (char_u)NUL;
+ for (idx = 0; ; idx++) {
+ if (cmds[idx] == NULL || STRCMP(begin_cmd, cmds[idx]) == 0) {
+ break;
}
- *end_cmd = save;
- return idx;
+ }
+ *end_cmd = save;
+ return idx;
}
/// Find a sign by name. Also returns pointer to the previous sign.
-static sign_T * sign_find(const char_u *name, sign_T **sp_prev)
+static sign_T *sign_find(const char_u *name, sign_T **sp_prev)
{
sign_T *sp;
@@ -808,10 +805,10 @@ static sign_T * sign_find(const char_u *name, sign_T **sp_prev)
}
/// Allocate a new sign
-static sign_T * alloc_new_sign(char_u *name)
+static sign_T *alloc_new_sign(char_u *name)
{
- sign_T *sp;
- sign_T *lp;
+ sign_T *sp;
+ sign_T *lp;
int start = next_sign_typenr;
// Allocate a new sign.
@@ -858,8 +855,8 @@ static void sign_define_init_icon(sign_T *sp, char_u *icon)
/// Initialize the text for a new sign
static int sign_define_init_text(sign_T *sp, char_u *text)
{
- char_u *s;
- char_u *endp;
+ char_u *s;
+ char_u *endp;
int cells;
size_t len;
@@ -904,17 +901,11 @@ static int sign_define_init_text(sign_T *sp, char_u *text)
}
/// Define a new sign or update an existing sign
-int sign_define_by_name(
- char_u *name,
- char_u *icon,
- char_u *linehl,
- char_u *text,
- char_u *texthl,
- char_u *numhl
-)
+int sign_define_by_name(char_u *name, char_u *icon, char_u *linehl, char_u *text, char_u *texthl,
+ char_u *numhl)
{
- sign_T *sp_prev;
- sign_T *sp;
+ sign_T *sp_prev;
+ sign_T *sp;
sp = sign_find(name, &sp_prev);
if (sp == NULL) {
@@ -966,8 +957,8 @@ int sign_define_by_name(
/// Free the sign specified by 'name'.
int sign_undefine_by_name(const char_u *name)
{
- sign_T *sp_prev;
- sign_T *sp;
+ sign_T *sp_prev;
+ sign_T *sp;
sp = sign_find(name, &sp_prev);
if (sp == NULL) {
@@ -982,18 +973,18 @@ int sign_undefine_by_name(const char_u *name)
static void may_force_numberwidth_recompute(buf_T *buf, int unplace)
{
FOR_ALL_TAB_WINDOWS(tp, wp)
- if (wp->w_buffer == buf
- && (wp->w_p_nu || wp->w_p_rnu)
- && (unplace || wp->w_nrwidth_width < 2)
- && (*wp->w_p_scl == 'n' && *(wp->w_p_scl + 1) == 'u')) {
- wp->w_nrwidth_line_count = 0;
- }
+ if (wp->w_buffer == buf
+ && (wp->w_p_nu || wp->w_p_rnu)
+ && (unplace || wp->w_nrwidth_width < 2)
+ && (*wp->w_p_scl == 'n' && *(wp->w_p_scl + 1) == 'u')) {
+ wp->w_nrwidth_line_count = 0;
+ }
}
/// List the signs matching 'name'
static void sign_list_by_name(char_u *name)
{
- sign_T *sp;
+ sign_T *sp;
sp = sign_find(name, NULL);
if (sp != NULL) {
@@ -1005,14 +996,8 @@ static void sign_list_by_name(char_u *name)
/// Place a sign at the specified file location or update a sign.
-int sign_place(
- int *sign_id,
- const char_u *sign_group,
- const char_u *sign_name,
- buf_T *buf,
- linenr_T lnum,
- int prio
-)
+int sign_place(int *sign_id, const char_u *sign_group, const char_u *sign_name, buf_T *buf,
+ linenr_T lnum, int prio)
{
sign_T *sp;
@@ -1038,14 +1023,13 @@ int sign_place(
// ":sign place {id} line={lnum} name={name} file={fname}":
// place a sign
bool has_text_or_icon = sp->sn_text != NULL || sp->sn_icon != NULL;
- buf_addsign(
- buf,
- *sign_id,
- sign_group,
- prio,
- lnum,
- sp->sn_typenr,
- has_text_or_icon);
+ buf_addsign(buf,
+ *sign_id,
+ sign_group,
+ prio,
+ lnum,
+ sp->sn_typenr,
+ has_text_or_icon);
} else {
// ":sign place {id} file={fname}": change sign type and/or priority
lnum = buf_change_sign_type(buf, *sign_id, sign_group, sp->sn_typenr, prio);
@@ -1075,7 +1059,7 @@ int sign_unplace(int sign_id, char_u *sign_group, buf_T *buf, linenr_T atlnum)
redraw_buf_later(buf, NOT_VALID);
buf_delete_signs(buf, sign_group);
} else {
- linenr_T lnum;
+ linenr_T lnum;
// Delete only the specified signs
lnum = buf_delsign(buf, atlnum, sign_id, sign_group);
@@ -1098,7 +1082,7 @@ int sign_unplace(int sign_id, char_u *sign_group, buf_T *buf, linenr_T atlnum)
/// Unplace the sign at the current cursor line.
static void sign_unplace_at_cursor(char_u *groupname)
{
- int id = -1;
+ int id = -1;
id = buf_findsign_id(curwin->w_buffer, curwin->w_cursor.lnum, groupname);
if (id > 0) {
@@ -1144,13 +1128,13 @@ linenr_T sign_jump(int sign_id, char_u *sign_group, buf_T *buf)
/// ":sign define {name} ..." command
static void sign_define_cmd(char_u *sign_name, char_u *cmdline)
{
- char_u *arg;
- char_u *p = cmdline;
- char_u *icon = NULL;
- char_u *text = NULL;
- char_u *linehl = NULL;
- char_u *texthl = NULL;
- char_u *numhl = NULL;
+ char_u *arg;
+ char_u *p = cmdline;
+ char_u *icon = NULL;
+ char_u *text = NULL;
+ char_u *linehl = NULL;
+ char_u *texthl = NULL;
+ char_u *numhl = NULL;
int failed = false;
// set values for a defined sign.
@@ -1194,14 +1178,8 @@ static void sign_define_cmd(char_u *sign_name, char_u *cmdline)
}
/// ":sign place" command
-static void sign_place_cmd(
- buf_T *buf,
- linenr_T lnum,
- char_u *sign_name,
- int id,
- char_u *group,
- int prio
-)
+static void sign_place_cmd(buf_T *buf, linenr_T lnum, char_u *sign_name, int id, char_u *group,
+ int prio)
{
if (id <= 0) {
// List signs placed in a file/buffer
@@ -1233,62 +1211,56 @@ static void sign_place_cmd(
}
/// ":sign unplace" command
-static void sign_unplace_cmd(
- buf_T *buf,
- linenr_T lnum,
- char_u *sign_name,
- int id,
- char_u *group
-)
+static void sign_unplace_cmd(buf_T *buf, linenr_T lnum, char_u *sign_name, int id, char_u *group)
{
- if (lnum >= 0 || sign_name != NULL || (group != NULL && *group == '\0')) {
- EMSG(_(e_invarg));
- return;
- }
+ if (lnum >= 0 || sign_name != NULL || (group != NULL && *group == '\0')) {
+ EMSG(_(e_invarg));
+ return;
+ }
- if (id == -2) {
- if (buf != NULL) {
- // :sign unplace * file={fname}
- // :sign unplace * group={group} file={fname}
- // :sign unplace * group=* file={fname}
- // :sign unplace * buffer={nr}
- // :sign unplace * group={group} buffer={nr}
- // :sign unplace * group=* buffer={nr}
- sign_unplace(0, group, buf, 0);
- } else {
- // :sign unplace *
- // :sign unplace * group={group}
- // :sign unplace * group=*
- FOR_ALL_BUFFERS(cbuf) {
- if (cbuf->b_signlist != NULL) {
- buf_delete_signs(cbuf, group);
- }
+ if (id == -2) {
+ if (buf != NULL) {
+ // :sign unplace * file={fname}
+ // :sign unplace * group={group} file={fname}
+ // :sign unplace * group=* file={fname}
+ // :sign unplace * buffer={nr}
+ // :sign unplace * group={group} buffer={nr}
+ // :sign unplace * group=* buffer={nr}
+ sign_unplace(0, group, buf, 0);
+ } else {
+ // :sign unplace *
+ // :sign unplace * group={group}
+ // :sign unplace * group=*
+ FOR_ALL_BUFFERS(cbuf) {
+ if (cbuf->b_signlist != NULL) {
+ buf_delete_signs(cbuf, group);
}
}
+ }
+ } else {
+ if (buf != NULL) {
+ // :sign unplace {id} file={fname}
+ // :sign unplace {id} group={group} file={fname}
+ // :sign unplace {id} group=* file={fname}
+ // :sign unplace {id} buffer={nr}
+ // :sign unplace {id} group={group} buffer={nr}
+ // :sign unplace {id} group=* buffer={nr}
+ sign_unplace(id, group, buf, 0);
} else {
- if (buf != NULL) {
- // :sign unplace {id} file={fname}
- // :sign unplace {id} group={group} file={fname}
- // :sign unplace {id} group=* file={fname}
- // :sign unplace {id} buffer={nr}
- // :sign unplace {id} group={group} buffer={nr}
- // :sign unplace {id} group=* buffer={nr}
- sign_unplace(id, group, buf, 0);
+ if (id == -1) {
+ // :sign unplace group={group}
+ // :sign unplace group=*
+ sign_unplace_at_cursor(group);
} else {
- if (id == -1) {
- // :sign unplace group={group}
- // :sign unplace group=*
- sign_unplace_at_cursor(group);
- } else {
- // :sign unplace {id}
- // :sign unplace {id} group={group}
- // :sign unplace {id} group=*
- FOR_ALL_BUFFERS(cbuf) {
- sign_unplace(id, group, cbuf, 0);
- }
+ // :sign unplace {id}
+ // :sign unplace {id} group={group}
+ // :sign unplace {id} group=*
+ FOR_ALL_BUFFERS(cbuf) {
+ sign_unplace(id, group, cbuf, 0);
}
}
}
+ }
}
/// Jump to a placed sign commands:
@@ -1296,13 +1268,7 @@ static void sign_unplace_cmd(
/// :sign jump {id} buffer={nr}
/// :sign jump {id} group={group} file={fname}
/// :sign jump {id} group={group} buffer={nr}
-static void sign_jump_cmd(
- buf_T *buf,
- linenr_T lnum,
- char_u *sign_name,
- int id,
- char_u *group
-)
+static void sign_jump_cmd(buf_T *buf, linenr_T lnum, char_u *sign_name, int id, char_u *group)
{
if (sign_name == NULL && group == NULL && id == -1) {
EMSG(_(e_argreq));
@@ -1324,21 +1290,13 @@ static void sign_jump_cmd(
/// ":sign jump" commands.
/// The supported arguments are: line={lnum} name={name} group={group}
/// priority={prio} and file={fname} or buffer={nr}.
-static int parse_sign_cmd_args(
- int cmd,
- char_u *arg,
- char_u **sign_name,
- int *signid,
- char_u **group,
- int *prio,
- buf_T **buf,
- linenr_T *lnum
-)
+static int parse_sign_cmd_args(int cmd, char_u *arg, char_u **sign_name, int *signid,
+ char_u **group, int *prio, buf_T **buf, linenr_T *lnum)
{
- char_u *arg1;
- char_u *name;
- char_u *filename = NULL;
- int lnum_arg = false;
+ char_u *arg1;
+ char_u *name;
+ char_u *filename = NULL;
+ int lnum_arg = false;
// first arg could be placed sign id
arg1 = arg;
@@ -1448,7 +1406,7 @@ void ex_sign(exarg_T *eap)
} else if (*arg == NUL) {
EMSG(_("E156: Missing sign name"));
} else {
- char_u *name;
+ char_u *name;
// Isolate the sign name. If it's a number skip leading zeroes,
// so that "099" and "99" are the same sign. But keep "0".
@@ -1574,12 +1532,8 @@ list_T *get_buffer_signs(buf_T *buf)
}
/// Return information about all the signs placed in a buffer
-static void sign_get_placed_in_buf(
- buf_T *buf,
- linenr_T lnum,
- int sign_id,
- const char_u *sign_group,
- list_T *retlist)
+static void sign_get_placed_in_buf(buf_T *buf, linenr_T lnum, int sign_id, const char_u *sign_group,
+ list_T *retlist)
{
dict_T *d;
list_T *l;
@@ -1609,13 +1563,8 @@ static void sign_get_placed_in_buf(
/// Get a list of signs placed in buffer 'buf'. If 'num' is non-zero, return the
/// sign placed at the line number. If 'lnum' is zero, return all the signs
/// placed in 'buf'. If 'buf' is NULL, return signs placed in all the buffers.
-void sign_get_placed(
- buf_T *buf,
- linenr_T lnum,
- int sign_id,
- const char_u *sign_group,
- list_T *retlist
-)
+void sign_get_placed(buf_T *buf, linenr_T lnum, int sign_id, const char_u *sign_group,
+ list_T *retlist)
{
if (buf != NULL) {
sign_get_placed_in_buf(buf, lnum, sign_id, sign_group, retlist);
@@ -1697,13 +1646,13 @@ void free_signs(void)
static enum
{
- EXP_SUBCMD, // expand :sign sub-commands
- EXP_DEFINE, // expand :sign define {name} args
- EXP_PLACE, // expand :sign place {id} args
- EXP_LIST, // expand :sign place args
- EXP_UNPLACE, // expand :sign unplace"
- EXP_SIGN_NAMES, // expand with name of placed signs
- EXP_SIGN_GROUPS, // expand with name of placed sign groups
+ EXP_SUBCMD, // expand :sign sub-commands
+ EXP_DEFINE, // expand :sign define {name} args
+ EXP_PLACE, // expand :sign place {id} args
+ EXP_LIST, // expand :sign place args
+ EXP_UNPLACE, // expand :sign unplace"
+ EXP_SIGN_NAMES, // expand with name of placed signs
+ EXP_SIGN_GROUPS, // expand with name of placed sign groups
} expand_what;
// Return the n'th sign name (used for command line completion)
@@ -1740,45 +1689,45 @@ static char_u *get_nth_sign_group_name(int idx)
/// Function given to ExpandGeneric() to obtain the sign command
/// expansion.
-char_u * get_sign_name(expand_T *xp, int idx)
+char_u *get_sign_name(expand_T *xp, int idx)
{
switch (expand_what) {
- case EXP_SUBCMD:
- return (char_u *)cmds[idx];
- case EXP_DEFINE: {
- char *define_arg[] = { "icon=", "linehl=", "text=", "texthl=", "numhl=",
- NULL };
- return (char_u *)define_arg[idx];
- }
- case EXP_PLACE: {
- char *place_arg[] = { "line=", "name=", "group=", "priority=", "file=",
- "buffer=", NULL };
- return (char_u *)place_arg[idx];
- }
- case EXP_LIST: {
- char *list_arg[] = { "group=", "file=", "buffer=", NULL };
- return (char_u *)list_arg[idx];
- }
- case EXP_UNPLACE: {
- char *unplace_arg[] = { "group=", "file=", "buffer=", NULL };
- return (char_u *)unplace_arg[idx];
- }
- case EXP_SIGN_NAMES:
- return get_nth_sign_name(idx);
- case EXP_SIGN_GROUPS:
- return get_nth_sign_group_name(idx);
- default:
- return NULL;
+ case EXP_SUBCMD:
+ return (char_u *)cmds[idx];
+ case EXP_DEFINE: {
+ char *define_arg[] = { "icon=", "linehl=", "text=", "texthl=", "numhl=",
+ NULL };
+ return (char_u *)define_arg[idx];
+ }
+ case EXP_PLACE: {
+ char *place_arg[] = { "line=", "name=", "group=", "priority=", "file=",
+ "buffer=", NULL };
+ return (char_u *)place_arg[idx];
+ }
+ case EXP_LIST: {
+ char *list_arg[] = { "group=", "file=", "buffer=", NULL };
+ return (char_u *)list_arg[idx];
+ }
+ case EXP_UNPLACE: {
+ char *unplace_arg[] = { "group=", "file=", "buffer=", NULL };
+ return (char_u *)unplace_arg[idx];
+ }
+ case EXP_SIGN_NAMES:
+ return get_nth_sign_name(idx);
+ case EXP_SIGN_GROUPS:
+ return get_nth_sign_group_name(idx);
+ default:
+ return NULL;
}
}
/// Handle command line completion for :sign command.
void set_context_in_sign_cmd(expand_T *xp, char_u *arg)
{
- char_u *end_subcmd;
- char_u *last;
- int cmd_idx;
- char_u *begin_subcmd_args;
+ char_u *end_subcmd;
+ char_u *last;
+ int cmd_idx;
+ char_u *begin_subcmd_args;
// Default: expand subcommands.
xp->xp_context = EXPAND_SIGN;
@@ -1822,70 +1771,70 @@ void set_context_in_sign_cmd(expand_T *xp, char_u *arg)
// Expand last argument name (before equal sign).
xp->xp_pattern = last;
switch (cmd_idx) {
- case SIGNCMD_DEFINE:
- expand_what = EXP_DEFINE;
- break;
- case SIGNCMD_PLACE:
- // List placed signs
- if (ascii_isdigit(*begin_subcmd_args)) {
- // :sign place {id} {args}...
- expand_what = EXP_PLACE;
- } else {
- // :sign place {args}...
- expand_what = EXP_LIST;
- }
- break;
- case SIGNCMD_LIST:
- case SIGNCMD_UNDEFINE:
- // :sign list <CTRL-D>
- // :sign undefine <CTRL-D>
- expand_what = EXP_SIGN_NAMES;
- break;
- case SIGNCMD_JUMP:
- case SIGNCMD_UNPLACE:
- expand_what = EXP_UNPLACE;
- break;
- default:
- xp->xp_context = EXPAND_NOTHING;
+ case SIGNCMD_DEFINE:
+ expand_what = EXP_DEFINE;
+ break;
+ case SIGNCMD_PLACE:
+ // List placed signs
+ if (ascii_isdigit(*begin_subcmd_args)) {
+ // :sign place {id} {args}...
+ expand_what = EXP_PLACE;
+ } else {
+ // :sign place {args}...
+ expand_what = EXP_LIST;
+ }
+ break;
+ case SIGNCMD_LIST:
+ case SIGNCMD_UNDEFINE:
+ // :sign list <CTRL-D>
+ // :sign undefine <CTRL-D>
+ expand_what = EXP_SIGN_NAMES;
+ break;
+ case SIGNCMD_JUMP:
+ case SIGNCMD_UNPLACE:
+ expand_what = EXP_UNPLACE;
+ break;
+ default:
+ xp->xp_context = EXPAND_NOTHING;
}
} else {
- // Expand last argument value (after equal sign).
+ // Expand last argument value (after equal sign).
xp->xp_pattern = p + 1;
switch (cmd_idx) {
- case SIGNCMD_DEFINE:
- if (STRNCMP(last, "texthl", 6) == 0
- || STRNCMP(last, "linehl", 6) == 0
- || STRNCMP(last, "numhl", 5) == 0) {
- xp->xp_context = EXPAND_HIGHLIGHT;
- } else if (STRNCMP(last, "icon", 4) == 0) {
- xp->xp_context = EXPAND_FILES;
- } else {
- xp->xp_context = EXPAND_NOTHING;
- }
- break;
- case SIGNCMD_PLACE:
- if (STRNCMP(last, "name", 4) == 0) {
- expand_what = EXP_SIGN_NAMES;
- } else if (STRNCMP(last, "group", 5) == 0) {
- expand_what = EXP_SIGN_GROUPS;
- } else if (STRNCMP(last, "file", 4) == 0) {
- xp->xp_context = EXPAND_BUFFERS;
- } else {
- xp->xp_context = EXPAND_NOTHING;
- }
- break;
- case SIGNCMD_UNPLACE:
- case SIGNCMD_JUMP:
- if (STRNCMP(last, "group", 5) == 0) {
- expand_what = EXP_SIGN_GROUPS;
- } else if (STRNCMP(last, "file", 4) == 0) {
- xp->xp_context = EXPAND_BUFFERS;
- } else {
- xp->xp_context = EXPAND_NOTHING;
- }
- break;
- default:
+ case SIGNCMD_DEFINE:
+ if (STRNCMP(last, "texthl", 6) == 0
+ || STRNCMP(last, "linehl", 6) == 0
+ || STRNCMP(last, "numhl", 5) == 0) {
+ xp->xp_context = EXPAND_HIGHLIGHT;
+ } else if (STRNCMP(last, "icon", 4) == 0) {
+ xp->xp_context = EXPAND_FILES;
+ } else {
xp->xp_context = EXPAND_NOTHING;
+ }
+ break;
+ case SIGNCMD_PLACE:
+ if (STRNCMP(last, "name", 4) == 0) {
+ expand_what = EXP_SIGN_NAMES;
+ } else if (STRNCMP(last, "group", 5) == 0) {
+ expand_what = EXP_SIGN_GROUPS;
+ } else if (STRNCMP(last, "file", 4) == 0) {
+ xp->xp_context = EXPAND_BUFFERS;
+ } else {
+ xp->xp_context = EXPAND_NOTHING;
+ }
+ break;
+ case SIGNCMD_UNPLACE:
+ case SIGNCMD_JUMP:
+ if (STRNCMP(last, "group", 5) == 0) {
+ expand_what = EXP_SIGN_GROUPS;
+ } else if (STRNCMP(last, "file", 4) == 0) {
+ xp->xp_context = EXPAND_BUFFERS;
+ } else {
+ xp->xp_context = EXPAND_NOTHING;
+ }
+ break;
+ default:
+ xp->xp_context = EXPAND_NOTHING;
}
}
}
@@ -1914,11 +1863,11 @@ int sign_define_from_dict(const char *name_arg, dict_T *dict)
goto cleanup;
}
if (dict != NULL) {
- icon = tv_dict_get_string(dict, "icon" , true);
+ icon = tv_dict_get_string(dict, "icon", true);
linehl = tv_dict_get_string(dict, "linehl", true);
- text = tv_dict_get_string(dict, "text" , true);
+ text = tv_dict_get_string(dict, "text", true);
texthl = tv_dict_get_string(dict, "texthl", true);
- numhl = tv_dict_get_string(dict, "numhl" , true);
+ numhl = tv_dict_get_string(dict, "numhl", true);
}
if (sign_define_by_name((char_u *)name, (char_u *)icon, (char_u *)linehl,
@@ -1942,27 +1891,23 @@ cleanup:
/// values in 'retlist'.
void sign_define_multiple(list_T *l, list_T *retlist)
{
- int retval;
+ int retval;
- TV_LIST_ITER_CONST(l, li, {
- retval = -1;
- if (TV_LIST_ITEM_TV(li)->v_type == VAR_DICT) {
- retval = sign_define_from_dict(NULL, TV_LIST_ITEM_TV(li)->vval.v_dict);
- } else {
- EMSG(_(e_dictreq));
- }
- tv_list_append_number(retlist, retval);
- });
+ TV_LIST_ITER_CONST(l, li, {
+ retval = -1;
+ if (TV_LIST_ITEM_TV(li)->v_type == VAR_DICT) {
+ retval = sign_define_from_dict(NULL, TV_LIST_ITEM_TV(li)->vval.v_dict);
+ } else {
+ EMSG(_(e_dictreq));
+ }
+ tv_list_append_number(retlist, retval);
+ });
}
/// Place a new sign using the values specified in dict 'dict'. Returns the sign
/// identifier if successfully placed, otherwise returns 0.
-int sign_place_from_dict(
- typval_T *id_tv,
- typval_T *group_tv,
- typval_T *name_tv,
- typval_T *buf_tv,
- dict_T *dict)
+int sign_place_from_dict(typval_T *id_tv, typval_T *group_tv, typval_T *name_tv, typval_T *buf_tv,
+ dict_T *dict)
{
int sign_id = 0;
char_u *group = NULL;
diff --git a/src/nvim/spell.c b/src/nvim/spell.c
index 771c2106db..3e56ad561b 100644
--- a/src/nvim/spell.c
+++ b/src/nvim/spell.c
@@ -72,15 +72,14 @@
#include <inttypes.h>
#include <limits.h>
#include <stdbool.h>
-#include <string.h>
#include <stdlib.h>
+#include <string.h>
#include <wctype.h>
-/* for offsetof() */
+// for offsetof()
#include <stddef.h>
#include "nvim/ascii.h"
-#include "nvim/spell.h"
#include "nvim/buffer.h"
#include "nvim/change.h"
#include "nvim/charset.h"
@@ -92,6 +91,7 @@
#include "nvim/ex_docmd.h"
#include "nvim/fileio.h"
#include "nvim/func_attr.h"
+#include "nvim/garray.h"
#include "nvim/getchar.h"
#include "nvim/hashtab.h"
#include "nvim/mark.h"
@@ -100,21 +100,21 @@
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/garray.h"
#include "nvim/normal.h"
#include "nvim/option.h"
+#include "nvim/os/input.h"
+#include "nvim/os/os.h"
#include "nvim/os_unix.h"
#include "nvim/path.h"
#include "nvim/regexp.h"
#include "nvim/screen.h"
#include "nvim/search.h"
+#include "nvim/spell.h"
#include "nvim/spellfile.h"
#include "nvim/strings.h"
#include "nvim/syntax.h"
-#include "nvim/undo.h"
#include "nvim/ui.h"
-#include "nvim/os/os.h"
-#include "nvim/os/input.h"
+#include "nvim/undo.h"
// only used for su_badflags
#define WF_MIXCAP 0x20 // mix of upper and lower case: macaRONI
@@ -151,26 +151,26 @@ typedef struct suginfo_S {
int su_maxscore; // maximum score for adding to su_ga
int su_sfmaxscore; // idem, for when doing soundfold words
garray_T su_sga; // like su_ga, sound-folded scoring
- char_u *su_badptr; // start of bad word in line
+ char_u *su_badptr; // start of bad word in line
int su_badlen; // length of detected bad word in line
int su_badflags; // caps flags for bad word
char_u su_badword[MAXWLEN]; // bad word truncated at su_badlen
char_u su_fbadword[MAXWLEN]; // su_badword case-folded
char_u su_sal_badword[MAXWLEN]; // su_badword soundfolded
hashtab_T su_banned; // table with banned words
- slang_T *su_sallang; // default language for sound folding
+ slang_T *su_sallang; // default language for sound folding
} suginfo_T;
// One word suggestion. Used in "si_ga".
typedef struct {
- char_u *st_word; // suggested word, allocated string
+ char_u *st_word; // suggested word, allocated string
int st_wordlen; // STRLEN(st_word)
int st_orglen; // length of replaced text
int st_score; // lower is better
int st_altscore; // used when st_score compares equal
bool st_salscore; // st_score is for soundalike
bool st_had_bonus; // bonus already included in score
- slang_T *st_slang; // language used for sound folding
+ slang_T *st_slang; // language used for sound folding
} suggest_T;
#define SUG(ga, i) (((suggest_T *)(ga).ga_data)[i])
@@ -235,14 +235,14 @@ typedef struct {
// Structure to store info for word matching.
typedef struct matchinf_S {
- langp_T *mi_lp; // info for language and region
+ langp_T *mi_lp; // info for language and region
// pointers to original text to be checked
- char_u *mi_word; // start of word being checked
- char_u *mi_end; // end of matching word so far
- char_u *mi_fend; // next char to be added to mi_fword
- char_u *mi_cend; // char after what was used for
- // mi_capflags
+ char_u *mi_word; // start of word being checked
+ char_u *mi_end; // end of matching word so far
+ char_u *mi_fend; // next char to be added to mi_fword
+ char_u *mi_cend; // char after what was used for
+ // mi_capflags
// case-folded text
char_u mi_fword[MAXWLEN + 1]; // mi_word case-folded
@@ -265,11 +265,11 @@ typedef struct matchinf_S {
// others
int mi_result; // result so far: SP_BAD, SP_OK, etc.
int mi_capflags; // WF_ONECAP WF_ALLCAP WF_KEEPCAP
- win_T *mi_win; // buffer being checked
+ win_T *mi_win; // buffer being checked
// for NOBREAK
int mi_result2; // "mi_resul" without following word
- char_u *mi_end2; // "mi_end" without following word
+ char_u *mi_end2; // "mi_end" without following word
} matchinf_T;
// Structure used for the cookie argument of do_in_runtimepath().
@@ -334,26 +334,24 @@ char *e_format = N_("E759: Format error in spell file");
static char_u *repl_from = NULL;
static char_u *repl_to = NULL;
-// Main spell-checking function.
-// "ptr" points to a character that could be the start of a word.
-// "*attrp" is set to the highlight index for a badly spelled word. For a
-// non-word or when it's OK it remains unchanged.
-// This must only be called when 'spelllang' is not empty.
-//
-// "capcol" is used to check for a Capitalised word after the end of a
-// sentence. If it's zero then perform the check. Return the column where to
-// check next, or -1 when no sentence end was found. If it's NULL then don't
-// worry.
-//
-// Returns the length of the word in bytes, also when it's OK, so that the
-// caller can skip over the word.
-size_t spell_check(
- win_T *wp, // current window
- char_u *ptr,
- hlf_T *attrp,
- int *capcol, // column to check for Capital
- bool docount // count good words
-)
+/// Main spell-checking function.
+/// "ptr" points to a character that could be the start of a word.
+/// "*attrp" is set to the highlight index for a badly spelled word. For a
+/// non-word or when it's OK it remains unchanged.
+/// This must only be called when 'spelllang' is not empty.
+///
+/// "capcol" is used to check for a Capitalised word after the end of a
+/// sentence. If it's zero then perform the check. Return the column where to
+/// check next, or -1 when no sentence end was found. If it's NULL then don't
+/// worry.
+///
+/// @param wp current window
+/// @param capcol column to check for Capital
+/// @param docount count good words
+///
+/// @return the length of the word in bytes, also when it's OK, so that the
+/// caller can skip over the word.
+size_t spell_check(win_T *wp, char_u *ptr, hlf_T *attrp, int *capcol, bool docount)
{
matchinf_T mi; // Most things are put in "mi" so that it can
// be passed to functions quickly.
@@ -383,7 +381,7 @@ size_t spell_check(
// julifeest".
if (*ptr >= '0' && *ptr <= '9') {
if (*ptr == '0' && (ptr[1] == 'b' || ptr[1] == 'B')) {
- mi.mi_end = (char_u*) skipbin((char*) ptr + 2);
+ mi.mi_end = (char_u *)skipbin((char *)ptr + 2);
} else if (*ptr == '0' && (ptr[1] == 'x' || ptr[1] == 'X')) {
mi.mi_end = skiphex(ptr + 2);
} else {
@@ -486,7 +484,7 @@ size_t spell_check(
// Count the word in the first language where it's found to be OK.
if (count_word && mi.mi_result == SP_OK) {
count_common_word(mi.mi_lp->lp_slang, ptr,
- (int)(mi.mi_end - ptr), 1);
+ (int)(mi.mi_end - ptr), 1);
count_word = false;
}
}
@@ -499,8 +497,8 @@ size_t spell_check(
return nrlen;
}
} else if (!spell_iswordp_nmw(ptr, wp)) {
- // When we are at a non-word character there is no error, just
- // skip over the character (try looking for a word after it).
+ // When we are at a non-word character there is no error, just
+ // skip over the character (try looking for a word after it).
if (capcol != NULL && wp->w_s->b_cap_prog != NULL) {
regmatch_T regmatch;
@@ -521,7 +519,7 @@ size_t spell_check(
MB_PTR_ADV(mi.mi_end);
} else if (mi.mi_result == SP_BAD
&& LANGP_ENTRY(wp->w_s->b_langp, 0)->lp_slang->sl_nobreak) {
- char_u *p, *fp;
+ char_u *p, *fp;
int save_result = mi.mi_result;
// First language in 'spelllang' is NOBREAK. Find first position
@@ -576,10 +574,10 @@ static void find_word(matchinf_T *mip, int mode)
{
int wlen = 0;
int flen;
- char_u *ptr;
- slang_T *slang = mip->mi_lp->lp_slang;
- char_u *byts;
- idx_T *idxs;
+ char_u *ptr;
+ slang_T *slang = mip->mi_lp->lp_slang;
+ char_u *byts;
+ idx_T *idxs;
if (mode == FIND_KEEPWORD || mode == FIND_KEEPCOMPOUND) {
// Check for word with matching case in keep-case tree.
@@ -588,9 +586,10 @@ static void find_word(matchinf_T *mip, int mode)
byts = slang->sl_kbyts;
idxs = slang->sl_kidxs;
- if (mode == FIND_KEEPCOMPOUND)
+ if (mode == FIND_KEEPCOMPOUND) {
// Skip over the previously found word(s).
wlen += mip->mi_compoff;
+ }
} else {
// Check for case-folded in case-folded tree.
ptr = mip->mi_fword;
@@ -607,12 +606,11 @@ static void find_word(matchinf_T *mip, int mode)
wlen = mip->mi_compoff;
flen -= mip->mi_compoff;
}
-
}
- if (byts == NULL)
+ if (byts == NULL) {
return; // array is empty
-
+ }
idx_T arridx = 0;
int endlen[MAXWLEN]; // length at possible word endings
idx_T endidx[MAXWLEN]; // possible word endings
@@ -625,8 +623,9 @@ static void find_word(matchinf_T *mip, int mode)
// - we reach the end of the tree,
// - or we reach the end of the line.
for (;; ) {
- if (flen <= 0 && *mip->mi_fend != NUL)
+ if (flen <= 0 && *mip->mi_fend != NUL) {
flen = fold_more(mip);
+ }
len = byts[arridx++];
@@ -648,35 +647,39 @@ static void find_word(matchinf_T *mip, int mode)
++arridx;
--len;
}
- if (len == 0)
+ if (len == 0) {
break; // no children, word must end here
+ }
}
// Stop looking at end of the line.
- if (ptr[wlen] == NUL)
+ if (ptr[wlen] == NUL) {
break;
+ }
// Perform a binary search in the list of accepted bytes.
c = ptr[wlen];
- if (c == TAB) // <Tab> is handled like <Space>
+ if (c == TAB) { // <Tab> is handled like <Space>
c = ' ';
+ }
idx_T lo = arridx;
idx_T hi = arridx + len - 1;
while (lo < hi) {
idx_T m = (lo + hi) / 2;
- if (byts[m] > c)
+ if (byts[m] > c) {
hi = m - 1;
- else if (byts[m] < c)
+ } else if (byts[m] < c) {
lo = m + 1;
- else {
+ } else {
lo = hi = m;
break;
}
}
// Stop if there is no matching byte.
- if (hi < lo || byts[lo] != c)
+ if (hi < lo || byts[lo] != c) {
break;
+ }
// Continue at the child (if there is one).
arridx = idxs[lo];
@@ -687,10 +690,12 @@ static void find_word(matchinf_T *mip, int mode)
// checked word.
if (c == ' ') {
for (;; ) {
- if (flen <= 0 && *mip->mi_fend != NUL)
+ if (flen <= 0 && *mip->mi_fend != NUL) {
flen = fold_more(mip);
- if (ptr[wlen] != ' ' && ptr[wlen] != TAB)
+ }
+ if (ptr[wlen] != ' ' && ptr[wlen] != TAB) {
break;
+ }
++wlen;
--flen;
}
@@ -711,11 +716,13 @@ static void find_word(matchinf_T *mip, int mode)
continue; // not at first byte of character
}
if (spell_iswordp(ptr + wlen, mip->mi_win)) {
- if (slang->sl_compprog == NULL && !slang->sl_nobreak)
+ if (slang->sl_compprog == NULL && !slang->sl_nobreak) {
continue; // next char is a word character
+ }
word_ends = false;
- } else
+ } else {
word_ends = true;
+ }
// The prefix flag is before compound flags. Once a valid prefix flag
// has been found we try compound flags.
bool prefix_found = false;
@@ -754,23 +761,26 @@ static void find_word(matchinf_T *mip, int mode)
}
if (mip->mi_capflags == WF_KEEPCAP
- || !spell_valid_case(mip->mi_capflags, flags))
+ || !spell_valid_case(mip->mi_capflags, flags)) {
continue;
+ }
}
// When mode is FIND_PREFIX the word must support the prefix:
// check the prefix ID and the condition. Do that for the list at
// mip->mi_prefarridx that find_prefix() filled.
else if (mode == FIND_PREFIX && !prefix_found) {
c = valid_word_prefix(mip->mi_prefcnt, mip->mi_prefarridx,
- flags,
- mip->mi_word + mip->mi_cprefixlen, slang,
- false);
- if (c == 0)
+ flags,
+ mip->mi_word + mip->mi_cprefixlen, slang,
+ false);
+ if (c == 0) {
continue;
+ }
// Use the WF_RARE flag for a rare prefix.
- if (c & WF_RAREPFX)
+ if (c & WF_RAREPFX) {
flags |= WF_RARE;
+ }
prefix_found = true;
}
@@ -790,8 +800,9 @@ static void find_word(matchinf_T *mip, int mode)
// that's too short... Myspell compatibility requires this
// anyway.
if (((unsigned)flags >> 24) == 0
- || wlen - mip->mi_compoff < slang->sl_compminlen)
+ || wlen - mip->mi_compoff < slang->sl_compminlen) {
continue;
+ }
// For multi-byte chars check character length against
// COMPOUNDMIN.
if (slang->sl_compminlen > 0
@@ -804,27 +815,32 @@ static void find_word(matchinf_T *mip, int mode)
// maximum for syllables is specified.
if (!word_ends && mip->mi_complen + mip->mi_compextra + 2
> slang->sl_compmax
- && slang->sl_compsylmax == MAXWLEN)
+ && slang->sl_compsylmax == MAXWLEN) {
continue;
+ }
// Don't allow compounding on a side where an affix was added,
// unless COMPOUNDPERMITFLAG was used.
- if (mip->mi_complen > 0 && (flags & WF_NOCOMPBEF))
+ if (mip->mi_complen > 0 && (flags & WF_NOCOMPBEF)) {
continue;
- if (!word_ends && (flags & WF_NOCOMPAFT))
+ }
+ if (!word_ends && (flags & WF_NOCOMPAFT)) {
continue;
+ }
// Quickly check if compounding is possible with this flag.
if (!byte_in_str(mip->mi_complen == 0
? slang->sl_compstartflags
: slang->sl_compallflags,
- ((unsigned)flags >> 24)))
+ ((unsigned)flags >> 24))) {
continue;
+ }
// If there is a match with a CHECKCOMPOUNDPATTERN rule
// discard the compound word.
- if (match_checkcompoundpattern(ptr, wlen, &slang->sl_comppat))
+ if (match_checkcompoundpattern(ptr, wlen, &slang->sl_comppat)) {
continue;
+ }
if (mode == FIND_COMPOUND) {
int capflags;
@@ -842,8 +858,9 @@ static void find_word(matchinf_T *mip, int mode)
}
capflags = captype(p, mip->mi_word + wlen);
if (capflags == WF_KEEPCAP || (capflags == WF_ALLCAP
- && (flags & WF_FIXCAP) != 0))
+ && (flags & WF_FIXCAP) != 0)) {
continue;
+ }
if (capflags != WF_ALLCAP) {
// When the character before the word is a word
@@ -876,23 +893,26 @@ static void find_word(matchinf_T *mip, int mode)
STRLCPY(fword, ptr, endlen[endidxcnt] + 1);
}
}
- if (!can_compound(slang, fword, mip->mi_compflags))
+ if (!can_compound(slang, fword, mip->mi_compflags)) {
continue;
+ }
} else if (slang->sl_comprules != NULL
- && !match_compoundrule(slang, mip->mi_compflags))
+ && !match_compoundrule(slang, mip->mi_compflags)) {
// The compound flags collected so far do not match any
// COMPOUNDRULE, discard the compounded word.
continue;
+ }
}
// Check NEEDCOMPOUND: can't use word without compounding.
- else if (flags & WF_NEEDCOMP)
+ else if (flags & WF_NEEDCOMP) {
continue;
+ }
int nobreak_result = SP_OK;
if (!word_ends) {
int save_result = mip->mi_result;
- char_u *save_end = mip->mi_end;
+ char_u *save_end = mip->mi_end;
langp_T *save_lp = mip->mi_lp;
// Check that a valid word follows. If there is one and we
@@ -900,8 +920,9 @@ static void find_word(matchinf_T *mip, int mode)
// always finished here. For NOBREAK we only check that a
// valid word follows.
// Recursive!
- if (slang->sl_nobreak)
+ if (slang->sl_nobreak) {
mip->mi_result = SP_BAD;
+ }
// Find following word in case-folded tree.
mip->mi_compoff = endlen[endidxcnt];
@@ -922,8 +943,9 @@ static void find_word(matchinf_T *mip, int mode)
c = mip->mi_compoff;
#endif
++mip->mi_complen;
- if (flags & WF_COMPROOT)
+ if (flags & WF_COMPROOT) {
++mip->mi_compextra;
+ }
// For NOBREAK we need to try all NOBREAK languages, at least
// to find the ".add" file(s).
@@ -931,8 +953,9 @@ static void find_word(matchinf_T *mip, int mode)
if (slang->sl_nobreak) {
mip->mi_lp = LANGP_ENTRY(mip->mi_win->w_s->b_langp, lpi);
if (mip->mi_lp->lp_slang->sl_fidxs == NULL
- || !mip->mi_lp->lp_slang->sl_nobreak)
+ || !mip->mi_lp->lp_slang->sl_nobreak) {
continue;
+ }
}
find_word(mip, FIND_COMPOUND);
@@ -956,12 +979,14 @@ static void find_word(matchinf_T *mip, int mode)
#endif
}
- if (!slang->sl_nobreak)
+ if (!slang->sl_nobreak) {
break;
+ }
}
--mip->mi_complen;
- if (flags & WF_COMPROOT)
+ if (flags & WF_COMPROOT) {
--mip->mi_compextra;
+ }
mip->mi_lp = save_lp;
if (slang->sl_nobreak) {
@@ -969,25 +994,28 @@ static void find_word(matchinf_T *mip, int mode)
mip->mi_result = save_result;
mip->mi_end = save_end;
} else {
- if (mip->mi_result == SP_OK)
+ if (mip->mi_result == SP_OK) {
break;
+ }
continue;
}
}
int res = SP_BAD;
- if (flags & WF_BANNED)
+ if (flags & WF_BANNED) {
res = SP_BANNED;
- else if (flags & WF_REGION) {
+ } else if (flags & WF_REGION) {
// Check region.
- if ((mip->mi_lp->lp_region & (flags >> 16)) != 0)
+ if ((mip->mi_lp->lp_region & (flags >> 16)) != 0) {
res = SP_OK;
- else
+ } else {
res = SP_LOCAL;
- } else if (flags & WF_RARE)
+ }
+ } else if (flags & WF_RARE) {
res = SP_RARE;
- else
+ } else {
res = SP_OK;
+ }
// Always use the longest match and the best result. For NOBREAK
// we separately keep the longest match without a following good
@@ -997,36 +1025,37 @@ static void find_word(matchinf_T *mip, int mode)
mip->mi_result2 = res;
mip->mi_end2 = mip->mi_word + wlen;
} else if (mip->mi_result2 == res
- && mip->mi_end2 < mip->mi_word + wlen)
+ && mip->mi_end2 < mip->mi_word + wlen) {
mip->mi_end2 = mip->mi_word + wlen;
+ }
} else if (mip->mi_result > res) {
mip->mi_result = res;
mip->mi_end = mip->mi_word + wlen;
- } else if (mip->mi_result == res && mip->mi_end < mip->mi_word + wlen)
+ } else if (mip->mi_result == res && mip->mi_end < mip->mi_word + wlen) {
mip->mi_end = mip->mi_word + wlen;
+ }
- if (mip->mi_result == SP_OK)
+ if (mip->mi_result == SP_OK) {
break;
+ }
}
- if (mip->mi_result == SP_OK)
+ if (mip->mi_result == SP_OK) {
break;
+ }
}
}
-// Returns true if there is a match between the word ptr[wlen] and
-// CHECKCOMPOUNDPATTERN rules, assuming that we will concatenate with another
-// word.
-// A match means that the first part of CHECKCOMPOUNDPATTERN matches at the
-// end of ptr[wlen] and the second part matches after it.
-static bool
-match_checkcompoundpattern (
- char_u *ptr,
- int wlen,
- garray_T *gap // &sl_comppat
-)
+/// Returns true if there is a match between the word ptr[wlen] and
+/// CHECKCOMPOUNDPATTERN rules, assuming that we will concatenate with another
+/// word.
+/// A match means that the first part of CHECKCOMPOUNDPATTERN matches at the
+/// end of ptr[wlen] and the second part matches after it.
+///
+/// @param gap &sl_comppat
+static bool match_checkcompoundpattern(char_u *ptr, int wlen, garray_T *gap)
{
- char_u *p;
+ char_u *p;
int len;
for (int i = 0; i + 1 < gap->ga_len; i += 2) {
@@ -1036,8 +1065,9 @@ match_checkcompoundpattern (
// check if first part matches at end of previous word.
p = ((char_u **)gap->ga_data)[i];
len = (int)STRLEN(p);
- if (len <= wlen && STRNCMP(ptr + wlen - len, p, len) == 0)
+ if (len <= wlen && STRNCMP(ptr + wlen - len, p, len) == 0) {
return true;
+ }
}
}
return false;
@@ -1045,8 +1075,7 @@ match_checkcompoundpattern (
// Returns true if "flags" is a valid sequence of compound flags and "word"
// does not have too many syllables.
-static bool can_compound(slang_T *slang, const char_u *word,
- const char_u *flags)
+static bool can_compound(slang_T *slang, const char_u *word, const char_u *flags)
FUNC_ATTR_NONNULL_ALL
{
char_u uflags[MAXWLEN * 2] = { 0 };
@@ -1069,8 +1098,9 @@ static bool can_compound(slang_T *slang, const char_u *word,
// are too many syllables AND the number of compound words is above
// COMPOUNDWORDMAX then compounding is not allowed.
if (slang->sl_compsylmax < MAXWLEN
- && count_syllables(slang, word) > slang->sl_compsylmax)
+ && count_syllables(slang, word) > slang->sl_compsylmax) {
return (int)STRLEN(flags) < slang->sl_compmax;
+ }
return true;
}
@@ -1082,8 +1112,9 @@ static bool can_be_compound(trystate_T *sp, slang_T *slang, char_u *compflags, i
// If the flag doesn't appear in sl_compstartflags or sl_compallflags
// then it can't possibly compound.
if (!byte_in_str(sp->ts_complen == sp->ts_compsplit
- ? slang->sl_compstartflags : slang->sl_compallflags, flag))
+ ? slang->sl_compstartflags : slang->sl_compallflags, flag)) {
return false;
+ }
// If there are no wildcards, we can check if the flags collected so far
// possibly can form a match with COMPOUNDRULE patterns. This only
@@ -1105,7 +1136,7 @@ static bool can_be_compound(trystate_T *sp, slang_T *slang, char_u *compflags, i
// Caller must check that slang->sl_comprules is not NULL.
static bool match_compoundrule(slang_T *slang, char_u *compflags)
{
- char_u *p;
+ char_u *p;
int i;
int c;
@@ -1115,30 +1146,37 @@ static bool match_compoundrule(slang_T *slang, char_u *compflags)
// them against the current rule entry
for (i = 0;; ++i) {
c = compflags[i];
- if (c == NUL)
+ if (c == NUL) {
// found a rule that matches for the flags we have so far
return true;
- if (*p == '/' || *p == NUL)
+ }
+ if (*p == '/' || *p == NUL) {
break; // end of rule, it's too short
+ }
if (*p == '[') {
bool match = false;
// compare against all the flags in []
++p;
- while (*p != ']' && *p != NUL)
- if (*p++ == c)
+ while (*p != ']' && *p != NUL) {
+ if (*p++ == c) {
match = true;
- if (!match)
+ }
+ }
+ if (!match) {
break; // none matches
- } else if (*p != c)
+ }
+ } else if (*p != c) {
break; // flag of word doesn't match flag in pattern
+ }
++p;
}
// Skip to the next "/", where the next pattern starts.
p = vim_strchr(p, '/');
- if (p == NULL)
+ if (p == NULL) {
break;
+ }
}
// Checked all the rules and none of them match the flags, so there
@@ -1146,18 +1184,15 @@ static bool match_compoundrule(slang_T *slang, char_u *compflags)
return false;
}
-// Return non-zero if the prefix indicated by "arridx" matches with the prefix
-// ID in "flags" for the word "word".
-// The WF_RAREPFX flag is included in the return value for a rare prefix.
-static int
-valid_word_prefix (
- int totprefcnt, // nr of prefix IDs
- int arridx, // idx in sl_pidxs[]
- int flags,
- char_u *word,
- slang_T *slang,
- bool cond_req // only use prefixes with a condition
-)
+/// Return non-zero if the prefix indicated by "arridx" matches with the prefix
+/// ID in "flags" for the word "word".
+/// The WF_RAREPFX flag is included in the return value for a rare prefix.
+///
+/// @param totprefcnt nr of prefix IDs
+/// @param arridx idx in sl_pidxs[]
+/// @param cond_req only use prefixes with a condition
+static int valid_word_prefix(int totprefcnt, int arridx, int flags, char_u *word, slang_T *slang,
+ bool cond_req)
{
int prefcnt;
int pidx;
@@ -1168,13 +1203,15 @@ valid_word_prefix (
pidx = slang->sl_pidxs[arridx + prefcnt];
// Check the prefix ID.
- if (prefid != (pidx & 0xff))
+ if (prefid != (pidx & 0xff)) {
continue;
+ }
// Check if the prefix doesn't combine and the word already has a
// suffix.
- if ((flags & WF_HAS_AFF) && (pidx & WF_PFX_NC))
+ if ((flags & WF_HAS_AFF) && (pidx & WF_PFX_NC)) {
continue;
+ }
// Check the condition, if there is one. The condition index is
// stored in the two bytes above the prefix ID byte.
@@ -1183,8 +1220,9 @@ valid_word_prefix (
if (!vim_regexec_prog(rp, false, word, 0)) {
continue;
}
- } else if (cond_req)
+ } else if (cond_req) {
continue;
+ }
// It's a match! Return the WF_ flags.
return pidx;
@@ -1206,16 +1244,16 @@ static void find_prefix(matchinf_T *mip, int mode)
int wlen = 0;
int flen;
int c;
- char_u *ptr;
+ char_u *ptr;
idx_T lo, hi, m;
- slang_T *slang = mip->mi_lp->lp_slang;
- char_u *byts;
- idx_T *idxs;
+ slang_T *slang = mip->mi_lp->lp_slang;
+ char_u *byts;
+ idx_T *idxs;
byts = slang->sl_pbyts;
- if (byts == NULL)
+ if (byts == NULL) {
return; // array is empty
-
+ }
// We use the case-folded word here, since prefixes are always
// case-folded.
ptr = mip->mi_fword;
@@ -1232,8 +1270,9 @@ static void find_prefix(matchinf_T *mip, int mode)
// - we reach the end of the tree,
// - or we reach the end of the line.
for (;; ) {
- if (flen == 0 && *mip->mi_fend != NUL)
+ if (flen == 0 && *mip->mi_fend != NUL) {
flen = fold_more(mip);
+ }
len = byts[arridx++];
@@ -1254,9 +1293,10 @@ static void find_prefix(matchinf_T *mip, int mode)
// Find the word that comes after the prefix.
mip->mi_prefixlen = wlen;
- if (mode == FIND_COMPOUND)
+ if (mode == FIND_COMPOUND) {
// Skip over the previously found word(s).
mip->mi_prefixlen += mip->mi_compoff;
+ }
// Case-folded length may differ from original length.
mip->mi_cprefixlen = nofold_len(mip->mi_fword, mip->mi_prefixlen,
@@ -1264,13 +1304,15 @@ static void find_prefix(matchinf_T *mip, int mode)
find_word(mip, FIND_PREFIX);
- if (len == 0)
+ if (len == 0) {
break; // no children, word must end here
+ }
}
// Stop looking at end of the line.
- if (ptr[wlen] == NUL)
+ if (ptr[wlen] == NUL) {
break;
+ }
// Perform a binary search in the list of accepted bytes.
c = ptr[wlen];
@@ -1278,19 +1320,20 @@ static void find_prefix(matchinf_T *mip, int mode)
hi = arridx + len - 1;
while (lo < hi) {
m = (lo + hi) / 2;
- if (byts[m] > c)
+ if (byts[m] > c) {
hi = m - 1;
- else if (byts[m] < c)
+ } else if (byts[m] < c) {
lo = m + 1;
- else {
+ } else {
lo = hi = m;
break;
}
}
// Stop if there is no matching byte.
- if (hi < lo || byts[lo] != c)
+ if (hi < lo || byts[lo] != c) {
break;
+ }
// Continue at the child (if there is one).
arridx = idxs[lo];
@@ -1305,7 +1348,7 @@ static void find_prefix(matchinf_T *mip, int mode)
static int fold_more(matchinf_T *mip)
{
int flen;
- char_u *p;
+ char_u *p;
p = mip->mi_fend;
do {
@@ -1349,42 +1392,40 @@ static bool no_spell_checking(win_T *wp)
return false;
}
-// Moves to the next spell error.
-// "curline" is false for "[s", "]s", "[S" and "]S".
-// "curline" is true to find word under/after cursor in the same line.
-// For Insert mode completion "dir" is BACKWARD and "curline" is true: move
-// to after badly spelled word before the cursor.
-// Return 0 if not found, length of the badly spelled word otherwise.
-size_t
-spell_move_to (
- win_T *wp,
- int dir, // FORWARD or BACKWARD
- bool allwords, // true for "[s"/"]s", false for "[S"/"]S"
- bool curline,
- hlf_T *attrp // return: attributes of bad word or NULL
- // (only when "dir" is FORWARD)
-)
+/// Moves to the next spell error.
+/// "curline" is false for "[s", "]s", "[S" and "]S".
+/// "curline" is true to find word under/after cursor in the same line.
+/// For Insert mode completion "dir" is BACKWARD and "curline" is true: move
+/// to after badly spelled word before the cursor.
+///
+/// @param dir FORWARD or BACKWARD
+/// @param allwords true for "[s"/"]s", false for "[S"/"]S"
+/// @param attrp return: attributes of bad word or NULL (only when "dir" is FORWARD)
+///
+/// @return 0 if not found, length of the badly spelled word otherwise.
+size_t spell_move_to(win_T *wp, int dir, bool allwords, bool curline, hlf_T *attrp)
{
linenr_T lnum;
pos_T found_pos;
size_t found_len = 0;
- char_u *line;
- char_u *p;
- char_u *endp;
+ char_u *line;
+ char_u *p;
+ char_u *endp;
hlf_T attr = HLF_COUNT;
size_t len;
int has_syntax = syntax_present(wp);
int col;
bool can_spell;
- char_u *buf = NULL;
+ char_u *buf = NULL;
size_t buflen = 0;
int skip = 0;
int capcol = -1;
bool found_one = false;
bool wrapped = false;
- if (no_spell_checking(wp))
+ if (no_spell_checking(wp)) {
return 0;
+ }
// Start looking for bad word at the start of the line, because we can't
// start halfway through a word, we don't know where it starts or ends.
@@ -1399,7 +1440,7 @@ spell_move_to (
clearpos(&found_pos);
while (!got_int) {
- line = ml_get_buf(wp->w_buffer, lnum, FALSE);
+ line = ml_get_buf(wp->w_buffer, lnum, false);
len = STRLEN(line);
if (buflen < len + MAXWLEN + 2) {
@@ -1410,8 +1451,9 @@ spell_move_to (
assert(buf && buflen >= len + MAXWLEN + 2);
// In first line check first word for Capital.
- if (lnum == 1)
+ if (lnum == 1) {
capcol = 0;
+ }
// For checking first word with a capital skip white space.
if (capcol == 0) {
@@ -1425,16 +1467,17 @@ spell_move_to (
// Need to get the line again, may have looked at the previous
// one.
- line = ml_get_buf(wp->w_buffer, lnum, FALSE);
+ line = ml_get_buf(wp->w_buffer, lnum, false);
}
// Copy the line into "buf" and append the start of the next line if
// possible.
STRCPY(buf, line);
- if (lnum < wp->w_buffer->b_ml.ml_line_count)
+ if (lnum < wp->w_buffer->b_ml.ml_line_count) {
spell_cat_line(buf + STRLEN(buf),
- ml_get_buf(wp->w_buffer, lnum + 1, FALSE),
+ ml_get_buf(wp->w_buffer, lnum + 1, false),
MAXWLEN);
+ }
p = buf + skip;
endp = buf + len;
while (p < endp) {
@@ -1443,8 +1486,9 @@ spell_move_to (
if (dir == BACKWARD
&& lnum == wp->w_cursor.lnum
&& !wrapped
- && (colnr_T)(p - buf) >= wp->w_cursor.col)
+ && (colnr_T)(p - buf) >= wp->w_cursor.col) {
break;
+ }
// start of word
attr = HLF_COUNT;
@@ -1464,11 +1508,13 @@ spell_move_to (
if (has_syntax) {
col = (int)(p - buf);
(void)syn_get_id(wp, lnum, (colnr_T)col,
- FALSE, &can_spell, FALSE);
- if (!can_spell)
+ FALSE, &can_spell, FALSE);
+ if (!can_spell) {
attr = HLF_COUNT;
- } else
+ }
+ } else {
can_spell = true;
+ }
if (can_spell) {
found_one = true;
@@ -1479,8 +1525,9 @@ spell_move_to (
// No need to search further.
wp->w_cursor = found_pos;
xfree(buf);
- if (attrp != NULL)
+ if (attrp != NULL) {
*attrp = attr;
+ }
return len;
} else if (curline) {
// Insert mode completion: put cursor after
@@ -1490,8 +1537,9 @@ spell_move_to (
}
found_len = len;
}
- } else
+ } else {
found_one = true;
+ }
}
}
@@ -1529,22 +1577,24 @@ spell_move_to (
// starting line again and accept the last match.
lnum = wp->w_buffer->b_ml.ml_line_count;
wrapped = true;
- if (!shortmess(SHM_SEARCH))
+ if (!shortmess(SHM_SEARCH)) {
give_warning((char_u *)_(top_bot_msg), true);
+ }
}
capcol = -1;
} else {
- if (lnum < wp->w_buffer->b_ml.ml_line_count)
+ if (lnum < wp->w_buffer->b_ml.ml_line_count) {
++lnum;
- else if (!p_ws)
+ } else if (!p_ws) {
break; // at first line and 'nowrapscan'
- else {
+ } else {
// Wrap around to the start of the buffer. May search the
// starting line again and accept the first match.
lnum = 1;
wrapped = true;
- if (!shortmess(SHM_SEARCH))
+ if (!shortmess(SHM_SEARCH)) {
give_warning((char_u *)_(bot_top_msg), true);
+ }
}
// If we are back at the starting line and there is no match then
@@ -1555,17 +1605,19 @@ spell_move_to (
// Skip the characters at the start of the next line that were
// included in a match crossing line boundaries.
- if (attr == HLF_COUNT)
+ if (attr == HLF_COUNT) {
skip = (int)(p - endp);
- else
+ } else {
skip = 0;
+ }
// Capcol skips over the inserted space.
--capcol;
// But after empty line check first word in next line
- if (*skipwhite(line) == NUL)
+ if (*skipwhite(line) == NUL) {
capcol = 0;
+ }
}
line_breakcheck();
@@ -1581,12 +1633,13 @@ spell_move_to (
// to skip those bytes if the word was OK.
void spell_cat_line(char_u *buf, char_u *line, int maxlen)
{
- char_u *p;
+ char_u *p;
int n;
p = skipwhite(line);
- while (vim_strchr((char_u *)"*#/\"\t", *p) != NULL)
+ while (vim_strchr((char_u *)"*#/\"\t", *p) != NULL) {
p = skipwhite(p + 1);
+ }
if (*p != NUL) {
// Only worth concatenating if there is something else than spaces to
@@ -1630,8 +1683,9 @@ static void spell_load_lang(char_u *lang)
if (r == FAIL && *sl.sl_lang != NUL && round == 1
&& apply_autocmds(EVENT_SPELLFILEMISSING, lang,
- curbuf->b_fname, FALSE, curbuf))
+ curbuf->b_fname, FALSE, curbuf)) {
continue;
+ }
break;
}
break;
@@ -1647,9 +1701,8 @@ static void spell_load_lang(char_u *lang)
lang);
do_cmdline_cmd(autocmd_buf);
} else {
- smsg(
- _("Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""),
- lang, spell_enc(), lang);
+ smsg(_("Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""),
+ lang, spell_enc(), lang);
}
} else if (sl.sl_slang != NULL) {
// At least one file was loaded, now load ALL the additions.
@@ -1662,9 +1715,9 @@ static void spell_load_lang(char_u *lang)
// use "latin1" for "latin9". And limit to 60 characters (just in case).
char_u *spell_enc(void)
{
-
- if (STRLEN(p_enc) < 60 && STRCMP(p_enc, "iso-8859-15") != 0)
+ if (STRLEN(p_enc) < 60 && STRCMP(p_enc, "iso-8859-15") != 0) {
return p_enc;
+ }
return (char_u *)"latin1";
}
@@ -1673,7 +1726,7 @@ char_u *spell_enc(void)
static void int_wordlist_spl(char_u *fname)
{
vim_snprintf((char *)fname, MAXPATHL, SPL_FNAME_TMPL,
- int_wordlist, spell_enc());
+ int_wordlist, spell_enc());
}
// Allocate a new slang_T for language "lang". "lang" can be NULL.
@@ -1683,8 +1736,9 @@ slang_T *slang_alloc(char_u *lang)
{
slang_T *lp = xcalloc(1, sizeof(slang_T));
- if (lang != NULL)
+ if (lang != NULL) {
lp->sl_name = vim_strsave(lang);
+ }
ga_init(&lp->sl_rep, sizeof(fromto_T), 10);
ga_init(&lp->sl_repsal, sizeof(fromto_T), 10);
lp->sl_compmax = MAXWLEN;
@@ -1722,7 +1776,7 @@ static void free_fromto(fromto_T *ftp) {
// Clear an slang_T so that the file can be reloaded.
void slang_clear(slang_T *lp)
{
- garray_T *gap;
+ garray_T *gap;
XFREE_CLEAR(lp->sl_fbyts);
XFREE_CLEAR(lp->sl_kbyts);
@@ -1792,17 +1846,18 @@ void slang_clear_sug(slang_T *lp)
// Invoked through do_in_runtimepath().
static void spell_load_cb(char_u *fname, void *cookie)
{
- spelload_T *slp = (spelload_T *)cookie;
- slang_T *slang;
+ spelload_T *slp = (spelload_T *)cookie;
+ slang_T *slang;
slang = spell_load_file(fname, slp->sl_lang, NULL, false);
if (slang != NULL) {
// When a previously loaded file has NOBREAK also use it for the
// ".add" files.
- if (slp->sl_nobreak && slang->sl_add)
+ if (slp->sl_nobreak && slang->sl_add) {
slang->sl_nobreak = true;
- else if (slang->sl_nobreak)
+ } else if (slang->sl_nobreak) {
slp->sl_nobreak = true;
+ }
slp->sl_slang = slang;
}
@@ -1818,10 +1873,10 @@ static void spell_load_cb(char_u *fname, void *cookie)
void count_common_word(slang_T *lp, char_u *word, int len, int count)
{
hash_T hash;
- hashitem_T *hi;
+ hashitem_T *hi;
wordcount_T *wc;
char_u buf[MAXWLEN];
- char_u *p;
+ char_u *p;
if (len == -1) {
p = word;
@@ -1842,21 +1897,18 @@ void count_common_word(slang_T *lp, char_u *word, int len, int count)
hash_add_item(&lp->sl_wordcount, hi, wc->wc_word, hash);
} else {
wc = HI2WC(hi);
- if ((wc->wc_count += count) < (unsigned)count) // check for overflow
+ if ((wc->wc_count += count) < (unsigned)count) { // check for overflow
wc->wc_count = MAXWORDCOUNT;
+ }
}
}
-// Adjust the score of common words.
-static int
-score_wordcount_adj (
- slang_T *slang,
- int score,
- char_u *word,
- bool split // word was split, less bonus
-)
+/// Adjust the score of common words.
+///
+/// @param split word was split, less bonus
+static int score_wordcount_adj(slang_T *slang, int score, char_u *word, bool split)
{
- hashitem_T *hi;
+ hashitem_T *hi;
wordcount_T *wc;
int bonus;
int newscore;
@@ -1864,18 +1916,21 @@ score_wordcount_adj (
hi = hash_find(&slang->sl_wordcount, word);
if (!HASHITEM_EMPTY(hi)) {
wc = HI2WC(hi);
- if (wc->wc_count < SCORE_THRES2)
+ if (wc->wc_count < SCORE_THRES2) {
bonus = SCORE_COMMON1;
- else if (wc->wc_count < SCORE_THRES3)
+ } else if (wc->wc_count < SCORE_THRES3) {
bonus = SCORE_COMMON2;
- else
+ } else {
bonus = SCORE_COMMON3;
- if (split)
+ }
+ if (split) {
newscore = score - bonus / 2;
- else
+ } else {
newscore = score - bonus;
- if (newscore < 0)
+ }
+ if (newscore < 0) {
return 0;
+ }
return newscore;
}
return score;
@@ -1885,11 +1940,13 @@ score_wordcount_adj (
// Like strchr() but independent of locale.
bool byte_in_str(char_u *str, int n)
{
- char_u *p;
+ char_u *p;
- for (p = str; *p != NUL; ++p)
- if (*p == n)
+ for (p = str; *p != NUL; ++p) {
+ if (*p == n) {
return true;
+ }
+ }
return false;
}
@@ -1897,24 +1954,27 @@ bool byte_in_str(char_u *str, int n)
// in "slang->sl_syl_items".
int init_syl_tab(slang_T *slang)
{
- char_u *p;
- char_u *s;
+ char_u *p;
+ char_u *s;
int l;
ga_init(&slang->sl_syl_items, sizeof(syl_item_T), 4);
p = vim_strchr(slang->sl_syllable, '/');
while (p != NULL) {
*p++ = NUL;
- if (*p == NUL) // trailing slash
+ if (*p == NUL) { // trailing slash
break;
+ }
s = p;
p = vim_strchr(p, '/');
- if (p == NULL)
+ if (p == NULL) {
l = (int)STRLEN(s);
- else
+ } else {
l = (int)(p - s);
- if (l >= SY_MAXLEN)
+ }
+ if (l >= SY_MAXLEN) {
return SP_FORMERROR;
+ }
syl_item_T *syl = GA_APPEND_VIA_PTR(syl_item_T, &slang->sl_syl_items);
STRLCPY(syl->sy_chars, s, l + 1);
@@ -1932,11 +1992,12 @@ static int count_syllables(slang_T *slang, const char_u *word)
int cnt = 0;
bool skip = false;
int len;
- syl_item_T *syl;
+ syl_item_T *syl;
int c;
- if (slang->sl_syllable == NULL)
+ if (slang->sl_syllable == NULL) {
return 0;
+ }
for (const char_u *p = word; *p != NUL; p += len) {
// When running into a space reset counter.
@@ -1951,8 +2012,9 @@ static int count_syllables(slang_T *slang, const char_u *word)
for (int i = 0; i < slang->sl_syl_items.ga_len; ++i) {
syl = ((syl_item_T *)slang->sl_syl_items.ga_data) + i;
if (syl->sy_len > len
- && STRNCMP(p, syl->sy_chars, syl->sy_len) == 0)
+ && STRNCMP(p, syl->sy_chars, syl->sy_len) == 0) {
len = syl->sy_len;
+ }
}
if (len != 0) { // found a match, count syllable
++cnt;
@@ -1961,9 +2023,9 @@ static int count_syllables(slang_T *slang, const char_u *word)
// No recognized syllable item, at least a syllable char then?
c = utf_ptr2char(p);
len = (*mb_ptr2len)(p);
- if (vim_strchr(slang->sl_syllable, c) == NULL)
+ if (vim_strchr(slang->sl_syllable, c) == NULL) {
skip = false; // No, search for next syllable
- else if (!skip) {
+ } else if (!skip) {
++cnt; // Yes, count it
skip = true; // don't count following syllable chars
}
@@ -1977,26 +2039,26 @@ static int count_syllables(slang_T *slang, const char_u *word)
char_u *did_set_spelllang(win_T *wp)
{
garray_T ga;
- char_u *splp;
- char_u *region;
+ char_u *splp;
+ char_u *region;
char_u region_cp[3];
bool filename;
int region_mask;
- slang_T *slang;
+ slang_T *slang;
int c;
char_u lang[MAXWLEN + 1];
char_u spf_name[MAXPATHL];
int len;
- char_u *p;
+ char_u *p;
int round;
- char_u *spf;
- char_u *use_region = NULL;
+ char_u *spf;
+ char_u *use_region = NULL;
bool dont_use_region = false;
bool nobreak = false;
- langp_T *lp, *lp2;
+ langp_T *lp, *lp2;
static bool recursive = false;
- char_u *ret_msg = NULL;
- char_u *spl_copy;
+ char_u *ret_msg = NULL;
+ char_u *spl_copy;
bufref_T bufref;
set_bufref(&bufref, wp->w_buffer);
@@ -2004,8 +2066,9 @@ char_u *did_set_spelllang(win_T *wp)
// We don't want to do this recursively. May happen when a language is
// not available and the SpellFileMissing autocommand opens a new buffer
// in which 'spell' is set.
- if (recursive)
+ if (recursive) {
return NULL;
+ }
recursive = true;
ga_init(&ga, sizeof(langp_T), 2);
@@ -2046,8 +2109,9 @@ char_u *did_set_spelllang(win_T *wp)
STRLCPY(region_cp, p + 1, 3);
memmove(p, p + 3, len - (p - lang) - 2);
region = region_cp;
- } else
+ } else {
dont_use_region = true;
+ }
// Check if we loaded this language before.
for (slang = first_lang; slang != NULL; slang = slang->sl_next) {
@@ -2061,28 +2125,32 @@ char_u *did_set_spelllang(win_T *wp)
if (len > 3 && lang[len - 3] == '_') {
region = lang + len - 2;
lang[len - 3] = NUL;
- } else
+ } else {
dont_use_region = true;
+ }
// Check if we loaded this language before.
- for (slang = first_lang; slang != NULL; slang = slang->sl_next)
- if (STRICMP(lang, slang->sl_name) == 0)
+ for (slang = first_lang; slang != NULL; slang = slang->sl_next) {
+ if (STRICMP(lang, slang->sl_name) == 0) {
break;
+ }
+ }
}
if (region != NULL) {
// If the region differs from what was used before then don't
// use it for 'spellfile'.
- if (use_region != NULL && STRCMP(region, use_region) != 0)
+ if (use_region != NULL && STRCMP(region, use_region) != 0) {
dont_use_region = true;
+ }
use_region = region;
}
// If not found try loading the language now.
if (slang == NULL) {
- if (filename)
+ if (filename) {
(void)spell_load_file(lang, lang, NULL, false);
- else {
+ } else {
spell_load_lang(lang);
// SpellFileMissing autocommands may do anything, including
// destroying the buffer we are using...
@@ -2105,16 +2173,19 @@ char_u *did_set_spelllang(win_T *wp)
c = find_region(slang->sl_regions, region);
if (c == REGION_ALL) {
if (slang->sl_add) {
- if (*slang->sl_regions != NUL)
+ if (*slang->sl_regions != NUL) {
// This addition file is for other regions.
region_mask = 0;
- } else
+ }
+ } else {
// This is probably an error. Give a warning and
// accept the words anyway.
smsg(_("Warning: region %s not supported"),
region);
- } else
+ }
+ } else {
region_mask = 1 << c;
+ }
}
if (region_mask != 0) {
@@ -2123,8 +2194,9 @@ char_u *did_set_spelllang(win_T *wp)
p_->lp_region = region_mask;
use_midword(slang, wp);
- if (slang->sl_nobreak)
+ if (slang->sl_nobreak) {
nobreak = true;
+ }
}
}
}
@@ -2138,8 +2210,9 @@ char_u *did_set_spelllang(win_T *wp)
for (round = 0; round == 0 || *spf != NUL; ++round) {
if (round == 0) {
// Internal wordlist, if there is one.
- if (int_wordlist == NULL)
+ if (int_wordlist == NULL) {
continue;
+ }
int_wordlist_spl(spf_name);
} else {
// One entry in 'spellfile'.
@@ -2154,8 +2227,9 @@ char_u *did_set_spelllang(win_T *wp)
break;
}
}
- if (c < ga.ga_len)
+ if (c < ga.ga_len) {
continue;
+ }
}
// Check if it was loaded already.
@@ -2169,31 +2243,34 @@ char_u *did_set_spelllang(win_T *wp)
// Not loaded, try loading it now. The language name includes the
// region name, the region is ignored otherwise. for int_wordlist
// use an arbitrary name.
- if (round == 0)
+ if (round == 0) {
STRCPY(lang, "internal wordlist");
- else {
+ } else {
STRLCPY(lang, path_tail(spf_name), MAXWLEN + 1);
p = vim_strchr(lang, '.');
- if (p != NULL)
+ if (p != NULL) {
*p = NUL; // truncate at ".encoding.add"
+ }
}
slang = spell_load_file(spf_name, lang, NULL, true);
// If one of the languages has NOBREAK we assume the addition
// files also have this.
- if (slang != NULL && nobreak)
+ if (slang != NULL && nobreak) {
slang->sl_nobreak = true;
+ }
}
if (slang != NULL) {
region_mask = REGION_ALL;
if (use_region != NULL && !dont_use_region) {
// find region in sl_regions
c = find_region(slang->sl_regions, use_region);
- if (c != REGION_ALL)
+ if (c != REGION_ALL) {
region_mask = 1 << c;
- else if (*slang->sl_regions != NUL)
+ } else if (*slang->sl_regions != NUL) {
// This spell file is for other regions.
region_mask = 0;
+ }
}
if (region_mask != 0) {
@@ -2219,36 +2296,38 @@ char_u *did_set_spelllang(win_T *wp)
lp = LANGP_ENTRY(ga, i);
// sound folding
- if (!GA_EMPTY(&lp->lp_slang->sl_sal))
+ if (!GA_EMPTY(&lp->lp_slang->sl_sal)) {
// language does sound folding itself
lp->lp_sallang = lp->lp_slang;
- else
+ } else {
// find first similar language that does sound folding
for (int j = 0; j < ga.ga_len; ++j) {
lp2 = LANGP_ENTRY(ga, j);
if (!GA_EMPTY(&lp2->lp_slang->sl_sal)
&& STRNCMP(lp->lp_slang->sl_name,
- lp2->lp_slang->sl_name, 2) == 0) {
+ lp2->lp_slang->sl_name, 2) == 0) {
lp->lp_sallang = lp2->lp_slang;
break;
}
}
+ }
// REP items
- if (!GA_EMPTY(&lp->lp_slang->sl_rep))
+ if (!GA_EMPTY(&lp->lp_slang->sl_rep)) {
// language has REP items itself
lp->lp_replang = lp->lp_slang;
- else
+ } else {
// find first similar language that has REP items
for (int j = 0; j < ga.ga_len; ++j) {
lp2 = LANGP_ENTRY(ga, j);
if (!GA_EMPTY(&lp2->lp_slang->sl_rep)
&& STRNCMP(lp->lp_slang->sl_name,
- lp2->lp_slang->sl_name, 2) == 0) {
+ lp2->lp_slang->sl_name, 2) == 0) {
lp->lp_replang = lp2->lp_slang;
break;
}
}
+ }
}
theend:
@@ -2302,10 +2381,12 @@ static int find_region(char_u *rp, char_u *region)
int i;
for (i = 0;; i += 2) {
- if (rp[i] == NUL)
+ if (rp[i] == NUL) {
return REGION_ALL;
- if (rp[i] == region[0] && rp[i + 1] == region[1])
+ }
+ if (rp[i] == region[0] && rp[i + 1] == region[1]) {
break;
+ }
}
return i / 2;
}
@@ -2323,7 +2404,7 @@ static int find_region(char_u *rp, char_u *region)
int captype(char_u *word, char_u *end)
FUNC_ATTR_NONNULL_ARG(1)
{
- char_u *p;
+ char_u *p;
int firstcap;
bool allcap;
bool past_second = false; // past second word char
@@ -2356,10 +2437,12 @@ int captype(char_u *word, char_u *end)
}
}
- if (allcap)
+ if (allcap) {
return WF_ALLCAP;
- if (firstcap)
+ }
+ if (firstcap) {
return WF_ONECAP;
+ }
return 0;
}
@@ -2373,7 +2456,7 @@ static int badword_captype(char_u *word, char_u *end)
int c;
int l, u;
bool first;
- char_u *p;
+ char_u *p;
if (flags & WF_KEEPCAP) {
// Count the number of UPPER and lower case letters.
@@ -2383,23 +2466,27 @@ static int badword_captype(char_u *word, char_u *end)
c = PTR2CHAR(p);
if (SPELL_ISUPPER(c)) {
++u;
- if (p == word)
+ if (p == word) {
first = true;
- } else
+ }
+ } else {
++l;
+ }
}
// If there are more UPPER than lower case letters suggest an
// ALLCAP word. Otherwise, if the first letter is UPPER then
// suggest ONECAP. Exception: "ALl" most likely should be "All",
// require three upper case letters.
- if (u > l && u > 2)
+ if (u > l && u > 2) {
flags |= WF_ALLCAP;
- else if (first)
+ } else if (first) {
flags |= WF_ONECAP;
+ }
- if (u >= 2 && l >= 2) // maCARONI maCAroni
+ if (u >= 2 && l >= 2) { // maCARONI maCAroni
flags |= WF_MIXCAP;
+ }
}
return flags;
}
@@ -2407,7 +2494,7 @@ static int badword_captype(char_u *word, char_u *end)
// Delete the internal wordlist and its .spl file.
void spell_delete_wordlist(void)
{
- char_u fname[MAXPATHL] = {0};
+ char_u fname[MAXPATHL] = { 0 };
if (int_wordlist != NULL) {
os_remove((char *)int_wordlist);
@@ -2420,7 +2507,7 @@ void spell_delete_wordlist(void)
// Free all languages.
void spell_free_all(void)
{
- slang_T *slang;
+ slang_T *slang;
// Go through all buffers and handle 'spelllang'. <VN>
FOR_ALL_BUFFERS(buf) {
@@ -2475,10 +2562,10 @@ static int bytes2offset(char_u **pp)
c = *p++;
if ((c & 0x80) == 0x00) { // 1 byte
nr = c - 1;
- } else if ((c & 0xc0) == 0x80) { // 2 bytes
+ } else if ((c & 0xc0) == 0x80) { // 2 bytes
nr = (c & 0x3f) - 1;
nr = nr * 255 + (*p++ - 1);
- } else if ((c & 0xe0) == 0xc0) { // 3 bytes
+ } else if ((c & 0xe0) == 0xc0) { // 3 bytes
nr = (c & 0x1f) - 1;
nr = nr * 255 + (*p++ - 1);
nr = nr * 255 + (*p++ - 1);
@@ -2537,8 +2624,9 @@ void clear_spell_chartab(spelltab_T *sp)
// We include digits. A word shouldn't start with a digit, but handling
// that is done separately.
- for (i = '0'; i <= '9'; ++i)
+ for (i = '0'; i <= '9'; ++i) {
sp->st_isw[i] = true;
+ }
for (i = 'A'; i <= 'Z'; ++i) {
sp->st_isw[i] = true;
sp->st_isu[i] = true;
@@ -2627,9 +2715,10 @@ bool spell_iswordp_nmw(const char_u *p, win_T *wp)
static bool spell_mb_isword_class(int cl, const win_T *wp)
FUNC_ATTR_PURE FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
- if (wp->w_s->b_cjk)
+ if (wp->w_s->b_cjk) {
// East Asian characters are not considered word characters.
return cl == 2 || cl == 0x2800;
+ }
return cl >= 2 && cl != 0x2070 && cl != 0x2080 && cl != 3;
}
@@ -2641,11 +2730,12 @@ static bool spell_iswordp_w(const int *p, const win_T *wp)
const int *s;
if (*p < 256 ? wp->w_s->b_spell_ismw[*p]
- : (wp->w_s->b_spell_ismw_mb != NULL
- && vim_strchr(wp->w_s->b_spell_ismw_mb, *p) != NULL))
+ : (wp->w_s->b_spell_ismw_mb != NULL
+ && vim_strchr(wp->w_s->b_spell_ismw_mb, *p) != NULL)) {
s = p + 1;
- else
+ } else {
s = p;
+ }
if (*s > 255) {
return spell_mb_isword_class(utf_class(*s), wp);
@@ -2657,8 +2747,7 @@ static bool spell_iswordp_w(const int *p, const win_T *wp)
// Uses the character definitions from the .spl file.
// When using a multi-byte 'encoding' the length may change!
// Returns FAIL when something wrong.
-int spell_casefold(const win_T *wp, char_u *str, int len, char_u *buf,
- int buflen)
+int spell_casefold(const win_T *wp, char_u *str, int len, char_u *buf, int buflen)
FUNC_ATTR_NONNULL_ALL
{
if (len >= buflen) {
@@ -2708,8 +2797,8 @@ static int sps_limit = 9999; // max nr of suggestions given
// Sets "sps_flags" and "sps_limit".
int spell_check_sps(void)
{
- char_u *p;
- char_u *s;
+ char_u *p;
+ char_u *s;
char_u buf[MAXPATHL];
int f;
@@ -2742,12 +2831,14 @@ int spell_check_sps(void)
sps_limit = 9999;
return FAIL;
}
- if (f != 0)
+ if (f != 0) {
sps_flags = f;
+ }
}
- if (sps_flags == 0)
+ if (sps_flags == 0) {
sps_flags = SPS_BEST;
+ }
return OK;
}
@@ -2758,13 +2849,13 @@ int spell_check_sps(void)
// When "count" is non-zero use that suggestion.
void spell_suggest(int count)
{
- char_u *line;
+ char_u *line;
pos_T prev_cursor = curwin->w_cursor;
char_u wcopy[MAXWLEN + 2];
- char_u *p;
+ char_u *p;
int c;
suginfo_T sug;
- suggest_T *stp;
+ suggest_T *stp;
int mouse_used;
int need_cap;
int limit;
@@ -2833,36 +2924,39 @@ void spell_suggest(int count)
// Get the list of suggestions. Limit to 'lines' - 2 or the number in
// 'spellsuggest', whatever is smaller.
- if (sps_limit > (int)Rows - 2)
+ if (sps_limit > (int)Rows - 2) {
limit = (int)Rows - 2;
- else
+ } else {
limit = sps_limit;
+ }
spell_find_suggest(line + curwin->w_cursor.col, badlen, &sug, limit,
- true, need_cap, true);
+ true, need_cap, true);
- if (GA_EMPTY(&sug.su_ga))
+ if (GA_EMPTY(&sug.su_ga)) {
MSG(_("Sorry, no suggestions"));
- else if (count > 0) {
- if (count > sug.su_ga.ga_len)
+ } else if (count > 0) {
+ if (count > sug.su_ga.ga_len) {
smsg(_("Sorry, only %" PRId64 " suggestions"),
(int64_t)sug.su_ga.ga_len);
+ }
} else {
// When 'rightleft' is set the list is drawn right-left.
cmdmsg_rl = curwin->w_p_rl;
- if (cmdmsg_rl)
+ if (cmdmsg_rl) {
msg_col = Columns - 1;
+ }
// List the suggestions.
msg_start();
msg_row = Rows - 1; // for when 'cmdheight' > 1
lines_left = Rows; // avoid more prompt
vim_snprintf((char *)IObuff, IOSIZE, _("Change \"%.*s\" to:"),
- sug.su_badlen, sug.su_badptr);
+ sug.su_badlen, sug.su_badptr);
if (cmdmsg_rl && STRNCMP(IObuff, "Change", 6) == 0) {
// And now the rabbit from the high hat: Avoid showing the
// untranslated message rightleft.
vim_snprintf((char *)IObuff, IOSIZE, ":ot \"%.*s\" egnahC",
- sug.su_badlen, sug.su_badptr);
+ sug.su_badlen, sug.su_badptr);
}
msg_puts((const char *)IObuff);
msg_clr_eos();
@@ -2875,10 +2969,11 @@ void spell_suggest(int count)
// The suggested word may replace only part of the bad word, add
// the not replaced part.
STRLCPY(wcopy, stp->st_word, MAXWLEN + 1);
- if (sug.su_badlen > stp->st_orglen)
+ if (sug.su_badlen > stp->st_orglen) {
STRLCPY(wcopy + stp->st_wordlen,
- sug.su_badptr + stp->st_orglen,
- sug.su_badlen - stp->st_orglen + 1);
+ sug.su_badptr + stp->st_orglen,
+ sug.su_badlen - stp->st_orglen + 1);
+ }
vim_snprintf((char *)IObuff, IOSIZE, "%2d", i + 1);
if (cmdmsg_rl) {
rl_mirror(IObuff);
@@ -2897,16 +2992,18 @@ void spell_suggest(int count)
if (p_verbose > 0) {
// Add the score.
- if (sps_flags & (SPS_DOUBLE | SPS_BEST))
+ if (sps_flags & (SPS_DOUBLE | SPS_BEST)) {
vim_snprintf((char *)IObuff, IOSIZE, " (%s%d - %d)",
- stp->st_salscore ? "s " : "",
- stp->st_score, stp->st_altscore);
- else
+ stp->st_salscore ? "s " : "",
+ stp->st_score, stp->st_altscore);
+ } else {
vim_snprintf((char *)IObuff, IOSIZE, " (%d)",
- stp->st_score);
- if (cmdmsg_rl)
+ stp->st_score);
+ }
+ if (cmdmsg_rl) {
// Mirror the numbers, but keep the leading space.
rl_mirror(IObuff + 1);
+ }
msg_advance(30);
msg_puts((const char *)IObuff);
}
@@ -2941,8 +3038,8 @@ void spell_suggest(int count)
// repl_to.
repl_from = vim_strnsave(sug.su_badptr, sug.su_badlen);
vim_snprintf((char *)IObuff, IOSIZE, "%s%.*s", stp->st_word,
- sug.su_badlen - stp->st_orglen,
- sug.su_badptr + stp->st_orglen);
+ sug.su_badlen - stp->st_orglen,
+ sug.su_badptr + stp->st_orglen);
repl_to = vim_strsave(IObuff);
} else {
// Replacing su_badlen or more, use the whole word.
@@ -2961,7 +3058,7 @@ void spell_suggest(int count)
ResetRedobuff();
AppendToRedobuff("ciw");
AppendToRedobuffLit(p + c,
- stp->st_wordlen + sug.su_badlen - stp->st_orglen);
+ stp->st_wordlen + sug.su_badlen - stp->st_orglen);
AppendCharToRedobuff(ESC);
// "p" may be freed here
@@ -2969,8 +3066,9 @@ void spell_suggest(int count)
curwin->w_cursor.col = c;
changed_bytes(curwin->w_cursor.lnum, c);
- } else
+ } else {
curwin->w_cursor = prev_cursor;
+ }
spell_find_cleanup(&sug);
xfree(line);
@@ -2982,27 +3080,28 @@ void spell_suggest(int count)
static bool check_need_cap(linenr_T lnum, colnr_T col)
{
bool need_cap = false;
- char_u *line;
- char_u *line_copy = NULL;
- char_u *p;
+ char_u *line;
+ char_u *line_copy = NULL;
+ char_u *p;
colnr_T endcol;
regmatch_T regmatch;
- if (curwin->w_s->b_cap_prog == NULL)
+ if (curwin->w_s->b_cap_prog == NULL) {
return false;
+ }
line = get_cursor_line_ptr();
endcol = 0;
if (getwhitecols(line) >= (int)col) {
// At start of line, check if previous line is empty or sentence
// ends there.
- if (lnum == 1)
+ if (lnum == 1) {
need_cap = true;
- else {
+ } else {
line = ml_get(lnum - 1);
- if (*skipwhite(line) == NUL)
+ if (*skipwhite(line) == NUL) {
need_cap = true;
- else {
+ } else {
// Append a space in place of the line break.
line_copy = concat_str(line, (char_u *)" ");
line = line_copy;
@@ -3042,10 +3141,10 @@ static bool check_need_cap(linenr_T lnum, colnr_T col)
void ex_spellrepall(exarg_T *eap)
{
pos_T pos = curwin->w_cursor;
- char_u *frompat;
+ char_u *frompat;
int addlen;
- char_u *line;
- char_u *p;
+ char_u *line;
+ char_u *p;
bool save_ws = p_ws;
linenr_T prev_lnum = 0;
@@ -3072,7 +3171,7 @@ void ex_spellrepall(exarg_T *eap)
// when changing "etc" to "etc.".
line = get_cursor_line_ptr();
if (addlen <= 0 || STRNCMP(line + curwin->w_cursor.col,
- repl_to, STRLEN(repl_to)) != 0) {
+ repl_to, STRLEN(repl_to)) != 0) {
p = xmalloc(STRLEN(line) + addlen + 1);
memmove(p, line, curwin->w_cursor.col);
STRCPY(p + curwin->w_cursor.col, repl_to);
@@ -3093,26 +3192,23 @@ void ex_spellrepall(exarg_T *eap)
curwin->w_cursor = pos;
xfree(frompat);
- if (sub_nsubs == 0)
+ if (sub_nsubs == 0) {
EMSG2(_("E753: Not found: %s"), repl_from);
- else
+ } else {
do_sub_msg(false);
+ }
}
-// Find spell suggestions for "word". Return them in the growarray "*gap" as
-// a list of allocated strings.
-void
-spell_suggest_list (
- garray_T *gap,
- char_u *word,
- int maxcount, // maximum nr of suggestions
- bool need_cap, // 'spellcapcheck' matched
- bool interactive
-)
+/// Find spell suggestions for "word". Return them in the growarray "*gap" as
+/// a list of allocated strings.
+///
+/// @param maxcount maximum nr of suggestions
+/// @param need_cap 'spellcapcheck' matched
+void spell_suggest_list(garray_T *gap, char_u *word, int maxcount, bool need_cap, bool interactive)
{
suginfo_T sug;
- suggest_T *stp;
- char_u *wcopy;
+ suggest_T *stp;
+ char_u *wcopy;
spell_find_suggest(word, 0, &sug, maxcount, false, need_cap, interactive);
@@ -3134,44 +3230,41 @@ spell_suggest_list (
spell_find_cleanup(&sug);
}
-// Find spell suggestions for the word at the start of "badptr".
-// Return the suggestions in "su->su_ga".
-// The maximum number of suggestions is "maxcount".
-// Note: does use info for the current window.
-// This is based on the mechanisms of Aspell, but completely reimplemented.
-static void
-spell_find_suggest (
- char_u *badptr,
- int badlen, // length of bad word or 0 if unknown
- suginfo_T *su,
- int maxcount,
- bool banbadword, // don't include badword in suggestions
- bool need_cap, // word should start with capital
- bool interactive
-)
+/// Find spell suggestions for the word at the start of "badptr".
+/// Return the suggestions in "su->su_ga".
+/// The maximum number of suggestions is "maxcount".
+/// Note: does use info for the current window.
+/// This is based on the mechanisms of Aspell, but completely reimplemented.
+///
+/// @param badlen length of bad word or 0 if unknown
+/// @param banbadword don't include badword in suggestions
+/// @param need_cap word should start with capital
+static void spell_find_suggest(char_u *badptr, int badlen, suginfo_T *su, int maxcount,
+ bool banbadword, bool need_cap, bool interactive)
{
hlf_T attr = HLF_COUNT;
char_u buf[MAXPATHL];
- char_u *p;
+ char_u *p;
bool do_combine = false;
- char_u *sps_copy;
+ char_u *sps_copy;
static bool expr_busy = false;
int c;
- langp_T *lp;
+ langp_T *lp;
bool did_intern = false;
// Set the info in "*su".
memset(su, 0, sizeof(suginfo_T));
ga_init(&su->su_ga, (int)sizeof(suggest_T), 10);
ga_init(&su->su_sga, (int)sizeof(suggest_T), 10);
- if (*badptr == NUL)
+ if (*badptr == NUL) {
return;
+ }
hash_init(&su->su_banned);
su->su_badptr = badptr;
- if (badlen != 0)
+ if (badlen != 0) {
su->su_badlen = badlen;
- else {
+ } else {
size_t tmplen = spell_check(curwin, su->su_badptr, &attr, NULL, false);
assert(tmplen <= INT_MAX);
su->su_badlen = (int)tmplen;
@@ -3179,8 +3272,9 @@ spell_find_suggest (
su->su_maxcount = maxcount;
su->su_maxscore = SCORE_MAXINIT;
- if (su->su_badlen >= MAXWLEN)
+ if (su->su_badlen >= MAXWLEN) {
su->su_badlen = MAXWLEN - 1; // just in case
+ }
STRLCPY(su->su_badword, su->su_badptr, su->su_badlen + 1);
(void)spell_casefold(curwin, su->su_badptr, su->su_badlen, su->su_fbadword,
MAXWLEN);
@@ -3192,9 +3286,10 @@ spell_find_suggest (
// get caps flags for bad word
su->su_badflags = badword_captype(su->su_badptr,
- su->su_badptr + su->su_badlen);
- if (need_cap)
+ su->su_badptr + su->su_badlen);
+ if (need_cap) {
su->su_badflags |= WF_ONECAP;
+ }
// Find the default language for sound folding. We simply use the first
// one in 'spelllang' that supports sound folding. That's good for when
@@ -3210,9 +3305,10 @@ spell_find_suggest (
// Soundfold the bad word with the default sound folding, so that we don't
// have to do this many times.
- if (su->su_sallang != NULL)
+ if (su->su_sallang != NULL) {
spell_soundfold(su->su_sallang, su->su_fbadword, true,
- su->su_sal_badword);
+ su->su_sal_badword);
+ }
// If the word is not capitalised and spell_check() doesn't consider the
// word to be bad then it might need to be capitalised. Add a suggestion
@@ -3221,12 +3317,13 @@ spell_find_suggest (
if (!SPELL_ISUPPER(c) && attr == HLF_COUNT) {
make_case_word(su->su_badword, buf, WF_ONECAP);
add_suggestion(su, &su->su_ga, buf, su->su_badlen, SCORE_ICASE,
- 0, true, su->su_sallang, false);
+ 0, true, su->su_sallang, false);
}
// Ban the bad word itself. It may appear in another region.
- if (banbadword)
+ if (banbadword) {
add_banned(su, su->su_badword);
+ }
// Make a copy of 'spellsuggest', because the expression may change it.
sps_copy = vim_strsave(p_sps);
@@ -3258,10 +3355,11 @@ spell_find_suggest (
xfree(sps_copy);
- if (do_combine)
+ if (do_combine) {
// Combine the two list of suggestions. This must be done last,
// because sorting changes the order again.
score_combine(su);
+ }
}
// Find suggestions by evaluating expression "expr".
@@ -3297,9 +3395,9 @@ static void spell_suggest_expr(suginfo_T *su, char_u *expr)
// Find suggestions in file "fname". Used for "file:" in 'spellsuggest'.
static void spell_suggest_file(suginfo_T *su, char_u *fname)
{
- FILE *fd;
+ FILE *fd;
char_u line[MAXWLEN * 2];
- char_u *p;
+ char_u *p;
int len;
char_u cword[MAXWLEN];
@@ -3315,13 +3413,15 @@ static void spell_suggest_file(suginfo_T *su, char_u *fname)
line_breakcheck();
p = vim_strchr(line, '/');
- if (p == NULL)
+ if (p == NULL) {
continue; // No Tab found, just skip the line.
+ }
*p++ = NUL;
if (STRICMP(su->su_badword, line) == 0) {
// Match! Isolate the good word, until CR or NL.
- for (len = 0; p[len] >= ' '; ++len)
+ for (len = 0; p[len] >= ' '; ++len) {
;
+ }
p[len] = NUL;
// If the suggestion doesn't have specific case duplicate the case
@@ -3332,7 +3432,7 @@ static void spell_suggest_file(suginfo_T *su, char_u *fname)
}
add_suggestion(su, &su->su_ga, p, su->su_badlen,
- SCORE_FILE, 0, true, su->su_sallang, false);
+ SCORE_FILE, 0, true, su->su_sallang, false);
}
}
@@ -3360,15 +3460,17 @@ static void spell_suggest_intern(suginfo_T *su, bool interactive)
suggest_try_change(su);
// For the resulting top-scorers compute the sound-a-like score.
- if (sps_flags & SPS_DOUBLE)
+ if (sps_flags & SPS_DOUBLE) {
score_comp_sal(su);
+ }
// 3. Try finding sound-a-like words.
if ((sps_flags & SPS_FAST) == 0) {
- if (sps_flags & SPS_BEST)
+ if (sps_flags & SPS_BEST) {
// Adjust the word score for the suggestions found so far for how
// they sounds like.
rescore_suggestions(su);
+ }
// While going through the soundfold tree "su_maxscore" is the score
// for the soundfold word, limits the changes that are being tried,
@@ -3407,9 +3509,10 @@ static void spell_suggest_intern(suginfo_T *su, bool interactive)
}
if ((sps_flags & SPS_DOUBLE) == 0 && su->su_ga.ga_len != 0) {
- if (sps_flags & SPS_BEST)
+ if (sps_flags & SPS_BEST) {
// Adjust the word score for how it sounds like.
rescore_suggestions(su);
+ }
// Remove bogus suggestions, sort and truncate at "maxcount".
check_suggestions(su, &su->su_ga);
@@ -3420,7 +3523,7 @@ static void spell_suggest_intern(suginfo_T *su, bool interactive)
// Free the info put in "*su" by spell_find_suggest().
static void spell_find_cleanup(suginfo_T *su)
{
-# define FREE_SUG_WORD(sug) xfree(sug->st_word)
+#define FREE_SUG_WORD(sug) xfree(sug->st_word)
// Free the suggestions.
GA_DEEP_CLEAR(&su->su_ga, suggest_T, FREE_SUG_WORD);
GA_DEEP_CLEAR(&su->su_sga, suggest_T, FREE_SUG_WORD);
@@ -3459,11 +3562,13 @@ static void allcap_copy(char_u *word, char_u *wcopy)
if (c == 0xdf) {
c = 'S';
- if (d - wcopy >= MAXWLEN - 1)
+ if (d - wcopy >= MAXWLEN - 1) {
break;
+ }
*d++ = c;
- } else
+ } else {
c = SPELL_TOUPPER(c);
+ }
if (d - wcopy >= MAXWLEN - MB_MAXBYTES) {
break;
@@ -3476,7 +3581,7 @@ static void allcap_copy(char_u *word, char_u *wcopy)
// Try finding suggestions by recognizing specific situations.
static void suggest_try_special(suginfo_T *su)
{
- char_u *p;
+ char_u *p;
size_t len;
int c;
char_u word[MAXWLEN];
@@ -3496,7 +3601,7 @@ static void suggest_try_special(suginfo_T *su)
// Give a soundalike score of 0, compute the score as if deleting one
// character.
add_suggestion(su, &su->su_ga, word, su->su_badlen,
- RESCORE(SCORE_REP, 0), 0, true, su->su_sallang, false);
+ RESCORE(SCORE_REP, 0), 0, true, su->su_sallang, false);
}
}
@@ -3509,8 +3614,7 @@ proftime_T total;
proftime_T times[STATE_FINAL + 1];
long counts[STATE_FINAL + 1];
- static void
-prof_init(void)
+static void prof_init(void)
{
for (int i = 0; i <= STATE_FINAL; i++) {
profile_zero(&times[i]);
@@ -3521,8 +3625,7 @@ prof_init(void)
}
// call before changing state
- static void
-prof_store(state_T state)
+static void prof_store(state_T state)
{
profile_end(&current);
profile_add(&times[state], &current);
@@ -3531,8 +3634,7 @@ prof_store(state_T state)
}
# define PROF_STORE(state) prof_store(state);
- static void
-prof_report(char *name)
+static void prof_report(char *name)
{
FILE *fd = fopen("suggestprof", "a");
@@ -3554,8 +3656,8 @@ static void suggest_try_change(suginfo_T *su)
{
char_u fword[MAXWLEN]; // copy of the bad word, case-folded
int n;
- char_u *p;
- langp_T *lp;
+ char_u *p;
+ langp_T *lp;
// We make a copy of the case-folded bad word, so that we can modify it
// to find matches (esp. REP items). Append some more text, changing
@@ -3570,8 +3672,9 @@ static void suggest_try_change(suginfo_T *su)
// If reloading a spell file fails it's still in the list but
// everything has been cleared.
- if (lp->lp_slang->sl_fbyts == NULL)
+ if (lp->lp_slang->sl_fbyts == NULL) {
continue;
+ }
// Try it for this language. Will add possible suggestions.
//
@@ -3623,28 +3726,28 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
char_u tword[MAXWLEN]; // good word collected so far
trystate_T stack[MAXWLEN];
char_u preword[MAXWLEN * 3] = { 0 }; // word found with proper case;
- // concatenation of prefix compound
- // words and split word. NUL terminated
- // when going deeper but not when coming
- // back.
+ // concatenation of prefix compound
+ // words and split word. NUL terminated
+ // when going deeper but not when coming
+ // back.
char_u compflags[MAXWLEN]; // compound flags, one for each word
- trystate_T *sp;
+ trystate_T *sp;
int newscore;
int score;
- char_u *byts, *fbyts, *pbyts;
- idx_T *idxs, *fidxs, *pidxs;
+ char_u *byts, *fbyts, *pbyts;
+ idx_T *idxs, *fidxs, *pidxs;
int depth;
int c, c2, c3;
int n = 0;
int flags;
- garray_T *gap;
+ garray_T *gap;
idx_T arridx;
int len;
- char_u *p;
- fromto_T *ftp;
+ char_u *p;
+ fromto_T *ftp;
int fl = 0, tl;
int repextra = 0; // extra bytes in fword[] from REP item
- slang_T *slang = lp->lp_slang;
+ slang_T *slang = lp->lp_slang;
int fword_ends;
bool goodword_ends;
#ifdef DEBUG_TRIEWALK
@@ -3709,8 +3812,9 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
if (sp->ts_prefixdepth == PFD_PREFIXTREE) {
// Skip over the NUL bytes, we use them later.
- for (n = 0; n < len && byts[arridx + n] == 0; ++n)
+ for (n = 0; n < len && byts[arridx + n] == 0; ++n) {
;
+ }
sp->ts_curi += n;
// Always past NUL bytes now.
@@ -3727,7 +3831,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
n = nofold_len(fword, sp->ts_fidx, su->su_badptr);
flags = badword_captype(su->su_badptr, su->su_badptr + n);
su->su_badflags = badword_captype(su->su_badptr + n,
- su->su_badptr + su->su_badlen);
+ su->su_badptr + su->su_badlen);
#ifdef DEBUG_TRIEWALK
sprintf(changename[depth], "prefix");
#endif
@@ -3743,7 +3847,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// and make find_keepcap_word() works.
tword[sp->ts_twordlen] = NUL;
make_case_word(tword + sp->ts_splitoff,
- preword + sp->ts_prewordlen, flags);
+ preword + sp->ts_prewordlen, flags);
sp->ts_prewordlen = (char_u)STRLEN(preword);
sp->ts_splitoff = sp->ts_twordlen;
}
@@ -3764,8 +3868,9 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
flags = (int)idxs[arridx];
// Skip words with the NOSUGGEST flag.
- if (flags & WF_NOSUGGEST)
+ if (flags & WF_NOSUGGEST) {
break;
+ }
fword_ends = (fword[sp->ts_fidx] == NUL
|| (soundfold
@@ -3782,17 +3887,20 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// none this must be the first try without a prefix.
n = stack[sp->ts_prefixdepth].ts_arridx;
len = pbyts[n++];
- for (c = 0; c < len && pbyts[n + c] == 0; ++c)
+ for (c = 0; c < len && pbyts[n + c] == 0; ++c) {
;
+ }
if (c > 0) {
c = valid_word_prefix(c, n, flags,
- tword + sp->ts_splitoff, slang, false);
- if (c == 0)
+ tword + sp->ts_splitoff, slang, false);
+ if (c == 0) {
break;
+ }
// Use the WF_RARE flag for a rare prefix.
- if (c & WF_RAREPFX)
+ if (c & WF_RAREPFX) {
flags |= WF_RARE;
+ }
// Tricky: when checking for both prefix and compounding
// we run into the prefix flag first.
@@ -3805,10 +3913,11 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// Check NEEDCOMPOUND: can't use word without compounding. Do try
// appending another compound word below.
if (sp->ts_complen == sp->ts_compsplit && fword_ends
- && (flags & WF_NEEDCOMP))
+ && (flags & WF_NEEDCOMP)) {
goodword_ends = false;
- else
+ } else {
goodword_ends = true;
+ }
p = NULL;
compound_ok = true;
@@ -3821,18 +3930,19 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
if (sp->ts_fidx - sp->ts_splitfidx
== sp->ts_twordlen - sp->ts_splitoff
&& STRNCMP(fword + sp->ts_splitfidx,
- tword + sp->ts_splitoff,
- sp->ts_fidx - sp->ts_splitfidx) == 0) {
+ tword + sp->ts_splitoff,
+ sp->ts_fidx - sp->ts_splitfidx) == 0) {
preword[sp->ts_prewordlen] = NUL;
newscore = score_wordcount_adj(slang, sp->ts_score,
- preword + sp->ts_prewordlen,
- sp->ts_prewordlen > 0);
+ preword + sp->ts_prewordlen,
+ sp->ts_prewordlen > 0);
// Add the suggestion if the score isn't too bad.
- if (newscore <= su->su_maxscore)
+ if (newscore <= su->su_maxscore) {
add_suggestion(su, &su->su_ga, preword,
- sp->ts_splitfidx - repextra,
- newscore, 0, false,
- lp->lp_sallang, false);
+ sp->ts_splitfidx - repextra,
+ newscore, 0, false,
+ lp->lp_sallang, false);
+ }
break;
}
} else {
@@ -3856,23 +3966,26 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
compflags[sp->ts_complen] = ((unsigned)flags >> 24);
compflags[sp->ts_complen + 1] = NUL;
STRLCPY(preword + sp->ts_prewordlen,
- tword + sp->ts_splitoff,
- sp->ts_twordlen - sp->ts_splitoff + 1);
+ tword + sp->ts_splitoff,
+ sp->ts_twordlen - sp->ts_splitoff + 1);
// Verify CHECKCOMPOUNDPATTERN rules.
if (match_checkcompoundpattern(preword, sp->ts_prewordlen,
- &slang->sl_comppat))
+ &slang->sl_comppat)) {
compound_ok = false;
+ }
if (compound_ok) {
p = preword;
- while (*skiptowhite(p) != NUL)
+ while (*skiptowhite(p) != NUL) {
p = skipwhite(skiptowhite(p));
+ }
if (fword_ends && !can_compound(slang, p,
- compflags + sp->ts_compsplit))
+ compflags + sp->ts_compsplit)) {
// Compound is not allowed. But it may still be
// possible if we add another (short) word.
compound_ok = false;
+ }
}
// Get pointer to last char of previous word.
@@ -3884,29 +3997,31 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// Form the word with proper case in preword.
// If there is a word from a previous split, append.
// For the soundfold tree don't change the case, simply append.
- if (soundfold)
+ if (soundfold) {
STRCPY(preword + sp->ts_prewordlen, tword + sp->ts_splitoff);
- else if (flags & WF_KEEPCAP)
+ } else if (flags & WF_KEEPCAP) {
// Must find the word in the keep-case tree.
find_keepcap_word(slang, tword + sp->ts_splitoff,
- preword + sp->ts_prewordlen);
- else {
+ preword + sp->ts_prewordlen);
+ } else {
// Include badflags: If the badword is onecap or allcap
// use that for the goodword too. But if the badword is
// allcap and it's only one char long use onecap.
c = su->su_badflags;
if ((c & WF_ALLCAP)
- && su->su_badlen == (*mb_ptr2len)(su->su_badptr)
- )
+ && su->su_badlen ==
+ (*mb_ptr2len)(su->su_badptr)) {
c = WF_ONECAP;
+ }
c |= flags;
// When appending a compound word after a word character don't
// use Onecap.
- if (p != NULL && spell_iswordp_nmw(p, curwin))
+ if (p != NULL && spell_iswordp_nmw(p, curwin)) {
c &= ~WF_ONECAP;
+ }
make_case_word(tword + sp->ts_splitoff,
- preword + sp->ts_prewordlen, c);
+ preword + sp->ts_prewordlen, c);
}
if (!soundfold) {
@@ -3919,8 +4034,9 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
if ((sp->ts_complen == sp->ts_compsplit
&& WAS_BANNED(su, preword + sp->ts_prewordlen))
|| WAS_BANNED(su, preword)) {
- if (slang->sl_compprog == NULL)
+ if (slang->sl_compprog == NULL) {
break;
+ }
// the word so far was banned but we may try compounding
goodword_ends = false;
}
@@ -3929,14 +4045,17 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
newscore = 0;
if (!soundfold) { // soundfold words don't have flags
if ((flags & WF_REGION)
- && (((unsigned)flags >> 16) & lp->lp_region) == 0)
+ && (((unsigned)flags >> 16) & lp->lp_region) == 0) {
newscore += SCORE_REGION;
- if (flags & WF_RARE)
+ }
+ if (flags & WF_RARE) {
newscore += SCORE_RARE;
+ }
if (!spell_valid_case(su->su_badflags,
- captype(preword + sp->ts_prewordlen, NULL)))
+ captype(preword + sp->ts_prewordlen, NULL))) {
newscore += SCORE_ICASE;
+ }
}
// TODO: how about splitting in the soundfold tree?
@@ -3951,15 +4070,16 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// print the stack of changes that brought us here
smsg("------ %s -------", fword);
- for (j = 0; j < depth; ++j)
+ for (j = 0; j < depth; ++j) {
smsg("%s", changename[j]);
+ }
}
#endif
if (soundfold) {
// For soundfolded words we need to find the original
// words, the edit distance and then add them.
add_sound_suggest(su, preword, sp->ts_score, lp);
- } else if (sp->ts_fidx > 0) {
+ } else if (sp->ts_fidx > 0) {
// Give a penalty when changing non-word char to word
// char, e.g., "thes," -> "these".
p = fword + sp->ts_fidx;
@@ -3974,15 +4094,15 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// Give a bonus to words seen before.
score = score_wordcount_adj(slang,
- sp->ts_score + newscore,
- preword + sp->ts_prewordlen,
- sp->ts_prewordlen > 0);
+ sp->ts_score + newscore,
+ preword + sp->ts_prewordlen,
+ sp->ts_prewordlen > 0);
// Add the suggestion if the score isn't too bad.
if (score <= su->su_maxscore) {
add_suggestion(su, &su->su_ga, preword,
- sp->ts_fidx - repextra,
- score, 0, false, lp->lp_sallang, false);
+ sp->ts_fidx - repextra,
+ score, 0, false, lp->lp_sallang, false);
if (su->su_badflags & WF_MIXCAP) {
// We really don't know if the word should be
@@ -3990,13 +4110,13 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
c = captype(preword, NULL);
if (c == 0 || c == WF_ALLCAP) {
make_case_word(tword + sp->ts_splitoff,
- preword + sp->ts_prewordlen,
- c == 0 ? WF_ALLCAP : 0);
+ preword + sp->ts_prewordlen,
+ c == 0 ? WF_ALLCAP : 0);
add_suggestion(su, &su->su_ga, preword,
- sp->ts_fidx - repextra,
- score + SCORE_ICASE, 0, false,
- lp->lp_sallang, false);
+ sp->ts_fidx - repextra,
+ score + SCORE_ICASE, 0, false,
+ lp->lp_sallang, false);
}
}
}
@@ -4006,8 +4126,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// Try word split and/or compounding.
if ((sp->ts_fidx >= sp->ts_fidxtry || fword_ends)
// Don't split in the middle of a character
- && (sp->ts_tcharlen == 0)
- ) {
+ && (sp->ts_tcharlen == 0)) {
bool try_compound;
int try_split;
@@ -4045,7 +4164,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
|| sp->ts_complen + 1 - sp->ts_compsplit
< slang->sl_compmax)
&& (can_be_compound(sp, slang,
- compflags, ((unsigned)flags >> 24)))) {
+ compflags, ((unsigned)flags >> 24)))) {
try_compound = true;
compflags[sp->ts_complen] = ((unsigned)flags >> 24);
compflags[sp->ts_complen + 1] = NUL;
@@ -4076,35 +4195,40 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// is only one word it must not have the NEEDCOMPOUND
// flag.
if (sp->ts_complen == sp->ts_compsplit
- && (flags & WF_NEEDCOMP))
+ && (flags & WF_NEEDCOMP)) {
break;
+ }
p = preword;
- while (*skiptowhite(p) != NUL)
+ while (*skiptowhite(p) != NUL) {
p = skipwhite(skiptowhite(p));
+ }
if (sp->ts_complen > sp->ts_compsplit
&& !can_compound(slang, p,
- compflags + sp->ts_compsplit))
+ compflags + sp->ts_compsplit)) {
break;
+ }
- if (slang->sl_nosplitsugs)
+ if (slang->sl_nosplitsugs) {
newscore += SCORE_SPLIT_NO;
- else
+ } else {
newscore += SCORE_SPLIT;
+ }
// Give a bonus to words seen before.
newscore = score_wordcount_adj(slang, newscore,
- preword + sp->ts_prewordlen, true);
+ preword + sp->ts_prewordlen, true);
}
if (TRY_DEEPER(su, stack, depth, newscore)) {
go_deeper(stack, depth, newscore);
#ifdef DEBUG_TRIEWALK
- if (!try_compound && !fword_ends)
+ if (!try_compound && !fword_ends) {
sprintf(changename[depth], "%.*s-%s: split",
- sp->ts_twordlen, tword, fword + sp->ts_fidx);
- else
+ sp->ts_twordlen, tword, fword + sp->ts_fidx);
+ } else {
sprintf(changename[depth], "%.*s-%s: compound",
- sp->ts_twordlen, tword, fword + sp->ts_fidx);
+ sp->ts_twordlen, tword, fword + sp->ts_fidx);
+ }
#endif
// Save things to be restored at STATE_SPLITUNDO.
sp->ts_save_badflags = su->su_badflags;
@@ -4115,8 +4239,9 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
sp = &stack[depth];
// Append a space to preword when splitting.
- if (!try_compound && !fword_ends)
+ if (!try_compound && !fword_ends) {
STRCAT(preword, " ");
+ }
sp->ts_prewordlen = (char_u)STRLEN(preword);
sp->ts_splitoff = sp->ts_twordlen;
sp->ts_splitfidx = sp->ts_fidx;
@@ -4127,8 +4252,8 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// character when the word ends. But only when the
// good word can end.
if (((!try_compound && !spell_iswordp_nmw(fword
- + sp->ts_fidx,
- curwin))
+ + sp->ts_fidx,
+ curwin))
|| fword_ends)
&& fword[sp->ts_fidx] != NUL
&& goodword_ends) {
@@ -4138,28 +4263,30 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
if (fword_ends) {
// Copy the skipped character to preword.
memmove(preword + sp->ts_prewordlen,
- fword + sp->ts_fidx, l);
+ fword + sp->ts_fidx, l);
sp->ts_prewordlen += l;
preword[sp->ts_prewordlen] = NUL;
- } else
+ } else {
sp->ts_score -= SCORE_SPLIT - SCORE_SUBST;
+ }
sp->ts_fidx += l;
}
// When compounding include compound flag in
// compflags[] (already set above). When splitting we
// may start compounding over again.
- if (try_compound)
+ if (try_compound) {
++sp->ts_complen;
- else
+ } else {
sp->ts_compsplit = sp->ts_complen;
+ }
sp->ts_prefixdepth = PFD_NOPREFIX;
// set su->su_badflags to the caps type at this
// position
n = nofold_len(fword, sp->ts_fidx, su->su_badptr);
su->su_badflags = badword_captype(su->su_badptr + n,
- su->su_badptr + su->su_badlen);
+ su->su_badptr + su->su_badlen);
// Restart at top of the tree.
sp->ts_arridx = 0;
@@ -4194,8 +4321,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// Past the NUL bytes in the node.
su->su_badflags = sp->ts_save_badflags;
if (fword[sp->ts_fidx] == NUL
- && sp->ts_tcharlen == 0
- ) {
+ && sp->ts_tcharlen == 0) {
// The badword ends, can't use STATE_PLAIN.
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_DEL;
@@ -4228,11 +4354,12 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// just deleted this byte, accepting it is always cheaper than
// delete + substitute.
if (c == fword[sp->ts_fidx]
- || (sp->ts_tcharlen > 0 && sp->ts_isdiff != DIFF_NONE)
- )
+ || (sp->ts_tcharlen > 0 &&
+ sp->ts_isdiff != DIFF_NONE)) {
newscore = 0;
- else
+ } else {
newscore = SCORE_SUBST;
+ }
if ((newscore == 0
|| (sp->ts_fidx >= sp->ts_fidxtry
&& ((sp->ts_flags & TSF_DIDDEL) == 0
@@ -4240,14 +4367,15 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
&& TRY_DEEPER(su, stack, depth, newscore)) {
go_deeper(stack, depth, newscore);
#ifdef DEBUG_TRIEWALK
- if (newscore > 0)
+ if (newscore > 0) {
sprintf(changename[depth], "%.*s-%s: subst %c to %c",
- sp->ts_twordlen, tword, fword + sp->ts_fidx,
- fword[sp->ts_fidx], c);
- else
+ sp->ts_twordlen, tword, fword + sp->ts_fidx,
+ fword[sp->ts_fidx], c);
+ } else {
sprintf(changename[depth], "%.*s-%s: accept %c",
- sp->ts_twordlen, tword, fword + sp->ts_fidx,
- fword[sp->ts_fidx]);
+ sp->ts_twordlen, tword, fword + sp->ts_fidx,
+ fword[sp->ts_fidx]);
+ }
#endif
++depth;
sp = &stack[depth];
@@ -4289,12 +4417,11 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
+ sp->ts_fcharstart))) {
sp->ts_score -= SCORE_SUBST - SCORE_SUBCOMP;
} else if (
- !soundfold
- && slang->sl_has_map
- && similar_chars(
- slang,
- utf_ptr2char(tword + sp->ts_twordlen - sp->ts_tcharlen),
- utf_ptr2char(fword + sp->ts_fcharstart))) {
+ !soundfold
+ && slang->sl_has_map
+ && similar_chars(slang,
+ utf_ptr2char(tword + sp->ts_twordlen - sp->ts_tcharlen),
+ utf_ptr2char(fword + sp->ts_fcharstart))) {
// For a similar character adjust score from
// SCORE_SUBST to SCORE_SIMILAR.
sp->ts_score -= SCORE_SUBST - SCORE_SIMILAR;
@@ -4339,19 +4466,20 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_INS_PREP;
sp->ts_curi = 1;
- if (soundfold && sp->ts_fidx == 0 && fword[sp->ts_fidx] == '*')
+ if (soundfold && sp->ts_fidx == 0 && fword[sp->ts_fidx] == '*') {
// Deleting a vowel at the start of a word counts less, see
// soundalike_score().
newscore = 2 * SCORE_DEL / 3;
- else
+ } else {
newscore = SCORE_DEL;
+ }
if (fword[sp->ts_fidx] != NUL
&& TRY_DEEPER(su, stack, depth, newscore)) {
go_deeper(stack, depth, newscore);
#ifdef DEBUG_TRIEWALK
sprintf(changename[depth], "%.*s-%s: delete %c",
- sp->ts_twordlen, tword, fword + sp->ts_fidx,
- fword[sp->ts_fidx]);
+ sp->ts_twordlen, tword, fword + sp->ts_fidx,
+ fword[sp->ts_fidx]);
#endif
++depth;
@@ -4421,19 +4549,20 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// accepting that byte is always better.
n += sp->ts_curi++;
c = byts[n];
- if (soundfold && sp->ts_twordlen == 0 && c == '*')
+ if (soundfold && sp->ts_twordlen == 0 && c == '*') {
// Inserting a vowel at the start of a word counts less,
// see soundalike_score().
newscore = 2 * SCORE_INS / 3;
- else
+ } else {
newscore = SCORE_INS;
+ }
if (c != fword[sp->ts_fidx]
&& TRY_DEEPER(su, stack, depth, newscore)) {
go_deeper(stack, depth, newscore);
#ifdef DEBUG_TRIEWALK
sprintf(changename[depth], "%.*s-%s: insert %c",
- sp->ts_twordlen, tword, fword + sp->ts_fidx,
- c);
+ sp->ts_twordlen, tword, fword + sp->ts_fidx,
+ c);
#endif
++depth;
sp = &stack[depth];
@@ -4454,8 +4583,9 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// soundfold words (illogical but does give a better
// score).
if (sp->ts_twordlen >= 2
- && tword[sp->ts_twordlen - 2] == c)
+ && tword[sp->ts_twordlen - 2] == c) {
sp->ts_score -= SCORE_INS - SCORE_INSDUP;
+ }
}
}
break;
@@ -4566,8 +4696,8 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
go_deeper(stack, depth, SCORE_SWAP3);
#ifdef DEBUG_TRIEWALK
sprintf(changename[depth], "%.*s-%s: swap3 %c and %c",
- sp->ts_twordlen, tword, fword + sp->ts_fidx,
- c, c3);
+ sp->ts_twordlen, tword, fword + sp->ts_fidx,
+ c, c3);
#endif
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_UNSWAP3;
@@ -4611,8 +4741,8 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
#ifdef DEBUG_TRIEWALK
p = fword + sp->ts_fidx;
sprintf(changename[depth], "%.*s-%s: rotate left %c%c%c",
- sp->ts_twordlen, tword, fword + sp->ts_fidx,
- p[0], p[1], p[2]);
+ sp->ts_twordlen, tword, fword + sp->ts_fidx,
+ p[0], p[1], p[2]);
#endif
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_UNROT3L;
@@ -4648,8 +4778,8 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
#ifdef DEBUG_TRIEWALK
p = fword + sp->ts_fidx;
sprintf(changename[depth], "%.*s-%s: rotate right %c%c%c",
- sp->ts_twordlen, tword, fword + sp->ts_fidx,
- p[0], p[1], p[2]);
+ sp->ts_twordlen, tword, fword + sp->ts_fidx,
+ p[0], p[1], p[2]);
#endif
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_UNROT3R;
@@ -4696,10 +4826,11 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// Use the first byte to quickly find the first entry that may
// match. If the index is -1 there is none.
- if (soundfold)
+ if (soundfold) {
sp->ts_curi = slang->sl_repsal_first[fword[sp->ts_fidx]];
- else
+ } else {
sp->ts_curi = lp->lp_replang->sl_rep_first[fword[sp->ts_fidx]];
+ }
if (sp->ts_curi < 0) {
PROF_STORE(sp->ts_state)
@@ -4717,10 +4848,11 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// valid.
p = fword + sp->ts_fidx;
- if (soundfold)
+ if (soundfold) {
gap = &slang->sl_repsal;
- else
+ } else {
gap = &lp->lp_replang->sl_rep;
+ }
while (sp->ts_curi < gap->ga_len) {
ftp = (fromto_T *)gap->ga_data + sp->ts_curi++;
if (*ftp->ft_from != *p) {
@@ -4733,8 +4865,8 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
go_deeper(stack, depth, SCORE_REP);
#ifdef DEBUG_TRIEWALK
sprintf(changename[depth], "%.*s-%s: replace %s with %s",
- sp->ts_twordlen, tword, fword + sp->ts_fidx,
- ftp->ft_from, ftp->ft_to);
+ sp->ts_twordlen, tword, fword + sp->ts_fidx,
+ ftp->ft_from, ftp->ft_to);
#endif
// Need to undo this afterwards.
PROF_STORE(sp->ts_state)
@@ -4755,19 +4887,21 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
}
}
- if (sp->ts_curi >= gap->ga_len && sp->ts_state == STATE_REP)
+ if (sp->ts_curi >= gap->ga_len && sp->ts_state == STATE_REP) {
// No (more) matches.
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_FINAL;
+ }
break;
case STATE_REP_UNDO:
// Undo a REP replacement and continue with the next one.
- if (soundfold)
+ if (soundfold) {
gap = &slang->sl_repsal;
- else
+ } else {
gap = &lp->lp_replang->sl_rep;
+ }
ftp = (fromto_T *)gap->ga_data + sp->ts_curi - 1;
fl = (int)STRLEN(ftp->ft_from);
tl = (int)STRLEN(ftp->ft_to);
@@ -4815,7 +4949,7 @@ static void go_deeper(trystate_T *stack, int depth, int score_add)
// fword[flen] and return the byte length of that many chars in "word".
static int nofold_len(char_u *fword, int flen, char_u *word)
{
- char_u *p;
+ char_u *p;
int i = 0;
for (p = fword; p < fword + flen; MB_PTR_ADV(p)) {
@@ -4849,9 +4983,9 @@ static void find_keepcap_word(slang_T *slang, char_u *fword, char_u *kword)
int len;
int c;
idx_T lo, hi, m;
- char_u *p;
- char_u *byts = slang->sl_kbyts; // array with bytes of the words
- idx_T *idxs = slang->sl_kidxs; // array with indexes
+ char_u *p;
+ char_u *byts = slang->sl_kbyts; // array with bytes of the words
+ idx_T *idxs = slang->sl_kidxs; // array with indexes
if (byts == NULL) {
// array is empty: "cannot happen"
@@ -4882,7 +5016,7 @@ static void find_keepcap_word(slang_T *slang, char_u *fword, char_u *kword)
// kword is getting too long, continue one level up
--depth;
- } else if (++round[depth] > 2) {
+ } else if (++round[depth] > 2) {
// tried both fold-case and upper-case character, continue one
// level up
--depth;
@@ -4907,19 +5041,20 @@ static void find_keepcap_word(slang_T *slang, char_u *fword, char_u *kword)
hi = tryidx + len - 1;
while (lo < hi) {
m = (lo + hi) / 2;
- if (byts[m] > c)
+ if (byts[m] > c) {
hi = m - 1;
- else if (byts[m] < c)
+ } else if (byts[m] < c) {
lo = m + 1;
- else {
+ } else {
lo = hi = m;
break;
}
}
// Stop if there is no matching byte.
- if (hi < lo || byts[lo] != c)
+ if (hi < lo || byts[lo] != c) {
break;
+ }
// Continue at the child (if there is one).
tryidx = idxs[lo];
@@ -4930,11 +5065,11 @@ static void find_keepcap_word(slang_T *slang, char_u *fword, char_u *kword)
// level deeper.
if (round[depth] == 1) {
STRNCPY(kword + kwordlen[depth], fword + fwordidx[depth],
- flen);
+ flen);
kwordlen[depth + 1] = kwordlen[depth] + flen;
} else {
STRNCPY(kword + kwordlen[depth], uword + uwordidx[depth],
- ulen);
+ ulen);
kwordlen[depth + 1] = kwordlen[depth] + ulen;
}
fwordidx[depth + 1] = fwordidx[depth] + flen;
@@ -4955,11 +5090,11 @@ static void find_keepcap_word(slang_T *slang, char_u *fword, char_u *kword)
// su->su_sga.
static void score_comp_sal(suginfo_T *su)
{
- langp_T *lp;
+ langp_T *lp;
char_u badsound[MAXWLEN];
int i;
- suggest_T *stp;
- suggest_T *sstp;
+ suggest_T *stp;
+ suggest_T *sstp;
int score;
ga_grow(&su->su_sga, su->su_ga.ga_len);
@@ -4998,13 +5133,13 @@ static void score_comp_sal(suginfo_T *su)
static void score_combine(suginfo_T *su)
{
garray_T ga;
- garray_T *gap;
- langp_T *lp;
- suggest_T *stp;
- char_u *p;
+ garray_T *gap;
+ langp_T *lp;
+ suggest_T *stp;
+ char_u *p;
char_u badsound[MAXWLEN];
int round;
- slang_T *slang = NULL;
+ slang_T *slang = NULL;
// Add the alternate score to su_ga.
for (int lpi = 0; lpi < curwin->w_s->b_langp.ga_len; ++lpi) {
@@ -5017,11 +5152,12 @@ static void score_combine(suginfo_T *su)
for (int i = 0; i < su->su_ga.ga_len; ++i) {
stp = &SUG(su->su_ga, i);
stp->st_altscore = stp_sal_score(stp, su, slang, badsound);
- if (stp->st_altscore == SCORE_MAXMAX)
+ if (stp->st_altscore == SCORE_MAXMAX) {
stp->st_score = (stp->st_score * 3 + SCORE_BIG) / 4;
- else
+ } else {
stp->st_score = (stp->st_score * 3
+ stp->st_altscore) / 4;
+ }
stp->st_salscore = false;
}
break;
@@ -5030,7 +5166,7 @@ static void score_combine(suginfo_T *su)
if (slang == NULL) { // Using "double" without sound folding.
(void)cleanup_suggestions(&su->su_ga, su->su_maxscore,
- su->su_maxcount);
+ su->su_maxcount);
return;
}
@@ -5038,11 +5174,12 @@ static void score_combine(suginfo_T *su)
for (int i = 0; i < su->su_sga.ga_len; ++i) {
stp = &SUG(su->su_sga, i);
stp->st_altscore = spell_edit_score(slang,
- su->su_badword, stp->st_word);
- if (stp->st_score == SCORE_MAXMAX)
+ su->su_badword, stp->st_word);
+ if (stp->st_score == SCORE_MAXMAX) {
stp->st_score = (SCORE_BIG * 7 + stp->st_altscore) / 8;
- else
+ } else {
stp->st_score = (stp->st_score * 7 + stp->st_altscore) / 8;
+ }
stp->st_salscore = true;
}
@@ -5066,13 +5203,16 @@ static void score_combine(suginfo_T *su)
// Don't add a word if it's already there.
p = SUG(*gap, i).st_word;
int j;
- for (j = 0; j < ga.ga_len; ++j)
- if (STRCMP(stp[j].st_word, p) == 0)
+ for (j = 0; j < ga.ga_len; ++j) {
+ if (STRCMP(stp[j].st_word, p) == 0) {
break;
- if (j == ga.ga_len)
+ }
+ }
+ if (j == ga.ga_len) {
stp[ga.ga_len++] = SUG(*gap, i);
- else
+ } else {
xfree(p);
+ }
}
}
}
@@ -5091,19 +5231,15 @@ static void score_combine(suginfo_T *su)
su->su_ga = ga;
}
-// For the goodword in "stp" compute the soundalike score compared to the
-// badword.
-static int
-stp_sal_score (
- suggest_T *stp,
- suginfo_T *su,
- slang_T *slang,
- char_u *badsound // sound-folded badword
-)
+/// For the goodword in "stp" compute the soundalike score compared to the
+/// badword.
+///
+/// @param badsound sound-folded badword
+static int stp_sal_score(suggest_T *stp, suginfo_T *su, slang_T *slang, char_u *badsound)
{
- char_u *p;
- char_u *pbad;
- char_u *pgood;
+ char_u *p;
+ char_u *pbad;
+ char_u *pgood;
char_u badsound2[MAXWLEN];
char_u fword[MAXWLEN];
char_u goodsound[MAXWLEN];
@@ -5111,9 +5247,9 @@ stp_sal_score (
int lendiff;
lendiff = su->su_badlen - stp->st_orglen;
- if (lendiff >= 0)
+ if (lendiff >= 0) {
pbad = badsound;
- else {
+ } else {
// soundfold the bad word with more characters following
(void)spell_casefold(curwin, su->su_badptr, stp->st_orglen, fword, MAXWLEN);
@@ -5122,9 +5258,11 @@ stp_sal_score (
// removing the space. Don't do it when the good word also contains a
// space.
if (ascii_iswhite(su->su_badptr[su->su_badlen])
- && *skiptowhite(stp->st_word) == NUL)
- for (p = fword; *(p = skiptowhite(p)) != NUL; )
+ && *skiptowhite(stp->st_word) == NUL) {
+ for (p = fword; *(p = skiptowhite(p)) != NUL; ) {
STRMOVE(p, p + 1);
+ }
+ }
spell_soundfold(slang, fword, true, badsound2);
pbad = badsound2;
@@ -5135,10 +5273,11 @@ stp_sal_score (
// what replaces the bad word.
STRCPY(goodword, stp->st_word);
STRLCPY(goodword + stp->st_wordlen,
- su->su_badptr + su->su_badlen - lendiff, lendiff + 1);
+ su->su_badptr + su->su_badlen - lendiff, lendiff + 1);
pgood = goodword;
- } else
+ } else {
pgood = stp->st_word;
+ }
// Sound-fold the word and compute the score for the difference.
spell_soundfold(slang, pgood, false, goodsound);
@@ -5153,17 +5292,18 @@ static sftword_T dumsft;
// Prepare for calling suggest_try_soundalike().
static void suggest_try_soundalike_prep(void)
{
- langp_T *lp;
- slang_T *slang;
+ langp_T *lp;
+ slang_T *slang;
// Do this for all languages that support sound folding and for which a
// .sug file has been loaded.
for (int lpi = 0; lpi < curwin->w_s->b_langp.ga_len; ++lpi) {
lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi);
slang = lp->lp_slang;
- if (!GA_EMPTY(&slang->sl_sal) && slang->sl_sbyts != NULL)
+ if (!GA_EMPTY(&slang->sl_sal) && slang->sl_sbyts != NULL) {
// prepare the hashtable used by add_sound_suggest()
hash_init(&slang->sl_sounddone);
+ }
}
}
@@ -5172,8 +5312,8 @@ static void suggest_try_soundalike_prep(void)
static void suggest_try_soundalike(suginfo_T *su)
{
char_u salword[MAXWLEN];
- langp_T *lp;
- slang_T *slang;
+ langp_T *lp;
+ slang_T *slang;
// Do this for all languages that support sound folding and for which a
// .sug file has been loaded.
@@ -5201,10 +5341,10 @@ static void suggest_try_soundalike(suginfo_T *su)
// Finish up after calling suggest_try_soundalike().
static void suggest_try_soundalike_finish(void)
{
- langp_T *lp;
- slang_T *slang;
+ langp_T *lp;
+ slang_T *slang;
int todo;
- hashitem_T *hi;
+ hashitem_T *hi;
// Do this for all languages that support sound folding and for which a
// .sug file has been loaded.
@@ -5214,11 +5354,12 @@ static void suggest_try_soundalike_finish(void)
if (!GA_EMPTY(&slang->sl_sal) && slang->sl_sbyts != NULL) {
// Free the info about handled words.
todo = (int)slang->sl_sounddone.ht_used;
- for (hi = slang->sl_sounddone.ht_array; todo > 0; ++hi)
+ for (hi = slang->sl_sounddone.ht_array; todo > 0; ++hi) {
if (!HASHITEM_EMPTY(hi)) {
xfree(HI2SFT(hi));
--todo;
}
+ }
// Clear the hashtable, it may also be used by another region.
hash_clear(&slang->sl_sounddone);
@@ -5227,32 +5368,28 @@ static void suggest_try_soundalike_finish(void)
}
}
-// A match with a soundfolded word is found. Add the good word(s) that
-// produce this soundfolded word.
-static void
-add_sound_suggest (
- suginfo_T *su,
- char_u *goodword,
- int score, // soundfold score
- langp_T *lp
-)
+/// A match with a soundfolded word is found. Add the good word(s) that
+/// produce this soundfolded word.
+///
+/// @param score soundfold score
+static void add_sound_suggest(suginfo_T *su, char_u *goodword, int score, langp_T *lp)
{
- slang_T *slang = lp->lp_slang; // language for sound folding
+ slang_T *slang = lp->lp_slang; // language for sound folding
int sfwordnr;
- char_u *nrline;
+ char_u *nrline;
int orgnr;
char_u theword[MAXWLEN];
int i;
int wlen;
- char_u *byts;
- idx_T *idxs;
+ char_u *byts;
+ idx_T *idxs;
int n;
int wordcount;
int wc;
int goodscore;
hash_T hash;
- hashitem_T *hi;
- sftword_T *sft;
+ hashitem_T *hi;
+ sftword_T *sft;
int bc, gc;
int limit;
@@ -5271,8 +5408,9 @@ add_sound_suggest (
hash_add_item(&slang->sl_sounddone, hi, sft->sft_word, hash);
} else {
sft = HI2SFT(hi);
- if (score >= sft->sft_score)
+ if (score >= sft->sft_score) {
return;
+ }
sft->sft_score = score;
}
@@ -5299,25 +5437,28 @@ add_sound_suggest (
wordcount = 0;
for (wlen = 0; wlen < MAXWLEN - 3; ++wlen) {
i = 1;
- if (wordcount == orgnr && byts[n + 1] == NUL)
+ if (wordcount == orgnr && byts[n + 1] == NUL) {
break; // found end of word
-
- if (byts[n + 1] == NUL)
+ }
+ if (byts[n + 1] == NUL) {
++wordcount;
+ }
// skip over the NUL bytes
- for (; byts[n + i] == NUL; ++i)
+ for (; byts[n + i] == NUL; ++i) {
if (i > byts[n]) { // safety check
STRCPY(theword + wlen, "BAD");
wlen += 3;
goto badword;
}
+ }
// One of the siblings must have the word.
for (; i < byts[n]; ++i) {
wc = idxs[idxs[n + i]]; // nr of words under this byte
- if (wordcount + wc > orgnr)
+ if (wordcount + wc > orgnr) {
break;
+ }
wordcount += wc;
}
@@ -5330,12 +5471,13 @@ badword:
// Go over the possible flags and regions.
for (; i <= byts[n] && byts[n + i] == NUL; ++i) {
char_u cword[MAXWLEN];
- char_u *p;
+ char_u *p;
int flags = (int)idxs[n + i];
// Skip words with the NOSUGGEST flag
- if (flags & WF_NOSUGGEST)
+ if (flags & WF_NOSUGGEST) {
continue;
+ }
if (flags & WF_KEEPCAP) {
// Must find the word in the keep-case tree.
@@ -5347,23 +5489,26 @@ badword:
// Need to fix case according to "flags".
make_case_word(theword, cword, flags);
p = cword;
- } else
+ } else {
p = theword;
+ }
}
// Add the suggestion.
if (sps_flags & SPS_DOUBLE) {
// Add the suggestion if the score isn't too bad.
- if (score <= su->su_maxscore)
+ if (score <= su->su_maxscore) {
add_suggestion(su, &su->su_sga, p, su->su_badlen,
- score, 0, false, slang, false);
+ score, 0, false, slang, false);
+ }
} else {
// Add a penalty for words in another region.
if ((flags & WF_REGION)
- && (((unsigned)flags >> 16) & lp->lp_region) == 0)
+ && (((unsigned)flags >> 16) & lp->lp_region) == 0) {
goodscore = SCORE_REGION;
- else
+ } else {
goodscore = 0;
+ }
// Add a small penalty for changing the first letter from
// lower to upper case. Helps for "tath" -> "Kath", which is
@@ -5373,8 +5518,9 @@ badword:
if (SPELL_ISUPPER(gc)) {
bc = PTR2CHAR(su->su_badword);
if (!SPELL_ISUPPER(bc)
- && SPELL_TOFOLD(bc) != SPELL_TOFOLD(gc))
+ && SPELL_TOFOLD(bc) != SPELL_TOFOLD(gc)) {
goodscore += SCORE_ICASE / 2;
+ }
}
// Compute the score for the good word. This only does letter
@@ -5385,11 +5531,12 @@ badword:
// If the limit is very high then the iterative method is
// inefficient, using an array is quicker.
limit = MAXSCORE(su->su_sfmaxscore - goodscore, score);
- if (limit > SCORE_LIMITMAX)
+ if (limit > SCORE_LIMITMAX) {
goodscore += spell_edit_score(slang, su->su_badword, p);
- else
+ } else {
goodscore += spell_edit_score_limit(slang, su->su_badword,
- p, limit);
+ p, limit);
+ }
// When going over the limit don't bother to do the rest.
if (goodscore < SCORE_MAXMAX) {
@@ -5398,9 +5545,10 @@ badword:
// Add the suggestion if the score isn't too bad.
goodscore = RESCORE(goodscore, score);
- if (goodscore <= su->su_sfmaxscore)
+ if (goodscore <= su->su_sfmaxscore) {
add_suggestion(su, &su->su_ga, p, su->su_badlen,
- goodscore, score, true, slang, true);
+ goodscore, score, true, slang, true);
+ }
}
}
}
@@ -5414,9 +5562,9 @@ static int soundfold_find(slang_T *slang, char_u *word)
int len;
int wlen = 0;
int c;
- char_u *ptr = word;
- char_u *byts;
- idx_T *idxs;
+ char_u *ptr = word;
+ char_u *byts;
+ idx_T *idxs;
int wordnr = 0;
byts = slang->sl_sbyts;
@@ -5430,35 +5578,41 @@ static int soundfold_find(slang_T *slang, char_u *word)
// If the word ends we found the word. If not skip the NUL bytes.
c = ptr[wlen];
if (byts[arridx] == NUL) {
- if (c == NUL)
+ if (c == NUL) {
break;
+ }
// Skip over the zeros, there can be several.
while (len > 0 && byts[arridx] == NUL) {
++arridx;
--len;
}
- if (len == 0)
+ if (len == 0) {
return -1; // no children, word should have ended here
+ }
++wordnr;
}
// If the word ends we didn't find it.
- if (c == NUL)
+ if (c == NUL) {
return -1;
+ }
// Perform a binary search in the list of accepted bytes.
- if (c == TAB) // <Tab> is handled like <Space>
+ if (c == TAB) { // <Tab> is handled like <Space>
c = ' ';
+ }
while (byts[arridx] < c) {
// The word count is in the first idxs[] entry of the child.
wordnr += idxs[idxs[arridx]];
++arridx;
- if (--len == 0) // end of the bytes, didn't find it
+ if (--len == 0) { // end of the bytes, didn't find it
return -1;
+ }
}
- if (byts[arridx] != c) // didn't find the byte
+ if (byts[arridx] != c) { // didn't find the byte
return -1;
+ }
// Continue at the child (if there is one).
arridx = idxs[arridx];
@@ -5466,9 +5620,11 @@ static int soundfold_find(slang_T *slang, char_u *word)
// One space in the good word may stand for several spaces in the
// checked word.
- if (c == ' ')
- while (ptr[wlen] == ' ' || ptr[wlen] == TAB)
+ if (c == ' ') {
+ while (ptr[wlen] == ' ' || ptr[wlen] == TAB) {
++wlen;
+ }
+ }
}
return wordnr;
@@ -5477,15 +5633,16 @@ static int soundfold_find(slang_T *slang, char_u *word)
// Copy "fword" to "cword", fixing case according to "flags".
static void make_case_word(char_u *fword, char_u *cword, int flags)
{
- if (flags & WF_ALLCAP)
+ if (flags & WF_ALLCAP) {
// Make it all upper-case
allcap_copy(fword, cword);
- else if (flags & WF_ONECAP)
+ } else if (flags & WF_ONECAP) {
// Make the first letter upper-case
onecap_copy(fword, cword, true);
- else
+ } else {
// Use goodword as-is.
STRCPY(cword, fword);
+ }
}
// Returns true if "c1" and "c2" are similar characters according to the MAP
@@ -5494,7 +5651,7 @@ static bool similar_chars(slang_T *slang, int c1, int c2)
{
int m1, m2;
char_u buf[MB_MAXBYTES + 1];
- hashitem_T *hi;
+ hashitem_T *hi;
if (c1 >= 256) {
buf[utf_char2bytes(c1, buf)] = 0;
@@ -5526,25 +5683,20 @@ static bool similar_chars(slang_T *slang, int c1, int c2)
return m1 == m2;
}
-// Adds a suggestion to the list of suggestions.
-// For a suggestion that is already in the list the lowest score is remembered.
-static void
-add_suggestion (
- suginfo_T *su,
- garray_T *gap, // either su_ga or su_sga
- const char_u *goodword,
- int badlenarg, // len of bad word replaced with "goodword"
- int score,
- int altscore,
- bool had_bonus, // value for st_had_bonus
- slang_T *slang, // language for sound folding
- bool maxsf // su_maxscore applies to soundfold score,
- // su_sfmaxscore to the total score.
-)
+/// Adds a suggestion to the list of suggestions.
+/// For a suggestion that is already in the list the lowest score is remembered.
+///
+/// @param gap either su_ga or su_sga
+/// @param badlenarg len of bad word replaced with "goodword"
+/// @param had_bonus value for st_had_bonus
+/// @param slang language for sound folding
+/// @param maxsf su_maxscore applies to soundfold score, su_sfmaxscore to the total score.
+static void add_suggestion(suginfo_T *su, garray_T *gap, const char_u *goodword, int badlenarg,
+ int score, int altscore, bool had_bonus, slang_T *slang, bool maxsf)
{
int goodlen; // len of goodword changed
int badlen; // len of bad word changed
- suggest_T *stp;
+ suggest_T *stp;
suggest_T new_sug;
// Minimize "badlen" for consistency. Avoids that changing "the the" to
@@ -5554,8 +5706,9 @@ add_suggestion (
for (;; ) {
goodlen = (int)(pgood - goodword);
badlen = (int)(pbad - su->su_badptr);
- if (goodlen <= 0 || badlen <= 0)
+ if (goodlen <= 0 || badlen <= 0) {
break;
+ }
MB_PTR_BACK(goodword, pgood);
MB_PTR_BACK(su->su_badptr, pbad);
if (utf_ptr2char(pgood) != utf_ptr2char(pbad)) {
@@ -5563,10 +5716,11 @@ add_suggestion (
}
}
- if (badlen == 0 && goodlen == 0)
+ if (badlen == 0 && goodlen == 0) {
// goodword doesn't change anything; may happen for "the the" changing
// the first "the" to itself.
return;
+ }
int i;
if (GA_EMPTY(gap)) {
@@ -5581,8 +5735,9 @@ add_suggestion (
&& stp->st_orglen == badlen
&& STRNCMP(stp->st_word, goodword, goodlen) == 0) {
// Found it. Remember the word with the lowest score.
- if (stp->st_slang == NULL)
+ if (stp->st_slang == NULL) {
stp->st_slang = slang;
+ }
new_sug.st_score = score;
new_sug.st_altscore = altscore;
@@ -5595,9 +5750,9 @@ add_suggestion (
// suggest_try_change() doesn't compute the soundalike
// word to keep it fast, while some special methods set
// the soundalike score to zero.
- if (had_bonus)
+ if (had_bonus) {
rescore_one(su, stp);
- else {
+ } else {
new_sug.st_word = stp->st_word;
new_sug.st_wordlen = stp->st_wordlen;
new_sug.st_slang = stp->st_slang;
@@ -5630,25 +5785,24 @@ add_suggestion (
// If we have too many suggestions now, sort the list and keep
// the best suggestions.
if (gap->ga_len > SUG_MAX_COUNT(su)) {
- if (maxsf)
+ if (maxsf) {
su->su_sfmaxscore = cleanup_suggestions(gap,
- su->su_sfmaxscore, SUG_CLEAN_COUNT(su));
- else
+ su->su_sfmaxscore, SUG_CLEAN_COUNT(su));
+ } else {
su->su_maxscore = cleanup_suggestions(gap,
- su->su_maxscore, SUG_CLEAN_COUNT(su));
+ su->su_maxscore, SUG_CLEAN_COUNT(su));
+ }
}
}
}
-// Suggestions may in fact be flagged as errors. Esp. for banned words and
-// for split words, such as "the the". Remove these from the list here.
-static void
-check_suggestions (
- suginfo_T *su,
- garray_T *gap // either su_ga or su_sga
-)
+/// Suggestions may in fact be flagged as errors. Esp. for banned words and
+/// for split words, such as "the the". Remove these from the list here.
+///
+/// @param gap either su_ga or su_sga
+static void check_suggestions(suginfo_T *su, garray_T *gap)
{
- suggest_T *stp;
+ suggest_T *stp;
char_u longword[MAXWLEN + 1];
int len;
hlf_T attr;
@@ -5662,16 +5816,17 @@ check_suggestions (
STRLCPY(longword, stp[i].st_word, MAXWLEN + 1);
len = stp[i].st_wordlen;
STRLCPY(longword + len, su->su_badptr + stp[i].st_orglen,
- MAXWLEN - len + 1);
+ MAXWLEN - len + 1);
attr = HLF_COUNT;
(void)spell_check(curwin, longword, &attr, NULL, false);
if (attr != HLF_COUNT) {
// Remove this entry.
xfree(stp[i].st_word);
--gap->ga_len;
- if (i < gap->ga_len)
+ if (i < gap->ga_len) {
memmove(stp + i, stp + i + 1,
- sizeof(suggest_T) * (gap->ga_len - i));
+ sizeof(suggest_T) * (gap->ga_len - i));
+ }
}
}
}
@@ -5680,9 +5835,9 @@ check_suggestions (
// Add a word to be banned.
static void add_banned(suginfo_T *su, char_u *word)
{
- char_u *s;
+ char_u *s;
hash_T hash;
- hashitem_T *hi;
+ hashitem_T *hi;
hash = hash_hash(word);
const size_t word_len = STRLEN(word);
@@ -5707,23 +5862,24 @@ static void rescore_suggestions(suginfo_T *su)
// Recompute the score for one suggestion if sound-folding is possible.
static void rescore_one(suginfo_T *su, suggest_T *stp)
{
- slang_T *slang = stp->st_slang;
+ slang_T *slang = stp->st_slang;
char_u sal_badword[MAXWLEN];
- char_u *p;
+ char_u *p;
// Only rescore suggestions that have no sal score yet and do have a
// language.
if (slang != NULL && !GA_EMPTY(&slang->sl_sal) && !stp->st_had_bonus) {
- if (slang == su->su_sallang)
+ if (slang == su->su_sallang) {
p = su->su_sal_badword;
- else {
+ } else {
spell_soundfold(slang, su->su_fbadword, true, sal_badword);
p = sal_badword;
}
stp->st_altscore = stp_sal_score(stp, su, slang, p);
- if (stp->st_altscore == SCORE_MAXMAX)
+ if (stp->st_altscore == SCORE_MAXMAX) {
stp->st_altscore = SCORE_BIG;
+ }
stp->st_score = RESCORE(stp->st_score, stp->st_altscore);
stp->st_had_bonus = true;
}
@@ -5734,28 +5890,27 @@ static void rescore_one(suginfo_T *su, suggest_T *stp)
// First on "st_score", then "st_altscore" then alphabetically.
static int sug_compare(const void *s1, const void *s2)
{
- suggest_T *p1 = (suggest_T *)s1;
- suggest_T *p2 = (suggest_T *)s2;
+ suggest_T *p1 = (suggest_T *)s1;
+ suggest_T *p2 = (suggest_T *)s2;
int n = p1->st_score - p2->st_score;
if (n == 0) {
n = p1->st_altscore - p2->st_altscore;
- if (n == 0)
+ if (n == 0) {
n = STRICMP(p1->st_word, p2->st_word);
+ }
}
return n;
}
-// Cleanup the suggestions:
-// - Sort on score.
-// - Remove words that won't be displayed.
-// Returns the maximum score in the list or "maxscore" unmodified.
-static int
-cleanup_suggestions (
- garray_T *gap,
- int maxscore,
- int keep // nr of suggestions to keep
-)
+/// Cleanup the suggestions:
+/// - Sort on score.
+/// - Remove words that won't be displayed.
+///
+/// @param keep nr of suggestions to keep
+///
+/// @return the maximum score in the list or "maxscore" unmodified.
+static int cleanup_suggestions(garray_T *gap, int maxscore, int keep)
FUNC_ATTR_NONNULL_ALL
{
if (gap->ga_len > 0) {
@@ -5823,12 +5978,12 @@ char *eval_soundfold(const char *const word)
void spell_soundfold(slang_T *slang, char_u *inword, bool folded, char_u *res)
{
char_u fword[MAXWLEN];
- char_u *word;
+ char_u *word;
- if (slang->sl_sofo)
+ if (slang->sl_sofo) {
// SOFOFROM and SOFOTO used
spell_soundfold_sofo(slang, inword, res);
- else {
+ } else {
// SAL items used. Requires the word to be case-folded.
if (folded) {
word = inword;
@@ -5892,12 +6047,12 @@ static void spell_soundfold_sofo(slang_T *slang, char_u *inword, char_u *res)
// Multi-byte version of spell_soundfold().
static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
{
- salitem_T *smp = (salitem_T *)slang->sl_sal.ga_data;
+ salitem_T *smp = (salitem_T *)slang->sl_sal.ga_data;
int word[MAXWLEN] = { 0 };
int wres[MAXWLEN] = { 0 };
int l;
- int *ws;
- int *pf;
+ int *ws;
+ int *pf;
int i, j, z;
int reslen;
int n, k = 0;
@@ -5954,27 +6109,34 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
&& ws[0] != NUL; ++n) {
// Quickly skip entries that don't match the word. Most
// entries are less then three chars, optimize for that.
- if (c != ws[0])
+ if (c != ws[0]) {
continue;
+ }
k = smp[n].sm_leadlen;
if (k > 1) {
- if (word[i + 1] != ws[1])
+ if (word[i + 1] != ws[1]) {
continue;
+ }
if (k > 2) {
- for (j = 2; j < k; ++j)
- if (word[i + j] != ws[j])
+ for (j = 2; j < k; ++j) {
+ if (word[i + j] != ws[j]) {
break;
- if (j < k)
+ }
+ }
+ if (j < k) {
continue;
+ }
}
}
if ((pf = smp[n].sm_oneof_w) != NULL) {
// Check for match with one of the chars in "sm_oneof".
- while (*pf != NUL && *pf != word[i + k])
+ while (*pf != NUL && *pf != word[i + k]) {
++pf;
- if (*pf == NUL)
+ }
+ if (*pf == NUL) {
continue;
+ }
++k;
}
char_u *s = smp[n].sm_rules;
@@ -5986,15 +6148,17 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
k--;
s++;
}
- if (*s == '<')
+ if (*s == '<') {
s++;
+ }
if (ascii_isdigit(*s)) {
// determine priority
pri = *s - '0';
s++;
}
- if (*s == '^' && *(s + 1) == '^')
+ if (*s == '^' && *(s + 1) == '^') {
s++;
+ }
if (*s == NUL
|| (*s == '^'
@@ -6017,19 +6181,24 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
for (; ((ws = smp[n0].sm_lead_w)[0] & 0xff)
== (c0 & 0xff); ++n0) {
// Quickly skip entries that don't match the word.
- if (c0 != ws[0])
+ if (c0 != ws[0]) {
continue;
+ }
k0 = smp[n0].sm_leadlen;
if (k0 > 1) {
- if (word[i + k] != ws[1])
+ if (word[i + k] != ws[1]) {
continue;
+ }
if (k0 > 2) {
pf = word + i + k + 1;
- for (j = 2; j < k0; ++j)
- if (*pf++ != ws[j])
+ for (j = 2; j < k0; ++j) {
+ if (*pf++ != ws[j]) {
break;
- if (j < k0)
+ }
+ }
+ if (j < k0) {
continue;
+ }
}
}
k0 += k - 1;
@@ -6037,10 +6206,12 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
if ((pf = smp[n0].sm_oneof_w) != NULL) {
// Check for match with one of the chars in
// "sm_oneof".
- while (*pf != NUL && *pf != word[i + k0])
+ while (*pf != NUL && *pf != word[i + k0]) {
++pf;
- if (*pf == NUL)
+ }
+ if (*pf == NUL) {
continue;
+ }
++k0;
}
@@ -6051,8 +6222,9 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
// "if (k0 == k)"
s++;
}
- if (*s == '<')
+ if (*s == '<') {
s++;
+ }
if (ascii_isdigit(*s)) {
p0 = *s - '0';
s++;
@@ -6062,22 +6234,25 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
// *s == '^' cuts
|| (*s == '$'
&& !spell_iswordp_w(word + i + k0,
- curwin))) {
- if (k0 == k)
+ curwin))) {
+ if (k0 == k) {
// this is just a piece of the string
continue;
+ }
- if (p0 < pri)
+ if (p0 < pri) {
// priority too low
continue;
+ }
// rule fits; stop search
break;
}
}
if (p0 >= pri && (smp[n0].sm_lead_w[0] & 0xff)
- == (c0 & 0xff))
+ == (c0 & 0xff)) {
continue;
+ }
}
// replace string
@@ -6088,20 +6263,23 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
// rule with '<' is used
if (reslen > 0 && ws != NULL && *ws != NUL
&& (wres[reslen - 1] == c
- || wres[reslen - 1] == *ws))
+ || wres[reslen - 1] == *ws)) {
reslen--;
+ }
z0 = 1;
z = 1;
k0 = 0;
- if (ws != NULL)
+ if (ws != NULL) {
while (*ws != NUL && word[i + k0] != NUL) {
word[i + k0] = *ws;
k0++;
ws++;
}
- if (k > k0)
+ }
+ if (k > k0) {
memmove(word + i + k0, word + i + k,
- sizeof(int) * (wordlen - (i + k) + 1));
+ sizeof(int) * (wordlen - (i + k) + 1));
+ }
// new "actual letter"
c = word[i];
@@ -6109,23 +6287,27 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
// no '<' rule used
i += k - 1;
z = 0;
- if (ws != NULL)
+ if (ws != NULL) {
while (*ws != NUL && ws[1] != NUL
&& reslen < MAXWLEN) {
- if (reslen == 0 || wres[reslen - 1] != *ws)
+ if (reslen == 0 || wres[reslen - 1] != *ws) {
wres[reslen++] = *ws;
+ }
ws++;
}
+ }
// new "actual letter"
- if (ws == NULL)
+ if (ws == NULL) {
c = NUL;
- else
+ } else {
c = *ws;
+ }
if (strstr((char *)s, "^^") != NULL) {
- if (c != NUL)
+ if (c != NUL) {
wres[reslen++] = c;
+ }
memmove(word, word + i + 1,
- sizeof(int) * (wordlen - (i + 1) + 1));
+ sizeof(int) * (wordlen - (i + 1) + 1));
i = 0;
z0 = 1;
}
@@ -6133,7 +6315,7 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
break;
}
}
- } else if (ascii_iswhite(c)) {
+ } else if (ascii_iswhite(c)) {
c = ' ';
k = 1;
}
@@ -6141,9 +6323,10 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
if (z0 == 0) {
if (k && !p0 && reslen < MAXWLEN && c != NUL
&& (!slang->sl_collapse || reslen == 0
- || wres[reslen - 1] != c))
+ || wres[reslen - 1] != c)) {
// condense only double letters
wres[reslen++] = c;
+ }
i++;
z = 0;
@@ -6162,35 +6345,36 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
res[l] = NUL;
}
-// Compute a score for two sound-a-like words.
-// This permits up to two inserts/deletes/swaps/etc. to keep things fast.
-// Instead of a generic loop we write out the code. That keeps it fast by
-// avoiding checks that will not be possible.
-static int
-soundalike_score (
- char_u *goodstart, // sound-folded good word
- char_u *badstart // sound-folded bad word
-)
+/// Compute a score for two sound-a-like words.
+/// This permits up to two inserts/deletes/swaps/etc. to keep things fast.
+/// Instead of a generic loop we write out the code. That keeps it fast by
+/// avoiding checks that will not be possible.
+///
+/// @param goodstart sound-folded good word
+/// @param badstart sound-folded bad word
+static int soundalike_score(char_u *goodstart, char_u *badstart)
{
- char_u *goodsound = goodstart;
- char_u *badsound = badstart;
+ char_u *goodsound = goodstart;
+ char_u *badsound = badstart;
int goodlen;
int badlen;
int n;
- char_u *pl, *ps;
- char_u *pl2, *ps2;
+ char_u *pl, *ps;
+ char_u *pl2, *ps2;
int score = 0;
// Adding/inserting "*" at the start (word starts with vowel) shouldn't be
// counted so much, vowels in the middle of the word aren't counted at all.
if ((*badsound == '*' || *goodsound == '*') && *badsound != *goodsound) {
if ((badsound[0] == NUL && goodsound[1] == NUL)
- || (goodsound[0] == NUL && badsound[1] == NUL))
+ || (goodsound[0] == NUL && badsound[1] == NUL)) {
// changing word with vowel to word without a sound
return SCORE_DEL;
- if (badsound[0] == NUL || goodsound[0] == NUL)
+ }
+ if (badsound[0] == NUL || goodsound[0] == NUL) {
// more than two changes
return SCORE_MAXMAX;
+ }
if (badsound[1] == goodsound[1]
|| (badsound[1] != NUL
@@ -6199,10 +6383,11 @@ soundalike_score (
// handle like a substitute
} else {
score = 2 * SCORE_DEL / 3;
- if (*badsound == '*')
+ if (*badsound == '*') {
++badsound;
- else
+ } else {
++goodsound;
+ }
}
}
@@ -6212,8 +6397,9 @@ soundalike_score (
// Return quickly if the lengths are too different to be fixed by two
// changes.
n = goodlen - badlen;
- if (n < -2 || n > 2)
+ if (n < -2 || n > 2) {
return SCORE_MAXMAX;
+ }
if (n > 0) {
pl = goodsound; // goodsound is longest
@@ -6239,8 +6425,9 @@ soundalike_score (
++ps;
}
// strings must be equal after second delete
- if (STRCMP(pl + 1, ps) == 0)
+ if (STRCMP(pl + 1, ps) == 0) {
return score + SCORE_DEL * 2;
+ }
// Failed to compare.
break;
@@ -6253,20 +6440,23 @@ soundalike_score (
pl2 = pl + 1;
ps2 = ps;
while (*pl2 == *ps2) {
- if (*pl2 == NUL) // reached the end
+ if (*pl2 == NUL) { // reached the end
return score + SCORE_DEL;
+ }
++pl2;
++ps2;
}
// 2: delete then swap, then rest must be equal
if (pl2[0] == ps2[1] && pl2[1] == ps2[0]
- && STRCMP(pl2 + 2, ps2 + 2) == 0)
+ && STRCMP(pl2 + 2, ps2 + 2) == 0) {
return score + SCORE_DEL + SCORE_SWAP;
+ }
// 3: delete then substitute, then the rest must be equal
- if (STRCMP(pl2 + 1, ps2 + 1) == 0)
+ if (STRCMP(pl2 + 1, ps2 + 1) == 0) {
return score + SCORE_DEL + SCORE_SUBST;
+ }
// 4: first swap then delete
if (pl[0] == ps[1] && pl[1] == ps[0]) {
@@ -6277,8 +6467,9 @@ soundalike_score (
++ps2;
}
// delete a char and then strings must be equal
- if (STRCMP(pl2 + 1, ps2) == 0)
+ if (STRCMP(pl2 + 1, ps2) == 0) {
return score + SCORE_SWAP + SCORE_DEL;
+ }
}
// 5: first substitute then delete
@@ -6289,8 +6480,9 @@ soundalike_score (
++ps2;
}
// delete a char and then strings must be equal
- if (STRCMP(pl2 + 1, ps2) == 0)
+ if (STRCMP(pl2 + 1, ps2) == 0) {
return score + SCORE_SUBST + SCORE_DEL;
+ }
// Failed to compare.
break;
@@ -6299,47 +6491,54 @@ soundalike_score (
// Lengths are equal, thus changes must result in same length: An
// insert is only possible in combination with a delete.
// 1: check if for identical strings
- if (*pl == NUL)
+ if (*pl == NUL) {
return score;
+ }
// 2: swap
if (pl[0] == ps[1] && pl[1] == ps[0]) {
pl2 = pl + 2; // swap, skip two chars
ps2 = ps + 2;
while (*pl2 == *ps2) {
- if (*pl2 == NUL) // reached the end
+ if (*pl2 == NUL) { // reached the end
return score + SCORE_SWAP;
+ }
++pl2;
++ps2;
}
// 3: swap and swap again
if (pl2[0] == ps2[1] && pl2[1] == ps2[0]
- && STRCMP(pl2 + 2, ps2 + 2) == 0)
+ && STRCMP(pl2 + 2, ps2 + 2) == 0) {
return score + SCORE_SWAP + SCORE_SWAP;
+ }
// 4: swap and substitute
- if (STRCMP(pl2 + 1, ps2 + 1) == 0)
+ if (STRCMP(pl2 + 1, ps2 + 1) == 0) {
return score + SCORE_SWAP + SCORE_SUBST;
+ }
}
// 5: substitute
pl2 = pl + 1;
ps2 = ps + 1;
while (*pl2 == *ps2) {
- if (*pl2 == NUL) // reached the end
+ if (*pl2 == NUL) { // reached the end
return score + SCORE_SUBST;
+ }
++pl2;
++ps2;
}
// 6: substitute and swap
if (pl2[0] == ps2[1] && pl2[1] == ps2[0]
- && STRCMP(pl2 + 2, ps2 + 2) == 0)
+ && STRCMP(pl2 + 2, ps2 + 2) == 0) {
return score + SCORE_SUBST + SCORE_SWAP;
+ }
// 7: substitute and substitute
- if (STRCMP(pl2 + 1, ps2 + 1) == 0)
+ if (STRCMP(pl2 + 1, ps2 + 1) == 0) {
return score + SCORE_SUBST + SCORE_SUBST;
+ }
// 8: insert then delete
pl2 = pl;
@@ -6348,8 +6547,9 @@ soundalike_score (
++pl2;
++ps2;
}
- if (STRCMP(pl2 + 1, ps2) == 0)
+ if (STRCMP(pl2 + 1, ps2) == 0) {
return score + SCORE_INS + SCORE_DEL;
+ }
// 9: delete then insert
pl2 = pl + 1;
@@ -6358,8 +6558,9 @@ soundalike_score (
++pl2;
++ps2;
}
- if (STRCMP(pl2, ps2 + 1) == 0)
+ if (STRCMP(pl2, ps2 + 1) == 0) {
return score + SCORE_INS + SCORE_DEL;
+ }
// Failed to compare.
break;
@@ -6408,8 +6609,9 @@ static int spell_edit_score(slang_T *slang, char_u *badword, char_u *goodword)
cnt = xmalloc(sizeof(int) * (badlen + 1) * (goodlen + 1));
CNT(0, 0) = 0;
- for (j = 1; j <= goodlen; ++j)
+ for (j = 1; j <= goodlen; ++j) {
CNT(0, j) = CNT(0, j - 1) + SCORE_INS;
+ }
for (i = 1; i <= badlen; ++i) {
CNT(i, 0) = CNT(i - 1, 0) + SCORE_DEL;
@@ -6420,16 +6622,17 @@ static int spell_edit_score(slang_T *slang, char_u *badword, char_u *goodword)
CNT(i, j) = CNT(i - 1, j - 1);
} else {
// Use a better score when there is only a case difference.
- if (SPELL_TOFOLD(bc) == SPELL_TOFOLD(gc))
+ if (SPELL_TOFOLD(bc) == SPELL_TOFOLD(gc)) {
CNT(i, j) = SCORE_ICASE + CNT(i - 1, j - 1);
- else {
+ } else {
// For a similar character use SCORE_SIMILAR.
if (slang != NULL
&& slang->sl_has_map
- && similar_chars(slang, gc, bc))
+ && similar_chars(slang, gc, bc)) {
CNT(i, j) = SCORE_SIMILAR + CNT(i - 1, j - 1);
- else
+ } else {
CNT(i, j) = SCORE_SUBST + CNT(i - 1, j - 1);
+ }
}
if (i > 1 && j > 1) {
@@ -6437,16 +6640,19 @@ static int spell_edit_score(slang_T *slang, char_u *badword, char_u *goodword)
pgc = wgoodword[j - 2];
if (bc == pgc && pbc == gc) {
t = SCORE_SWAP + CNT(i - 2, j - 2);
- if (t < CNT(i, j))
+ if (t < CNT(i, j)) {
CNT(i, j) = t;
+ }
}
}
t = SCORE_DEL + CNT(i - 1, j);
- if (t < CNT(i, j))
+ if (t < CNT(i, j)) {
CNT(i, j) = t;
+ }
t = SCORE_INS + CNT(i, j - 1);
- if (t < CNT(i, j))
+ if (t < CNT(i, j)) {
CNT(i, j) = t;
+ }
}
}
}
@@ -6515,11 +6721,13 @@ static int spell_edit_score_limit_w(slang_T *slang, char_u *badword, char_u *goo
bc = wbadword[bi];
gc = wgoodword[gi];
- if (bc != gc) // stop at a char that's different
+ if (bc != gc) { // stop at a char that's different
break;
+ }
if (bc == NUL) { // both words end
- if (score < minscore)
+ if (score < minscore) {
minscore = score;
+ }
goto pop; // do next alternative
}
++bi;
@@ -6528,14 +6736,16 @@ static int spell_edit_score_limit_w(slang_T *slang, char_u *badword, char_u *goo
if (gc == NUL) { // goodword ends, delete badword chars
do {
- if ((score += SCORE_DEL) >= minscore)
+ if ((score += SCORE_DEL) >= minscore) {
goto pop; // do next alternative
+ }
} while (wbadword[++bi] != NUL);
minscore = score;
- } else if (bc == NUL) { // badword ends, insert badword chars
+ } else if (bc == NUL) { // badword ends, insert badword chars
do {
- if ((score += SCORE_INS) >= minscore)
+ if ((score += SCORE_INS) >= minscore) {
goto pop; // do next alternative
+ }
} while (wgoodword[++gi] != NUL);
minscore = score;
} else { // both words continue
@@ -6586,16 +6796,17 @@ static int spell_edit_score_limit_w(slang_T *slang, char_u *badword, char_u *goo
// Substitute one character for another which is the same
// thing as deleting a character from both goodword and badword.
// Use a better score when there is only a case difference.
- if (SPELL_TOFOLD(bc) == SPELL_TOFOLD(gc))
+ if (SPELL_TOFOLD(bc) == SPELL_TOFOLD(gc)) {
score += SCORE_ICASE;
- else {
+ } else {
// For a similar character use SCORE_SIMILAR.
if (slang != NULL
&& slang->sl_has_map
- && similar_chars(slang, gc, bc))
+ && similar_chars(slang, gc, bc)) {
score += SCORE_SIMILAR;
- else
+ } else {
score += SCORE_SUBST;
+ }
}
if (score < minscore) {
@@ -6607,8 +6818,9 @@ static int spell_edit_score_limit_w(slang_T *slang, char_u *badword, char_u *goo
}
pop:
// Get here to try the next alternative, pop it from the stack.
- if (stackidx == 0) // stack is empty, finished
+ if (stackidx == 0) { // stack is empty, finished
break;
+ }
// pop an item from the stack
--stackidx;
@@ -6620,8 +6832,9 @@ pop:
// When the score goes over "limit" it may actually be much higher.
// Return a very large number to avoid going below the limit when giving a
// bonus.
- if (minscore > limit)
+ if (minscore > limit) {
return SCORE_MAXMAX;
+ }
return minscore;
}
@@ -6656,7 +6869,7 @@ void ex_spellinfo(exarg_T *eap)
// ":spelldump"
void ex_spelldump(exarg_T *eap)
{
- char_u *spl;
+ char_u *spl;
long dummy;
if (no_spell_checking(curwin)) {
@@ -6672,7 +6885,7 @@ void ex_spelldump(exarg_T *eap)
set_option_value("spl", dummy, (char *)spl, OPT_LOCAL);
xfree(spl);
- if (!BUFEMPTY()) {
+ if (!buf_is_empty(curbuf)) {
return;
}
@@ -6685,50 +6898,49 @@ void ex_spelldump(exarg_T *eap)
redraw_later(curwin, NOT_VALID);
}
-// Go through all possible words and:
-// 1. When "pat" is NULL: dump a list of all words in the current buffer.
-// "ic" and "dir" are not used.
-// 2. When "pat" is not NULL: add matching words to insert mode completion.
-void
-spell_dump_compl (
- char_u *pat, // leading part of the word
- int ic, // ignore case
- Direction *dir, // direction for adding matches
- int dumpflags_arg // DUMPFLAG_*
-)
+/// Go through all possible words and:
+/// 1. When "pat" is NULL: dump a list of all words in the current buffer.
+/// "ic" and "dir" are not used.
+/// 2. When "pat" is not NULL: add matching words to insert mode completion.
+///
+/// @param pat leading part of the word
+/// @param ic ignore case
+/// @param dir direction for adding matches
+/// @param dumpflags_arg DUMPFLAG_*
+void spell_dump_compl(char_u *pat, int ic, Direction *dir, int dumpflags_arg)
{
- langp_T *lp;
- slang_T *slang;
+ langp_T *lp;
+ slang_T *slang;
idx_T arridx[MAXWLEN];
int curi[MAXWLEN];
char_u word[MAXWLEN];
int c;
- char_u *byts;
- idx_T *idxs;
+ char_u *byts;
+ idx_T *idxs;
linenr_T lnum = 0;
int round;
int depth;
int n;
int flags;
- char_u *region_names = NULL; // region names being used
+ char_u *region_names = NULL; // region names being used
bool do_region = true; // dump region names and numbers
- char_u *p;
+ char_u *p;
int dumpflags = dumpflags_arg;
int patlen;
// When ignoring case or when the pattern starts with capital pass this on
// to dump_word().
if (pat != NULL) {
- if (ic)
+ if (ic) {
dumpflags |= DUMPFLAG_ICASE;
- else {
+ } else {
n = captype(pat, NULL);
- if (n == WF_ONECAP)
+ if (n == WF_ONECAP) {
dumpflags |= DUMPFLAG_ONECAP;
- else if (n == WF_ALLCAP
- && (int)STRLEN(pat) > mb_ptr2len(pat)
- )
+ } else if (n == WF_ALLCAP
+ && (int)STRLEN(pat) > mb_ptr2len(pat)) {
dumpflags |= DUMPFLAG_ALLCAP;
+ }
}
}
@@ -6738,9 +6950,9 @@ spell_dump_compl (
lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi);
p = lp->lp_slang->sl_regions;
if (p[0] != 0) {
- if (region_names == NULL) // first language with regions
+ if (region_names == NULL) { // first language with regions
region_names = p;
- else if (STRCMP(region_names, p) != 0) {
+ } else if (STRCMP(region_names, p) != 0) {
do_region = false; // region names are different
break;
}
@@ -6752,15 +6964,17 @@ spell_dump_compl (
vim_snprintf((char *)IObuff, IOSIZE, "/regions=%s", region_names);
ml_append(lnum++, IObuff, (colnr_T)0, false);
}
- } else
+ } else {
do_region = false;
+ }
// Loop over all files loaded for the entries in 'spelllang'.
for (int lpi = 0; lpi < curwin->w_s->b_langp.ga_len; ++lpi) {
lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi);
slang = lp->lp_slang;
- if (slang->sl_fbyts == NULL) // reloading failed
+ if (slang->sl_fbyts == NULL) { // reloading failed
continue;
+ }
if (pat == NULL) {
vim_snprintf((char *)IObuff, IOSIZE, "# file: %s", slang->sl_fname);
@@ -6769,10 +6983,11 @@ spell_dump_compl (
// When matching with a pattern and there are no prefixes only use
// parts of the tree that match "pat".
- if (pat != NULL && slang->sl_pbyts == NULL)
+ if (pat != NULL && slang->sl_pbyts == NULL) {
patlen = (int)STRLEN(pat);
- else
+ } else {
patlen = -1;
+ }
// round 1: case-folded tree
// round 2: keep-case tree
@@ -6786,9 +7001,9 @@ spell_dump_compl (
byts = slang->sl_kbyts;
idxs = slang->sl_kidxs;
}
- if (byts == NULL)
+ if (byts == NULL) {
continue; // array is empty
-
+ }
depth = 0;
arridx[0] = 0;
curi[0] = 1;
@@ -6817,23 +7032,26 @@ spell_dump_compl (
|| (((unsigned)flags >> 16)
& lp->lp_region) != 0)) {
word[depth] = NUL;
- if (!do_region)
+ if (!do_region) {
flags &= ~WF_REGION;
+ }
// Dump the basic word if there is no prefix or
// when it's the first one.
c = (unsigned)flags >> 24;
if (c == 0 || curi[depth] == 2) {
dump_word(slang, word, pat, dir,
- dumpflags, flags, lnum);
- if (pat == NULL)
+ dumpflags, flags, lnum);
+ if (pat == NULL) {
++lnum;
+ }
}
// Apply the prefix, if there is one.
- if (c != 0)
+ if (c != 0) {
lnum = dump_prefixes(slang, word, pat, dir,
- dumpflags, flags, lnum);
+ dumpflags, flags, lnum);
+ }
}
} else {
// Normal char, go one level deeper.
@@ -6849,8 +7067,9 @@ spell_dump_compl (
// ignore case...
assert(depth >= 0);
if (depth <= patlen
- && mb_strnicmp(word, pat, (size_t)depth) != 0)
+ && mb_strnicmp(word, pat, (size_t)depth) != 0) {
--depth;
+ }
}
}
}
@@ -6860,22 +7079,23 @@ spell_dump_compl (
// Dumps one word: apply case modifications and append a line to the buffer.
// When "lnum" is zero add insert mode completion.
-static void dump_word(slang_T *slang, char_u *word, char_u *pat,
- Direction *dir, int dumpflags, int wordflags,
- linenr_T lnum)
+static void dump_word(slang_T *slang, char_u *word, char_u *pat, Direction *dir, int dumpflags,
+ int wordflags, linenr_T lnum)
{
bool keepcap = false;
- char_u *p;
- char_u *tw;
+ char_u *p;
+ char_u *tw;
char_u cword[MAXWLEN];
char_u badword[MAXWLEN + 10];
int i;
int flags = wordflags;
- if (dumpflags & DUMPFLAG_ONECAP)
+ if (dumpflags & DUMPFLAG_ONECAP) {
flags |= WF_ONECAP;
- if (dumpflags & DUMPFLAG_ALLCAP)
+ }
+ if (dumpflags & DUMPFLAG_ALLCAP) {
flags |= WF_ALLCAP;
+ }
if ((dumpflags & DUMPFLAG_KEEPCASE) == 0 && (flags & WF_CAPMASK) != 0) {
// Need to fix case according to "flags".
@@ -6885,8 +7105,9 @@ static void dump_word(slang_T *slang, char_u *word, char_u *pat,
p = word;
if ((dumpflags & DUMPFLAG_KEEPCASE)
&& ((captype(word, NULL) & WF_KEEPCAP) == 0
- || (flags & WF_FIXCAP) != 0))
+ || (flags & WF_FIXCAP) != 0)) {
keepcap = true;
+ }
}
tw = p;
@@ -6917,13 +7138,13 @@ static void dump_word(slang_T *slang, char_u *word, char_u *pat,
}
if (dumpflags & DUMPFLAG_COUNT) {
- hashitem_T *hi;
+ hashitem_T *hi;
// Include the word count for ":spelldump!".
hi = hash_find(&slang->sl_wordcount, tw);
if (!HASHITEM_EMPTY(hi)) {
vim_snprintf((char *)IObuff, IOSIZE, "%s\t%d",
- tw, HI2WC(hi)->wc_count);
+ tw, HI2WC(hi)->wc_count);
p = IObuff;
}
}
@@ -6939,20 +7160,16 @@ static void dump_word(slang_T *slang, char_u *word, char_u *pat,
}
}
-// For ":spelldump": Find matching prefixes for "word". Prepend each to
-// "word" and append a line to the buffer.
-// When "lnum" is zero add insert mode completion.
-// Return the updated line number.
-static linenr_T
-dump_prefixes (
- slang_T *slang,
- char_u *word, // case-folded word
- char_u *pat,
- Direction *dir,
- int dumpflags,
- int flags, // flags with prefix ID
- linenr_T startlnum
-)
+/// For ":spelldump": Find matching prefixes for "word". Prepend each to
+/// "word" and append a line to the buffer.
+/// When "lnum" is zero add insert mode completion.
+///
+/// @param word case-folded word
+/// @param flags flags with prefix ID
+///
+/// @return the updated line number.
+static linenr_T dump_prefixes(slang_T *slang, char_u *word, char_u *pat, Direction *dir,
+ int dumpflags, int flags, linenr_T startlnum)
{
idx_T arridx[MAXWLEN];
int curi[MAXWLEN];
@@ -6960,8 +7177,8 @@ dump_prefixes (
char_u word_up[MAXWLEN];
bool has_word_up = false;
int c;
- char_u *byts;
- idx_T *idxs;
+ char_u *byts;
+ idx_T *idxs;
linenr_T lnum = startlnum;
int depth;
int n;
@@ -6998,19 +7215,22 @@ dump_prefixes (
c = byts[n];
if (c == 0) {
// End of prefix, find out how many IDs there are.
- for (i = 1; i < len; ++i)
- if (byts[n + i] != 0)
+ for (i = 1; i < len; ++i) {
+ if (byts[n + i] != 0) {
break;
+ }
+ }
curi[depth] += i - 1;
c = valid_word_prefix(i, n, flags, word, slang, false);
if (c != 0) {
STRLCPY(prefix + depth, word, MAXWLEN - depth);
dump_word(slang, prefix, pat, dir, dumpflags,
- (c & WF_RAREPFX) ? (flags | WF_RARE)
- : flags, lnum);
- if (lnum != 0)
+ (c & WF_RAREPFX) ? (flags | WF_RARE)
+ : flags, lnum);
+ if (lnum != 0) {
++lnum;
+ }
}
// Check for prefix that matches the word when the
@@ -7018,14 +7238,15 @@ dump_prefixes (
// a condition.
if (has_word_up) {
c = valid_word_prefix(i, n, flags, word_up, slang,
- true);
+ true);
if (c != 0) {
STRLCPY(prefix + depth, word_up, MAXWLEN - depth);
dump_word(slang, prefix, pat, dir, dumpflags,
- (c & WF_RAREPFX) ? (flags | WF_RARE)
- : flags, lnum);
- if (lnum != 0)
+ (c & WF_RAREPFX) ? (flags | WF_RARE)
+ : flags, lnum);
+ if (lnum != 0) {
++lnum;
+ }
}
}
} else {
@@ -7045,7 +7266,7 @@ dump_prefixes (
// Uses the spell-checking word characters.
char_u *spell_to_word_end(char_u *start, win_T *win)
{
- char_u *p = start;
+ char_u *p = start;
while (*p != NUL && spell_iswordp(p, win)) {
MB_PTR_ADV(p);
@@ -7060,8 +7281,8 @@ char_u *spell_to_word_end(char_u *start, win_T *win)
// Returns the column number of the word.
int spell_word_start(int startcol)
{
- char_u *line;
- char_u *p;
+ char_u *line;
+ char_u *p;
int col = 0;
if (no_spell_checking(curwin)) {
diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c
index 0597f392e7..772275df84 100644
--- a/src/nvim/spellfile.c
+++ b/src/nvim/spellfile.c
@@ -226,19 +226,17 @@
// stored as an offset to the previous number in as
// few bytes as possible, see offset2bytes())
-#include <stdio.h>
#include <stdint.h>
+#include <stdio.h>
#include <wctype.h>
-#include "nvim/vim.h"
-#include "nvim/spell_defs.h"
#include "nvim/ascii.h"
#include "nvim/buffer.h"
#include "nvim/charset.h"
#include "nvim/ex_cmds2.h"
#include "nvim/fileio.h"
-#include "nvim/memory.h"
#include "nvim/memline.h"
+#include "nvim/memory.h"
#include "nvim/misc1.h"
#include "nvim/option.h"
#include "nvim/os/os.h"
@@ -246,9 +244,11 @@
#include "nvim/regexp.h"
#include "nvim/screen.h"
#include "nvim/spell.h"
+#include "nvim/spell_defs.h"
#include "nvim/spellfile.h"
#include "nvim/ui.h"
#include "nvim/undo.h"
+#include "nvim/vim.h"
#ifndef UNIX // it's in os/unix_defs.h for Unix
# include <time.h> // for time_t
@@ -310,7 +310,7 @@ static char *msg_compressing = N_("Compressing word tree...");
// and .dic file.
// Main structure to store the contents of a ".aff" file.
typedef struct afffile_S {
- char_u *af_enc; // "SET", normalized, alloc'ed string or NULL
+ char_u *af_enc; // "SET", normalized, alloc'ed string or NULL
int af_flagtype; // AFT_CHAR, AFT_LONG, AFT_NUM or AFT_CAPLONG
unsigned af_rare; // RARE ID for rare word
unsigned af_keepcase; // KEEPCASE ID for keep-case word
@@ -338,17 +338,17 @@ typedef struct afffile_S {
typedef struct affentry_S affentry_T;
// Affix entry from ".aff" file. Used for prefixes and suffixes.
struct affentry_S {
- affentry_T *ae_next; // next affix with same name/number
- char_u *ae_chop; // text to chop off basic word (can be NULL)
- char_u *ae_add; // text to add to basic word (can be NULL)
- char_u *ae_flags; // flags on the affix (can be NULL)
- char_u *ae_cond; // condition (NULL for ".")
- regprog_T *ae_prog; // regexp program for ae_cond or NULL
+ affentry_T *ae_next; // next affix with same name/number
+ char_u *ae_chop; // text to chop off basic word (can be NULL)
+ char_u *ae_add; // text to add to basic word (can be NULL)
+ char_u *ae_flags; // flags on the affix (can be NULL)
+ char_u *ae_cond; // condition (NULL for ".")
+ regprog_T *ae_prog; // regexp program for ae_cond or NULL
char ae_compforbid; // COMPOUNDFORBIDFLAG found
char ae_comppermit; // COMPOUNDPERMITFLAG found
};
-# define AH_KEY_LEN 17 // 2 x 8 bytes + NUL
+#define AH_KEY_LEN 17 // 2 x 8 bytes + NUL
// Affix header from ".aff" file. Used for af_pref and af_suff.
typedef struct affheader_S {
@@ -357,7 +357,7 @@ typedef struct affheader_S {
int ah_newID; // prefix ID after renumbering; 0 if not used
int ah_combine; // suffix may combine with prefix
int ah_follows; // another affix block should be following
- affentry_T *ah_first; // first affix entry
+ affentry_T *ah_first; // first affix entry
} affheader_T;
#define HI2AH(hi) ((affheader_T *)(hi)->hi_key)
@@ -381,7 +381,7 @@ typedef struct compitem_S {
typedef struct sblock_S sblock_T;
struct sblock_S {
int sb_used; // nr of bytes already in use
- sblock_T *sb_next; // next block in list
+ sblock_T *sb_next; // next block in list
char_u sb_data[1]; // data, actually longer
};
@@ -397,9 +397,9 @@ struct wordnode_S {
wordnode_T *next; // next node with same hash key
wordnode_T *wnode; // parent node that will write this node
} wn_u2;
- wordnode_T *wn_child; // child (next byte in word)
- wordnode_T *wn_sibling; // next sibling (alternate byte in word,
- // always sorted)
+ wordnode_T *wn_child; // child (next byte in word)
+ wordnode_T *wn_sibling; // next sibling (alternate byte in word,
+ // always sorted)
int wn_refs; // Nr. of references to this node. Only
// relevant for first node in a list of
// siblings, in following siblings it is
@@ -425,29 +425,29 @@ struct wordnode_S {
// Info used while reading the spell files.
typedef struct spellinfo_S {
- wordnode_T *si_foldroot; // tree with case-folded words
+ wordnode_T *si_foldroot; // tree with case-folded words
long si_foldwcount; // nr of words in si_foldroot
- wordnode_T *si_keeproot; // tree with keep-case words
+ wordnode_T *si_keeproot; // tree with keep-case words
long si_keepwcount; // nr of words in si_keeproot
- wordnode_T *si_prefroot; // tree with postponed prefixes
+ wordnode_T *si_prefroot; // tree with postponed prefixes
long si_sugtree; // creating the soundfolding trie
- sblock_T *si_blocks; // memory blocks used
+ sblock_T *si_blocks; // memory blocks used
long si_blocks_cnt; // memory blocks allocated
int si_did_emsg; // TRUE when ran out of memory
long si_compress_cnt; // words to add before lowering
// compression limit
- wordnode_T *si_first_free; // List of nodes that have been freed during
- // compression, linked by "wn_child" field.
+ wordnode_T *si_first_free; // List of nodes that have been freed during
+ // compression, linked by "wn_child" field.
long si_free_count; // number of nodes in si_first_free
#ifdef SPELL_PRINTTREE
int si_wordnode_nr; // sequence nr for nodes
#endif
- buf_T *si_spellbuf; // buffer used to store soundfold word table
+ buf_T *si_spellbuf; // buffer used to store soundfold word table
int si_ascii; // handling only ASCII words
int si_add; // addition file
@@ -457,18 +457,18 @@ typedef struct spellinfo_S {
int si_memtot; // runtime memory used
int si_verbose; // verbose messages
int si_msg_count; // number of words added since last message
- char_u *si_info; // info text chars or NULL
+ char_u *si_info; // info text chars or NULL
int si_region_count; // number of regions supported (1 when there
// are no regions)
char_u si_region_name[MAXREGIONS * 2 + 1];
- // region names; used only if
- // si_region_count > 1)
+ // region names; used only if
+ // si_region_count > 1)
garray_T si_rep; // list of fromto_T entries from REP lines
garray_T si_repsal; // list of fromto_T entries from REPSAL lines
garray_T si_sal; // list of fromto_T entries from SAL lines
- char_u *si_sofofr; // SOFOFROM text
- char_u *si_sofoto; // SOFOTO text
+ char_u *si_sofofr; // SOFOFROM text
+ char_u *si_sofoto; // SOFOTO text
int si_nosugfile; // NOSUGFILE item found
int si_nosplitsugs; // NOSPLITSUGS item found
int si_nocompoundsugs; // NOCOMPOUNDSUGS item found
@@ -478,16 +478,16 @@ typedef struct spellinfo_S {
time_t si_sugtime; // timestamp for .sug file
int si_rem_accents; // soundsalike: remove accents
garray_T si_map; // MAP info concatenated
- char_u *si_midword; // MIDWORD chars or NULL
+ char_u *si_midword; // MIDWORD chars or NULL
int si_compmax; // max nr of words for compounding
int si_compminlen; // minimal length for compounding
int si_compsylmax; // max nr of syllables for compounding
int si_compoptions; // COMP_ flags
garray_T si_comppat; // CHECKCOMPOUNDPATTERN items, each stored as
// a string
- char_u *si_compflags; // flags used for compounding
+ char_u *si_compflags; // flags used for compounding
char_u si_nobreak; // NOBREAK
- char_u *si_syllable; // syllable string
+ char_u *si_syllable; // syllable string
garray_T si_prefcond; // table with conditions for postponed
// prefixes, each stored as a string
int si_newprefID; // current value for ah_newID
@@ -508,16 +508,16 @@ typedef struct spellinfo_S {
/// @return Allows to proceed if everything is OK, returns SP_TRUNCERROR if
/// there are not enough bytes, returns SP_OTHERERROR if reading failed.
#define SPELL_READ_BYTES(buf, n, fd, exit_code) \
- do { \
- const size_t n__SPRB = (n); \
- FILE *const fd__SPRB = (fd); \
- char *const buf__SPRB = (buf); \
- const size_t read_bytes__SPRB = fread(buf__SPRB, 1, n__SPRB, fd__SPRB); \
- if (read_bytes__SPRB != n__SPRB) { \
- exit_code; \
- return feof(fd__SPRB) ? SP_TRUNCERROR : SP_OTHERERROR; \
- } \
- } while (0)
+ do { \
+ const size_t n__SPRB = (n); \
+ FILE *const fd__SPRB = (fd); \
+ char *const buf__SPRB = (buf); \
+ const size_t read_bytes__SPRB = fread(buf__SPRB, 1, n__SPRB, fd__SPRB); \
+ if (read_bytes__SPRB != n__SPRB) { \
+ exit_code; \
+ return feof(fd__SPRB) ? SP_TRUNCERROR : SP_OTHERERROR; \
+ } \
+ } while (0)
/// Like #SPELL_READ_BYTES, but also error out if NUL byte was read
///
@@ -525,16 +525,16 @@ typedef struct spellinfo_S {
/// there are not enough bytes, returns SP_OTHERERROR if reading failed,
/// returns SP_FORMERROR if read out a NUL byte.
#define SPELL_READ_NONNUL_BYTES(buf, n, fd, exit_code) \
- do { \
- const size_t n__SPRNB = (n); \
- FILE *const fd__SPRNB = (fd); \
- char *const buf__SPRNB = (buf); \
- SPELL_READ_BYTES(buf__SPRNB, n__SPRNB, fd__SPRNB, exit_code); \
- if (memchr(buf__SPRNB, NUL, (size_t)n__SPRNB)) { \
- exit_code; \
- return SP_FORMERROR; \
- } \
- } while (0)
+ do { \
+ const size_t n__SPRNB = (n); \
+ FILE *const fd__SPRNB = (fd); \
+ char *const buf__SPRNB = (buf); \
+ SPELL_READ_BYTES(buf__SPRNB, n__SPRNB, fd__SPRNB, exit_code); \
+ if (memchr(buf__SPRNB, NUL, (size_t)n__SPRNB)) { \
+ exit_code; \
+ return SP_FORMERROR; \
+ } \
+ } while (0)
/// Check that spell file starts with a magic string
///
@@ -556,40 +556,36 @@ static inline int spell_check_magic_string(FILE *const fd)
return 0;
}
-// Load one spell file and store the info into a slang_T.
-//
-// This is invoked in three ways:
-// - From spell_load_cb() to load a spell file for the first time. "lang" is
-// the language name, "old_lp" is NULL. Will allocate an slang_T.
-// - To reload a spell file that was changed. "lang" is NULL and "old_lp"
-// points to the existing slang_T.
-// - Just after writing a .spl file; it's read back to produce the .sug file.
-// "old_lp" is NULL and "lang" is NULL. Will allocate an slang_T.
-//
-// Returns the slang_T the spell file was loaded into. NULL for error.
-slang_T *
-spell_load_file (
- char_u *fname,
- char_u *lang,
- slang_T *old_lp,
- bool silent // no error if file doesn't exist
-)
+/// Load one spell file and store the info into a slang_T.
+///
+/// This is invoked in three ways:
+/// - From spell_load_cb() to load a spell file for the first time. "lang" is
+/// the language name, "old_lp" is NULL. Will allocate an slang_T.
+/// - To reload a spell file that was changed. "lang" is NULL and "old_lp"
+/// points to the existing slang_T.
+/// - Just after writing a .spl file; it's read back to produce the .sug file.
+/// "old_lp" is NULL and "lang" is NULL. Will allocate an slang_T.
+///
+/// @param silent no error if file doesn't exist
+///
+/// @return the slang_T the spell file was loaded into. NULL for error.
+slang_T *spell_load_file(char_u *fname, char_u *lang, slang_T *old_lp, bool silent)
{
- FILE *fd;
- char_u *p;
+ FILE *fd;
+ char_u *p;
int n;
int len;
- char_u *save_sourcing_name = sourcing_name;
+ char_u *save_sourcing_name = sourcing_name;
linenr_T save_sourcing_lnum = sourcing_lnum;
- slang_T *lp = NULL;
+ slang_T *lp = NULL;
int c = 0;
int res;
fd = os_fopen((char *)fname, "r");
if (fd == NULL) {
- if (!silent)
+ if (!silent) {
EMSG2(_(e_notopen), fname);
- else if (p_verbose > 2) {
+ } else if (p_verbose > 2) {
verbose_enter();
smsg((char *)e_notopen, fname);
verbose_leave();
@@ -610,8 +606,9 @@ spell_load_file (
// Check for .add.spl.
lp->sl_add = strstr((char *)path_tail(fname), SPL_FNAME_ADD) != NULL;
- } else
+ } else {
lp = old_lp;
+ }
// Set sourcing_name, so that error messages mention the file name.
sourcing_name = fname;
@@ -620,19 +617,16 @@ spell_load_file (
// <HEADER>: <fileID>
const int scms_ret = spell_check_magic_string(fd);
switch (scms_ret) {
- case SP_FORMERROR:
- case SP_TRUNCERROR: {
- emsgf("%s", _("E757: This does not look like a spell file"));
- goto endFAIL;
- }
- case SP_OTHERERROR: {
- emsgf(_("E5042: Failed to read spell file %s: %s"),
- fname, strerror(ferror(fd)));
- goto endFAIL;
- }
- case 0: {
- break;
- }
+ case SP_FORMERROR:
+ case SP_TRUNCERROR:
+ emsgf("%s", _("E757: This does not look like a spell file"));
+ goto endFAIL;
+ case SP_OTHERERROR:
+ emsgf(_("E5042: Failed to read spell file %s: %s"),
+ fname, strerror(ferror(fd)));
+ goto endFAIL;
+ case 0:
+ break;
}
c = getc(fd); // <versionnr>
if (c < VIMSPELLVERSION) {
@@ -648,19 +642,22 @@ spell_load_file (
// <section>: <sectionID> <sectionflags> <sectionlen> (section contents)
for (;; ) {
n = getc(fd); // <sectionID> or <sectionend>
- if (n == SN_END)
+ if (n == SN_END) {
break;
+ }
c = getc(fd); // <sectionflags>
len = get4c(fd); // <sectionlen>
- if (len < 0)
+ if (len < 0) {
goto truncerr;
+ }
res = 0;
switch (n) {
case SN_INFO:
lp->sl_info = READ_STRING(fd, len); // <infotext>
- if (lp->sl_info == NULL)
+ if (lp->sl_info == NULL) {
goto endFAIL;
+ }
break;
case SN_REGION:
@@ -673,8 +670,9 @@ spell_load_file (
case SN_MIDWORD:
lp->sl_midword = READ_STRING(fd, len); // <midword>
- if (lp->sl_midword == NULL)
+ if (lp->sl_midword == NULL) {
goto endFAIL;
+ }
break;
case SN_PREFCOND:
@@ -699,8 +697,9 @@ spell_load_file (
case SN_MAP:
p = READ_STRING(fd, len); // <mapstr>
- if (p == NULL)
+ if (p == NULL) {
goto endFAIL;
+ }
set_map_str(lp, p);
xfree(p);
break;
@@ -731,10 +730,12 @@ spell_load_file (
case SN_SYLLABLE:
lp->sl_syllable = READ_STRING(fd, len); // <syllable>
- if (lp->sl_syllable == NULL)
+ if (lp->sl_syllable == NULL) {
goto endFAIL;
- if (init_syl_tab(lp) == FAIL)
+ }
+ if (init_syl_tab(lp) == FAIL) {
goto endFAIL;
+ }
break;
default:
@@ -744,9 +745,11 @@ spell_load_file (
EMSG(_("E770: Unsupported section in spell file"));
goto endFAIL;
}
- while (--len >= 0)
- if (getc(fd) < 0)
+ while (--len >= 0) {
+ if (getc(fd) < 0) {
goto truncerr;
+ }
+ }
break;
}
someerror:
@@ -759,8 +762,9 @@ truncerr:
EMSG(_(e_spell_trunc));
goto endFAIL;
}
- if (res == SP_OTHERERROR)
+ if (res == SP_OTHERERROR) {
goto endFAIL;
+ }
}
// <LWORDTREE>
@@ -792,16 +796,19 @@ truncerr:
goto endOK;
endFAIL:
- if (lang != NULL)
+ if (lang != NULL) {
// truncating the name signals the error to spell_load_lang()
*lang = NUL;
- if (lp != NULL && old_lp == NULL)
+ }
+ if (lp != NULL && old_lp == NULL) {
slang_free(lp);
+ }
lp = NULL;
endOK:
- if (fd != NULL)
+ if (fd != NULL) {
fclose(fd);
+ }
sourcing_name = save_sourcing_name;
sourcing_lnum = save_sourcing_lnum;
@@ -827,8 +834,9 @@ static void tree_count_words(char_u *byts, idx_T *idxs)
if (curi[depth] > byts[arridx[depth]]) {
// Done all bytes at this node, go up one level.
idxs[arridx[depth]] = wordcount[depth];
- if (depth > 0)
+ if (depth > 0) {
wordcount[depth - 1] += wordcount[depth];
+ }
--depth;
fast_breakcheck();
@@ -862,10 +870,10 @@ static void tree_count_words(char_u *byts, idx_T *idxs)
// Load the .sug files for languages that have one and weren't loaded yet.
void suggest_load_files(void)
{
- langp_T *lp;
- slang_T *slang;
- char_u *dotp;
- FILE *fd;
+ langp_T *lp;
+ slang_T *slang;
+ char_u *dotp;
+ FILE *fd;
char_u buf[MAXWLEN];
int i;
time_t timestamp;
@@ -895,21 +903,22 @@ void suggest_load_files(void)
}
// <SUGHEADER>: <fileID> <versionnr> <timestamp>
- for (i = 0; i < VIMSUGMAGICL; ++i)
+ for (i = 0; i < VIMSUGMAGICL; ++i) {
buf[i] = getc(fd); // <fileID>
+ }
if (STRNCMP(buf, VIMSUGMAGIC, VIMSUGMAGICL) != 0) {
EMSG2(_("E778: This does not look like a .sug file: %s"),
- slang->sl_fname);
+ slang->sl_fname);
goto nextone;
}
c = getc(fd); // <versionnr>
if (c < VIMSUGVERSION) {
EMSG2(_("E779: Old .sug file, needs to be updated: %s"),
- slang->sl_fname);
+ slang->sl_fname);
goto nextone;
- } else if (c > VIMSUGVERSION) {
+ } else if (c > VIMSUGVERSION) {
EMSG2(_("E780: .sug file is for newer version of Vim: %s"),
- slang->sl_fname);
+ slang->sl_fname);
goto nextone;
}
@@ -918,7 +927,7 @@ void suggest_load_files(void)
timestamp = get8ctime(fd); // <timestamp>
if (timestamp != slang->sl_sugtime) {
EMSG2(_("E781: .sug file doesn't match .spl file: %s"),
- slang->sl_fname);
+ slang->sl_fname);
goto nextone;
}
@@ -928,7 +937,7 @@ void suggest_load_files(void)
false, 0) != 0) {
someerror:
EMSG2(_("E782: error while reading .sug file: %s"),
- slang->sl_fname);
+ slang->sl_fname);
slang_clear_sug(slang);
goto nextone;
}
@@ -942,8 +951,9 @@ someerror:
// <sugwcount>
wcount = get4c(fd);
- if (wcount < 0)
+ if (wcount < 0) {
goto someerror;
+ }
// Read all the wordnr lists into the buffer, one NUL terminated
// list per line.
@@ -956,8 +966,9 @@ someerror:
goto someerror;
}
GA_APPEND(char_u, &ga, c);
- if (c == NUL)
+ if (c == NUL) {
break;
+ }
}
if (ml_append_buf(slang->sl_sugbuf, (linenr_T)wordnr,
ga.ga_data, ga.ga_len, true) == FAIL) {
@@ -972,8 +983,9 @@ someerror:
tree_count_words(slang->sl_sbyts, slang->sl_sidxs);
nextone:
- if (fd != NULL)
+ if (fd != NULL) {
fclose(fd);
+ }
STRCPY(dotp, ".spl");
}
}
@@ -988,7 +1000,7 @@ nextone:
static char_u *read_cnt_string(FILE *fd, int cnt_bytes, int *cntp)
{
int cnt = 0;
- char_u *str;
+ char_u *str;
// read the length bytes, MSB first
for (int i = 0; i < cnt_bytes; i++) {
@@ -1001,12 +1013,13 @@ static char_u *read_cnt_string(FILE *fd, int cnt_bytes, int *cntp)
cnt = (cnt << 8) + (unsigned)c;
}
*cntp = cnt;
- if (cnt == 0)
+ if (cnt == 0) {
return NULL; // nothing to read, return NULL
-
+ }
str = READ_STRING(fd, cnt);
- if (str == NULL)
+ if (str == NULL) {
*cntp = SP_OTHERERROR;
+ }
return str;
}
@@ -1027,14 +1040,15 @@ static int read_region_section(FILE *fd, slang_T *lp, int len)
// Return SP_*ERROR flags.
static int read_charflags_section(FILE *fd)
{
- char_u *flags;
- char_u *fol;
+ char_u *flags;
+ char_u *fol;
int flagslen, follen;
// <charflagslen> <charflags>
flags = read_cnt_string(fd, 1, &flagslen);
- if (flagslen < 0)
+ if (flagslen < 0) {
return flagslen;
+ }
// <folcharslen> <folchars>
fol = read_cnt_string(fd, 2, &follen);
@@ -1044,15 +1058,17 @@ static int read_charflags_section(FILE *fd)
}
// Set the word-char flags and fill SPELL_ISUPPER() table.
- if (flags != NULL && fol != NULL)
+ if (flags != NULL && fol != NULL) {
set_spell_charflags(flags, flagslen, fol);
+ }
xfree(flags);
xfree(fol);
// When <charflagslen> is zero then <fcharlen> must also be zero.
- if ((flags == NULL) != (fol == NULL))
+ if ((flags == NULL) != (fol == NULL)) {
return SP_FORMERROR;
+ }
return 0;
}
@@ -1094,11 +1110,12 @@ static int read_prefcond_section(FILE *fd, slang_T *lp)
static int read_rep_section(FILE *fd, garray_T *gap, int16_t *first)
{
int cnt;
- fromto_T *ftp;
+ fromto_T *ftp;
cnt = get2c(fd); // <repcount>
- if (cnt < 0)
+ if (cnt < 0) {
return SP_TRUNCERROR;
+ }
ga_grow(gap, cnt);
@@ -1107,15 +1124,18 @@ static int read_rep_section(FILE *fd, garray_T *gap, int16_t *first)
int c;
ftp = &((fromto_T *)gap->ga_data)[gap->ga_len];
ftp->ft_from = read_cnt_string(fd, 1, &c);
- if (c < 0)
+ if (c < 0) {
return c;
- if (c == 0)
+ }
+ if (c == 0) {
return SP_FORMERROR;
+ }
ftp->ft_to = read_cnt_string(fd, 1, &c);
if (c <= 0) {
xfree(ftp->ft_from);
- if (c < 0)
+ if (c < 0) {
return c;
+ }
return SP_FORMERROR;
}
}
@@ -1126,8 +1146,9 @@ static int read_rep_section(FILE *fd, garray_T *gap, int16_t *first)
}
for (int i = 0; i < gap->ga_len; ++i) {
ftp = &((fromto_T *)gap->ga_data)[i];
- if (first[*ftp->ft_from] == -1)
+ if (first[*ftp->ft_from] == -1) {
first[*ftp->ft_from] = i;
+ }
}
return 0;
}
@@ -1137,10 +1158,10 @@ static int read_rep_section(FILE *fd, garray_T *gap, int16_t *first)
static int read_sal_section(FILE *fd, slang_T *slang)
{
int cnt;
- garray_T *gap;
- salitem_T *smp;
+ garray_T *gap;
+ salitem_T *smp;
int ccnt;
- char_u *p;
+ char_u *p;
slang->sl_sofo = false;
@@ -1156,8 +1177,9 @@ static int read_sal_section(FILE *fd, slang_T *slang)
}
cnt = get2c(fd); // <salcount>
- if (cnt < 0)
+ if (cnt < 0) {
return SP_TRUNCERROR;
+ }
gap = &slang->sl_sal;
ga_init(gap, sizeof(salitem_T), 10);
@@ -1169,8 +1191,9 @@ static int read_sal_section(FILE *fd, slang_T *slang)
smp = &((salitem_T *)gap->ga_data)[gap->ga_len];
ccnt = getc(fd); // <salfromlen>
- if (ccnt < 0)
+ if (ccnt < 0) {
return SP_TRUNCERROR;
+ }
p = xmalloc(ccnt + 2);
smp->sm_lead = p;
@@ -1178,8 +1201,9 @@ static int read_sal_section(FILE *fd, slang_T *slang)
int i = 0;
for (; i < ccnt; ++i) {
c = getc(fd); // <salfrom>
- if (vim_strchr((char_u *)"0123456789(-<^$", c) != NULL)
+ if (vim_strchr((char_u *)"0123456789(-<^$", c) != NULL) {
break;
+ }
*p++ = c;
}
smp->sm_leadlen = (int)(p - smp->sm_lead);
@@ -1190,15 +1214,18 @@ static int read_sal_section(FILE *fd, slang_T *slang)
smp->sm_oneof = p;
for (++i; i < ccnt; ++i) {
c = getc(fd); // <salfrom>
- if (c == ')')
+ if (c == ')') {
break;
+ }
*p++ = c;
}
*p++ = NUL;
- if (++i < ccnt)
+ if (++i < ccnt) {
c = getc(fd);
- } else
+ }
+ } else {
smp->sm_oneof = NULL;
+ }
// Any following chars go in sm_rules.
smp->sm_rules = p;
@@ -1209,7 +1236,8 @@ static int read_sal_section(FILE *fd, slang_T *slang)
i++;
if (i < ccnt) {
SPELL_READ_NONNUL_BYTES( // <salfrom>
- (char *)p, (size_t)(ccnt - i), fd, xfree(smp->sm_lead));
+ (char *)p, (size_t)(ccnt - i), fd,
+ xfree(smp->sm_lead));
p += (ccnt - i);
}
*p++ = NUL;
@@ -1272,13 +1300,16 @@ static int read_words_section(FILE *fd, slang_T *lp, int len)
// Read one word at a time.
for (i = 0;; ++i) {
c = getc(fd);
- if (c == EOF)
+ if (c == EOF) {
return SP_TRUNCERROR;
+ }
word[i] = c;
- if (word[i] == NUL)
+ if (word[i] == NUL) {
break;
- if (i == MAXWLEN - 1)
+ }
+ if (i == MAXWLEN - 1) {
return SP_FORMERROR;
+ }
}
// Init the count to 10.
@@ -1293,15 +1324,16 @@ static int read_words_section(FILE *fd, slang_T *lp, int len)
static int read_sofo_section(FILE *fd, slang_T *slang)
{
int cnt;
- char_u *from, *to;
+ char_u *from, *to;
int res;
slang->sl_sofo = true;
// <sofofromlen> <sofofrom>
from = read_cnt_string(fd, 2, &cnt);
- if (cnt < 0)
+ if (cnt < 0) {
return cnt;
+ }
// <sofotolen> <sofoto>
to = read_cnt_string(fd, 2, &cnt);
@@ -1311,12 +1343,13 @@ static int read_sofo_section(FILE *fd, slang_T *slang)
}
// Store the info in slang->sl_sal and/or slang->sl_sal_first.
- if (from != NULL && to != NULL)
+ if (from != NULL && to != NULL) {
res = set_sofo(slang, from, to);
- else if (from != NULL || to != NULL)
+ } else if (from != NULL || to != NULL) {
res = SP_FORMERROR; // only one of two strings is an error
- else
+ } else {
res = 0;
+ }
xfree(from);
xfree(to);
@@ -1331,39 +1364,42 @@ static int read_compound(FILE *fd, slang_T *slang, int len)
int todo = len;
int c;
int atstart;
- char_u *pat;
- char_u *pp;
- char_u *cp;
- char_u *ap;
- char_u *crp;
+ char_u *pat;
+ char_u *pp;
+ char_u *cp;
+ char_u *ap;
+ char_u *crp;
int cnt;
- garray_T *gap;
+ garray_T *gap;
- if (todo < 2)
+ if (todo < 2) {
return SP_FORMERROR; // need at least two bytes
-
+ }
--todo;
c = getc(fd); // <compmax>
- if (c < 2)
+ if (c < 2) {
c = MAXWLEN;
+ }
slang->sl_compmax = c;
--todo;
c = getc(fd); // <compminlen>
- if (c < 1)
+ if (c < 1) {
c = 0;
+ }
slang->sl_compminlen = c;
--todo;
c = getc(fd); // <compsylmax>
- if (c < 1)
+ if (c < 1) {
c = MAXWLEN;
+ }
slang->sl_compsylmax = c;
c = getc(fd); // <compoptions>
- if (c != 0)
+ if (c != 0) {
ungetc(c, fd); // be backwards compatible with Vim 7.0b
- else {
+ } else {
--todo;
c = getc(fd); // only use the lower byte for now
--todo;
@@ -1371,6 +1407,9 @@ static int read_compound(FILE *fd, slang_T *slang, int len)
gap = &slang->sl_comppat;
c = get2c(fd); // <comppatcount>
+ if (c < 0) {
+ return SP_TRUNCERROR;
+ }
todo -= 2;
ga_init(gap, sizeof(char_u *), c);
ga_grow(gap, c);
@@ -1378,13 +1417,15 @@ static int read_compound(FILE *fd, slang_T *slang, int len)
((char_u **)(gap->ga_data))[gap->ga_len++] =
read_cnt_string(fd, 1, &cnt);
// <comppatlen> <comppattext>
- if (cnt < 0)
+ if (cnt < 0) {
return cnt;
+ }
todo -= cnt + 1;
}
}
- if (todo < 0)
+ if (todo < 0) {
return SP_FORMERROR;
+ }
// Turn the COMPOUNDRULE items into a regexp pattern:
// "a[bc]/a*b+" -> "^\(a[bc]\|a*b\+\)$".
@@ -1433,17 +1474,18 @@ static int read_compound(FILE *fd, slang_T *slang, int len)
if (atstart != 0) {
// At start of item: copy flags to "sl_compstartflags". For a
// [abc] item set "atstart" to 2 and copy up to the ']'.
- if (c == '[')
+ if (c == '[') {
atstart = 2;
- else if (c == ']')
+ } else if (c == ']') {
atstart = 0;
- else {
+ } else {
if (!byte_in_str(slang->sl_compstartflags, c)) {
*cp++ = c;
*cp = NUL;
}
- if (atstart == 1)
+ if (atstart == 1) {
atstart = 0;
+ }
}
}
@@ -1452,8 +1494,9 @@ static int read_compound(FILE *fd, slang_T *slang, int len)
if (c == '?' || c == '+' || c == '*') {
XFREE_CLEAR(slang->sl_comprules);
crp = NULL;
- } else
+ } else {
*crp++ = c;
+ }
}
if (c == '/') { // slash separates two items
@@ -1473,13 +1516,15 @@ static int read_compound(FILE *fd, slang_T *slang, int len)
*pp++ = '$';
*pp = NUL;
- if (crp != NULL)
+ if (crp != NULL) {
*crp = NUL;
+ }
slang->sl_compprog = vim_regcomp(pat, RE_MAGIC + RE_STRING + RE_STRICT);
xfree(pat);
- if (slang->sl_compprog == NULL)
+ if (slang->sl_compprog == NULL) {
return SP_FORMERROR;
+ }
return 0;
}
@@ -1488,8 +1533,8 @@ static int read_compound(FILE *fd, slang_T *slang, int len)
// Returns SP_*ERROR flags when there is something wrong.
static int set_sofo(slang_T *lp, char_u *from, char_u *to)
{
- char_u *s;
- char_u *p;
+ char_u *s;
+ char_u *p;
// Use "sl_sal" as an array with 256 pointers to a list of wide
// characters. The index is the low byte of the character.
@@ -1551,10 +1596,10 @@ static int set_sofo(slang_T *lp, char_u *from, char_u *to)
// Fill the first-index table for "lp".
static void set_sal_first(slang_T *lp)
{
- salfirst_T *sfirst;
- salitem_T *smp;
+ salfirst_T *sfirst;
+ salitem_T *smp;
int c;
- garray_T *gap = &lp->sl_sal;
+ garray_T *gap = &lp->sl_sal;
sfirst = lp->sl_sal_first;
for (int i = 0; i < 256; ++i) {
@@ -1610,24 +1655,21 @@ static int *mb_str2wide(char_u *s)
return res;
}
-// Reads a tree from the .spl or .sug file.
-// Allocates the memory and stores pointers in "bytsp" and "idxsp".
-// This is skipped when the tree has zero length.
-// Returns zero when OK, SP_ value for an error.
-static int
-spell_read_tree (
- FILE *fd,
- char_u **bytsp,
- long *bytsp_len,
- idx_T **idxsp,
- bool prefixtree, // true for the prefix tree
- int prefixcnt // when "prefixtree" is true: prefix count
-)
+/// Reads a tree from the .spl or .sug file.
+/// Allocates the memory and stores pointers in "bytsp" and "idxsp".
+/// This is skipped when the tree has zero length.
+///
+/// @param prefixtree true for the prefix tree
+/// @param prefixcnt when "prefixtree" is true: prefix count
+///
+/// @return zero when OK, SP_ value for an error.
+static int spell_read_tree(FILE *fd, char_u **bytsp, long *bytsp_len, idx_T **idxsp,
+ bool prefixtree, int prefixcnt)
FUNC_ATTR_NONNULL_ARG(1, 2, 4)
{
int idx;
- char_u *bp;
- idx_T *ip;
+ char_u *bp;
+ idx_T *ip;
// The tree size was computed when writing the file, so that we can
// allocate it as one long block. <nodecount>
@@ -1653,30 +1695,28 @@ spell_read_tree (
// Recursively read the tree and store it in the array.
idx = read_tree_node(fd, bp, ip, len, 0, prefixtree, prefixcnt);
- if (idx < 0)
+ if (idx < 0) {
return idx;
+ }
}
return 0;
}
-// Read one row of siblings from the spell file and store it in the byte array
-// "byts" and index array "idxs". Recursively read the children.
-//
-// NOTE: The code here must match put_node()!
-//
-// Returns the index (>= 0) following the siblings.
-// Returns SP_TRUNCERROR if the file is shorter than expected.
-// Returns SP_FORMERROR if there is a format error.
-static idx_T
-read_tree_node (
- FILE *fd,
- char_u *byts,
- idx_T *idxs,
- int maxidx, // size of arrays
- idx_T startidx, // current index in "byts" and "idxs"
- bool prefixtree, // true for reading PREFIXTREE
- int maxprefcondnr // maximum for <prefcondnr>
-)
+/// Read one row of siblings from the spell file and store it in the byte array
+/// "byts" and index array "idxs". Recursively read the children.
+///
+/// NOTE: The code here must match put_node()!
+///
+/// Returns the index (>= 0) following the siblings.
+/// Returns SP_TRUNCERROR if the file is shorter than expected.
+/// Returns SP_FORMERROR if there is a format error.
+///
+/// @param maxidx size of arrays
+/// @param startidx current index in "byts" and "idxs"
+/// @param prefixtree true for reading PREFIXTREE
+/// @param maxprefcondnr maximum for <prefcondnr>
+static idx_T read_tree_node(FILE *fd, char_u *byts, idx_T *idxs, int maxidx, idx_T startidx,
+ bool prefixtree, int maxprefcondnr)
{
int len;
int i;
@@ -1687,18 +1727,21 @@ read_tree_node (
#define SHARED_MASK 0x8000000
len = getc(fd); // <siblingcount>
- if (len <= 0)
+ if (len <= 0) {
return SP_TRUNCERROR;
+ }
- if (startidx + len >= maxidx)
+ if (startidx + len >= maxidx) {
return SP_FORMERROR;
+ }
byts[idx++] = len;
// Read the byte values, flag/region bytes and shared indexes.
for (i = 1; i <= len; ++i) {
c = getc(fd); // <byte>
- if (c < 0)
+ if (c < 0) {
return SP_TRUNCERROR;
+ }
if (c <= BY_SPECIAL) {
if (c == BY_NOFLAGS && !prefixtree) {
// No flags, all regions.
@@ -1709,16 +1752,18 @@ read_tree_node (
// condition nr. In idxs[] store the prefix ID in the low
// byte, the condition index shifted up 8 bits, the flags
// shifted up 24 bits.
- if (c == BY_FLAGS)
+ if (c == BY_FLAGS) {
c = getc(fd) << 24; // <pflags>
- else
+ } else {
c = 0;
+ }
c |= getc(fd); // <affixID>
n = get2c(fd); // <prefcondnr>
- if (n >= maxprefcondnr)
+ if (n >= maxprefcondnr) {
return SP_FORMERROR;
+ }
c |= (n << 8);
} else { // c must be BY_FLAGS or BY_FLAGS2
// Read flags and optional region and prefix ID. In
@@ -1726,21 +1771,25 @@ read_tree_node (
// that and prefix ID above the region.
c2 = c;
c = getc(fd); // <flags>
- if (c2 == BY_FLAGS2)
+ if (c2 == BY_FLAGS2) {
c = (getc(fd) << 8) + c; // <flags2>
- if (c & WF_REGION)
+ }
+ if (c & WF_REGION) {
c = (getc(fd) << 16) + c; // <region>
- if (c & WF_AFX)
+ }
+ if (c & WF_AFX) {
c = (getc(fd) << 24) + c; // <affixID>
+ }
}
idxs[idx] = c;
c = 0;
- } else { // c == BY_INDEX
+ } else { // c == BY_INDEX
// <nodeidx>
n = get3c(fd);
- if (n < 0 || n >= maxidx)
+ if (n < 0 || n >= maxidx) {
return SP_FORMERROR;
+ }
idxs[idx] = n + SHARED_MASK;
c = getc(fd); // <xbyte>
}
@@ -1751,38 +1800,39 @@ read_tree_node (
// Recursively read the children for non-shared siblings.
// Skip the end-of-word ones (zero byte value) and the shared ones (and
// remove SHARED_MASK)
- for (i = 1; i <= len; ++i)
+ for (i = 1; i <= len; ++i) {
if (byts[startidx + i] != 0) {
- if (idxs[startidx + i] & SHARED_MASK)
+ if (idxs[startidx + i] & SHARED_MASK) {
idxs[startidx + i] &= ~SHARED_MASK;
- else {
+ } else {
idxs[startidx + i] = idx;
idx = read_tree_node(fd, byts, idxs, maxidx, idx,
- prefixtree, maxprefcondnr);
- if (idx < 0)
+ prefixtree, maxprefcondnr);
+ if (idx < 0) {
break;
+ }
}
}
+ }
return idx;
}
-// Reload the spell file "fname" if it's loaded.
-static void
-spell_reload_one (
- char_u *fname,
- bool added_word // invoked through "zg"
-)
+/// Reload the spell file "fname" if it's loaded.
+///
+/// @param added_word invoked through "zg"
+static void spell_reload_one(char_u *fname, bool added_word)
{
- slang_T *slang;
+ slang_T *slang;
bool didit = false;
for (slang = first_lang; slang != NULL; slang = slang->sl_next) {
if (path_full_compare(fname, slang->sl_fname, false, true) == kEqualFiles) {
slang_clear(slang);
- if (spell_load_file(fname, NULL, slang, false) == NULL)
+ if (spell_load_file(fname, NULL, slang, false) == NULL) {
// reloading failed, clear the language
slang_clear(slang);
+ }
redraw_all_later(SOME_VALID);
didit = true;
}
@@ -1790,8 +1840,9 @@ spell_reload_one (
// When "zg" was used and the file wasn't loaded yet, should redo
// 'spelllang' to load it now.
- if (added_word && !didit)
+ if (added_word && !didit) {
did_set_spelllang(curwin);
+ }
}
// Functions for ":mkspell".
@@ -1817,13 +1868,14 @@ static long compress_added = 500000; // word count
// Sets "sps_flags".
int spell_check_msm(void)
{
- char_u *p = p_msm;
+ char_u *p = p_msm;
long start = 0;
long incr = 0;
long added = 0;
- if (!ascii_isdigit(*p))
+ if (!ascii_isdigit(*p)) {
return FAIL;
+ }
// block count = (value * 1024) / SBLOCKSIZE (but avoid overflow)
start = (getdigits_long(&p, true, 0) * 10) / (SBLOCKSIZE / 102);
if (*p != ',') {
@@ -1861,11 +1913,12 @@ int spell_check_msm(void)
// readable format, so that we can see what happens when adding a word and/or
// compressing the tree.
// Based on code from Olaf Seibert.
-#define PRINTLINESIZE 1000
-#define PRINTWIDTH 6
+# define PRINTLINESIZE 1000
+# define PRINTWIDTH 6
-#define PRINTSOME(l, depth, fmt, a1, a2) vim_snprintf(l + depth * PRINTWIDTH, \
- PRINTLINESIZE - PRINTWIDTH * depth, fmt, a1, a2)
+# define PRINTSOME(l, depth, fmt, a1, a2) vim_snprintf(l + depth * PRINTWIDTH, \
+ PRINTLINESIZE - PRINTWIDTH * depth, fmt, a1, \
+ a2)
static char line1[PRINTLINESIZE];
static char line2[PRINTLINESIZE];
@@ -1873,7 +1926,7 @@ static char line3[PRINTLINESIZE];
static void spell_clear_flags(wordnode_T *node)
{
- wordnode_T *np;
+ wordnode_T *np;
for (np = node; np != NULL; np = np->wn_sibling) {
np->wn_u1.index = FALSE;
@@ -1895,20 +1948,23 @@ static void spell_print_node(wordnode_T *node, int depth)
node->wn_u1.index = TRUE;
if (node->wn_byte != NUL) {
- if (node->wn_child != NULL)
+ if (node->wn_child != NULL) {
PRINTSOME(line1, depth, " %c -> ", node->wn_byte, 0);
- else
+ } else {
// Cannot happen?
PRINTSOME(line1, depth, " %c ???", node->wn_byte, 0);
- } else
+ }
+ } else {
PRINTSOME(line1, depth, " $ ", 0, 0);
+ }
PRINTSOME(line2, depth, "%d/%d ", node->wn_nr, node->wn_refs);
- if (node->wn_sibling != NULL)
+ if (node->wn_sibling != NULL) {
PRINTSOME(line3, depth, " | ", 0, 0);
- else
+ } else {
PRINTSOME(line3, depth, " ", 0, 0);
+ }
if (node->wn_byte == NUL) {
msg((char_u *)line1);
@@ -1917,8 +1973,9 @@ static void spell_print_node(wordnode_T *node, int depth)
}
// do the children
- if (node->wn_byte != NUL && node->wn_child != NULL)
+ if (node->wn_byte != NUL && node->wn_child != NULL) {
spell_print_node(node->wn_child, depth + 1);
+ }
// do the siblings
if (node->wn_sibling != NULL) {
@@ -1948,39 +2005,39 @@ static void spell_print_tree(wordnode_T *root)
// Returns an afffile_T, NULL for complete failure.
static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
{
- FILE *fd;
+ FILE *fd;
char_u rline[MAXLINELEN];
- char_u *line;
- char_u *pc = NULL;
+ char_u *line;
+ char_u *pc = NULL;
#define MAXITEMCNT 30
- char_u *(items[MAXITEMCNT]);
+ char_u *(items[MAXITEMCNT]);
int itemcnt;
- char_u *p;
+ char_u *p;
int lnum = 0;
affheader_T *cur_aff = NULL;
bool did_postpone_prefix = false;
int aff_todo = 0;
- hashtab_T *tp;
- char_u *low = NULL;
- char_u *fol = NULL;
- char_u *upp = NULL;
+ hashtab_T *tp;
+ char_u *low = NULL;
+ char_u *fol = NULL;
+ char_u *upp = NULL;
int do_rep;
int do_repsal;
int do_sal;
int do_mapline;
bool found_map = false;
- hashitem_T *hi;
+ hashitem_T *hi;
int l;
int compminlen = 0; // COMPOUNDMIN value
int compsylmax = 0; // COMPOUNDSYLMAX value
int compoptions = 0; // COMP_ flags
int compmax = 0; // COMPOUNDWORDMAX value
- char_u *compflags = NULL; // COMPOUNDFLAG and COMPOUNDRULE
- // concatenated
- char_u *midword = NULL; // MIDWORD value
- char_u *syllable = NULL; // SYLLABLE value
- char_u *sofofrom = NULL; // SOFOFROM value
- char_u *sofoto = NULL; // SOFOTO value
+ char_u *compflags = NULL; // COMPOUNDFLAG and COMPOUNDRULE
+ // concatenated
+ char_u *midword = NULL; // MIDWORD value
+ char_u *syllable = NULL; // SYLLABLE value
+ char_u *sofofrom = NULL; // SOFOFROM value
+ char_u *sofoto = NULL; // SOFOTO value
// Open the file.
fd = os_fopen((char *)fname, "r");
@@ -2016,8 +2073,9 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
++lnum;
// Skip comment lines.
- if (*rline == '#')
+ if (*rline == '#') {
continue;
+ }
// Convert from "SET" to 'encoding' when needed.
xfree(pc);
@@ -2038,22 +2096,29 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
// item.
itemcnt = 0;
for (p = line;; ) {
- while (*p != NUL && *p <= ' ') // skip white space and CR/NL
+ while (*p != NUL && *p <= ' ') { // skip white space and CR/NL
++p;
- if (*p == NUL)
+ }
+ if (*p == NUL) {
break;
- if (itemcnt == MAXITEMCNT) // too many items
+ }
+ if (itemcnt == MAXITEMCNT) { // too many items
break;
+ }
items[itemcnt++] = p;
// A few items have arbitrary text argument, don't split them.
- if (itemcnt == 2 && spell_info_item(items[0]))
- while (*p >= ' ' || *p == TAB) // skip until CR/NL
+ if (itemcnt == 2 && spell_info_item(items[0])) {
+ while (*p >= ' ' || *p == TAB) { // skip until CR/NL
++p;
- else
- while (*p > ' ') // skip until white space or CR/NL
+ }
+ } else {
+ while (*p > ' ') { // skip until white space or CR/NL
++p;
- if (*p == NUL)
+ }
+ }
+ if (*p == NUL) {
break;
+ }
*p++ = NUL;
}
@@ -2064,21 +2129,23 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
aff->af_enc = enc_canonize(items[1]);
if (!spin->si_ascii
&& convert_setup(&spin->si_conv, aff->af_enc,
- p_enc) == FAIL)
+ p_enc) == FAIL) {
smsg(_("Conversion in %s not supported: from %s to %s"),
fname, aff->af_enc, p_enc);
+ }
spin->si_conv.vc_fail = true;
} else if (is_aff_rule(items, itemcnt, "FLAG", 2)
&& aff->af_flagtype == AFT_CHAR) {
- if (STRCMP(items[1], "long") == 0)
+ if (STRCMP(items[1], "long") == 0) {
aff->af_flagtype = AFT_LONG;
- else if (STRCMP(items[1], "num") == 0)
+ } else if (STRCMP(items[1], "num") == 0) {
aff->af_flagtype = AFT_NUM;
- else if (STRCMP(items[1], "caplong") == 0)
+ } else if (STRCMP(items[1], "caplong") == 0) {
aff->af_flagtype = AFT_CAPLONG;
- else
+ } else {
smsg(_("Invalid value for FLAG in %s line %d: %s"),
fname, lnum, items[1]);
+ }
if (aff->af_rare != 0
|| aff->af_keepcase != 0
|| aff->af_bad != 0
@@ -2089,10 +2156,11 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
|| aff->af_nosuggest != 0
|| compflags != NULL
|| aff->af_suff.ht_used > 0
- || aff->af_pref.ht_used > 0)
+ || aff->af_pref.ht_used > 0) {
smsg(_("FLAG after using flags in %s line %d: %s"),
fname, lnum, items[1]);
- } else if (spell_info_item(items[0]) && itemcnt > 1) {
+ }
+ } else if (spell_info_item(items[0]) && itemcnt > 1) {
p = getroom(spin,
(spin->si_info == NULL ? 0 : STRLEN(spin->si_info))
+ STRLEN(items[0])
@@ -2108,7 +2176,7 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
} else if (is_aff_rule(items, itemcnt, "MIDWORD", 2)
&& midword == NULL) {
midword = getroom_save(spin, items[1]);
- } else if (is_aff_rule(items, itemcnt, "TRY", 2)) {
+ } else if (is_aff_rule(items, itemcnt, "TRY", 2)) {
// ignored, we look in the tree for what chars may appear
}
// TODO: remove "RAR" later
@@ -2116,54 +2184,56 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
|| is_aff_rule(items, itemcnt, "RARE", 2))
&& aff->af_rare == 0) {
aff->af_rare = affitem2flag(aff->af_flagtype, items[1],
- fname, lnum);
+ fname, lnum);
}
// TODO: remove "KEP" later
else if ((is_aff_rule(items, itemcnt, "KEP", 2)
|| is_aff_rule(items, itemcnt, "KEEPCASE", 2))
&& aff->af_keepcase == 0) {
aff->af_keepcase = affitem2flag(aff->af_flagtype, items[1],
- fname, lnum);
+ fname, lnum);
} else if ((is_aff_rule(items, itemcnt, "BAD", 2)
|| is_aff_rule(items, itemcnt, "FORBIDDENWORD", 2))
&& aff->af_bad == 0) {
aff->af_bad = affitem2flag(aff->af_flagtype, items[1],
- fname, lnum);
+ fname, lnum);
} else if (is_aff_rule(items, itemcnt, "NEEDAFFIX", 2)
&& aff->af_needaffix == 0) {
aff->af_needaffix = affitem2flag(aff->af_flagtype, items[1],
- fname, lnum);
+ fname, lnum);
} else if (is_aff_rule(items, itemcnt, "CIRCUMFIX", 2)
&& aff->af_circumfix == 0) {
aff->af_circumfix = affitem2flag(aff->af_flagtype, items[1],
- fname, lnum);
+ fname, lnum);
} else if (is_aff_rule(items, itemcnt, "NOSUGGEST", 2)
&& aff->af_nosuggest == 0) {
aff->af_nosuggest = affitem2flag(aff->af_flagtype, items[1],
- fname, lnum);
+ fname, lnum);
} else if ((is_aff_rule(items, itemcnt, "NEEDCOMPOUND", 2)
|| is_aff_rule(items, itemcnt, "ONLYINCOMPOUND", 2))
&& aff->af_needcomp == 0) {
aff->af_needcomp = affitem2flag(aff->af_flagtype, items[1],
- fname, lnum);
+ fname, lnum);
} else if (is_aff_rule(items, itemcnt, "COMPOUNDROOT", 2)
&& aff->af_comproot == 0) {
aff->af_comproot = affitem2flag(aff->af_flagtype, items[1],
- fname, lnum);
+ fname, lnum);
} else if (is_aff_rule(items, itemcnt, "COMPOUNDFORBIDFLAG", 2)
&& aff->af_compforbid == 0) {
aff->af_compforbid = affitem2flag(aff->af_flagtype, items[1],
- fname, lnum);
- if (aff->af_pref.ht_used > 0)
+ fname, lnum);
+ if (aff->af_pref.ht_used > 0) {
smsg(_("Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line %d"),
fname, lnum);
+ }
} else if (is_aff_rule(items, itemcnt, "COMPOUNDPERMITFLAG", 2)
&& aff->af_comppermit == 0) {
aff->af_comppermit = affitem2flag(aff->af_flagtype, items[1],
- fname, lnum);
- if (aff->af_pref.ht_used > 0)
+ fname, lnum);
+ if (aff->af_pref.ht_used > 0) {
smsg(_("Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line %d"),
fname, lnum);
+ }
} else if (is_aff_rule(items, itemcnt, "COMPOUNDFLAG", 2)
&& compflags == NULL) {
// Turn flag "c" into COMPOUNDRULE compatible string "c+",
@@ -2172,20 +2242,22 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
STRCPY(p, items[1]);
STRCAT(p, "+");
compflags = p;
- } else if (is_aff_rule(items, itemcnt, "COMPOUNDRULES", 2)) {
+ } else if (is_aff_rule(items, itemcnt, "COMPOUNDRULES", 2)) {
// We don't use the count, but do check that it's a number and
// not COMPOUNDRULE mistyped.
- if (atoi((char *)items[1]) == 0)
+ if (atoi((char *)items[1]) == 0) {
smsg(_("Wrong COMPOUNDRULES value in %s line %d: %s"),
fname, lnum, items[1]);
- } else if (is_aff_rule(items, itemcnt, "COMPOUNDRULE", 2)) {
+ }
+ } else if (is_aff_rule(items, itemcnt, "COMPOUNDRULE", 2)) {
// Don't use the first rule if it is a number.
if (compflags != NULL || *skipdigits(items[1]) != NUL) {
// Concatenate this string to previously defined ones,
// using a slash to separate them.
l = (int)STRLEN(items[1]) + 1;
- if (compflags != NULL)
+ if (compflags != NULL) {
l += (int)STRLEN(compflags) + 1;
+ }
p = getroom(spin, l, false);
if (compflags != NULL) {
STRCPY(p, compflags);
@@ -2197,43 +2269,49 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
} else if (is_aff_rule(items, itemcnt, "COMPOUNDWORDMAX", 2)
&& compmax == 0) {
compmax = atoi((char *)items[1]);
- if (compmax == 0)
+ if (compmax == 0) {
smsg(_("Wrong COMPOUNDWORDMAX value in %s line %d: %s"),
fname, lnum, items[1]);
+ }
} else if (is_aff_rule(items, itemcnt, "COMPOUNDMIN", 2)
&& compminlen == 0) {
compminlen = atoi((char *)items[1]);
- if (compminlen == 0)
+ if (compminlen == 0) {
smsg(_("Wrong COMPOUNDMIN value in %s line %d: %s"),
fname, lnum, items[1]);
+ }
} else if (is_aff_rule(items, itemcnt, "COMPOUNDSYLMAX", 2)
&& compsylmax == 0) {
compsylmax = atoi((char *)items[1]);
- if (compsylmax == 0)
+ if (compsylmax == 0) {
smsg(_("Wrong COMPOUNDSYLMAX value in %s line %d: %s"),
fname, lnum, items[1]);
- } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDDUP", 1)) {
+ }
+ } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDDUP", 1)) {
compoptions |= COMP_CHECKDUP;
- } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDREP", 1)) {
+ } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDREP", 1)) {
compoptions |= COMP_CHECKREP;
- } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDCASE", 1)) {
+ } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDCASE", 1)) {
compoptions |= COMP_CHECKCASE;
- } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDTRIPLE", 1)) {
+ } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDTRIPLE", 1)) {
compoptions |= COMP_CHECKTRIPLE;
- } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDPATTERN", 2)) {
- if (atoi((char *)items[1]) == 0)
+ } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDPATTERN", 2)) {
+ if (atoi((char *)items[1]) == 0) {
smsg(_("Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"),
fname, lnum, items[1]);
- } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDPATTERN", 3)) {
- garray_T *gap = &spin->si_comppat;
+ }
+ } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDPATTERN", 3)) {
+ garray_T *gap = &spin->si_comppat;
int i;
// Only add the couple if it isn't already there.
- for (i = 0; i < gap->ga_len - 1; i += 2)
+ for (i = 0; i < gap->ga_len - 1; i += 2) {
if (STRCMP(((char_u **)(gap->ga_data))[i], items[1]) == 0
&& STRCMP(((char_u **)(gap->ga_data))[i + 1],
- items[2]) == 0)
+ items[2]) == 0) {
break;
+ }
+ }
if (i >= gap->ga_len) {
ga_grow(gap, 2);
((char_u **)(gap->ga_data))[gap->ga_len++]
@@ -2244,15 +2322,15 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
} else if (is_aff_rule(items, itemcnt, "SYLLABLE", 2)
&& syllable == NULL) {
syllable = getroom_save(spin, items[1]);
- } else if (is_aff_rule(items, itemcnt, "NOBREAK", 1)) {
+ } else if (is_aff_rule(items, itemcnt, "NOBREAK", 1)) {
spin->si_nobreak = true;
- } else if (is_aff_rule(items, itemcnt, "NOSPLITSUGS", 1)) {
+ } else if (is_aff_rule(items, itemcnt, "NOSPLITSUGS", 1)) {
spin->si_nosplitsugs = true;
} else if (is_aff_rule(items, itemcnt, "NOCOMPOUNDSUGS", 1)) {
spin->si_nocompoundsugs = true;
- } else if (is_aff_rule(items, itemcnt, "NOSUGFILE", 1)) {
+ } else if (is_aff_rule(items, itemcnt, "NOSUGFILE", 1)) {
spin->si_nosugfile = true;
- } else if (is_aff_rule(items, itemcnt, "PFXPOSTPONE", 1)) {
+ } else if (is_aff_rule(items, itemcnt, "PFXPOSTPONE", 1)) {
aff->af_pfxpostpone = true;
} else if (is_aff_rule(items, itemcnt, "IGNOREEXTRA", 1)) {
aff->af_ignoreextra = true;
@@ -2263,10 +2341,11 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
int lasti = 4;
char_u key[AH_KEY_LEN];
- if (*items[0] == 'P')
+ if (*items[0] == 'P') {
tp = &aff->af_pref;
- else
+ } else {
tp = &aff->af_suff;
+ }
// Myspell allows the same affix name to be used multiple
// times. The affix files that do this have an undocumented
@@ -2276,12 +2355,14 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
hi = hash_find(tp, key);
if (!HASHITEM_EMPTY(hi)) {
cur_aff = HI2AH(hi);
- if (cur_aff->ah_combine != (*items[2] == 'Y'))
+ if (cur_aff->ah_combine != (*items[2] == 'Y')) {
smsg(_("Different combining flag in continued affix block in %s line %d: %s"),
fname, lnum, items[1]);
- if (!cur_aff->ah_follows)
+ }
+ if (!cur_aff->ah_follows) {
smsg(_("Duplicate affix in %s line %d: %s"),
fname, lnum, items[1]);
+ }
} else {
// New affix letter.
cur_aff = getroom(spin, sizeof(*cur_aff), true);
@@ -2314,20 +2395,23 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
if (itemcnt > lasti && STRCMP(items[lasti], "S") == 0) {
++lasti;
cur_aff->ah_follows = true;
- } else
+ } else {
cur_aff->ah_follows = false;
+ }
// Myspell allows extra text after the item, but that might
// mean mistakes go unnoticed. Require a comment-starter,
// unless IGNOREEXTRA is used. Hunspell uses a "-" item.
if (itemcnt > lasti
&& !aff->af_ignoreextra
- && *items[lasti] != '#')
+ && *items[lasti] != '#') {
smsg(_(e_afftrailing), fname, lnum, items[lasti]);
+ }
- if (STRCMP(items[2], "Y") != 0 && STRCMP(items[2], "N") != 0)
+ if (STRCMP(items[2], "Y") != 0 && STRCMP(items[2], "N") != 0) {
smsg(_("Expected Y or N in %s line %d: %s"),
- fname, lnum, items[2]);
+ fname, lnum, items[2]);
+ }
if (*items[0] == 'P' && aff->af_pfxpostpone) {
if (cur_aff->ah_newID == 0) {
@@ -2340,9 +2424,10 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
// postponed. We know that only after handling all
// the items.
did_postpone_prefix = false;
- } else
+ } else {
// Did use the ID in a previous block.
did_postpone_prefix = true;
+ }
}
aff_todo = atoi((char *)items[3]);
@@ -2351,7 +2436,7 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
&& aff_todo > 0
&& STRCMP(cur_aff->ah_key, items[1]) == 0
&& itemcnt >= 5) {
- affentry_T *aff_entry;
+ affentry_T *aff_entry;
bool upper = false;
int lasti = 5;
@@ -2360,15 +2445,17 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
// Hunspell uses a "-" item.
if (itemcnt > lasti && *items[lasti] != '#'
&& (STRCMP(items[lasti], "-") != 0
- || itemcnt != lasti + 1))
+ || itemcnt != lasti + 1)) {
smsg(_(e_afftrailing), fname, lnum, items[lasti]);
+ }
// New item for an affix letter.
aff_todo--;
aff_entry = getroom(spin, sizeof(*aff_entry), true);
- if (STRCMP(items[2], "0") != 0)
+ if (STRCMP(items[2], "0") != 0) {
aff_entry->ae_chop = getroom_save(spin, items[2]);
+ }
if (STRCMP(items[3], "0") != 0) {
aff_entry->ae_add = getroom_save(spin, items[3]);
@@ -2391,15 +2478,17 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
char_u buf[MAXLINELEN];
aff_entry->ae_cond = getroom_save(spin, items[4]);
- if (*items[0] == 'P')
+ if (*items[0] == 'P') {
sprintf((char *)buf, "^%s", items[4]);
- else
+ } else {
sprintf((char *)buf, "%s$", items[4]);
+ }
aff_entry->ae_prog = vim_regcomp(buf,
- RE_MAGIC + RE_STRING + RE_STRICT);
- if (aff_entry->ae_prog == NULL)
+ RE_MAGIC + RE_STRING + RE_STRICT);
+ if (aff_entry->ae_prog == NULL) {
smsg(_("Broken condition in %s line %d: %s"),
fname, lnum, items[4]);
+ }
}
// For postponed prefixes we need an entry in si_prefcond
@@ -2415,9 +2504,8 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
// be empty or start with the same letter.
if (aff_entry->ae_chop != NULL
&& aff_entry->ae_add != NULL
- && aff_entry->ae_chop[(*mb_ptr2len)(
- aff_entry->ae_chop)] == NUL
- ) {
+ && aff_entry->ae_chop[(*mb_ptr2len)(aff_entry->ae_chop)] ==
+ NUL) {
int c, c_up;
c = PTR2CHAR(aff_entry->ae_chop);
@@ -2442,10 +2530,9 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
aff_entry->ae_cond = getroom_save(spin, buf);
if (aff_entry->ae_cond != NULL) {
sprintf((char *)buf, "^%s",
- aff_entry->ae_cond);
+ aff_entry->ae_cond);
vim_regfree(aff_entry->ae_prog);
- aff_entry->ae_prog = vim_regcomp(
- buf, RE_MAGIC + RE_STRING);
+ aff_entry->ae_prog = vim_regcomp(buf, RE_MAGIC + RE_STRING);
}
}
}
@@ -2454,43 +2541,49 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
if (aff_entry->ae_chop == NULL) {
int idx;
- char_u **pp;
+ char_u **pp;
int n;
// Find a previously used condition.
for (idx = spin->si_prefcond.ga_len - 1; idx >= 0;
--idx) {
p = ((char_u **)spin->si_prefcond.ga_data)[idx];
- if (str_equal(p, aff_entry->ae_cond))
+ if (str_equal(p, aff_entry->ae_cond)) {
break;
+ }
}
if (idx < 0) {
// Not found, add a new condition.
idx = spin->si_prefcond.ga_len;
pp = GA_APPEND_VIA_PTR(char_u *, &spin->si_prefcond);
*pp = (aff_entry->ae_cond == NULL) ?
- NULL : getroom_save(spin, aff_entry->ae_cond);
+ NULL : getroom_save(spin, aff_entry->ae_cond);
}
// Add the prefix to the prefix tree.
- if (aff_entry->ae_add == NULL)
+ if (aff_entry->ae_add == NULL) {
p = (char_u *)"";
- else
+ } else {
p = aff_entry->ae_add;
+ }
// PFX_FLAGS is a negative number, so that
// tree_add_word() knows this is the prefix tree.
n = PFX_FLAGS;
- if (!cur_aff->ah_combine)
+ if (!cur_aff->ah_combine) {
n |= WFP_NC;
- if (upper)
+ }
+ if (upper) {
n |= WFP_UP;
- if (aff_entry->ae_comppermit)
+ }
+ if (aff_entry->ae_comppermit) {
n |= WFP_COMPPERMIT;
- if (aff_entry->ae_compforbid)
+ }
+ if (aff_entry->ae_compforbid) {
n |= WFP_COMPFORBID;
+ }
tree_add_word(spin, p, spin->si_prefroot, n,
- idx, cur_aff->ah_newID);
+ idx, cur_aff->ah_newID);
did_postpone_prefix = true;
}
@@ -2501,26 +2594,28 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
}
}
}
- } else if (is_aff_rule(items, itemcnt, "FOL", 2) && fol == NULL) {
+ } else if (is_aff_rule(items, itemcnt, "FOL", 2) && fol == NULL) {
fol = vim_strsave(items[1]);
- } else if (is_aff_rule(items, itemcnt, "LOW", 2) && low == NULL) {
+ } else if (is_aff_rule(items, itemcnt, "LOW", 2) && low == NULL) {
low = vim_strsave(items[1]);
- } else if (is_aff_rule(items, itemcnt, "UPP", 2) && upp == NULL) {
+ } else if (is_aff_rule(items, itemcnt, "UPP", 2) && upp == NULL) {
upp = vim_strsave(items[1]);
} else if (is_aff_rule(items, itemcnt, "REP", 2)
|| is_aff_rule(items, itemcnt, "REPSAL", 2)) {
/* Ignore REP/REPSAL count */;
- if (!isdigit(*items[1]))
+ if (!isdigit(*items[1])) {
smsg(_("Expected REP(SAL) count in %s line %d"),
fname, lnum);
+ }
} else if ((STRCMP(items[0], "REP") == 0
|| STRCMP(items[0], "REPSAL") == 0)
&& itemcnt >= 3) {
// REP/REPSAL item
// Myspell ignores extra arguments, we require it starts with
// # to detect mistakes.
- if (itemcnt > 3 && items[3][0] != '#')
+ if (itemcnt > 3 && items[3][0] != '#') {
smsg(_(e_afftrailing), fname, lnum, items[3]);
+ }
if (items[0][3] == 'S' ? do_repsal : do_rep) {
// Replace underscore with space (can't include a space
// directly).
@@ -2538,15 +2633,16 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
? &spin->si_repsal
: &spin->si_rep, items[1], items[2]);
}
- } else if (is_aff_rule(items, itemcnt, "MAP", 2)) {
+ } else if (is_aff_rule(items, itemcnt, "MAP", 2)) {
// MAP item or count
if (!found_map) {
// First line contains the count.
found_map = true;
- if (!isdigit(*items[1]))
+ if (!isdigit(*items[1])) {
smsg(_("Expected MAP count in %s line %d"),
fname, lnum);
- } else if (do_mapline) {
+ }
+ } else if (do_mapline) {
int c;
// Check that every character appears only once.
@@ -2572,17 +2668,18 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
if (do_sal) {
// SAL item (sounds-a-like)
// Either one of the known keys or a from-to pair.
- if (STRCMP(items[1], "followup") == 0)
+ if (STRCMP(items[1], "followup") == 0) {
spin->si_followup = sal_to_bool(items[2]);
- else if (STRCMP(items[1], "collapse_result") == 0)
+ } else if (STRCMP(items[1], "collapse_result") == 0) {
spin->si_collapse = sal_to_bool(items[2]);
- else if (STRCMP(items[1], "remove_accents") == 0)
+ } else if (STRCMP(items[1], "remove_accents") == 0) {
spin->si_rem_accents = sal_to_bool(items[2]);
- else
+ } else {
// when "to" is "_" it means empty
add_fromto(spin, &spin->si_sal, items[1],
- STRCMP(items[2], "_") == 0 ? (char_u *)""
- : items[2]);
+ STRCMP(items[2], "_") == 0 ? (char_u *)""
+ : items[2]);
+ }
}
} else if (is_aff_rule(items, itemcnt, "SOFOFROM", 2)
&& sofofrom == NULL) {
@@ -2590,19 +2687,20 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
} else if (is_aff_rule(items, itemcnt, "SOFOTO", 2)
&& sofoto == NULL) {
sofoto = getroom_save(spin, items[1]);
- } else if (STRCMP(items[0], "COMMON") == 0) {
+ } else if (STRCMP(items[0], "COMMON") == 0) {
int i;
for (i = 1; i < itemcnt; ++i) {
if (HASHITEM_EMPTY(hash_find(&spin->si_commonwords,
- items[i]))) {
+ items[i]))) {
p = vim_strsave(items[i]);
hash_add(&spin->si_commonwords, p);
}
}
- } else
+ } else {
smsg(_("Unrecognized or duplicate item in %s line %d: %s"),
fname, lnum, items[0]);
+ }
}
}
@@ -2643,17 +2741,19 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
spin->si_compoptions |= compoptions;
}
- if (compflags != NULL)
+ if (compflags != NULL) {
process_compflags(spin, aff, compflags);
+ }
// Check that we didn't use too many renumbered flags.
if (spin->si_newcompID < spin->si_newprefID) {
- if (spin->si_newcompID == 127 || spin->si_newcompID == 255)
+ if (spin->si_newcompID == 127 || spin->si_newcompID == 255) {
MSG(_("Too many postponed prefixes"));
- else if (spin->si_newprefID == 0 || spin->si_newprefID == 127)
+ } else if (spin->si_newprefID == 0 || spin->si_newprefID == 127) {
MSG(_("Too many compound flags"));
- else
+ } else {
MSG(_("Too many postponed prefixes and/or compound flags"));
+ }
}
if (syllable != NULL) {
@@ -2662,12 +2762,12 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
}
if (sofofrom != NULL || sofoto != NULL) {
- if (sofofrom == NULL || sofoto == NULL)
+ if (sofofrom == NULL || sofoto == NULL) {
smsg(_("Missing SOFO%s line in %s"),
sofofrom == NULL ? "FROM" : "TO", fname);
- else if (!GA_EMPTY(&spin->si_sal))
+ } else if (!GA_EMPTY(&spin->si_sal)) {
smsg(_("Both SAL and SOFO lines in %s"), fname);
- else {
+ } else {
aff_check_string(spin->si_sofofr, sofofrom, "SOFOFROM");
aff_check_string(spin->si_sofoto, sofoto, "SOFOTO");
spin->si_sofofr = sofofrom;
@@ -2698,8 +2798,8 @@ static bool is_aff_rule(char_u **items, int itemcnt, char *rulename, int mincoun
// ae_flags to ae_comppermit and ae_compforbid.
static void aff_process_flags(afffile_T *affile, affentry_T *entry)
{
- char_u *p;
- char_u *prevp;
+ char_u *p;
+ char_u *prevp;
unsigned flag;
if (entry->ae_flags != NULL
@@ -2710,16 +2810,19 @@ static void aff_process_flags(afffile_T *affile, affentry_T *entry)
if (flag == affile->af_comppermit || flag == affile->af_compforbid) {
STRMOVE(prevp, p);
p = prevp;
- if (flag == affile->af_comppermit)
+ if (flag == affile->af_comppermit) {
entry->ae_comppermit = true;
- else
+ } else {
entry->ae_compforbid = true;
+ }
}
- if (affile->af_flagtype == AFT_NUM && *p == ',')
+ if (affile->af_flagtype == AFT_NUM && *p == ',') {
++p;
+ }
}
- if (*entry->ae_flags == NUL)
+ if (*entry->ae_flags == NUL) {
entry->ae_flags = NULL; // nothing left
+ }
}
}
@@ -2739,16 +2842,17 @@ static bool spell_info_item(char_u *s)
static unsigned affitem2flag(int flagtype, char_u *item, char_u *fname, int lnum)
{
unsigned res;
- char_u *p = item;
+ char_u *p = item;
res = get_affitem(flagtype, &p);
if (res == 0) {
- if (flagtype == AFT_NUM)
+ if (flagtype == AFT_NUM) {
smsg(_("Flag is not a number in %s line %d: %s"),
fname, lnum, item);
- else
+ } else {
smsg(_("Illegal flag in %s line %d: %s"),
fname, lnum, item);
+ }
}
if (*p != NUL) {
smsg(_(e_affname), fname, lnum, item);
@@ -2778,8 +2882,9 @@ static unsigned get_affitem(int flagtype, char_u **pp)
res = mb_ptr2char_adv((const char_u **)pp);
if (flagtype == AFT_LONG || (flagtype == AFT_CAPLONG
&& res >= 'A' && res <= 'Z')) {
- if (**pp == NUL)
+ if (**pp == NUL) {
return 0;
+ }
res = mb_ptr2char_adv((const char_u **)pp) + (res << 16);
}
}
@@ -2792,22 +2897,23 @@ static unsigned get_affitem(int flagtype, char_u **pp)
// they fit in one byte.
static void process_compflags(spellinfo_T *spin, afffile_T *aff, char_u *compflags)
{
- char_u *p;
- char_u *prevp;
+ char_u *p;
+ char_u *prevp;
unsigned flag;
- compitem_T *ci;
+ compitem_T *ci;
int id;
int len;
- char_u *tp;
+ char_u *tp;
char_u key[AH_KEY_LEN];
- hashitem_T *hi;
+ hashitem_T *hi;
// Make room for the old and the new compflags, concatenated with a / in
// between. Processing it makes it shorter, but we don't know by how
// much, thus allocate the maximum.
len = (int)STRLEN(compflags) + 1;
- if (spin->si_compflags != NULL)
+ if (spin->si_compflags != NULL) {
len += (int)STRLEN(spin->si_compflags) + 1;
+ }
p = getroom(spin, len, false);
if (spin->si_compflags != NULL) {
STRCPY(p, spin->si_compflags);
@@ -2817,10 +2923,10 @@ static void process_compflags(spellinfo_T *spin, afffile_T *aff, char_u *compfla
tp = p + STRLEN(p);
for (p = compflags; *p != NUL; ) {
- if (vim_strchr((char_u *)"/?*+[]", *p) != NULL)
+ if (vim_strchr((char_u *)"/?*+[]", *p) != NULL) {
// Copy non-flag characters directly.
*tp++ = *p++;
- else {
+ } else {
// First get the flag number, also checks validity.
prevp = p;
flag = get_affitem(aff->af_flagtype, &p);
@@ -2846,8 +2952,9 @@ static void process_compflags(spellinfo_T *spin, afffile_T *aff, char_u *compfla
}
*tp++ = id;
}
- if (aff->af_flagtype == AFT_NUM && *p == ',')
+ if (aff->af_flagtype == AFT_NUM && *p == ',') {
++p;
+ }
}
}
@@ -2869,7 +2976,7 @@ static void check_renumber(spellinfo_T *spin)
// Returns true if flag "flag" appears in affix list "afflist".
static bool flag_in_afflist(int flagtype, char_u *afflist, unsigned flag)
{
- char_u *p;
+ char_u *p;
unsigned n;
switch (flagtype) {
@@ -2913,25 +3020,28 @@ static bool flag_in_afflist(int flagtype, char_u *afflist, unsigned flag)
// Give a warning when "spinval" and "affval" numbers are set and not the same.
static void aff_check_number(int spinval, int affval, char *name)
{
- if (spinval != 0 && spinval != affval)
+ if (spinval != 0 && spinval != affval) {
smsg(_("%s value differs from what is used in another .aff file"),
name);
+ }
}
// Give a warning when "spinval" and "affval" strings are set and not the same.
static void aff_check_string(char_u *spinval, char_u *affval, char *name)
{
- if (spinval != NULL && STRCMP(spinval, affval) != 0)
+ if (spinval != NULL && STRCMP(spinval, affval) != 0) {
smsg(_("%s value differs from what is used in another .aff file"),
name);
+ }
}
// Returns true if strings "s1" and "s2" are equal. Also consider both being
// NULL as equal.
static bool str_equal(char_u *s1, char_u *s2)
{
- if (s1 == NULL || s2 == NULL)
+ if (s1 == NULL || s2 == NULL) {
return s1 == s2;
+ }
return STRCMP(s1, s2) == 0;
}
@@ -2957,11 +3067,11 @@ static bool sal_to_bool(char_u *s)
// Free the structure filled by spell_read_aff().
static void spell_free_aff(afffile_T *aff)
{
- hashtab_T *ht;
- hashitem_T *hi;
+ hashtab_T *ht;
+ hashitem_T *hi;
int todo;
affheader_T *ah;
- affentry_T *ae;
+ affentry_T *ae;
xfree(aff->af_enc);
@@ -2972,12 +3082,14 @@ static void spell_free_aff(afffile_T *aff)
if (!HASHITEM_EMPTY(hi)) {
--todo;
ah = HI2AH(hi);
- for (ae = ah->ah_first; ae != NULL; ae = ae->ae_next)
+ for (ae = ah->ah_first; ae != NULL; ae = ae->ae_next) {
vim_regfree(ae->ae_prog);
+ }
}
}
- if (ht == &aff->af_suff)
+ if (ht == &aff->af_suff) {
break;
+ }
}
hash_clear(&aff->af_pref);
@@ -2991,18 +3103,18 @@ static int spell_read_dic(spellinfo_T *spin, char_u *fname, afffile_T *affile)
{
hashtab_T ht;
char_u line[MAXLINELEN];
- char_u *p;
- char_u *afflist;
+ char_u *p;
+ char_u *afflist;
char_u store_afflist[MAXWLEN];
int pfxlen;
bool need_affix;
- char_u *dw;
- char_u *pc;
- char_u *w;
+ char_u *dw;
+ char_u *pc;
+ char_u *w;
int l;
hash_T hash;
- hashitem_T *hi;
- FILE *fd;
+ hashitem_T *hi;
+ FILE *fd;
int lnum = 1;
int non_ascii = 0;
int retval = OK;
@@ -3039,16 +3151,18 @@ static int spell_read_dic(spellinfo_T *spin, char_u *fname, afffile_T *affile)
while (!vim_fgets(line, MAXLINELEN, fd) && !got_int) {
line_breakcheck();
++lnum;
- if (line[0] == '#' || line[0] == '/')
+ if (line[0] == '#' || line[0] == '/') {
continue; // comment line
-
+ }
// Remove CR, LF and white space from the end. White space halfway through
// the word is kept to allow multi-word terms like "et al.".
l = (int)STRLEN(line);
- while (l > 0 && line[l - 1] <= ' ')
+ while (l > 0 && line[l - 1] <= ' ') {
--l;
- if (l == 0)
+ }
+ if (l == 0) {
continue; // empty line
+ }
line[l] = NUL;
// Convert from "SET" to 'encoding' when needed.
@@ -3114,15 +3228,17 @@ static int spell_read_dic(spellinfo_T *spin, char_u *fname, afffile_T *affile)
hash = hash_hash(dw);
hi = hash_lookup(&ht, (const char *)dw, STRLEN(dw), hash);
if (!HASHITEM_EMPTY(hi)) {
- if (p_verbose > 0)
+ if (p_verbose > 0) {
smsg(_("Duplicate word in %s line %d: %s"),
fname, lnum, dw);
- else if (duplicate == 0)
+ } else if (duplicate == 0) {
smsg(_("First duplicate word in %s line %d: %s"),
fname, lnum, dw);
+ }
++duplicate;
- } else
+ } else {
hash_add_item(&ht, hi, dw, hash);
+ }
flags = 0;
store_afflist[0] = NUL;
@@ -3132,48 +3248,57 @@ static int spell_read_dic(spellinfo_T *spin, char_u *fname, afffile_T *affile)
// Extract flags from the affix list.
flags |= get_affix_flags(affile, afflist);
- if (affile->af_needaffix != 0 && flag_in_afflist(
- affile->af_flagtype, afflist, affile->af_needaffix))
+ if (affile->af_needaffix != 0 &&
+ flag_in_afflist(affile->af_flagtype, afflist,
+ affile->af_needaffix)) {
need_affix = true;
+ }
- if (affile->af_pfxpostpone)
+ if (affile->af_pfxpostpone) {
// Need to store the list of prefix IDs with the word.
pfxlen = get_pfxlist(affile, afflist, store_afflist);
+ }
- if (spin->si_compflags != NULL)
+ if (spin->si_compflags != NULL) {
// Need to store the list of compound flags with the word.
// Concatenate them to the list of prefix IDs.
get_compflags(affile, afflist, store_afflist + pfxlen);
+ }
}
// Add the word to the word tree(s).
if (store_word(spin, dw, flags, spin->si_region,
- store_afflist, need_affix) == FAIL)
+ store_afflist, need_affix) == FAIL) {
retval = FAIL;
+ }
if (afflist != NULL) {
// Find all matching suffixes and add the resulting words.
// Additionally do matching prefixes that combine.
if (store_aff_word(spin, dw, afflist, affile,
- &affile->af_suff, &affile->af_pref,
- CONDIT_SUF, flags, store_afflist, pfxlen) == FAIL)
+ &affile->af_suff, &affile->af_pref,
+ CONDIT_SUF, flags, store_afflist, pfxlen) == FAIL) {
retval = FAIL;
+ }
// Find all matching prefixes and add the resulting words.
if (store_aff_word(spin, dw, afflist, affile,
- &affile->af_pref, NULL,
- CONDIT_SUF, flags, store_afflist, pfxlen) == FAIL)
+ &affile->af_pref, NULL,
+ CONDIT_SUF, flags, store_afflist, pfxlen) == FAIL) {
retval = FAIL;
+ }
}
xfree(pc);
}
- if (duplicate > 0)
+ if (duplicate > 0) {
smsg(_("%d duplicate word(s) in %s"), duplicate, fname);
- if (spin->si_ascii && non_ascii > 0)
+ }
+ if (spin->si_ascii && non_ascii > 0) {
smsg(_("Ignored %d word(s) with non-ASCII characters in %s"),
non_ascii, fname);
+ }
hash_clear(&ht);
fclose(fd);
@@ -3186,24 +3311,34 @@ static int get_affix_flags(afffile_T *affile, char_u *afflist)
{
int flags = 0;
- if (affile->af_keepcase != 0 && flag_in_afflist(
- affile->af_flagtype, afflist, affile->af_keepcase))
+ if (affile->af_keepcase != 0 &&
+ flag_in_afflist(affile->af_flagtype, afflist,
+ affile->af_keepcase)) {
flags |= WF_KEEPCAP | WF_FIXCAP;
- if (affile->af_rare != 0 && flag_in_afflist(
- affile->af_flagtype, afflist, affile->af_rare))
+ }
+ if (affile->af_rare != 0 &&
+ flag_in_afflist(affile->af_flagtype, afflist, affile->af_rare)) {
flags |= WF_RARE;
- if (affile->af_bad != 0 && flag_in_afflist(
- affile->af_flagtype, afflist, affile->af_bad))
+ }
+ if (affile->af_bad != 0 &&
+ flag_in_afflist(affile->af_flagtype, afflist, affile->af_bad)) {
flags |= WF_BANNED;
- if (affile->af_needcomp != 0 && flag_in_afflist(
- affile->af_flagtype, afflist, affile->af_needcomp))
+ }
+ if (affile->af_needcomp != 0 &&
+ flag_in_afflist(affile->af_flagtype, afflist,
+ affile->af_needcomp)) {
flags |= WF_NEEDCOMP;
- if (affile->af_comproot != 0 && flag_in_afflist(
- affile->af_flagtype, afflist, affile->af_comproot))
+ }
+ if (affile->af_comproot != 0 &&
+ flag_in_afflist(affile->af_flagtype, afflist,
+ affile->af_comproot)) {
flags |= WF_COMPROOT;
- if (affile->af_nosuggest != 0 && flag_in_afflist(
- affile->af_flagtype, afflist, affile->af_nosuggest))
+ }
+ if (affile->af_nosuggest != 0 &&
+ flag_in_afflist(affile->af_flagtype, afflist,
+ affile->af_nosuggest)) {
flags |= WF_NOSUGGEST;
+ }
return flags;
}
@@ -3213,12 +3348,12 @@ static int get_affix_flags(afffile_T *affile, char_u *afflist)
// and return the number of affixes.
static int get_pfxlist(afffile_T *affile, char_u *afflist, char_u *store_afflist)
{
- char_u *p;
- char_u *prevp;
+ char_u *p;
+ char_u *prevp;
int cnt = 0;
int id;
char_u key[AH_KEY_LEN];
- hashitem_T *hi;
+ hashitem_T *hi;
for (p = afflist; *p != NUL; ) {
prevp = p;
@@ -3229,12 +3364,14 @@ static int get_pfxlist(afffile_T *affile, char_u *afflist, char_u *store_afflist
hi = hash_find(&affile->af_pref, key);
if (!HASHITEM_EMPTY(hi)) {
id = HI2AH(hi)->ah_newID;
- if (id != 0)
+ if (id != 0) {
store_afflist[cnt++] = id;
+ }
}
}
- if (affile->af_flagtype == AFT_NUM && *p == ',')
+ if (affile->af_flagtype == AFT_NUM && *p == ',') {
++p;
+ }
}
store_afflist[cnt] = NUL;
@@ -3246,11 +3383,11 @@ static int get_pfxlist(afffile_T *affile, char_u *afflist, char_u *store_afflist
// Puts the flags in "store_afflist[]".
static void get_compflags(afffile_T *affile, char_u *afflist, char_u *store_afflist)
{
- char_u *p;
- char_u *prevp;
+ char_u *p;
+ char_u *prevp;
int cnt = 0;
char_u key[AH_KEY_LEN];
- hashitem_T *hi;
+ hashitem_T *hi;
for (p = afflist; *p != NUL; ) {
prevp = p;
@@ -3258,48 +3395,47 @@ static void get_compflags(afffile_T *affile, char_u *afflist, char_u *store_affl
// A flag is a compound flag if it appears in "af_comp".
STRLCPY(key, prevp, p - prevp + 1);
hi = hash_find(&affile->af_comp, key);
- if (!HASHITEM_EMPTY(hi))
+ if (!HASHITEM_EMPTY(hi)) {
store_afflist[cnt++] = HI2CI(hi)->ci_newID;
+ }
}
- if (affile->af_flagtype == AFT_NUM && *p == ',')
+ if (affile->af_flagtype == AFT_NUM && *p == ',') {
++p;
+ }
}
store_afflist[cnt] = NUL;
}
-// Apply affixes to a word and store the resulting words.
-// "ht" is the hashtable with affentry_T that need to be applied, either
-// prefixes or suffixes.
-// "xht", when not NULL, is the prefix hashtable, to be used additionally on
-// the resulting words for combining affixes.
-//
-// Returns FAIL when out of memory.
-static int
-store_aff_word (
- spellinfo_T *spin, // spell info
- char_u *word, // basic word start
- char_u *afflist, // list of names of supported affixes
- afffile_T *affile,
- hashtab_T *ht,
- hashtab_T *xht,
- int condit, // CONDIT_SUF et al.
- int flags, // flags for the word
- char_u *pfxlist, // list of prefix IDs
- int pfxlen // nr of flags in "pfxlist" for prefixes, rest
- // is compound flags
-)
+/// Apply affixes to a word and store the resulting words.
+/// "ht" is the hashtable with affentry_T that need to be applied, either
+/// prefixes or suffixes.
+/// "xht", when not NULL, is the prefix hashtable, to be used additionally on
+/// the resulting words for combining affixes.
+///
+/// @param spin spell info
+/// @param word basic word start
+/// @param afflist list of names of supported affixes
+/// @param condit CONDIT_SUF et al.
+/// @param flags flags for the word
+/// @param pfxlist list of prefix IDs
+/// @param pfxlen nr of flags in "pfxlist" for prefixes, rest is compound flags
+///
+/// @return FAIL when out of memory.
+static int store_aff_word(spellinfo_T *spin, char_u *word, char_u *afflist, afffile_T *affile,
+ hashtab_T *ht, hashtab_T *xht, int condit, int flags, char_u *pfxlist,
+ int pfxlen)
{
int todo;
- hashitem_T *hi;
+ hashitem_T *hi;
affheader_T *ah;
- affentry_T *ae;
+ affentry_T *ae;
char_u newword[MAXWLEN];
int retval = OK;
int i, j;
- char_u *p;
+ char_u *p;
int use_flags;
- char_u *use_pfxlist;
+ char_u *use_pfxlist;
int use_pfxlen;
bool need_affix;
char_u store_afflist[MAXWLEN];
@@ -3317,7 +3453,7 @@ store_aff_word (
// supports this affix.
if (((condit & CONDIT_COMB) == 0 || ah->ah_combine)
&& flag_in_afflist(affile->af_flagtype, afflist,
- ah->ah_flag)) {
+ ah->ah_flag)) {
// Loop over all affix entries with this name.
for (ae = ah->ah_first; ae != NULL; ae = ae->ae_next) {
// Check the condition. It's not logical to match case
@@ -3341,7 +3477,7 @@ store_aff_word (
== ((condit & CONDIT_AFF) == 0
|| ae->ae_flags == NULL
|| !flag_in_afflist(affile->af_flagtype,
- ae->ae_flags, affile->af_circumfix)))) {
+ ae->ae_flags, affile->af_circumfix)))) {
// Match. Remove the chop and add the affix.
if (xht == NULL) {
// prefix: chop/add at the start of the word
@@ -3371,8 +3507,9 @@ store_aff_word (
}
*p = NUL;
}
- if (ae->ae_add != NULL)
+ if (ae->ae_add != NULL) {
STRCAT(newword, ae->ae_add);
+ }
}
use_flags = flags;
@@ -3384,57 +3521,64 @@ store_aff_word (
// Extract flags from the affix list.
use_flags |= get_affix_flags(affile, ae->ae_flags);
- if (affile->af_needaffix != 0 && flag_in_afflist(
- affile->af_flagtype, ae->ae_flags,
- affile->af_needaffix))
+ if (affile->af_needaffix != 0 && flag_in_afflist(affile->af_flagtype, ae->ae_flags,
+ affile->af_needaffix)) {
need_affix = true;
+ }
// When there is a CIRCUMFIX flag the other affix
// must also have it and we don't add the word
// with one affix.
- if (affile->af_circumfix != 0 && flag_in_afflist(
- affile->af_flagtype, ae->ae_flags,
- affile->af_circumfix)) {
+ if (affile->af_circumfix != 0 && flag_in_afflist(affile->af_flagtype, ae->ae_flags,
+ affile->af_circumfix)) {
use_condit |= CONDIT_CFIX;
- if ((condit & CONDIT_CFIX) == 0)
+ if ((condit & CONDIT_CFIX) == 0) {
need_affix = true;
+ }
}
if (affile->af_pfxpostpone
|| spin->si_compflags != NULL) {
- if (affile->af_pfxpostpone)
+ if (affile->af_pfxpostpone) {
// Get prefix IDS from the affix list.
use_pfxlen = get_pfxlist(affile,
- ae->ae_flags, store_afflist);
- else
+ ae->ae_flags, store_afflist);
+ } else {
use_pfxlen = 0;
+ }
use_pfxlist = store_afflist;
// Combine the prefix IDs. Avoid adding the
// same ID twice.
for (i = 0; i < pfxlen; ++i) {
- for (j = 0; j < use_pfxlen; ++j)
- if (pfxlist[i] == use_pfxlist[j])
+ for (j = 0; j < use_pfxlen; ++j) {
+ if (pfxlist[i] == use_pfxlist[j]) {
break;
- if (j == use_pfxlen)
+ }
+ }
+ if (j == use_pfxlen) {
use_pfxlist[use_pfxlen++] = pfxlist[i];
+ }
}
- if (spin->si_compflags != NULL)
+ if (spin->si_compflags != NULL) {
// Get compound IDS from the affix list.
get_compflags(affile, ae->ae_flags,
- use_pfxlist + use_pfxlen);
- else
+ use_pfxlist + use_pfxlen);
+ } else {
use_pfxlist[use_pfxlen] = NUL;
+ }
// Combine the list of compound flags.
// Concatenate them to the prefix IDs list.
// Avoid adding the same ID twice.
for (i = pfxlen; pfxlist[i] != NUL; ++i) {
for (j = use_pfxlen;
- use_pfxlist[j] != NUL; ++j)
- if (pfxlist[i] == use_pfxlist[j])
+ use_pfxlist[j] != NUL; ++j) {
+ if (pfxlist[i] == use_pfxlist[j]) {
break;
+ }
+ }
if (use_pfxlist[j] == NUL) {
use_pfxlist[j++] = pfxlist[i];
use_pfxlist[j] = NUL;
@@ -3459,52 +3603,58 @@ store_aff_word (
// ... don't use a prefix list if combining
// affixes is not allowed. But do use the
// compound flags after them.
- if (!ah->ah_combine && use_pfxlist != NULL)
+ if (!ah->ah_combine && use_pfxlist != NULL) {
use_pfxlist += use_pfxlen;
+ }
}
// When compounding is supported and there is no
// "COMPOUNDPERMITFLAG" then forbid compounding on the
// side where the affix is applied.
if (spin->si_compflags != NULL && !ae->ae_comppermit) {
- if (xht != NULL)
+ if (xht != NULL) {
use_flags |= WF_NOCOMPAFT;
- else
+ } else {
use_flags |= WF_NOCOMPBEF;
+ }
}
// Store the modified word.
if (store_word(spin, newword, use_flags,
- spin->si_region, use_pfxlist,
- need_affix) == FAIL)
+ spin->si_region, use_pfxlist,
+ need_affix) == FAIL) {
retval = FAIL;
+ }
// When added a prefix or a first suffix and the affix
// has flags may add a(nother) suffix. RECURSIVE!
- if ((condit & CONDIT_SUF) && ae->ae_flags != NULL)
+ if ((condit & CONDIT_SUF) && ae->ae_flags != NULL) {
if (store_aff_word(spin, newword, ae->ae_flags,
- affile, &affile->af_suff, xht,
- use_condit & (xht == NULL
+ affile, &affile->af_suff, xht,
+ use_condit & (xht == NULL
? ~0 : ~CONDIT_SUF),
- use_flags, use_pfxlist, pfxlen) == FAIL)
+ use_flags, use_pfxlist, pfxlen) == FAIL) {
retval = FAIL;
+ }
+ }
// When added a suffix and combining is allowed also
// try adding a prefix additionally. Both for the
// word flags and for the affix flags. RECURSIVE!
if (xht != NULL && ah->ah_combine) {
if (store_aff_word(spin, newword,
- afflist, affile,
- xht, NULL, use_condit,
- use_flags, use_pfxlist,
- pfxlen) == FAIL
+ afflist, affile,
+ xht, NULL, use_condit,
+ use_flags, use_pfxlist,
+ pfxlen) == FAIL
|| (ae->ae_flags != NULL
&& store_aff_word(spin, newword,
- ae->ae_flags, affile,
- xht, NULL, use_condit,
- use_flags, use_pfxlist,
- pfxlen) == FAIL))
+ ae->ae_flags, affile,
+ xht, NULL, use_condit,
+ use_flags, use_pfxlist,
+ pfxlen) == FAIL)) {
retval = FAIL;
+ }
}
}
}
@@ -3518,12 +3668,12 @@ store_aff_word (
// Read a file with a list of words.
static int spell_read_wordfile(spellinfo_T *spin, char_u *fname)
{
- FILE *fd;
+ FILE *fd;
long lnum = 0;
char_u rline[MAXLINELEN];
- char_u *line;
- char_u *pc = NULL;
- char_u *p;
+ char_u *line;
+ char_u *pc = NULL;
+ char_u *p;
int l;
int retval = OK;
bool did_word = false;
@@ -3547,15 +3697,18 @@ static int spell_read_wordfile(spellinfo_T *spin, char_u *fname)
++lnum;
// Skip comment lines.
- if (*rline == '#')
+ if (*rline == '#') {
continue;
+ }
// Remove CR, LF and white space from the end.
l = (int)STRLEN(rline);
- while (l > 0 && rline[l - 1] <= ' ')
+ while (l > 0 && rline[l - 1] <= ' ') {
--l;
- if (l == 0)
+ }
+ if (l == 0) {
continue; // empty or blank line
+ }
rline[l] = NUL;
// Convert from "/encoding={encoding}" to 'encoding' when needed.
@@ -3583,16 +3736,17 @@ static int spell_read_wordfile(spellinfo_T *spin, char_u *fname)
smsg(_("/encoding= line after word ignored in %s line %ld: %s"),
fname, lnum, line - 1);
} else {
- char_u *enc;
+ char_u *enc;
// Setup for conversion to 'encoding'.
line += 9;
enc = enc_canonize(line);
if (!spin->si_ascii
&& convert_setup(&spin->si_conv, enc,
- p_enc) == FAIL)
+ p_enc) == FAIL) {
smsg(_("Conversion in %s not supported: from %s to %s"),
fname, line, p_enc);
+ }
xfree(enc);
spin->si_conv.vc_fail = true;
}
@@ -3632,15 +3786,16 @@ static int spell_read_wordfile(spellinfo_T *spin, char_u *fname)
if (p != NULL) {
*p++ = NUL;
while (*p != NUL) {
- if (*p == '=') // keep-case word
+ if (*p == '=') { // keep-case word
flags |= WF_KEEPCAP | WF_FIXCAP;
- else if (*p == '!') // Bad, bad, wicked word.
+ } else if (*p == '!') { // Bad, bad, wicked word.
flags |= WF_BANNED;
- else if (*p == '?') // Rare word.
+ } else if (*p == '?') { // Rare word.
flags |= WF_RARE;
- else if (ascii_isdigit(*p)) { // region number(s)
- if ((flags & WF_REGION) == 0) // first one
+ } else if (ascii_isdigit(*p)) { // region number(s)
+ if ((flags & WF_REGION) == 0) { // first one
regionmask = 0;
+ }
flags |= WF_REGION;
l = *p - '0';
@@ -3678,7 +3833,7 @@ static int spell_read_wordfile(spellinfo_T *spin, char_u *fname)
if (spin->si_ascii && non_ascii > 0) {
vim_snprintf((char *)IObuff, IOSIZE,
- _("Ignored %d words with non-ASCII characters"), non_ascii);
+ _("Ignored %d words with non-ASCII characters"), non_ascii);
spell_message(spin, IObuff);
}
@@ -3696,16 +3851,17 @@ static int spell_read_wordfile(spellinfo_T *spin, char_u *fname)
static void *getroom(spellinfo_T *spin, size_t len, bool align)
FUNC_ATTR_NONNULL_RET
{
- char_u *p;
- sblock_T *bl = spin->si_blocks;
+ char_u *p;
+ sblock_T *bl = spin->si_blocks;
assert(len <= SBLOCKSIZE);
-
- if (align && bl != NULL)
+
+ if (align && bl != NULL) {
// Round size up for alignment. On some systems structures need to be
// aligned to the size of a pointer (e.g., SPARC).
bl->sb_used = (bl->sb_used + sizeof(char *) - 1)
& ~(sizeof(char *) - 1);
+ }
if (bl == NULL || bl->sb_used + len > SBLOCKSIZE) {
// Allocate a block of memory. It is not freed until much later.
@@ -3734,7 +3890,7 @@ static char_u *getroom_save(spellinfo_T *spin, char_u *s)
// Free the list of allocated sblock_T.
static void free_blocks(sblock_T *bl)
{
- sblock_T *next;
+ sblock_T *next;
while (bl != NULL) {
next = bl->sb_next;
@@ -3751,22 +3907,20 @@ static wordnode_T *wordtree_alloc(spellinfo_T *spin)
return (wordnode_T *)getroom(spin, sizeof(wordnode_T), true);
}
-// Store a word in the tree(s).
-// Always store it in the case-folded tree. For a keep-case word this is
-// useful when the word can also be used with all caps (no WF_FIXCAP flag) and
-// used to find suggestions.
-// For a keep-case word also store it in the keep-case tree.
-// When "pfxlist" is not NULL store the word for each postponed prefix ID and
-// compound flag.
-static int
-store_word (
- spellinfo_T *spin,
- char_u *word,
- int flags, // extra flags, WF_BANNED
- int region, // supported region(s)
- const char_u *pfxlist, // list of prefix IDs or NULL
- bool need_affix // only store word with affix ID
-)
+/// Store a word in the tree(s).
+/// Always store it in the case-folded tree. For a keep-case word this is
+/// useful when the word can also be used with all caps (no WF_FIXCAP flag) and
+/// used to find suggestions.
+/// For a keep-case word also store it in the keep-case tree.
+/// When "pfxlist" is not NULL store the word for each postponed prefix ID and
+/// compound flag.
+///
+/// @param flags extra flags, wf_banned
+/// @param region supported region(s)
+/// @param pfxlist list of prefix ids or null
+/// @param need_affix only store word with affix id
+static int store_word(spellinfo_T *spin, char_u *word, int flags, int region, const char_u *pfxlist,
+ bool need_affix)
{
int len = (int)STRLEN(word);
int ct = captype(word, word + len);
@@ -3804,12 +3958,13 @@ store_word (
// When "flags" < 0 we are adding to the prefix tree where "flags" is used for
// "rare" and "region" is the condition nr.
// Returns FAIL when out of memory.
-static int tree_add_word(spellinfo_T *spin, char_u *word, wordnode_T *root, int flags, int region, int affixID)
+static int tree_add_word(spellinfo_T *spin, char_u *word, wordnode_T *root, int flags, int region,
+ int affixID)
{
- wordnode_T *node = root;
- wordnode_T *np;
- wordnode_T *copyp, **copyprev;
- wordnode_T **prev = NULL;
+ wordnode_T *node = root;
+ wordnode_T *np;
+ wordnode_T *copyp, **copyprev;
+ wordnode_T **prev = NULL;
int i;
// Add each byte of the word to the tree, including the NUL at the end.
@@ -3823,11 +3978,13 @@ static int tree_add_word(spellinfo_T *spin, char_u *word, wordnode_T *root, int
for (copyp = node; copyp != NULL; copyp = copyp->wn_sibling) {
// Allocate a new node and copy the info.
np = get_wordnode(spin);
- if (np == NULL)
+ if (np == NULL) {
return FAIL;
+ }
np->wn_child = copyp->wn_child;
- if (np->wn_child != NULL)
+ if (np->wn_child != NULL) {
++np->wn_child->wn_refs; // child gets extra ref
+ }
np->wn_byte = copyp->wn_byte;
if (np->wn_byte == NUL) {
np->wn_flags = copyp->wn_flags;
@@ -3837,13 +3994,15 @@ static int tree_add_word(spellinfo_T *spin, char_u *word, wordnode_T *root, int
// Link the new node in the list, there will be one ref.
np->wn_refs = 1;
- if (copyprev != NULL)
+ if (copyprev != NULL) {
*copyprev = np;
+ }
copyprev = &np->wn_sibling;
// Let "node" point to the head of the copied list.
- if (copyp == node)
+ if (copyp == node) {
node = np;
+ }
}
}
@@ -3874,22 +4033,24 @@ static int tree_add_word(spellinfo_T *spin, char_u *word, wordnode_T *root, int
|| node->wn_affixID != affixID))) {
// Allocate a new node.
np = get_wordnode(spin);
- if (np == NULL)
+ if (np == NULL) {
return FAIL;
+ }
np->wn_byte = word[i];
// If "node" is NULL this is a new child or the end of the sibling
// list: ref count is one. Otherwise use ref count of sibling and
// make ref count of sibling one (matters when inserting in front
// of the list of siblings).
- if (node == NULL)
+ if (node == NULL) {
np->wn_refs = 1;
- else {
+ } else {
np->wn_refs = node->wn_refs;
node->wn_refs = 1;
}
- if (prev != NULL)
+ if (prev != NULL) {
*prev = np;
+ }
np->wn_sibling = node;
node = np;
}
@@ -3931,7 +4092,7 @@ static int tree_add_word(spellinfo_T *spin, char_u *word, wordnode_T *root, int
#ifndef SPELL_COMPRESS_ALLWAYS
if (spin->si_compress_cnt == 1 // NOLINT(readability/braces)
? spin->si_free_count < MAXWLEN
- : spin->si_blocks_cnt >= compress_start)
+ : spin->si_blocks_cnt >= compress_start)
#endif
{
// Decrement the block counter. The effect is that we compress again
@@ -3945,7 +4106,7 @@ static int tree_add_word(spellinfo_T *spin, char_u *word, wordnode_T *root, int
msg_start();
msg_puts(_(msg_compressing));
msg_clr_eos();
- msg_didout = FALSE;
+ msg_didout = false;
msg_col = 0;
ui_flush();
}
@@ -3970,17 +4131,18 @@ static wordnode_T *get_wordnode(spellinfo_T *spin)
{
wordnode_T *n;
- if (spin->si_first_free == NULL)
+ if (spin->si_first_free == NULL) {
n = (wordnode_T *)getroom(spin, sizeof(wordnode_T), true);
- else {
+ } else {
n = spin->si_first_free;
spin->si_first_free = n->wn_child;
memset(n, 0, sizeof(wordnode_T));
--spin->si_free_count;
}
#ifdef SPELL_PRINTTREE
- if (n != NULL)
+ if (n != NULL) {
n->wn_nr = ++spin->si_wordnode_nr;
+ }
#endif
return n;
}
@@ -3992,13 +4154,14 @@ static wordnode_T *get_wordnode(spellinfo_T *spin)
static int deref_wordnode(spellinfo_T *spin, wordnode_T *node)
FUNC_ATTR_NONNULL_ALL
{
- wordnode_T *np;
+ wordnode_T *np;
int cnt = 0;
if (--node->wn_refs == 0) {
for (np = node; np != NULL; np = np->wn_sibling) {
- if (np->wn_child != NULL)
+ if (np->wn_child != NULL) {
cnt += deref_wordnode(spin, np->wn_child);
+ }
free_wordnode(spin, np);
++cnt;
}
@@ -4018,8 +4181,7 @@ static void free_wordnode(spellinfo_T *spin, wordnode_T *n)
}
// Compress a tree: find tails that are identical and can be shared.
-static void wordtree_compress(spellinfo_T *spin, wordnode_T *root,
- const char *name)
+static void wordtree_compress(spellinfo_T *spin, wordnode_T *root, const char *name)
FUNC_ATTR_NONNULL_ALL
{
hashtab_T ht;
@@ -4036,12 +4198,13 @@ static void wordtree_compress(spellinfo_T *spin, wordnode_T *root,
if (spin->si_verbose || p_verbose > 2)
#endif
{
- if (tot > 1000000)
+ if (tot > 1000000) {
perc = (tot - n) / (tot / 100);
- else if (tot == 0)
+ } else if (tot == 0) {
perc = 0;
- else
+ } else {
perc = (tot - n) * 100 / tot;
+ }
vim_snprintf((char *)IObuff, IOSIZE,
_("Compressed %s of %ld nodes; %ld (%ld%%) remaining"),
name, tot, tot - n, perc);
@@ -4054,22 +4217,18 @@ static void wordtree_compress(spellinfo_T *spin, wordnode_T *root,
}
}
-// Compress a node, its siblings and its children, depth first.
-// Returns the number of compressed nodes.
-static long node_compress(
- spellinfo_T *spin,
- wordnode_T *node,
- hashtab_T *ht,
- long *tot // total count of nodes before compressing,
- // incremented while going through the tree
-)
+/// Compress a node, its siblings and its children, depth first.
+/// Returns the number of compressed nodes.
+///
+/// @param tot total count of nodes before compressing, incremented while going through the tree
+static long node_compress(spellinfo_T *spin, wordnode_T *node, hashtab_T *ht, long *tot)
FUNC_ATTR_NONNULL_ALL
{
- wordnode_T *np;
- wordnode_T *tp;
- wordnode_T *child;
+ wordnode_T *np;
+ wordnode_T *tp;
+ wordnode_T *child;
hash_T hash;
- hashitem_T *hi;
+ hashitem_T *hi;
long len = 0;
unsigned nr, n;
long compressed = 0;
@@ -4092,7 +4251,7 @@ static long node_compress(
// There are children we encountered before with a hash value
// identical to the current child. Now check if there is one
// that is really identical.
- for (tp = HI2WN(hi); tp != NULL; tp = tp->wn_u2.next)
+ for (tp = HI2WN(hi); tp != NULL; tp = tp->wn_u2.next) {
if (node_equal(child, tp)) {
// Found one! Now use that child in place of the
// current one. This means the current child and all
@@ -4102,6 +4261,7 @@ static long node_compress(
np->wn_child = tp;
break;
}
+ }
if (tp == NULL) {
// No other child with this hash value equals the child of
// the node, add it to the linked list after the first
@@ -4110,10 +4270,11 @@ static long node_compress(
child->wn_u2.next = tp->wn_u2.next;
tp->wn_u2.next = child;
}
- } else
+ } else {
// No other child has this hash value, add it to the
// hashtable.
hash_add_item(ht, hi, child->wn_u1.hashkey, hash);
+ }
}
}
*tot += len + 1; // add one for the node that stores the length
@@ -4124,12 +4285,13 @@ static long node_compress(
node->wn_u1.hashkey[0] = len;
nr = 0;
for (np = node; np != NULL; np = np->wn_sibling) {
- if (np->wn_byte == NUL)
+ if (np->wn_byte == NUL) {
// end node: use wn_flags, wn_region and wn_affixID
n = np->wn_flags + (np->wn_region << 8) + (np->wn_affixID << 16);
- else
+ } else {
// byte node: use the byte value and the child pointer
n = (unsigned)(np->wn_byte + ((uintptr_t)np->wn_child << 8));
+ }
nr = nr * 101 + n;
}
@@ -4153,18 +4315,20 @@ static long node_compress(
// Returns true when two nodes have identical siblings and children.
static bool node_equal(wordnode_T *n1, wordnode_T *n2)
{
- wordnode_T *p1;
- wordnode_T *p2;
+ wordnode_T *p1;
+ wordnode_T *p2;
for (p1 = n1, p2 = n2; p1 != NULL && p2 != NULL;
- p1 = p1->wn_sibling, p2 = p2->wn_sibling)
+ p1 = p1->wn_sibling, p2 = p2->wn_sibling) {
if (p1->wn_byte != p2->wn_byte
|| (p1->wn_byte == NUL
? (p1->wn_flags != p2->wn_flags
|| p1->wn_region != p2->wn_region
|| p1->wn_affixID != p2->wn_affixID)
- : (p1->wn_child != p2->wn_child)))
+ : (p1->wn_child != p2->wn_child))) {
break;
+ }
+ }
return p1 == NULL && p2 == NULL;
}
@@ -4173,8 +4337,8 @@ static bool node_equal(wordnode_T *n1, wordnode_T *n2)
// Function given to qsort() to sort the REP items on "from" string.
static int rep_compare(const void *s1, const void *s2)
{
- fromto_T *p1 = (fromto_T *)s1;
- fromto_T *p2 = (fromto_T *)s2;
+ fromto_T *p1 = (fromto_T *)s1;
+ fromto_T *p2 = (fromto_T *)s2;
return STRCMP(p1->ft_from, p2->ft_from);
}
@@ -4195,9 +4359,10 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname)
// <HEADER>: <fileID> <versionnr>
// <fileID>
size_t fwv = fwrite(VIMSPELLMAGIC, VIMSPELLMAGICL, 1, fd);
- if (fwv != (size_t)1)
+ if (fwv != (size_t)1) {
// Catch first write error, don't try writing more.
goto theend;
+ }
putc(VIMSPELLVERSION, fd); // <versionnr>
@@ -4222,8 +4387,9 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname)
fwv &= fwrite(spin->si_region_name, l, 1, fd);
// <regionname> ...
regionmask = (1 << spin->si_region_count) - 1;
- } else
+ } else {
regionmask = 0;
+ }
// SN_CHARFLAGS: <charflagslen> <charflags> <folcharslen> <folchars>
//
@@ -4251,10 +4417,12 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname)
fputc(128, fd); // <charflagslen>
for (size_t i = 128; i < 256; ++i) {
flags = 0;
- if (spelltab.st_isw[i])
+ if (spelltab.st_isw[i]) {
flags |= CF_WORD;
- if (spelltab.st_isu[i])
+ }
+ if (spelltab.st_isu[i]) {
flags |= CF_UPPER;
+ }
fputc(flags, fd); // <charflags>
}
@@ -4293,24 +4461,28 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname)
// round 3: SN_REPSAL section
for (unsigned int round = 1; round <= 3; ++round) {
garray_T *gap;
- if (round == 1)
+ if (round == 1) {
gap = &spin->si_rep;
- else if (round == 2) {
+ } else if (round == 2) {
// Don't write SN_SAL when using a SN_SOFO section
- if (spin->si_sofofr != NULL && spin->si_sofoto != NULL)
+ if (spin->si_sofofr != NULL && spin->si_sofoto != NULL) {
continue;
+ }
gap = &spin->si_sal;
- } else
+ } else {
gap = &spin->si_repsal;
+ }
// Don't write the section if there are no items.
- if (GA_EMPTY(gap))
+ if (GA_EMPTY(gap)) {
continue;
+ }
// Sort the REP/REPSAL items.
- if (round != 2)
+ if (round != 2) {
qsort(gap->ga_data, (size_t)gap->ga_len,
- sizeof(fromto_T), rep_compare);
+ sizeof(fromto_T), rep_compare);
+ }
int sect_id = round == 1 ? SN_REP : (round == 2 ? SN_SAL : SN_REPSAL);
putc(sect_id, fd); // <sectionID>
@@ -4326,18 +4498,22 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname)
l += 1 + STRLEN(ftp->ft_from); // count <*fromlen> and <*from>
l += 1 + STRLEN(ftp->ft_to); // count <*tolen> and <*to>
}
- if (round == 2)
+ if (round == 2) {
++l; // count <salflags>
+ }
put_bytes(fd, l, 4); // <sectionlen>
if (round == 2) {
int i = 0;
- if (spin->si_followup)
+ if (spin->si_followup) {
i |= SAL_F0LLOWUP;
- if (spin->si_collapse)
+ }
+ if (spin->si_collapse) {
i |= SAL_COLLAPSE;
- if (spin->si_rem_accents)
+ }
+ if (spin->si_rem_accents) {
i |= SAL_REM_ACCENTS;
+ }
putc(i, fd); // <salflags>
}
@@ -4351,11 +4527,11 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname)
l = STRLEN(p);
assert(l < INT_MAX);
putc((int)l, fd);
- if (l > 0)
+ if (l > 0) {
fwv &= fwrite(p, l, 1, fd);
+ }
}
}
-
}
// SN_SOFO: <sofofromlen> <sofofrom> <sofotolen> <sofoto>
@@ -4386,19 +4562,22 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname)
for (unsigned int round = 1; round <= 2; ++round) {
size_t todo;
size_t len = 0;
- hashitem_T *hi;
+ hashitem_T *hi;
todo = spin->si_commonwords.ht_used;
- for (hi = spin->si_commonwords.ht_array; todo > 0; ++hi)
+ for (hi = spin->si_commonwords.ht_array; todo > 0; ++hi) {
if (!HASHITEM_EMPTY(hi)) {
size_t l = STRLEN(hi->hi_key) + 1;
len += l;
- if (round == 2) // <word>
+ if (round == 2) { // <word>
fwv &= fwrite(hi->hi_key, l, 1, fd);
+ }
--todo;
}
- if (round == 1)
+ }
+ if (round == 1) {
put_bytes(fd, len, 4); // <sectionlen>
+ }
}
}
@@ -4506,12 +4685,13 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname)
spin->si_memtot = 0;
for (unsigned int round = 1; round <= 3; ++round) {
wordnode_T *tree;
- if (round == 1)
+ if (round == 1) {
tree = spin->si_foldroot->wn_sibling;
- else if (round == 2)
+ } else if (round == 2) {
tree = spin->si_keeproot->wn_sibling;
- else
+ } else {
tree = spin->si_prefroot->wn_sibling;
+ }
// Clear the index and wnode fields in the tree.
clear_node(tree);
@@ -4531,16 +4711,20 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname)
}
// Write another byte to check for errors (file system full).
- if (putc(0, fd) == EOF)
+ if (putc(0, fd) == EOF) {
retval = FAIL;
+ }
theend:
- if (fclose(fd) == EOF)
+ if (fclose(fd) == EOF) {
retval = FAIL;
+ }
- if (fwv != (size_t)1)
+ if (fwv != (size_t)1) {
retval = FAIL;
- if (retval == FAIL)
+ }
+ if (retval == FAIL) {
EMSG(_(e_write));
+ }
return retval;
}
@@ -4550,54 +4734,54 @@ theend:
// space.
static void clear_node(wordnode_T *node)
{
- wordnode_T *np;
+ wordnode_T *np;
- if (node != NULL)
+ if (node != NULL) {
for (np = node; np != NULL; np = np->wn_sibling) {
np->wn_u1.index = 0;
np->wn_u2.wnode = NULL;
- if (np->wn_byte != NUL)
+ if (np->wn_byte != NUL) {
clear_node(np->wn_child);
+ }
}
+ }
}
-// Dump a word tree at node "node".
-//
-// This first writes the list of possible bytes (siblings). Then for each
-// byte recursively write the children.
-//
-// NOTE: The code here must match the code in read_tree_node(), since
-// assumptions are made about the indexes (so that we don't have to write them
-// in the file).
-//
-// Returns the number of nodes used.
-static int
-put_node (
- FILE *fd, // NULL when only counting
- wordnode_T *node,
- int idx,
- int regionmask,
- bool prefixtree // true for PREFIXTREE
-)
+/// Dump a word tree at node "node".
+///
+/// This first writes the list of possible bytes (siblings). Then for each
+/// byte recursively write the children.
+///
+/// NOTE: The code here must match the code in read_tree_node(), since
+/// assumptions are made about the indexes (so that we don't have to write them
+/// in the file).
+///
+/// @param fd NULL when only counting
+/// @param prefixtree true for PREFIXTREE
+///
+/// @return the number of nodes used.
+static int put_node(FILE *fd, wordnode_T *node, int idx, int regionmask, bool prefixtree)
{
// If "node" is zero the tree is empty.
- if (node == NULL)
+ if (node == NULL) {
return 0;
+ }
// Store the index where this node is written.
node->wn_u1.index = idx;
// Count the number of siblings.
int siblingcount = 0;
- for (wordnode_T *np = node; np != NULL; np = np->wn_sibling)
+ for (wordnode_T *np = node; np != NULL; np = np->wn_sibling) {
++siblingcount;
+ }
// Write the sibling count.
- if (fd != NULL)
+ if (fd != NULL) {
putc(siblingcount, fd); // <siblingcount>
-
+ }
// Write each sibling byte and optionally extra info.
for (wordnode_T *np = node; np != NULL; np = np->wn_sibling) {
if (np->wn_byte == 0) {
@@ -4608,9 +4792,9 @@ put_node (
// associated condition nr (stored in wn_region). The
// byte value is misused to store the "rare" and "not
// combining" flags
- if (np->wn_flags == (uint16_t)PFX_FLAGS)
+ if (np->wn_flags == (uint16_t)PFX_FLAGS) {
putc(BY_NOFLAGS, fd); // <byte>
- else {
+ } else {
putc(BY_FLAGS, fd); // <byte>
putc(np->wn_flags, fd); // <pflags>
}
@@ -4619,10 +4803,12 @@ put_node (
} else {
// For word trees we write the flag/region items.
int flags = np->wn_flags;
- if (regionmask != 0 && np->wn_region != regionmask)
+ if (regionmask != 0 && np->wn_region != regionmask) {
flags |= WF_REGION;
- if (np->wn_affixID != 0)
+ }
+ if (np->wn_affixID != 0) {
flags |= WF_AFX;
+ }
if (flags == 0) {
// word without flags or region
putc(BY_NOFLAGS, fd); // <byte>
@@ -4635,10 +4821,12 @@ put_node (
putc(BY_FLAGS, fd); // <byte>
putc(flags, fd); // <flags>
}
- if (flags & WF_REGION)
+ if (flags & WF_REGION) {
putc(np->wn_region, fd); // <region>
- if (flags & WF_AFX)
+ }
+ if (flags & WF_AFX) {
putc(np->wn_affixID, fd); // <affixID>
+ }
}
}
}
@@ -4650,15 +4838,17 @@ put_node (
putc(BY_INDEX, fd); // <byte>
put_bytes(fd, (uintmax_t)np->wn_child->wn_u1.index, 3); // <nodeidx>
}
- } else if (np->wn_child->wn_u2.wnode == NULL)
+ } else if (np->wn_child->wn_u2.wnode == NULL) {
// We will write the child below and give it an index.
np->wn_child->wn_u2.wnode = node;
+ }
- if (fd != NULL)
+ if (fd != NULL) {
if (putc(np->wn_byte, fd) == EOF) { // <byte> or <xbyte>
EMSG(_(e_write));
return 0;
}
+ }
}
}
@@ -4667,10 +4857,12 @@ put_node (
int newindex = idx + siblingcount + 1;
// Recursively dump the children of each sibling.
- for (wordnode_T *np = node; np != NULL; np = np->wn_sibling)
- if (np->wn_byte != 0 && np->wn_child->wn_u2.wnode == node)
+ for (wordnode_T *np = node; np != NULL; np = np->wn_sibling) {
+ if (np->wn_byte != 0 && np->wn_child->wn_u2.wnode == node) {
newindex = put_node(fd, np->wn_child, newindex, regionmask,
- prefixtree);
+ prefixtree);
+ }
+ }
return newindex;
}
@@ -4681,8 +4873,8 @@ put_node (
void ex_mkspell(exarg_T *eap)
{
int fcount;
- char_u **fnames;
- char_u *arg = eap->arg;
+ char_u **fnames;
+ char_u *arg = eap->arg;
bool ascii = false;
if (STRNCMP(arg, "-ascii", 6) == 0) {
@@ -4702,9 +4894,9 @@ void ex_mkspell(exarg_T *eap)
// Writes the file with the name "wfname", with ".spl" changed to ".sug".
static void spell_make_sugfile(spellinfo_T *spin, char_u *wfname)
{
- char_u *fname = NULL;
+ char_u *fname = NULL;
int len;
- slang_T *slang;
+ slang_T *slang;
bool free_slang = false;
// Read back the .spl file that was written. This fills the required
@@ -4721,8 +4913,9 @@ static void spell_make_sugfile(spellinfo_T *spin, char_u *wfname)
if (slang == NULL) {
spell_message(spin, (char_u *)_("Reading back spell file..."));
slang = spell_load_file(wfname, NULL, NULL, false);
- if (slang == NULL)
+ if (slang == NULL) {
return;
+ }
free_slang = true;
}
@@ -4737,15 +4930,17 @@ static void spell_make_sugfile(spellinfo_T *spin, char_u *wfname)
// Go through the trie of good words, soundfold each word and add it to
// the soundfold trie.
spell_message(spin, (char_u *)_("Performing soundfolding..."));
- if (sug_filltree(spin, slang) == FAIL)
+ if (sug_filltree(spin, slang) == FAIL) {
goto theend;
+ }
// Create the table which links each soundfold word with a list of the
// good words it may come from. Creates buffer "spin->si_spellbuf".
// This also removes the wordnr from the NUL byte entries to make
// compression possible.
- if (sug_maketable(spin) == FAIL)
+ if (sug_maketable(spin) == FAIL) {
goto theend;
+ }
smsg(_("Number of words after soundfolding: %" PRId64),
(int64_t)spin->si_spellbuf->b_ml.ml_line_count);
@@ -4765,8 +4960,9 @@ static void spell_make_sugfile(spellinfo_T *spin, char_u *wfname)
theend:
xfree(fname);
- if (free_slang)
+ if (free_slang) {
slang_free(slang);
+ }
free_blocks(spin->si_blocks);
close_spellbuf(spin->si_spellbuf);
}
@@ -4774,8 +4970,8 @@ theend:
// Build the soundfold trie for language "slang".
static int sug_filltree(spellinfo_T *spin, slang_T *slang)
{
- char_u *byts;
- idx_T *idxs;
+ char_u *byts;
+ idx_T *idxs;
int depth;
idx_T arridx[MAXWLEN];
int curi[MAXWLEN];
@@ -4806,13 +5002,13 @@ static int sug_filltree(spellinfo_T *spin, slang_T *slang)
if (curi[depth] > byts[arridx[depth]]) {
// Done all bytes at this node, go up one level.
idxs[arridx[depth]] = wordcount[depth];
- if (depth > 0)
+ if (depth > 0) {
wordcount[depth - 1] += wordcount[depth];
+ }
--depth;
line_breakcheck();
} else {
-
// Do one more byte at this node.
n = arridx[depth] + curi[depth];
++curi[depth];
@@ -4826,9 +5022,10 @@ static int sug_filltree(spellinfo_T *spin, slang_T *slang)
// We use the "flags" field for the MSB of the wordnr,
// "region" for the LSB of the wordnr.
if (tree_add_word(spin, tsalword, spin->si_foldroot,
- words_done >> 16, words_done & 0xffff,
- 0) == FAIL)
+ words_done >> 16, words_done & 0xffff,
+ 0) == FAIL) {
return FAIL;
+ }
++words_done;
++wordcount[depth];
@@ -4877,25 +5074,22 @@ static int sug_maketable(spellinfo_T *spin)
ga_init(&ga, 1, 100);
// recursively go through the tree
- if (sug_filltable(spin, spin->si_foldroot->wn_sibling, 0, &ga) == -1)
+ if (sug_filltable(spin, spin->si_foldroot->wn_sibling, 0, &ga) == -1) {
res = FAIL;
+ }
ga_clear(&ga);
return res;
}
-// Fill the table for one node and its children.
-// Returns the wordnr at the start of the node.
-// Returns -1 when out of memory.
-static int
-sug_filltable (
- spellinfo_T *spin,
- wordnode_T *node,
- int startwordnr,
- garray_T *gap // place to store line of numbers
-)
+/// Fill the table for one node and its children.
+/// Returns the wordnr at the start of the node.
+/// Returns -1 when out of memory.
+///
+/// @param gap place to store line of numbers
+static int sug_filltable(spellinfo_T *spin, wordnode_T *node, int startwordnr, garray_T *gap)
{
- wordnode_T *p, *np;
+ wordnode_T *p, *np;
int wordnr = startwordnr;
int nr;
int prev_nr;
@@ -4915,7 +5109,7 @@ sug_filltable (
nr -= prev_nr;
prev_nr += nr;
gap->ga_len += offset2bytes(nr,
- (char_u *)gap->ga_data + gap->ga_len);
+ (char_u *)gap->ga_data + gap->ga_len);
}
// add the NUL byte
@@ -4929,8 +5123,9 @@ sug_filltable (
// Remove extra NUL entries, we no longer need them. We don't
// bother freeing the nodes, the won't be reused anyway.
- while (p->wn_sibling != NULL && p->wn_sibling->wn_byte == NUL)
+ while (p->wn_sibling != NULL && p->wn_sibling->wn_byte == NUL) {
p->wn_sibling = p->wn_sibling->wn_sibling;
+ }
// Clear the flags on the remaining NUL node, so that compression
// works a lot better.
@@ -4938,8 +5133,9 @@ sug_filltable (
p->wn_region = 0;
} else {
wordnr = sug_filltable(spin, p->wn_child, wordnr, gap);
- if (wordnr == -1)
+ if (wordnr == -1) {
return -1;
+ }
}
}
return wordnr;
@@ -4999,7 +5195,7 @@ static void sug_write(spellinfo_T *spin, char_u *fname)
spell_message(spin, IObuff);
// <SUGHEADER>: <fileID> <versionnr> <timestamp>
- if (fwrite(VIMSUGMAGIC, VIMSUGMAGICL, (size_t)1, fd) != 1) { // <fileID>
+ if (fwrite(VIMSUGMAGIC, VIMSUGMAGICL, (size_t)1, fd) != 1) { // <fileID>
EMSG(_(e_write));
goto theend;
}
@@ -5035,7 +5231,7 @@ static void sug_write(spellinfo_T *spin, char_u *fname)
for (linenr_T lnum = 1; lnum <= wcount; ++lnum) {
// <sugline>: <sugnr> ... NUL
- char_u *line = ml_get_buf(spin->si_spellbuf, lnum, FALSE);
+ char_u *line = ml_get_buf(spin->si_spellbuf, lnum, false);
size_t len = STRLEN(line) + 1;
if (fwrite(line, len, 1, fd) == 0) {
EMSG(_(e_write));
@@ -5046,11 +5242,12 @@ static void sug_write(spellinfo_T *spin, char_u *fname)
}
// Write another byte to check for errors.
- if (putc(0, fd) == EOF)
+ if (putc(0, fd) == EOF) {
EMSG(_(e_write));
+ }
vim_snprintf((char *)IObuff, IOSIZE,
- _("Estimated runtime memory use: %d bytes"), spin->si_memtot);
+ _("Estimated runtime memory use: %d bytes"), spin->si_memtot);
spell_message(spin, IObuff);
theend:
@@ -5059,23 +5256,20 @@ theend:
}
-// Create a Vim spell file from one or more word lists.
-// "fnames[0]" is the output file name.
-// "fnames[fcount - 1]" is the last input file name.
-// Exception: when "fnames[0]" ends in ".add" it's used as the input file name
-// and ".spl" is appended to make the output file name.
-static void
-mkspell (
- int fcount,
- char_u **fnames,
- bool ascii, // -ascii argument given
- bool over_write, // overwrite existing output file
- bool added_word // invoked through "zg"
-)
+/// Create a Vim spell file from one or more word lists.
+/// "fnames[0]" is the output file name.
+/// "fnames[fcount - 1]" is the last input file name.
+/// Exception: when "fnames[0]" ends in ".add" it's used as the input file name
+/// and ".spl" is appended to make the output file name.
+///
+/// @param ascii -ascii argument given
+/// @param over_write overwrite existing output file
+/// @param added_word invoked through "zg"
+static void mkspell(int fcount, char_u **fnames, bool ascii, bool over_write, bool added_word)
{
- char_u *fname = NULL;
- char_u *wfname;
- char_u **innames;
+ char_u *fname = NULL;
+ char_u *wfname;
+ char_u **innames;
int incount;
afffile_T *(afile[MAXREGIONS]);
int i;
@@ -5111,26 +5305,29 @@ mkspell (
// "path/en.latin1.add.spl".
incount = 1;
vim_snprintf((char *)wfname, MAXPATHL, "%s.spl", fnames[0]);
- } else if (fcount == 1) {
+ } else if (fcount == 1) {
// For ":mkspell path/vim" output file is "path/vim.latin1.spl".
incount = 1;
vim_snprintf((char *)wfname, MAXPATHL, SPL_FNAME_TMPL,
- fnames[0], spin.si_ascii ? (char_u *)"ascii" : spell_enc());
- } else if (len > 4 && STRCMP(fnames[0] + len - 4, ".spl") == 0) {
+ fnames[0], spin.si_ascii ? (char_u *)"ascii" : spell_enc());
+ } else if (len > 4 && STRCMP(fnames[0] + len - 4, ".spl") == 0) {
// Name ends in ".spl", use as the file name.
STRLCPY(wfname, fnames[0], MAXPATHL);
- } else
+ } else {
// Name should be language, make the file name from it.
vim_snprintf((char *)wfname, MAXPATHL, SPL_FNAME_TMPL,
- fnames[0], spin.si_ascii ? (char_u *)"ascii" : spell_enc());
+ fnames[0], spin.si_ascii ? (char_u *)"ascii" : spell_enc());
+ }
// Check for .ascii.spl.
- if (strstr((char *)path_tail(wfname), SPL_FNAME_ASCII) != NULL)
+ if (strstr((char *)path_tail(wfname), SPL_FNAME_ASCII) != NULL) {
spin.si_ascii = true;
+ }
// Check for .add.spl.
- if (strstr((char *)path_tail(wfname), SPL_FNAME_ADD) != NULL)
+ if (strstr((char *)path_tail(wfname), SPL_FNAME_ADD) != NULL) {
spin.si_add = true;
+ }
}
if (incount <= 0) {
@@ -5181,8 +5378,9 @@ mkspell (
// one in the .spl file if the .aff file doesn't define one. That's
// better than guessing the contents, the table will match a
// previously loaded spell file.
- if (!spin.si_add)
+ if (!spin.si_add) {
spin.si_clear_chartab = true;
+ }
// Read all the .aff and .dic files.
// Text is converted to 'encoding'.
@@ -5196,28 +5394,31 @@ mkspell (
// Read the .aff file. Will init "spin->si_conv" based on the
// "SET" line.
afile[i] = spell_read_aff(&spin, fname);
- if (afile[i] == NULL)
+ if (afile[i] == NULL) {
error = true;
- else {
+ } else {
// Read the .dic file and store the words in the trees.
vim_snprintf((char *)fname, MAXPATHL, "%s.dic",
- innames[i]);
- if (spell_read_dic(&spin, fname, afile[i]) == FAIL)
+ innames[i]);
+ if (spell_read_dic(&spin, fname, afile[i]) == FAIL) {
error = true;
+ }
}
} else {
// No .aff file, try reading the file as a word list. Store
// the words in the trees.
- if (spell_read_wordfile(&spin, innames[i]) == FAIL)
+ if (spell_read_wordfile(&spin, innames[i]) == FAIL) {
error = true;
+ }
}
// Free any conversion stuff.
convert_setup(&spin.si_conv, NULL, NULL);
}
- if (spin.si_compflags != NULL && spin.si_nobreak)
+ if (spin.si_compflags != NULL && spin.si_nobreak) {
MSG(_("Warning: both compounding and NOBREAK specified"));
+ }
if (!error && !got_int) {
// Combine tails in the tree.
@@ -5237,12 +5438,13 @@ mkspell (
spell_message(&spin, (char_u *)_("Done!"));
vim_snprintf((char *)IObuff, IOSIZE,
- _("Estimated runtime memory use: %d bytes"), spin.si_memtot);
+ _("Estimated runtime memory use: %d bytes"), spin.si_memtot);
spell_message(&spin, IObuff);
// If the file is loaded need to reload it.
- if (!error)
+ if (!error) {
spell_reload_one(wfname, added_word);
+ }
}
// Free the allocated memory.
@@ -5255,18 +5457,20 @@ mkspell (
hash_clear_all(&spin.si_commonwords, 0);
// Free the .aff file structures.
- for (i = 0; i < incount; ++i)
- if (afile[i] != NULL)
+ for (i = 0; i < incount; ++i) {
+ if (afile[i] != NULL) {
spell_free_aff(afile[i]);
+ }
+ }
// Free all the bits and pieces at once.
free_blocks(spin.si_blocks);
// If there is soundfolding info and no NOSUGFILE item create the
// .sug file with the soundfolded word trie.
- if (spin.si_sugtime != 0 && !error && !got_int)
+ if (spin.si_sugtime != 0 && !error && !got_int) {
spell_make_sugfile(&spin, wfname);
-
+ }
}
theend:
@@ -5280,12 +5484,14 @@ static void spell_message(const spellinfo_T *spin, char_u *str)
FUNC_ATTR_NONNULL_ALL
{
if (spin->si_verbose || p_verbose > 2) {
- if (!spin->si_verbose)
+ if (!spin->si_verbose) {
verbose_enter();
+ }
MSG(str);
ui_flush();
- if (!spin->si_verbose)
+ if (!spin->si_verbose) {
verbose_leave();
+ }
}
}
@@ -5302,32 +5508,29 @@ void ex_spell(exarg_T *eap)
eap->cmdidx == CMD_spellundo);
}
-// Add "word[len]" to 'spellfile' as a good or bad word.
-void
-spell_add_word (
- char_u *word,
- int len,
- SpellAddType what, // SPELL_ADD_ values
- int idx, // "zG" and "zW": zero, otherwise index in
- // 'spellfile'
- bool undo // true for "zug", "zuG", "zuw" and "zuW"
-)
+/// Add "word[len]" to 'spellfile' as a good or bad word.
+///
+/// @param what SPELL_ADD_ values
+/// @param idx "zG" and "zW": zero, otherwise index in 'spellfile'
+/// @param bool // true for "zug", "zuG", "zuw" and "zuW"
+void spell_add_word(char_u *word, int len, SpellAddType what, int idx, bool undo)
{
- FILE *fd = NULL;
- buf_T *buf = NULL;
+ FILE *fd = NULL;
+ buf_T *buf = NULL;
bool new_spf = false;
- char_u *fname;
- char_u *fnamebuf = NULL;
+ char_u *fname;
+ char_u *fnamebuf = NULL;
char_u line[MAXWLEN * 2];
long fpos, fpos_next = 0;
int i;
- char_u *spf;
+ char_u *spf;
if (idx == 0) { // use internal wordlist
if (int_wordlist == NULL) {
int_wordlist = vim_tempname();
- if (int_wordlist == NULL)
+ if (int_wordlist == NULL) {
return;
+ }
}
fname = int_wordlist;
} else {
@@ -5345,8 +5548,9 @@ spell_add_word (
for (spf = curwin->w_s->b_p_spf, i = 1; *spf != NUL; ++i) {
copy_option_part(&spf, fnamebuf, MAXPATHL, ",");
- if (i == idx)
+ if (i == idx) {
break;
+ }
if (*spf == NUL) {
EMSGN(_("E765: 'spellfile' does not have %" PRId64 " entries"), idx);
xfree(fnamebuf);
@@ -5356,8 +5560,9 @@ spell_add_word (
// Check that the user isn't editing the .add file somewhere.
buf = buflist_findname_exp(fnamebuf);
- if (buf != NULL && buf->b_ml.ml_mfp == NULL)
+ if (buf != NULL && buf->b_ml.ml_mfp == NULL) {
buf = NULL;
+ }
if (buf != NULL && bufIsChanged(buf)) {
EMSG(_(e_bufloaded));
xfree(fnamebuf);
@@ -5399,8 +5604,9 @@ spell_add_word (
}
}
}
- if (fd != NULL)
+ if (fd != NULL) {
fclose(fd);
+ }
}
}
@@ -5447,8 +5653,9 @@ spell_add_word (
mkspell(1, &fname, false, true, true);
// If the .add file is edited somewhere, reload it.
- if (buf != NULL)
+ if (buf != NULL) {
buf_reload(buf, buf->b_orig_mode);
+ }
redraw_all_later(SOME_VALID);
}
@@ -5458,13 +5665,13 @@ spell_add_word (
// Initialize 'spellfile' for the current buffer.
static void init_spellfile(void)
{
- char_u *buf;
+ char_u *buf;
int l;
- char_u *fname;
- char_u *rtp;
- char_u *lend;
+ char_u *fname;
+ char_u *rtp;
+ char_u *lend;
bool aspath = false;
- char_u *lstart = curbuf->b_s.b_p_spl;
+ char_u *lstart = curbuf->b_s.b_p_spl;
if (*curwin->w_s->b_p_spl != NUL && !GA_EMPTY(&curwin->w_s->b_langp)) {
buf = xmalloc(MAXPATHL);
@@ -5472,31 +5679,33 @@ static void init_spellfile(void)
// Find the end of the language name. Exclude the region. If there
// is a path separator remember the start of the tail.
for (lend = curwin->w_s->b_p_spl; *lend != NUL
- && vim_strchr((char_u *)",._", *lend) == NULL; ++lend)
+ && vim_strchr((char_u *)",._", *lend) == NULL; ++lend) {
if (vim_ispathsep(*lend)) {
aspath = true;
lstart = lend + 1;
}
+ }
// Loop over all entries in 'runtimepath'. Use the first one where we
// are allowed to write.
rtp = p_rtp;
while (*rtp != NUL) {
- if (aspath)
+ if (aspath) {
// Use directory of an entry with path, e.g., for
// "/dir/lg.utf-8.spl" use "/dir".
STRLCPY(buf, curbuf->b_s.b_p_spl,
- lstart - curbuf->b_s.b_p_spl);
- else
+ lstart - curbuf->b_s.b_p_spl);
+ } else {
// Copy the path from 'runtimepath' to buf[].
copy_option_part(&rtp, buf, MAXPATHL, ",");
+ }
if (os_file_is_writable((char *)buf) == 2) {
// Use the first language name from 'spelllang' and the
// encoding used in the first loaded .spl file.
- if (aspath)
+ if (aspath) {
STRLCPY(buf, curbuf->b_s.b_p_spl,
- lend - curbuf->b_s.b_p_spl + 1);
- else {
+ lend - curbuf->b_s.b_p_spl + 1);
+ } else {
// Create the "spell" directory if it doesn't exist yet.
l = (int)STRLEN(buf);
vim_snprintf((char *)buf + l, MAXPATHL - l, "/spell");
@@ -5506,7 +5715,7 @@ static void init_spellfile(void)
l = (int)STRLEN(buf);
vim_snprintf((char *)buf + l, MAXPATHL - l,
- "/%.*s", (int)(lend - lstart), lstart);
+ "/%.*s", (int)(lend - lstart), lstart);
}
l = (int)STRLEN(buf);
fname = LANGP_ENTRY(curwin->w_s->b_langp, 0)
@@ -5526,19 +5735,16 @@ static void init_spellfile(void)
}
}
-// Set the spell character tables from strings in the .spl file.
-static void
-set_spell_charflags (
- char_u *flags,
- int cnt, // length of "flags"
- char_u *fol
-)
+/// Set the spell character tables from strings in the .spl file.
+///
+/// @param cnt length of "flags"
+static void set_spell_charflags(char_u *flags, int cnt, char_u *fol)
{
// We build the new tables here first, so that we can compare with the
// previous one.
spelltab_T new_st;
int i;
- char_u *p = fol;
+ char_u *p = fol;
int c;
clear_spell_chartab(&new_st);
@@ -5552,8 +5758,9 @@ set_spell_charflags (
if (*p != NUL) {
c = mb_ptr2char_adv((const char_u **)&p);
new_st.st_fold[i + 128] = c;
- if (i + 128 != c && new_st.st_isu[i + 128] && c < 256)
+ if (i + 128 != c && new_st.st_isu[i + 128] && c < 256) {
new_st.st_upper[c] = i + 128;
+ }
}
}
@@ -5590,9 +5797,9 @@ static int write_spell_prefcond(FILE *fd, garray_T *gap)
{
assert(gap->ga_len >= 0);
- if (fd != NULL)
+ if (fd != NULL) {
put_bytes(fd, (uintmax_t)gap->ga_len, 2); // <prefcondcnt>
-
+ }
size_t totlen = 2 + (size_t)gap->ga_len; // <prefcondcnt> and <condlen> bytes
size_t x = 1; // collect return value of fwrite()
for (int i = 0; i < gap->ga_len; ++i) {
@@ -5606,8 +5813,9 @@ static int write_spell_prefcond(FILE *fd, garray_T *gap)
x &= fwrite(p, len, 1, fd);
}
totlen += len;
- } else if (fd != NULL)
+ } else if (fd != NULL) {
fputc(0, fd);
+ }
}
assert(totlen <= INT_MAX);
@@ -5617,7 +5825,7 @@ static int write_spell_prefcond(FILE *fd, garray_T *gap)
// Use map string "map" for languages "lp".
static void set_map_str(slang_T *lp, char_u *map)
{
- char_u *p;
+ char_u *p;
int headc = 0;
int c;
int i;
@@ -5629,8 +5837,9 @@ static void set_map_str(slang_T *lp, char_u *map)
lp->sl_has_map = true;
// Init the array and hash tables empty.
- for (i = 0; i < 256; ++i)
+ for (i = 0; i < 256; ++i) {
lp->sl_map_array[i] = 0;
+ }
hash_init(&lp->sl_map_hash);
// The similar characters are stored separated with slashes:
@@ -5651,9 +5860,9 @@ static void set_map_str(slang_T *lp, char_u *map)
if (c >= 256) {
int cl = mb_char2len(c);
int headcl = mb_char2len(headc);
- char_u *b;
+ char_u *b;
hash_T hash;
- hashitem_T *hi;
+ hashitem_T *hi;
b = xmalloc(cl + headcl + 2);
utf_char2bytes(c, b);
@@ -5670,8 +5879,9 @@ static void set_map_str(slang_T *lp, char_u *map)
EMSG(_("E783: duplicate char in MAP entry"));
xfree(b);
}
- } else
+ } else {
lp->sl_map_array[c] = headc;
+ }
}
}
}
diff --git a/src/nvim/state.c b/src/nvim/state.c
index a3c74789d1..a9f3d67849 100644
--- a/src/nvim/state.c
+++ b/src/nvim/state.c
@@ -3,19 +3,18 @@
#include <assert.h>
-#include "nvim/lib/kvec.h"
-
#include "nvim/ascii.h"
+#include "nvim/edit.h"
+#include "nvim/ex_docmd.h"
+#include "nvim/getchar.h"
+#include "nvim/lib/kvec.h"
#include "nvim/log.h"
-#include "nvim/state.h"
-#include "nvim/vim.h"
#include "nvim/main.h"
-#include "nvim/getchar.h"
#include "nvim/option_defs.h"
-#include "nvim/ui.h"
#include "nvim/os/input.h"
-#include "nvim/ex_docmd.h"
-#include "nvim/edit.h"
+#include "nvim/state.h"
+#include "nvim/ui.h"
+#include "nvim/vim.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "state.c.generated.h"
@@ -144,6 +143,9 @@ char *get_mode(void)
buf[0] = (char)(VIsual_mode + 's' - 'v');
} else {
buf[0] = (char)VIsual_mode;
+ if (restart_VIsual_select) {
+ buf[1] = 's';
+ }
}
} else if (State == HITRETURN || State == ASKMORE || State == SETWSIZE
|| State == CONFIRM) {
@@ -171,12 +173,10 @@ char *get_mode(void)
buf[1] = 'x';
}
}
- } else if ((State & CMDLINE) || exmode_active) {
+ } else if (State & CMDLINE) {
buf[0] = 'c';
- if (exmode_active == EXMODE_VIM) {
+ if (exmode_active) {
buf[1] = 'v';
- } else if (exmode_active == EXMODE_NORMAL) {
- buf[1] = 'e';
}
} else if (State & TERM_FOCUS) {
buf[0] = 't';
diff --git a/src/nvim/strings.c b/src/nvim/strings.c
index cb66f7682d..79a3db4843 100644
--- a/src/nvim/strings.c
+++ b/src/nvim/strings.c
@@ -190,6 +190,7 @@ char_u *vim_strsave_shellescape(const char_u *string,
char_u *escaped_string;
size_t l;
int csh_like;
+ bool fish_like;
/* Only csh and similar shells expand '!' within single quotes. For sh and
* the like we must not put a backslash before it, it will be taken
@@ -197,6 +198,10 @@ char_u *vim_strsave_shellescape(const char_u *string,
* Csh also needs to have "\n" escaped twice when do_special is set. */
csh_like = csh_like_shell();
+ // Fish shell uses '\' as an escape character within single quotes, so '\'
+ // itself must be escaped to get a literal '\'.
+ fish_like = fish_like_shell();
+
/* First count the number of extra bytes required. */
size_t length = STRLEN(string) + 3; // two quotes and a trailing NUL
for (const char_u *p = string; *p != NUL; MB_PTR_ADV(p)) {
@@ -220,6 +225,9 @@ char_u *vim_strsave_shellescape(const char_u *string,
++length; /* insert backslash */
p += l - 1;
}
+ if (*p == '\\' && fish_like) {
+ length++; // insert backslash
+ }
}
/* Allocate memory for the result and fill it. */
@@ -267,6 +275,11 @@ char_u *vim_strsave_shellescape(const char_u *string,
*d++ = *p++;
continue;
}
+ if (*p == '\\' && fish_like) {
+ *d++ = '\\';
+ *d++ = *p++;
+ continue;
+ }
MB_COPY_CHAR(p, d);
}
@@ -964,7 +977,7 @@ int vim_vsnprintf_typval(
break;
}
}
- str_arg_l = precision = (size_t)(p1 - (char_u *)str_arg);
+ str_arg_l = (size_t)(p1 - (char_u *)str_arg);
}
}
break;
diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c
index ce81f26d38..d2c94d9fe8 100644
--- a/src/nvim/syntax.c
+++ b/src/nvim/syntax.c
@@ -9,13 +9,12 @@
#include <ctype.h>
#include <inttypes.h>
#include <stdbool.h>
-#include <string.h>
#include <stdlib.h>
+#include <string.h>
-#include "nvim/vim.h"
-#include "nvim/ascii.h"
#include "nvim/api/private/helpers.h"
-#include "nvim/syntax.h"
+#include "nvim/ascii.h"
+#include "nvim/buffer.h"
#include "nvim/charset.h"
#include "nvim/cursor_shape.h"
#include "nvim/eval.h"
@@ -23,39 +22,40 @@
#include "nvim/ex_docmd.h"
#include "nvim/fileio.h"
#include "nvim/fold.h"
+#include "nvim/garray.h"
#include "nvim/hashtab.h"
#include "nvim/highlight.h"
#include "nvim/indent_c.h"
+#include "nvim/keymap.h"
+#include "nvim/macros.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/keymap.h"
-#include "nvim/garray.h"
#include "nvim/option.h"
+#include "nvim/os/os.h"
+#include "nvim/os/time.h"
#include "nvim/os_unix.h"
#include "nvim/path.h"
-#include "nvim/macros.h"
#include "nvim/regexp.h"
#include "nvim/screen.h"
#include "nvim/sign.h"
#include "nvim/strings.h"
+#include "nvim/syntax.h"
#include "nvim/syntax_defs.h"
#include "nvim/terminal.h"
#include "nvim/ui.h"
-#include "nvim/os/os.h"
-#include "nvim/os/time.h"
-#include "nvim/buffer.h"
+#include "nvim/vim.h"
static bool did_syntax_onoff = false;
/// Structure that stores information about a highlight group.
/// The ID of a highlight group is also called group ID. It is the index in
/// the highlight_ga array PLUS ONE.
-struct hl_group {
- char_u *sg_name; ///< highlight group name
- char_u *sg_name_u; ///< uppercase of sg_name
+typedef struct hl_group {
+ char_u *sg_name; ///< highlight group name
+ char *sg_name_u; ///< uppercase of sg_name
bool sg_cleared; ///< "hi clear" was used
int sg_attr; ///< Screen attr @see ATTR_ENTRY
int sg_link; ///< link to this highlight group ID
@@ -80,7 +80,7 @@ struct hl_group {
char *sg_rgb_sp_name; ///< RGB special color name
int sg_blend; ///< blend level (0-100 inclusive), -1 if unset
-};
+} HlGroup;
/// \addtogroup SG_SET
/// @{
@@ -91,28 +91,29 @@ struct hl_group {
// builtin |highlight-groups|
static garray_T highlight_ga = GA_EMPTY_INIT_VALUE;
+Map(cstr_t, int) highlight_unames = MAP_INIT;
-static inline struct hl_group * HL_TABLE(void)
+static inline struct hl_group *HL_TABLE(void)
{
return ((struct hl_group *)((highlight_ga.ga_data)));
}
-#define MAX_HL_ID 20000 /* maximum value for a highlight ID. */
+#define MAX_HL_ID 20000 // maximum value for a highlight ID.
-/* different types of offsets that are possible */
-#define SPO_MS_OFF 0 /* match start offset */
-#define SPO_ME_OFF 1 /* match end offset */
-#define SPO_HS_OFF 2 /* highl. start offset */
-#define SPO_HE_OFF 3 /* highl. end offset */
-#define SPO_RS_OFF 4 /* region start offset */
-#define SPO_RE_OFF 5 /* region end offset */
-#define SPO_LC_OFF 6 /* leading context offset */
+// different types of offsets that are possible
+#define SPO_MS_OFF 0 // match start offset
+#define SPO_ME_OFF 1 // match end offset
+#define SPO_HS_OFF 2 // highl. start offset
+#define SPO_HE_OFF 3 // highl. end offset
+#define SPO_RS_OFF 4 // region start offset
+#define SPO_RE_OFF 5 // region end offset
+#define SPO_LC_OFF 6 // leading context offset
#define SPO_COUNT 7
-/* Flags to indicate an additional string for highlight name completion. */
-static int include_none = 0; /* when 1 include "nvim/None" */
-static int include_default = 0; /* when 1 include "nvim/default" */
-static int include_link = 0; /* when 2 include "nvim/link" and "clear" */
+// Flags to indicate an additional string for highlight name completion.
+static int include_none = 0; // when 1 include "nvim/None"
+static int include_default = 0; // when 1 include "nvim/default"
+static int include_link = 0; // when 2 include "nvim/link" and "clear"
/// The "term", "cterm" and "gui" arguments can be any combination of the
/// following names, separated by commas (but no spaces!).
@@ -214,12 +215,12 @@ typedef struct {
proftime_T slowest;
proftime_T average;
int id;
- char_u *pattern;
+ char_u *pattern;
} time_entry_T;
struct name_list {
int flag;
- char *name;
+ char *name;
};
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -227,40 +228,40 @@ struct name_list {
#endif
static char *(spo_name_tab[SPO_COUNT]) =
-{"ms=", "me=", "hs=", "he=", "rs=", "re=", "lc="};
+{ "ms=", "me=", "hs=", "he=", "rs=", "re=", "lc=" };
/* The sp_off_flags are computed like this:
* offset from the start of the matched text: (1 << SPO_XX_OFF)
- * offset from the end of the matched text: (1 << (SPO_XX_OFF + SPO_COUNT))
+ * offset from the end of the matched text: (1 << (SPO_XX_OFF + SPO_COUNT))
* When both are present, only one is used.
*/
-#define SPTYPE_MATCH 1 /* match keyword with this group ID */
-#define SPTYPE_START 2 /* match a regexp, start of item */
-#define SPTYPE_END 3 /* match a regexp, end of item */
-#define SPTYPE_SKIP 4 /* match a regexp, skip within item */
+#define SPTYPE_MATCH 1 // match keyword with this group ID
+#define SPTYPE_START 2 // match a regexp, start of item
+#define SPTYPE_END 3 // match a regexp, end of item
+#define SPTYPE_SKIP 4 // match a regexp, skip within item
#define SYN_ITEMS(buf) ((synpat_T *)((buf)->b_syn_patterns.ga_data))
-#define NONE_IDX -2 /* value of sp_sync_idx for "NONE" */
+#define NONE_IDX -2 // value of sp_sync_idx for "NONE"
/*
* Flags for b_syn_sync_flags:
*/
-#define SF_CCOMMENT 0x01 /* sync on a C-style comment */
-#define SF_MATCH 0x02 /* sync by matching a pattern */
+#define SF_CCOMMENT 0x01 // sync on a C-style comment
+#define SF_MATCH 0x02 // sync by matching a pattern
#define SYN_STATE_P(ssp) ((bufstate_T *)((ssp)->ga_data))
-#define MAXKEYWLEN 80 /* maximum length of a keyword */
+#define MAXKEYWLEN 80 // maximum length of a keyword
/*
* The attributes of the syntax item that has been recognized.
*/
-static int current_attr = 0; /* attr of current syntax word */
-static int current_id = 0; /* ID of current char for syn_get_id() */
-static int current_trans_id = 0; /* idem, transparency removed */
+static int current_attr = 0; // attr of current syntax word
+static int current_id = 0; // ID of current char for syn_get_id()
+static int current_trans_id = 0; // idem, transparency removed
static int current_flags = 0;
static int current_seqnr = 0;
static int current_sub_char = 0;
@@ -268,9 +269,9 @@ static int current_sub_char = 0;
/*
* Methods of combining two clusters
*/
-#define CLUSTER_REPLACE 1 /* replace first list with second */
-#define CLUSTER_ADD 2 /* add second list to first */
-#define CLUSTER_SUBTRACT 3 /* subtract second list from first */
+#define CLUSTER_REPLACE 1 // replace first list with second
+#define CLUSTER_ADD 2 // add second list to first
+#define CLUSTER_SUBTRACT 3 // subtract second list from first
#define SYN_CLSTR(buf) ((syn_cluster_T *)((buf)->b_syn_clusters.ga_data))
@@ -282,12 +283,12 @@ static int current_sub_char = 0;
* 22000 - 22999 CONTAINED indicator (current_syn_inc_tag added)
* 23000 - 32767 cluster IDs (subtract SYNID_CLUSTER for the cluster ID)
*/
-#define SYNID_ALLBUT MAX_HL_ID /* syntax group ID for contains=ALLBUT */
-#define SYNID_TOP 21000 /* syntax group ID for contains=TOP */
-#define SYNID_CONTAINED 22000 /* syntax group ID for contains=CONTAINED */
-#define SYNID_CLUSTER 23000 /* first syntax group ID for clusters */
+#define SYNID_ALLBUT MAX_HL_ID // syntax group ID for contains=ALLBUT
+#define SYNID_TOP 21000 // syntax group ID for contains=TOP
+#define SYNID_CONTAINED 22000 // syntax group ID for contains=CONTAINED
+#define SYNID_CLUSTER 23000 // first syntax group ID for clusters
-#define MAX_SYN_INC_TAG 999 /* maximum before the above overflow */
+#define MAX_SYN_INC_TAG 999 // maximum before the above overflow
#define MAX_CLUSTER_ID (32767 - SYNID_CLUSTER)
/*
@@ -333,7 +334,7 @@ static char msg_no_items[] = N_("No Syntax items defined for this buffer");
// valid of si_cont_list for containing all but contained groups
#define ID_LIST_ALL (int16_t *)-1
-static int next_seqnr = 1; /* value to use for si_seqnr */
+static int next_seqnr = 1; // value to use for si_seqnr
/*
* The next possible match in the current line for any pattern is remembered,
@@ -342,15 +343,15 @@ static int next_seqnr = 1; /* value to use for si_seqnr */
* If next_match_col == MAXCOL, no match found in this line.
* (All end positions have the column of the char after the end)
*/
-static int next_match_col; /* column for start of next match */
-static lpos_T next_match_m_endpos; /* position for end of next match */
-static lpos_T next_match_h_startpos; /* pos. for highl. start of next match */
-static lpos_T next_match_h_endpos; /* pos. for highl. end of next match */
-static int next_match_idx; /* index of matched item */
-static long next_match_flags; /* flags for next match */
-static lpos_T next_match_eos_pos; /* end of start pattn (start region) */
-static lpos_T next_match_eoe_pos; /* pos. for end of end pattern */
-static int next_match_end_idx; /* ID of group for end pattn or zero */
+static int next_match_col; // column for start of next match
+static lpos_T next_match_m_endpos; // position for end of next match
+static lpos_T next_match_h_startpos; // pos. for highl. start of next match
+static lpos_T next_match_h_endpos; // pos. for highl. end of next match
+static int next_match_idx; // index of matched item
+static long next_match_flags; // flags for next match
+static lpos_T next_match_eos_pos; // end of start pattn (start region)
+static lpos_T next_match_eoe_pos; // pos. for end of end pattern
+static int next_match_end_idx; // ID of group for end pattn or zero
static reg_extmatch_T *next_match_extmatch = NULL;
/*
@@ -364,25 +365,25 @@ static reg_extmatch_T *next_match_extmatch = NULL;
* The current state (within the line) of the recognition engine.
* When current_state.ga_itemsize is 0 the current state is invalid.
*/
-static win_T *syn_win; // current window for highlighting
-static buf_T *syn_buf; // current buffer for highlighting
-static synblock_T *syn_block; // current buffer for highlighting
-static proftime_T *syn_tm; // timeout limit
-static linenr_T current_lnum = 0; // lnum of current state
-static colnr_T current_col = 0; // column of current state
-static int current_state_stored = 0; // TRUE if stored current state
- // after setting current_finished
-static int current_finished = 0; // current line has been finished
-static garray_T current_state // current stack of state_items
+static win_T *syn_win; // current window for highlighting
+static buf_T *syn_buf; // current buffer for highlighting
+static synblock_T *syn_block; // current buffer for highlighting
+static proftime_T *syn_tm; // timeout limit
+static linenr_T current_lnum = 0; // lnum of current state
+static colnr_T current_col = 0; // column of current state
+static bool current_state_stored = false; // true if stored current state
+ // after setting current_finished
+static bool current_finished = false; // current line has been finished
+static garray_T current_state // current stack of state_items
= GA_EMPTY_INIT_VALUE;
-static int16_t *current_next_list = NULL; // when non-zero, nextgroup list
-static int current_next_flags = 0; // flags for current_next_list
-static int current_line_id = 0; // unique number for current line
+static int16_t *current_next_list = NULL; // when non-zero, nextgroup list
+static int current_next_flags = 0; // flags for current_next_list
+static int current_line_id = 0; // unique number for current line
#define CUR_STATE(idx) ((stateitem_T *)(current_state.ga_data))[idx]
-static int syn_time_on = FALSE;
-# define IF_SYN_TIME(p) (p)
+static bool syn_time_on = false;
+#define IF_SYN_TIME(p) (p)
// Set the timeout used for syntax highlighting.
// Use NULL to reset, no timeout.
@@ -395,19 +396,19 @@ void syn_set_timeout(proftime_T *tm)
* Start the syntax recognition for a line. This function is normally called
* from the screen updating, once for each displayed line.
* The buffer is remembered in syn_buf, because get_syntax_attr() doesn't get
- * it. Careful: curbuf and curwin are likely to point to another buffer and
+ * it. Careful: curbuf and curwin are likely to point to another buffer and
* window.
*/
void syntax_start(win_T *wp, linenr_T lnum)
{
- synstate_T *p;
- synstate_T *last_valid = NULL;
- synstate_T *last_min_valid = NULL;
- synstate_T *sp, *prev = NULL;
+ synstate_T *p;
+ synstate_T *last_valid = NULL;
+ synstate_T *last_min_valid = NULL;
+ synstate_T *sp, *prev = NULL;
linenr_T parsed_lnum;
linenr_T first_stored;
int dist;
- static int changedtick = 0; /* remember the last change ID */
+ static int changedtick = 0; // remember the last change ID
current_sub_char = NUL;
@@ -430,8 +431,9 @@ void syntax_start(win_T *wp, linenr_T lnum)
* Allocate syntax stack when needed.
*/
syn_stack_alloc();
- if (syn_block->b_sst_array == NULL)
- return; /* out of memory */
+ if (syn_block->b_sst_array == NULL) {
+ return; // out of memory
+ }
syn_block->b_sst_lasttick = display_tick;
/*
@@ -451,29 +453,33 @@ void syntax_start(win_T *wp, linenr_T lnum)
* state (this happens very often!). Otherwise invalidate
* current_state and figure it out below.
*/
- if (current_lnum != lnum)
+ if (current_lnum != lnum) {
invalidate_current_state();
- } else
+ }
+ } else {
invalidate_current_state();
+ }
/*
* Try to synchronize from a saved state in b_sst_array[].
* Only do this if lnum is not before and not to far beyond a saved state.
*/
if (INVALID_STATE(&current_state) && syn_block->b_sst_array != NULL) {
- /* Find last valid saved state before start_lnum. */
+ // Find last valid saved state before start_lnum.
for (p = syn_block->b_sst_first; p != NULL; p = p->sst_next) {
if (p->sst_lnum > lnum) {
break;
}
if (p->sst_change_lnum == 0) {
last_valid = p;
- if (p->sst_lnum >= lnum - syn_block->b_syn_sync_minlines)
+ if (p->sst_lnum >= lnum - syn_block->b_syn_sync_minlines) {
last_min_valid = p;
+ }
}
}
- if (last_min_valid != NULL)
+ if (last_min_valid != NULL) {
load_current_state(last_min_valid);
+ }
}
/*
@@ -482,24 +488,27 @@ void syntax_start(win_T *wp, linenr_T lnum)
*/
if (INVALID_STATE(&current_state)) {
syn_sync(wp, lnum, last_valid);
- if (current_lnum == 1)
- /* First line is always valid, no matter "minlines". */
+ if (current_lnum == 1) {
+ // First line is always valid, no matter "minlines".
first_stored = 1;
- else
+ } else {
/* Need to parse "minlines" lines before state can be considered
* valid to store. */
first_stored = current_lnum + syn_block->b_syn_sync_minlines;
- } else
+ }
+ } else {
first_stored = current_lnum;
+ }
/*
* Advance from the sync point or saved state until the current line.
* Save some entries for syncing with later on.
*/
- if (syn_block->b_sst_len <= Rows)
+ if (syn_block->b_sst_len <= Rows) {
dist = 999999;
- else
+ } else {
dist = syn_buf->b_ml.ml_line_count / (syn_block->b_sst_len - Rows) + 1;
+ }
while (current_lnum < lnum) {
syn_start_line();
(void)syn_finish_line(false);
@@ -511,26 +520,30 @@ void syntax_start(win_T *wp, linenr_T lnum)
/* Check if the saved state entry is for the current line and is
* equal to the current state. If so, then validate all saved
* states that depended on a change before the parsed line. */
- if (prev == NULL)
+ if (prev == NULL) {
prev = syn_stack_find_entry(current_lnum - 1);
- if (prev == NULL)
+ }
+ if (prev == NULL) {
sp = syn_block->b_sst_first;
- else
+ } else {
sp = prev;
- while (sp != NULL && sp->sst_lnum < current_lnum)
+ }
+ while (sp != NULL && sp->sst_lnum < current_lnum) {
sp = sp->sst_next;
+ }
if (sp != NULL
&& sp->sst_lnum == current_lnum
&& syn_stack_equal(sp)) {
parsed_lnum = current_lnum;
prev = sp;
while (sp != NULL && sp->sst_change_lnum <= parsed_lnum) {
- if (sp->sst_lnum <= lnum)
- /* valid state before desired line, use this one */
+ if (sp->sst_lnum <= lnum) {
+ // valid state before desired line, use this one
prev = sp;
- else if (sp->sst_change_lnum == 0)
- /* past saved states depending on change, break here. */
+ } else if (sp->sst_change_lnum == 0) {
+ // past saved states depending on change, break here.
break;
+ }
sp->sst_change_lnum = 0;
sp = sp->sst_next;
}
@@ -541,8 +554,9 @@ void syntax_start(win_T *wp, linenr_T lnum)
* saved state. But only when parsed at least 'minlines'. */
else if (prev == NULL
|| current_lnum == lnum
- || current_lnum >= prev->sst_lnum + dist)
+ || current_lnum >= prev->sst_lnum + dist) {
prev = store_current_state();
+ }
}
/* This can take a long time: break when CTRL-C pressed. The current
@@ -564,7 +578,7 @@ void syntax_start(win_T *wp, linenr_T lnum)
static void clear_syn_state(synstate_T *p)
{
if (p->sst_stacksize > SST_FIX_STATES) {
-# define UNREF_BUFSTATE_EXTMATCH(bs) unref_extmatch((bs)->bs_extmatch)
+#define UNREF_BUFSTATE_EXTMATCH(bs) unref_extmatch((bs)->bs_extmatch)
GA_DEEP_CLEAR(&(p->sst_union.sst_ga), bufstate_T, UNREF_BUFSTATE_EXTMATCH);
} else {
for (int i = 0; i < p->sst_stacksize; i++) {
@@ -578,7 +592,7 @@ static void clear_syn_state(synstate_T *p)
*/
static void clear_current_state(void)
{
-# define UNREF_STATEITEM_EXTMATCH(si) unref_extmatch((si)->si_extmatch)
+#define UNREF_STATEITEM_EXTMATCH(si) unref_extmatch((si)->si_extmatch)
GA_DEEP_CLEAR(&current_state, stateitem_T, UNREF_STATEITEM_EXTMATCH);
}
@@ -593,8 +607,8 @@ static void clear_current_state(void)
*/
static void syn_sync(win_T *wp, linenr_T start_lnum, synstate_T *last_valid)
{
- buf_T *curbuf_save;
- win_T *curwin_save;
+ buf_T *curbuf_save;
+ win_T *curwin_save;
pos_T cursor_save;
int idx;
linenr_T lnum;
@@ -602,8 +616,8 @@ static void syn_sync(win_T *wp, linenr_T start_lnum, synstate_T *last_valid)
linenr_T break_lnum;
bool had_sync_point;
stateitem_T *cur_si;
- synpat_T *spp;
- char_u *line;
+ synpat_T *spp;
+ char_u *line;
int found_flags = 0;
int found_match_idx = 0;
linenr_T found_current_lnum = 0;
@@ -624,22 +638,25 @@ static void syn_sync(win_T *wp, linenr_T start_lnum, synstate_T *last_valid)
* where N is minlines * 1.5, or minlines * 2 if minlines is small.
* Watch out for overflow when minlines is MAXLNUM.
*/
- if (syn_block->b_syn_sync_minlines > start_lnum)
+ if (syn_block->b_syn_sync_minlines > start_lnum) {
start_lnum = 1;
- else {
- if (syn_block->b_syn_sync_minlines == 1)
+ } else {
+ if (syn_block->b_syn_sync_minlines == 1) {
lnum = 1;
- else if (syn_block->b_syn_sync_minlines < 10)
+ } else if (syn_block->b_syn_sync_minlines < 10) {
lnum = syn_block->b_syn_sync_minlines * 2;
- else
+ } else {
lnum = syn_block->b_syn_sync_minlines * 3 / 2;
+ }
if (syn_block->b_syn_sync_maxlines != 0
- && lnum > syn_block->b_syn_sync_maxlines)
+ && lnum > syn_block->b_syn_sync_maxlines) {
lnum = syn_block->b_syn_sync_maxlines;
- if (lnum >= start_lnum)
+ }
+ if (lnum >= start_lnum) {
start_lnum = 1;
- else
+ } else {
start_lnum -= lnum;
+ }
}
current_lnum = start_lnum;
@@ -659,12 +676,13 @@ static void syn_sync(win_T *wp, linenr_T start_lnum, synstate_T *last_valid)
*/
for (; start_lnum > 1; --start_lnum) {
line = ml_get(start_lnum - 1);
- if (*line == NUL || *(line + STRLEN(line) - 1) != '\\')
+ if (*line == NUL || *(line + STRLEN(line) - 1) != '\\') {
break;
+ }
}
current_lnum = start_lnum;
- /* set cursor to start of search */
+ // set cursor to start of search
cursor_save = wp->w_cursor;
wp->w_cursor.lnum = start_lnum;
wp->w_cursor.col = 0;
@@ -675,7 +693,7 @@ static void syn_sync(win_T *wp, linenr_T start_lnum, synstate_T *last_valid)
* Restrict the search for the end of a comment to b_syn_sync_maxlines.
*/
if (find_start_comment((int)syn_block->b_syn_sync_maxlines) != NULL) {
- for (idx = syn_block->b_syn_patterns.ga_len; --idx >= 0; )
+ for (idx = syn_block->b_syn_patterns.ga_len; --idx >= 0; ) {
if (SYN_ITEMS(syn_block)[idx].sp_syn.id
== syn_block->b_syn_sync_id
&& SYN_ITEMS(syn_block)[idx].sp_type == SPTYPE_START) {
@@ -684,9 +702,10 @@ static void syn_sync(win_T *wp, linenr_T start_lnum, synstate_T *last_valid)
update_si_attr(current_state.ga_len - 1);
break;
}
+ }
}
- /* restore cursor and buffer */
+ // restore cursor and buffer
wp->w_cursor = cursor_save;
curwin = curwin_save;
curbuf = curbuf_save;
@@ -696,17 +715,18 @@ static void syn_sync(win_T *wp, linenr_T start_lnum, synstate_T *last_valid)
*/
else if (syn_block->b_syn_sync_flags & SF_MATCH) {
if (syn_block->b_syn_sync_maxlines != 0
- && start_lnum > syn_block->b_syn_sync_maxlines)
+ && start_lnum > syn_block->b_syn_sync_maxlines) {
break_lnum = start_lnum - syn_block->b_syn_sync_maxlines;
- else
+ } else {
break_lnum = 0;
+ }
found_m_endpos.lnum = 0;
found_m_endpos.col = 0;
end_lnum = start_lnum;
lnum = start_lnum;
while (--lnum > break_lnum) {
- /* This can take a long time: break when CTRL-C pressed. */
+ // This can take a long time: break when CTRL-C pressed.
line_breakcheck();
if (got_int) {
invalidate_current_state();
@@ -714,7 +734,7 @@ static void syn_sync(win_T *wp, linenr_T start_lnum, synstate_T *last_valid)
break;
}
- /* Check if we have run into a valid saved state stack now. */
+ // Check if we have run into a valid saved state stack now.
if (last_valid != NULL && lnum == last_valid->sst_lnum) {
load_current_state(last_valid);
break;
@@ -723,8 +743,9 @@ static void syn_sync(win_T *wp, linenr_T start_lnum, synstate_T *last_valid)
/*
* Check if the previous line has the line-continuation pattern.
*/
- if (lnum > 1 && syn_match_linecont(lnum - 1))
+ if (lnum > 1 && syn_match_linecont(lnum - 1)) {
continue;
+ }
/*
* Start with nothing on the state stack
@@ -740,12 +761,12 @@ static void syn_sync(win_T *wp, linenr_T start_lnum, synstate_T *last_valid)
if (had_sync_point && current_state.ga_len) {
cur_si = &CUR_STATE(current_state.ga_len - 1);
if (cur_si->si_m_endpos.lnum > start_lnum) {
- /* ignore match that goes to after where started */
+ // ignore match that goes to after where started
current_lnum = end_lnum;
break;
}
if (cur_si->si_idx < 0) {
- /* Cannot happen? */
+ // Cannot happen?
found_flags = 0;
found_match_idx = KEYWORD_IDX;
} else {
@@ -763,23 +784,27 @@ static void syn_sync(win_T *wp, linenr_T start_lnum, synstate_T *last_valid)
if (found_m_endpos.lnum > current_lnum) {
current_lnum = found_m_endpos.lnum;
current_col = found_m_endpos.col;
- if (current_lnum >= end_lnum)
+ if (current_lnum >= end_lnum) {
break;
- } else if (found_m_endpos.col > current_col)
+ }
+ } else if (found_m_endpos.col > current_col) {
current_col = found_m_endpos.col;
- else
+ } else {
++current_col;
+ }
/* syn_current_attr() will have skipped the check for
* an item that ends here, need to do that now. Be
* careful not to go past the NUL. */
prev_current_col = current_col;
- if (syn_getcurline()[current_col] != NUL)
+ if (syn_getcurline()[current_col] != NUL) {
++current_col;
+ }
check_state_ends();
current_col = prev_current_col;
- } else
+ } else {
break;
+ }
}
}
@@ -809,7 +834,7 @@ static void syn_sync(win_T *wp, linenr_T start_lnum, synstate_T *last_valid)
cur_si = &CUR_STATE(current_state.ga_len - 1);
cur_si->si_h_startpos.lnum = found_current_lnum;
cur_si->si_h_startpos.col = found_current_col;
- update_si_end(cur_si, (int)current_col, TRUE);
+ update_si_end(cur_si, (int)current_col, true);
check_keepend();
}
current_col = found_m_endpos.col;
@@ -827,7 +852,7 @@ static void syn_sync(win_T *wp, linenr_T start_lnum, synstate_T *last_valid)
invalidate_current_state();
}
- /* Ran into start of the file or exceeded maximum number of lines */
+ // Ran into start of the file or exceeded maximum number of lines
if (lnum <= break_lnum) {
invalidate_current_state();
current_lnum = break_lnum + 1;
@@ -880,7 +905,7 @@ static int syn_match_linecont(linenr_T lnum)
*/
static void syn_start_line(void)
{
- current_finished = FALSE;
+ current_finished = false;
current_col = 0;
/*
@@ -888,7 +913,7 @@ static void syn_start_line(void)
* previous line and regions that have "keepend".
*/
if (!GA_EMPTY(&current_state)) {
- syn_update_ends(TRUE);
+ syn_update_ends(true);
check_state_ends();
}
@@ -897,15 +922,13 @@ static void syn_start_line(void)
next_seqnr = 1;
}
-/*
- * Check for items in the stack that need their end updated.
- * When "startofline" is TRUE the last item is always updated.
- * When "startofline" is FALSE the item with "keepend" is forcefully updated.
- */
-static void syn_update_ends(int startofline)
+/// Check for items in the stack that need their end updated.
+///
+/// @param startofline if true the last item is always updated.
+/// if false the item with "keepend" is forcefully updated.
+static void syn_update_ends(bool startofline)
{
stateitem_T *cur_si;
- int seen_keepend;
if (startofline) {
/* Check for a match carried over from a previous line with a
@@ -935,25 +958,30 @@ static void syn_update_ends(int startofline)
* Then check for items ending in column 0.
*/
int i = current_state.ga_len - 1;
- if (keepend_level >= 0)
- for (; i > keepend_level; --i)
- if (CUR_STATE(i).si_flags & HL_EXTEND)
+ if (keepend_level >= 0) {
+ for (; i > keepend_level; --i) {
+ if (CUR_STATE(i).si_flags & HL_EXTEND) {
break;
+ }
+ }
+ }
- seen_keepend = FALSE;
- for (; i < current_state.ga_len; ++i) {
+ bool seen_keepend = false;
+ for (; i < current_state.ga_len; i++) {
cur_si = &CUR_STATE(i);
if ((cur_si->si_flags & HL_KEEPEND)
|| (seen_keepend && !startofline)
|| (i == current_state.ga_len - 1 && startofline)) {
- cur_si->si_h_startpos.col = 0; /* start highl. in col 0 */
+ cur_si->si_h_startpos.col = 0; // start highl. in col 0
cur_si->si_h_startpos.lnum = current_lnum;
- if (!(cur_si->si_flags & HL_MATCHCONT))
+ if (!(cur_si->si_flags & HL_MATCHCONT)) {
update_si_end(cur_si, (int)current_col, !startofline);
+ }
- if (!startofline && (cur_si->si_flags & HL_KEEPEND))
- seen_keepend = TRUE;
+ if (!startofline && (cur_si->si_flags & HL_KEEPEND)) {
+ seen_keepend = true;
+ }
}
}
check_keepend();
@@ -997,7 +1025,7 @@ static void syn_update_ends(int startofline)
static void syn_stack_free_block(synblock_T *block)
{
- synstate_T *p;
+ synstate_T *p;
if (block->b_sst_array != NULL) {
for (p = block->b_sst_first; p != NULL; p = p->sst_next) {
@@ -1016,7 +1044,7 @@ void syn_stack_free_all(synblock_T *block)
{
syn_stack_free_block(block);
- /* When using "syntax" fold method, must update all folds. */
+ // When using "syntax" fold method, must update all folds.
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
if (wp->w_s == block && foldmethodIsSyntax(wp)) {
foldUpdateAll(wp);
@@ -1033,31 +1061,35 @@ void syn_stack_free_all(synblock_T *block)
static void syn_stack_alloc(void)
{
long len;
- synstate_T *to, *from;
- synstate_T *sstp;
+ synstate_T *to, *from;
+ synstate_T *sstp;
len = syn_buf->b_ml.ml_line_count / SST_DIST + Rows * 2;
- if (len < SST_MIN_ENTRIES)
+ if (len < SST_MIN_ENTRIES) {
len = SST_MIN_ENTRIES;
- else if (len > SST_MAX_ENTRIES)
+ } else if (len > SST_MAX_ENTRIES) {
len = SST_MAX_ENTRIES;
+ }
if (syn_block->b_sst_len > len * 2 || syn_block->b_sst_len < len) {
- /* Allocate 50% too much, to avoid reallocating too often. */
+ // Allocate 50% too much, to avoid reallocating too often.
len = syn_buf->b_ml.ml_line_count;
len = (len + len / 2) / SST_DIST + Rows * 2;
- if (len < SST_MIN_ENTRIES)
+ if (len < SST_MIN_ENTRIES) {
len = SST_MIN_ENTRIES;
- else if (len > SST_MAX_ENTRIES)
+ } else if (len > SST_MAX_ENTRIES) {
len = SST_MAX_ENTRIES;
+ }
if (syn_block->b_sst_array != NULL) {
/* When shrinking the array, cleanup the existing stack.
* Make sure that all valid entries fit in the new array. */
while (syn_block->b_sst_len - syn_block->b_sst_freecount + 2 > len
- && syn_stack_cleanup())
+ && syn_stack_cleanup()) {
;
- if (len < syn_block->b_sst_len - syn_block->b_sst_freecount + 2)
+ }
+ if (len < syn_block->b_sst_len - syn_block->b_sst_freecount + 2) {
len = syn_block->b_sst_len - syn_block->b_sst_freecount + 2;
+ }
}
assert(len >= 0);
@@ -1065,7 +1097,7 @@ static void syn_stack_alloc(void)
to = sstp - 1;
if (syn_block->b_sst_array != NULL) {
- /* Move the states from the old array to the new one. */
+ // Move the states from the old array to the new one.
for (from = syn_block->b_sst_first; from != NULL;
from = from->sst_next) {
++to;
@@ -1082,10 +1114,11 @@ static void syn_stack_alloc(void)
syn_block->b_sst_freecount = len;
}
- /* Create the list of free entries. */
+ // Create the list of free entries.
syn_block->b_sst_firstfree = to + 1;
- while (++to < sstp + len)
+ while (++to < sstp + len) {
to->sst_next = to + 1;
+ }
(sstp + len - 1)->sst_next = NULL;
xfree(syn_block->b_sst_array);
@@ -1113,7 +1146,7 @@ void syn_stack_apply_changes(buf_T *buf)
static void syn_stack_apply_changes_block(synblock_T *block, buf_T *buf)
{
- synstate_T *p, *prev, *np;
+ synstate_T *p, *prev, *np;
linenr_T n;
prev = NULL;
@@ -1121,12 +1154,13 @@ static void syn_stack_apply_changes_block(synblock_T *block, buf_T *buf)
if (p->sst_lnum + block->b_syn_sync_linebreaks > buf->b_mod_top) {
n = p->sst_lnum + buf->b_mod_xlines;
if (n <= buf->b_mod_bot) {
- /* this state is inside the changed area, remove it */
+ // this state is inside the changed area, remove it
np = p->sst_next;
- if (prev == NULL)
+ if (prev == NULL) {
block->b_sst_first = np;
- else
+ } else {
prev->sst_next = np;
+ }
syn_stack_free_entry(block, p);
p = np;
continue;
@@ -1135,14 +1169,16 @@ static void syn_stack_apply_changes_block(synblock_T *block, buf_T *buf)
* that needs to be parsed before this entry can be made valid
* again. */
if (p->sst_change_lnum != 0 && p->sst_change_lnum > buf->b_mod_top) {
- if (p->sst_change_lnum + buf->b_mod_xlines > buf->b_mod_top)
+ if (p->sst_change_lnum + buf->b_mod_xlines > buf->b_mod_top) {
p->sst_change_lnum += buf->b_mod_xlines;
- else
+ } else {
p->sst_change_lnum = buf->b_mod_top;
+ }
}
if (p->sst_change_lnum == 0
- || p->sst_change_lnum < buf->b_mod_bot)
+ || p->sst_change_lnum < buf->b_mod_bot) {
p->sst_change_lnum = buf->b_mod_bot;
+ }
p->sst_lnum = n;
}
@@ -1151,27 +1187,26 @@ static void syn_stack_apply_changes_block(synblock_T *block, buf_T *buf)
}
}
-/*
- * Reduce the number of entries in the state stack for syn_buf.
- * Returns TRUE if at least one entry was freed.
- */
-static int syn_stack_cleanup(void)
+/// Reduce the number of entries in the state stack for syn_buf.
+///
+/// @return true if at least one entry was freed.
+static bool syn_stack_cleanup(void)
{
- synstate_T *p, *prev;
+ synstate_T *p, *prev;
disptick_T tick;
- int above;
int dist;
- int retval = FALSE;
+ bool retval = false;
if (syn_block->b_sst_first == NULL) {
return retval;
}
- /* Compute normal distance between non-displayed entries. */
- if (syn_block->b_sst_len <= Rows)
+ // Compute normal distance between non-displayed entries.
+ if (syn_block->b_sst_len <= Rows) {
dist = 999999;
- else
+ } else {
dist = syn_buf->b_ml.ml_line_count / (syn_block->b_sst_len - Rows) + 1;
+ }
/*
* Go through the list to find the "tick" for the oldest entry that can
@@ -1179,16 +1214,18 @@ static int syn_stack_cleanup(void)
* "b_sst_lasttick" (the display tick wraps around).
*/
tick = syn_block->b_sst_lasttick;
- above = FALSE;
+ bool above = false;
prev = syn_block->b_sst_first;
for (p = prev->sst_next; p != NULL; prev = p, p = p->sst_next) {
if (prev->sst_lnum + dist > p->sst_lnum) {
if (p->sst_tick > syn_block->b_sst_lasttick) {
- if (!above || p->sst_tick < tick)
+ if (!above || p->sst_tick < tick) {
tick = p->sst_tick;
- above = TRUE;
- } else if (!above && p->sst_tick < tick)
+ }
+ above = true;
+ } else if (!above && p->sst_tick < tick) {
tick = p->sst_tick;
+ }
}
}
@@ -1199,11 +1236,11 @@ static int syn_stack_cleanup(void)
prev = syn_block->b_sst_first;
for (p = prev->sst_next; p != NULL; prev = p, p = p->sst_next) {
if (p->sst_tick == tick && prev->sst_lnum + dist > p->sst_lnum) {
- /* Move this entry from used list to free list */
+ // Move this entry from used list to free list
prev->sst_next = p->sst_next;
syn_stack_free_entry(syn_block, p);
p = prev;
- retval = TRUE;
+ retval = true;
}
}
return retval;
@@ -1227,14 +1264,16 @@ static void syn_stack_free_entry(synblock_T *block, synstate_T *p)
*/
static synstate_T *syn_stack_find_entry(linenr_T lnum)
{
- synstate_T *p, *prev;
+ synstate_T *p, *prev;
prev = NULL;
for (p = syn_block->b_sst_first; p != NULL; prev = p, p = p->sst_next) {
- if (p->sst_lnum == lnum)
+ if (p->sst_lnum == lnum) {
return p;
- if (p->sst_lnum > lnum)
+ }
+ if (p->sst_lnum > lnum) {
break;
+ }
}
return prev;
}
@@ -1246,10 +1285,10 @@ static synstate_T *syn_stack_find_entry(linenr_T lnum)
static synstate_T *store_current_state(void)
{
int i;
- synstate_T *p;
- bufstate_T *bp;
+ synstate_T *p;
+ bufstate_T *bp;
stateitem_T *cur_si;
- synstate_T *sp = syn_stack_find_entry(current_lnum);
+ synstate_T *sp = syn_stack_find_entry(current_lnum);
/*
* If the current state contains a start or end pattern that continues
@@ -1261,51 +1300,55 @@ static synstate_T *store_current_state(void)
|| cur_si->si_m_endpos.lnum >= current_lnum
|| cur_si->si_h_endpos.lnum >= current_lnum
|| (cur_si->si_end_idx
- && cur_si->si_eoe_pos.lnum >= current_lnum))
+ && cur_si->si_eoe_pos.lnum >= current_lnum)) {
break;
+ }
}
if (i >= 0) {
if (sp != NULL) {
- /* find "sp" in the list and remove it */
- if (syn_block->b_sst_first == sp)
- /* it's the first entry */
+ // find "sp" in the list and remove it
+ if (syn_block->b_sst_first == sp) {
+ // it's the first entry
syn_block->b_sst_first = sp->sst_next;
- else {
- /* find the entry just before this one to adjust sst_next */
- for (p = syn_block->b_sst_first; p != NULL; p = p->sst_next)
- if (p->sst_next == sp)
+ } else {
+ // find the entry just before this one to adjust sst_next
+ for (p = syn_block->b_sst_first; p != NULL; p = p->sst_next) {
+ if (p->sst_next == sp) {
break;
- if (p != NULL) /* just in case */
+ }
+ }
+ if (p != NULL) { // just in case
p->sst_next = sp->sst_next;
+ }
}
syn_stack_free_entry(syn_block, sp);
sp = NULL;
}
- } else if (sp == NULL || sp->sst_lnum != current_lnum) {
+ } else if (sp == NULL || sp->sst_lnum != current_lnum) {
/*
* Add a new entry
*/
- /* If no free items, cleanup the array first. */
+ // If no free items, cleanup the array first.
if (syn_block->b_sst_freecount == 0) {
(void)syn_stack_cleanup();
- /* "sp" may have been moved to the freelist now */
+ // "sp" may have been moved to the freelist now
sp = syn_stack_find_entry(current_lnum);
}
- /* Still no free items? Must be a strange problem... */
- if (syn_block->b_sst_freecount == 0)
+ // Still no free items? Must be a strange problem...
+ if (syn_block->b_sst_freecount == 0) {
sp = NULL;
- else {
+ } else {
/* Take the first item from the free list and put it in the used
* list, after *sp */
p = syn_block->b_sst_firstfree;
syn_block->b_sst_firstfree = p->sst_next;
--syn_block->b_sst_freecount;
if (sp == NULL) {
- /* Insert in front of the list */
+ // Insert in front of the list
p->sst_next = syn_block->b_sst_first;
syn_block->b_sst_first = p;
} else {
- /* insert in list after *sp */
+ // insert in list after *sp
p->sst_next = sp->sst_next;
sp->sst_next = p;
}
@@ -1315,7 +1358,7 @@ static synstate_T *store_current_state(void)
}
}
if (sp != NULL) {
- /* When overwriting an existing state stack, clear it first */
+ // When overwriting an existing state stack, clear it first
clear_syn_state(sp);
sp->sst_stacksize = current_state.ga_len;
if (current_state.ga_len > SST_FIX_STATES) {
@@ -1325,8 +1368,9 @@ static synstate_T *store_current_state(void)
ga_grow(&sp->sst_union.sst_ga, current_state.ga_len);
sp->sst_union.sst_ga.ga_len = current_state.ga_len;
bp = SYN_STATE_P(&(sp->sst_union.sst_ga));
- } else
+ } else {
bp = sp->sst_union.sst_stack;
+ }
for (i = 0; i < sp->sst_stacksize; ++i) {
bp[i].bs_idx = CUR_STATE(i).si_idx;
bp[i].bs_flags = CUR_STATE(i).si_flags;
@@ -1339,7 +1383,7 @@ static synstate_T *store_current_state(void)
sp->sst_tick = display_tick;
sp->sst_change_lnum = 0;
}
- current_state_stored = TRUE;
+ current_state_stored = true;
return sp;
}
@@ -1349,32 +1393,35 @@ static synstate_T *store_current_state(void)
static void load_current_state(synstate_T *from)
{
int i;
- bufstate_T *bp;
+ bufstate_T *bp;
clear_current_state();
validate_current_state();
keepend_level = -1;
if (from->sst_stacksize) {
ga_grow(&current_state, from->sst_stacksize);
- if (from->sst_stacksize > SST_FIX_STATES)
+ if (from->sst_stacksize > SST_FIX_STATES) {
bp = SYN_STATE_P(&(from->sst_union.sst_ga));
- else
+ } else {
bp = from->sst_union.sst_stack;
+ }
for (i = 0; i < from->sst_stacksize; ++i) {
CUR_STATE(i).si_idx = bp[i].bs_idx;
CUR_STATE(i).si_flags = bp[i].bs_flags;
CUR_STATE(i).si_seqnr = bp[i].bs_seqnr;
CUR_STATE(i).si_cchar = bp[i].bs_cchar;
CUR_STATE(i).si_extmatch = ref_extmatch(bp[i].bs_extmatch);
- if (keepend_level < 0 && (CUR_STATE(i).si_flags & HL_KEEPEND))
+ if (keepend_level < 0 && (CUR_STATE(i).si_flags & HL_KEEPEND)) {
keepend_level = i;
+ }
CUR_STATE(i).si_ends = FALSE;
CUR_STATE(i).si_m_lnum = 0;
- if (CUR_STATE(i).si_idx >= 0)
+ if (CUR_STATE(i).si_idx >= 0) {
CUR_STATE(i).si_next_list =
(SYN_ITEMS(syn_block)[CUR_STATE(i).si_idx]).sp_next_list;
- else
+ } else {
CUR_STATE(i).si_next_list = NULL;
+ }
update_si_attr(i);
}
current_state.ga_len = from->sst_stacksize;
@@ -1384,32 +1431,33 @@ static void load_current_state(synstate_T *from)
current_lnum = from->sst_lnum;
}
-/*
- * Compare saved state stack "*sp" with the current state.
- * Return TRUE when they are equal.
- */
-static int syn_stack_equal(synstate_T *sp)
+/// Compare saved state stack "*sp" with the current state.
+///
+/// @return true when they are equal.
+static bool syn_stack_equal(synstate_T *sp)
{
- bufstate_T *bp;
- reg_extmatch_T *six, *bsx;
+ bufstate_T *bp;
+ reg_extmatch_T *six, *bsx;
- /* First a quick check if the stacks have the same size end nextlist. */
+ // First a quick check if the stacks have the same size end nextlist.
if (sp->sst_stacksize != current_state.ga_len
|| sp->sst_next_list != current_next_list) {
- return FALSE;
+ return false;
}
- /* Need to compare all states on both stacks. */
- if (sp->sst_stacksize > SST_FIX_STATES)
+ // Need to compare all states on both stacks.
+ if (sp->sst_stacksize > SST_FIX_STATES) {
bp = SYN_STATE_P(&(sp->sst_union.sst_ga));
- else
+ } else {
bp = sp->sst_union.sst_stack;
+ }
int i;
for (i = current_state.ga_len; --i >= 0; ) {
- /* If the item has another index the state is different. */
- if (bp[i].bs_idx != CUR_STATE(i).si_idx)
+ // If the item has another index the state is different.
+ if (bp[i].bs_idx != CUR_STATE(i).si_idx) {
break;
+ }
if (bp[i].bs_extmatch == CUR_STATE(i).si_extmatch) {
continue;
}
@@ -1420,8 +1468,9 @@ static int syn_stack_equal(synstate_T *sp)
six = CUR_STATE(i).si_extmatch;
/* If one of the extmatch pointers is NULL the states are
* different. */
- if (bsx == NULL || six == NULL)
+ if (bsx == NULL || six == NULL) {
break;
+ }
int j;
for (j = 0; j < NSUBEXP; ++j) {
/* Check each referenced match string. They must all be
@@ -1440,13 +1489,15 @@ static int syn_stack_equal(synstate_T *sp)
}
}
}
- if (j != NSUBEXP)
+ if (j != NSUBEXP) {
break;
+ }
+ }
+ if (i < 0) {
+ return true;
}
- if (i < 0)
- return TRUE;
- return FALSE;
+ return false;
}
/*
@@ -1454,21 +1505,23 @@ static int syn_stack_equal(synstate_T *sp)
* this line depended on a change before it, it now depends on the line below
* the last parsed line.
* The window looks like this:
- * line which changed
- * displayed line
- * displayed line
+ * line which changed
+ * displayed line
+ * displayed line
* lnum -> line below window
*/
void syntax_end_parsing(linenr_T lnum)
{
- synstate_T *sp;
+ synstate_T *sp;
sp = syn_stack_find_entry(lnum);
- if (sp != NULL && sp->sst_lnum < lnum)
+ if (sp != NULL && sp->sst_lnum < lnum) {
sp = sp->sst_next;
+ }
- if (sp != NULL && sp->sst_change_lnum != 0)
+ if (sp != NULL && sp->sst_change_lnum != 0) {
sp->sst_change_lnum = lnum;
+ }
}
/*
@@ -1478,7 +1531,7 @@ void syntax_end_parsing(linenr_T lnum)
static void invalidate_current_state(void)
{
clear_current_state();
- current_state.ga_itemsize = 0; /* mark current_state invalid */
+ current_state.ga_itemsize = 0; // mark current_state invalid
current_next_list = NULL;
keepend_level = -1;
}
@@ -1489,15 +1542,14 @@ static void validate_current_state(void)
ga_set_growsize(&current_state, 3);
}
-/*
- * Return TRUE if the syntax at start of lnum changed since last time.
- * This will only be called just after get_syntax_attr() for the previous
- * line, to check if the next line needs to be redrawn too.
- */
-int syntax_check_changed(linenr_T lnum)
+/// This will only be called just after get_syntax_attr() for the previous
+/// line, to check if the next line needs to be redrawn too.
+///
+/// @return true if the syntax at start of lnum changed since last time.
+bool syntax_check_changed(linenr_T lnum)
{
- int retval = TRUE;
- synstate_T *sp;
+ bool retval = true;
+ synstate_T *sp;
/*
* Check the state stack when:
@@ -1519,8 +1571,9 @@ int syntax_check_changed(linenr_T lnum)
* Compare the current state with the previously saved state of
* the line.
*/
- if (syn_stack_equal(sp))
- retval = FALSE;
+ if (syn_stack_equal(sp)) {
+ retval = false;
+ }
/*
* Store the current state in b_sst_array[] for later use.
@@ -1533,16 +1586,13 @@ int syntax_check_changed(linenr_T lnum)
return retval;
}
-/*
- * Finish the current line.
- * This doesn't return any attributes, it only gets the state at the end of
- * the line. It can start anywhere in the line, as long as the current state
- * is valid.
- */
-static bool
-syn_finish_line(
- const bool syncing // called for syncing
-)
+/// Finish the current line.
+/// This doesn't return any attributes, it only gets the state at the end of
+/// the line. It can start anywhere in the line, as long as the current state
+/// is valid.
+///
+/// @param syncing called for syncing
+static bool syn_finish_line(const bool syncing)
{
while (!current_finished) {
(void)syn_current_attr(syncing, false, NULL, false);
@@ -1572,36 +1622,35 @@ syn_finish_line(
return false;
}
-/*
- * Return highlight attributes for next character.
- * Must first call syntax_start() once for the line.
- * "col" is normally 0 for the first use in a line, and increments by one each
- * time. It's allowed to skip characters and to stop before the end of the
- * line. But only a "col" after a previously used column is allowed.
- * When "can_spell" is not NULL set it to TRUE when spell-checking should be
- * done.
- */
-int
-get_syntax_attr(
- const colnr_T col,
- bool *const can_spell,
- const bool keep_state // keep state of char at "col"
-)
+/// Gets highlight attributes for next character.
+/// Must first call syntax_start() once for the line.
+/// "col" is normally 0 for the first use in a line, and increments by one each
+/// time. It's allowed to skip characters and to stop before the end of the
+/// line. But only a "col" after a previously used column is allowed.
+/// When "can_spell" is not NULL set it to TRUE when spell-checking should be
+/// done.
+///
+/// @param keep_state keep state of char at "col"
+///
+/// @return highlight attributes for next character.
+int get_syntax_attr(const colnr_T col, bool *const can_spell, const bool keep_state)
{
int attr = 0;
- if (can_spell != NULL)
+ if (can_spell != NULL) {
/* Default: Only do spelling when there is no @Spell cluster or when
* ":syn spell toplevel" was used. */
*can_spell = syn_block->b_syn_spell == SYNSPL_DEFAULT
? (syn_block->b_spell_cluster_id == 0)
: (syn_block->b_syn_spell == SYNSPL_TOP);
+ }
- /* check for out of memory situation */
- if (syn_block->b_sst_array == NULL)
+ // check for out of memory situation
+ if (syn_block->b_sst_array == NULL) {
return 0;
+ }
- /* After 'synmaxcol' the attribute is always zero. */
+ // After 'synmaxcol' the attribute is always zero.
if (syn_buf->b_p_smc > 0 && col >= (colnr_T)syn_buf->b_p_smc) {
clear_current_state();
current_id = 0;
@@ -1611,9 +1660,10 @@ get_syntax_attr(
return 0;
}
- /* Make sure current_state is valid */
- if (INVALID_STATE(&current_state))
+ // Make sure current_state is valid
+ if (INVALID_STATE(&current_state)) {
validate_current_state();
+ }
/*
* Skip from the current column to "col", get the attributes for "col".
@@ -1627,15 +1677,14 @@ get_syntax_attr(
return attr;
}
-/*
- * Get syntax attributes for current_lnum, current_col.
- */
-static int syn_current_attr(
- const bool syncing, // When true: called for syncing
- const bool displaying, // result will be displayed
- bool *const can_spell, // return: do spell checking
- const bool keep_state // keep syntax stack afterwards
-)
+/// Get syntax attributes for current_lnum, current_col.
+///
+/// @param syncing When true: called for syncing
+/// @param displaying result will be displayed
+/// @param can_spell return: do spell checking
+/// @param keep_state keep syntax stack afterwards
+static int syn_current_attr(const bool syncing, const bool displaying, bool *const can_spell,
+ const bool keep_state)
{
lpos_T endpos; // was: char_u *endp;
lpos_T hl_startpos; // was: int hl_startcol;
@@ -1654,9 +1703,9 @@ static int syn_current_attr(
regmmatch_T regmatch;
lpos_T pos;
reg_extmatch_T *cur_extmatch = NULL;
- char_u buf_chartab[32]; // chartab array for syn iskeyword
- char_u *line; // current line. NOTE: becomes invalid after
- // looking for a pattern match!
+ char_u buf_chartab[32]; // chartab array for syn iskeyword
+ char_u *line; // current line. NOTE: becomes invalid after
+ // looking for a pattern match!
// variables for zero-width matches that have a "nextgroup" argument
bool keep_next_list;
@@ -1677,15 +1726,15 @@ static int syn_current_attr(
(void)push_next_match();
}
- current_finished = TRUE;
- current_state_stored = FALSE;
+ current_finished = true;
+ current_state_stored = false;
return 0;
}
- /* if the current or next character is NUL, we will finish the line now */
+ // if the current or next character is NUL, we will finish the line now
if (line[current_col] == NUL || line[current_col + 1] == NUL) {
- current_finished = TRUE;
- current_state_stored = FALSE;
+ current_finished = true;
+ current_state_stored = false;
}
/*
@@ -1700,8 +1749,8 @@ static int syn_current_attr(
// Only check for keywords when not syncing and there are some.
const bool do_keywords = !syncing
- && (syn_block->b_keywtab.ht_used > 0
- || syn_block->b_keywtab_ic.ht_used > 0);
+ && (syn_block->b_keywtab.ht_used > 0
+ || syn_block->b_keywtab_ic.ht_used > 0);
/* Init the list of zero-width matches with a nextlist. This is used to
* avoid matching the same item in the same position twice. */
@@ -1727,23 +1776,25 @@ static int syn_current_attr(
* Always need to check for contained items if some item has the
* "containedin" argument (takes extra time!).
*/
- if (current_state.ga_len)
+ if (current_state.ga_len) {
cur_si = &CUR_STATE(current_state.ga_len - 1);
- else
+ } else {
cur_si = NULL;
+ }
if (syn_block->b_syn_containedin || cur_si == NULL
|| cur_si->si_cont_list != NULL) {
/*
* 2. Check for keywords, if on a keyword char after a non-keyword
- * char. Don't do this when syncing.
+ * char. Don't do this when syncing.
*/
if (do_keywords) {
line = syn_getcurline();
const char_u *cur_pos = line + current_col;
if (vim_iswordp_buf(cur_pos, syn_buf)
- && (current_col == 0 || !vim_iswordp_buf(
- cur_pos - 1 - utf_head_off(line, cur_pos - 1), syn_buf))) {
+ && (current_col == 0 ||
+ !vim_iswordp_buf(cur_pos - 1 - utf_head_off(line, cur_pos - 1),
+ syn_buf))) {
syn_id = check_keyword_id(line, (int)current_col, &endcol, &flags,
&next_list, cur_si, &cchar);
if (syn_id != 0) {
@@ -1752,7 +1803,7 @@ static int syn_current_attr(
cur_si = &CUR_STATE(current_state.ga_len - 1);
cur_si->si_m_startcol = current_col;
cur_si->si_h_startpos.lnum = current_lnum;
- cur_si->si_h_startpos.col = 0; /* starts right away */
+ cur_si->si_h_startpos.col = 0; // starts right away
cur_si->si_m_endpos.lnum = current_lnum;
cur_si->si_m_endpos.col = endcol;
cur_si->si_h_endpos.lnum = current_lnum;
@@ -1762,10 +1813,11 @@ static int syn_current_attr(
cur_si->si_flags = flags;
cur_si->si_seqnr = next_seqnr++;
cur_si->si_cchar = cchar;
- if (current_state.ga_len > 1)
+ if (current_state.ga_len > 1) {
cur_si->si_flags |=
CUR_STATE(current_state.ga_len - 2).si_flags
& HL_CONCEAL;
+ }
cur_si->si_id = syn_id;
cur_si->si_trans_id = syn_id;
if (flags & HL_TRANSP) {
@@ -1773,10 +1825,8 @@ static int syn_current_attr(
cur_si->si_attr = 0;
cur_si->si_trans_id = 0;
} else {
- cur_si->si_attr = CUR_STATE(
- current_state.ga_len - 2).si_attr;
- cur_si->si_trans_id = CUR_STATE(
- current_state.ga_len - 2).si_trans_id;
+ cur_si->si_attr = CUR_STATE(current_state.ga_len - 2).si_attr;
+ cur_si->si_trans_id = CUR_STATE(current_state.ga_len - 2).si_trans_id;
}
} else {
cur_si->si_attr = syn_id2attr(syn_id);
@@ -1804,28 +1854,29 @@ static int syn_current_attr(
* pattern takes quite a bit of time, thus we want to
* avoid doing it when it's not needed.
*/
- next_match_idx = 0; /* no match in this line yet */
+ next_match_idx = 0; // no match in this line yet
next_match_col = MAXCOL;
for (int idx = syn_block->b_syn_patterns.ga_len; --idx >= 0; ) {
synpat_T *const spp = &(SYN_ITEMS(syn_block)[idx]);
- if ( spp->sp_syncing == syncing
- && (displaying || !(spp->sp_flags & HL_DISPLAY))
- && (spp->sp_type == SPTYPE_MATCH
- || spp->sp_type == SPTYPE_START)
- && (current_next_list != NULL
+ if (spp->sp_syncing == syncing
+ && (displaying || !(spp->sp_flags & HL_DISPLAY))
+ && (spp->sp_type == SPTYPE_MATCH
+ || spp->sp_type == SPTYPE_START)
+ && (current_next_list != NULL
? in_id_list(NULL, current_next_list,
- &spp->sp_syn, 0)
+ &spp->sp_syn, 0)
: (cur_si == NULL
? !(spp->sp_flags & HL_CONTAINED)
: in_id_list(cur_si,
- cur_si->si_cont_list, &spp->sp_syn,
- spp->sp_flags & HL_CONTAINED)))) {
+ cur_si->si_cont_list, &spp->sp_syn,
+ spp->sp_flags & HL_CONTAINED)))) {
/* If we already tried matching in this line, and
* there isn't a match before next_match_col, skip
* this item. */
if (spp->sp_line_id == current_line_id
- && spp->sp_startcol >= next_match_col)
+ && spp->sp_startcol >= next_match_col) {
continue;
+ }
spp->sp_line_id = current_line_id;
colnr_T lc_col = current_col - spp->sp_offsets[SPO_LC_OFF];
@@ -1839,7 +1890,7 @@ static int syn_current_attr(
IF_SYN_TIME(&spp->sp_time));
spp->sp_prog = regmatch.regprog;
if (!r) {
- /* no match in this line, try another one */
+ // no match in this line, try another one
spp->sp_startcol = MAXCOL;
continue;
}
@@ -1848,7 +1899,7 @@ static int syn_current_attr(
* Compute the first column of the match.
*/
syn_add_start_off(&pos, &regmatch,
- spp, SPO_MS_OFF, -1);
+ spp, SPO_MS_OFF, -1);
if (pos.lnum > current_lnum) {
/* must have used end of match in a next line,
* we can't handle that */
@@ -1865,8 +1916,9 @@ static int syn_current_attr(
* If a previously found match starts at a lower
* column number, don't use this one.
*/
- if (startcol >= next_match_col)
+ if (startcol >= next_match_col) {
continue;
+ }
/*
* If we matched this pattern at this position
@@ -1881,14 +1933,14 @@ static int syn_current_attr(
endpos.lnum = regmatch.endpos[0].lnum;
endpos.col = regmatch.endpos[0].col;
- /* Compute the highlight start. */
+ // Compute the highlight start.
syn_add_start_off(&hl_startpos, &regmatch,
- spp, SPO_HS_OFF, -1);
+ spp, SPO_HS_OFF, -1);
- /* Compute the region start. */
- /* Default is to use the end of the match. */
+ // Compute the region start.
+ // Default is to use the end of the match.
syn_add_end_off(&eos_pos, &regmatch,
- spp, SPO_RS_OFF, 0);
+ spp, SPO_RS_OFF, 0);
/*
* Grab the external submatches before they get
@@ -1899,7 +1951,7 @@ static int syn_current_attr(
re_extmatch_out = NULL;
flags = 0;
- eoe_pos.lnum = 0; /* avoid warning */
+ eoe_pos.lnum = 0; // avoid warning
eoe_pos.col = 0;
end_idx = 0;
hl_endpos.lnum = 0;
@@ -1916,9 +1968,10 @@ static int syn_current_attr(
startpos = endpos;
find_endpos(idx, &startpos, &endpos, &hl_endpos,
- &flags, &eoe_pos, &end_idx, cur_extmatch);
- if (endpos.lnum == 0)
- continue; /* not found */
+ &flags, &eoe_pos, &end_idx, cur_extmatch);
+ if (endpos.lnum == 0) {
+ continue; // not found
+ }
}
/*
* For a "match" the size must be > 0 after the
@@ -1927,9 +1980,9 @@ static int syn_current_attr(
*/
else if (spp->sp_type == SPTYPE_MATCH) {
syn_add_end_off(&hl_endpos, &regmatch, spp,
- SPO_HE_OFF, 0);
+ SPO_HE_OFF, 0);
syn_add_end_off(&endpos, &regmatch, spp,
- SPO_ME_OFF, 0);
+ SPO_ME_OFF, 0);
if (endpos.lnum == current_lnum
&& (int)endpos.col + syncing < startcol) {
/*
@@ -1949,8 +2002,9 @@ static int syn_current_attr(
/* Highlighting must start after startpos and end
* before endpos. */
if (hl_startpos.lnum == current_lnum
- && (int)hl_startpos.col < startcol)
+ && (int)hl_startpos.col < startcol) {
hl_startpos.col = startcol;
+ }
limit_pos_zero(&hl_endpos, &endpos);
next_match_idx = idx;
@@ -1973,7 +2027,7 @@ static int syn_current_attr(
* If we found a match at the current column, use it.
*/
if (next_match_idx >= 0 && next_match_col == (int)current_col) {
- synpat_T *lspp;
+ synpat_T *lspp;
/* When a zero-width item matched which has a nextgroup,
* don't push the item but set nextgroup. */
@@ -2013,8 +2067,9 @@ static int syn_current_attr(
if (((current_next_flags & HL_SKIPWHITE)
&& ascii_iswhite(line[current_col]))
|| ((current_next_flags & HL_SKIPEMPTY)
- && *line == NUL))
+ && *line == NUL)) {
break;
+ }
}
/*
@@ -2031,7 +2086,6 @@ static int syn_current_attr(
found_match = true;
}
}
-
} while (found_match);
restore_chartab(buf_chartab);
@@ -2076,9 +2130,9 @@ static int syn_current_attr(
/* There is no @Spell cluster: Do spelling for items without
* @NoSpell cluster. */
if (syn_block->b_nospell_cluster_id == 0
- || current_trans_id == 0)
+ || current_trans_id == 0) {
*can_spell = (syn_block->b_syn_spell != SYNSPL_NOTOP);
- else {
+ } else {
sps.inc_tag = 0;
sps.id = syn_block->b_nospell_cluster_id;
sps.cont_in_list = NULL;
@@ -2089,9 +2143,9 @@ static int syn_current_attr(
* the @Spell cluster. But not when @NoSpell is also there.
* At the toplevel only spell check when ":syn spell toplevel"
* was used. */
- if (current_trans_id == 0)
+ if (current_trans_id == 0) {
*can_spell = (syn_block->b_syn_spell == SYNSPL_TOP);
- else {
+ } else {
sps.inc_tag = 0;
sps.id = syn_block->b_spell_cluster_id;
sps.cont_in_list = NULL;
@@ -2099,8 +2153,9 @@ static int syn_current_attr(
if (syn_block->b_nospell_cluster_id != 0) {
sps.id = syn_block->b_nospell_cluster_id;
- if (in_id_list(sip, sip->si_cont_list, &sps, 0))
+ if (in_id_list(sip, sip->si_cont_list, &sps, 0)) {
*can_spell = false;
+ }
}
}
}
@@ -2124,14 +2179,15 @@ static int syn_current_attr(
--current_col;
}
}
- } else if (can_spell != NULL)
+ } else if (can_spell != NULL) {
/* Default: Only do spelling when there is no @Spell cluster or when
* ":syn spell toplevel" was used. */
*can_spell = syn_block->b_syn_spell == SYNSPL_DEFAULT
? (syn_block->b_spell_cluster_id == 0)
: (syn_block->b_syn_spell == SYNSPL_TOP);
+ }
- /* nextgroup ends at end of line, unless "skipnl" or "skipempty" present */
+ // nextgroup ends at end of line, unless "skipnl" or "skipempty" present
if (current_next_list != NULL
&& (line = syn_getcurline())[current_col] != NUL
&& line[current_col + 1] == NUL
@@ -2139,10 +2195,11 @@ static int syn_current_attr(
current_next_list = NULL;
}
- if (!GA_EMPTY(&zero_width_next_ga))
+ if (!GA_EMPTY(&zero_width_next_ga)) {
ga_clear(&zero_width_next_ga);
+ }
- /* No longer need external matches. But keep next_match_extmatch. */
+ // No longer need external matches. But keep next_match_extmatch.
unref_extmatch(re_extmatch_out);
re_extmatch_out = NULL;
unref_extmatch(cur_extmatch);
@@ -2151,16 +2208,14 @@ static int syn_current_attr(
}
-/*
- * Check if we already matched pattern "idx" at the current column.
- */
-static int did_match_already(int idx, garray_T *gap)
+/// @return true if we already matched pattern "idx" at the current column.
+static bool did_match_already(int idx, garray_T *gap)
{
for (int i = current_state.ga_len; --i >= 0; ) {
if (CUR_STATE(i).si_m_startcol == (int)current_col
&& CUR_STATE(i).si_m_lnum == (int)current_lnum
&& CUR_STATE(i).si_idx == idx) {
- return TRUE;
+ return true;
}
}
@@ -2168,11 +2223,11 @@ static int did_match_already(int idx, garray_T *gap)
* stack, and can only be matched once anyway. */
for (int i = gap->ga_len; --i >= 0; ) {
if (((int *)(gap->ga_data))[i] == idx) {
- return TRUE;
+ return true;
}
}
- return FALSE;
+ return false;
}
/*
@@ -2202,14 +2257,15 @@ static stateitem_T *push_next_match(void)
cur_si->si_flags = spp->sp_flags;
cur_si->si_seqnr = next_seqnr++;
cur_si->si_cchar = spp->sp_cchar;
- if (current_state.ga_len > 1)
+ if (current_state.ga_len > 1) {
cur_si->si_flags |=
CUR_STATE(current_state.ga_len - 2).si_flags & HL_CONCEAL;
+ }
cur_si->si_next_list = spp->sp_next_list;
cur_si->si_extmatch = ref_extmatch(next_match_extmatch);
if (spp->sp_type == SPTYPE_START && !(spp->sp_flags & HL_ONELINE)) {
- /* Try to find the end pattern in the current line */
- update_si_end(cur_si, (int)(next_match_m_endpos.col), TRUE);
+ // Try to find the end pattern in the current line
+ update_si_end(cur_si, (int)(next_match_m_endpos.col), true);
check_keepend();
} else {
cur_si->si_m_endpos = next_match_m_endpos;
@@ -2219,8 +2275,9 @@ static stateitem_T *push_next_match(void)
cur_si->si_eoe_pos = next_match_eoe_pos;
cur_si->si_end_idx = next_match_end_idx;
}
- if (keepend_level < 0 && (cur_si->si_flags & HL_KEEPEND))
+ if (keepend_level < 0 && (cur_si->si_flags & HL_KEEPEND)) {
keepend_level = current_state.ga_len - 1;
+ }
check_keepend();
update_si_attr(current_state.ga_len - 1);
@@ -2242,15 +2299,16 @@ static stateitem_T *push_next_match(void)
cur_si->si_flags = HL_MATCH;
cur_si->si_seqnr = next_seqnr++;
cur_si->si_flags |= save_flags;
- if (cur_si->si_flags & HL_CONCEALENDS)
+ if (cur_si->si_flags & HL_CONCEALENDS) {
cur_si->si_flags |= HL_CONCEAL;
+ }
cur_si->si_next_list = NULL;
check_keepend();
update_si_attr(current_state.ga_len - 1);
}
}
- next_match_idx = -1; /* try other match next time */
+ next_match_idx = -1; // try other match next time
return cur_si;
}
@@ -2285,14 +2343,15 @@ static void check_state_ends(void)
cur_si->si_h_endpos = cur_si->si_eoe_pos;
cur_si->si_flags |= HL_MATCH;
cur_si->si_seqnr = next_seqnr++;
- if (cur_si->si_flags & HL_CONCEALENDS)
+ if (cur_si->si_flags & HL_CONCEALENDS) {
cur_si->si_flags |= HL_CONCEAL;
+ }
update_si_attr(current_state.ga_len - 1);
- /* nextgroup= should not match in the end pattern */
+ // nextgroup= should not match in the end pattern
current_next_list = NULL;
- /* what matches next may be different now, clear it */
+ // what matches next may be different now, clear it
next_match_idx = 0;
next_match_col = MAXCOL;
break;
@@ -2302,8 +2361,9 @@ static void check_state_ends(void)
current_next_list = cur_si->si_next_list;
current_next_flags = cur_si->si_flags;
if (!(current_next_flags & (HL_SKIPNL | HL_SKIPEMPTY))
- && syn_getcurline()[current_col] == NUL)
+ && syn_getcurline()[current_col] == NUL) {
current_next_list = NULL;
+ }
/* When the ended item has "extend", another item with
* "keepend" now needs to check for its end. */
@@ -2311,13 +2371,15 @@ static void check_state_ends(void)
pop_current_state();
- if (GA_EMPTY(&current_state))
+ if (GA_EMPTY(&current_state)) {
break;
+ }
if (had_extend && keepend_level >= 0) {
- syn_update_ends(FALSE);
- if (GA_EMPTY(&current_state))
+ syn_update_ends(false);
+ if (GA_EMPTY(&current_state)) {
break;
+ }
}
cur_si = &CUR_STATE(current_state.ga_len - 1);
@@ -2335,16 +2397,18 @@ static void check_state_ends(void)
&& SYN_ITEMS(syn_block)[cur_si->si_idx].sp_type
== SPTYPE_START
&& !(cur_si->si_flags & (HL_MATCH | HL_KEEPEND))) {
- update_si_end(cur_si, (int)current_col, TRUE);
+ update_si_end(cur_si, (int)current_col, true);
check_keepend();
if ((current_next_flags & HL_HAS_EOL)
&& keepend_level < 0
- && syn_getcurline()[current_col] == NUL)
+ && syn_getcurline()[current_col] == NUL) {
break;
+ }
}
}
- } else
+ } else {
break;
+ }
}
}
@@ -2355,23 +2419,26 @@ static void check_state_ends(void)
static void update_si_attr(int idx)
{
stateitem_T *sip = &CUR_STATE(idx);
- synpat_T *spp;
+ synpat_T *spp;
- /* This should not happen... */
- if (sip->si_idx < 0)
+ // This should not happen...
+ if (sip->si_idx < 0) {
return;
+ }
spp = &(SYN_ITEMS(syn_block)[sip->si_idx]);
- if (sip->si_flags & HL_MATCH)
+ if (sip->si_flags & HL_MATCH) {
sip->si_id = spp->sp_syn_match_id;
- else
+ } else {
sip->si_id = spp->sp_syn.id;
+ }
sip->si_attr = syn_id2attr(sip->si_id);
sip->si_trans_id = sip->si_id;
- if (sip->si_flags & HL_MATCH)
+ if (sip->si_flags & HL_MATCH) {
sip->si_cont_list = NULL;
- else
+ } else {
sip->si_cont_list = spp->sp_cont_list;
+ }
/*
* For transparent items, take attr from outer item.
@@ -2382,8 +2449,9 @@ static void update_si_attr(int idx)
if (idx == 0) {
sip->si_attr = 0;
sip->si_trans_id = 0;
- if (sip->si_cont_list == NULL)
+ if (sip->si_cont_list == NULL) {
sip->si_cont_list = ID_LIST_ALL;
+ }
} else {
sip->si_attr = CUR_STATE(idx - 1).si_attr;
sip->si_trans_id = CUR_STATE(idx - 1).si_trans_id;
@@ -2412,17 +2480,20 @@ static void check_keepend(void)
* This check can consume a lot of time; only do it from the level where
* there really is a keepend.
*/
- if (keepend_level < 0)
+ if (keepend_level < 0) {
return;
+ }
/*
* Find the last index of an "extend" item. "keepend" items before that
* won't do anything. If there is no "extend" item "i" will be
* "keepend_level" and all "keepend" items will work normally.
*/
- for (i = current_state.ga_len - 1; i > keepend_level; --i)
- if (CUR_STATE(i).si_flags & HL_EXTEND)
+ for (i = current_state.ga_len - 1; i > keepend_level; --i) {
+ if (CUR_STATE(i).si_flags & HL_EXTEND) {
break;
+ }
+ }
maxpos.lnum = 0;
maxpos.col = 0;
@@ -2440,42 +2511,42 @@ static void check_keepend(void)
if (maxpos.lnum == 0
|| maxpos.lnum > sip->si_m_endpos.lnum
|| (maxpos.lnum == sip->si_m_endpos.lnum
- && maxpos.col > sip->si_m_endpos.col))
+ && maxpos.col > sip->si_m_endpos.col)) {
maxpos = sip->si_m_endpos;
+ }
if (maxpos_h.lnum == 0
|| maxpos_h.lnum > sip->si_h_endpos.lnum
|| (maxpos_h.lnum == sip->si_h_endpos.lnum
- && maxpos_h.col > sip->si_h_endpos.col))
+ && maxpos_h.col > sip->si_h_endpos.col)) {
maxpos_h = sip->si_h_endpos;
+ }
}
}
}
-/*
- * Update an entry in the current_state stack for a start-skip-end pattern.
- * This finds the end of the current item, if it's in the current line.
- *
- * Return the flags for the matched END.
- */
-static void
-update_si_end(
- stateitem_T *sip,
- int startcol, /* where to start searching for the end */
- int force /* when TRUE overrule a previous end */
-)
+/// Update an entry in the current_state stack for a start-skip-end pattern.
+/// This finds the end of the current item, if it's in the current line.
+///
+/// @param startcol where to start searching for the end
+/// @param force when true overrule a previous end
+///
+/// @return the flags for the matched END.
+static void update_si_end(stateitem_T *sip, int startcol, bool force)
{
lpos_T hl_endpos;
lpos_T end_endpos;
- /* return quickly for a keyword */
- if (sip->si_idx < 0)
+ // return quickly for a keyword
+ if (sip->si_idx < 0) {
return;
+ }
/* Don't update when it's already done. Can be a match of an end pattern
* that started in a previous line. Watch out: can also be a "keepend"
* from a containing item. */
- if (!force && sip->si_m_endpos.lnum >= current_lnum)
+ if (!force && sip->si_m_endpos.lnum >= current_lnum) {
return;
+ }
/*
* We need to find the end of the region. It may continue in the next
@@ -2488,23 +2559,23 @@ update_si_end(
};
lpos_T endpos = { 0 };
find_endpos(sip->si_idx, &startpos, &endpos, &hl_endpos,
- &(sip->si_flags), &end_endpos, &end_idx, sip->si_extmatch);
+ &(sip->si_flags), &end_endpos, &end_idx, sip->si_extmatch);
if (endpos.lnum == 0) {
- /* No end pattern matched. */
+ // No end pattern matched.
if (SYN_ITEMS(syn_block)[sip->si_idx].sp_flags & HL_ONELINE) {
- /* a "oneline" never continues in the next line */
+ // a "oneline" never continues in the next line
sip->si_ends = TRUE;
sip->si_m_endpos.lnum = current_lnum;
sip->si_m_endpos.col = (colnr_T)STRLEN(syn_getcurline());
} else {
- /* continues in the next line */
+ // continues in the next line
sip->si_ends = FALSE;
sip->si_m_endpos.lnum = 0;
}
sip->si_h_endpos = sip->si_m_endpos;
} else {
- /* match within this line */
+ // match within this line
sip->si_m_endpos = endpos;
sip->si_h_endpos = hl_endpos;
sip->si_eoe_pos = end_endpos;
@@ -2533,49 +2604,49 @@ static void pop_current_state(void)
unref_extmatch(CUR_STATE(current_state.ga_len - 1).si_extmatch);
--current_state.ga_len;
}
- /* after the end of a pattern, try matching a keyword or pattern */
+ // after the end of a pattern, try matching a keyword or pattern
next_match_idx = -1;
- /* if first state with "keepend" is popped, reset keepend_level */
- if (keepend_level >= current_state.ga_len)
+ // if first state with "keepend" is popped, reset keepend_level
+ if (keepend_level >= current_state.ga_len) {
keepend_level = -1;
+ }
}
-/*
- * Find the end of a start/skip/end syntax region after "startpos".
- * Only checks one line.
- * Also handles a match item that continued from a previous line.
- * If not found, the syntax item continues in the next line. m_endpos->lnum
- * will be 0.
- * If found, the end of the region and the end of the highlighting is
- * computed.
- */
-static void
-find_endpos(
- int idx, // index of the pattern
- lpos_T *startpos, // where to start looking for an END match
- lpos_T *m_endpos, // return: end of match
- lpos_T *hl_endpos, // return: end of highlighting
- long *flagsp, // return: flags of matching END
- lpos_T *end_endpos, // return: end of end pattern match
- int *end_idx, // return: group ID for end pat. match, or 0
- reg_extmatch_T *start_ext // submatches from the start pattern
-)
+/// Find the end of a start/skip/end syntax region after "startpos".
+/// Only checks one line.
+/// Also handles a match item that continued from a previous line.
+/// If not found, the syntax item continues in the next line. m_endpos->lnum
+/// will be 0.
+/// If found, the end of the region and the end of the highlighting is
+/// computed.
+///
+/// @param idx index of the pattern
+/// @param startpos where to start looking for an END match
+/// @param m_endpos return: end of match
+/// @param hl_endpos return: end of highlighting
+/// @param flagsp return: flags of matching END
+/// @param end_endpos return: end of end pattern match
+/// @param end_idx return: group ID for end pat. match, or 0
+/// @param start_ext submatches from the start pattern
+static void find_endpos(int idx, lpos_T *startpos, lpos_T *m_endpos, lpos_T *hl_endpos,
+ long *flagsp, lpos_T *end_endpos, int *end_idx, reg_extmatch_T *start_ext)
{
colnr_T matchcol;
- synpat_T *spp, *spp_skip;
+ synpat_T *spp, *spp_skip;
int start_idx;
int best_idx;
regmmatch_T regmatch;
- regmmatch_T best_regmatch; /* startpos/endpos of best match */
+ regmmatch_T best_regmatch; // startpos/endpos of best match
lpos_T pos;
- char_u *line;
- int had_match = false;
+ char_u *line;
+ bool had_match = false;
char_u buf_chartab[32]; // chartab array for syn option iskeyword
- /* just in case we are invoked for a keyword */
- if (idx < 0)
+ // just in case we are invoked for a keyword
+ if (idx < 0) {
return;
+ }
/*
* Check for being called with a START pattern.
@@ -2593,21 +2664,23 @@ find_endpos(
*/
for (;; ) {
spp = &(SYN_ITEMS(syn_block)[idx]);
- if (spp->sp_type != SPTYPE_START)
+ if (spp->sp_type != SPTYPE_START) {
break;
+ }
++idx;
}
/*
- * Lookup the SKIP pattern (if present)
+ * Lookup the SKIP pattern (if present)
*/
if (spp->sp_type == SPTYPE_SKIP) {
spp_skip = spp;
++idx;
- } else
+ } else {
spp_skip = NULL;
+ }
- /* Setup external matches for syn_regexec(). */
+ // Setup external matches for syn_regexec().
unref_extmatch(re_extmatch_in);
re_extmatch_in = ref_extmatch(start_ext);
@@ -2627,11 +2700,13 @@ find_endpos(
int lc_col = matchcol;
spp = &(SYN_ITEMS(syn_block)[idx]);
- if (spp->sp_type != SPTYPE_END) /* past last END pattern */
+ if (spp->sp_type != SPTYPE_END) { // past last END pattern
break;
+ }
lc_col -= spp->sp_offsets[SPO_LC_OFF];
- if (lc_col < 0)
+ if (lc_col < 0) {
lc_col = 0;
+ }
regmatch.rmm_ic = spp->sp_ic;
regmatch.regprog = spp->sp_prog;
@@ -2652,8 +2727,9 @@ find_endpos(
* If all end patterns have been tried, and there is no match, the
* item continues until end-of-line.
*/
- if (best_idx == -1)
+ if (best_idx == -1) {
break;
+ }
/*
* If the skip pattern matches before the end pattern,
@@ -2662,8 +2738,9 @@ find_endpos(
if (spp_skip != NULL) {
int lc_col = matchcol - spp_skip->sp_offsets[SPO_LC_OFF];
- if (lc_col < 0)
+ if (lc_col < 0) {
lc_col = 0;
+ }
regmatch.rmm_ic = spp_skip->sp_ic;
regmatch.regprog = spp_skip->sp_prog;
int r = syn_regexec(&regmatch, startpos->lnum, lc_col,
@@ -2710,16 +2787,18 @@ find_endpos(
*/
spp = &(SYN_ITEMS(syn_block)[best_idx]);
syn_add_end_off(m_endpos, &best_regmatch, spp, SPO_ME_OFF, 1);
- /* can't end before the start */
- if (m_endpos->lnum == startpos->lnum && m_endpos->col < startpos->col)
+ // can't end before the start
+ if (m_endpos->lnum == startpos->lnum && m_endpos->col < startpos->col) {
m_endpos->col = startpos->col;
+ }
syn_add_end_off(end_endpos, &best_regmatch, spp, SPO_HE_OFF, 1);
- /* can't end before the start */
+ // can't end before the start
if (end_endpos->lnum == startpos->lnum
- && end_endpos->col < startpos->col)
+ && end_endpos->col < startpos->col) {
end_endpos->col = startpos->col;
- /* can't end after the match */
+ }
+ // can't end after the match
limit_pos(end_endpos, m_endpos);
/*
@@ -2736,10 +2815,11 @@ find_endpos(
}
hl_endpos->col += spp->sp_offsets[SPO_RE_OFF];
- /* can't end before the start */
+ // can't end before the start
if (hl_endpos->lnum == startpos->lnum
- && hl_endpos->col < startpos->col)
+ && hl_endpos->col < startpos->col) {
hl_endpos->col = startpos->col;
+ }
limit_pos(hl_endpos, m_endpos);
/* now the match ends where the highlighting ends, it is turned
@@ -2752,17 +2832,18 @@ find_endpos(
*flagsp = spp->sp_flags;
- had_match = TRUE;
+ had_match = true;
break;
}
- /* no match for an END pattern in this line */
- if (!had_match)
+ // no match for an END pattern in this line
+ if (!had_match) {
m_endpos->lnum = 0;
+ }
restore_chartab(buf_chartab);
- /* Remove external matches. */
+ // Remove external matches.
unref_extmatch(re_extmatch_in);
re_extmatch_in = NULL;
}
@@ -2772,10 +2853,11 @@ find_endpos(
*/
static void limit_pos(lpos_T *pos, lpos_T *limit)
{
- if (pos->lnum > limit->lnum)
+ if (pos->lnum > limit->lnum) {
*pos = *limit;
- else if (pos->lnum == limit->lnum && pos->col > limit->col)
+ } else if (pos->lnum == limit->lnum && pos->col > limit->col) {
pos->col = limit->col;
+ }
}
/*
@@ -2783,28 +2865,27 @@ static void limit_pos(lpos_T *pos, lpos_T *limit)
*/
static void limit_pos_zero(lpos_T *pos, lpos_T *limit)
{
- if (pos->lnum == 0)
+ if (pos->lnum == 0) {
*pos = *limit;
- else
+ } else {
limit_pos(pos, limit);
+ }
}
-/*
- * Add offset to matched text for end of match or highlight.
- */
-static void
-syn_add_end_off(
- lpos_T *result, // returned position
- regmmatch_T *regmatch, // start/end of match
- synpat_T *spp, // matched pattern
- int idx, // index of offset
- int extra // extra chars for offset to start
-)
+/// Add offset to matched text for end of match or highlight.
+///
+/// @param result returned position
+/// @param regmatch start/end of match
+/// @param spp matched pattern
+/// @param idx index of offset
+/// @param extra extra chars for offset to start
+static void syn_add_end_off(lpos_T *result, regmmatch_T *regmatch, synpat_T *spp, int idx,
+ int extra)
{
int col;
int off;
- char_u *base;
- char_u *p;
+ char_u *base;
+ char_u *p;
if (spp->sp_off_flags & (1 << idx)) {
result->lnum = regmatch->startpos[0].lnum;
@@ -2815,12 +2896,12 @@ syn_add_end_off(
col = regmatch->endpos[0].col;
off = spp->sp_offsets[idx];
}
- /* Don't go past the end of the line. Matters for "rs=e+2" when there
- * is a matchgroup. Watch out for match with last NL in the buffer. */
- if (result->lnum > syn_buf->b_ml.ml_line_count)
+ // Don't go past the end of the line. Matters for "rs=e+2" when there
+ // is a matchgroup. Watch out for match with last NL in the buffer.
+ if (result->lnum > syn_buf->b_ml.ml_line_count) {
col = 0;
- else if (off != 0) {
- base = ml_get_buf(syn_buf, result->lnum, FALSE);
+ } else if (off != 0) {
+ base = ml_get_buf(syn_buf, result->lnum, false);
p = base + col;
if (off > 0) {
while (off-- > 0 && *p != NUL) {
@@ -2836,23 +2917,19 @@ syn_add_end_off(
result->col = col;
}
-/*
- * Add offset to matched text for start of match or highlight.
- * Avoid resulting column to become negative.
- */
-static void
-syn_add_start_off(
- lpos_T *result, // returned position
- regmmatch_T *regmatch, // start/end of match
- synpat_T *spp,
- int idx,
- int extra // extra chars for offset to end
-)
+/// Add offset to matched text for start of match or highlight.
+/// Avoid resulting column to become negative.
+///
+/// @param result returned position
+/// @param regmatch start/end of match
+/// @param extra extra chars for offset to end
+static void syn_add_start_off(lpos_T *result, regmmatch_T *regmatch, synpat_T *spp, int idx,
+ int extra)
{
int col;
int off;
- char_u *base;
- char_u *p;
+ char_u *base;
+ char_u *p;
if (spp->sp_off_flags & (1 << (idx + SPO_COUNT))) {
result->lnum = regmatch->endpos[0].lnum;
@@ -2864,12 +2941,12 @@ syn_add_start_off(
off = spp->sp_offsets[idx];
}
if (result->lnum > syn_buf->b_ml.ml_line_count) {
- /* a "\n" at the end of the pattern may take us below the last line */
+ // a "\n" at the end of the pattern may take us below the last line
result->lnum = syn_buf->b_ml.ml_line_count;
- col = (int)STRLEN(ml_get_buf(syn_buf, result->lnum, FALSE));
+ col = (int)STRLEN(ml_get_buf(syn_buf, result->lnum, false));
}
if (off != 0) {
- base = ml_get_buf(syn_buf, result->lnum, FALSE);
+ base = ml_get_buf(syn_buf, result->lnum, false);
p = base + col;
if (off > 0) {
while (off-- && *p != NUL) {
@@ -2890,7 +2967,7 @@ syn_add_start_off(
*/
static char_u *syn_getcurline(void)
{
- return ml_get_buf(syn_buf, current_lnum, FALSE);
+ return ml_get_buf(syn_buf, current_lnum, false);
}
/*
@@ -2902,7 +2979,7 @@ static int syn_regexec(regmmatch_T *rmp, linenr_T lnum, colnr_T col, syn_time_T
int r;
int timed_out = 0;
proftime_T pt;
- const int l_syn_time_on = syn_time_on;
+ const bool l_syn_time_on = syn_time_on;
if (l_syn_time_on) {
pt = profile_start();
@@ -2926,8 +3003,9 @@ static int syn_regexec(regmmatch_T *rmp, linenr_T lnum, colnr_T col, syn_time_T
st->slowest = pt;
}
++st->count;
- if (r > 0)
+ if (r > 0) {
++st->match;
+ }
}
if (timed_out && !syn_win->w_s->b_syn_slow) {
syn_win->w_s->b_syn_slow = true;
@@ -2942,20 +3020,19 @@ static int syn_regexec(regmmatch_T *rmp, linenr_T lnum, colnr_T col, syn_time_T
return FALSE;
}
-/*
- * Check one position in a line for a matching keyword.
- * The caller must check if a keyword can start at startcol.
- * Return its ID if found, 0 otherwise.
- */
-static int check_keyword_id(
- char_u *const line,
- const int startcol, // position in line to check for keyword
- int *const endcolp, // return: character after found keyword
- long *const flagsp, // return: flags of matching keyword
- int16_t **const next_listp, // return: next_list of matching keyword
- stateitem_T *const cur_si, // item at the top of the stack
- int *const ccharp // conceal substitution char
-)
+/// Check one position in a line for a matching keyword.
+/// The caller must check if a keyword can start at startcol.
+/// Return its ID if found, 0 otherwise.
+///
+/// @param startcol position in line to check for keyword
+/// @param endcolp return: character after found keyword
+/// @param flagsp return: flags of matching keyword
+/// @param next_listp return: next_list of matching keyword
+/// @param cur_si item at the top of the stack
+/// @param ccharp conceal substitution char
+static int check_keyword_id(char_u *const line, const int startcol, int *const endcolp,
+ long *const flagsp, int16_t **const next_listp,
+ stateitem_T *const cur_si, int *const ccharp)
{
// Find first character after the keyword. First character was already
// checked.
@@ -3003,11 +3080,10 @@ static int check_keyword_id(
/// When current_next_list is non-zero accept only that group, otherwise:
/// Accept a not-contained keyword at toplevel.
/// Accept a keyword at other levels only if it is in the contains list.
-static keyentry_T *match_keyword(char_u *keyword, hashtab_T *ht,
- stateitem_T *cur_si)
+static keyentry_T *match_keyword(char_u *keyword, hashtab_T *ht, stateitem_T *cur_si)
{
hashitem_T *hi = hash_find(ht, keyword);
- if (!HASHITEM_EMPTY(hi))
+ if (!HASHITEM_EMPTY(hi)) {
for (keyentry_T *kp = HI2KE(hi); kp != NULL; kp = kp->ke_next) {
if (current_next_list != 0
? in_id_list(NULL, current_next_list, &kp->k_syn, 0)
@@ -3018,6 +3094,7 @@ static keyentry_T *match_keyword(char_u *keyword, hashtab_T *ht,
return kp;
}
}
+ }
return NULL;
}
@@ -3026,12 +3103,13 @@ static keyentry_T *match_keyword(char_u *keyword, hashtab_T *ht,
*/
static void syn_cmd_conceal(exarg_T *eap, int syncing)
{
- char_u *arg = eap->arg;
- char_u *next;
+ char_u *arg = eap->arg;
+ char_u *next;
eap->nextcmd = find_nextcmd(arg);
- if (eap->skip)
+ if (eap->skip) {
return;
+ }
next = skiptowhite(arg);
if (*arg == NUL) {
@@ -3054,12 +3132,13 @@ static void syn_cmd_conceal(exarg_T *eap, int syncing)
*/
static void syn_cmd_case(exarg_T *eap, int syncing)
{
- char_u *arg = eap->arg;
- char_u *next;
+ char_u *arg = eap->arg;
+ char_u *next;
eap->nextcmd = find_nextcmd(arg);
- if (eap->skip)
+ if (eap->skip) {
return;
+ }
next = skiptowhite(arg);
if (*arg == NUL) {
@@ -3084,14 +3163,18 @@ static void syn_cmd_foldlevel(exarg_T *eap, int syncing)
char_u *arg_end;
eap->nextcmd = find_nextcmd(arg);
- if (eap->skip)
+ if (eap->skip) {
return;
+ }
if (*arg == NUL) {
switch (curwin->w_s->b_syn_foldlevel) {
- case SYNFLD_START: MSG(_("syntax foldlevel start")); break;
- case SYNFLD_MINIMUM: MSG(_("syntax foldlevel minimum")); break;
- default: break;
+ case SYNFLD_START:
+ MSG(_("syntax foldlevel start")); break;
+ case SYNFLD_MINIMUM:
+ MSG(_("syntax foldlevel minimum")); break;
+ default:
+ break;
}
return;
}
@@ -3117,12 +3200,13 @@ static void syn_cmd_foldlevel(exarg_T *eap, int syncing)
*/
static void syn_cmd_spell(exarg_T *eap, int syncing)
{
- char_u *arg = eap->arg;
- char_u *next;
+ char_u *arg = eap->arg;
+ char_u *next;
eap->nextcmd = find_nextcmd(arg);
- if (eap->skip)
+ if (eap->skip) {
return;
+ }
next = skiptowhite(arg);
if (*arg == NUL) {
@@ -3201,17 +3285,17 @@ void syntax_clear(synblock_T *block)
block->b_syn_containedin = false;
block->b_syn_conceal = false;
- /* free the keywords */
+ // free the keywords
clear_keywtab(&block->b_keywtab);
clear_keywtab(&block->b_keywtab_ic);
- /* free the syntax patterns */
+ // free the syntax patterns
for (int i = block->b_syn_patterns.ga_len; --i >= 0; ) {
syn_clear_pattern(block, i);
}
ga_clear(&block->b_syn_patterns);
- /* free the syntax clusters */
+ // free the syntax clusters
for (int i = block->b_syn_clusters.ga_len; --i >= 0; ) {
syn_clear_cluster(block, i);
}
@@ -3230,11 +3314,11 @@ void syntax_clear(synblock_T *block)
block->b_syn_folditems = 0;
clear_string_option(&block->b_syn_isk);
- /* free the stored states */
+ // free the stored states
syn_stack_free_all(block);
invalidate_current_state();
- /* Reset the counter for ":syn include" */
+ // Reset the counter for ":syn include"
running_syn_inc_tag = 0;
}
@@ -3255,7 +3339,7 @@ void reset_synblock(win_T *wp)
*/
static void syntax_sync_clear(void)
{
- /* free the syntax patterns */
+ // free the syntax patterns
for (int i = curwin->w_s->b_syn_patterns.ga_len; --i >= 0; ) {
if (SYN_ITEMS(curwin->w_s)[i].sp_syncing) {
syn_remove_pattern(curwin->w_s, i);
@@ -3272,7 +3356,7 @@ static void syntax_sync_clear(void)
XFREE_CLEAR(curwin->w_s->b_syn_linecont_pat);
clear_string_option(&curwin->w_s->b_syn_isk);
- syn_stack_free_all(curwin->w_s); /* Need to recompute all syntax. */
+ syn_stack_free_all(curwin->w_s); // Need to recompute all syntax.
}
/*
@@ -3280,14 +3364,15 @@ static void syntax_sync_clear(void)
*/
static void syn_remove_pattern(synblock_T *block, int idx)
{
- synpat_T *spp;
+ synpat_T *spp;
spp = &(SYN_ITEMS(block)[idx]);
- if (spp->sp_flags & HL_FOLD)
+ if (spp->sp_flags & HL_FOLD) {
--block->b_syn_folditems;
+ }
syn_clear_pattern(block, idx);
memmove(spp, spp + 1,
- sizeof(synpat_T) * (block->b_syn_patterns.ga_len - idx - 1));
+ sizeof(synpat_T) * (block->b_syn_patterns.ga_len - idx - 1));
--block->b_syn_patterns.ga_len;
}
@@ -3299,7 +3384,7 @@ static void syn_clear_pattern(synblock_T *block, int i)
{
xfree(SYN_ITEMS(block)[i].sp_pattern);
vim_regfree(SYN_ITEMS(block)[i].sp_prog);
- /* Only free sp_cont_list and sp_next_list of first start pattern */
+ // Only free sp_cont_list and sp_next_list of first start pattern
if (i == 0 || SYN_ITEMS(block)[i - 1].sp_type != SPTYPE_START) {
xfree(SYN_ITEMS(block)[i].sp_cont_list);
xfree(SYN_ITEMS(block)[i].sp_next_list);
@@ -3322,13 +3407,14 @@ static void syn_clear_cluster(synblock_T *block, int i)
*/
static void syn_cmd_clear(exarg_T *eap, int syncing)
{
- char_u *arg = eap->arg;
- char_u *arg_end;
+ char_u *arg = eap->arg;
+ char_u *arg_end;
int id;
eap->nextcmd = find_nextcmd(arg);
- if (eap->skip)
+ if (eap->skip) {
return;
+ }
/*
* We have to disable this within ":syn include @group filename",
@@ -3336,16 +3422,17 @@ static void syn_cmd_clear(exarg_T *eap, int syncing)
* Only required for Vim 5.x syntax files, 6.0 ones don't contain ":syn
* clear".
*/
- if (curwin->w_s->b_syn_topgrp != 0)
+ if (curwin->w_s->b_syn_topgrp != 0) {
return;
+ }
if (ends_excmd(*arg)) {
/*
* No argument: Clear all syntax items.
*/
- if (syncing)
+ if (syncing) {
syntax_sync_clear();
- else {
+ } else {
syntax_clear(curwin->w_s);
if (curwin->w_s == &curwin->w_buffer->b_s) {
do_unlet(S_LEN("b:current_syntax"), true);
@@ -3372,18 +3459,19 @@ static void syn_cmd_clear(exarg_T *eap, int syncing)
XFREE_CLEAR(SYN_CLSTR(curwin->w_s)[scl_id].scl_list);
}
} else {
- id = syn_namen2id(arg, (int)(arg_end - arg));
+ id = syn_name2id_len(arg, (int)(arg_end - arg));
if (id == 0) {
EMSG2(_(e_nogroup), arg);
break;
- } else
+ } else {
syn_clear_one(id, syncing);
+ }
}
arg = skipwhite(arg_end);
}
}
redraw_curbuf_later(SOME_VALID);
- syn_stack_free_all(curwin->w_s); /* Need to recompute all syntax. */
+ syn_stack_free_all(curwin->w_s); // Need to recompute all syntax.
}
/*
@@ -3391,19 +3479,20 @@ static void syn_cmd_clear(exarg_T *eap, int syncing)
*/
static void syn_clear_one(const int id, const bool syncing)
{
- synpat_T *spp;
+ synpat_T *spp;
- /* Clear keywords only when not ":syn sync clear group-name" */
+ // Clear keywords only when not ":syn sync clear group-name"
if (!syncing) {
syn_clear_keyword(id, &curwin->w_s->b_keywtab);
syn_clear_keyword(id, &curwin->w_s->b_keywtab_ic);
}
- /* clear the patterns for "id" */
+ // clear the patterns for "id"
for (int idx = curwin->w_s->b_syn_patterns.ga_len; --idx >= 0; ) {
spp = &(SYN_ITEMS(curwin->w_s)[idx]);
- if (spp->sp_syn.id != id || spp->sp_syncing != syncing)
+ if (spp->sp_syn.id != id || spp->sp_syncing != syncing) {
continue;
+ }
syn_remove_pattern(curwin->w_s, idx);
}
}
@@ -3417,16 +3506,6 @@ static void syn_cmd_on(exarg_T *eap, int syncing)
}
/*
- * Handle ":syntax enable" command.
- */
-static void syn_cmd_enable(exarg_T *eap, int syncing)
-{
- set_internal_string_var("syntax_cmd", (char_u *)"enable");
- syn_cmd_onoff(eap, "syntax");
- do_unlet(S_LEN("g:syntax_cmd"), true);
-}
-
-/*
* Handle ":syntax reset" command.
* It actually resets highlighting, not syntax.
*/
@@ -3434,9 +3513,7 @@ static void syn_cmd_reset(exarg_T *eap, int syncing)
{
eap->nextcmd = check_nextcmd(eap->arg);
if (!eap->skip) {
- set_internal_string_var("syntax_cmd", (char_u *)"reset");
- do_cmdline_cmd("runtime! syntax/syncolor.vim");
- do_unlet(S_LEN("g:syntax_cmd"), true);
+ init_highlight(true, true);
}
}
@@ -3475,25 +3552,22 @@ void syn_maybe_enable(void)
exarg_T ea;
ea.arg = (char_u *)"";
ea.skip = false;
- syn_cmd_enable(&ea, false);
+ syn_cmd_on(&ea, false);
}
}
-/*
- * Handle ":syntax [list]" command: list current syntax words.
- */
-static void
-syn_cmd_list(
- exarg_T *eap,
- int syncing /* when TRUE: list syncing items */
-)
+/// Handle ":syntax [list]" command: list current syntax words.
+///
+/// @param syncing when TRUE: list syncing items
+static void syn_cmd_list(exarg_T *eap, int syncing)
{
- char_u *arg = eap->arg;
- char_u *arg_end;
+ char_u *arg = eap->arg;
+ char_u *arg_end;
eap->nextcmd = find_nextcmd(arg);
- if (eap->skip)
+ if (eap->skip) {
return;
+ }
if (!syntax_present(curwin)) {
MSG(_(msg_no_items));
@@ -3506,7 +3580,7 @@ syn_cmd_list(
syn_lines_msg();
syn_match_msg();
return;
- } else if (!(curwin->w_s->b_syn_sync_flags & SF_MATCH)) {
+ } else if (!(curwin->w_s->b_syn_sync_flags & SF_MATCH)) {
if (curwin->w_s->b_syn_sync_minlines == 0) {
MSG_PUTS(_("no syncing"));
} else {
@@ -3529,8 +3603,9 @@ syn_cmd_list(
syn_lines_msg();
syn_match_msg();
}
- } else
+ } else {
MSG_PUTS_TITLE(_("\n--- Syntax items ---"));
+ }
if (ends_excmd(*arg)) {
/*
* No argument: List all group IDs and all syntax clusters.
@@ -3549,12 +3624,13 @@ syn_cmd_list(
arg_end = skiptowhite(arg);
if (*arg == '@') {
int id = syn_scl_namen2id(arg + 1, (int)(arg_end - arg - 1));
- if (id == 0)
+ if (id == 0) {
EMSG2(_("E392: No such syntax cluster: %s"), arg);
- else
+ } else {
syn_list_cluster(id - SYNID_CLUSTER);
+ }
} else {
- int id = syn_namen2id(arg, (int)(arg_end - arg));
+ int id = syn_name2id_len(arg, (int)(arg_end - arg));
if (id == 0) {
EMSG2(_(e_nogroup), arg);
} else {
@@ -3603,37 +3679,33 @@ static void syn_match_msg(void)
static int last_matchgroup;
-/*
- * List one syntax item, for ":syntax" or "syntax list syntax_name".
- */
-static void
-syn_list_one(
- const int id,
- const bool syncing, // when true: list syncing items
- const bool link_only // when true; list link-only too
-)
+/// List one syntax item, for ":syntax" or "syntax list syntax_name".
+///
+/// @param syncing when true: list syncing items
+/// @param link_only when true; list link-only too
+static void syn_list_one(const int id, const bool syncing, const bool link_only)
{
bool did_header = false;
static struct name_list namelist1[] =
{
- {HL_DISPLAY, "display"},
- {HL_CONTAINED, "contained"},
- {HL_ONELINE, "oneline"},
- {HL_KEEPEND, "keepend"},
- {HL_EXTEND, "extend"},
- {HL_EXCLUDENL, "excludenl"},
- {HL_TRANSP, "transparent"},
- {HL_FOLD, "fold"},
- {HL_CONCEAL, "conceal"},
- {HL_CONCEALENDS, "concealends"},
- {0, NULL}
+ { HL_DISPLAY, "display" },
+ { HL_CONTAINED, "contained" },
+ { HL_ONELINE, "oneline" },
+ { HL_KEEPEND, "keepend" },
+ { HL_EXTEND, "extend" },
+ { HL_EXCLUDENL, "excludenl" },
+ { HL_TRANSP, "transparent" },
+ { HL_FOLD, "fold" },
+ { HL_CONCEAL, "conceal" },
+ { HL_CONCEALENDS, "concealends" },
+ { 0, NULL }
};
static struct name_list namelist2[] =
{
- {HL_SKIPWHITE, "skipwhite"},
- {HL_SKIPNL, "skipnl"},
- {HL_SKIPEMPTY, "skipempty"},
- {0, NULL}
+ { HL_SKIPWHITE, "skipwhite" },
+ { HL_SKIPNL, "skipnl" },
+ { HL_SKIPEMPTY, "skipempty" },
+ { 0, NULL }
};
const int attr = HL_ATTR(HLF_D); // highlight like directories
@@ -3660,14 +3732,17 @@ syn_list_one(
if (spp->sp_type == SPTYPE_MATCH) {
put_pattern("match", ' ', spp, attr);
msg_putchar(' ');
- } else if (spp->sp_type == SPTYPE_START) {
- while (SYN_ITEMS(curwin->w_s)[idx].sp_type == SPTYPE_START)
+ } else if (spp->sp_type == SPTYPE_START) {
+ while (SYN_ITEMS(curwin->w_s)[idx].sp_type == SPTYPE_START) {
put_pattern("start", '=', &SYN_ITEMS(curwin->w_s)[idx++], attr);
- if (SYN_ITEMS(curwin->w_s)[idx].sp_type == SPTYPE_SKIP)
+ }
+ if (SYN_ITEMS(curwin->w_s)[idx].sp_type == SPTYPE_SKIP) {
put_pattern("skip", '=', &SYN_ITEMS(curwin->w_s)[idx++], attr);
+ }
while (idx < curwin->w_s->b_syn_patterns.ga_len
- && SYN_ITEMS(curwin->w_s)[idx].sp_type == SPTYPE_END)
+ && SYN_ITEMS(curwin->w_s)[idx].sp_type == SPTYPE_END) {
put_pattern("end", '=', &SYN_ITEMS(curwin->w_s)[idx++], attr);
+ }
--idx;
msg_putchar(' ');
}
@@ -3692,16 +3767,17 @@ syn_list_one(
msg_puts_attr("groupthere", attr);
}
msg_putchar(' ');
- if (spp->sp_sync_idx >= 0)
+ if (spp->sp_sync_idx >= 0) {
msg_outtrans(HL_TABLE()[SYN_ITEMS(curwin->w_s)
[spp->sp_sync_idx].sp_syn.id - 1].sg_name);
- else
+ } else {
MSG_PUTS("NONE");
+ }
msg_putchar(' ');
}
}
- /* list the link, if there is one */
+ // list the link, if there is one
if (HL_TABLE()[id - 1].sg_link && (did_header || link_only) && !got_int) {
(void)syn_list_header(did_header, 0, id, true);
msg_puts_attr("links to", attr);
@@ -3714,11 +3790,12 @@ static void syn_list_flags(struct name_list *nlist, int flags, int attr)
{
int i;
- for (i = 0; nlist[i].flag != 0; ++i)
+ for (i = 0; nlist[i].flag != 0; ++i) {
if (flags & nlist[i].flag) {
msg_puts_attr(nlist[i].name, attr);
msg_putchar(' ');
}
+ }
}
/*
@@ -3728,14 +3805,16 @@ static void syn_list_cluster(int id)
{
int endcol = 15;
- /* slight hack: roughly duplicate the guts of syn_list_header() */
+ // slight hack: roughly duplicate the guts of syn_list_header()
msg_putchar('\n');
msg_outtrans(SYN_CLSTR(curwin->w_s)[id].scl_name);
- if (msg_col >= endcol) /* output at least one space */
+ if (msg_col >= endcol) { // output at least one space
endcol = msg_col + 1;
- if (Columns <= endcol) /* avoid hang for tiny window */
+ }
+ if (Columns <= endcol) { // avoid hang for tiny window
endcol = Columns - 1;
+ }
msg_advance(endcol);
if (SYN_CLSTR(curwin->w_s)[id].scl_list != NULL) {
@@ -3746,9 +3825,7 @@ static void syn_list_cluster(int id)
}
}
-static void put_id_list(const char *const name,
- const int16_t *const list,
- const int attr)
+static void put_id_list(const char *const name, const int16_t *const list, const int attr)
{
msg_puts_attr(name, attr);
msg_putchar('=');
@@ -3759,38 +3836,40 @@ static void put_id_list(const char *const name,
} else {
msg_puts("ALL");
}
- } else if (*p >= SYNID_TOP && *p < SYNID_CONTAINED) {
+ } else if (*p >= SYNID_TOP && *p < SYNID_CONTAINED) {
msg_puts("TOP");
- } else if (*p >= SYNID_CONTAINED && *p < SYNID_CLUSTER) {
+ } else if (*p >= SYNID_CONTAINED && *p < SYNID_CLUSTER) {
msg_puts("CONTAINED");
- } else if (*p >= SYNID_CLUSTER) {
+ } else if (*p >= SYNID_CLUSTER) {
int scl_id = *p - SYNID_CLUSTER;
msg_putchar('@');
msg_outtrans(SYN_CLSTR(curwin->w_s)[scl_id].scl_name);
- } else
+ } else {
msg_outtrans(HL_TABLE()[*p - 1].sg_name);
- if (p[1])
+ }
+ if (p[1]) {
msg_putchar(',');
+ }
}
msg_putchar(' ');
}
-static void put_pattern(const char *const s, const int c,
- const synpat_T *const spp, const int attr)
+static void put_pattern(const char *const s, const int c, const synpat_T *const spp, const int attr)
{
static const char *const sepchars = "/+=-#@\"|'^&";
int i;
- /* May have to write "matchgroup=group" */
+ // May have to write "matchgroup=group"
if (last_matchgroup != spp->sp_syn_match_id) {
last_matchgroup = spp->sp_syn_match_id;
msg_puts_attr("matchgroup", attr);
msg_putchar('=');
- if (last_matchgroup == 0)
+ if (last_matchgroup == 0) {
msg_outtrans((char_u *)"NONE");
- else
+ } else {
msg_outtrans(HL_TABLE()[last_matchgroup - 1].sg_name);
+ }
msg_putchar(' ');
}
@@ -3798,12 +3877,13 @@ static void put_pattern(const char *const s, const int c,
msg_puts_attr(s, attr);
msg_putchar(c);
- /* output the pattern, in between a char that is not in the pattern */
- for (i = 0; vim_strchr(spp->sp_pattern, sepchars[i]) != NULL; )
+ // output the pattern, in between a char that is not in the pattern
+ for (i = 0; vim_strchr(spp->sp_pattern, sepchars[i]) != NULL; ) {
if (sepchars[++i] == NUL) {
- i = 0; /* no good char found, just use the first one */
+ i = 0; // no good char found, just use the first one
break;
}
+ }
msg_putchar(sepchars[i]);
msg_outtrans(spp->sp_pattern);
msg_putchar(sepchars[i]);
@@ -3821,12 +3901,14 @@ static void put_pattern(const char *const s, const int c,
msg_puts(spo_name_tab[i]);
const long n = spp->sp_offsets[i];
if (i != SPO_LC_OFF) {
- if (spp->sp_off_flags & mask)
+ if (spp->sp_off_flags & mask) {
msg_putchar('s');
- else
+ } else {
msg_putchar('e');
- if (n > 0)
+ }
+ if (n > 0) {
msg_putchar('+');
+ }
}
if (n || i == SPO_LC_OFF) {
msg_outnum(n);
@@ -3836,14 +3918,13 @@ static void put_pattern(const char *const s, const int c,
msg_putchar(' ');
}
-// List or clear the keywords for one syntax group.
-// Return true if the header has been printed.
-static bool syn_list_keywords(
- const int id,
- const hashtab_T *const ht,
- bool did_header, // header has already been printed
- const int attr
-)
+/// List or clear the keywords for one syntax group.
+///
+/// @param did_header header has already been printed
+///
+/// @return true if the header has been printed.
+static bool syn_list_keywords(const int id, const hashtab_T *const ht, bool did_header,
+ const int attr)
{
int prev_contained = 0;
const int16_t *prev_next_list = NULL;
@@ -3870,7 +3951,7 @@ static bool syn_list_keywords(
|| prev_skipempty != (kp->flags & HL_SKIPEMPTY)
|| prev_cont_in_list != kp->k_syn.cont_in_list
|| prev_next_list != kp->next_list) {
- force_newline = true;
+ force_newline = true;
} else {
outlen = (int)STRLEN(kp->keyword);
}
@@ -3924,10 +4005,10 @@ static bool syn_list_keywords(
static void syn_clear_keyword(int id, hashtab_T *ht)
{
- hashitem_T *hi;
- keyentry_T *kp;
- keyentry_T *kp_prev;
- keyentry_T *kp_next;
+ hashitem_T *hi;
+ keyentry_T *kp;
+ keyentry_T *kp_prev;
+ keyentry_T *kp_next;
int todo;
hash_lock(ht);
@@ -3942,12 +4023,14 @@ static void syn_clear_keyword(int id, hashtab_T *ht)
if (kp->k_syn.id == id) {
kp_next = kp->ke_next;
if (kp_prev == NULL) {
- if (kp_next == NULL)
+ if (kp_next == NULL) {
hash_remove(ht, hi);
- else
+ } else {
hi->hi_key = KE2HIKEY(kp_next);
- } else
+ }
+ } else {
kp_prev->ke_next = kp_next;
+ }
xfree(kp->next_list);
xfree(kp->k_syn.cont_in_list);
xfree(kp);
@@ -3966,10 +4049,10 @@ static void syn_clear_keyword(int id, hashtab_T *ht)
*/
static void clear_keywtab(hashtab_T *ht)
{
- hashitem_T *hi;
+ hashitem_T *hi;
int todo;
- keyentry_T *kp;
- keyentry_T *kp_next;
+ keyentry_T *kp;
+ keyentry_T *kp_next;
todo = (int)ht->ht_used;
for (hi = ht->ht_array; todo > 0; ++hi) {
@@ -3994,11 +4077,8 @@ static void clear_keywtab(hashtab_T *ht)
/// @param flags flags for this keyword
/// @param cont_in_list containedin for this keyword
/// @param next_list nextgroup for this keyword
-static void add_keyword(char_u *const name,
- const int id,
- const int flags,
- int16_t *const cont_in_list,
- int16_t *const next_list,
+static void add_keyword(char_u *const name, const int id, const int flags,
+ int16_t *const cont_in_list, int16_t *const next_list,
const int conceal_char)
{
char_u name_folded[MAXKEYWLEN + 1];
@@ -4040,18 +4120,16 @@ static void add_keyword(char_u *const name,
}
}
-/*
- * Get the start and end of the group name argument.
- * Return a pointer to the first argument.
- * Return NULL if the end of the command was found instead of further args.
- */
-static char_u *
-get_group_name (
- char_u *arg, /* start of the argument */
- char_u **name_end /* pointer to end of the name */
-)
+/// Get the start and end of the group name argument.
+///
+/// @param arg start of the argument
+/// @param name_end pointer to end of the name
+///
+/// @return a pointer to the first argument.
+/// Return NULL if the end of the command was found instead of further args.
+static char_u *get_group_name(char_u *arg, char_u **name_end)
{
- char_u *rest;
+ char_u *rest;
*name_end = skiptowhite(arg);
rest = skipwhite(*name_end);
@@ -4060,62 +4138,62 @@ get_group_name (
* Check if there are enough arguments. The first argument may be a
* pattern, where '|' is allowed, so only check for NUL.
*/
- if (ends_excmd(*arg) || *rest == NUL)
+ if (ends_excmd(*arg) || *rest == NUL) {
return NULL;
+ }
return rest;
}
-/*
- * Check for syntax command option arguments.
- * This can be called at any place in the list of arguments, and just picks
- * out the arguments that are known. Can be called several times in a row to
- * collect all options in between other arguments.
- * Return a pointer to the next argument (which isn't an option).
- * Return NULL for any error;
- */
-static char_u *
-get_syn_options(
- char_u *arg, // next argument to be checked
- syn_opt_arg_T *opt, // various things
- int *conceal_char,
- int skip // TRUE if skipping over command
-)
-{
- char_u *gname_start, *gname;
+/// Check for syntax command option arguments.
+/// This can be called at any place in the list of arguments, and just picks
+/// out the arguments that are known. Can be called several times in a row to
+/// collect all options in between other arguments.
+///
+/// @param arg next argument to be checked
+/// @param opt various things
+/// @param skip TRUE if skipping over command
+///
+/// @return a pointer to the next argument (which isn't an option).
+/// Return NULL for any error;
+static char_u *get_syn_options(char_u *arg, syn_opt_arg_T *opt, int *conceal_char, int skip)
+{
+ char_u *gname_start, *gname;
int syn_id;
int len = 0;
- char *p;
+ char *p;
int fidx;
static const struct flag {
- char *name;
+ char *name;
int argtype;
int flags;
- } flagtab[] = { {"cCoOnNtTaAiInNeEdD", 0, HL_CONTAINED},
- {"oOnNeElLiInNeE", 0, HL_ONELINE},
- {"kKeEeEpPeEnNdD", 0, HL_KEEPEND},
- {"eExXtTeEnNdD", 0, HL_EXTEND},
- {"eExXcClLuUdDeEnNlL", 0, HL_EXCLUDENL},
- {"tTrRaAnNsSpPaArReEnNtT", 0, HL_TRANSP},
- {"sSkKiIpPnNlL", 0, HL_SKIPNL},
- {"sSkKiIpPwWhHiItTeE", 0, HL_SKIPWHITE},
- {"sSkKiIpPeEmMpPtTyY", 0, HL_SKIPEMPTY},
- {"gGrRoOuUpPhHeErReE", 0, HL_SYNC_HERE},
- {"gGrRoOuUpPtThHeErReE", 0, HL_SYNC_THERE},
- {"dDiIsSpPlLaAyY", 0, HL_DISPLAY},
- {"fFoOlLdD", 0, HL_FOLD},
- {"cCoOnNcCeEaAlL", 0, HL_CONCEAL},
- {"cCoOnNcCeEaAlLeEnNdDsS", 0, HL_CONCEALENDS},
- {"cCcChHaArR", 11, 0},
- {"cCoOnNtTaAiInNsS", 1, 0},
- {"cCoOnNtTaAiInNeEdDiInN", 2, 0},
- {"nNeExXtTgGrRoOuUpP", 3, 0},};
+ } flagtab[] = { { "cCoOnNtTaAiInNeEdD", 0, HL_CONTAINED },
+ { "oOnNeElLiInNeE", 0, HL_ONELINE },
+ { "kKeEeEpPeEnNdD", 0, HL_KEEPEND },
+ { "eExXtTeEnNdD", 0, HL_EXTEND },
+ { "eExXcClLuUdDeEnNlL", 0, HL_EXCLUDENL },
+ { "tTrRaAnNsSpPaArReEnNtT", 0, HL_TRANSP },
+ { "sSkKiIpPnNlL", 0, HL_SKIPNL },
+ { "sSkKiIpPwWhHiItTeE", 0, HL_SKIPWHITE },
+ { "sSkKiIpPeEmMpPtTyY", 0, HL_SKIPEMPTY },
+ { "gGrRoOuUpPhHeErReE", 0, HL_SYNC_HERE },
+ { "gGrRoOuUpPtThHeErReE", 0, HL_SYNC_THERE },
+ { "dDiIsSpPlLaAyY", 0, HL_DISPLAY },
+ { "fFoOlLdD", 0, HL_FOLD },
+ { "cCoOnNcCeEaAlL", 0, HL_CONCEAL },
+ { "cCoOnNcCeEaAlLeEnNdDsS", 0, HL_CONCEALENDS },
+ { "cCcChHaArR", 11, 0 },
+ { "cCoOnNtTaAiInNsS", 1, 0 },
+ { "cCoOnNtTaAiInNeEdDiInN", 2, 0 },
+ { "nNeExXtTgGrRoOuUpP", 3, 0 }, };
static const char *const first_letters = "cCoOkKeEtTsSgGdDfFnN";
- if (arg == NULL) /* already detected error */
+ if (arg == NULL) { // already detected error
return NULL;
+ }
- if (curwin->w_s->b_syn_conceal)
+ if (curwin->w_s->b_syn_conceal) {
opt->flags |= HL_CONCEAL;
+ }
for (;; ) {
/*
@@ -4123,15 +4201,17 @@ get_syn_options(
* Need to skip quickly when no option name is found.
* Also avoid tolower(), it's slow.
*/
- if (strchr(first_letters, *arg) == NULL)
+ if (strchr(first_letters, *arg) == NULL) {
break;
+ }
for (fidx = ARRAY_SIZE(flagtab); --fidx >= 0; ) {
p = flagtab[fidx].name;
int i;
for (i = 0, len = 0; p[i] != NUL; i += 2, ++len) {
- if (arg[len] != p[i] && arg[len] != p[i + 1])
+ if (arg[len] != p[i] && arg[len] != p[i + 1]) {
break;
+ }
}
if (p[i] == NUL && (ascii_iswhite(arg[len])
|| (flagtab[fidx].argtype > 0
@@ -4140,14 +4220,16 @@ get_syn_options(
if (opt->keyword
&& (flagtab[fidx].flags == HL_DISPLAY
|| flagtab[fidx].flags == HL_FOLD
- || flagtab[fidx].flags == HL_EXTEND))
- /* treat "display", "fold" and "extend" as a keyword */
+ || flagtab[fidx].flags == HL_EXTEND)) {
+ // treat "display", "fold" and "extend" as a keyword
fidx = -1;
+ }
break;
}
}
- if (fidx < 0) /* no match found */
+ if (fidx < 0) { // no match found
break;
+ }
if (flagtab[fidx].argtype == 1) {
if (!opt->has_cont_list) {
@@ -4157,15 +4239,15 @@ get_syn_options(
if (get_id_list(&arg, 8, &opt->cont_list, skip) == FAIL) {
return NULL;
}
- } else if (flagtab[fidx].argtype == 2) {
+ } else if (flagtab[fidx].argtype == 2) {
if (get_id_list(&arg, 11, &opt->cont_in_list, skip) == FAIL) {
return NULL;
}
- } else if (flagtab[fidx].argtype == 3) {
+ } else if (flagtab[fidx].argtype == 3) {
if (get_id_list(&arg, 9, &opt->next_list, skip) == FAIL) {
return NULL;
}
- } else if (flagtab[fidx].argtype == 11 && arg[5] == '=') {
+ } else if (flagtab[fidx].argtype == 11 && arg[5] == '=') {
// cchar=?
*conceal_char = utf_ptr2char(arg + 6);
arg += mb_ptr2len(arg + 6) - 1;
@@ -4186,20 +4268,22 @@ get_syn_options(
}
gname_start = arg;
arg = skiptowhite(arg);
- if (gname_start == arg)
+ if (gname_start == arg) {
return NULL;
+ }
gname = vim_strnsave(gname_start, arg - gname_start);
if (STRCMP(gname, "NONE") == 0) {
*opt->sync_idx = NONE_IDX;
} else {
syn_id = syn_name2id(gname);
int i;
- for (i = curwin->w_s->b_syn_patterns.ga_len; --i >= 0; )
+ for (i = curwin->w_s->b_syn_patterns.ga_len; --i >= 0; ) {
if (SYN_ITEMS(curwin->w_s)[i].sp_syn.id == syn_id
&& SYN_ITEMS(curwin->w_s)[i].sp_type == SPTYPE_START) {
*opt->sync_idx = i;
break;
}
+ }
if (i < 0) {
EMSG2(_("E394: Didn't find region item for %s"), gname);
xfree(gname);
@@ -4210,9 +4294,10 @@ get_syn_options(
xfree(gname);
arg = skipwhite(arg);
} else if (flagtab[fidx].flags == HL_FOLD
- && foldmethodIsSyntax(curwin))
- /* Need to update folds later. */
+ && foldmethodIsSyntax(curwin)) {
+ // Need to update folds later.
foldUpdateAll(curwin);
+ }
}
}
@@ -4226,8 +4311,9 @@ get_syn_options(
*/
static void syn_incl_toplevel(int id, int *flagsp)
{
- if ((*flagsp & HL_CONTAINED) || curwin->w_s->b_syn_topgrp == 0)
+ if ((*flagsp & HL_CONTAINED) || curwin->w_s->b_syn_topgrp == 0) {
return;
+ }
*flagsp |= HL_CONTAINED;
if (curwin->w_s->b_syn_topgrp >= SYNID_CLUSTER) {
// We have to alloc this, because syn_combine_list() will free it.
@@ -4237,7 +4323,7 @@ static void syn_incl_toplevel(int id, int *flagsp)
grp_list[0] = id;
grp_list[1] = 0;
syn_combine_list(&SYN_CLSTR(curwin->w_s)[tlg_id].scl_list, &grp_list,
- CLUSTER_ADD);
+ CLUSTER_ADD);
}
}
@@ -4246,18 +4332,19 @@ static void syn_incl_toplevel(int id, int *flagsp)
*/
static void syn_cmd_include(exarg_T *eap, int syncing)
{
- char_u *arg = eap->arg;
+ char_u *arg = eap->arg;
int sgl_id = 1;
- char_u *group_name_end;
- char_u *rest;
- char_u *errormsg = NULL;
+ char_u *group_name_end;
+ char_u *rest;
+ char_u *errormsg = NULL;
int prev_toplvl_grp;
int prev_syn_inc_tag;
- int source = FALSE;
+ bool source = false;
eap->nextcmd = find_nextcmd(arg);
- if (eap->skip)
+ if (eap->skip) {
return;
+ }
if (arg[0] == '@') {
++arg;
@@ -4267,9 +4354,10 @@ static void syn_cmd_include(exarg_T *eap, int syncing)
return;
}
sgl_id = syn_check_cluster(arg, (int)(group_name_end - arg));
- if (sgl_id == 0)
+ if (sgl_id == 0) {
return;
- /* separate_nextcmd() and expand_filename() depend on this */
+ }
+ // separate_nextcmd() and expand_filename() depend on this
eap->arg = rest;
}
@@ -4285,8 +4373,9 @@ static void syn_cmd_include(exarg_T *eap, int syncing)
// ":runtime!" is used.
source = true;
if (expand_filename(eap, syn_cmdlinep, &errormsg) == FAIL) {
- if (errormsg != NULL)
+ if (errormsg != NULL) {
EMSG(errormsg);
+ }
return;
}
}
@@ -4305,7 +4394,7 @@ static void syn_cmd_include(exarg_T *eap, int syncing)
curwin->w_s->b_syn_topgrp = sgl_id;
if (source
? do_source(eap->arg, false, DOSO_NONE) == FAIL
- : source_in_path(p_rtp, eap->arg, DIP_ALL) == FAIL) {
+ : source_runtime(eap->arg, DIP_ALL) == FAIL) {
EMSG2(_(e_notopen), eap->arg);
}
curwin->w_s->b_syn_topgrp = prev_toplvl_grp;
@@ -4317,13 +4406,13 @@ static void syn_cmd_include(exarg_T *eap, int syncing)
*/
static void syn_cmd_keyword(exarg_T *eap, int syncing)
{
- char_u *arg = eap->arg;
- char_u *group_name_end;
+ char_u *arg = eap->arg;
+ char_u *group_name_end;
int syn_id;
- char_u *rest;
- char_u *keyword_copy = NULL;
- char_u *p;
- char_u *kw;
+ char_u *rest;
+ char_u *keyword_copy = NULL;
+ char_u *p;
+ char_u *kw;
syn_opt_arg_T syn_opt_arg;
int cnt;
int conceal_char = NUL;
@@ -4413,39 +4502,36 @@ error:
}
}
- if (rest != NULL)
+ if (rest != NULL) {
eap->nextcmd = check_nextcmd(rest);
- else
+ } else {
EMSG2(_(e_invarg2), arg);
+ }
redraw_curbuf_later(SOME_VALID);
- syn_stack_free_all(curwin->w_s); /* Need to recompute all syntax. */
+ syn_stack_free_all(curwin->w_s); // Need to recompute all syntax.
}
-/*
- * Handle ":syntax match {name} [{options}] {pattern} [{options}]".
- *
- * Also ":syntax sync match {name} [[grouphere | groupthere] {group-name}] .."
- */
-static void
-syn_cmd_match(
- exarg_T *eap,
- int syncing /* TRUE for ":syntax sync match .. " */
-)
-{
- char_u *arg = eap->arg;
- char_u *group_name_end;
- char_u *rest;
- synpat_T item; /* the item found in the line */
+/// Handle ":syntax match {name} [{options}] {pattern} [{options}]".
+///
+/// Also ":syntax sync match {name} [[grouphere | groupthere] {group-name}] .."
+///
+/// @param syncing TRUE for ":syntax sync match .. "
+static void syn_cmd_match(exarg_T *eap, int syncing)
+{
+ char_u *arg = eap->arg;
+ char_u *group_name_end;
+ char_u *rest;
+ synpat_T item; // the item found in the line
int syn_id;
syn_opt_arg_T syn_opt_arg;
int sync_idx = 0;
int conceal_char = NUL;
- /* Isolate the group name, check for validity */
+ // Isolate the group name, check for validity
rest = get_group_name(arg, &group_name_end);
- /* Get options before the pattern */
+ // Get options before the pattern
syn_opt_arg.flags = 0;
syn_opt_arg.keyword = false;
syn_opt_arg.sync_idx = syncing ? &sync_idx : NULL;
@@ -4455,7 +4541,7 @@ syn_cmd_match(
syn_opt_arg.next_list = NULL;
rest = get_syn_options(rest, &syn_opt_arg, &conceal_char, eap->skip);
- /* get the pattern. */
+ // get the pattern.
init_syn_patterns();
memset(&item, 0, sizeof(item));
rest = get_syn_pattern(rest, &item);
@@ -4466,14 +4552,14 @@ syn_cmd_match(
// Get options after the pattern
rest = get_syn_options(rest, &syn_opt_arg, &conceal_char, eap->skip);
- if (rest != NULL) { /* all arguments are valid */
+ if (rest != NULL) { // all arguments are valid
/*
* Check for trailing command and illegal trailing arguments.
*/
eap->nextcmd = check_nextcmd(rest);
- if (!ends_excmd(*rest) || eap->skip)
+ if (!ends_excmd(*rest) || eap->skip) {
rest = NULL;
- else {
+ } else {
if ((syn_id = syn_check_group(arg, (int)(group_name_end - arg))) != 0) {
syn_incl_toplevel(syn_id, &syn_opt_arg.flags);
/*
@@ -4491,19 +4577,22 @@ syn_cmd_match(
spp->sp_cont_list = syn_opt_arg.cont_list;
spp->sp_syn.cont_in_list = syn_opt_arg.cont_in_list;
spp->sp_cchar = conceal_char;
- if (syn_opt_arg.cont_in_list != NULL)
+ if (syn_opt_arg.cont_in_list != NULL) {
curwin->w_s->b_syn_containedin = TRUE;
+ }
spp->sp_next_list = syn_opt_arg.next_list;
- /* remember that we found a match for syncing on */
- if (syn_opt_arg.flags & (HL_SYNC_HERE|HL_SYNC_THERE))
+ // remember that we found a match for syncing on
+ if (syn_opt_arg.flags & (HL_SYNC_HERE|HL_SYNC_THERE)) {
curwin->w_s->b_syn_sync_flags |= SF_MATCH;
- if (syn_opt_arg.flags & HL_FOLD)
+ }
+ if (syn_opt_arg.flags & HL_FOLD) {
++curwin->w_s->b_syn_folditems;
+ }
redraw_curbuf_later(SOME_VALID);
- syn_stack_free_all(curwin->w_s); /* Need to recompute all syntax. */
- return; /* don't free the progs and patterns now */
+ syn_stack_free_all(curwin->w_s); // Need to recompute all syntax.
+ return; // don't free the progs and patterns now
}
}
}
@@ -4517,49 +4606,46 @@ syn_cmd_match(
xfree(syn_opt_arg.cont_in_list);
xfree(syn_opt_arg.next_list);
- if (rest == NULL)
+ if (rest == NULL) {
EMSG2(_(e_invarg2), arg);
+ }
}
-/*
- * Handle ":syntax region {group-name} [matchgroup={group-name}]
- * start {start} .. [skip {skip}] end {end} .. [{options}]".
- */
-static void
-syn_cmd_region(
- exarg_T *eap,
- int syncing /* TRUE for ":syntax sync region .." */
-)
-{
- char_u *arg = eap->arg;
- char_u *group_name_end;
- char_u *rest; /* next arg, NULL on error */
- char_u *key_end;
- char_u *key = NULL;
- char_u *p;
+/// Handle ":syntax region {group-name} [matchgroup={group-name}]
+/// start {start} .. [skip {skip}] end {end} .. [{options}]".
+///
+/// @param syncing TRUE for ":syntax sync region .."
+static void syn_cmd_region(exarg_T *eap, int syncing)
+{
+ char_u *arg = eap->arg;
+ char_u *group_name_end;
+ char_u *rest; // next arg, NULL on error
+ char_u *key_end;
+ char_u *key = NULL;
+ char_u *p;
int item;
#define ITEM_START 0
#define ITEM_SKIP 1
#define ITEM_END 2
#define ITEM_MATCHGROUP 3
struct pat_ptr {
- synpat_T *pp_synp; /* pointer to syn_pattern */
- int pp_matchgroup_id; /* matchgroup ID */
- struct pat_ptr *pp_next; /* pointer to next pat_ptr */
+ synpat_T *pp_synp; // pointer to syn_pattern
+ int pp_matchgroup_id; // matchgroup ID
+ struct pat_ptr *pp_next; // pointer to next pat_ptr
} *(pat_ptrs[3]);
- /* patterns found in the line */
- struct pat_ptr *ppp;
- struct pat_ptr *ppp_next;
- int pat_count = 0; /* nr of syn_patterns found */
+ // patterns found in the line
+ struct pat_ptr *ppp;
+ struct pat_ptr *ppp_next;
+ int pat_count = 0; // nr of syn_patterns found
int syn_id;
int matchgroup_id = 0;
- int not_enough = FALSE; /* not enough arguments */
- int illegal = FALSE; /* illegal arguments */
- int success = FALSE;
+ bool not_enough = false; // not enough arguments
+ bool illegal = false; // illegal arguments
+ bool success = false;
syn_opt_arg_T syn_opt_arg;
int conceal_char = NUL;
- /* Isolate the group name, check for validity */
+ // Isolate the group name, check for validity
rest = get_group_name(arg, &group_name_end);
pat_ptrs[0] = NULL;
@@ -4584,10 +4670,11 @@ syn_cmd_region(
break;
}
- /* must be a pattern or matchgroup then */
+ // must be a pattern or matchgroup then
key_end = rest;
- while (*key_end && !ascii_iswhite(*key_end) && *key_end != '=')
+ while (*key_end && !ascii_iswhite(*key_end) && *key_end != '=') {
++key_end;
+ }
xfree(key);
key = vim_strnsave_up(rest, key_end - rest);
if (STRCMP(key, "MATCHGROUP") == 0) {
@@ -4613,18 +4700,18 @@ syn_cmd_region(
}
rest = skipwhite(rest + 1);
if (*rest == NUL) {
- not_enough = TRUE;
+ not_enough = true;
break;
}
if (item == ITEM_MATCHGROUP) {
p = skiptowhite(rest);
- if ((p - rest == 4 && STRNCMP(rest, "NONE", 4) == 0) || eap->skip)
+ if ((p - rest == 4 && STRNCMP(rest, "NONE", 4) == 0) || eap->skip) {
matchgroup_id = 0;
- else {
+ } else {
matchgroup_id = syn_check_group(rest, (int)(p - rest));
if (matchgroup_id == 0) {
- illegal = TRUE;
+ illegal = true;
break;
}
}
@@ -4660,8 +4747,9 @@ syn_cmd_region(
}
}
xfree(key);
- if (illegal || not_enough)
+ if (illegal || not_enough) {
rest = NULL;
+ }
// Must have a "start" and "end" pattern.
if (rest != NULL && (pat_ptrs[ITEM_START] == NULL
@@ -4676,9 +4764,9 @@ syn_cmd_region(
* If OK, add the item.
*/
eap->nextcmd = check_nextcmd(rest);
- if (!ends_excmd(*rest) || eap->skip)
+ if (!ends_excmd(*rest) || eap->skip) {
rest = NULL;
- else {
+ } else {
ga_grow(&(curwin->w_s->b_syn_patterns), pat_count);
if ((syn_id = syn_check_group(arg, (int)(group_name_end - arg))) != 0) {
syn_incl_toplevel(syn_id, &syn_opt_arg.flags);
@@ -4705,21 +4793,23 @@ syn_cmd_region(
syn_opt_arg.cont_list;
SYN_ITEMS(curwin->w_s)[idx].sp_syn.cont_in_list =
syn_opt_arg.cont_in_list;
- if (syn_opt_arg.cont_in_list != NULL)
+ if (syn_opt_arg.cont_in_list != NULL) {
curwin->w_s->b_syn_containedin = TRUE;
+ }
SYN_ITEMS(curwin->w_s)[idx].sp_next_list =
syn_opt_arg.next_list;
}
++curwin->w_s->b_syn_patterns.ga_len;
++idx;
- if (syn_opt_arg.flags & HL_FOLD)
+ if (syn_opt_arg.flags & HL_FOLD) {
++curwin->w_s->b_syn_folditems;
+ }
}
}
redraw_curbuf_later(SOME_VALID);
- syn_stack_free_all(curwin->w_s); /* Need to recompute all syntax. */
- success = TRUE; /* don't free the progs and patterns now */
+ syn_stack_free_all(curwin->w_s); // Need to recompute all syntax.
+ success = true; // don't free the progs and patterns now
}
}
}
@@ -4727,7 +4817,7 @@ syn_cmd_region(
/*
* Free the allocated memory.
*/
- for (item = ITEM_START; item <= ITEM_END; ++item)
+ for (item = ITEM_START; item <= ITEM_END; ++item) {
for (ppp = pat_ptrs[item]; ppp != NULL; ppp = ppp_next) {
if (!success && ppp->pp_synp != NULL) {
vim_regfree(ppp->pp_synp->sp_prog);
@@ -4737,15 +4827,17 @@ syn_cmd_region(
ppp_next = ppp->pp_next;
xfree(ppp);
}
+ }
if (!success) {
xfree(syn_opt_arg.cont_list);
xfree(syn_opt_arg.cont_in_list);
xfree(syn_opt_arg.next_list);
- if (not_enough)
+ if (not_enough) {
EMSG2(_("E399: Not enough arguments: syntax region %s"), arg);
- else if (illegal || rest == NULL)
+ } else if (illegal || rest == NULL) {
EMSG2(_(e_invarg2), arg);
+ }
}
}
@@ -4760,8 +4852,7 @@ static int syn_compare_stub(const void *const v1, const void *const v2)
// Combines lists of syntax clusters.
// *clstr1 and *clstr2 must both be allocated memory; they will be consumed.
-static void syn_combine_list(int16_t **const clstr1, int16_t **const clstr2,
- const int list_op)
+static void syn_combine_list(int16_t **const clstr1, int16_t **const clstr2, const int list_op)
{
size_t count1 = 0;
size_t count2 = 0;
@@ -4772,15 +4863,18 @@ static void syn_combine_list(int16_t **const clstr1, int16_t **const clstr2,
/*
* Handle degenerate cases.
*/
- if (*clstr2 == NULL)
+ if (*clstr2 == NULL) {
return;
+ }
if (*clstr1 == NULL || list_op == CLUSTER_REPLACE) {
- if (list_op == CLUSTER_REPLACE)
+ if (list_op == CLUSTER_REPLACE) {
xfree(*clstr1);
- if (list_op == CLUSTER_REPLACE || list_op == CLUSTER_ADD)
+ }
+ if (list_op == CLUSTER_REPLACE || list_op == CLUSTER_ADD) {
*clstr1 = *clstr2;
- else
+ } else {
xfree(*clstr2);
+ }
return;
}
@@ -4812,8 +4906,9 @@ static void syn_combine_list(int16_t **const clstr1, int16_t **const clstr2,
* We always want to add from the first list.
*/
if (*g1 < *g2) {
- if (round == 2)
+ if (round == 2) {
clstr[count] = *g1;
+ }
count++;
g1++;
continue;
@@ -4823,12 +4918,14 @@ static void syn_combine_list(int16_t **const clstr1, int16_t **const clstr2,
* lists.
*/
if (list_op == CLUSTER_ADD) {
- if (round == 2)
+ if (round == 2) {
clstr[count] = *g2;
+ }
count++;
}
- if (*g1 == *g2)
+ if (*g1 == *g2) {
g1++;
+ }
g2++;
}
@@ -4837,13 +4934,18 @@ static void syn_combine_list(int16_t **const clstr1, int16_t **const clstr2,
* first. As before, we only want to add from the second list if
* we're adding the lists.
*/
- for (; *g1; g1++, count++)
- if (round == 2)
+ for (; *g1; g1++, count++) {
+ if (round == 2) {
clstr[count] = *g1;
- if (list_op == CLUSTER_ADD)
- for (; *g2; g2++, count++)
- if (round == 2)
+ }
+ }
+ if (list_op == CLUSTER_ADD) {
+ for (; *g2; g2++, count++) {
+ if (round == 2) {
clstr[count] = *g2;
+ }
+ }
+ }
if (round == 1) {
/*
@@ -4903,15 +5005,16 @@ static int syn_scl_namen2id(char_u *linep, int len)
static int syn_check_cluster(char_u *pp, int len)
{
int id;
- char_u *name;
+ char_u *name;
name = vim_strnsave(pp, len);
id = syn_scl_name2id(name);
- if (id == 0) /* doesn't exist yet */
+ if (id == 0) { // doesn't exist yet
id = syn_add_cluster(name);
- else
+ } else {
xfree(name);
+ }
return id;
}
@@ -4942,30 +5045,33 @@ static int syn_add_cluster(char_u *name)
scp->scl_name_u = vim_strsave_up(name);
scp->scl_list = NULL;
- if (STRICMP(name, "Spell") == 0)
+ if (STRICMP(name, "Spell") == 0) {
curwin->w_s->b_spell_cluster_id = len + SYNID_CLUSTER;
- if (STRICMP(name, "NoSpell") == 0)
+ }
+ if (STRICMP(name, "NoSpell") == 0) {
curwin->w_s->b_nospell_cluster_id = len + SYNID_CLUSTER;
+ }
return len + SYNID_CLUSTER;
}
/*
* Handle ":syntax cluster {cluster-name} [contains={groupname},..]
- * [add={groupname},..] [remove={groupname},..]".
+ * [add={groupname},..] [remove={groupname},..]".
*/
static void syn_cmd_cluster(exarg_T *eap, int syncing)
{
- char_u *arg = eap->arg;
- char_u *group_name_end;
- char_u *rest;
+ char_u *arg = eap->arg;
+ char_u *group_name_end;
+ char_u *rest;
bool got_clstr = false;
int opt_len;
int list_op;
eap->nextcmd = find_nextcmd(arg);
- if (eap->skip)
+ if (eap->skip) {
return;
+ }
rest = get_group_name(arg, &group_name_end);
@@ -4989,8 +5095,9 @@ static void syn_cmd_cluster(exarg_T *eap, int syncing)
&& (ascii_iswhite(rest[8]) || rest[8] == '=')) {
opt_len = 8;
list_op = CLUSTER_REPLACE;
- } else
+ } else {
break;
+ }
int16_t *clstr_list = NULL;
if (get_id_list(&rest, opt_len, &clstr_list, eap->skip) == FAIL) {
@@ -5008,14 +5115,16 @@ static void syn_cmd_cluster(exarg_T *eap, int syncing)
if (got_clstr) {
redraw_curbuf_later(SOME_VALID);
- syn_stack_free_all(curwin->w_s); /* Need to recompute all. */
+ syn_stack_free_all(curwin->w_s); // Need to recompute all.
}
}
- if (!got_clstr)
+ if (!got_clstr) {
EMSG(_("E400: No cluster specified"));
- if (rest == NULL || !ends_excmd(*rest))
+ }
+ if (rest == NULL || !ends_excmd(*rest)) {
EMSG2(_(e_invarg2), arg);
+ }
}
/*
@@ -5034,10 +5143,10 @@ static void init_syn_patterns(void)
*/
static char_u *get_syn_pattern(char_u *arg, synpat_T *ci)
{
- char_u *end;
- int *p;
+ char_u *end;
+ int *p;
int idx;
- char_u *cpo_save;
+ char_u *cpo_save;
// need at least three chars
if (arg == NULL || arg[0] == NUL || arg[1] == NUL || arg[2] == NUL) {
@@ -5045,21 +5154,22 @@ static char_u *get_syn_pattern(char_u *arg, synpat_T *ci)
}
end = skip_regexp(arg + 1, *arg, TRUE, NULL);
- if (*end != *arg) { /* end delimiter not found */
+ if (*end != *arg) { // end delimiter not found
EMSG2(_("E401: Pattern delimiter not found: %s"), arg);
return NULL;
}
// store the pattern and compiled regexp program
ci->sp_pattern = vim_strnsave(arg + 1, end - arg - 1);
- /* Make 'cpoptions' empty, to avoid the 'l' flag */
+ // Make 'cpoptions' empty, to avoid the 'l' flag
cpo_save = p_cpo;
p_cpo = (char_u *)"";
ci->sp_prog = vim_regcomp(ci->sp_pattern, RE_MAGIC);
p_cpo = cpo_save;
- if (ci->sp_prog == NULL)
+ if (ci->sp_prog == NULL) {
return NULL;
+ }
ci->sp_ic = curwin->w_s->b_syn_ic;
syn_clear_time(&ci->sp_time);
@@ -5068,41 +5178,49 @@ static char_u *get_syn_pattern(char_u *arg, synpat_T *ci)
*/
++end;
do {
- for (idx = SPO_COUNT; --idx >= 0; )
- if (STRNCMP(end, spo_name_tab[idx], 3) == 0)
+ for (idx = SPO_COUNT; --idx >= 0; ) {
+ if (STRNCMP(end, spo_name_tab[idx], 3) == 0) {
break;
+ }
+ }
if (idx >= 0) {
p = &(ci->sp_offsets[idx]);
- if (idx != SPO_LC_OFF)
+ if (idx != SPO_LC_OFF) {
switch (end[3]) {
- case 's': break;
- case 'b': break;
- case 'e': idx += SPO_COUNT; break;
- default: idx = -1; break;
+ case 's':
+ break;
+ case 'b':
+ break;
+ case 'e':
+ idx += SPO_COUNT; break;
+ default:
+ idx = -1; break;
}
+ }
if (idx >= 0) {
ci->sp_off_flags |= (1 << idx);
- if (idx == SPO_LC_OFF) { /* lc=99 */
+ if (idx == SPO_LC_OFF) { // lc=99
end += 3;
*p = getdigits_int(&end, true, 0);
- /* "lc=" offset automatically sets "ms=" offset */
+ // "lc=" offset automatically sets "ms=" offset
if (!(ci->sp_off_flags & (1 << SPO_MS_OFF))) {
ci->sp_off_flags |= (1 << SPO_MS_OFF);
ci->sp_offsets[SPO_MS_OFF] = *p;
}
- } else { /* yy=x+99 */
+ } else { // yy=x+99
end += 4;
if (*end == '+') {
end++;
*p = getdigits_int(&end, true, 0); // positive offset
- } else if (*end == '-') {
+ } else if (*end == '-') {
end++;
*p = -getdigits_int(&end, true, 0); // negative offset
}
}
- if (*end != ',')
+ if (*end != ',') {
break;
+ }
++end;
}
}
@@ -5120,14 +5238,14 @@ static char_u *get_syn_pattern(char_u *arg, synpat_T *ci)
*/
static void syn_cmd_sync(exarg_T *eap, int syncing)
{
- char_u *arg_start = eap->arg;
- char_u *arg_end;
- char_u *key = NULL;
- char_u *next_arg;
+ char_u *arg_start = eap->arg;
+ char_u *arg_end;
+ char_u *key = NULL;
+ char_u *next_arg;
int illegal = FALSE;
int finished = FALSE;
long n;
- char_u *cpo_save;
+ char_u *cpo_save;
if (ends_excmd(*arg_start)) {
syn_cmd_list(eap, TRUE);
@@ -5140,45 +5258,50 @@ static void syn_cmd_sync(exarg_T *eap, int syncing)
xfree(key);
key = vim_strnsave_up(arg_start, arg_end - arg_start);
if (STRCMP(key, "CCOMMENT") == 0) {
- if (!eap->skip)
+ if (!eap->skip) {
curwin->w_s->b_syn_sync_flags |= SF_CCOMMENT;
+ }
if (!ends_excmd(*next_arg)) {
arg_end = skiptowhite(next_arg);
- if (!eap->skip)
+ if (!eap->skip) {
curwin->w_s->b_syn_sync_id = syn_check_group(next_arg,
- (int)(arg_end - next_arg));
+ (int)(arg_end - next_arg));
+ }
next_arg = skipwhite(arg_end);
- } else if (!eap->skip)
+ } else if (!eap->skip) {
curwin->w_s->b_syn_sync_id = syn_name2id((char_u *)"Comment");
- } else if ( STRNCMP(key, "LINES", 5) == 0
- || STRNCMP(key, "MINLINES", 8) == 0
- || STRNCMP(key, "MAXLINES", 8) == 0
- || STRNCMP(key, "LINEBREAKS", 10) == 0) {
- if (key[4] == 'S')
+ }
+ } else if (STRNCMP(key, "LINES", 5) == 0
+ || STRNCMP(key, "MINLINES", 8) == 0
+ || STRNCMP(key, "MAXLINES", 8) == 0
+ || STRNCMP(key, "LINEBREAKS", 10) == 0) {
+ if (key[4] == 'S') {
arg_end = key + 6;
- else if (key[0] == 'L')
+ } else if (key[0] == 'L') {
arg_end = key + 11;
- else
+ } else {
arg_end = key + 9;
+ }
if (arg_end[-1] != '=' || !ascii_isdigit(*arg_end)) {
illegal = TRUE;
break;
}
n = getdigits_long(&arg_end, false, 0);
if (!eap->skip) {
- if (key[4] == 'B')
+ if (key[4] == 'B') {
curwin->w_s->b_syn_sync_linebreaks = n;
- else if (key[1] == 'A')
+ } else if (key[1] == 'A') {
curwin->w_s->b_syn_sync_maxlines = n;
- else
+ } else {
curwin->w_s->b_syn_sync_minlines = n;
+ }
}
- } else if (STRCMP(key, "FROMSTART") == 0) {
+ } else if (STRCMP(key, "FROMSTART") == 0) {
if (!eap->skip) {
curwin->w_s->b_syn_sync_minlines = MAXLNUM;
curwin->w_s->b_syn_sync_maxlines = 0;
}
- } else if (STRCMP(key, "LINECONT") == 0) {
+ } else if (STRCMP(key, "LINECONT") == 0) {
if (*next_arg == NUL) { // missing pattern
illegal = true;
break;
@@ -5189,18 +5312,18 @@ static void syn_cmd_sync(exarg_T *eap, int syncing)
break;
}
arg_end = skip_regexp(next_arg + 1, *next_arg, TRUE, NULL);
- if (*arg_end != *next_arg) { /* end delimiter not found */
+ if (*arg_end != *next_arg) { // end delimiter not found
illegal = TRUE;
break;
}
if (!eap->skip) {
- /* store the pattern and compiled regexp program */
+ // store the pattern and compiled regexp program
curwin->w_s->b_syn_linecont_pat =
vim_strnsave(next_arg + 1, arg_end - next_arg - 1);
curwin->w_s->b_syn_linecont_ic = curwin->w_s->b_syn_ic;
- /* Make 'cpoptions' empty, to avoid the 'l' flag */
+ // Make 'cpoptions' empty, to avoid the 'l' flag
cpo_save = p_cpo;
p_cpo = (char_u *)"";
curwin->w_s->b_syn_linecont_prog =
@@ -5217,47 +5340,43 @@ static void syn_cmd_sync(exarg_T *eap, int syncing)
next_arg = skipwhite(arg_end + 1);
} else {
eap->arg = next_arg;
- if (STRCMP(key, "MATCH") == 0)
+ if (STRCMP(key, "MATCH") == 0) {
syn_cmd_match(eap, TRUE);
- else if (STRCMP(key, "REGION") == 0)
+ } else if (STRCMP(key, "REGION") == 0) {
syn_cmd_region(eap, TRUE);
- else if (STRCMP(key, "CLEAR") == 0)
+ } else if (STRCMP(key, "CLEAR") == 0) {
syn_cmd_clear(eap, TRUE);
- else
+ } else {
illegal = TRUE;
+ }
finished = TRUE;
break;
}
arg_start = next_arg;
}
xfree(key);
- if (illegal)
+ if (illegal) {
EMSG2(_("E404: Illegal arguments: %s"), arg_start);
- else if (!finished) {
+ } else if (!finished) {
eap->nextcmd = check_nextcmd(arg_start);
redraw_curbuf_later(SOME_VALID);
- syn_stack_free_all(curwin->w_s); /* Need to recompute all syntax. */
+ syn_stack_free_all(curwin->w_s); // Need to recompute all syntax.
}
}
-/*
- * Convert a line of highlight group names into a list of group ID numbers.
- * "arg" should point to the "contains" or "nextgroup" keyword.
- * "arg" is advanced to after the last group name.
- * Careful: the argument is modified (NULs added).
- * returns FAIL for some error, OK for success.
- */
-static int
-get_id_list(
- char_u **const arg,
- const int keylen, // length of keyword
- int16_t **const list, // where to store the resulting list, if not
- // NULL, the list is silently skipped!
- const bool skip
-)
-{
- char_u *p = NULL;
- char_u *end;
+/// Convert a line of highlight group names into a list of group ID numbers.
+/// "arg" should point to the "contains" or "nextgroup" keyword.
+/// "arg" is advanced to after the last group name.
+/// Careful: the argument is modified (NULs added).
+///
+/// @param keylen length of keyword
+/// @param list where to store the resulting list, if not NULL, the list is silently skipped!
+///
+/// @return FAIL for some error, OK for success.
+static int get_id_list(char_u **const arg, const int keylen, int16_t **const list, const bool skip)
+{
+ char_u *p = NULL;
+ char_u *end;
int total_count = 0;
int16_t *retval = NULL;
regmatch_T regmatch;
@@ -5289,10 +5408,10 @@ get_id_list(
}
char_u *const name = xmalloc((int)(end - p + 3)); // leave room for "^$"
STRLCPY(name + 1, p, end - p + 1);
- if ( STRCMP(name + 1, "ALLBUT") == 0
- || STRCMP(name + 1, "ALL") == 0
- || STRCMP(name + 1, "TOP") == 0
- || STRCMP(name + 1, "CONTAINED") == 0) {
+ if (STRCMP(name + 1, "ALLBUT") == 0
+ || STRCMP(name + 1, "ALL") == 0
+ || STRCMP(name + 1, "TOP") == 0
+ || STRCMP(name + 1, "CONTAINED") == 0) {
if (TOUPPER_ASC(**arg) != 'C') {
EMSG2(_("E407: %s not allowed here"), name + 1);
failed = true;
@@ -5317,7 +5436,7 @@ get_id_list(
} else {
id = SYNID_CONTAINED + current_syn_inc_tag;
}
- } else if (name[1] == '@') {
+ } else if (name[1] == '@') {
if (skip) {
id = -1;
} else {
@@ -5382,12 +5501,14 @@ get_id_list(
++count;
}
p = skipwhite(end);
- if (*p != ',')
+ if (*p != ',') {
break;
- p = skipwhite(p + 1); /* skip comma in between arguments */
+ }
+ p = skipwhite(p + 1); // skip comma in between arguments
} while (!ends_excmd(*p));
- if (failed)
+ if (failed) {
break;
+ }
if (round == 1) {
retval = xmalloc((count + 1) * sizeof(*retval));
retval[count] = 0; // zero means end of the list
@@ -5401,11 +5522,11 @@ get_id_list(
return FAIL;
}
- if (*list == NULL)
+ if (*list == NULL) {
*list = retval;
- else
- xfree(retval); /* list already found, don't overwrite it */
-
+ } else {
+ xfree(retval); // list already found, don't overwrite it
+ }
return OK;
}
@@ -5428,20 +5549,17 @@ static int16_t *copy_id_list(const int16_t *const list)
return retval;
}
-/*
- * Check if syntax group "ssp" is in the ID list "list" of "cur_si".
- * "cur_si" can be NULL if not checking the "containedin" list.
- * Used to check if a syntax item is in the "contains" or "nextgroup" list of
- * the current item.
- * This function is called very often, keep it fast!!
- */
-static int
-in_id_list(
- stateitem_T *cur_si, // current item or NULL
- int16_t *list, // id list
- struct sp_syn *ssp, // group id and ":syn include" tag of group
- int contained // group id is contained
-)
+/// Check if syntax group "ssp" is in the ID list "list" of "cur_si".
+/// "cur_si" can be NULL if not checking the "containedin" list.
+/// Used to check if a syntax item is in the "contains" or "nextgroup" list of
+/// the current item.
+/// This function is called very often, keep it fast!!
+///
+/// @param cur_si current item or NULL
+/// @param list id list
+/// @param ssp group id and ":syn include" tag of group
+/// @param contained group id is contained
+static int in_id_list(stateitem_T *cur_si, int16_t *list, struct sp_syn *ssp, int contained)
{
int retval;
int16_t *scl_list;
@@ -5450,30 +5568,35 @@ in_id_list(
static int depth = 0;
int r;
- /* If ssp has a "containedin" list and "cur_si" is in it, return TRUE. */
+ // If ssp has a "containedin" list and "cur_si" is in it, return TRUE.
if (cur_si != NULL && ssp->cont_in_list != NULL
&& !(cur_si->si_flags & HL_MATCH)) {
/* Ignore transparent items without a contains argument. Double check
* that we don't go back past the first one. */
while ((cur_si->si_flags & HL_TRANS_CONT)
- && cur_si > (stateitem_T *)(current_state.ga_data))
+ && cur_si > (stateitem_T *)(current_state.ga_data)) {
--cur_si;
- /* cur_si->si_idx is -1 for keywords, these never contain anything. */
+ }
+ // cur_si->si_idx is -1 for keywords, these never contain anything.
if (cur_si->si_idx >= 0 && in_id_list(NULL, ssp->cont_in_list,
- &(SYN_ITEMS(syn_block)[cur_si->si_idx].sp_syn),
- SYN_ITEMS(syn_block)[cur_si->si_idx].sp_flags & HL_CONTAINED))
+ &(SYN_ITEMS(syn_block)[cur_si->si_idx].sp_syn),
+ SYN_ITEMS(syn_block)[cur_si->si_idx].sp_flags &
+ HL_CONTAINED)) {
return TRUE;
+ }
}
- if (list == NULL)
+ if (list == NULL) {
return FALSE;
+ }
/*
* If list is ID_LIST_ALL, we are in a transparent item that isn't
* inside anything. Only allow not-contained groups.
*/
- if (list == ID_LIST_ALL)
+ if (list == ID_LIST_ALL) {
return !contained;
+ }
/*
* If the first item is "ALLBUT", return TRUE if "id" is NOT in the
@@ -5483,29 +5606,34 @@ in_id_list(
item = *list;
if (item >= SYNID_ALLBUT && item < SYNID_CLUSTER) {
if (item < SYNID_TOP) {
- /* ALL or ALLBUT: accept all groups in the same file */
- if (item - SYNID_ALLBUT != ssp->inc_tag)
+ // ALL or ALLBUT: accept all groups in the same file
+ if (item - SYNID_ALLBUT != ssp->inc_tag) {
return FALSE;
- } else if (item < SYNID_CONTAINED) {
- /* TOP: accept all not-contained groups in the same file */
- if (item - SYNID_TOP != ssp->inc_tag || contained)
+ }
+ } else if (item < SYNID_CONTAINED) {
+ // TOP: accept all not-contained groups in the same file
+ if (item - SYNID_TOP != ssp->inc_tag || contained) {
return FALSE;
+ }
} else {
- /* CONTAINED: accept all contained groups in the same file */
- if (item - SYNID_CONTAINED != ssp->inc_tag || !contained)
+ // CONTAINED: accept all contained groups in the same file
+ if (item - SYNID_CONTAINED != ssp->inc_tag || !contained) {
return FALSE;
+ }
}
item = *++list;
retval = FALSE;
- } else
+ } else {
retval = TRUE;
+ }
/*
* Return "retval" if id is in the contains list.
*/
while (item != 0) {
- if (item == id)
+ if (item == id) {
return retval;
+ }
if (item >= SYNID_CLUSTER) {
scl_list = SYN_CLSTR(syn_block)[item - SYNID_CLUSTER].scl_list;
/* restrict recursiveness to 30 to avoid an endless loop for a
@@ -5514,8 +5642,9 @@ in_id_list(
++depth;
r = in_id_list(NULL, scl_list, ssp, contained);
--depth;
- if (r)
+ if (r) {
return retval;
+ }
}
}
item = *++list;
@@ -5524,8 +5653,8 @@ in_id_list(
}
struct subcommand {
- char *name; /* subcommand name */
- void (*func)(exarg_T *, int); /* function to call */
+ char *name; // subcommand name
+ void (*func)(exarg_T *, int); // function to call
};
static struct subcommand subcommands[] =
@@ -5534,7 +5663,7 @@ static struct subcommand subcommands[] =
{ "clear", syn_cmd_clear },
{ "cluster", syn_cmd_cluster },
{ "conceal", syn_cmd_conceal },
- { "enable", syn_cmd_enable },
+ { "enable", syn_cmd_on },
{ "foldlevel", syn_cmd_foldlevel },
{ "include", syn_cmd_include },
{ "iskeyword", syn_cmd_iskeyword },
@@ -5559,8 +5688,8 @@ static struct subcommand subcommands[] =
*/
void ex_syntax(exarg_T *eap)
{
- char_u *arg = eap->arg;
- char_u *subcmd_end;
+ char_u *arg = eap->arg;
+ char_u *subcmd_end;
syn_cmdlinep = eap->cmdlinep;
@@ -5583,14 +5712,15 @@ void ex_syntax(exarg_T *eap)
}
}
xfree(subcmd_name);
- if (eap->skip)
+ if (eap->skip) {
--emsg_skip;
+ }
}
void ex_ownsyntax(exarg_T *eap)
{
- char_u *old_value;
- char_u *new_value;
+ char_u *old_value;
+ char_u *new_value;
if (curwin->w_s == &curwin->w_buffer->b_s) {
curwin->w_s = xmalloc(sizeof(synblock_T));
@@ -5613,9 +5743,8 @@ void ex_ownsyntax(exarg_T *eap)
old_value = vim_strsave(old_value);
}
- /* Apply the "syntax" autocommand event, this finds and loads the syntax
- * file. */
- apply_autocmds(EVENT_SYNTAX, eap->arg, curbuf->b_fname, TRUE, curbuf);
+ // Apply the "syntax" autocommand event, this finds and loads the syntax file.
+ apply_autocmds(EVENT_SYNTAX, eap->arg, curbuf->b_fname, true, curbuf);
// Move value of b:current_syntax to w:current_syntax.
new_value = get_var_value("b:current_syntax");
@@ -5680,7 +5809,7 @@ void set_context_in_syntax_cmd(expand_T *xp, const char *arg)
include_link = 0;
include_default = 0;
- /* (part of) subcommand already typed */
+ // (part of) subcommand already typed
if (*arg != NUL) {
const char *p = (const char *)skiptowhite((const char_u *)arg);
if (*p != NUL) { // Past first word.
@@ -5712,47 +5841,44 @@ void set_context_in_syntax_cmd(expand_T *xp, const char *arg)
char_u *get_syntax_name(expand_T *xp, int idx)
{
switch (expand_what) {
- case EXP_SUBCMD:
- return (char_u *)subcommands[idx].name;
- case EXP_CASE: {
- static char *case_args[] = { "match", "ignore", NULL };
- return (char_u *)case_args[idx];
- }
- case EXP_SPELL: {
- static char *spell_args[] =
- { "toplevel", "notoplevel", "default", NULL };
- return (char_u *)spell_args[idx];
- }
- case EXP_SYNC: {
- static char *sync_args[] =
- { "ccomment", "clear", "fromstart",
- "linebreaks=", "linecont", "lines=", "match",
- "maxlines=", "minlines=", "region", NULL };
- return (char_u *)sync_args[idx];
- }
+ case EXP_SUBCMD:
+ return (char_u *)subcommands[idx].name;
+ case EXP_CASE: {
+ static char *case_args[] = { "match", "ignore", NULL };
+ return (char_u *)case_args[idx];
+ }
+ case EXP_SPELL: {
+ static char *spell_args[] =
+ { "toplevel", "notoplevel", "default", NULL };
+ return (char_u *)spell_args[idx];
+ }
+ case EXP_SYNC: {
+ static char *sync_args[] =
+ { "ccomment", "clear", "fromstart",
+ "linebreaks=", "linecont", "lines=", "match",
+ "maxlines=", "minlines=", "region", NULL };
+ return (char_u *)sync_args[idx];
+ }
}
return NULL;
}
-// Function called for expression evaluation: get syntax ID at file position.
-int syn_get_id(
- win_T *wp,
- long lnum,
- colnr_T col,
- int trans, // remove transparency
- bool *spellp, // return: can do spell checking
- int keep_state // keep state of char at "col"
-)
+/// Function called for expression evaluation: get syntax ID at file position.
+///
+/// @param trans remove transparency
+/// @param spellp return: can do spell checking
+/// @param keep_state keep state of char at "col"
+int syn_get_id(win_T *wp, long lnum, colnr_T col, int trans, bool *spellp, int keep_state)
{
// When the position is not after the current position and in the same
// line of the same buffer, need to restart parsing.
if (wp->w_buffer != syn_buf || lnum != current_lnum || col < current_col) {
syntax_start(wp, lnum);
} else if (col > current_col) {
- // next_match may not be correct when moving around, e.g. with the
- // "skip" expression in searchpair()
- next_match_idx = -1;
+ // next_match may not be correct when moving around, e.g. with the
+ // "skip" expression in searchpair()
+ next_match_idx = -1;
}
(void)get_syntax_attr(col, spellp, keep_state);
@@ -5860,8 +5986,9 @@ int syn_get_foldlevel(win_T *wp, long lnum)
}
if (level > wp->w_p_fdn) {
level = wp->w_p_fdn;
- if (level < 0)
+ if (level < 0) {
level = 0;
+ }
}
return level;
}
@@ -5871,16 +5998,17 @@ int syn_get_foldlevel(win_T *wp, long lnum)
*/
void ex_syntime(exarg_T *eap)
{
- if (STRCMP(eap->arg, "on") == 0)
- syn_time_on = TRUE;
- else if (STRCMP(eap->arg, "off") == 0)
- syn_time_on = FALSE;
- else if (STRCMP(eap->arg, "clear") == 0)
+ if (STRCMP(eap->arg, "on") == 0) {
+ syn_time_on = true;
+ } else if (STRCMP(eap->arg, "off") == 0) {
+ syn_time_on = false;
+ } else if (STRCMP(eap->arg, "clear") == 0) {
syntime_clear();
- else if (STRCMP(eap->arg, "report") == 0)
+ } else if (STRCMP(eap->arg, "report") == 0) {
syntime_report();
- else
+ } else {
EMSG2(_(e_invarg2), eap->arg);
+ }
}
static void syn_clear_time(syn_time_T *st)
@@ -5896,7 +6024,7 @@ static void syn_clear_time(syn_time_T *st)
*/
static void syntime_clear(void)
{
- synpat_T *spp;
+ synpat_T *spp;
if (!syntax_present(curwin)) {
MSG(_(msg_no_items));
@@ -5915,18 +6043,22 @@ static void syntime_clear(void)
char_u *get_syntime_arg(expand_T *xp, int idx)
{
switch (idx) {
- case 0: return (char_u *)"on";
- case 1: return (char_u *)"off";
- case 2: return (char_u *)"clear";
- case 3: return (char_u *)"report";
+ case 0:
+ return (char_u *)"on";
+ case 1:
+ return (char_u *)"off";
+ case 2:
+ return (char_u *)"clear";
+ case 3:
+ return (char_u *)"report";
}
return NULL;
}
static int syn_compare_syntime(const void *v1, const void *v2)
{
- const time_entry_T *s1 = v1;
- const time_entry_T *s2 = v2;
+ const time_entry_T *s1 = v1;
+ const time_entry_T *s2 = v2;
return profile_cmp(s1->total, s2->total);
}
@@ -5971,14 +6103,13 @@ static void syntime_report(void)
syn_compare_syntime);
}
- MSG_PUTS_TITLE(_(
- " TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN"));
+ MSG_PUTS_TITLE(_(" TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN"));
MSG_PUTS("\n");
for (int idx = 0; idx < ga.ga_len && !got_int; ++idx) {
p = ((time_entry_T *)ga.ga_data) + idx;
MSG_PUTS(profile_msg(p->total));
- MSG_PUTS(" "); /* make sure there is always a separating space */
+ MSG_PUTS(" "); // make sure there is always a separating space
msg_advance(13);
msg_outnum(p->count);
MSG_PUTS(" ");
@@ -5997,12 +6128,14 @@ static void syntime_report(void)
msg_advance(69);
int len;
- if (Columns < 80)
- len = 20; /* will wrap anyway */
- else
+ if (Columns < 80) {
+ len = 20; // will wrap anyway
+ } else {
len = Columns - 70;
- if (len > (int)STRLEN(p->pattern))
+ }
+ if (len > (int)STRLEN(p->pattern)) {
len = (int)STRLEN(p->pattern);
+ }
msg_outtrans_len(p->pattern, len);
MSG_PUTS("\n");
}
@@ -6017,7 +6150,7 @@ static void syntime_report(void)
}
/**************************************
-* Highlighting stuff *
+* Highlighting stuff *
**************************************/
// The default highlight groups. These are compiled-in for fast startup and
@@ -6026,8 +6159,7 @@ static void syntime_report(void)
// When making changes here, also change runtime/colors/default.vim!
static const char *highlight_init_both[] = {
- "Conceal "
- "ctermbg=DarkGrey ctermfg=LightGrey guibg=DarkGrey guifg=LightGrey",
+ "Conceal ctermbg=DarkGrey ctermfg=LightGrey guibg=DarkGrey guifg=LightGrey",
"Cursor guibg=fg guifg=bg",
"lCursor guibg=fg guifg=bg",
"DiffText cterm=bold ctermbg=Red gui=bold guibg=Red",
@@ -6045,6 +6177,8 @@ static const char *highlight_init_both[] = {
"VertSplit cterm=reverse gui=reverse",
"WildMenu ctermbg=Yellow ctermfg=Black guibg=Yellow guifg=Black",
"default link EndOfBuffer NonText",
+ "default link LineNrAbove LineNr",
+ "default link LineNrBelow LineNr",
"default link QuickFixLine Search",
"default link Substitute Search",
"default link Whitespace NonText",
@@ -6057,6 +6191,32 @@ static const char *highlight_init_both[] = {
"RedrawDebugClear ctermbg=Yellow guibg=Yellow",
"RedrawDebugComposed ctermbg=Green guibg=Green",
"RedrawDebugRecompose ctermbg=Red guibg=Red",
+ "Error term=reverse cterm=NONE ctermfg=White ctermbg=Red gui=NONE guifg=White guibg=Red",
+ "Todo term=standout cterm=NONE ctermfg=Black ctermbg=Yellow gui=NONE guifg=Blue guibg=Yellow",
+ "default link String Constant",
+ "default link Character Constant",
+ "default link Number Constant",
+ "default link Boolean Constant",
+ "default link Float Number",
+ "default link Function Identifier",
+ "default link Conditional Statement",
+ "default link Repeat Statement",
+ "default link Label Statement",
+ "default link Operator Statement",
+ "default link Keyword Statement",
+ "default link Exception Statement",
+ "default link Include PreProc",
+ "default link Define PreProc",
+ "default link Macro PreProc",
+ "default link PreCondit PreProc",
+ "default link StorageClass Type",
+ "default link Structure Type",
+ "default link Typedef Type",
+ "default link Tag Special",
+ "default link SpecialChar Special",
+ "default link Delimiter Special",
+ "default link SpecialComment Special",
+ "default link Debug Special",
NULL
};
@@ -6065,7 +6225,7 @@ static const char *highlight_init_light[] = {
"ColorColumn ctermbg=LightRed guibg=LightRed",
"CursorColumn ctermbg=LightGrey guibg=Grey90",
"CursorLine cterm=underline guibg=Grey90",
- "CursorLineNr ctermfg=Brown gui=bold guifg=Brown",
+ "CursorLineNr cterm=underline ctermfg=Brown gui=bold guifg=Brown",
"DiffAdd ctermbg=LightBlue guibg=LightBlue",
"DiffChange ctermbg=LightMagenta guibg=LightMagenta",
"DiffDelete ctermfg=Blue ctermbg=LightCyan gui=bold guifg=Blue guibg=LightCyan",
@@ -6090,6 +6250,15 @@ static const char *highlight_init_light[] = {
"Title ctermfg=DarkMagenta gui=bold guifg=Magenta",
"Visual guibg=LightGrey",
"WarningMsg ctermfg=DarkRed guifg=Red",
+ "Comment term=bold cterm=NONE ctermfg=DarkBlue ctermbg=NONE gui=NONE guifg=Blue guibg=NONE",
+ "Constant term=underline cterm=NONE ctermfg=DarkRed ctermbg=NONE gui=NONE guifg=Magenta guibg=NONE",
+ "Special term=bold cterm=NONE ctermfg=DarkMagenta ctermbg=NONE gui=NONE guifg=#6a5acd guibg=NONE",
+ "Identifier term=underline cterm=NONE ctermfg=DarkCyan ctermbg=NONE gui=NONE guifg=DarkCyan guibg=NONE",
+ "Statement term=bold cterm=NONE ctermfg=Brown ctermbg=NONE gui=bold guifg=Brown guibg=NONE",
+ "PreProc term=underline cterm=NONE ctermfg=DarkMagenta ctermbg=NONE gui=NONE guifg=#6a0dad guibg=NONE",
+ "Type term=underline cterm=NONE ctermfg=DarkGreen ctermbg=NONE gui=bold guifg=SeaGreen guibg=NONE",
+ "Underlined term=underline cterm=underline ctermfg=DarkMagenta gui=underline guifg=SlateBlue",
+ "Ignore term=NONE cterm=NONE ctermfg=white ctermbg=NONE gui=NONE guifg=bg guibg=NONE",
NULL
};
@@ -6098,7 +6267,7 @@ static const char *highlight_init_dark[] = {
"ColorColumn ctermbg=DarkRed guibg=DarkRed",
"CursorColumn ctermbg=DarkGrey guibg=Grey40",
"CursorLine cterm=underline guibg=Grey40",
- "CursorLineNr ctermfg=Yellow gui=bold guifg=Yellow",
+ "CursorLineNr cterm=underline ctermfg=Yellow gui=bold guifg=Yellow",
"DiffAdd ctermbg=DarkBlue guibg=DarkBlue",
"DiffChange ctermbg=DarkMagenta guibg=DarkMagenta",
"DiffDelete ctermfg=Blue ctermbg=DarkCyan gui=bold guifg=Blue guibg=DarkCyan",
@@ -6123,11 +6292,20 @@ static const char *highlight_init_dark[] = {
"Title ctermfg=LightMagenta gui=bold guifg=Magenta",
"Visual guibg=DarkGrey",
"WarningMsg ctermfg=LightRed guifg=Red",
+ "Comment term=bold cterm=NONE ctermfg=Cyan ctermbg=NONE gui=NONE guifg=#80a0ff guibg=NONE",
+ "Constant term=underline cterm=NONE ctermfg=Magenta ctermbg=NONE gui=NONE guifg=#ffa0a0 guibg=NONE",
+ "Special term=bold cterm=NONE ctermfg=LightRed ctermbg=NONE gui=NONE guifg=Orange guibg=NONE",
+ "Identifier term=underline cterm=bold ctermfg=Cyan ctermbg=NONE gui=NONE guifg=#40ffff guibg=NONE",
+ "Statement term=bold cterm=NONE ctermfg=Yellow ctermbg=NONE gui=bold guifg=#ffff60 guibg=NONE",
+ "PreProc term=underline cterm=NONE ctermfg=LightBlue ctermbg=NONE gui=NONE guifg=#ff80ff guibg=NONE",
+ "Type term=underline cterm=NONE ctermfg=LightGreen ctermbg=NONE gui=bold guifg=#60ff60 guibg=NONE",
+ "Underlined term=underline cterm=underline ctermfg=LightBlue gui=underline guifg=#80a0ff",
+ "Ignore term=NONE cterm=NONE ctermfg=black ctermbg=NONE gui=NONE guifg=bg guibg=NONE",
NULL
};
const char *const highlight_init_cmdline[] = {
- // XXX When modifying a list modify it in both valid and invalid halfs.
+ // XXX When modifying a list modify it in both valid and invalid halves.
// TODO(ZyX-I): merge valid and invalid groups via a macros.
// NvimInternalError should appear only when highlighter has a bug.
@@ -6229,12 +6407,9 @@ const char *const highlight_init_cmdline[] = {
"default link NvimInvalidAssignment NvimInvalid",
"default link NvimInvalidPlainAssignment NvimInvalidAssignment",
"default link NvimInvalidAugmentedAssignment NvimInvalidAssignment",
- "default link NvimInvalidAssignmentWithAddition "
- "NvimInvalidAugmentedAssignment",
- "default link NvimInvalidAssignmentWithSubtraction "
- "NvimInvalidAugmentedAssignment",
- "default link NvimInvalidAssignmentWithConcatenation "
- "NvimInvalidAugmentedAssignment",
+ "default link NvimInvalidAssignmentWithAddition NvimInvalidAugmentedAssignment",
+ "default link NvimInvalidAssignmentWithSubtraction NvimInvalidAugmentedAssignment",
+ "default link NvimInvalidAssignmentWithConcatenation NvimInvalidAugmentedAssignment",
"default link NvimInvalidOperator NvimInvalid",
@@ -6296,7 +6471,7 @@ const char *const highlight_init_cmdline[] = {
"default link NvimInvalidOptionName NvimInvalidIdentifier",
"default link NvimInvalidOptionScope NvimInvalidIdentifierScope",
"default link NvimInvalidOptionScopeDelimiter "
- "NvimInvalidIdentifierScopeDelimiter",
+ "NvimInvalidIdentifierScopeDelimiter",
"default link NvimInvalidEnvironmentSigil NvimInvalidOptionSigil",
"default link NvimInvalidEnvironmentName NvimInvalidIdentifier",
@@ -6354,7 +6529,7 @@ void init_highlight(bool both, bool reset)
bool okay = load_colors(copy_p);
xfree(copy_p);
if (okay) {
- return;
+ return;
}
}
@@ -6368,7 +6543,7 @@ void init_highlight(bool both, bool reset)
do_highlight(pp[i], reset, true);
}
} else if (!had_both) {
- // Don't do anything before the call with both == TRUE from main().
+ // Don't do anything before the call with both == true from main().
// Not everything has been setup then, and that call will overrule
// everything anyway.
return;
@@ -6387,8 +6562,7 @@ void init_highlight(bool both, bool reset)
* to avoid Statement highlighted text disappears.
* Clear the attributes, needed when changing the t_Co value. */
if (t_colors > 8) {
- do_highlight(
- (*p_bg == 'l'
+ do_highlight((*p_bg == 'l'
? "Visual cterm=NONE ctermbg=LightGrey"
: "Visual cterm=NONE ctermbg=DarkGrey"), false, true);
} else {
@@ -6398,20 +6572,6 @@ void init_highlight(bool both, bool reset)
}
}
- /*
- * If syntax highlighting is enabled load the highlighting for it.
- */
- if (get_var_value("g:syntax_on") != NULL) {
- static int recursive = 0;
-
- if (recursive >= 5) {
- EMSG(_("E679: recursive loop loading syncolor.vim"));
- } else {
- recursive++;
- (void)source_runtime((char_u *)"syntax/syncolor.vim", DIP_ALL);
- recursive--;
- }
- }
syn_init_cmdline_highlight(false, false);
}
@@ -6421,9 +6581,9 @@ void init_highlight(bool both, bool reset)
*/
int load_colors(char_u *name)
{
- char_u *buf;
+ char_u *buf;
int retval = FAIL;
- static int recursive = false;
+ static bool recursive = false;
// When being called recursively, this is probably because setting
// 'background' caused the highlighting to be reloaded. This means it is
@@ -6443,7 +6603,7 @@ int load_colors(char_u *name)
retval = source_runtime(buf, DIP_START + DIP_OPT);
}
xfree(buf);
- apply_autocmds(EVENT_COLORSCHEME, name, curbuf->b_fname, FALSE, curbuf);
+ apply_autocmds(EVENT_COLORSCHEME, name, curbuf->b_fname, false, curbuf);
recursive = false;
@@ -6457,46 +6617,47 @@ static char *(color_names[28]) = {
"DarkGray", "DarkGrey",
"Blue", "LightBlue", "Green", "LightGreen",
"Cyan", "LightCyan", "Red", "LightRed", "Magenta",
- "LightMagenta", "Yellow", "LightYellow", "White", "NONE" };
- // indices:
- // 0, 1, 2, 3,
- // 4, 5, 6, 7,
- // 8, 9, 10, 11,
- // 12, 13,
- // 14, 15, 16, 17,
- // 18, 19, 20, 21, 22,
- // 23, 24, 25, 26, 27
+ "LightMagenta", "Yellow", "LightYellow", "White", "NONE"
+};
+// indices:
+// 0, 1, 2, 3,
+// 4, 5, 6, 7,
+// 8, 9, 10, 11,
+// 12, 13,
+// 14, 15, 16, 17,
+// 18, 19, 20, 21, 22,
+// 23, 24, 25, 26, 27
static int color_numbers_16[28] = { 0, 1, 2, 3,
- 4, 5, 6, 6,
- 7, 7, 7, 7,
- 8, 8,
- 9, 9, 10, 10,
- 11, 11, 12, 12, 13,
- 13, 14, 14, 15, -1 };
+ 4, 5, 6, 6,
+ 7, 7, 7, 7,
+ 8, 8,
+ 9, 9, 10, 10,
+ 11, 11, 12, 12, 13,
+ 13, 14, 14, 15, -1 };
// for xterm with 88 colors...
static int color_numbers_88[28] = { 0, 4, 2, 6,
- 1, 5, 32, 72,
- 84, 84, 7, 7,
- 82, 82,
- 12, 43, 10, 61,
- 14, 63, 9, 74, 13,
- 75, 11, 78, 15, -1 };
+ 1, 5, 32, 72,
+ 84, 84, 7, 7,
+ 82, 82,
+ 12, 43, 10, 61,
+ 14, 63, 9, 74, 13,
+ 75, 11, 78, 15, -1 };
// for xterm with 256 colors...
static int color_numbers_256[28] = { 0, 4, 2, 6,
- 1, 5, 130, 3,
- 248, 248, 7, 7,
- 242, 242,
- 12, 81, 10, 121,
- 14, 159, 9, 224, 13,
- 225, 11, 229, 15, -1 };
+ 1, 5, 130, 3,
+ 248, 248, 7, 7,
+ 242, 242,
+ 12, 81, 10, 121,
+ 14, 159, 9, 224, 13,
+ 225, 11, 229, 15, -1 };
// for terminals with less than 16 colors...
static int color_numbers_8[28] = { 0, 4, 2, 6,
- 1, 5, 3, 3,
- 7, 7, 7, 7,
- 0+8, 0+8,
- 4+8, 4+8, 2+8, 2+8,
- 6+8, 6+8, 1+8, 1+8, 5+8,
- 5+8, 3+8, 3+8, 7+8, -1 };
+ 1, 5, 3, 3,
+ 7, 7, 7, 7,
+ 0+8, 0+8,
+ 4+8, 4+8, 2+8, 2+8,
+ 6+8, 6+8, 1+8, 1+8, 5+8,
+ 5+8, 3+8, 3+8, 7+8, -1 };
// Lookup the "cterm" value to be used for color with index "idx" in
// color_names[].
@@ -6597,7 +6758,7 @@ void do_highlight(const char *line, const bool forceit, const bool init)
// ":highlight {group-name}": list highlighting for one group.
if (!doclear && !dolink && ends_excmd((uint8_t)(*linep))) {
- id = syn_namen2id((const char_u *)line, (int)(name_end - line));
+ id = syn_name2id_len((const char_u *)line, (int)(name_end - line));
if (id == 0) {
emsgf(_("E411: highlight group not found: %s"), line);
} else {
@@ -6814,7 +6975,7 @@ void do_highlight(const char *line, const bool forceit, const bool init)
if (error) {
break;
}
- if (*key == 'C') {
+ if (*key == 'C') {
if (!init || !(HL_TABLE()[idx].sg_set & SG_CTERM)) {
if (!init) {
HL_TABLE()[idx].sg_set |= SG_CTERM;
@@ -6830,7 +6991,7 @@ void do_highlight(const char *line, const bool forceit, const bool init)
HL_TABLE()[idx].sg_gui = attr;
}
}
- } else if (STRCMP(key, "FONT") == 0) {
+ } else if (STRCMP(key, "FONT") == 0) {
// in non-GUI fonts are simply ignored
} else if (STRCMP(key, "CTERMFG") == 0 || STRCMP(key, "CTERMBG") == 0) {
if (!init || !(HL_TABLE()[idx].sg_set & SG_CTERM)) {
@@ -6846,7 +7007,7 @@ void do_highlight(const char *line, const bool forceit, const bool init)
}
if (ascii_isdigit(*arg)) {
- color = atoi((char *)arg);
+ color = atoi(arg);
} else if (STRICMP(arg, "fg") == 0) {
if (cterm_normal_fg_color) {
color = cterm_normal_fg_color - 1;
@@ -6855,10 +7016,10 @@ void do_highlight(const char *line, const bool forceit, const bool init)
error = true;
break;
}
- } else if (STRICMP(arg, "bg") == 0) {
- if (cterm_normal_bg_color > 0)
+ } else if (STRICMP(arg, "bg") == 0) {
+ if (cterm_normal_bg_color > 0) {
color = cterm_normal_bg_color - 1;
- else {
+ } else {
EMSG(_("E420: BG color unknown"));
error = true;
break;
@@ -6925,7 +7086,7 @@ void do_highlight(const char *line, const bool forceit, const bool init)
}
}
}
- } else if (strcmp(key, "GUIFG") == 0) {
+ } else if (strcmp(key, "GUIFG") == 0) {
char **namep = &HL_TABLE()[idx].sg_rgb_fg_name;
if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) {
@@ -6949,7 +7110,7 @@ void do_highlight(const char *line, const bool forceit, const bool init)
if (is_normal_group) {
normal_fg = HL_TABLE()[idx].sg_rgb_fg;
}
- } else if (STRCMP(key, "GUIBG") == 0) {
+ } else if (STRCMP(key, "GUIBG") == 0) {
char **const namep = &HL_TABLE()[idx].sg_rgb_bg_name;
if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) {
@@ -6973,7 +7134,7 @@ void do_highlight(const char *line, const bool forceit, const bool init)
if (is_normal_group) {
normal_bg = HL_TABLE()[idx].sg_rgb_bg;
}
- } else if (strcmp(key, "GUISP") == 0) {
+ } else if (strcmp(key, "GUISP") == 0) {
char **const namep = &HL_TABLE()[idx].sg_rgb_sp_name;
if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) {
@@ -6997,9 +7158,9 @@ void do_highlight(const char *line, const bool forceit, const bool init)
if (is_normal_group) {
normal_sp = HL_TABLE()[idx].sg_rgb_sp;
}
- } else if (strcmp(key, "START") == 0 || strcmp(key, "STOP") == 0) {
+ } else if (strcmp(key, "START") == 0 || strcmp(key, "STOP") == 0) {
// Ignored for now
- } else if (strcmp(key, "BLEND") == 0) {
+ } else if (strcmp(key, "BLEND") == 0) {
if (strcmp(arg, "NONE") != 0) {
HL_TABLE()[idx].sg_blend = strtol(arg, NULL, 10);
} else {
@@ -7075,6 +7236,7 @@ void free_highlight(void)
xfree(HL_TABLE()[i].sg_name_u);
}
ga_clear(&highlight_ga);
+ map_destroy(cstr_t, int)(&highlight_unames);
}
#endif
@@ -7092,20 +7254,19 @@ void restore_cterm_colors(void)
cterm_normal_bg_color = 0;
}
-/*
- * Return TRUE if highlight group "idx" has any settings.
- * When "check_link" is TRUE also check for an existing link.
- */
-static int hl_has_settings(int idx, int check_link)
+/// @param check_link if true also check for an existing link.
+///
+/// @return TRUE if highlight group "idx" has any settings.
+static int hl_has_settings(int idx, bool check_link)
{
return HL_TABLE()[idx].sg_cleared == 0
- && (HL_TABLE()[idx].sg_attr != 0
- || HL_TABLE()[idx].sg_cterm_fg != 0
- || HL_TABLE()[idx].sg_cterm_bg != 0
- || HL_TABLE()[idx].sg_rgb_fg_name != NULL
- || HL_TABLE()[idx].sg_rgb_bg_name != NULL
- || HL_TABLE()[idx].sg_rgb_sp_name != NULL
- || (check_link && (HL_TABLE()[idx].sg_set & SG_LINK)));
+ && (HL_TABLE()[idx].sg_attr != 0
+ || HL_TABLE()[idx].sg_cterm_fg != 0
+ || HL_TABLE()[idx].sg_cterm_bg != 0
+ || HL_TABLE()[idx].sg_rgb_fg_name != NULL
+ || HL_TABLE()[idx].sg_rgb_bg_name != NULL
+ || HL_TABLE()[idx].sg_rgb_sp_name != NULL
+ || (check_link && (HL_TABLE()[idx].sg_set & SG_LINK)));
}
/*
@@ -7153,18 +7314,18 @@ static void highlight_list_one(const int id)
}
didh = highlight_list_arg(id, didh, LIST_ATTR,
- sgp->sg_cterm, NULL, "cterm");
+ sgp->sg_cterm, NULL, "cterm");
didh = highlight_list_arg(id, didh, LIST_INT,
- sgp->sg_cterm_fg, NULL, "ctermfg");
+ sgp->sg_cterm_fg, NULL, "ctermfg");
didh = highlight_list_arg(id, didh, LIST_INT,
- sgp->sg_cterm_bg, NULL, "ctermbg");
+ sgp->sg_cterm_bg, NULL, "ctermbg");
didh = highlight_list_arg(id, didh, LIST_ATTR,
- sgp->sg_gui, NULL, "gui");
+ sgp->sg_gui, NULL, "gui");
didh = highlight_list_arg(id, didh, LIST_STRING,
- 0, sgp->sg_rgb_fg_name, "guifg");
+ 0, sgp->sg_rgb_fg_name, "guifg");
didh = highlight_list_arg(id, didh, LIST_STRING,
- 0, sgp->sg_rgb_bg_name, "guibg");
+ 0, sgp->sg_rgb_bg_name, "guibg");
didh = highlight_list_arg(id, didh, LIST_STRING,
0, sgp->sg_rgb_sp_name, "guisp");
@@ -7210,9 +7371,8 @@ Dictionary get_global_hl_defs(void)
/// @param type one of \ref LIST_XXX
/// @param iarg integer argument used if \p type == LIST_INT
/// @param sarg string used if \p type == LIST_STRING
-static bool highlight_list_arg(
- const int id, bool didh, const int type, int iarg,
- char *const sarg, const char *const name)
+static bool highlight_list_arg(const int id, bool didh, const int type, int iarg, char *const sarg,
+ const char *const name)
{
char buf[100];
@@ -7229,10 +7389,11 @@ static bool highlight_list_arg(
buf[0] = NUL;
for (int i = 0; hl_attr_table[i] != 0; i++) {
if (iarg & hl_attr_table[i]) {
- if (buf[0] != NUL)
+ if (buf[0] != NUL) {
xstrlcat((char *)buf, ",", 100);
+ }
xstrlcat((char *)buf, hl_name_table[i], 100);
- iarg &= ~hl_attr_table[i]; /* don't want "inverse" */
+ iarg &= ~hl_attr_table[i]; // don't want "inverse"
}
}
}
@@ -7285,8 +7446,7 @@ const char *highlight_has_attr(const int id, const int flag, const int modec)
///
/// @return color name, possibly in a static buffer. Buffer will be overwritten
/// on next highlight_color() call. May return NULL.
-const char *highlight_color(const int id, const char *const what,
- const int modec)
+const char *highlight_color(const int id, const char *const what, const int modec)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
static char name[20];
@@ -7312,11 +7472,11 @@ const char *highlight_color(const int id, const char *const what,
if (modec == 'g') {
if (what[2] == '#' && ui_rgb_attached()) {
if (fg) {
- n = HL_TABLE()[id - 1].sg_rgb_fg;
+ n = HL_TABLE()[id - 1].sg_rgb_fg;
} else if (sp) {
- n = HL_TABLE()[id - 1].sg_rgb_sp;
+ n = HL_TABLE()[id - 1].sg_rgb_sp;
} else {
- n = HL_TABLE()[id - 1].sg_rgb_bg;
+ n = HL_TABLE()[id - 1].sg_rgb_bg;
}
if (n < 0 || n > 0xffffff) {
return NULL;
@@ -7358,8 +7518,8 @@ const char *highlight_color(const int id, const char *const what,
/// @param id highlight group id
/// @param force_newline always start a new line
/// @return true when started a new line.
-static bool syn_list_header(const bool did_header, const int outlen,
- const int id, bool force_newline)
+static bool syn_list_header(const bool did_header, const int outlen, const int id,
+ bool force_newline)
{
int endcol = 19;
bool newline = true;
@@ -7375,7 +7535,7 @@ static bool syn_list_header(const bool did_header, const int outlen,
} else if ((ui_has(kUIMessages) || msg_silent) && !force_newline) {
msg_putchar(' ');
adjust = false;
- } else if (msg_col + outlen + 1 >= Columns || force_newline) {
+ } else if (msg_col + outlen + 1 >= Columns || force_newline) {
msg_putchar('\n');
if (got_int) {
return true;
@@ -7395,7 +7555,7 @@ static bool syn_list_header(const bool did_header, const int outlen,
msg_advance(endcol);
}
- /* Show "xxx" with the attributes. */
+ // Show "xxx" with the attributes.
if (!did_header) {
msg_puts_attr("xxx", syn_id2attr(id));
msg_putchar(' ');
@@ -7410,7 +7570,7 @@ static bool syn_list_header(const bool did_header, const int outlen,
static void set_hl_attr(int idx)
{
HlAttrs at_en = HLATTRS_INIT;
- struct hl_group *sgp = HL_TABLE() + idx;
+ struct hl_group *sgp = HL_TABLE() + idx;
at_en.cterm_ae_attr = sgp->sg_cterm;
at_en.cterm_fg_color = sgp->sg_cterm_fg;
@@ -7432,26 +7592,35 @@ static void set_hl_attr(int idx)
}
}
+int syn_name2id(const char_u *name)
+ FUNC_ATTR_NONNULL_ALL
+{
+ return syn_name2id_len(name, STRLEN(name));
+}
+
/// Lookup a highlight group name and return its ID.
///
/// @param highlight name e.g. 'Cursor', 'Normal'
/// @return the highlight id, else 0 if \p name does not exist
-int syn_name2id(const char_u *name)
+int syn_name2id_len(const char_u *name, size_t len)
FUNC_ATTR_NONNULL_ALL
{
- int i;
- char_u name_u[200];
-
- /* Avoid using stricmp() too much, it's slow on some systems */
- /* Avoid alloc()/free(), these are slow too. ID names over 200 chars
- * don't deserve to be found! */
- STRLCPY(name_u, name, 200);
- vim_strup(name_u);
- for (i = highlight_ga.ga_len; --i >= 0; )
- if (HL_TABLE()[i].sg_name_u != NULL
- && STRCMP(name_u, HL_TABLE()[i].sg_name_u) == 0)
- break;
- return i + 1;
+ char name_u[201];
+
+ if (len == 0 || len > 200) {
+ // ID names over 200 chars don't deserve to be found!
+ return 0;
+ }
+
+ // Avoid using stricmp() too much, it's slow on some systems */
+ // Avoid alloc()/free(), these are slow too.
+ memcpy(name_u, name, len);
+ name_u[len] = '\0';
+ vim_strup((char_u *)name_u);
+
+ // map_get(..., int) returns 0 when no key is present, which is
+ // the expected value for missing highlight group.
+ return map_get(cstr_t, int)(&highlight_unames, name_u);
}
/// Lookup a highlight group name and return its attributes.
@@ -7481,22 +7650,12 @@ int highlight_exists(const char_u *name)
*/
char_u *syn_id2name(int id)
{
- if (id <= 0 || id > highlight_ga.ga_len)
+ if (id <= 0 || id > highlight_ga.ga_len) {
return (char_u *)"";
+ }
return HL_TABLE()[id - 1].sg_name;
}
-/*
- * Like syn_name2id(), but take a pointer + length argument.
- */
-int syn_namen2id(const char_u *linep, int len)
-{
- char_u *name = vim_strnsave(linep, len);
- int id = syn_name2id(name);
- xfree(name);
-
- return id;
-}
/// Find highlight group name in the table and return its ID.
/// If it doesn't exist yet, a new entry is created.
@@ -7505,14 +7664,11 @@ int syn_namen2id(const char_u *linep, int len)
/// @param len length of \p pp
///
/// @return 0 for failure else the id of the group
-int syn_check_group(const char_u *pp, int len)
+int syn_check_group(const char_u *name, int len)
{
- char_u *name = vim_strnsave(pp, len);
- int id = syn_name2id(name);
+ int id = syn_name2id_len(name, len);
if (id == 0) { // doesn't exist yet
- id = syn_add_group(name);
- } else {
- xfree(name);
+ return syn_add_group(vim_strnsave(name, len));
}
return id;
}
@@ -7524,15 +7680,15 @@ int syn_check_group(const char_u *pp, int len)
/// @see syn_check_group syn_unadd_group
static int syn_add_group(char_u *name)
{
- char_u *p;
+ char_u *p;
- /* Check that the name is ASCII letters, digits and underscore. */
+ // Check that the name is ASCII letters, digits and underscore.
for (p = name; *p != NUL; ++p) {
if (!vim_isprintc(*p)) {
EMSG(_("E669: Unprintable character in group name"));
xfree(name);
return 0;
- } else if (!ASCII_ISALNUM(*p) && *p != '_') {
+ } else if (!ASCII_ISALNUM(*p) && *p != '_') {
/* This is an error, but since there previously was no check only
* give a warning. */
msg_source(HL_ATTR(HLF_W));
@@ -7555,10 +7711,10 @@ static int syn_add_group(char_u *name)
return 0;
}
- char_u *const name_up = vim_strsave_up(name);
+ char *const name_up = (char *)vim_strsave_up(name);
// Append another syntax_highlight entry.
- struct hl_group* hlgp = GA_APPEND_VIA_PTR(struct hl_group, &highlight_ga);
+ struct hl_group * hlgp = GA_APPEND_VIA_PTR(struct hl_group, &highlight_ga);
memset(hlgp, 0, sizeof(*hlgp));
hlgp->sg_name = name;
hlgp->sg_rgb_bg = -1;
@@ -7567,7 +7723,11 @@ static int syn_add_group(char_u *name)
hlgp->sg_blend = -1;
hlgp->sg_name_u = name_up;
- return highlight_ga.ga_len; /* ID is index plus one */
+ int id = highlight_ga.ga_len; // ID is index plus one
+
+ map_put(cstr_t, int)(&highlight_unames, name_up, id);
+
+ return id;
}
/// When, just after calling syn_add_group(), an error is discovered, this
@@ -7575,8 +7735,10 @@ static int syn_add_group(char_u *name)
static void syn_unadd_group(void)
{
highlight_ga.ga_len--;
- xfree(HL_TABLE()[highlight_ga.ga_len].sg_name);
- xfree(HL_TABLE()[highlight_ga.ga_len].sg_name_u);
+ HlGroup *item = &HL_TABLE()[highlight_ga.ga_len];
+ map_del(cstr_t, int)(&highlight_unames, item->sg_name_u);
+ xfree(item->sg_name);
+ xfree(item->sg_name_u);
}
@@ -7604,9 +7766,9 @@ int syn_get_final_id(int hl_id)
{
int count;
- if (hl_id > highlight_ga.ga_len || hl_id < 1)
- return 0; /* Can be called from eval!! */
-
+ if (hl_id > highlight_ga.ga_len || hl_id < 1) {
+ return 0; // Can be called from eval!!
+ }
/*
* Follow links until there is no more.
* Look out for loops! Break after 100 links.
@@ -7654,8 +7816,7 @@ void highlight_attr_set_all(void)
}
// Apply difference between User[1-9] and HLF_S to HLF_SNC.
-static void combine_stl_hlt(int id, int id_S, int id_alt, int hlcnt, int i,
- int hlf, int *table)
+static void combine_stl_hlt(int id, int id_S, int id_alt, int hlcnt, int i, int hlf, int *table)
FUNC_ATTR_NONNULL_ALL
{
struct hl_group *const hlt = HL_TABLE();
@@ -7703,23 +7864,23 @@ void highlight_changed(void)
int id_SNC = 0;
int hlcnt;
- need_highlight_changed = FALSE;
+ need_highlight_changed = false;
/// Translate builtin highlight groups into attributes for quick lookup.
- for (int hlf = 0; hlf < (int)HLF_COUNT; hlf++) {
+ for (int hlf = 0; hlf < HLF_COUNT; hlf++) {
id = syn_check_group((char_u *)hlf_names[hlf], STRLEN(hlf_names[hlf]));
if (id == 0) {
abort();
}
int final_id = syn_get_final_id(id);
- if (hlf == (int)HLF_SNC) {
+ if (hlf == HLF_SNC) {
id_SNC = final_id;
- } else if (hlf == (int)HLF_S) {
+ } else if (hlf == HLF_S) {
id_S = final_id;
}
highlight_attr[hlf] = hl_get_ui_attr(hlf, final_id,
- hlf == (int)HLF_INACTIVE);
+ hlf == HLF_INACTIVE);
if (highlight_attr[hlf] != highlight_attr_last[hlf]) {
if (hlf == HLF_MSG) {
@@ -7772,7 +7933,7 @@ void set_context_in_highlight_cmd(expand_T *xp, const char *arg)
include_link = 2;
include_default = 1;
- /* (part of) subcommand already typed */
+ // (part of) subcommand already typed
if (*arg != NUL) {
const char *p = (const char *)skiptowhite((const char_u *)arg);
if (*p != NUL) { // Past "default" or group name.
@@ -7782,7 +7943,7 @@ void set_context_in_highlight_cmd(expand_T *xp, const char *arg)
xp->xp_pattern = (char_u *)arg;
p = (const char *)skiptowhite((const char_u *)arg);
}
- if (*p != NUL) { /* past group name */
+ if (*p != NUL) { // past group name
include_link = 0;
if (arg[1] == 'i' && arg[0] == 'N') {
highlight_list();
@@ -7837,8 +7998,9 @@ const char *get_highlight_name(expand_T *const xp, int idx)
/// Obtain a highlight group name.
-/// When "skip_cleared" is TRUE don't return a cleared entry.
-const char *get_highlight_name_ext(expand_T *xp, int idx, int skip_cleared)
+///
+/// @param skip_cleared if true don't return a cleared entry.
+const char *get_highlight_name_ext(expand_T *xp, int idx, bool skip_cleared)
FUNC_ATTR_WARN_UNUSED_RESULT
{
if (idx < 0) {
@@ -8560,7 +8722,6 @@ color_name_table_T color_name_table[] = {
/// return the hex value or -1 if could not find a correct value
RgbValue name_to_color(const char *name)
{
-
if (name[0] == '#' && isxdigit(name[1]) && isxdigit(name[2])
&& isxdigit(name[3]) && isxdigit(name[4]) && isxdigit(name[5])
&& isxdigit(name[6]) && name[7] == NUL) {
@@ -8583,5 +8744,5 @@ RgbValue name_to_color(const char *name)
/**************************************
-* End of Highlighting stuff *
+* End of Highlighting stuff *
**************************************/
diff --git a/src/nvim/tag.c b/src/nvim/tag.c
index ab35c936ca..c63cdad098 100644
--- a/src/nvim/tag.c
+++ b/src/nvim/tag.c
@@ -1371,12 +1371,12 @@ find_tags(
tagname_T tn; /* info for get_tagfname() */
int first_file; /* trying first tag file */
tagptrs_T tagp;
- int did_open = FALSE; /* did open a tag file */
- int stop_searching = FALSE; /* stop when match found or error */
- int retval = FAIL; /* return value */
- int is_static; /* current tag line is static */
- int is_current; /* file name matches */
- int eof = FALSE; /* found end-of-file */
+ bool did_open = false; // did open a tag file
+ bool stop_searching = false; // stop when match found or error
+ int retval = FAIL; // return value
+ int is_static; // current tag line is static
+ int is_current; // file name matches
+ bool eof = false; // found end-of-file
char_u *p;
char_u *s;
int i;
@@ -1429,12 +1429,12 @@ find_tags(
vimconv_T vimconv;
int findall = (mincount == MAXCOL || mincount == TAG_MANY);
- /* find all matching tags */
- int sort_error = FALSE; /* tags file not sorted */
- int linear; /* do a linear search */
- int sortic = FALSE; /* tag file sorted in nocase */
- int line_error = FALSE; /* syntax error */
- int has_re = (flags & TAG_REGEXP); /* regexp used */
+ // find all matching tags
+ bool sort_error = false; // tags file not sorted
+ int linear; // do a linear search
+ bool sortic = false; // tag file sorted in nocase
+ bool line_error = false; // syntax error
+ int has_re = (flags & TAG_REGEXP); // regexp used
int help_only = (flags & TAG_HELP);
int name_only = (flags & TAG_NAMES);
int noic = (flags & TAG_NOIC);
@@ -1467,6 +1467,7 @@ find_tags(
help_save = curbuf->b_help;
orgpat.pat = pat;
+ orgpat.regmatch.regprog = NULL;
vimconv.vc_type = CONV_NONE;
/*
@@ -1621,7 +1622,7 @@ find_tags(
verbose_leave();
}
}
- did_open = TRUE; /* remember that we found at least one file */
+ did_open = true; // remember that we found at least one file
state = TS_START; /* we're at the start of the file */
@@ -1638,13 +1639,13 @@ find_tags(
if ((flags & TAG_INS_COMP)) /* Double brackets for gcc */
ins_compl_check_keys(30, false);
if (got_int || compl_interrupted) {
- stop_searching = TRUE;
+ stop_searching = true;
break;
}
/* When mincount is TAG_MANY, stop when enough matches have been
* found (for completion). */
if (mincount == TAG_MANY && match_count >= TAG_MANY) {
- stop_searching = TRUE;
+ stop_searching = true;
retval = OK;
break;
}
@@ -1795,7 +1796,7 @@ line_read_in:
state = TS_BINARY;
else if (tag_file_sorted == '2') {
state = TS_BINARY;
- sortic = TRUE;
+ sortic = true;
orgpat.regmatch.rm_ic = (p_ic || !noic);
} else
state = TS_LINEAR;
@@ -1878,8 +1879,9 @@ parse_line:
i = (int)tagp.tagname[0];
if (sortic)
i = TOUPPER_ASC(tagp.tagname[0]);
- if (i < search_info.low_char || i > search_info.high_char)
- sort_error = TRUE;
+ if (i < search_info.low_char || i > search_info.high_char) {
+ sort_error = true;
+ }
/*
* Compare the current tag with the searched tag.
@@ -1970,7 +1972,7 @@ parse_line:
i = parse_tag_line(lbuf,
&tagp);
if (i == FAIL) {
- line_error = TRUE;
+ line_error = true;
break;
}
@@ -2175,7 +2177,7 @@ parse_line:
tag_file_sorted = NUL;
if (sort_error) {
EMSG2(_("E432: Tags file not sorted: %s"), tag_fname);
- sort_error = FALSE;
+ sort_error = false;
}
/*
@@ -2183,7 +2185,7 @@ parse_line:
*/
if (match_count >= mincount) {
retval = OK;
- stop_searching = TRUE;
+ stop_searching = true;
}
if (stop_searching || use_cscope)
@@ -2611,7 +2613,6 @@ static int jumpto_tag(
int keep_help // keep help flag (FALSE for cscope)
)
{
- int save_secure;
int save_magic;
bool save_p_ws;
int save_p_scs, save_p_ic;
@@ -2766,9 +2767,6 @@ static int jumpto_tag(
curwin->w_set_curswant = true;
postponed_split = 0;
- save_secure = secure;
- secure = 1;
- ++sandbox;
save_magic = p_magic;
p_magic = false; // always execute with 'nomagic'
// Save value of no_hlsearch, jumping to a tag is not a real search
@@ -2866,21 +2864,26 @@ static int jumpto_tag(
* of the line. May need to correct that here. */
check_cursor();
} else {
- curwin->w_cursor.lnum = 1; /* start command in line 1 */
+ const int save_secure = secure;
+
+ // Setup the sandbox for executing the command from the tags file.
+ secure = 1;
+ sandbox++;
+ curwin->w_cursor.lnum = 1; // start command in line 1
do_cmdline_cmd((char *)pbuf);
retval = OK;
+
+ // When the command has done something that is not allowed make sure
+ // the error message can be seen.
+ if (secure == 2) {
+ wait_return(true);
+ }
+ secure = save_secure;
+ sandbox--;
}
- /*
- * When the command has done something that is not allowed make sure
- * the error message can be seen.
- */
- if (secure == 2)
- wait_return(TRUE);
- secure = save_secure;
p_magic = save_magic;
- --sandbox;
- /* restore no_hlsearch when keeping the old search pattern */
+ // restore no_hlsearch when keeping the old search pattern
if (search_options) {
set_no_hlsearch(save_no_hlsearch);
}
@@ -3059,24 +3062,26 @@ expand_tags (
)
{
int i;
- int c;
- int tagnmflag;
- char_u tagnm[100];
+ int extra_flag;
+ char_u *name_buf;
+ size_t name_buf_size = 100;
tagptrs_T t_p;
int ret;
- if (tagnames)
- tagnmflag = TAG_NAMES;
- else
- tagnmflag = 0;
+ name_buf = xmalloc(name_buf_size);
+
+ if (tagnames) {
+ extra_flag = TAG_NAMES;
+ } else {
+ extra_flag = 0;
+ }
if (pat[0] == '/') {
ret = find_tags(pat + 1, num_file, file,
- TAG_REGEXP | tagnmflag | TAG_VERBOSE | TAG_NO_TAGFUNC,
+ TAG_REGEXP | extra_flag | TAG_VERBOSE | TAG_NO_TAGFUNC,
TAG_MANY, curbuf->b_ffname);
} else {
ret = find_tags(pat, num_file, file,
- TAG_REGEXP | tagnmflag | TAG_VERBOSE
- | TAG_NO_TAGFUNC | TAG_NOIC,
+ TAG_REGEXP | extra_flag | TAG_VERBOSE | TAG_NO_TAGFUNC | TAG_NOIC,
TAG_MANY, curbuf->b_ffname);
}
if (ret == OK && !tagnames) {
@@ -3084,18 +3089,29 @@ expand_tags (
* "<tagname>\0<kind>\0<filename>\0"
*/
for (i = 0; i < *num_file; i++) {
+ size_t len;
+
parse_match((*file)[i], &t_p);
- c = (int)(t_p.tagname_end - t_p.tagname);
- memmove(tagnm, t_p.tagname, (size_t)c);
- tagnm[c++] = 0;
- tagnm[c++] = (t_p.tagkind != NULL && *t_p.tagkind)
- ? *t_p.tagkind : 'f';
- tagnm[c++] = 0;
- memmove((*file)[i] + c, t_p.fname, t_p.fname_end - t_p.fname);
- (*file)[i][c + (t_p.fname_end - t_p.fname)] = 0;
- memmove((*file)[i], tagnm, (size_t)c);
+ len = t_p.tagname_end - t_p.tagname;
+ if (len > name_buf_size - 3) {
+ char_u *buf;
+
+ name_buf_size = len + 3;
+ buf = xrealloc(name_buf, name_buf_size);
+ name_buf = buf;
+ }
+
+ memmove(name_buf, t_p.tagname, len);
+ name_buf[len++] = 0;
+ name_buf[len++] = (t_p.tagkind != NULL && *t_p.tagkind)
+ ? *t_p.tagkind : 'f';
+ name_buf[len++] = 0;
+ memmove((*file)[i] + len, t_p.fname, t_p.fname_end - t_p.fname);
+ (*file)[i][len + (t_p.fname_end - t_p.fname)] = 0;
+ memmove((*file)[i], name_buf, len);
}
}
+ xfree(name_buf);
return ret;
}
@@ -3291,7 +3307,7 @@ static void tagstack_clear(win_T *wp)
}
// Remove the oldest entry from the tag stack and shift the rest of
-// the entires to free up the top of the stack.
+// the entries to free up the top of the stack.
static void tagstack_shift(win_T *wp)
{
taggy_T *tagstack = wp->w_tagstack;
diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c
index c07a956dde..3335fa500a 100644
--- a/src/nvim/terminal.c
+++ b/src/nvim/terminal.c
@@ -76,7 +76,6 @@
#include "nvim/event/time.h"
#include "nvim/os/input.h"
#include "nvim/api/private/helpers.h"
-#include "nvim/api/private/handle.h"
typedef struct terminal_state {
VimState state;
@@ -153,11 +152,10 @@ static VTermScreenCallbacks vterm_screen_callbacks = {
.sb_popline = term_sb_pop,
};
-static PMap(ptr_t) *invalidated_terminals;
+static PMap(ptr_t) invalidated_terminals = MAP_INIT;
void terminal_init(void)
{
- invalidated_terminals = pmap_new(ptr_t)();
time_watcher_init(&main_loop, &refresh_timer, NULL);
// refresh_timer_cb will redraw the screen which can call vimscript
refresh_timer.events = multiqueue_new_child(main_loop.events);
@@ -168,8 +166,10 @@ void terminal_teardown(void)
time_watcher_stop(&refresh_timer);
multiqueue_free(refresh_timer.events);
time_watcher_close(&refresh_timer, NULL);
- pmap_free(ptr_t)(invalidated_terminals);
- invalidated_terminals = NULL;
+ pmap_destroy(ptr_t)(&invalidated_terminals);
+ // terminal_destroy might be called after terminal_teardown is invoked
+ // make sure it is in an empty, valid state
+ pmap_init(ptr_t, &invalidated_terminals);
}
// public API {{{
@@ -260,7 +260,7 @@ Terminal *terminal_open(buf_T *buf, TerminalOptions opts)
return rv;
}
-void terminal_close(Terminal *term, char *msg)
+void terminal_close(Terminal *term, int status)
{
if (term->closed) {
return;
@@ -278,8 +278,8 @@ void terminal_close(Terminal *term, char *msg)
buf_T *buf = handle_get_buffer(term->buf_handle);
term->closed = true;
- if (!msg || exiting) {
- // If no msg was given, this was called by close_buffer(buffer.c). Or if
+ if (status == -1 || exiting) {
+ // If status is -1, this was called by close_buffer(buffer.c). Or if
// exiting, we must inform the buffer the terminal no longer exists so that
// close_buffer() doesn't call this again.
term->buf_handle = 0;
@@ -291,11 +291,16 @@ void terminal_close(Terminal *term, char *msg)
term->opts.close_cb(term->opts.data);
}
} else {
+ char msg[sizeof("\r\n[Process exited ]") + NUMBUFLEN];
+ snprintf(msg, sizeof msg, "\r\n[Process exited %d]", status);
terminal_receive(term, msg, strlen(msg));
}
- if (buf) {
+ if (buf && !is_autocmd_blocked()) {
+ dict_T *dict = get_vim_var_dict(VV_EVENT);
+ tv_dict_add_nr(dict, S_LEN("status"), status);
apply_autocmds(EVENT_TERMCLOSE, NULL, NULL, false, buf);
+ tv_dict_clear(dict);
}
}
@@ -521,14 +526,12 @@ void terminal_destroy(Terminal *term)
}
if (!term->refcount) {
- // might be destroyed after terminal_teardown is invoked
- if (invalidated_terminals
- && pmap_has(ptr_t)(invalidated_terminals, term)) {
+ if (pmap_has(ptr_t)(&invalidated_terminals, term)) {
// flush any pending changes to the buffer
block_autocmds();
refresh_terminal(term);
unblock_autocmds();
- pmap_del(ptr_t)(invalidated_terminals, term);
+ pmap_del(ptr_t)(&invalidated_terminals, term);
}
for (size_t i = 0; i < term->sb_current; i++) {
xfree(term->sb_buffer[i]);
@@ -865,7 +868,7 @@ static int term_sb_push(int cols, const VTermScreenCell *cells, void *data)
}
memcpy(sbrow->cells, cells, sizeof(cells[0]) * c);
- pmap_put(ptr_t)(invalidated_terminals, term, NULL);
+ pmap_put(ptr_t)(&invalidated_terminals, term, NULL);
return 1;
}
@@ -906,7 +909,7 @@ static int term_sb_pop(int cols, VTermScreenCell *cells, void *data)
}
xfree(sbrow);
- pmap_put(ptr_t)(invalidated_terminals, term, NULL);
+ pmap_put(ptr_t)(&invalidated_terminals, term, NULL);
return 1;
}
@@ -1208,7 +1211,7 @@ static void invalidate_terminal(Terminal *term, int start_row, int end_row)
term->invalid_end = MAX(term->invalid_end, end_row);
}
- pmap_put(ptr_t)(invalidated_terminals, term, NULL);
+ pmap_put(ptr_t)(&invalidated_terminals, term, NULL);
if (!refresh_pending) {
time_watcher_start(&refresh_timer, refresh_timer_cb, REFRESH_DELAY, 0);
refresh_pending = true;
@@ -1250,10 +1253,10 @@ static void refresh_timer_cb(TimeWatcher *watcher, void *data)
void *stub; (void)(stub);
// don't process autocommands while updating terminal buffers
block_autocmds();
- map_foreach(invalidated_terminals, term, stub, {
+ map_foreach(&invalidated_terminals, term, stub, {
refresh_terminal(term);
});
- pmap_clear(ptr_t)(invalidated_terminals);
+ pmap_clear(ptr_t)(&invalidated_terminals);
unblock_autocmds();
}
diff --git a/src/nvim/testdir/check.vim b/src/nvim/testdir/check.vim
index 7b06e53dd5..14bab33a2f 100644
--- a/src/nvim/testdir/check.vim
+++ b/src/nvim/testdir/check.vim
@@ -9,6 +9,17 @@ func CheckFeature(name)
endif
endfunc
+" Command to check for the absence of a feature.
+command -nargs=1 CheckNotFeature call CheckNotFeature(<f-args>)
+func CheckNotFeature(name)
+ if !has(a:name, 1)
+ throw 'Checking for non-existent feature ' .. a:name
+ endif
+ if has(a:name)
+ throw 'Skipped: ' .. a:name .. ' feature present'
+ endif
+endfunc
+
" Command to check for the presence of a working option.
command -nargs=1 CheckOption call CheckOption(<f-args>)
func CheckOption(name)
diff --git a/src/nvim/testdir/samples/memfile_test.c b/src/nvim/testdir/samples/memfile_test.c
index c71a5c8f40..7023064637 100644
--- a/src/nvim/testdir/samples/memfile_test.c
+++ b/src/nvim/testdir/samples/memfile_test.c
@@ -37,8 +37,8 @@ test_mf_hash(void)
mf_hashtab_T ht;
mf_hashitem_T *item;
blocknr_T key;
- long_u i;
- long_u num_buckets;
+ size_t i;
+ size_t num_buckets;
mf_hash_init(&ht);
diff --git a/src/nvim/testdir/sautest/autoload/foo.vim b/src/nvim/testdir/sautest/autoload/foo.vim
index d7dcd5ce3d..298e7275d8 100644
--- a/src/nvim/testdir/sautest/autoload/foo.vim
+++ b/src/nvim/testdir/sautest/autoload/foo.vim
@@ -5,3 +5,7 @@ let foo#bar = {}
func foo#bar.echo()
let g:called_foo_bar_echo += 1
endfunc
+
+func foo#addFoo(head)
+ return a:head .. 'foo'
+endfunc
diff --git a/src/nvim/testdir/setup.vim b/src/nvim/testdir/setup.vim
index fd9cfb54be..b3df8c63e6 100644
--- a/src/nvim/testdir/setup.vim
+++ b/src/nvim/testdir/setup.vim
@@ -12,6 +12,7 @@ set directory^=.
set fillchars=vert:\|,fold:-
set laststatus=1
set listchars=eol:$
+set joinspaces
set nohidden smarttab noautoindent noautoread complete-=i noruler noshowcmd
set nrformats+=octal
set shortmess-=F
@@ -20,7 +21,15 @@ set tags=./tags,tags
set undodir^=.
set wildoptions=
set startofline
-set sessionoptions&vi
+set sessionoptions+=options
+set viewoptions+=options
+set switchbuf=
+
+" Unmap Nvim default mappings.
+unmap Y
+unmap <C-L>
+iunmap <C-U>
+iunmap <C-W>
" Prevent Nvim log from writing to stderr.
let $NVIM_LOG_FILE = exists($NVIM_LOG_FILE) ? $NVIM_LOG_FILE : 'Xnvim.log'
diff --git a/src/nvim/testdir/test42.in b/src/nvim/testdir/test42.in
index d9057e72fb..456f9ddb07 100644
--- a/src/nvim/testdir/test42.in
+++ b/src/nvim/testdir/test42.in
Binary files differ
diff --git a/src/nvim/testdir/test_alot.vim b/src/nvim/testdir/test_alot.vim
index b5c50b5894..cc767a9bcf 100644
--- a/src/nvim/testdir/test_alot.vim
+++ b/src/nvim/testdir/test_alot.vim
@@ -7,6 +7,7 @@ source test_cd.vim
source test_changedtick.vim
source test_compiler.vim
source test_cursor_func.vim
+source test_cursorline.vim
source test_ex_equal.vim
source test_ex_undo.vim
source test_ex_z.vim
diff --git a/src/nvim/testdir/test_arglist.vim b/src/nvim/testdir/test_arglist.vim
index a1ef8325ec..01d8f32893 100644
--- a/src/nvim/testdir/test_arglist.vim
+++ b/src/nvim/testdir/test_arglist.vim
@@ -90,8 +90,8 @@ func Test_argadd_empty_curbuf()
call assert_equal('', bufname('%'))
call assert_equal(1, line('$'))
rew
- call assert_notequal(curbuf, bufnr('%'))
- call assert_equal('Xargadd', bufname('%'))
+ call assert_notequal(curbuf, '%'->bufnr())
+ call assert_equal('Xargadd', '%'->bufname())
call assert_equal(2, line('$'))
%argd
diff --git a/src/nvim/testdir/test_assert.vim b/src/nvim/testdir/test_assert.vim
index 1d114221dc..52f243aaea 100644
--- a/src/nvim/testdir/test_assert.vim
+++ b/src/nvim/testdir/test_assert.vim
@@ -7,7 +7,7 @@ func Test_assert_equalfile()
let goodtext = ["one", "two", "three"]
call writefile(goodtext, 'Xone')
- call assert_equal(1, assert_equalfile('Xone', 'xyzxyz'))
+ call assert_equal(1, 'Xone'->assert_equalfile('xyzxyz'))
call assert_match("E485: Can't read file xyzxyz", v:errors[0])
call remove(v:errors, 0)
diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim
index ad28118f16..015979e1be 100644
--- a/src/nvim/testdir/test_autocmd.vim
+++ b/src/nvim/testdir/test_autocmd.vim
@@ -998,6 +998,7 @@ func Test_bufunload_all()
endfunc
au BufUnload * call UnloadAllBufs()
au VimLeave * call writefile(['Test Finished'], 'Xout')
+ set nohidden
edit Xxx1
split Xxx2
q
@@ -1955,7 +1956,7 @@ func Test_autocmd_sigusr1()
let g:sigusr1_passed = 0
au Signal SIGUSR1 let g:sigusr1_passed = 1
- call system('/bin/kill -s usr1 ' . getpid())
+ call system('kill -s usr1 ' . getpid())
call WaitForAssert({-> assert_true(g:sigusr1_passed)})
au! Signal
diff --git a/src/nvim/testdir/test_autoload.vim b/src/nvim/testdir/test_autoload.vim
index 7396c227c9..b8c4fa251f 100644
--- a/src/nvim/testdir/test_autoload.vim
+++ b/src/nvim/testdir/test_autoload.vim
@@ -8,6 +8,8 @@ func Test_autoload_dict_func()
call g:foo#bar.echo()
call assert_equal(1, g:loaded_foo_vim)
call assert_equal(1, g:called_foo_bar_echo)
+
+ eval 'bar'->g:foo#addFoo()->assert_equal('barfoo')
endfunc
func Test_source_autoload()
diff --git a/src/nvim/testdir/test_blob.vim b/src/nvim/testdir/test_blob.vim
new file mode 100644
index 0000000000..20758b0c0a
--- /dev/null
+++ b/src/nvim/testdir/test_blob.vim
@@ -0,0 +1,349 @@
+" Tests for the Blob types
+
+func TearDown()
+ " Run garbage collection after every test
+ call test_garbagecollect_now()
+endfunc
+
+" Tests for Blob type
+
+" Blob creation from constant
+func Test_blob_create()
+ let b = 0zDEADBEEF
+ call assert_equal(v:t_blob, type(b))
+ call assert_equal(4, len(b))
+ call assert_equal(0xDE, b[0])
+ call assert_equal(0xAD, b[1])
+ call assert_equal(0xBE, b[2])
+ call assert_equal(0xEF, b[3])
+ call assert_fails('let x = b[4]')
+
+ call assert_equal(0xDE, get(b, 0))
+ call assert_equal(0xEF, get(b, 3))
+
+ call assert_fails('let b = 0z1', 'E973:')
+ call assert_fails('let b = 0z1x', 'E973:')
+ call assert_fails('let b = 0z12345', 'E973:')
+
+ call assert_equal(0z, v:_null_blob)
+
+ let b = 0z001122.33445566.778899.aabbcc.dd
+ call assert_equal(0z00112233445566778899aabbccdd, b)
+ call assert_fails('let b = 0z1.1')
+ call assert_fails('let b = 0z.')
+ call assert_fails('let b = 0z001122.')
+ call assert_fails('call get("", 1)', 'E896:')
+ call assert_equal(0, len(v:_null_blob))
+endfunc
+
+" assignment to a blob
+func Test_blob_assign()
+ let b = 0zDEADBEEF
+ let b2 = b[1:2]
+ call assert_equal(0zADBE, b2)
+
+ let bcopy = b[:]
+ call assert_equal(b, bcopy)
+ call assert_false(b is bcopy)
+
+ let b = 0zDEADBEEF
+ let b2 = b
+ call assert_true(b is b2)
+ let b[:] = 0z11223344
+ call assert_equal(0z11223344, b)
+ call assert_equal(0z11223344, b2)
+ call assert_true(b is b2)
+
+ let b = 0zDEADBEEF
+ let b[3:] = 0z66
+ call assert_equal(0zDEADBE66, b)
+ let b[:1] = 0z8899
+ call assert_equal(0z8899BE66, b)
+
+ call assert_fails('let b[2:3] = 0z112233', 'E972:')
+ call assert_fails('let b[2:3] = 0z11', 'E972:')
+ call assert_fails('let b[3:2] = 0z', 'E979:')
+
+ let b = 0zDEADBEEF
+ let b += 0z99
+ call assert_equal(0zDEADBEEF99, b)
+
+ call assert_fails('let b .= 0z33', 'E734:')
+ call assert_fails('let b .= "xx"', 'E734:')
+ call assert_fails('let b += "xx"', 'E734:')
+ call assert_fails('let b[1:1] .= 0z55', 'E734:')
+
+ let l = [0z12]
+ let m = deepcopy(l)
+ let m[0] = 0z34 " E742 or E741 should not occur.
+endfunc
+
+func Test_blob_get_range()
+ let b = 0z0011223344
+ call assert_equal(0z2233, b[2:3])
+ call assert_equal(0z223344, b[2:-1])
+ call assert_equal(0z00, b[0:-5])
+ call assert_equal(0z, b[0:-11])
+ call assert_equal(0z44, b[-1:])
+ call assert_equal(0z0011223344, b[:])
+ call assert_equal(0z0011223344, b[:-1])
+ call assert_equal(0z, b[5:6])
+endfunc
+
+func Test_blob_get()
+ let b = 0z0011223344
+ call assert_equal(0x00, get(b, 0))
+ call assert_equal(0x22, get(b, 2, 999))
+ call assert_equal(0x44, get(b, 4))
+ call assert_equal(0x44, get(b, -1))
+ call assert_equal(-1, get(b, 5))
+ call assert_equal(999, get(b, 5, 999))
+ call assert_equal(-1, get(b, -8))
+ call assert_equal(999, get(b, -8, 999))
+ call assert_equal(10, get(v:_null_blob, 2, 10))
+
+ call assert_equal(0x00, b[0])
+ call assert_equal(0x22, b[2])
+ call assert_equal(0x44, b[4])
+ call assert_equal(0x44, b[-1])
+ call assert_fails('echo b[5]', 'E979:')
+ call assert_fails('echo b[-8]', 'E979:')
+endfunc
+
+func Test_blob_to_string()
+ let b = 0z00112233445566778899aabbccdd
+ call assert_equal('0z00112233.44556677.8899AABB.CCDD', string(b))
+ call assert_equal(b, eval(string(b)))
+ call remove(b, 4, -1)
+ call assert_equal('0z00112233', string(b))
+ call remove(b, 0, 3)
+ call assert_equal('0z', string(b))
+endfunc
+
+func Test_blob_compare()
+ let b1 = 0z0011
+ let b2 = 0z1100
+ let b3 = 0z001122
+ call assert_true(b1 == b1)
+ call assert_false(b1 == b2)
+ call assert_false(b1 == b3)
+ call assert_true(b1 != b2)
+ call assert_true(b1 != b3)
+ call assert_true(b1 == 0z0011)
+ call assert_fails('echo b1 == 9', 'E977:')
+ call assert_fails('echo b1 != 9', 'E977:')
+
+ call assert_false(b1 is b2)
+ let b2 = b1
+ call assert_true(b1 == b2)
+ call assert_true(b1 is b2)
+ let b2 = copy(b1)
+ call assert_true(b1 == b2)
+ call assert_false(b1 is b2)
+ let b2 = b1[:]
+ call assert_true(b1 == b2)
+ call assert_false(b1 is b2)
+
+ call assert_fails('let x = b1 > b2')
+ call assert_fails('let x = b1 < b2')
+ call assert_fails('let x = b1 - b2')
+ call assert_fails('let x = b1 / b2')
+ call assert_fails('let x = b1 * b2')
+endfunc
+
+" test for range assign
+func Test_blob_range_assign()
+ let b = 0z00
+ let b[1] = 0x11
+ let b[2] = 0x22
+ call assert_equal(0z001122, b)
+ call assert_fails('let b[4] = 0x33', 'E979:')
+endfunc
+
+func Test_blob_for_loop()
+ let blob = 0z00010203
+ let i = 0
+ for byte in blob
+ call assert_equal(i, byte)
+ let i += 1
+ endfor
+ call assert_equal(4, i)
+
+ let blob = 0z00
+ call remove(blob, 0)
+ call assert_equal(0, len(blob))
+ for byte in blob
+ call assert_error('loop over empty blob')
+ endfor
+
+ let blob = 0z0001020304
+ let i = 0
+ for byte in blob
+ call assert_equal(i, byte)
+ if i == 1
+ call remove(blob, 0)
+ elseif i == 3
+ call remove(blob, 3)
+ endif
+ let i += 1
+ endfor
+ call assert_equal(5, i)
+endfunc
+
+func Test_blob_concatenate()
+ let b = 0z0011
+ let b += 0z2233
+ call assert_equal(0z00112233, b)
+
+ call assert_fails('let b += "a"')
+ call assert_fails('let b += 88')
+
+ let b = 0zDEAD + 0zBEEF
+ call assert_equal(0zDEADBEEF, b)
+endfunc
+
+func Test_blob_add()
+ let b = 0z0011
+ call add(b, 0x22)
+ call assert_equal(0z001122, b)
+ call add(b, '51')
+ call assert_equal(0z00112233, b)
+
+ call assert_fails('call add(b, [9])', 'E745:')
+ call assert_fails('call add("", 0x01)', 'E897:')
+endfunc
+
+func Test_blob_empty()
+ call assert_false(empty(0z001122))
+ call assert_true(empty(0z))
+ call assert_true(empty(v:_null_blob))
+endfunc
+
+" Test removing items in blob
+func Test_blob_func_remove()
+ " Test removing 1 element
+ let b = 0zDEADBEEF
+ call assert_equal(0xDE, remove(b, 0))
+ call assert_equal(0zADBEEF, b)
+
+ let b = 0zDEADBEEF
+ call assert_equal(0xEF, remove(b, -1))
+ call assert_equal(0zDEADBE, b)
+
+ let b = 0zDEADBEEF
+ call assert_equal(0xAD, remove(b, 1))
+ call assert_equal(0zDEBEEF, b)
+
+ " Test removing range of element(s)
+ let b = 0zDEADBEEF
+ call assert_equal(0zBE, remove(b, 2, 2))
+ call assert_equal(0zDEADEF, b)
+
+ let b = 0zDEADBEEF
+ call assert_equal(0zADBE, remove(b, 1, 2))
+ call assert_equal(0zDEEF, b)
+
+ " Test invalid cases
+ let b = 0zDEADBEEF
+ call assert_fails("call remove(b, 5)", 'E979:')
+ call assert_fails("call remove(b, 1, 5)", 'E979:')
+ call assert_fails("call remove(b, 3, 2)", 'E979:')
+ call assert_fails("call remove(1, 0)", 'E896:')
+ call assert_fails("call remove(b, b)", 'E974:')
+ call assert_fails("call remove(v:_null_blob, 1, 2)", 'E979:')
+
+ " Translated from v8.2.3284
+ let b = 0zDEADBEEF
+ lockvar b
+ call assert_fails('call remove(b, 0)', 'E741:')
+ unlockvar b
+endfunc
+
+func Test_blob_read_write()
+ let b = 0zDEADBEEF
+ call writefile(b, 'Xblob')
+ let br = readfile('Xblob', 'B')
+ call assert_equal(b, br)
+ call delete('Xblob')
+
+ " This was crashing when calling readfile() with a directory.
+ call assert_fails("call readfile('.', 'B')", 'E17: "." is a directory')
+endfunc
+
+" filter() item in blob
+func Test_blob_filter()
+ call assert_equal(0z, filter(0zDEADBEEF, '0'))
+ call assert_equal(0zADBEEF, filter(0zDEADBEEF, 'v:val != 0xDE'))
+ call assert_equal(0zDEADEF, filter(0zDEADBEEF, 'v:val != 0xBE'))
+ call assert_equal(0zDEADBE, filter(0zDEADBEEF, 'v:val != 0xEF'))
+ call assert_equal(0zDEADBEEF, filter(0zDEADBEEF, '1'))
+ call assert_equal(0z01030103, filter(0z010203010203, 'v:val != 0x02'))
+ call assert_equal(0zADEF, filter(0zDEADBEEF, 'v:key % 2'))
+endfunc
+
+" map() item in blob
+func Test_blob_map()
+ call assert_equal(0zDFAEBFF0, map(0zDEADBEEF, 'v:val + 1'))
+ call assert_equal(0z00010203, map(0zDEADBEEF, 'v:key'))
+ call assert_equal(0zDEAEC0F2, map(0zDEADBEEF, 'v:key + v:val'))
+
+ call assert_fails("call map(0z00, '[9]')", 'E978:')
+endfunc
+
+func Test_blob_index()
+ call assert_equal(2, index(0zDEADBEEF, 0xBE))
+ call assert_equal(-1, index(0zDEADBEEF, 0))
+ call assert_equal(2, index(0z11111111, 0x11, 2))
+ call assert_equal(3, index(0z11110111, 0x11, 2))
+ call assert_equal(2, index(0z11111111, 0x11, -2))
+ call assert_equal(3, index(0z11110111, 0x11, -2))
+
+ call assert_fails('call index("asdf", 0)', 'E897:')
+endfunc
+
+func Test_blob_insert()
+ let b = 0zDEADBEEF
+ call insert(b, 0x33)
+ call assert_equal(0z33DEADBEEF, b)
+
+ let b = 0zDEADBEEF
+ call insert(b, 0x33, 2)
+ call assert_equal(0zDEAD33BEEF, b)
+
+ call assert_fails('call insert(b, -1)', 'E475:')
+ call assert_fails('call insert(b, 257)', 'E475:')
+ call assert_fails('call insert(b, 0, [9])', 'E745:')
+ call assert_equal(0, insert(v:_null_blob, 0x33))
+
+ " Translated from v8.2.3284
+ let b = 0zDEADBEEF
+ lockvar b
+ call assert_fails('call insert(b, 3)', 'E741:')
+ unlockvar b
+endfunc
+
+func Test_blob_reverse()
+ call assert_equal(0zEFBEADDE, reverse(0zDEADBEEF))
+ call assert_equal(0zBEADDE, reverse(0zDEADBE))
+ call assert_equal(0zADDE, reverse(0zDEAD))
+ call assert_equal(0zDE, reverse(0zDE))
+ call assert_equal(0z, reverse(v:_null_blob))
+endfunc
+
+func Test_blob_lock()
+ let b = 0z112233
+ lockvar b
+ call assert_fails('let b = 0z44', 'E741:')
+ unlockvar b
+ let b = 0z44
+endfunc
+
+func Test_blob_sort()
+ if has('float')
+ call assert_fails('call sort([1.0, 0z11], "f")', 'E975:')
+ else
+ call assert_fails('call sort(["abc", 0z11], "f")', 'E702:')
+ endif
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_breakindent.vim b/src/nvim/testdir/test_breakindent.vim
index ff5029b889..97b570e64f 100644
--- a/src/nvim/testdir/test_breakindent.vim
+++ b/src/nvim/testdir/test_breakindent.vim
@@ -16,6 +16,10 @@ func s:screen_lines(lnum, width) abort
return ScreenLines([a:lnum, a:lnum + 2], a:width)
endfunc
+func s:screen_lines2(lnums, lnume, width) abort
+ return ScreenLines([a:lnums, a:lnume], a:width)
+endfunc
+
func! s:compare_lines(expect, actual)
call assert_equal(join(a:expect, "\n"), join(a:actual, "\n"))
endfunc
@@ -63,7 +67,8 @@ endfunc
func Test_breakindent02()
" simple breakindent test with showbreak set
- call s:test_windows('setl briopt=min:0 sbr=>>')
+ set sbr=>>
+ call s:test_windows('setl briopt=min:0 sbr=')
let lines = s:screen_lines(line('.'),8)
let expect = [
\ " abcd",
@@ -123,7 +128,8 @@ endfunc
func Test_breakindent04()
" breakindent set with min width 18
- call s:test_windows('setl sbr= briopt=min:18')
+ set sbr=<<<
+ call s:test_windows('setl sbr=NONE briopt=min:18')
let lines = s:screen_lines(line('.'),8)
let expect = [
\ " abcd",
@@ -133,6 +139,7 @@ func Test_breakindent04()
call s:compare_lines(expect, lines)
" clean up
call s:close_windows('set sbr=')
+ set sbr=
endfunc
func Test_breakindent04_vartabs()
@@ -745,4 +752,141 @@ func Test_breakindent20_cpo_n_nextpage()
call s:close_windows('set breakindent& briopt& cpo& number&')
endfunc
+func Test_breakindent20_list()
+ call s:test_windows('setl breakindent breakindentopt= linebreak')
+ " default:
+ call setline(1, [' 1. Congress shall make no law',
+ \ ' 2.) Congress shall make no law',
+ \ ' 3.] Congress shall make no law'])
+ norm! 1gg
+ redraw!
+ let lines = s:screen_lines2(1, 6, 20)
+ let expect = [
+ \ " 1. Congress ",
+ \ "shall make no law ",
+ \ " 2.) Congress ",
+ \ "shall make no law ",
+ \ " 3.] Congress ",
+ \ "shall make no law ",
+ \ ]
+ call s:compare_lines(expect, lines)
+ " set mininum indent
+ setl briopt=min:5
+ redraw!
+ let lines = s:screen_lines2(1, 6, 20)
+ let expect = [
+ \ " 1. Congress ",
+ \ " shall make no law ",
+ \ " 2.) Congress ",
+ \ " shall make no law ",
+ \ " 3.] Congress ",
+ \ " shall make no law ",
+ \ ]
+ call s:compare_lines(expect, lines)
+ " set additional handing indent
+ setl briopt+=list:4
+ redraw!
+ let expect = [
+ \ " 1. Congress ",
+ \ " shall make no ",
+ \ " law ",
+ \ " 2.) Congress ",
+ \ " shall make no ",
+ \ " law ",
+ \ " 3.] Congress ",
+ \ " shall make no ",
+ \ " law ",
+ \ ]
+ let lines = s:screen_lines2(1, 9, 20)
+ call s:compare_lines(expect, lines)
+
+ " reset linebreak option
+ " Note: it indents by one additional
+ " space, because of the leading space.
+ setl linebreak&vim list listchars=eol:$,space:_
+ redraw!
+ let expect = [
+ \ "__1.__Congress_shall",
+ \ " _make_no_law$ ",
+ \ "__2.)_Congress_shall",
+ \ " _make_no_law$ ",
+ \ "__3.]_Congress_shall",
+ \ " _make_no_law$ ",
+ \ ]
+ let lines = s:screen_lines2(1, 6, 20)
+ call s:compare_lines(expect, lines)
+
+ " check formatlistpat indent
+ setl briopt=min:5,list:-1
+ setl linebreak list&vim listchars&vim
+ let &l:flp = '^\s*\d\+\.\?[\]:)}\t ]\s*'
+ redraw!
+ let expect = [
+ \ " 1. Congress ",
+ \ " shall make no ",
+ \ " law ",
+ \ " 2.) Congress ",
+ \ " shall make no ",
+ \ " law ",
+ \ " 3.] Congress ",
+ \ " shall make no ",
+ \ " law ",
+ \ ]
+ let lines = s:screen_lines2(1, 9, 20)
+ call s:compare_lines(expect, lines)
+ " check formatlistpat indent with different list levels
+ let &l:flp = '^\s*\*\+\s\+'
+ redraw!
+ %delete _
+ call setline(1, ['* Congress shall make no law',
+ \ '*** Congress shall make no law',
+ \ '**** Congress shall make no law'])
+ norm! 1gg
+ let expect = [
+ \ "* Congress shall ",
+ \ " make no law ",
+ \ "*** Congress shall ",
+ \ " make no law ",
+ \ "**** Congress shall ",
+ \ " make no law ",
+ \ ]
+ let lines = s:screen_lines2(1, 6, 20)
+ call s:compare_lines(expect, lines)
+
+ " check formatlistpat indent with different list level
+ " showbreak and sbr
+ setl briopt=min:5,sbr,list:-1,shift:2
+ setl showbreak=>
+ redraw!
+ let expect = [
+ \ "* Congress shall ",
+ \ "> make no law ",
+ \ "*** Congress shall ",
+ \ "> make no law ",
+ \ "**** Congress shall ",
+ \ "> make no law ",
+ \ ]
+ let lines = s:screen_lines2(1, 6, 20)
+ call s:compare_lines(expect, lines)
+ call s:close_windows('set breakindent& briopt& linebreak& list& listchars& showbreak&')
+endfunc
+
+" The following used to crash Vim. This is fixed by 8.2.3391.
+" This is a regression introduced by 8.2.2903.
+func Test_window_resize_with_linebreak()
+ new
+ 53vnew
+ set linebreak
+ set showbreak=>>
+ set breakindent
+ set breakindentopt=shift:4
+ call setline(1, "\naaaaaaaaa\n\na\naaaaa\n¯aaaaaaaaaa\naaaaaaaaaaaa\naaa\n\"a:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - aaaaaaaa\"\naaaaaaaa\n\"a")
+ redraw!
+ call assert_equal([" >>aa^@\"a: "], ScreenLines(2, 14))
+ vertical resize 52
+ redraw!
+ call assert_equal([" >>aaa^@\"a:"], ScreenLines(2, 14))
+ %bw!
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_bufline.vim b/src/nvim/testdir/test_bufline.vim
index e038bce08e..b4e8a0bc71 100644
--- a/src/nvim/testdir/test_bufline.vim
+++ b/src/nvim/testdir/test_bufline.vim
@@ -102,7 +102,7 @@ func Test_deletebufline()
call assert_equal(0, deletebufline(b, 2, 8))
call assert_equal(['aaa'], getbufline(b, 1, 2))
exe "bd!" b
- call assert_equal(1, deletebufline(b, 1))
+ call assert_equal(1, b->deletebufline(1))
split Xtest
call setline(1, ['a', 'b', 'c'])
@@ -131,11 +131,11 @@ func Test_appendbufline_redraw()
endif
let lines =<< trim END
new foo
- let winnr=bufwinnr('foo')
- let buf=bufnr('foo')
+ let winnr = 'foo'->bufwinnr()
+ let buf = bufnr('foo')
wincmd p
call appendbufline(buf, '$', range(1,200))
- exe winnr. 'wincmd w'
+ exe winnr .. 'wincmd w'
norm! G
wincmd p
call deletebufline(buf, 1, '$')
diff --git a/src/nvim/testdir/test_bufwintabinfo.vim b/src/nvim/testdir/test_bufwintabinfo.vim
index cb7ab44798..4b5b55e6bf 100644
--- a/src/nvim/testdir/test_bufwintabinfo.vim
+++ b/src/nvim/testdir/test_bufwintabinfo.vim
@@ -18,7 +18,7 @@ function Test_getbufwintabinfo()
let l = getbufinfo('%')
call assert_equal(bufnr('%'), l[0].bufnr)
call assert_equal('vim', l[0].variables.editor)
- call assert_notequal(-1, index(l[0].windows, bufwinid('%')))
+ call assert_notequal(-1, index(l[0].windows, '%'->bufwinid()))
" Test for getbufinfo() with 'bufmodified'
call assert_equal(0, len(getbufinfo({'bufmodified' : 1})))
diff --git a/src/nvim/testdir/test_cd.vim b/src/nvim/testdir/test_cd.vim
index 770ed55b8d..02a23bf82f 100644
--- a/src/nvim/testdir/test_cd.vim
+++ b/src/nvim/testdir/test_cd.vim
@@ -1,4 +1,7 @@
-" Test for :cd
+" Test for :cd and chdir()
+
+source shared.vim
+source check.vim
func Test_cd_large_path()
" This used to crash with a heap write overflow.
@@ -65,3 +68,18 @@ func Test_cd_with_cpo_chdir()
set cpo&
bw!
endfunc
+
+func Test_cd_from_non_existing_dir()
+ CheckNotMSWindows
+
+ let saveddir = getcwd()
+ call mkdir('Xdeleted_dir')
+ cd Xdeleted_dir
+ call delete(saveddir .. '/Xdeleted_dir', 'd')
+
+ " Expect E187 as the current directory was deleted.
+ call assert_fails('pwd', 'E187:')
+ call assert_equal('', getcwd())
+ cd -
+ call assert_equal(saveddir, getcwd())
+endfunc
diff --git a/src/nvim/testdir/test_cindent.vim b/src/nvim/testdir/test_cindent.vim
index b6c2d1467e..562867f548 100644
--- a/src/nvim/testdir/test_cindent.vim
+++ b/src/nvim/testdir/test_cindent.vim
@@ -118,6 +118,16 @@ b = something();
bw!
endfunc
+func Test_cindent_func()
+ new
+ setlocal cindent
+ call setline(1, ['int main(void)', '{', 'return 0;', '}'])
+ call assert_equal(-1, cindent(0))
+ call assert_equal(&sw, 3->cindent())
+ call assert_equal(-1, cindent(line('$')+1))
+ bwipe!
+endfunc
+
" this was going beyond the end of the line.
func Test_cindent_case()
new
diff --git a/src/nvim/testdir/test_cmdline.vim b/src/nvim/testdir/test_cmdline.vim
index 34126b49fa..5a6824b5c1 100644
--- a/src/nvim/testdir/test_cmdline.vim
+++ b/src/nvim/testdir/test_cmdline.vim
@@ -7,6 +7,10 @@ func Test_complete_tab()
call writefile(['testfile'], 'Xtestfile')
call feedkeys(":e Xtestf\t\r", "tx")
call assert_equal('testfile', getline(1))
+
+ " Pressing <Tab> after '%' completes the current file, also on MS-Windows
+ call feedkeys(":e %\t\r", "tx")
+ call assert_equal('e Xtestfile', @:)
call delete('Xtestfile')
endfunc
@@ -595,13 +599,26 @@ endfunc
func Test_cmdline_complete_user_func()
call feedkeys(":func Test_cmdline_complete_user\<Tab>\<Home>\"\<cr>", 'tx')
- call assert_match('"func Test_cmdline_complete_user', @:)
+ call assert_match('"func Test_cmdline_complete_user_', @:)
call feedkeys(":func s:ScriptL\<Tab>\<Home>\"\<cr>", 'tx')
call assert_match('"func <SNR>\d\+_ScriptLocalFunction', @:)
" g: prefix also works
call feedkeys(":echo g:Test_cmdline_complete_user_f\<Tab>\<Home>\"\<cr>", 'tx')
call assert_match('"echo g:Test_cmdline_complete_user_func', @:)
+
+ " using g: prefix does not result in just "g:" matches from a lambda
+ let Fx = { a -> a }
+ call feedkeys(":echo g:\<Tab>\<Home>\"\<cr>", 'tx')
+ call assert_match('"echo g:[A-Z]', @:)
+
+ " existence of script-local dict function does not break user function name
+ " completion
+ function s:a_dict_func() dict
+ endfunction
+ call feedkeys(":call Test_cmdline_complete_user\<Tab>\<Home>\"\<cr>", 'tx')
+ call assert_match('"call Test_cmdline_complete_user_', @:)
+ delfunction s:a_dict_func
endfunc
func Test_cmdline_complete_user_names()
diff --git a/src/nvim/testdir/test_command_count.vim b/src/nvim/testdir/test_command_count.vim
index 55b230373f..c7dddf4164 100644
--- a/src/nvim/testdir/test_command_count.vim
+++ b/src/nvim/testdir/test_command_count.vim
@@ -33,7 +33,7 @@ func Test_command_count_0()
delcommand RangeBuffers
delcommand RangeBuffersAll
- set hidden&
+ set nohidden
set swapfile&
endfunc
diff --git a/src/nvim/testdir/test_const.vim b/src/nvim/testdir/test_const.vim
index ea69c8cba4..0d064617a5 100644
--- a/src/nvim/testdir/test_const.vim
+++ b/src/nvim/testdir/test_const.vim
@@ -244,18 +244,33 @@ func Test_const_with_eval_name()
call assert_fails('const {s2} = "bar"', 'E995:')
endfunc
-func Test_lock_depth_is_1()
- const l = [1, 2, 3]
- const d = {'foo': 10}
-
- " Modify list - setting item is OK, adding/removing items not
- let l[0] = 42
+func Test_lock_depth_is_2()
+ " Modify list - error when changing item or adding/removing items
+ const l = [1, 2, [3, 4]]
+ call assert_fails('let l[0] = 42', 'E741:')
+ call assert_fails('let l[2][0] = 42', 'E741:')
call assert_fails('call add(l, 4)', 'E741:')
call assert_fails('unlet l[1]', 'E741:')
- " Modify dict - changing item is OK, adding/removing items not
- let d['foo'] = 'hello'
- let d.foo = 44
+ " Modify blob - error when changing
+ const b = 0z001122
+ call assert_fails('let b[0] = 42', 'E741:')
+
+ " Modify dict - error when changing item or adding/removing items
+ const d = {'foo': 10}
+ call assert_fails("let d['foo'] = 'hello'", 'E741:')
+ call assert_fails("let d.foo = 'hello'", 'E741:')
call assert_fails("let d['bar'] = 'hello'", 'E741:')
call assert_fails("unlet d['foo']", 'E741:')
+
+ " Modifying list or dict item contents is OK.
+ let lvar = ['a', 'b']
+ let bvar = 0z1122
+ const l2 = [0, lvar, bvar]
+ let l2[1][0] = 'c'
+ let l2[2][1] = 0x33
+ call assert_equal([0, ['c', 'b'], 0z1133], l2)
+
+ const d2 = #{a: 0, b: lvar, c: 4}
+ let d2.b[1] = 'd'
endfunc
diff --git a/src/nvim/testdir/test_cursorline.vim b/src/nvim/testdir/test_cursorline.vim
new file mode 100644
index 0000000000..39d8b901ed
--- /dev/null
+++ b/src/nvim/testdir/test_cursorline.vim
@@ -0,0 +1,271 @@
+" Test for cursorline and cursorlineopt
+
+source check.vim
+source screendump.vim
+
+function! s:screen_attr(lnum) abort
+ return map(range(1, 8), 'screenattr(a:lnum, v:val)')
+endfunction
+
+function! s:test_windows(h, w) abort
+ call NewWindow(a:h, a:w)
+endfunction
+
+function! s:close_windows() abort
+ call CloseWindow()
+endfunction
+
+function! s:new_hi() abort
+ redir => save_hi
+ silent! hi CursorLineNr
+ redir END
+ let save_hi = join(split(substitute(save_hi, '\s*xxx\s*', ' ', ''), "\n"), '')
+ exe 'hi' save_hi 'ctermbg=0 guibg=Black'
+ return save_hi
+endfunction
+
+func Test_cursorline_highlight1()
+ let save_hi = s:new_hi()
+ try
+ call s:test_windows(10, 20)
+ call setline(1, repeat(['aaaa'], 10))
+ redraw
+ let attr01 = s:screen_attr(1)
+ call assert_equal(repeat([attr01[0]], 8), attr01)
+
+ setl number numberwidth=4
+ redraw
+ let attr11 = s:screen_attr(1)
+ call assert_equal(repeat([attr11[0]], 4), attr11[0:3])
+ call assert_equal(repeat([attr11[4]], 4), attr11[4:7])
+ call assert_notequal(attr11[0], attr11[4])
+
+ setl cursorline
+ redraw
+ let attr21 = s:screen_attr(1)
+ let attr22 = s:screen_attr(2)
+ call assert_equal(repeat([attr21[0]], 4), attr21[0:3])
+ call assert_equal(repeat([attr21[4]], 4), attr21[4:7])
+ call assert_equal(attr11, attr22)
+ call assert_notequal(attr22, attr21)
+
+ setl nocursorline relativenumber
+ redraw
+ let attr31 = s:screen_attr(1)
+ call assert_equal(attr22[0:3], attr31[0:3])
+ call assert_equal(attr11[4:7], attr31[4:7])
+
+ call s:close_windows()
+ finally
+ exe 'hi' save_hi
+ endtry
+endfunc
+
+func Test_cursorline_highlight2()
+ CheckOption cursorlineopt
+
+ let save_hi = s:new_hi()
+ try
+ call s:test_windows(10, 20)
+ call setline(1, repeat(['aaaa'], 10))
+ redraw
+ let attr0 = s:screen_attr(1)
+ call assert_equal(repeat([attr0[0]], 8), attr0)
+
+ setl number
+ redraw
+ let attr1 = s:screen_attr(1)
+ call assert_notequal(attr0[0:3], attr1[0:3])
+ call assert_equal(attr0[0:3], attr1[4:7])
+
+ setl cursorline cursorlineopt=both
+ redraw
+ let attr2 = s:screen_attr(1)
+ call assert_notequal(attr1[0:3], attr2[0:3])
+ call assert_notequal(attr1[4:7], attr2[4:7])
+
+ setl cursorlineopt=line
+ redraw
+ let attr3 = s:screen_attr(1)
+ call assert_equal(attr1[0:3], attr3[0:3])
+ call assert_equal(attr2[4:7], attr3[4:7])
+
+ setl cursorlineopt=number
+ redraw
+ let attr4 = s:screen_attr(1)
+ call assert_equal(attr2[0:3], attr4[0:3])
+ call assert_equal(attr1[4:7], attr4[4:7])
+
+ setl nonumber
+ redraw
+ let attr5 = s:screen_attr(1)
+ call assert_equal(attr0, attr5)
+
+ call s:close_windows()
+ finally
+ exe 'hi' save_hi
+ endtry
+endfunc
+
+func Test_cursorline_screenline()
+ CheckScreendump
+ CheckOption cursorlineopt
+
+ let filename='Xcursorline'
+ let lines = []
+
+ let file_content =<< trim END
+ 1 foooooooo ar eins‍zwei drei vier fünf sechs sieben acht un zehn elf zwöfl dreizehn v ierzehn fünfzehn
+ 2 foooooooo bar eins zwei drei vier fünf sechs sieben
+ 3 foooooooo bar eins zwei drei vier fünf sechs sieben
+ 4 foooooooo bar eins zwei drei vier fünf sechs sieben
+ END
+ let lines1 =<< trim END1
+ set nocp
+ set display=lastline
+ set cursorlineopt=screenline cursorline nu wrap sbr=>
+ hi CursorLineNr ctermfg=blue
+ 25vsp
+ END1
+ let lines2 =<< trim END2
+ call cursor(1,1)
+ END2
+ call extend(lines, lines1)
+ call extend(lines, ["call append(0, ".. string(file_content).. ')'])
+ call extend(lines, lines2)
+ call writefile(lines, filename)
+ " basic test
+ let buf = RunVimInTerminal('-S '. filename, #{rows: 20})
+ call term_wait(buf)
+ call VerifyScreenDump(buf, 'Test_'. filename. '_1', {})
+ call term_sendkeys(buf, "fagj")
+ call term_wait(buf)
+ call VerifyScreenDump(buf, 'Test_'. filename. '_2', {})
+ call term_sendkeys(buf, "gj")
+ call term_wait(buf)
+ call VerifyScreenDump(buf, 'Test_'. filename. '_3', {})
+ call term_sendkeys(buf, "gj")
+ call term_wait(buf)
+ call VerifyScreenDump(buf, 'Test_'. filename. '_4', {})
+ call term_sendkeys(buf, "gj")
+ call term_wait(buf)
+ call VerifyScreenDump(buf, 'Test_'. filename. '_5', {})
+ call term_sendkeys(buf, "gj")
+ call term_wait(buf)
+ call VerifyScreenDump(buf, 'Test_'. filename. '_6', {})
+ " test with set list and cursorlineopt containing number
+ call term_sendkeys(buf, "gg0")
+ call term_sendkeys(buf, ":set list cursorlineopt+=number listchars=space:-\<cr>")
+ call VerifyScreenDump(buf, 'Test_'. filename. '_7', {})
+ call term_sendkeys(buf, "fagj")
+ call term_wait(buf)
+ call VerifyScreenDump(buf, 'Test_'. filename. '_8', {})
+ call term_sendkeys(buf, "gj")
+ call term_wait(buf)
+ call VerifyScreenDump(buf, 'Test_'. filename. '_9', {})
+ call term_sendkeys(buf, "gj")
+ call term_wait(buf)
+ call VerifyScreenDump(buf, 'Test_'. filename. '_10', {})
+ call term_sendkeys(buf, "gj")
+ call term_wait(buf)
+ call VerifyScreenDump(buf, 'Test_'. filename. '_11', {})
+ call term_sendkeys(buf, "gj")
+ call term_wait(buf)
+ call VerifyScreenDump(buf, 'Test_'. filename. '_12', {})
+ if exists("+foldcolumn") && exists("+signcolumn") && exists("+breakindent")
+ " test with set foldcolumn signcoloumn and breakindent
+ call term_sendkeys(buf, "gg0")
+ call term_sendkeys(buf, ":set breakindent foldcolumn=2 signcolumn=yes\<cr>")
+ call VerifyScreenDump(buf, 'Test_'. filename. '_13', {})
+ call term_sendkeys(buf, "fagj")
+ call term_wait(buf)
+ call VerifyScreenDump(buf, 'Test_'. filename. '_14', {})
+ call term_sendkeys(buf, "gj")
+ call term_wait(buf)
+ call VerifyScreenDump(buf, 'Test_'. filename. '_15', {})
+ call term_sendkeys(buf, "gj")
+ call term_wait(buf)
+ call VerifyScreenDump(buf, 'Test_'. filename. '_16', {})
+ call term_sendkeys(buf, "gj")
+ call term_wait(buf)
+ call VerifyScreenDump(buf, 'Test_'. filename. '_17', {})
+ call term_sendkeys(buf, "gj")
+ call term_wait(buf)
+ call VerifyScreenDump(buf, 'Test_'. filename. '_18', {})
+ call term_sendkeys(buf, ":set breakindent& foldcolumn& signcolumn&\<cr>")
+ endif
+ " showbreak should not be highlighted with CursorLine when 'number' is off
+ call term_sendkeys(buf, "gg0")
+ call term_sendkeys(buf, ":set list cursorlineopt=screenline listchars=space:-\<cr>")
+ call term_sendkeys(buf, ":set nonumber\<cr>")
+ call VerifyScreenDump(buf, 'Test_'. filename. '_19', {})
+ call term_sendkeys(buf, "fagj")
+ call term_wait(buf)
+ call VerifyScreenDump(buf, 'Test_'. filename. '_20', {})
+ call term_sendkeys(buf, "gj")
+ call term_wait(buf)
+ call VerifyScreenDump(buf, 'Test_'. filename. '_21', {})
+ call term_sendkeys(buf, "gj")
+ call term_wait(buf)
+ call VerifyScreenDump(buf, 'Test_'. filename. '_22', {})
+ call term_sendkeys(buf, "gj")
+ call term_wait(buf)
+ call VerifyScreenDump(buf, 'Test_'. filename. '_23', {})
+ call term_sendkeys(buf, "gj")
+ call term_wait(buf)
+ call VerifyScreenDump(buf, 'Test_'. filename. '_24', {})
+ call term_sendkeys(buf, ":set list& cursorlineopt& listchars&\<cr>")
+
+ call StopVimInTerminal(buf)
+ call delete(filename)
+endfunc
+
+func Test_cursorline_redraw()
+ CheckScreendump
+ CheckOption cursorlineopt
+
+ let textlines =<< END
+ When the option is a list of flags, {value} must be
+ exactly as they appear in the option. Remove flags
+ one by one to avoid problems.
+ Also see |:set-args| above.
+
+The {option} arguments to ":set" may be repeated. For example: >
+ :set ai nosi sw=3 ts=3
+If you make an error in one of the arguments, an error message will be given
+and the following arguments will be ignored.
+
+ *:set-verbose*
+When 'verbose' is non-zero, displaying an option value will also tell where it
+was last set. Example: >
+ :verbose set shiftwidth cindent?
+< shiftwidth=4 ~
+ Last set from modeline line 1 ~
+ cindent ~
+ Last set from /usr/local/share/vim/vim60/ftplugin/c.vim line 30 ~
+This is only done when specific option values are requested, not for ":verbose
+set all" or ":verbose set" without an argument.
+When the option was set by hand there is no "Last set" message.
+When the option was set while executing a function, user command or
+END
+ call writefile(textlines, 'Xtextfile')
+
+ let script =<< trim END
+ set cursorline scrolloff=2
+ normal 12G
+ END
+ call writefile(script, 'Xscript')
+
+ let buf = RunVimInTerminal('-S Xscript Xtextfile', #{rows: 20, cols: 40})
+ call VerifyScreenDump(buf, 'Test_cursorline_redraw_1', {})
+ call term_sendkeys(buf, "zt")
+ call TermWait(buf)
+ call term_sendkeys(buf, "\<C-U>")
+ call VerifyScreenDump(buf, 'Test_cursorline_redraw_2', {})
+
+ call StopVimInTerminal(buf)
+ call delete('Xscript')
+ call delete('Xtextfile')
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_debugger.vim b/src/nvim/testdir/test_debugger.vim
index d1464e9d3b..a396efc09e 100644
--- a/src/nvim/testdir/test_debugger.vim
+++ b/src/nvim/testdir/test_debugger.vim
@@ -267,9 +267,7 @@ func Test_Debugger()
call RunDbgCmd(buf, 'breakd func a()', ['E475: Invalid argument: func a()'])
call RunDbgCmd(buf, 'breakd func a', ['E161: Breakpoint not found: func a'])
call RunDbgCmd(buf, 'breakd expr', ['E475: Invalid argument: expr'])
- call RunDbgCmd(buf, 'breakd expr x', [
- \ 'E121: Undefined variable: x',
- \ 'E161: Breakpoint not found: expr x'])
+ call RunDbgCmd(buf, 'breakd expr x', ['E161: Breakpoint not found: expr x'])
" finish the current function
call RunDbgCmd(buf, 'finish', [
@@ -314,9 +312,12 @@ func Test_Debugger()
call RunDbgCmd(buf, 'enew! | only!')
call StopVimInTerminal(buf)
+endfunc
+func Test_Debugger_breakadd()
" Tests for :breakadd file and :breakadd here
" Breakpoints should be set before sourcing the file
+ CheckRunVimInTerminal
let lines =<< trim END
let var1 = 10
@@ -337,6 +338,10 @@ func Test_Debugger()
call StopVimInTerminal(buf)
call delete('Xtest.vim')
+ %bw!
+
+ call assert_fails('breakadd here', 'E32:')
+ call assert_fails('breakadd file Xtest.vim /\)/', 'E55:')
endfunc
func Test_Backtrace_Through_Source()
diff --git a/src/nvim/testdir/test_diffmode.vim b/src/nvim/testdir/test_diffmode.vim
index 8592f48af7..32cee7ca56 100644
--- a/src/nvim/testdir/test_diffmode.vim
+++ b/src/nvim/testdir/test_diffmode.vim
@@ -540,7 +540,7 @@ func Test_diffopt_hiddenoff()
bwipe!
bwipe!
- set hidden& diffopt&
+ set nohidden diffopt&
endfunc
func Test_diffoff_hidden()
@@ -577,7 +577,7 @@ func Test_diffoff_hidden()
bwipe!
bwipe!
- set hidden& diffopt&
+ set nohidden diffopt&
endfunc
func Test_setting_cursor()
@@ -725,7 +725,7 @@ func Test_diff_filler()
diffthis
redraw
- call assert_equal([0, 0, 0, 0, 0, 0, 0, 1, 0], map(range(-1, 7), 'diff_filler(v:val)'))
+ call assert_equal([0, 0, 0, 0, 0, 0, 0, 1, 0], map(range(-1, 7), 'v:val->diff_filler()'))
wincmd w
call assert_equal([0, 0, 0, 0, 2, 0, 0, 0], map(range(-1, 6), 'diff_filler(v:val)'))
@@ -741,16 +741,16 @@ func Test_diff_hlID()
diffthis
redraw
- call assert_equal(synIDattr(diff_hlID(-1, 1), "name"), "")
+ call diff_hlID(-1, 1)->synIDattr("name")->assert_equal("")
call assert_equal(diff_hlID(1, 1), hlID("DiffChange"))
- call assert_equal(synIDattr(diff_hlID(1, 1), "name"), "DiffChange")
+ call diff_hlID(1, 1)->synIDattr("name")->assert_equal("DiffChange")
call assert_equal(diff_hlID(1, 2), hlID("DiffText"))
- call assert_equal(synIDattr(diff_hlID(1, 2), "name"), "DiffText")
- call assert_equal(synIDattr(diff_hlID(2, 1), "name"), "")
+ call diff_hlID(1, 2)->synIDattr("name")->assert_equal("DiffText")
+ call diff_hlID(2, 1)->synIDattr("name")->assert_equal("")
call assert_equal(diff_hlID(3, 1), hlID("DiffAdd"))
- call assert_equal(synIDattr(diff_hlID(3, 1), "name"), "DiffAdd")
- call assert_equal(synIDattr(diff_hlID(4, 1), "name"), "")
+ call diff_hlID(3, 1)->synIDattr("name")->assert_equal("DiffAdd")
+ call diff_hlID(4, 1)->synIDattr("name")->assert_equal("")
wincmd w
call assert_equal(diff_hlID(1, 1), hlID("DiffChange"))
@@ -965,6 +965,30 @@ func Test_diff_screen()
call delete('XdiffSetup')
endfunc
+func Test_diff_with_scroll_and_change()
+ CheckScreendump
+
+ let lines =<< trim END
+ call setline(1, range(1, 15))
+ vnew
+ call setline(1, range(9, 15))
+ windo diffthis
+ wincmd h
+ exe "normal Gl5\<C-E>"
+ END
+ call writefile(lines, 'Xtest_scroll_change')
+ let buf = RunVimInTerminal('-S Xtest_scroll_change', {})
+
+ call VerifyScreenDump(buf, 'Test_diff_scroll_change_01', {})
+
+ call term_sendkeys(buf, "ax\<Esc>")
+ call VerifyScreenDump(buf, 'Test_diff_scroll_change_02', {})
+
+ " clean up
+ call StopVimInTerminal(buf)
+ call delete('Xtest_scroll_change')
+endfunc
+
func Test_diff_with_cursorline()
CheckScreendump
@@ -990,6 +1014,37 @@ func Test_diff_with_cursorline()
call delete('Xtest_diff_cursorline')
endfunc
+func Test_diff_with_cursorline_breakindent()
+ CheckScreendump
+
+ call writefile([
+ \ 'hi CursorLine ctermbg=red ctermfg=white',
+ \ 'set noequalalways wrap diffopt=followwrap cursorline breakindent',
+ \ '50vnew',
+ \ 'call setline(1, [" "," "," "," "])',
+ \ 'exe "norm 20Afoo\<Esc>j20Afoo\<Esc>j20Afoo\<Esc>j20Abar\<Esc>"',
+ \ 'vnew',
+ \ 'call setline(1, [" "," "," "," "])',
+ \ 'exe "norm 20Abee\<Esc>j20Afoo\<Esc>j20Afoo\<Esc>j20Abaz\<Esc>"',
+ \ 'windo diffthis',
+ \ '2wincmd w',
+ \ ], 'Xtest_diff_cursorline_breakindent')
+ let buf = RunVimInTerminal('-S Xtest_diff_cursorline_breakindent', {})
+
+ call term_sendkeys(buf, "gg0")
+ call VerifyScreenDump(buf, 'Test_diff_with_cul_bri_01', {})
+ call term_sendkeys(buf, "j")
+ call VerifyScreenDump(buf, 'Test_diff_with_cul_bri_02', {})
+ call term_sendkeys(buf, "j")
+ call VerifyScreenDump(buf, 'Test_diff_with_cul_bri_03', {})
+ call term_sendkeys(buf, "j")
+ call VerifyScreenDump(buf, 'Test_diff_with_cul_bri_04', {})
+
+ " clean up
+ call StopVimInTerminal(buf)
+ call delete('Xtest_diff_cursorline_breakindent')
+endfunc
+
func Test_diff_with_syntax()
CheckScreendump
diff --git a/src/nvim/testdir/test_display.vim b/src/nvim/testdir/test_display.vim
index c702b44b88..12327f34d6 100644
--- a/src/nvim/testdir/test_display.vim
+++ b/src/nvim/testdir/test_display.vim
@@ -262,3 +262,21 @@ func Test_display_scroll_at_topline()
call StopVimInTerminal(buf)
endfunc
+
+func Test_display_linebreak_breakat()
+ new
+ vert resize 25
+ let _breakat = &breakat
+ setl signcolumn=yes linebreak breakat=) showbreak=+\
+ call setline(1, repeat('x', winwidth(0) - 2) .. ')abc')
+ let lines = ScreenLines([1, 2], 25)
+ let expected = [
+ \ ' xxxxxxxxxxxxxxxxxxxxxxx',
+ \ ' + )abc '
+ \ ]
+ call assert_equal(expected, lines)
+ %bw!
+ let &breakat=_breakat
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_eval_stuff.vim b/src/nvim/testdir/test_eval_stuff.vim
index 4870b9a60a..883ba5de3d 100644
--- a/src/nvim/testdir/test_eval_stuff.vim
+++ b/src/nvim/testdir/test_eval_stuff.vim
@@ -12,25 +12,18 @@ func Test_catch_return_with_error()
call assert_equal(1, s:foo())
endfunc
-func Test_E963()
- " These commands used to cause an internal error prior to vim 8.1.0563
- let v_e = v:errors
- let v_o = v:oldfiles
- call assert_fails("let v:errors=''", 'E963:')
- call assert_equal(v_e, v:errors)
- call assert_fails("let v:oldfiles=''", 'E963:')
- call assert_equal(v_o, v:oldfiles)
-endfunc
-
-func Test_for_invalid()
- call assert_fails("for x in 99", 'E714:')
- call assert_fails("for x in function('winnr')", 'E714:')
- call assert_fails("for x in {'a': 9}", 'E714:')
-
- if 0
- /1/5/2/s/\n
- endif
- redraw
+func Test_nocatch_restore_silent_emsg()
+ silent! try
+ throw 1
+ catch
+ endtry
+ echoerr 'wrong'
+ let c1 = nr2char(screenchar(&lines, 1))
+ let c2 = nr2char(screenchar(&lines, 2))
+ let c3 = nr2char(screenchar(&lines, 3))
+ let c4 = nr2char(screenchar(&lines, 4))
+ let c5 = nr2char(screenchar(&lines, 5))
+ call assert_equal('wrong', c1 . c2 . c3 . c4 . c5)
endfunc
func Test_mkdir_p()
@@ -61,6 +54,54 @@ func Test_line_continuation()
call assert_equal([5, 6], array)
endfunc
+func Test_E963()
+ " These commands used to cause an internal error prior to vim 8.1.0563
+ let v_e = v:errors
+ let v_o = v:oldfiles
+ call assert_fails("let v:errors=''", 'E963:')
+ call assert_equal(v_e, v:errors)
+ call assert_fails("let v:oldfiles=''", 'E963:')
+ call assert_equal(v_o, v:oldfiles)
+endfunc
+
+func Test_for_invalid()
+ " Vim gives incorrect emsg here until v8.2.3284, but the exact emsg from that
+ " patch cannot be used until v8.2.2658 is ported (for loop over Strings)
+ call assert_fails("for x in 99", 'E897:')
+ call assert_fails("for x in function('winnr')", 'E897:')
+ call assert_fails("for x in {'a': 9}", 'E897:')
+
+ if 0
+ /1/5/2/s/\n
+ endif
+ redraw
+endfunc
+
+func Test_readfile_binary()
+ new
+ call setline(1, ['one', 'two', 'three'])
+ setlocal ff=dos
+ silent write XReadfile
+ let lines = readfile('XReadfile')
+ call assert_equal(['one', 'two', 'three'], lines)
+ let lines = readfile('XReadfile', '', 2)
+ call assert_equal(['one', 'two'], lines)
+ let lines = readfile('XReadfile', 'b')
+ call assert_equal(["one\r", "two\r", "three\r", ""], lines)
+ let lines = readfile('XReadfile', 'b', 2)
+ call assert_equal(["one\r", "two\r"], lines)
+
+ bwipe!
+ call delete('XReadfile')
+endfunc
+
+func Test_let_errmsg()
+ call assert_fails('let v:errmsg = []', 'E730:')
+ let v:errmsg = ''
+ call assert_fails('let v:errmsg = []', 'E730:')
+ let v:errmsg = ''
+endfunc
+
func Test_string_concatenation()
call assert_equal('ab', 'a'.'b')
call assert_equal('ab', 'a' .'b')
@@ -90,27 +131,6 @@ func Test_string_concatenation()
call assert_equal('ab', a)
endfunc
-func Test_nocatch_restore_silent_emsg()
- silent! try
- throw 1
- catch
- endtry
- echoerr 'wrong'
- let c1 = nr2char(screenchar(&lines, 1))
- let c2 = nr2char(screenchar(&lines, 2))
- let c3 = nr2char(screenchar(&lines, 3))
- let c4 = nr2char(screenchar(&lines, 4))
- let c5 = nr2char(screenchar(&lines, 5))
- call assert_equal('wrong', c1 . c2 . c3 . c4 . c5)
-endfunc
-
-func Test_let_errmsg()
- call assert_fails('let v:errmsg = []', 'E730:')
- let v:errmsg = ''
- call assert_fails('let v:errmsg = []', 'E730:')
- let v:errmsg = ''
-endfunc
-
" Test fix for issue #4507
func Test_skip_after_throw()
try
@@ -120,6 +140,31 @@ func Test_skip_after_throw()
endtry
endfunc
+" scriptversion 1
+func Test_string_concat_scriptversion1()
+ call assert_true(has('vimscript-1'))
+ let a = 'a'
+ let b = 'b'
+
+ echo a . b
+ let a .= b
+ let vers = 1.2.3
+ call assert_equal('123', vers)
+
+ if has('float')
+ call assert_fails('let f = .5', 'E15:')
+ endif
+endfunc
+
+" scriptversion 1
+func Test_vvar_scriptversion1()
+ call assert_equal(15, 017)
+ call assert_equal(15, 0o17)
+ call assert_equal(15, 0O17)
+ call assert_equal(18, 018)
+ call assert_equal(511, 0o777)
+endfunc
+
func Test_number_max_min_size()
" This will fail on systems without 64 bit number support or when not
" configured correctly.
@@ -129,6 +174,132 @@ func Test_number_max_min_size()
call assert_true(v:numbermax > 9999999)
endfunc
+func Assert_reg(name, type, value, valuestr, expr, exprstr)
+ call assert_equal(a:type, getregtype(a:name))
+ call assert_equal(a:value, getreg(a:name))
+ call assert_equal(a:valuestr, string(getreg(a:name, 0, 1)))
+ call assert_equal(a:expr, getreg(a:name, 1))
+ call assert_equal(a:exprstr, string(getreg(a:name, 1, 1)))
+endfunc
+
+func Test_let_register()
+ let @" = 'abc'
+ call Assert_reg('"', 'v', "abc", "['abc']", "abc", "['abc']")
+ let @" = "abc\n"
+ call Assert_reg('"', 'V', "abc\n", "['abc']", "abc\n", "['abc']")
+ let @" = "abc\<C-m>"
+ call Assert_reg('"', 'V', "abc\r\n", "['abc\r']", "abc\r\n", "['abc\r']")
+ let @= = '"abc"'
+ call Assert_reg('=', 'v', "abc", "['abc']", '"abc"', "['\"abc\"']")
+endfunc
+
+func Assert_regput(name, result)
+ new
+ execute "silent normal! o==\n==\e\"" . a:name . "P"
+ call assert_equal(a:result, getline(2, line('$')))
+ bwipe!
+endfunc
+
+func Test_setreg_basic()
+ call setreg('a', 'abcA', 'c')
+ call Assert_reg('a', 'v', "abcA", "['abcA']", "abcA", "['abcA']")
+ call Assert_regput('a', ['==', '=abcA='])
+
+ call setreg('A', 'abcAc', 'c')
+ call Assert_reg('A', 'v', "abcAabcAc", "['abcAabcAc']", "abcAabcAc", "['abcAabcAc']")
+ call Assert_regput('a', ['==', '=abcAabcAc='])
+
+ call setreg('A', 'abcAl', 'l')
+ call Assert_reg('A', 'V', "abcAabcAcabcAl\n", "['abcAabcAcabcAl']", "abcAabcAcabcAl\n", "['abcAabcAcabcAl']")
+ call Assert_regput('a', ['==', 'abcAabcAcabcAl', '=='])
+
+ call setreg('A', 'abcAc2','c')
+ call Assert_reg('A', 'v', "abcAabcAcabcAl\nabcAc2", "['abcAabcAcabcAl', 'abcAc2']", "abcAabcAcabcAl\nabcAc2", "['abcAabcAcabcAl', 'abcAc2']")
+ call Assert_regput('a', ['==', '=abcAabcAcabcAl', 'abcAc2='])
+
+ call setreg('b', 'abcB', 'v')
+ call Assert_reg('b', 'v', "abcB", "['abcB']", "abcB", "['abcB']")
+ call Assert_regput('b', ['==', '=abcB='])
+
+ call setreg('b', 'abcBc', 'ca')
+ call Assert_reg('b', 'v', "abcBabcBc", "['abcBabcBc']", "abcBabcBc", "['abcBabcBc']")
+ call Assert_regput('b', ['==', '=abcBabcBc='])
+
+ call setreg('b', 'abcBb', 'ba')
+ call Assert_reg('b', "\<C-V>5", "abcBabcBcabcBb", "['abcBabcBcabcBb']", "abcBabcBcabcBb", "['abcBabcBcabcBb']")
+ call Assert_regput('b', ['==', '=abcBabcBcabcBb='])
+
+ call setreg('b', 'abcBc2','ca')
+ call Assert_reg('b', "v", "abcBabcBcabcBb\nabcBc2", "['abcBabcBcabcBb', 'abcBc2']", "abcBabcBcabcBb\nabcBc2", "['abcBabcBcabcBb', 'abcBc2']")
+ call Assert_regput('b', ['==', '=abcBabcBcabcBb', 'abcBc2='])
+
+ call setreg('b', 'abcBb2','b50a')
+ call Assert_reg('b', "\<C-V>50", "abcBabcBcabcBb\nabcBc2abcBb2", "['abcBabcBcabcBb', 'abcBc2abcBb2']", "abcBabcBcabcBb\nabcBc2abcBb2", "['abcBabcBcabcBb', 'abcBc2abcBb2']")
+ call Assert_regput('b', ['==', '=abcBabcBcabcBb =', ' abcBc2abcBb2'])
+
+ call setreg('c', 'abcC', 'l')
+ call Assert_reg('c', 'V', "abcC\n", "['abcC']", "abcC\n", "['abcC']")
+ call Assert_regput('c', ['==', 'abcC', '=='])
+
+ call setreg('C', 'abcCl', 'l')
+ call Assert_reg('C', 'V', "abcC\nabcCl\n", "['abcC', 'abcCl']", "abcC\nabcCl\n", "['abcC', 'abcCl']")
+ call Assert_regput('c', ['==', 'abcC', 'abcCl', '=='])
+
+ call setreg('C', 'abcCc', 'c')
+ call Assert_reg('C', 'v', "abcC\nabcCl\nabcCc", "['abcC', 'abcCl', 'abcCc']", "abcC\nabcCl\nabcCc", "['abcC', 'abcCl', 'abcCc']")
+ call Assert_regput('c', ['==', '=abcC', 'abcCl', 'abcCc='])
+
+ call setreg('d', 'abcD', 'V')
+ call Assert_reg('d', 'V', "abcD\n", "['abcD']", "abcD\n", "['abcD']")
+ call Assert_regput('d', ['==', 'abcD', '=='])
+
+ call setreg('D', 'abcDb', 'b')
+ call Assert_reg('d', "\<C-V>5", "abcD\nabcDb", "['abcD', 'abcDb']", "abcD\nabcDb", "['abcD', 'abcDb']")
+ call Assert_regput('d', ['==', '=abcD =', ' abcDb'])
+
+ call setreg('e', 'abcE', 'b')
+ call Assert_reg('e', "\<C-V>4", "abcE", "['abcE']", "abcE", "['abcE']")
+ call Assert_regput('e', ['==', '=abcE='])
+
+ call setreg('E', 'abcEb', 'b')
+ call Assert_reg('E', "\<C-V>5", "abcE\nabcEb", "['abcE', 'abcEb']", "abcE\nabcEb", "['abcE', 'abcEb']")
+ call Assert_regput('e', ['==', '=abcE =', ' abcEb'])
+
+ call setreg('E', 'abcEl', 'l')
+ call Assert_reg('E', "V", "abcE\nabcEb\nabcEl\n", "['abcE', 'abcEb', 'abcEl']", "abcE\nabcEb\nabcEl\n", "['abcE', 'abcEb', 'abcEl']")
+ call Assert_regput('e', ['==', 'abcE', 'abcEb', 'abcEl', '=='])
+
+ call setreg('f', 'abcF', "\<C-v>")
+ call Assert_reg('f', "\<C-V>4", "abcF", "['abcF']", "abcF", "['abcF']")
+ call Assert_regput('f', ['==', '=abcF='])
+
+ call setreg('F', 'abcFc', 'c')
+ call Assert_reg('F', "v", "abcF\nabcFc", "['abcF', 'abcFc']", "abcF\nabcFc", "['abcF', 'abcFc']")
+ call Assert_regput('f', ['==', '=abcF', 'abcFc='])
+
+ call setreg('g', 'abcG', 'b10')
+ call Assert_reg('g', "\<C-V>10", "abcG", "['abcG']", "abcG", "['abcG']")
+ call Assert_regput('g', ['==', '=abcG ='])
+
+ call setreg('h', 'abcH', "\<C-v>10")
+ call Assert_reg('h', "\<C-V>10", "abcH", "['abcH']", "abcH", "['abcH']")
+ call Assert_regput('h', ['==', '=abcH ='])
+
+ call setreg('I', 'abcI')
+ call Assert_reg('I', "v", "abcI", "['abcI']", "abcI", "['abcI']")
+ call Assert_regput('I', ['==', '=abcI='])
+
+ " Error cases
+ call assert_fails('call setreg()', 'E119:')
+ call assert_fails('call setreg(1)', 'E119:')
+ call assert_fails('call setreg(1, 2, 3, 4)', 'E118:')
+ call assert_fails('call setreg([], 2)', 'E730:')
+ call assert_fails('call setreg(1, 2, [])', 'E730:')
+ call assert_fails('call setreg("/", ["1", "2"])', 'E883:')
+ call assert_fails('call setreg("=", ["1", "2"])', 'E883:')
+ call assert_fails('call setreg(1, ["", "", [], ""])', 'E730:')
+endfunc
+
func Test_curly_assignment()
let s:svar = 'svar'
let g:gvar = 'gvar'
diff --git a/src/nvim/testdir/test_ex_z.vim b/src/nvim/testdir/test_ex_z.vim
index 608a36c490..481747ce84 100644
--- a/src/nvim/testdir/test_ex_z.vim
+++ b/src/nvim/testdir/test_ex_z.vim
@@ -16,8 +16,9 @@ func Test_z()
call assert_equal(23, line('.'))
let a = execute('20z+3')
- " FIXME: I would expect the same result as '20z3' but it
- " gives "\n21\n22\n23" instead. Bug in Vim or in ":help :z"?
+ " FIXME: I would expect the same result as '20z3' since 'help z'
+ " says: Specifying no mark at all is the same as "+".
+ " However it " gives "\n21\n22\n23" instead. Bug in Vim or in ":help :z"?
"call assert_equal("\n20\n21\n22", a)
"call assert_equal(22, line('.'))
@@ -55,19 +56,48 @@ func Test_z()
call assert_equal(100, line('.'))
let a = execute('20z-1000')
- call assert_match("^\n1\n2\n.*\n19\n20$", a)
call assert_equal(20, line('.'))
let a = execute('20z=1000')
call assert_match("^\n1\n.*\n-\\+\n20\n-\\\+\n.*\n100$", a)
call assert_equal(20, line('.'))
+ " Tests with multiple windows.
+ 5split
+ call setline(1, range(1, 100))
+ " Without a count, the number line is window height - 3.
+ let a = execute('20z')
+ call assert_equal("\n20\n21", a)
+ call assert_equal(21, line('.'))
+ " If window height - 3 is less than 1, it should be clamped to 1.
+ resize 2
+ let a = execute('20z')
+ call assert_equal("\n20", a)
+ call assert_equal(20, line('.'))
+
call assert_fails('20z=a', 'E144:')
set window& scroll&
bw!
endfunc
+" :z! is the same as :z but count uses the Vim window height when not specified.
+func Test_z_bang()
+ 4split
+ call setline(1, range(1, 20))
+
+ let a = execute('10z!')
+ call assert_equal("\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20", a)
+
+ let a = execute('10z!#')
+ call assert_equal("\n 10 10\n 11 11\n 12 12\n 13 13\n 14 14\n 15 15\n 16 16\n 17 17\n 18 18\n 19 19\n 20 20", a)
+
+ let a = execute('10z!3')
+ call assert_equal("\n10\n11\n12", a)
+
+ %bwipe!
+endfunc
+
func Test_z_bug()
" This used to access invalid memory as a result of an integer overflow
" and freeze vim.
diff --git a/src/nvim/testdir/test_excmd.vim b/src/nvim/testdir/test_excmd.vim
index ed2bb2c06b..2d01cbba83 100644
--- a/src/nvim/testdir/test_excmd.vim
+++ b/src/nvim/testdir/test_excmd.vim
@@ -313,6 +313,42 @@ func Test_confirm_write_ro()
call delete('Xconfirm_write_ro')
endfunc
+func Test_confirm_write_partial_file()
+ CheckNotGui
+ CheckRunVimInTerminal
+
+ call writefile(['a', 'b', 'c', 'd'], 'Xwrite_partial')
+ call writefile(['set nobackup ff=unix cmdheight=2',
+ \ 'edit Xwrite_partial'], 'Xscript')
+ let buf = RunVimInTerminal('-S Xscript', {'rows': 20})
+
+ call term_sendkeys(buf, ":confirm 2,3w\n")
+ call WaitForAssert({-> assert_match('^Write partial file? *$',
+ \ term_getline(buf, 19))}, 1000)
+ call WaitForAssert({-> assert_match('^(Y)es, \[N\]o: *$',
+ \ term_getline(buf, 20))}, 1000)
+ call term_sendkeys(buf, 'N')
+ call WaitForAssert({-> assert_match('.* All$', term_getline(buf, 20))}, 1000)
+ call assert_equal(['a', 'b', 'c', 'd'], readfile('Xwrite_partial'))
+ call delete('Xwrite_partial')
+
+ call term_sendkeys(buf, ":confirm 2,3w\n")
+ call WaitForAssert({-> assert_match('^Write partial file? *$',
+ \ term_getline(buf, 19))}, 1000)
+ call WaitForAssert({-> assert_match('^(Y)es, \[N\]o: *$',
+ \ term_getline(buf, 20))}, 1000)
+ call term_sendkeys(buf, 'Y')
+ call WaitForAssert({-> assert_match('^"Xwrite_partial" \[New\] 2L, 4B written *$',
+ \ term_getline(buf, 19))}, 1000)
+ call WaitForAssert({-> assert_match('^Press ENTER or type command to continue *$',
+ \ term_getline(buf, 20))}, 1000)
+ call assert_equal(['b', 'c'], readfile('Xwrite_partial'))
+
+ call StopVimInTerminal(buf)
+ call delete('Xwrite_partial')
+ call delete('Xscript')
+endfunc
+
" Test for the :winsize command
func Test_winsize_cmd()
call assert_fails('winsize 1', 'E465:')
diff --git a/src/nvim/testdir/test_expr.vim b/src/nvim/testdir/test_expr.vim
index 0b41a1127a..c49285621a 100644
--- a/src/nvim/testdir/test_expr.vim
+++ b/src/nvim/testdir/test_expr.vim
@@ -502,6 +502,17 @@ func Test_empty_concatenate()
call assert_equal('b', 'b' . 'a'[4:0])
endfunc
+func Test_broken_number()
+ let X = 'bad'
+ call assert_fails('echo 1X', 'E15:')
+ call assert_fails('echo 0b1X', 'E15:')
+ call assert_fails('echo 0b12', 'E15:')
+ call assert_fails('echo 0x1X', 'E15:')
+ call assert_fails('echo 011X', 'E15:')
+ call assert_equal(2, str2nr('2a'))
+ call assert_fails('inoremap <Char-0b1z> b', 'E474:')
+endfunc
+
func Test_eval_after_if()
let s:val = ''
func SetVal(x)
diff --git a/src/nvim/testdir/test_filetype.vim b/src/nvim/testdir/test_filetype.vim
index eb6151fbe1..cc789cb6bd 100644
--- a/src/nvim/testdir/test_filetype.vim
+++ b/src/nvim/testdir/test_filetype.vim
@@ -151,7 +151,6 @@ let s:filename_checks = {
\ 'dosini': ['.editorconfig', '/etc/pacman.conf', '/etc/yum.conf', 'file.ini', 'npmrc', '.npmrc', 'php.ini', 'php.ini-5', 'php.ini-file', '/etc/yum.repos.d/file', 'any/etc/pacman.conf', 'any/etc/yum.conf', 'any/etc/yum.repos.d/file', 'file.wrap'],
\ 'dot': ['file.dot', 'file.gv'],
\ 'dracula': ['file.drac', 'file.drc', 'filelvs', 'filelpe', 'drac.file', 'lpe', 'lvs', 'some-lpe', 'some-lvs'],
- \ 'dsl': ['file.dsl'],
\ 'dtd': ['file.dtd'],
\ 'dts': ['file.dts', 'file.dtsi'],
\ 'dune': ['jbuild', 'dune', 'dune-project', 'dune-workspace'],
@@ -192,6 +191,7 @@ let s:filename_checks = {
\ 'gdb': ['.gdbinit'],
\ 'gdmo': ['file.mo', 'file.gdmo'],
\ 'gedcom': ['file.ged', 'lltxxxxx.txt', '/tmp/lltmp', '/tmp/lltmp-file', 'any/tmp/lltmp', 'any/tmp/lltmp-file'],
+ \ 'gemtext': ['file.gmi', 'file.gemini'],
\ 'gift': ['file.gift'],
\ 'gitcommit': ['COMMIT_EDITMSG', 'MERGE_MSG', 'TAG_EDITMSG'],
\ 'gitconfig': ['file.git/config', '.gitconfig', '.gitmodules', 'file.git/modules//config', '/.config/git/config', '/etc/gitconfig', '/etc/gitconfig.d/file', '/.gitconfig.d/file', 'any/.config/git/config', 'any/.gitconfig.d/file', 'some.git/config', 'some.git/modules/any/config'],
@@ -260,7 +260,9 @@ let s:filename_checks = {
\ 'jovial': ['file.jov', 'file.j73', 'file.jovial'],
\ 'jproperties': ['file.properties', 'file.properties_xx', 'file.properties_xx_xx', 'some.properties_xx_xx_file'],
\ 'json': ['file.json', 'file.jsonp', 'file.json-patch', 'file.webmanifest', 'Pipfile.lock', 'file.ipynb'],
+ \ 'jsonc': ['file.jsonc'],
\ 'jsp': ['file.jsp'],
+ \ 'julia': ['file.jl'],
\ 'kconfig': ['Kconfig', 'Kconfig.debug', 'Kconfig.file'],
\ 'kivy': ['file.kv'],
\ 'kix': ['file.kix'],
@@ -293,6 +295,7 @@ let s:filename_checks = {
\ 'lss': ['file.lss'],
\ 'lua': ['file.lua', 'file.rockspec', 'file.nse'],
\ 'lynx': ['lynx.cfg'],
+ \ 'matlab': ['file.m'],
\ 'm3build': ['m3makefile', 'm3overrides'],
\ 'm3quake': ['file.quake', 'cm3.cfg'],
\ 'm4': ['file.at'],
@@ -348,6 +351,7 @@ let s:filename_checks = {
\ 'obj': ['file.obj'],
\ 'ocaml': ['file.ml', 'file.mli', 'file.mll', 'file.mly', '.ocamlinit', 'file.mlt', 'file.mlp', 'file.mlip', 'file.mli.cppo', 'file.ml.cppo'],
\ 'occam': ['file.occ'],
+ \ 'octave': ['octaverc', '.octaverc', 'octave.conf'],
\ 'omnimark': ['file.xom', 'file.xin'],
\ 'opam': ['opam', 'file.opam', 'file.opam.template'],
\ 'openroad': ['file.or'],
@@ -394,6 +398,7 @@ let s:filename_checks = {
\ 'psf': ['file.psf'],
\ 'psl': ['file.psl'],
\ 'puppet': ['file.pp'],
+ \ 'pyret': ['file.arr'],
\ 'pyrex': ['file.pyx', 'file.pxd'],
\ 'python': ['file.py', 'file.pyw', '.pythonstartup', '.pythonrc', 'file.ptl', 'file.pyi', 'SConstruct'],
\ 'quake': ['anybaseq2/file.cfg', 'anyid1/file.cfg', 'quake3/file.cfg', 'baseq2/file.cfg', 'id1/file.cfg', 'quake1/file.cfg', 'some-baseq2/file.cfg', 'some-id1/file.cfg', 'some-quake1/file.cfg'],
@@ -425,10 +430,11 @@ let s:filename_checks = {
\ 'sather': ['file.sa'],
\ 'sbt': ['file.sbt'],
\ 'scala': ['file.scala', 'file.sc'],
- \ 'scheme': ['file.scm', 'file.ss', 'file.rkt'],
+ \ 'scheme': ['file.scm', 'file.ss', 'file.rkt', 'file.rktd', 'file.rktl'],
\ 'scilab': ['file.sci', 'file.sce'],
\ 'screen': ['.screenrc', 'screenrc'],
\ 'sexplib': ['file.sexp'],
+ \ 'scdoc': ['file.scd'],
\ 'scss': ['file.scss'],
\ 'sd': ['file.sd'],
\ 'sdc': ['file.sdc'],
@@ -751,6 +757,7 @@ func Test_pp_file()
split Xfile.pp
call assert_equal('pascal', &filetype)
bwipe!
+ unlet g:filetype_pp
" Test dist#ft#FTpp()
call writefile(['{ pascal comment'], 'Xfile.pp')
@@ -804,4 +811,110 @@ func Test_ex_file()
filetype off
endfunc
+func Test_dsl_file()
+ filetype on
+
+ call writefile([' <!doctype dsssl-spec ['], 'dslfile.dsl')
+ split dslfile.dsl
+ call assert_equal('dsl', &filetype)
+ bwipe!
+
+ call writefile(['workspace {'], 'dslfile.dsl')
+ split dslfile.dsl
+ call assert_equal('structurizr', &filetype)
+ bwipe!
+
+ call delete('dslfile.dsl')
+ filetype off
+endfunc
+
+func Test_m_file()
+ filetype on
+
+ call writefile(['looks like Matlab'], 'Xfile.m')
+ split Xfile.m
+ call assert_equal('matlab', &filetype)
+ bwipe!
+
+ let g:filetype_m = 'octave'
+ split Xfile.m
+ call assert_equal('octave', &filetype)
+ bwipe!
+ unlet g:filetype_m
+
+ " Test dist#ft#FTm()
+
+ " Objective-C
+
+ call writefile(['// Objective-C line comment'], 'Xfile.m')
+ split Xfile.m
+ call assert_equal('objc', &filetype)
+ bwipe!
+
+ call writefile(['/* Objective-C block comment */'], 'Xfile.m')
+ split Xfile.m
+ call assert_equal('objc', &filetype)
+ bwipe!
+
+ call writefile(['#import "test.m"'], 'Xfile.m')
+ split Xfile.m
+ call assert_equal('objc', &filetype)
+ bwipe!
+
+ " Octave
+
+ call writefile(['# Octave line comment'], 'Xfile.m')
+ split Xfile.m
+ call assert_equal('octave', &filetype)
+ bwipe!
+
+ call writefile(['%!test "Octave test"'], 'Xfile.m')
+ split Xfile.m
+ call assert_equal('octave', &filetype)
+ bwipe!
+
+ call writefile(['unwind_protect'], 'Xfile.m')
+ split Xfile.m
+ call assert_equal('octave', &filetype)
+ bwipe!
+
+ call writefile(['try; 42; end_try_catch'], 'Xfile.m')
+ split Xfile.m
+ call assert_equal('octave', &filetype)
+ bwipe!
+
+ " Mathematica
+
+ call writefile(['(* Mathematica comment'], 'Xfile.m')
+ split Xfile.m
+ call assert_equal('mma', &filetype)
+ bwipe!
+
+ " MATLAB
+
+ call writefile(['% MATLAB line comment'], 'Xfile.m')
+ split Xfile.m
+ call assert_equal('matlab', &filetype)
+ bwipe!
+
+ " Murphi
+
+ call writefile(['-- Murphi comment'], 'Xfile.m')
+ split Xfile.m
+ call assert_equal('murphi', &filetype)
+ bwipe!
+
+ call writefile(['/* Murphi block comment */', 'Type'], 'Xfile.m')
+ split Xfile.m
+ call assert_equal('murphi', &filetype)
+ bwipe!
+
+ call writefile(['Type'], 'Xfile.m')
+ split Xfile.m
+ call assert_equal('murphi', &filetype)
+ bwipe!
+
+ call delete('Xfile.m')
+ filetype off
+endfunc
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_filter_map.vim b/src/nvim/testdir/test_filter_map.vim
index a15567bcf2..a52a66ac2f 100644
--- a/src/nvim/testdir/test_filter_map.vim
+++ b/src/nvim/testdir/test_filter_map.vim
@@ -81,7 +81,11 @@ func Test_filter_map_dict_expr_funcref()
call assert_equal({"foo": "f", "bar": "b", "baz": "b"}, map(copy(dict), function('s:filter4')))
endfunc
-func Test_map_fails()
+func Test_map_filter_fails()
call assert_fails('call map([1], "42 +")', 'E15:')
call assert_fails('call filter([1], "42 +")', 'E15:')
+ call assert_fails("let l = map('abc', '\"> \" . v:val')", 'E896:')
+ call assert_fails("let l = filter('abc', '\"> \" . v:val')", 'E896:')
endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_float_func.vim b/src/nvim/testdir/test_float_func.vim
index 154ef570e0..78675d7016 100644
--- a/src/nvim/testdir/test_float_func.vim
+++ b/src/nvim/testdir/test_float_func.vim
@@ -7,6 +7,8 @@ end
func Test_abs()
call assert_equal('1.23', string(abs(1.23)))
call assert_equal('1.23', string(abs(-1.23)))
+ eval -1.23->abs()->string()->assert_equal('1.23')
+
call assert_equal('0.0', string(abs(0.0)))
call assert_equal('0.0', string(abs(1.0/(1.0/0.0))))
call assert_equal('0.0', string(abs(-1.0/(1.0/0.0))))
@@ -22,6 +24,7 @@ endfunc
func Test_sqrt()
call assert_equal('0.0', string(sqrt(0.0)))
call assert_equal('1.414214', string(sqrt(2.0)))
+ eval 2.0->sqrt()->string()->assert_equal('1.414214')
call assert_equal("str2float('inf')", string(sqrt(1.0/0.0)))
call assert_equal("str2float('nan')", string(sqrt(-1.0)))
call assert_equal("str2float('nan')", string(sqrt(0.0/0.0)))
@@ -31,6 +34,7 @@ endfunc
func Test_log()
call assert_equal('0.0', string(log(1.0)))
call assert_equal('-0.693147', string(log(0.5)))
+ eval 0.5->log()->string()->assert_equal('-0.693147')
call assert_equal("-str2float('inf')", string(log(0.0)))
call assert_equal("str2float('nan')", string(log(-1.0)))
call assert_equal("str2float('inf')", string(log(1.0/0.0)))
@@ -42,6 +46,7 @@ func Test_log10()
call assert_equal('0.0', string(log10(1.0)))
call assert_equal('2.0', string(log10(100.0)))
call assert_equal('2.079181', string(log10(120.0)))
+ eval 120.0->log10()->string()->assert_equal('2.079181')
call assert_equal("-str2float('inf')", string(log10(0.0)))
call assert_equal("str2float('nan')", string(log10(-1.0)))
call assert_equal("str2float('inf')", string(log10(1.0/0.0)))
@@ -53,6 +58,7 @@ func Test_exp()
call assert_equal('1.0', string(exp(0.0)))
call assert_equal('7.389056', string(exp(2.0)))
call assert_equal('0.367879', string(exp(-1.0)))
+ eval -1.0->exp()->string()->assert_equal('0.367879')
call assert_equal("str2float('inf')", string(exp(1.0/0.0)))
call assert_equal('0.0', string(exp(-1.0/0.0)))
call assert_equal("str2float('nan')", string(exp(0.0/0.0)))
@@ -63,6 +69,7 @@ func Test_sin()
call assert_equal('0.0', string(sin(0.0)))
call assert_equal('0.841471', string(sin(1.0)))
call assert_equal('-0.479426', string(sin(-0.5)))
+ eval -0.5->sin()->string()->assert_equal('-0.479426')
call assert_equal("str2float('nan')", string(sin(0.0/0.0)))
call assert_equal("str2float('nan')", string(sin(1.0/0.0)))
call assert_equal('0.0', string(sin(1.0/(1.0/0.0))))
@@ -73,6 +80,8 @@ endfunc
func Test_asin()
call assert_equal('0.0', string(asin(0.0)))
call assert_equal('1.570796', string(asin(1.0)))
+ eval 1.0->asin()->string()->assert_equal('1.570796')
+
call assert_equal('-0.523599', string(asin(-0.5)))
call assert_equal("str2float('nan')", string(asin(1.1)))
call assert_equal("str2float('nan')", string(asin(1.0/0.0)))
@@ -84,6 +93,7 @@ func Test_sinh()
call assert_equal('0.0', string(sinh(0.0)))
call assert_equal('0.521095', string(sinh(0.5)))
call assert_equal('-1.026517', string(sinh(-0.9)))
+ eval -0.9->sinh()->string()->assert_equal('-1.026517')
call assert_equal("str2float('inf')", string(sinh(1.0/0.0)))
call assert_equal("-str2float('inf')", string(sinh(-1.0/0.0)))
call assert_equal("str2float('nan')", string(sinh(0.0/0.0)))
@@ -94,6 +104,7 @@ func Test_cos()
call assert_equal('1.0', string(cos(0.0)))
call assert_equal('0.540302', string(cos(1.0)))
call assert_equal('0.877583', string(cos(-0.5)))
+ eval -0.5->cos()->string()->assert_equal('0.877583')
call assert_equal("str2float('nan')", string(cos(0.0/0.0)))
call assert_equal("str2float('nan')", string(cos(1.0/0.0)))
call assert_fails('call cos("")', 'E808:')
@@ -103,6 +114,7 @@ func Test_acos()
call assert_equal('1.570796', string(acos(0.0)))
call assert_equal('0.0', string(acos(1.0)))
call assert_equal('3.141593', string(acos(-1.0)))
+ eval -1.0->acos()->string()->assert_equal('3.141593')
call assert_equal('2.094395', string(acos(-0.5)))
call assert_equal("str2float('nan')", string(acos(1.1)))
call assert_equal("str2float('nan')", string(acos(1.0/0.0)))
@@ -113,6 +125,7 @@ endfunc
func Test_cosh()
call assert_equal('1.0', string(cosh(0.0)))
call assert_equal('1.127626', string(cosh(0.5)))
+ eval 0.5->cosh()->string()->assert_equal('1.127626')
call assert_equal("str2float('inf')", string(cosh(1.0/0.0)))
call assert_equal("str2float('inf')", string(cosh(-1.0/0.0)))
call assert_equal("str2float('nan')", string(cosh(0.0/0.0)))
@@ -123,6 +136,7 @@ func Test_tan()
call assert_equal('0.0', string(tan(0.0)))
call assert_equal('0.546302', string(tan(0.5)))
call assert_equal('-0.546302', string(tan(-0.5)))
+ eval -0.5->tan()->string()->assert_equal('-0.546302')
call assert_equal("str2float('nan')", string(tan(1.0/0.0)))
call assert_equal("str2float('nan')", string(cos(0.0/0.0)))
call assert_equal('0.0', string(tan(1.0/(1.0/0.0))))
@@ -134,6 +148,7 @@ func Test_atan()
call assert_equal('0.0', string(atan(0.0)))
call assert_equal('0.463648', string(atan(0.5)))
call assert_equal('-0.785398', string(atan(-1.0)))
+ eval -1.0->atan()->string()->assert_equal('-0.785398')
call assert_equal('1.570796', string(atan(1.0/0.0)))
call assert_equal('-1.570796', string(atan(-1.0/0.0)))
call assert_equal("str2float('nan')", string(atan(0.0/0.0)))
@@ -144,6 +159,7 @@ func Test_atan2()
call assert_equal('-2.356194', string(atan2(-1, -1)))
call assert_equal('2.356194', string(atan2(1, -1)))
call assert_equal('0.0', string(atan2(1.0, 1.0/0.0)))
+ eval 1.0->atan2(1.0/0.0)->string()->assert_equal('0.0')
call assert_equal('1.570796', string(atan2(1.0/0.0, 1.0)))
call assert_equal("str2float('nan')", string(atan2(0.0/0.0, 1.0)))
call assert_fails('call atan2("", -1)', 'E808:')
@@ -154,6 +170,7 @@ func Test_tanh()
call assert_equal('0.0', string(tanh(0.0)))
call assert_equal('0.462117', string(tanh(0.5)))
call assert_equal('-0.761594', string(tanh(-1.0)))
+ eval -1.0->tanh()->string()->assert_equal('-0.761594')
call assert_equal('1.0', string(tanh(1.0/0.0)))
call assert_equal('-1.0', string(tanh(-1.0/0.0)))
call assert_equal("str2float('nan')", string(tanh(0.0/0.0)))
@@ -164,6 +181,7 @@ func Test_fmod()
call assert_equal('0.13', string(fmod(12.33, 1.22)))
call assert_equal('-0.13', string(fmod(-12.33, 1.22)))
call assert_equal("str2float('nan')", string(fmod(1.0/0.0, 1.0)))
+ eval (1.0/0.0)->fmod(1.0)->string()->assert_equal("str2float('nan')")
" On Windows we get "nan" instead of 1.0, accept both.
let res = string(fmod(1.0, 1.0/0.0))
if res != "str2float('nan')"
@@ -177,6 +195,7 @@ endfunc
func Test_pow()
call assert_equal('1.0', string(pow(0.0, 0.0)))
call assert_equal('8.0', string(pow(2.0, 3.0)))
+ eval 2.0->pow(3.0)->string()->assert_equal('8.0')
call assert_equal("str2float('nan')", string(pow(2.0, 0.0/0.0)))
call assert_equal("str2float('nan')", string(pow(0.0/0.0, 3.0)))
call assert_equal("str2float('nan')", string(pow(0.0/0.0, 3.0)))
@@ -192,6 +211,7 @@ func Test_str2float()
call assert_equal('1.0', string(str2float(' 1.0 ')))
call assert_equal('1.23', string(str2float('1.23')))
call assert_equal('1.23', string(str2float('1.23abc')))
+ eval '1.23abc'->str2float()->string()->assert_equal('1.23')
call assert_equal('1.0e40', string(str2float('1e40')))
call assert_equal('-1.23', string(str2float('-1.23')))
call assert_equal('1.23', string(str2float(' + 1.23 ')))
@@ -228,6 +248,7 @@ func Test_float2nr()
call assert_equal(1, float2nr(1.234))
call assert_equal(123, float2nr(1.234e2))
call assert_equal(12, float2nr(123.4e-1))
+ eval 123.4e-1->float2nr()->assert_equal(12)
let max_number = 1/0
let min_number = -max_number
call assert_equal(max_number/2+1, float2nr(pow(2, 62)))
@@ -242,6 +263,7 @@ func Test_floor()
call assert_equal('2.0', string(floor(2.0)))
call assert_equal('2.0', string(floor(2.11)))
call assert_equal('2.0', string(floor(2.99)))
+ eval 2.99->floor()->string()->assert_equal('2.0')
call assert_equal('-3.0', string(floor(-2.11)))
call assert_equal('-3.0', string(floor(-2.99)))
call assert_equal("str2float('nan')", string(floor(0.0/0.0)))
@@ -255,6 +277,7 @@ func Test_ceil()
call assert_equal('3.0', string(ceil(2.11)))
call assert_equal('3.0', string(ceil(2.99)))
call assert_equal('-2.0', string(ceil(-2.11)))
+ eval -2.11->ceil()->string()->assert_equal('-2.0')
call assert_equal('-2.0', string(ceil(-2.99)))
call assert_equal("str2float('nan')", string(ceil(0.0/0.0)))
call assert_equal("str2float('inf')", string(ceil(1.0/0.0)))
@@ -266,6 +289,7 @@ func Test_round()
call assert_equal('2.0', string(round(2.1)))
call assert_equal('3.0', string(round(2.5)))
call assert_equal('3.0', string(round(2.9)))
+ eval 2.9->round()->string()->assert_equal('3.0')
call assert_equal('-2.0', string(round(-2.1)))
call assert_equal('-3.0', string(round(-2.5)))
call assert_equal('-3.0', string(round(-2.9)))
@@ -279,6 +303,7 @@ func Test_trunc()
call assert_equal('2.0', string(trunc(2.1)))
call assert_equal('2.0', string(trunc(2.5)))
call assert_equal('2.0', string(trunc(2.9)))
+ eval 2.9->trunc()->string()->assert_equal('2.0')
call assert_equal('-2.0', string(trunc(-2.1)))
call assert_equal('-2.0', string(trunc(-2.5)))
call assert_equal('-2.0', string(trunc(-2.9)))
@@ -291,6 +316,7 @@ endfunc
func Test_isinf()
call assert_equal(1, isinf(1.0/0.0))
call assert_equal(-1, isinf(-1.0/0.0))
+ eval (-1.0/0.0)->isinf()->assert_equal(-1)
call assert_false(isinf(1.0))
call assert_false(isinf(0.0/0.0))
call assert_false(isinf('a'))
@@ -302,6 +328,7 @@ func Test_isnan()
call assert_true(isnan(0.0/0.0))
call assert_false(isnan(1.0))
call assert_false(isnan(1.0/0.0))
+ eval (1.0/0.0)->isnan()->assert_false()
call assert_false(isnan(-1.0/0.0))
call assert_false(isnan('a'))
call assert_false(isnan([]))
diff --git a/src/nvim/testdir/test_fnamemodify.vim b/src/nvim/testdir/test_fnamemodify.vim
index 116d23ba88..fe1df8fd4a 100644
--- a/src/nvim/testdir/test_fnamemodify.vim
+++ b/src/nvim/testdir/test_fnamemodify.vim
@@ -72,4 +72,8 @@ func Test_fnamemodify_er()
" :e never includes the whole filename, so "a.b":e:e:e --> "b"
call assert_equal('b.c', fnamemodify('a.b.c.d.e', ':r:r:e:e:e'))
call assert_equal('b.c', fnamemodify('a.b.c.d.e', ':r:r:e:e:e:e'))
+
+ call assert_equal('', fnamemodify(v:_null_string, v:_null_string))
endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_functions.vim b/src/nvim/testdir/test_functions.vim
index 224ca257ab..e82fefc7fc 100644
--- a/src/nvim/testdir/test_functions.vim
+++ b/src/nvim/testdir/test_functions.vim
@@ -152,6 +152,10 @@ func Test_str2nr()
call assert_equal(65, str2nr('0101', 8))
call assert_equal(-65, str2nr('-101', 8))
call assert_equal(-65, str2nr('-0101', 8))
+ call assert_equal(65, str2nr('0o101', 8))
+ call assert_equal(65, str2nr('0O0101', 8))
+ call assert_equal(-65, str2nr('-0O101', 8))
+ call assert_equal(-65, str2nr('-0o0101', 8))
call assert_equal(11259375, str2nr('abcdef', 16))
call assert_equal(11259375, str2nr('ABCDEF', 16))
@@ -161,8 +165,16 @@ func Test_str2nr()
call assert_equal(11259375, str2nr('0XABCDEF', 16))
call assert_equal(-11259375, str2nr('-0xABCDEF', 16))
+ call assert_equal(1, str2nr("1'000'000", 10, 0))
+ call assert_equal(256, str2nr("1'0000'0000", 2, 1))
+ call assert_equal(262144, str2nr("1'000'000", 8, 1))
+ call assert_equal(1000000, str2nr("1'000'000", 10, 1))
+ call assert_equal(1000, str2nr("1'000''000", 10, 1))
+ call assert_equal(65536, str2nr("1'00'00", 16, 1))
+
call assert_equal(0, str2nr('0x10'))
call assert_equal(0, str2nr('0b10'))
+ call assert_equal(0, str2nr('0o10'))
call assert_equal(1, str2nr('12', 2))
call assert_equal(1, str2nr('18', 8))
call assert_equal(1, str2nr('1g', 16))
@@ -534,6 +546,7 @@ func Test_mode()
set complete=.
inoremap <F2> <C-R>=Save_mode()<CR>
+ xnoremap <F2> <Cmd>call Save_mode()<CR>
normal! 3G
exe "normal i\<F2>\<Esc>"
@@ -645,6 +658,14 @@ func Test_mode()
call assert_equal("\<C-S>", mode(1))
call feedkeys("\<Esc>", 'xt')
+ " v_CTRL-O
+ exe "normal gh\<C-O>\<F2>\<Esc>"
+ call assert_equal("v-vs", g:current_modes)
+ exe "normal gH\<C-O>\<F2>\<Esc>"
+ call assert_equal("V-Vs", g:current_modes)
+ exe "normal g\<C-H>\<C-O>\<F2>\<Esc>"
+ call assert_equal("\<C-V>-\<C-V>s", g:current_modes)
+
call feedkeys(":echo \<C-R>=Save_mode()\<C-U>\<CR>", 'xt')
call assert_equal('c-c', g:current_modes)
call feedkeys("gQecho \<C-R>=Save_mode()\<CR>\<CR>vi\<CR>", 'xt')
@@ -653,6 +674,7 @@ func Test_mode()
bwipe!
iunmap <F2>
+ xunmap <F2>
set complete&
endfunc
@@ -842,7 +864,7 @@ func Test_byte2line_line2byte()
set fileformat=mac
call assert_equal([-1, -1, 1, 1, 2, 2, 2, 3, 3, -1],
- \ map(range(-1, 8), 'byte2line(v:val)'))
+ \ map(range(-1, 8), 'v:val->byte2line()'))
call assert_equal([-1, -1, 1, 3, 6, 8, -1],
\ map(range(-1, 5), 'line2byte(v:val)'))
@@ -865,6 +887,34 @@ func Test_byte2line_line2byte()
bw!
endfunc
+func Test_byteidx()
+ let a = '.é.' " one char of two bytes
+ call assert_equal(0, byteidx(a, 0))
+ call assert_equal(0, byteidxcomp(a, 0))
+ call assert_equal(1, byteidx(a, 1))
+ call assert_equal(1, byteidxcomp(a, 1))
+ call assert_equal(3, byteidx(a, 2))
+ call assert_equal(3, byteidxcomp(a, 2))
+ call assert_equal(4, byteidx(a, 3))
+ call assert_equal(4, byteidxcomp(a, 3))
+ call assert_equal(-1, byteidx(a, 4))
+ call assert_equal(-1, byteidxcomp(a, 4))
+
+ let b = '.é.' " normal e with composing char
+ call assert_equal(0, b->byteidx(0))
+ call assert_equal(1, b->byteidx(1))
+ call assert_equal(4, b->byteidx(2))
+ call assert_equal(5, b->byteidx(3))
+ call assert_equal(-1, b->byteidx(4))
+
+ call assert_equal(0, b->byteidxcomp(0))
+ call assert_equal(1, b->byteidxcomp(1))
+ call assert_equal(2, b->byteidxcomp(2))
+ call assert_equal(4, b->byteidxcomp(3))
+ call assert_equal(5, b->byteidxcomp(4))
+ call assert_equal(-1, b->byteidxcomp(5))
+endfunc
+
" Test for charidx()
func Test_charidx()
let a = 'xáb́y'
@@ -996,6 +1046,9 @@ func Test_Executable()
if catcmd =~ '\<sbin\>' && result =~ '\<bin\>'
call assert_equal('/' .. substitute(catcmd, '\<sbin\>', 'bin', ''), result)
else
+ " /bin/cat and /usr/bin/cat may be hard linked, we could get either
+ let result = substitute(result, '/usr/bin/cat', '/bin/cat', '')
+ let catcmd = substitute(catcmd, 'usr/bin/cat', 'bin/cat', '')
call assert_equal('/' .. catcmd, result)
endif
bwipe
@@ -1052,7 +1105,7 @@ func Test_col()
call assert_equal(7, col('$'))
call assert_equal(4, col("'x"))
call assert_equal(6, col("'Y"))
- call assert_equal(2, col([1, 2]))
+ call assert_equal(2, [1, 2]->col())
call assert_equal(7, col([1, '$']))
call assert_equal(0, col(''))
@@ -1119,6 +1172,29 @@ func Test_shellescape()
call assert_equal("'te\\\nxt'", shellescape("te\nxt"))
call assert_equal("'te\\\\\nxt'", shellescape("te\nxt", 1))
+ set shell=fish
+ call assert_equal("'text'", shellescape('text'))
+ call assert_equal("'te\"xt'", shellescape('te"xt'))
+ call assert_equal("'te'\\''xt'", shellescape("te'xt"))
+
+ call assert_equal("'te%xt'", shellescape("te%xt"))
+ call assert_equal("'te\\%xt'", shellescape("te%xt", 1))
+ call assert_equal("'te#xt'", shellescape("te#xt"))
+ call assert_equal("'te\\#xt'", shellescape("te#xt", 1))
+ call assert_equal("'te!xt'", shellescape("te!xt"))
+ call assert_equal("'te\\!xt'", shellescape("te!xt", 1))
+
+ call assert_equal("'te\\\\xt'", shellescape("te\\xt"))
+ call assert_equal("'te\\\\xt'", shellescape("te\\xt", 1))
+ call assert_equal("'te\\\\'\\''xt'", shellescape("te\\'xt"))
+ call assert_equal("'te\\\\'\\''xt'", shellescape("te\\'xt", 1))
+ call assert_equal("'te\\\\!xt'", shellescape("te\\!xt"))
+ call assert_equal("'te\\\\\\!xt'", shellescape("te\\!xt", 1))
+ call assert_equal("'te\\\\%xt'", shellescape("te\\%xt"))
+ call assert_equal("'te\\\\\\%xt'", shellescape("te\\%xt", 1))
+ call assert_equal("'te\\\\#xt'", shellescape("te\\#xt"))
+ call assert_equal("'te\\\\\\#xt'", shellescape("te\\#xt", 1))
+
let &shell = save_shell
endfunc
@@ -1315,7 +1391,15 @@ endfunc
func Test_getchar()
call feedkeys('a', '')
call assert_equal(char2nr('a'), getchar())
+ call assert_equal(0, getchar(0))
+ call assert_equal(0, getchar(1))
+
+ call feedkeys('a', '')
+ call assert_equal('a', getcharstr())
+ call assert_equal('', getcharstr(0))
+ call assert_equal('', getcharstr(1))
+ call setline(1, 'xxxx')
" call test_setmouse(1, 3)
" let v:mouse_win = 9
" let v:mouse_winid = 9
@@ -1328,6 +1412,7 @@ func Test_getchar()
call assert_equal(win_getid(1), v:mouse_winid)
call assert_equal(1, v:mouse_lnum)
call assert_equal(3, v:mouse_col)
+ enew!
endfunc
func Test_libcall_libcallnr()
@@ -1391,13 +1476,13 @@ func Test_bufadd_bufload()
call assert_equal([''], getbufline(buf, 1, '$'))
let curbuf = bufnr('')
- call writefile(['some', 'text'], 'otherName')
- let buf = bufadd('otherName')
+ call writefile(['some', 'text'], 'XotherName')
+ let buf = 'XotherName'->bufadd()
call assert_notequal(0, buf)
- call assert_equal(1, bufexists('otherName'))
+ eval 'XotherName'->bufexists()->assert_equal(1)
call assert_equal(0, getbufvar(buf, '&buflisted'))
call assert_equal(0, bufloaded(buf))
- call bufload(buf)
+ eval buf->bufload()
call assert_equal(1, bufloaded(buf))
call assert_equal(['some', 'text'], getbufline(buf, 1, '$'))
call assert_equal(curbuf, bufnr(''))
@@ -1417,8 +1502,9 @@ func Test_bufadd_bufload()
call assert_equal(0, bufexists(buf2))
bwipe someName
- bwipe otherName
+ bwipe XotherName
call assert_equal(0, bufexists('someName'))
+ call delete('XotherName')
endfunc
func Test_readdir()
@@ -1451,6 +1537,20 @@ func Test_readdir()
call delete('Xdir', 'rf')
endfunc
+func Test_call()
+ call assert_equal(3, call('len', [123]))
+ call assert_equal(3, 'len'->call([123]))
+ call assert_fails("call call('len', 123)", 'E714:')
+ call assert_equal(0, call('', []))
+
+ function Mylen() dict
+ return len(self.data)
+ endfunction
+ let mydict = {'data': [0, 1, 2, 3], 'len': function("Mylen")}
+ eval mydict.len->call([], mydict)->assert_equal(4)
+ call assert_fails("call call('Mylen', [], 0)", 'E715:')
+endfunc
+
" Test for the eval() function
func Test_eval()
call assert_fails("call eval('5 a')", 'E488:')
diff --git a/src/nvim/testdir/test_gf.vim b/src/nvim/testdir/test_gf.vim
index ee548037ba..43efd6248e 100644
--- a/src/nvim/testdir/test_gf.vim
+++ b/src/nvim/testdir/test_gf.vim
@@ -145,7 +145,7 @@ func Test_gf_visual()
bwipe!
call delete('Xtest_gf_visual')
- set hidden&
+ set nohidden
endfunc
func Test_gf_error()
diff --git a/src/nvim/testdir/test_hide.vim b/src/nvim/testdir/test_hide.vim
index 128b8ff945..41b1a4ad7c 100644
--- a/src/nvim/testdir/test_hide.vim
+++ b/src/nvim/testdir/test_hide.vim
@@ -37,7 +37,7 @@ function Test_hide()
" :hide as a command
hide
call assert_equal([orig_bname, orig_winnr], [bufname(''), winnr('$')])
- call assert_equal([1, 1], [buflisted('Xf1'), bufloaded('Xf1')])
+ call assert_equal([1, 1], ['Xf1'->buflisted(), 'Xf1'->bufloaded()])
bwipeout! Xf1
new Xf1
diff --git a/src/nvim/testdir/test_highlight.vim b/src/nvim/testdir/test_highlight.vim
index 24c9c3580e..6fd9477ce9 100644
--- a/src/nvim/testdir/test_highlight.vim
+++ b/src/nvim/testdir/test_highlight.vim
@@ -426,6 +426,7 @@ func Test_highlight_eol_with_cursorline_breakindent()
let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine()
call NewWindow('topleft 5', 10)
+ set showbreak=xxx
setlocal breakindent breakindentopt=min:0,shift:1 showbreak=>
call setline(1, ' ' . repeat('a', 9) . 'bcd')
call matchadd('Search', '\n')
@@ -483,6 +484,7 @@ func Test_highlight_eol_with_cursorline_breakindent()
call CloseWindow()
set showbreak=
+ setlocal showbreak=
exe hiCursorLine
endfunc
diff --git a/src/nvim/testdir/test_ins_complete.vim b/src/nvim/testdir/test_ins_complete.vim
index 3da3648fec..ce75799551 100644
--- a/src/nvim/testdir/test_ins_complete.vim
+++ b/src/nvim/testdir/test_ins_complete.vim
@@ -95,7 +95,7 @@ func Test_ins_complete()
call delete('Xtest11.one')
call delete('Xtest11.two')
call delete('Xtestdata')
- set cpt& cot& def& tags& tagbsearch& hidden&
+ set cpt& cot& def& tags& tagbsearch& nohidden
cd ..
call delete('Xdir', 'rf')
endfunc
@@ -497,6 +497,133 @@ func Test_ins_compl_tag_sft()
%bwipe!
endfunc
+" Test for completing special characters
+func Test_complete_special_chars()
+ new
+ call setline(1, 'int .*[-\^$ func float')
+ call feedkeys("oin\<C-X>\<C-P>\<C-X>\<C-P>\<C-X>\<C-P>", 'xt')
+ call assert_equal('int .*[-\^$ func float', getline(2))
+ close!
+endfunc
+
+" Test for completion when text is wrapped across lines.
+func Test_complete_across_line()
+ new
+ call setline(1, ['red green blue', 'one two three'])
+ setlocal textwidth=20
+ exe "normal 2G$a re\<C-X>\<C-P>\<C-X>\<C-P>\<C-X>\<C-P>\<C-X>\<C-P>"
+ call assert_equal(['one two three red', 'green blue one'], getline(2, '$'))
+ close!
+endfunc
+
+" Test for using CTRL-L to add one character when completing matching
+func Test_complete_add_onechar()
+ new
+ call setline(1, ['wool', 'woodwork'])
+ call feedkeys("Gowoo\<C-P>\<C-P>\<C-P>\<C-L>f", 'xt')
+ call assert_equal('woof', getline(3))
+
+ " use 'ignorecase' and backspace to erase characters from the prefix string
+ " and then add letters using CTRL-L
+ %d
+ set ignorecase backspace=2
+ setlocal complete=.
+ call setline(1, ['workhorse', 'workload'])
+ normal Go
+ exe "normal aWOR\<C-P>\<bs>\<bs>\<bs>\<bs>\<bs>\<bs>\<C-L>r\<C-L>\<C-L>"
+ call assert_equal('workh', getline(3))
+ set ignorecase& backspace&
+ close!
+endfunc
+
+" Test insert completion with 'cindent' (adjust the indent)
+func Test_complete_with_cindent()
+ new
+ setlocal cindent
+ call setline(1, ['if (i == 1)', " j = 2;"])
+ exe "normal Go{\<CR>i\<C-X>\<C-L>\<C-X>\<C-L>\<CR>}"
+ call assert_equal(['{', "\tif (i == 1)", "\t\tj = 2;", '}'], getline(3, '$'))
+
+ %d
+ call setline(1, ['when while', '{', ''])
+ setlocal cinkeys+==while
+ exe "normal Giwh\<C-P> "
+ call assert_equal("\twhile ", getline('$'))
+ close!
+endfunc
+
+" Test for <CTRL-X> <CTRL-V> completion. Complete commands and functions
+func Test_complete_cmdline()
+ new
+ exe "normal icaddb\<C-X>\<C-V>"
+ call assert_equal('caddbuffer', getline(1))
+ exe "normal ocall getqf\<C-X>\<C-V>"
+ call assert_equal('call getqflist(', getline(2))
+ exe "normal oabcxyz(\<C-X>\<C-V>"
+ call assert_equal('abcxyz(', getline(3))
+ com! -buffer TestCommand1 echo 'TestCommand1'
+ com! -buffer TestCommand2 echo 'TestCommand2'
+ write TestCommand1Test
+ write TestCommand2Test
+ " Test repeating <CTRL-X> <CTRL-V> and switching to another CTRL-X mode
+ exe "normal oT\<C-X>\<C-V>\<C-X>\<C-V>\<C-X>\<C-F>\<Esc>"
+ call assert_equal('TestCommand2Test', getline(4))
+ call delete('TestCommand1Test')
+ call delete('TestCommand2Test')
+ delcom TestCommand1
+ delcom TestCommand2
+ close!
+endfunc
+
+" Test for <CTRL-X> <CTRL-Z> stopping completion without changing the match
+func Test_complete_stop()
+ new
+ func Save_mode1()
+ let g:mode1 = mode(1)
+ return ''
+ endfunc
+ func Save_mode2()
+ let g:mode2 = mode(1)
+ return ''
+ endfunc
+ inoremap <F1> <C-R>=Save_mode1()<CR>
+ inoremap <F2> <C-R>=Save_mode2()<CR>
+ call setline(1, ['aaa bbb ccc '])
+ exe "normal A\<C-N>\<C-P>\<F1>\<C-X>\<C-Z>\<F2>\<Esc>"
+ call assert_equal('ic', g:mode1)
+ call assert_equal('i', g:mode2)
+ call assert_equal('aaa bbb ccc ', getline(1))
+ exe "normal A\<C-N>\<Down>\<F1>\<C-X>\<C-Z>\<F2>\<Esc>"
+ call assert_equal('ic', g:mode1)
+ call assert_equal('i', g:mode2)
+ call assert_equal('aaa bbb ccc aaa', getline(1))
+ set completeopt+=noselect
+ exe "normal A \<C-N>\<Down>\<Down>\<C-L>\<C-L>\<F1>\<C-X>\<C-Z>\<F2>\<Esc>"
+ call assert_equal('ic', g:mode1)
+ call assert_equal('i', g:mode2)
+ call assert_equal('aaa bbb ccc aaa bb', getline(1))
+ set completeopt&
+ exe "normal A d\<C-N>\<F1>\<C-X>\<C-Z>\<F2>\<Esc>"
+ call assert_equal('ic', g:mode1)
+ call assert_equal('i', g:mode2)
+ call assert_equal('aaa bbb ccc aaa bb d', getline(1))
+ com! -buffer TestCommand1 echo 'TestCommand1'
+ com! -buffer TestCommand2 echo 'TestCommand2'
+ exe "normal oT\<C-X>\<C-V>\<C-X>\<C-V>\<F1>\<C-X>\<C-Z>\<F2>\<Esc>"
+ call assert_equal('ic', g:mode1)
+ call assert_equal('i', g:mode2)
+ call assert_equal('TestCommand2', getline(2))
+ delcom TestCommand1
+ delcom TestCommand2
+ unlet g:mode1
+ unlet g:mode2
+ iunmap <F1>
+ iunmap <F2>
+ delfunc Save_mode1
+ delfunc Save_mode2
+ close!
+endfunc
+
" Test to ensure 'Scanning...' messages are not recorded in messages history
func Test_z1_complete_no_history()
new
diff --git a/src/nvim/testdir/test_ins_complete_no_halt.vim b/src/nvim/testdir/test_ins_complete_no_halt.vim
new file mode 100644
index 0000000000..e12925daa9
--- /dev/null
+++ b/src/nvim/testdir/test_ins_complete_no_halt.vim
@@ -0,0 +1,51 @@
+" Test insert mode completion does not get stuck when looping around.
+" In a separate file to avoid the settings to leak to other test cases.
+
+set complete+=kspell
+set completeopt+=menu
+set completeopt+=menuone
+set completeopt+=noselect
+set completeopt+=noinsert
+let g:autocompletion = v:true
+
+func Test_ins_complete_no_halt()
+ function! OpenCompletion()
+ if pumvisible() && (g:autocompletion == v:true)
+ call feedkeys("\<C-e>\<C-n>", "i")
+ return
+ endif
+ if ((v:char >= 'a' && v:char <= 'z') || (v:char >= 'A' && v:char <= 'Z')) && (g:autocompletion == v:true)
+ call feedkeys("\<C-n>", "i")
+ redraw
+ endif
+ endfunction
+
+ autocmd InsertCharPre * noautocmd call OpenCompletion()
+
+ setlocal spell! spelllang=en_us
+
+ call feedkeys("iauto-complete-halt-test test test test test test test test test test test test test test test test test test test\<C-c>", "tx!")
+ call assert_equal(["auto-complete-halt-test test test test test test test test test test test test test test test test test test test"], getline(1, "$"))
+endfunc
+
+func Test_auto_complete_backwards_no_halt()
+ function! OpenCompletion()
+ if pumvisible() && (g:autocompletion == v:true)
+ call feedkeys("\<C-e>\<C-p>", "i")
+ return
+ endif
+ if ((v:char >= 'a' && v:char <= 'z') || (v:char >= 'A' && v:char <= 'Z')) && (g:autocompletion == v:true)
+ call feedkeys("\<C-p>", "i")
+ redraw
+ endif
+ endfunction
+
+ autocmd InsertCharPre * noautocmd call OpenCompletion()
+
+ setlocal spell! spelllang=en_us
+
+ call feedkeys("iauto-complete-halt-test test test test test test test test test test test test test test test test test test test\<C-c>", "tx!")
+ call assert_equal(["auto-complete-halt-test test test test test test test test test test test test test test test test test test test"], getline(1, "$"))
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_join.vim b/src/nvim/testdir/test_join.vim
index ac6ef8f29f..ecb969d10a 100644
--- a/src/nvim/testdir/test_join.vim
+++ b/src/nvim/testdir/test_join.vim
@@ -51,7 +51,7 @@ func Test_join_marks()
/^This line/;'}-join
call assert_equal([0, 4, 11, 0], getpos("'["))
- call assert_equal([0, 4, 67, 0], getpos("']"))
+ call assert_equal([0, 4, 66, 0], getpos("']"))
enew!
endfunc
diff --git a/src/nvim/testdir/test_lambda.vim b/src/nvim/testdir/test_lambda.vim
index f026c8a55f..63bb4ae1ef 100644
--- a/src/nvim/testdir/test_lambda.vim
+++ b/src/nvim/testdir/test_lambda.vim
@@ -61,7 +61,7 @@ endfunction
function Test_lambda_fails()
call assert_equal(3, {a, b -> a + b}(1, 2))
- call assert_fails('echo {a, a -> a + a}(1, 2)', 'E15:')
+ call assert_fails('echo {a, a -> a + a}(1, 2)', 'E853:')
call assert_fails('echo {a, b -> a + b)}(1, 2)', 'E15:')
endfunc
diff --git a/src/nvim/testdir/test_listchars.vim b/src/nvim/testdir/test_listchars.vim
index 4cb609aaf0..8a1393a45d 100644
--- a/src/nvim/testdir/test_listchars.vim
+++ b/src/nvim/testdir/test_listchars.vim
@@ -140,13 +140,100 @@ func Test_listchars()
call assert_equal(expected, split(execute("%list"), "\n"))
+ " Test multispace
+ normal ggdG
+ set listchars=eol:$
+ set listchars+=multispace:yYzZ
+ set list
+
+ call append(0, [
+ \ ' ffff ',
+ \ ' i i gg',
+ \ ' h ',
+ \ ' j ',
+ \ ' 0 0 ',
+ \ ])
+
+ let expected = [
+ \ 'yYzZffffyYzZ$',
+ \ 'yYi iyYzZygg$',
+ \ ' hyYzZyYzZyY$',
+ \ 'yYzZyYzZyYj $',
+ \ 'yYzZ0yY0yYzZ$',
+ \ '$'
+ \ ]
+ redraw!
+ for i in range(1, 5)
+ call cursor(i, 1)
+ call assert_equal([expected[i - 1]], ScreenLines(i, virtcol('$')))
+ endfor
+
+ call assert_equal(expected, split(execute("%list"), "\n"))
+
+ " the last occurrence of 'multispace:' is used
+ set listchars+=space:x,multispace:XyY
+
+ let expected = [
+ \ 'XyYXffffXyYX$',
+ \ 'XyixiXyYXygg$',
+ \ 'xhXyYXyYXyYX$',
+ \ 'XyYXyYXyYXjx$',
+ \ 'XyYX0Xy0XyYX$',
+ \ '$'
+ \ ]
+ redraw!
+ for i in range(1, 5)
+ call cursor(i, 1)
+ call assert_equal([expected[i - 1]], ScreenLines(i, virtcol('$')))
+ endfor
+
+ call assert_equal(expected, split(execute("%list"), "\n"))
+
+ set listchars+=lead:>,trail:<
+
+ let expected = [
+ \ '>>>>ffff<<<<$',
+ \ '>>ixiXyYXygg$',
+ \ '>h<<<<<<<<<<$',
+ \ '>>>>>>>>>>j<$',
+ \ '>>>>0Xy0<<<<$',
+ \ '$'
+ \ ]
+ redraw!
+ for i in range(1, 5)
+ call cursor(i, 1)
+ call assert_equal([expected[i - 1]], ScreenLines(i, virtcol('$')))
+ endfor
+
+ call assert_equal(expected, split(execute("%list"), "\n"))
+
+ " removing 'multispace:'
+ set listchars-=multispace:XyY
+ set listchars-=multispace:yYzZ
+
+ let expected = [
+ \ '>>>>ffff<<<<$',
+ \ '>>ixixxxxxgg$',
+ \ '>h<<<<<<<<<<$',
+ \ '>>>>>>>>>>j<$',
+ \ '>>>>0xx0<<<<$',
+ \ '$'
+ \ ]
+ redraw!
+ for i in range(1, 5)
+ call cursor(i, 1)
+ call assert_equal([expected[i - 1]], ScreenLines(i, virtcol('$')))
+ endfor
+
+ call assert_equal(expected, split(execute("%list"), "\n"))
+
" test nbsp
normal ggdG
set listchars=nbsp:X,trail:Y
set list
" Non-breaking space
let nbsp = nr2char(0xa0)
- call append(0, [ ">".nbsp."<" ])
+ call append(0, [ ">" .. nbsp .. "<" ])
let expected = '>X< '
@@ -181,3 +268,100 @@ func Test_listchars()
enew!
set listchars& ff&
endfunc
+
+" Test that unicode listchars characters get properly inserted
+func Test_listchars_unicode()
+ enew!
+ let oldencoding=&encoding
+ set encoding=utf-8
+ set ff=unix
+
+ set listchars=eol:⇔,space:␣,multispace:≡≢≣,nbsp:≠,tab:←↔→
+ set list
+
+ let nbsp = nr2char(0xa0)
+ call append(0, [" a\tb c" .. nbsp .. "d "])
+ let expected = ['≡≢≣≡≢≣≡≢a←↔↔↔↔↔→b␣c≠d≡≢⇔']
+ redraw!
+ call cursor(1, 1)
+ call assert_equal(expected, ScreenLines(1, virtcol('$')))
+
+ set listchars+=lead:⇨,trail:⇦
+ let expected = ['⇨⇨⇨⇨⇨⇨⇨⇨a←↔↔↔↔↔→b␣c≠d⇦⇦⇔']
+ redraw!
+ call cursor(1, 1)
+ call assert_equal(expected, ScreenLines(1, virtcol('$')))
+
+ let &encoding=oldencoding
+ enew!
+ set listchars& ff&
+endfunction
+
+func Test_listchars_invalid()
+ enew!
+ set ff=unix
+
+ set listchars=eol:$
+ set list
+ set ambiwidth=double
+
+ " No colon
+ call assert_fails('set listchars=x', 'E474:')
+ call assert_fails('set listchars=x', 'E474:')
+ call assert_fails('set listchars=multispace', 'E474:')
+
+ " Too short
+ call assert_fails('set listchars=space:', 'E474:')
+ call assert_fails('set listchars=tab:x', 'E474:')
+ call assert_fails('set listchars=multispace:', 'E474:')
+
+ " One occurrence too short
+ call assert_fails('set listchars=space:,space:x', 'E474:')
+ call assert_fails('set listchars=space:x,space:', 'E474:')
+ call assert_fails('set listchars=tab:x,tab:xx', 'E474:')
+ call assert_fails('set listchars=tab:xx,tab:x', 'E474:')
+ call assert_fails('set listchars=multispace:,multispace:x', 'E474:')
+ call assert_fails('set listchars=multispace:x,multispace:', 'E474:')
+
+ " Too long
+ call assert_fails('set listchars=space:xx', 'E474:')
+ call assert_fails('set listchars=tab:xxxx', 'E474:')
+
+ " Has non-single width character
+ call assert_fails('set listchars=space:·', 'E474:')
+ call assert_fails('set listchars=tab:·x', 'E474:')
+ call assert_fails('set listchars=tab:x·', 'E474:')
+ call assert_fails('set listchars=tab:xx·', 'E474:')
+ call assert_fails('set listchars=multispace:·', 'E474:')
+ call assert_fails('set listchars=multispace:xxx·', 'E474:')
+
+ enew!
+ set ambiwidth& listchars& ff&
+endfunction
+
+" Tests that space characters following composing character won't get replaced
+" by listchars.
+func Test_listchars_composing()
+ enew!
+ let oldencoding=&encoding
+ set encoding=utf-8
+ set ff=unix
+ set list
+
+ set listchars=eol:$,space:_,nbsp:=
+
+ let nbsp1 = nr2char(0xa0)
+ let nbsp2 = nr2char(0x202f)
+ call append(0, [
+ \ " \u3099\t \u309A" .. nbsp1 .. nbsp1 .. "\u0302" .. nbsp2 .. nbsp2 .. "\u0302",
+ \ ])
+ let expected = [
+ \ "_ \u3099^I \u309A=" .. nbsp1 .. "\u0302=" .. nbsp2 .. "\u0302$"
+ \ ]
+ redraw!
+ call cursor(1, 1)
+ call assert_equal(expected, ScreenLines(1, virtcol('$')))
+ let &encoding=oldencoding
+ enew!
+ set listchars& ff&
+endfunction
diff --git a/src/nvim/testdir/test_listdict.vim b/src/nvim/testdir/test_listdict.vim
index 5152af8f58..ae035fa519 100644
--- a/src/nvim/testdir/test_listdict.vim
+++ b/src/nvim/testdir/test_listdict.vim
@@ -139,7 +139,7 @@ func Test_list_func_remove()
call assert_fails("call remove(l, 5)", 'E684:')
call assert_fails("call remove(l, 1, 5)", 'E684:')
call assert_fails("call remove(l, 3, 2)", 'E16:')
- call assert_fails("call remove(1, 0)", 'E712:')
+ call assert_fails("call remove(1, 0)", 'E896:')
call assert_fails("call remove(l, l)", 'E745:')
endfunc
@@ -616,6 +616,8 @@ func Test_reverse_sort_uniq()
call assert_equal(['bar', 'BAR', 'Bar', 'Foo', 'FOO', 'foo', 'FOOBAR', -1, 0, 0, 0.22, 1.0e-15, 12, 18, 22, 255, 7, 9, [], {}], sort(copy(l), 1))
call assert_equal(['bar', 'BAR', 'Bar', 'Foo', 'FOO', 'foo', 'FOOBAR', -1, 0, 0, 0.22, 1.0e-15, 12, 18, 22, 255, 7, 9, [], {}], sort(copy(l), 'i'))
call assert_equal(['BAR', 'Bar', 'FOO', 'FOOBAR', 'Foo', 'bar', 'foo', -1, 0, 0, 0.22, 1.0e-15, 12, 18, 22, 255, 7, 9, [], {}], sort(copy(l)))
+
+ call assert_fails('call reverse("")', 'E899:')
endfunc
" splitting a string to a List
diff --git a/src/nvim/testdir/test_match.vim b/src/nvim/testdir/test_match.vim
index 09448ca71b..505a052a19 100644
--- a/src/nvim/testdir/test_match.vim
+++ b/src/nvim/testdir/test_match.vim
@@ -157,7 +157,10 @@ func Test_match_error()
endfunc
func Test_matchadd_error()
- call assert_fails("call matchadd('GroupDoesNotExist', 'X')", 'E28:')
+ call clearmatches()
+ " Nvim: not an error anymore:
+ call matchadd('GroupDoesNotExist', 'X')
+ call assert_equal([{'group': 'GroupDoesNotExist', 'pattern': 'X', 'priority': 10, 'id': 13}], getmatches())
call assert_fails("call matchadd('Search', '\\(')", 'E475:')
call assert_fails("call matchadd('Search', 'XXX', 1, 123, 1)", 'E715:')
call assert_fails("call matchadd('Error', 'XXX', 1, 3)", 'E798:')
@@ -239,7 +242,7 @@ func Test_matchaddpos_otherwin()
\]
call assert_equal(expect, savematches)
- call clearmatches(winid)
+ eval winid->clearmatches()
call assert_equal([], getmatches(winid))
call setmatches(savematches, winid)
diff --git a/src/nvim/testdir/test_method.vim b/src/nvim/testdir/test_method.vim
new file mode 100644
index 0000000000..d34448e09e
--- /dev/null
+++ b/src/nvim/testdir/test_method.vim
@@ -0,0 +1,154 @@
+" Tests for ->method()
+
+func Test_list_method()
+ let l = [1, 2, 3]
+ call assert_equal([1, 2, 3, 4], [1, 2, 3]->add(4))
+ eval l->assert_equal(l)
+ eval l->assert_equal(l, 'wrong')
+ eval l->assert_notequal([3, 2, 1])
+ eval l->assert_notequal([3, 2, 1], 'wrong')
+ call assert_equal(l, l->copy())
+ call assert_equal(l, l->deepcopy())
+ call assert_equal(1, l->count(2))
+ call assert_false(l->empty())
+ call assert_true([]->empty())
+ call assert_equal(579, ['123', '+', '456']->join()->eval())
+ call assert_equal([1, 2, 3, 4, 5], [1, 2, 3]->extend([4, 5]))
+ call assert_equal([1, 3], [1, 2, 3]->filter('v:val != 2'))
+ call assert_equal(2, l->get(1))
+ call assert_equal(1, l->index(2))
+ call assert_equal([0, 1, 2, 3], [1, 2, 3]->insert(0))
+ call assert_fails('eval l->items()', 'E715:')
+ call assert_equal('1 2 3', l->join())
+ call assert_fails('eval l->keys()', 'E715:')
+ call assert_equal(3, l->len())
+ call assert_equal([2, 3, 4], [1, 2, 3]->map('v:val + 1'))
+ call assert_equal(3, l->max())
+ call assert_equal(1, l->min())
+ call assert_equal(2, [1, 2, 3]->remove(1))
+ call assert_equal([1, 2, 3, 1, 2, 3], l->repeat(2))
+ call assert_equal([3, 2, 1], [1, 2, 3]->reverse())
+ call assert_equal([1, 2, 3, 4], [4, 2, 3, 1]->sort())
+ call assert_equal('[1, 2, 3]', l->string())
+ call assert_equal(v:t_list, l->type())
+ call assert_equal([1, 2, 3], [1, 1, 2, 3, 3]->uniq())
+ call assert_fails('eval l->values()', 'E715:')
+endfunc
+
+func Test_dict_method()
+ let d = #{one: 1, two: 2, three: 3}
+
+ call assert_equal(d, d->copy())
+ call assert_equal(d, d->deepcopy())
+ call assert_equal(1, d->count(2))
+ call assert_false(d->empty())
+ call assert_true({}->empty())
+ call assert_equal(#{one: 1, two: 2, three: 3, four: 4}, d->extend(#{four: 4}))
+ call assert_equal(#{one: 1, two: 2, three: 3}, d->filter('v:val != 4'))
+ call assert_equal(2, d->get('two'))
+ call assert_fails("let x = d->index(2)", 'E897:')
+ call assert_fails("let x = d->insert(0)", 'E899:')
+ call assert_true(d->has_key('two'))
+ call assert_equal([['one', 1], ['two', 2], ['three', 3]], d->items())
+ call assert_fails("let x = d->join()", 'E714:')
+ call assert_equal(['one', 'two', 'three'], d->keys())
+ call assert_equal(3, d->len())
+ call assert_equal(#{one: 2, two: 3, three: 4}, d->map('v:val + 1'))
+ call assert_equal(#{one: 1, two: 2, three: 3}, d->map('v:val - 1'))
+ call assert_equal(3, d->max())
+ call assert_equal(1, d->min())
+ call assert_equal(2, d->remove("two"))
+ let d.two = 2
+ call assert_fails('let x = d->repeat(2)', 'E731:')
+ call assert_fails('let x = d->reverse()', 'E899:')
+ call assert_fails('let x = d->sort()', 'E686:')
+ call assert_equal("{'one': 1, 'two': 2, 'three': 3}", d->string())
+ call assert_equal(v:t_dict, d->type())
+ call assert_fails('let x = d->uniq()', 'E686:')
+ call assert_equal([1, 2, 3], d->values())
+endfunc
+
+func Test_string_method()
+ eval '1 2 3'->split()->assert_equal(['1', '2', '3'])
+ eval '1 2 3'->split()->map({i, v -> str2nr(v)})->assert_equal([1, 2, 3])
+ eval 'ABC'->str2list()->assert_equal([65, 66, 67])
+ eval 'ABC'->strlen()->assert_equal(3)
+ eval "a\rb\ec"->strtrans()->assert_equal('a^Mb^[c')
+ eval "aあb"->strwidth()->assert_equal(4)
+ eval 'abc'->substitute('b', 'x', '')->assert_equal('axc')
+
+ eval 'abc'->printf('the %s arg')->assert_equal('the abc arg')
+endfunc
+
+func Test_method_append()
+ new
+ eval ['one', 'two', 'three']->append(1)
+ call assert_equal(['', 'one', 'two', 'three'], getline(1, '$'))
+
+ %del
+ let bnr = bufnr('')
+ wincmd w
+ eval ['one', 'two', 'three']->appendbufline(bnr, 1)
+ call assert_equal(['', 'one', 'two', 'three'], getbufline(bnr, 1, '$'))
+
+ exe 'bwipe! ' .. bnr
+endfunc
+
+func Test_method_funcref()
+ func Concat(one, two, three)
+ return a:one .. a:two .. a:three
+ endfunc
+ let FuncRef = function('Concat')
+ eval 'foo'->FuncRef('bar', 'tail')->assert_equal('foobartail')
+
+ " not enough arguments
+ call assert_fails("eval 'foo'->FuncRef('bar')", 'E119:')
+ " too many arguments
+ call assert_fails("eval 'foo'->FuncRef('bar', 'tail', 'four')", 'E118:')
+
+ let Partial = function('Concat', ['two'])
+ eval 'one'->Partial('three')->assert_equal('onetwothree')
+
+ " not enough arguments
+ call assert_fails("eval 'one'->Partial()", 'E119:')
+ " too many arguments
+ call assert_fails("eval 'one'->Partial('three', 'four')", 'E118:')
+
+ delfunc Concat
+endfunc
+
+func Test_method_float()
+ eval 1.234->string()->assert_equal('1.234')
+ eval -1.234->string()->assert_equal('-1.234')
+endfunc
+
+func Test_method_syntax()
+ eval [1, 2, 3] ->sort( )
+ eval [1, 2, 3]
+ \ ->sort(
+ \ )
+ call assert_fails('eval [1, 2, 3]-> sort()', 'E260:')
+ call assert_fails('eval [1, 2, 3]->sort ()', 'E274:')
+ call assert_fails('eval [1, 2, 3]-> sort ()', 'E260:')
+endfunc
+
+func Test_method_lambda()
+ eval "text"->{x -> x .. " extended"}()->assert_equal('text extended')
+ eval "text"->{x, y -> x .. " extended " .. y}('more')->assert_equal('text extended more')
+
+ call assert_fails('eval "text"->{x -> x .. " extended"} ()', 'E274:')
+
+ " todo: lambda accepts more arguments than it consumes
+ " call assert_fails('eval "text"->{x -> x .. " extended"}("more")', 'E99:')
+
+ " Nvim doesn't include test_refcount().
+ " let l = [1, 2, 3]
+ " eval l->{x -> x}()
+ " call assert_equal(1, test_refcount(l))
+endfunc
+
+func Test_method_not_supported()
+ call assert_fails('eval 123->changenr()', 'E276:')
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_mksession.vim b/src/nvim/testdir/test_mksession.vim
index 4e46dbac16..c96c6a9678 100644
--- a/src/nvim/testdir/test_mksession.vim
+++ b/src/nvim/testdir/test_mksession.vim
@@ -170,7 +170,7 @@ func Test_mksession_rtp()
return
endif
new
- set sessionoptions&vi
+ set sessionoptions+=options
let _rtp=&rtp
" Make a real long (invalid) runtimepath value,
" that should exceed PATH_MAX (hopefully)
@@ -287,10 +287,33 @@ func Test_mksession_blank_windows()
call delete('Xtest_mks.out')
endfunc
+func Test_mksession_buffer_count()
+ set hidden
+
+ " Edit exactly three files in the current session.
+ %bwipe!
+ e Xfoo | tabe Xbar | tabe Xbaz
+ tabdo write
+ mksession! Xtest_mks.out
+
+ " Verify that loading the session does not create additional buffers.
+ %bwipe!
+ source Xtest_mks.out
+ call assert_equal(3, len(getbufinfo()))
+
+ " Clean up.
+ call delete('Xfoo')
+ call delete('Xbar')
+ call delete('Xbaz')
+ call delete('Xtest_mks.out')
+ %bwipe!
+ set nohidden
+endfunc
+
if has('extra_search')
func Test_mksession_hlsearch()
- set sessionoptions&vi
+ set sessionoptions+=options
set hlsearch
mksession! Xtest_mks.out
nohlsearch
@@ -630,7 +653,7 @@ endfunc
" Test for mksession with a named scratch buffer
func Test_mksession_scratch()
- set sessionoptions&vi
+ set sessionoptions+=options
enew | only
file Xscratch
set buftype=nofile
diff --git a/src/nvim/testdir/test_modeline.vim b/src/nvim/testdir/test_modeline.vim
index 9bdada616c..b3fe79f545 100644
--- a/src/nvim/testdir/test_modeline.vim
+++ b/src/nvim/testdir/test_modeline.vim
@@ -280,3 +280,13 @@ func Test_modeline_fails_modelineexpr()
call s:modeline_fails('tabline', 'tabline=Something()', 'E992:')
call s:modeline_fails('titlestring', 'titlestring=Something()', 'E992:')
endfunc
+
+func Test_modeline_disable()
+ set modeline
+ call writefile(['vim: sw=2', 'vim: nomodeline', 'vim: sw=3'], 'Xmodeline_disable')
+ edit Xmodeline_disable
+ call assert_equal(2, &sw)
+ call delete('Xmodeline_disable')
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_normal.vim b/src/nvim/testdir/test_normal.vim
index 5c413d1e16..aff22f5d01 100644
--- a/src/nvim/testdir/test_normal.vim
+++ b/src/nvim/testdir/test_normal.vim
@@ -1227,7 +1227,7 @@ func Test_normal23_K()
set iskeyword-=\|
" Only expect "man" to work on Unix
- if !has("unix")
+ if !has("unix") || has('nvim') " Nvim K uses :terminal. #15398
let &keywordprg = k
bw!
return
diff --git a/src/nvim/testdir/test_number.vim b/src/nvim/testdir/test_number.vim
index eaabe3f67e..d737ebe9f0 100644
--- a/src/nvim/testdir/test_number.vim
+++ b/src/nvim/testdir/test_number.vim
@@ -3,6 +3,8 @@
source check.vim
source view_util.vim
+source screendump.vim
+
func s:screen_lines(start, end) abort
return ScreenLines([a:start, a:end], 8)
endfunc
@@ -265,6 +267,37 @@ func Test_relativenumber_uninitialised()
bwipe!
endfunc
+func Test_relativenumber_colors()
+ CheckScreendump
+
+ let lines =<< trim [CODE]
+ call setline(1, range(200))
+ 111
+ set number relativenumber
+ hi LineNr ctermfg=red
+ [CODE]
+ call writefile(lines, 'XTest_relnr')
+
+ " Check that the balloon shows up after a mouse move
+ let buf = RunVimInTerminal('-S XTest_relnr', {'rows': 10, 'cols': 50})
+ call term_wait(buf, 100)
+ " Default colors
+ call VerifyScreenDump(buf, 'Test_relnr_colors_1', {})
+
+ call term_sendkeys(buf, ":hi LineNrAbove ctermfg=blue\<CR>")
+ call VerifyScreenDump(buf, 'Test_relnr_colors_2', {})
+
+ call term_sendkeys(buf, ":hi LineNrBelow ctermfg=green\<CR>")
+ call VerifyScreenDump(buf, 'Test_relnr_colors_3', {})
+
+ call term_sendkeys(buf, ":hi clear LineNrAbove\<CR>")
+ call VerifyScreenDump(buf, 'Test_relnr_colors_4', {})
+
+ " clean up
+ call StopVimInTerminal(buf)
+ call delete('XTest_relnr')
+endfunc
+
" Test for displaying line numbers with 'rightleft'
func Test_number_rightleft()
CheckFeature rightleft
@@ -287,4 +320,15 @@ func Test_number_rightleft()
bw!
endfunc
+" This used to cause a divide by zero
+func Test_number_no_text_virtual_edit()
+ vnew
+ call setline(1, ['line one', 'line two'])
+ set number virtualedit=all
+ normal w
+ 4wincmd |
+ normal j
+ bwipe!
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_options.vim b/src/nvim/testdir/test_options.vim
index 8796af7a20..72c151142d 100644
--- a/src/nvim/testdir/test_options.vim
+++ b/src/nvim/testdir/test_options.vim
@@ -539,7 +539,7 @@ func Test_copy_winopt()
call assert_equal(4,&numberwidth)
bw!
- set hidden&
+ set nohidden
endfunc
func Test_shortmess_F()
diff --git a/src/nvim/testdir/test_popup.vim b/src/nvim/testdir/test_popup.vim
index 06bdb1236a..710450293c 100644
--- a/src/nvim/testdir/test_popup.vim
+++ b/src/nvim/testdir/test_popup.vim
@@ -250,7 +250,7 @@ endfunc
func Test_noinsert_complete()
func! s:complTest1() abort
- call complete(1, ['source', 'soundfold'])
+ eval ['source', 'soundfold']->complete(1)
return ''
endfunc
@@ -403,7 +403,7 @@ func DummyCompleteFour(findstart, base)
return 0
else
call complete_add('four1')
- call complete_add('four2')
+ eval 'four2'->complete_add()
call complete_check()
call complete_add('four3')
call complete_add('four4')
@@ -989,7 +989,7 @@ func GetCompleteInfo()
if empty(g:compl_what)
let g:compl_info = complete_info()
else
- let g:compl_info = complete_info(g:compl_what)
+ let g:compl_info = g:compl_what->complete_info()
endif
return ''
endfunc
diff --git a/src/nvim/testdir/test_quickfix.vim b/src/nvim/testdir/test_quickfix.vim
index 6bd64caa6c..18587b9b2c 100644
--- a/src/nvim/testdir/test_quickfix.vim
+++ b/src/nvim/testdir/test_quickfix.vim
@@ -134,6 +134,21 @@ func XlistTests(cchar)
call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
\ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
+ " Ranged entries
+ call g:Xsetlist([{'lnum':10,'text':'Line1'},
+ \ {'lnum':20,'col':10,'text':'Line2'},
+ \ {'lnum':30,'col':15,'end_col':20,'text':'Line3'},
+ \ {'lnum':40,'end_lnum':45,'text':'Line4'},
+ \ {'lnum':50,'end_lnum':55,'col':15,'text':'Line5'},
+ \ {'lnum':60,'end_lnum':65,'col':25,'end_col':35,'text':'Line6'}])
+ let l = split(execute('Xlist', ""), "\n")
+ call assert_equal([' 1:10: Line1',
+ \ ' 2:20 col 10: Line2',
+ \ ' 3:30 col 15-20: Line3',
+ \ ' 4:40-45: Line4',
+ \ ' 5:50-55 col 15: Line5',
+ \ ' 6:60-65 col 25-35: Line6'], l)
+
" Different types of errors
call g:Xsetlist([{'lnum':10,'col':5,'type':'W', 'text':'Warning','nr':11},
\ {'lnum':20,'col':10,'type':'e','text':'Error','nr':22},
@@ -599,6 +614,7 @@ func s:test_xhelpgrep(cchar)
call assert_true(&buftype == 'help')
call assert_true(winnr() == 1)
call assert_true(winnr('$') == 2)
+ call assert_match('|\d\+ col \d\+-\d\+|', getbufline(winbufnr(2), 1)[0])
" This wipes out the buffer, make sure that doesn't cause trouble.
Xclose
@@ -1437,10 +1453,13 @@ func SetXlistTests(cchar, bnum)
call s:setup_commands(a:cchar)
call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 1},
- \ {'bufnr': a:bnum, 'lnum': 2}])
+ \ {'bufnr': a:bnum, 'lnum': 2, 'end_lnum': 3, 'col': 4, 'end_col': 5}])
let l = g:Xgetlist()
call assert_equal(2, len(l))
call assert_equal(2, l[1].lnum)
+ call assert_equal(3, l[1].end_lnum)
+ call assert_equal(4, l[1].col)
+ call assert_equal(5, l[1].end_col)
Xnext
call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3}], 'a')
@@ -1892,7 +1911,7 @@ func Test_switchbuf()
enew | only
set switchbuf=useopen
cexpr "Xqftestfile1:1:10"
- call assert_equal('', &switchbuf)
+ call assert_equal('uselast', &switchbuf)
call delete('Xqftestfile1')
call delete('Xqftestfile2')
@@ -2202,6 +2221,10 @@ func Xproperty_tests(cchar)
call g:Xsetlist([], 'a', {'context':246})
let d = g:Xgetlist({'context':1})
call assert_equal(246, d.context)
+ " set other Vim data types as context
+ call g:Xsetlist([], 'a', {'context' : v:_null_blob})
+ call g:Xsetlist([], 'a', {'context' : ''})
+ call test_garbagecollect_now()
if a:cchar == 'l'
" Test for copying context across two different location lists
new | only
@@ -2743,7 +2766,9 @@ func XvimgrepTests(cchar)
let l = g:Xgetlist()
call assert_equal(2, len(l))
call assert_equal(8, l[0].col)
+ call assert_equal(11, l[0].end_col)
call assert_equal(12, l[1].col)
+ call assert_equal(15, l[1].end_col)
1Xvimgrep ?Editor? Xtestfile*
let l = g:Xgetlist()
@@ -2965,7 +2990,7 @@ func Test_cclose_in_autocmd()
" call test_override('starting', 0)
endfunc
-" Check that ":file" without an argument is possible even when "curbuf_lock"
+" Check that ":file" without an argument is possible even when curbuf is locked
" is set.
func Test_file_from_copen()
" Works without argument.
@@ -4850,7 +4875,42 @@ func Test_add_invalid_entry_with_qf_window()
call setqflist(['bb'], 'a')
call assert_equal(1, line('$'))
call assert_equal(['Xfile1|10| aa'], getline(1, '$'))
- call assert_equal([{'lnum': 10, 'bufnr': bufnr('Xfile1'), 'col': 0, 'pattern': '', 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'module': '', 'text': 'aa'}], getqflist())
+ call assert_equal([{'lnum': 10 , 'end_lnum': 0 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'end_col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , getqflist())
+
+ call setqflist([{'lnum': 10 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r')
+ call assert_equal(1 , line('$'))
+ call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
+ call assert_equal([{'lnum': 10 , 'end_lnum': 0 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'end_col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , getqflist())
+
+ call setqflist([{'lnum': 10 , 'end_lnum': 0 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'end_col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r')
+ call assert_equal(1 , line('$'))
+ call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
+ call assert_equal([{'lnum': 10 , 'end_lnum': 0 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'end_col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , getqflist())
+
+ call setqflist([{'lnum': 10 , 'end_lnum': -123 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'end_col': -456 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r')
+ call assert_equal(1 , line('$'))
+ call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
+ call assert_equal([{'lnum': 10 , 'end_lnum': -123 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'end_col': -456 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , getqflist())
+
+ call setqflist([{'lnum': 10 , 'end_lnum': -123 , 'bufnr': bufnr('Xfile1') , 'col': 666 , 'end_col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r')
+ call assert_equal(1 , line('$'))
+ call assert_equal(['Xfile1|10 col 666| aa'] , getline(1 , '$'))
+ call assert_equal([{'lnum': 10 , 'end_lnum': -123 , 'bufnr': bufnr('Xfile1') , 'col': 666 , 'end_col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , getqflist())
+
+ call setqflist([{'lnum': 10 , 'end_lnum': -123 , 'bufnr': bufnr('Xfile1') , 'col': 666 , 'end_col': -456 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r')
+ call assert_equal(1 , line('$'))
+ call assert_equal(['Xfile1|10 col 666| aa'] , getline(1 , '$'))
+ call assert_equal([{'lnum': 10 , 'end_lnum': -123 , 'bufnr': bufnr('Xfile1') , 'col': 666 , 'end_col': -456 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , getqflist())
+
+ call setqflist([{'lnum': 10 , 'end_lnum': -123 , 'bufnr': bufnr('Xfile1') , 'col': 666 , 'end_col': 222 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r')
+ call assert_equal(1 , line('$'))
+ call assert_equal(['Xfile1|10 col 666-222| aa'] , getline(1 , '$'))
+ call assert_equal([{'lnum': 10 , 'end_lnum': -123 , 'bufnr': bufnr('Xfile1') , 'col': 666 , 'end_col': 222 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , getqflist())
+
+ call setqflist([{'lnum': 10 , 'end_lnum': 6 , 'bufnr': bufnr('Xfile1') , 'col': 666 , 'end_col': 222 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r')
+ call assert_equal(1 , line('$'))
+ call assert_equal(['Xfile1|10-6 col 666-222| aa'] , getline(1 , '$'))
+ call assert_equal([{'lnum': 10 , 'end_lnum': 6 , 'bufnr': bufnr('Xfile1') , 'col': 666 , 'end_col': 222 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , getqflist())
cclose
endfunc
@@ -5001,15 +5061,21 @@ func Xtest_qftextfunc(cchar)
call assert_equal('Tqfexpr', &quickfixtextfunc)
call assert_equal('',
\ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
- Xexpr ['F1:10:2:green', 'F1:20:4:blue']
+ call g:Xsetlist([
+ \ { 'filename': 'F1', 'lnum': 10, 'col': 2,
+ \ 'end_col': 7, 'text': 'green'},
+ \ { 'filename': 'F1', 'lnum': 20, 'end_lnum': 25, 'col': 4,
+ \ 'end_col': 8, 'text': 'blue'},
+ \ ])
+
Xwindow
call assert_equal('F1-L10C2-green', getline(1))
call assert_equal('F1-L20C4-blue', getline(2))
Xclose
set quickfixtextfunc&vim
Xwindow
- call assert_equal('F1|10 col 2| green', getline(1))
- call assert_equal('F1|20 col 4| blue', getline(2))
+ call assert_equal('F1|10 col 2-7| green', getline(1))
+ call assert_equal('F1|20-25 col 4-8| blue', getline(2))
Xclose
set efm&
set quickfixtextfunc&
@@ -5196,4 +5262,54 @@ func Test_qftextfunc_other_loclist()
%bw!
endfunc
+func Test_locationlist_open_in_newtab()
+ call s:create_test_file('Xqftestfile1')
+ call s:create_test_file('Xqftestfile2')
+ call s:create_test_file('Xqftestfile3')
+
+ %bwipe!
+
+ lgetexpr ['Xqftestfile1:5:Line5',
+ \ 'Xqftestfile2:10:Line10',
+ \ 'Xqftestfile3:16:Line16']
+
+ silent! llast
+ call assert_equal(1, tabpagenr('$'))
+ call assert_equal('Xqftestfile3', bufname())
+
+ set switchbuf=newtab
+
+ silent! lfirst
+ call assert_equal(2, tabpagenr('$'))
+ call assert_equal('Xqftestfile1', bufname())
+
+ silent! lnext
+ call assert_equal(3, tabpagenr('$'))
+ call assert_equal('Xqftestfile2', bufname())
+
+ call delete('Xqftestfile1')
+ call delete('Xqftestfile2')
+ call delete('Xqftestfile3')
+ set switchbuf&vim
+
+ %bwipe!
+endfunc
+
+" Test for win_gettype() in quickfix and location list windows
+func Test_win_gettype()
+ copen
+ call assert_equal("quickfix", win_gettype())
+ let wid = win_getid()
+ wincmd p
+ call assert_equal("quickfix", win_gettype(wid))
+ cclose
+ lexpr ''
+ lopen
+ call assert_equal("loclist", win_gettype())
+ let wid = win_getid()
+ wincmd p
+ call assert_equal("loclist", win_gettype(wid))
+ lclose
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_registers.vim b/src/nvim/testdir/test_registers.vim
index 53069b3d31..fd8653a2eb 100644
--- a/src/nvim/testdir/test_registers.vim
+++ b/src/nvim/testdir/test_registers.vim
@@ -283,4 +283,84 @@ func Test_insert_small_delete()
bwipe!
endfunc
+" Test for getting register info
+func Test_get_reginfo()
+ enew
+ call setline(1, ['foo', 'bar'])
+
+ exe 'norm! "zyy'
+ let info = getreginfo('"')
+ call assert_equal('z', info.points_to)
+ call setreg('y', 'baz')
+ call assert_equal('z', getreginfo('').points_to)
+ call setreg('y', { 'isunnamed': v:true })
+ call assert_equal('y', getreginfo('"').points_to)
+
+ exe '$put'
+ call assert_equal(getreg('y'), getline(3))
+ call setreg('', 'qux')
+ call assert_equal('0', getreginfo('').points_to)
+ call setreg('x', 'quux')
+ call assert_equal('0', getreginfo('').points_to)
+
+ let info = getreginfo('')
+ call assert_equal(getreg('', 1, 1), info.regcontents)
+ call assert_equal(getregtype(''), info.regtype)
+
+ exe "norm! 0\<c-v>e" .. '"zy'
+ let info = getreginfo('z')
+ call assert_equal(getreg('z', 1, 1), info.regcontents)
+ call assert_equal(getregtype('z'), info.regtype)
+ call assert_equal(1, +info.isunnamed)
+
+ let info = getreginfo('"')
+ call assert_equal('z', info.points_to)
+
+ bwipe!
+endfunc
+
+" Test for restoring register with dict from getreginfo
+func Test_set_register_dict()
+ enew!
+
+ call setreg('"', #{ regcontents: ['one', 'two'],
+ \ regtype: 'V', points_to: 'z' })
+ call assert_equal(['one', 'two'], getreg('"', 1, 1))
+ let info = getreginfo('"')
+ call assert_equal('z', info.points_to)
+ call assert_equal('V', info.regtype)
+ call assert_equal(1, +getreginfo('z').isunnamed)
+
+ call setreg('x', #{ regcontents: ['three', 'four'],
+ \ regtype: 'v', isunnamed: v:true })
+ call assert_equal(['three', 'four'], getreg('"', 1, 1))
+ let info = getreginfo('"')
+ call assert_equal('x', info.points_to)
+ call assert_equal('v', info.regtype)
+ call assert_equal(1, +getreginfo('x').isunnamed)
+
+ call setreg('y', #{ regcontents: 'five',
+ \ regtype: "\<c-v>", isunnamed: v:false })
+ call assert_equal("\<c-v>4", getreginfo('y').regtype)
+ call assert_equal(0, +getreginfo('y').isunnamed)
+ call assert_equal(['three', 'four'], getreg('"', 1, 1))
+ call assert_equal('x', getreginfo('"').points_to)
+
+ call setreg('"', #{ regcontents: 'six' })
+ call assert_equal('0', getreginfo('"').points_to)
+ call assert_equal(1, +getreginfo('0').isunnamed)
+ call assert_equal(['six'], getreginfo('0').regcontents)
+ call assert_equal(['six'], getreginfo('"').regcontents)
+
+ let @x = 'one'
+ call setreg('x', {})
+ call assert_equal(1, len(split(execute('reg x'), '\n')))
+
+ call assert_fails("call setreg('0', #{regtype: 'V'}, 'v')", 'E118:')
+ call assert_fails("call setreg('0', #{regtype: 'X'})", 'E475:')
+ call assert_fails("call setreg('0', #{regtype: 'vy'})", 'E475:')
+
+ bwipe!
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_rename.vim b/src/nvim/testdir/test_rename.vim
index e4228188bd..2311caf790 100644
--- a/src/nvim/testdir/test_rename.vim
+++ b/src/nvim/testdir/test_rename.vim
@@ -95,7 +95,6 @@ func Test_rename_copy()
endfunc
func Test_rename_fails()
- throw 'skipped: TODO: '
call writefile(['foo'], 'Xrenamefile')
" Can't rename into a non-existing directory.
diff --git a/src/nvim/testdir/test_spellfile.vim b/src/nvim/testdir/test_spellfile.vim
index 729467b556..0f48ab8f6f 100644
--- a/src/nvim/testdir/test_spellfile.vim
+++ b/src/nvim/testdir/test_spellfile.vim
@@ -210,6 +210,52 @@ func Test_spellfile_CHECKCOMPOUNDPATTERN()
call delete('XtestCHECKCOMPOUNDPATTERN-utf8.spl')
endfunc
+" Test NOCOMPOUNDSUGS (see :help spell-NOCOMPOUNDSUGS)
+func Test_spellfile_NOCOMPOUNDSUGS()
+ call writefile(['3',
+ \ 'one/c',
+ \ 'two/c',
+ \ 'three/c'], 'XtestNOCOMPOUNDSUGS.dic')
+
+ " pass 0 tests without NOCOMPOUNDSUGS, pass 1 tests with NOCOMPOUNDSUGS
+ for pass in [0, 1]
+ if pass == 0
+ call writefile(['COMPOUNDFLAG c'], 'XtestNOCOMPOUNDSUGS.aff')
+ else
+ call writefile(['NOCOMPOUNDSUGS',
+ \ 'COMPOUNDFLAG c'], 'XtestNOCOMPOUNDSUGS.aff')
+ endif
+
+ mkspell! XtestNOCOMPOUNDSUGS-utf8.spl XtestNOCOMPOUNDSUGS
+ set spell spelllang=XtestNOCOMPOUNDSUGS-utf8.spl
+
+ for goodword in ['one', 'two', 'three',
+ \ 'oneone', 'onetwo', 'onethree',
+ \ 'twoone', 'twotwo', 'twothree',
+ \ 'threeone', 'threetwo', 'threethree',
+ \ 'onetwothree', 'onethreetwo', 'twothreeone', 'oneoneone']
+ call assert_equal(['', ''], spellbadword(goodword), goodword)
+ endfor
+
+ for badword in ['four', 'onetwox', 'onexone']
+ call assert_equal([badword, 'bad'], spellbadword(badword))
+ endfor
+
+ if pass == 0
+ call assert_equal(['one', 'oneone'], spellsuggest('onne', 2))
+ call assert_equal(['onethree', 'one three'], spellsuggest('onethre', 2))
+ else
+ call assert_equal(['one', 'one one'], spellsuggest('onne', 2))
+ call assert_equal(['one three'], spellsuggest('onethre', 2))
+ endif
+ endfor
+
+ set spell& spelllang&
+ call delete('XtestNOCOMPOUNDSUGS.dic')
+ call delete('XtestNOCOMPOUNDSUGS.aff')
+ call delete('XtestNOCOMPOUNDSUGS-utf8.spl')
+endfunc
+
" Test COMMON (better suggestions with common words, see :help spell-COMMON)
func Test_spellfile_COMMON()
call writefile(['7',
diff --git a/src/nvim/testdir/test_startup.vim b/src/nvim/testdir/test_startup.vim
index e0dc0e0075..b140077111 100644
--- a/src/nvim/testdir/test_startup.vim
+++ b/src/nvim/testdir/test_startup.vim
@@ -27,8 +27,8 @@ func Test_after_comes_later()
set guioptions+=M
let $HOME = "/does/not/exist"
set loadplugins
- set rtp=Xhere,Xafter,Xanother
- set packpath=Xhere,Xafter
+ set rtp=Xhere,Xdir/after,Xanother
+ set packpath=Xhere,Xdir/after
set nomore
let g:sequence = ""
[CODE]
@@ -50,8 +50,8 @@ func Test_after_comes_later()
call mkdir('Xhere/pack/foo/start/foobar/plugin', 'p')
call writefile(['let g:sequence .= "pack "'], 'Xhere/pack/foo/start/foobar/plugin/foo.vim')
- call mkdir('Xafter/plugin', 'p')
- call writefile(['let g:sequence .= "after "'], 'Xafter/plugin/later.vim')
+ call mkdir('Xdir/after/plugin', 'p')
+ call writefile(['let g:sequence .= "after "'], 'Xdir/after/plugin/later.vim')
if RunVim(before, after, '')
@@ -74,7 +74,7 @@ func Test_after_comes_later()
call delete('Xsequence')
call delete('Xhere', 'rf')
call delete('Xanother', 'rf')
- call delete('Xafter', 'rf')
+ call delete('Xdir', 'rf')
endfunc
func Test_pack_in_rtp_when_plugins_run()
@@ -102,7 +102,7 @@ func Test_pack_in_rtp_when_plugins_run()
if RunVim(before, after, '')
let lines = filter(readfile('Xtestout'), '!empty(v:val)')
- call assert_match('Xhere[/\\]pack[/\\]foo[/\\]start[/\\]foobar', get(lines, 0))
+ call assert_match('runtimepath=Xhere', get(lines, 0))
call assert_match('autoloaded foo', get(lines, 1))
endif
diff --git a/src/nvim/testdir/test_swap.vim b/src/nvim/testdir/test_swap.vim
index f27920d20f..e3101d4e44 100644
--- a/src/nvim/testdir/test_swap.vim
+++ b/src/nvim/testdir/test_swap.vim
@@ -168,7 +168,6 @@ func Test_swapname()
endfunc
func Test_swapfile_delete()
- throw 'skipped: need the "blob" feature for this test'
autocmd! SwapExists
function s:swap_exists()
let v:swapchoice = s:swap_choice
@@ -319,6 +318,7 @@ func Test_swap_prompt_splitwin()
let buf = RunVimInTerminal('', {'rows': 20})
call term_sendkeys(buf, ":set nomore\n")
call term_sendkeys(buf, ":set noruler\n")
+
call term_sendkeys(buf, ":split Xfile1\n")
call term_wait(buf)
call WaitForAssert({-> assert_match('^\[O\]pen Read-Only, (E)dit anyway, (R)ecover, (Q)uit, (A)bort: $', term_getline(buf, 20))})
@@ -330,8 +330,19 @@ func Test_swap_prompt_splitwin()
call term_wait(buf)
call WaitForAssert({-> assert_match('^1$', term_getline(buf, 20))})
call StopVimInTerminal(buf)
+
+ " This caused Vim to crash when typing "q".
+ " TODO: it does not actually reproduce the crash.
+ call writefile(['au BufAdd * set virtualedit=all'], 'Xvimrc')
+
+ let buf = RunVimInTerminal('-u Xvimrc Xfile1', {'rows': 20, 'wait_for_ruler': 0})
+ call TermWait(buf)
+ call WaitForAssert({-> assert_match('^\[O\]pen Read-Only, (E)dit anyway, (R)ecover, (Q)uit, (A)bort:', term_getline(buf, 20))})
+ call term_sendkeys(buf, "q")
+
%bwipe!
call delete('Xfile1')
+ call delete('Xvimrc')
endfunc
func Test_swap_symlink()
@@ -364,4 +375,8 @@ func Test_swap_symlink()
call delete('Xswapdir', 'rf')
endfunc
+func Test_no_swap_file()
+ call assert_equal("\nNo swap file", execute('swapname'))
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_syntax.vim b/src/nvim/testdir/test_syntax.vim
index 875e23894f..914d9c2782 100644
--- a/src/nvim/testdir/test_syntax.vim
+++ b/src/nvim/testdir/test_syntax.vim
@@ -116,7 +116,7 @@ func Test_syntime()
let a = execute('syntime report')
call assert_equal("\nNo Syntax items defined for this buffer", a)
- view ../memfile_test.c
+ view samples/memfile_test.c
setfiletype cpp
redraw
let a = execute('syntime report')
@@ -546,8 +546,8 @@ func Test_synstack_synIDtrans()
call assert_equal([], synstack(1, 1))
norm f/
- call assert_equal(['cComment', 'cCommentStart'], map(synstack(line("."), col(".")), 'synIDattr(v:val, "name")'))
- call assert_equal(['Comment', 'Comment'], map(synstack(line("."), col(".")), 'synIDattr(synIDtrans(v:val), "name")'))
+ eval synstack(line("."), col("."))->map('synIDattr(v:val, "name")')->assert_equal(['cComment', 'cCommentStart'])
+ eval synstack(line("."), col("."))->map('synIDattr(synIDtrans(v:val), "name")')->assert_equal(['Comment', 'Comment'])
norm fA
call assert_equal(['cComment'], map(synstack(line("."), col(".")), 'synIDattr(v:val, "name")'))
diff --git a/src/nvim/testdir/test_system.vim b/src/nvim/testdir/test_system.vim
index 6bbe714d19..7b8ee778cc 100644
--- a/src/nvim/testdir/test_system.vim
+++ b/src/nvim/testdir/test_system.vim
@@ -7,10 +7,10 @@ func Test_System()
if !executable('echo') || !executable('cat') || !executable('wc')
return
endif
- let out = system('echo 123')
+ let out = 'echo 123'->system()
call assert_equal("123\n", out)
- let out = systemlist('echo 123')
+ let out = 'echo 123'->systemlist()
if &shell =~# 'cmd.exe$'
call assert_equal(["123\r"], out)
else
diff --git a/src/nvim/testdir/test_tagjump.vim b/src/nvim/testdir/test_tagjump.vim
index 9f02af7d8e..0fa7f85f0d 100644
--- a/src/nvim/testdir/test_tagjump.vim
+++ b/src/nvim/testdir/test_tagjump.vim
@@ -170,7 +170,7 @@ func Test_tag_symbolic()
call assert_equal('Xtest.c', expand('%:t'))
call assert_equal(2, col('.'))
- set hidden&
+ set nohidden
set tags&
enew!
call delete('Xtags')
@@ -548,6 +548,16 @@ func Test_tag_line_toolong()
call assert_equal('Xsomewhere', expand('%'))
call assert_equal(3, getcurpos()[1])
+ " expansion on command line works with long lines when &wildoptions contains
+ " 'tagfile'
+ set wildoptions=tagfile
+ call writefile([
+ \ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa file /^pattern$/;" f'
+ \ ], 'Xtags')
+ call feedkeys(":tag \<Tab>", 'tx')
+ " Should not crash
+ call assert_true(v:true)
+
call delete('Xtags')
call delete('Xsomewhere')
set tags&
@@ -771,15 +781,16 @@ func Test_ltag()
ltag third
call assert_equal('Xfoo', bufname(''))
call assert_equal(3, line('.'))
- call assert_equal([{'lnum': 3, 'bufnr': bufnr('Xfoo'), 'col': 0,
- \ 'pattern': '', 'valid': 1, 'vcol': 0, 'nr': 0, 'type': '',
- \ 'module': '', 'text': 'third'}], getloclist(0))
+ call assert_equal([{'lnum': 3, 'end_lnum': 0, 'bufnr': bufnr('Xfoo'),
+ \ 'col': 0, 'end_col': 0, 'pattern': '', 'valid': 1, 'vcol': 0,
+ \ 'nr': 0, 'type': '', 'module': '', 'text': 'third'}], getloclist(0))
ltag second
call assert_equal(2, line('.'))
- call assert_equal([{'lnum': 0, 'bufnr': bufnr('Xfoo'), 'col': 0,
- \ 'pattern': '^\Vint second() {}\$', 'valid': 1, 'vcol': 0, 'nr': 0,
- \ 'type': '', 'module': '', 'text': 'second'}], getloclist(0))
+ call assert_equal([{'lnum': 0, 'end_lnum': 0, 'bufnr': bufnr('Xfoo'),
+ \ 'col': 0, 'end_col': 0, 'pattern': '^\Vint second() {}\$',
+ \ 'valid': 1, 'vcol': 0, 'nr': 0, 'type': '', 'module': '',
+ \ 'text': 'second'}], getloclist(0))
call delete('Xtags')
call delete('Xfoo')
diff --git a/src/nvim/testdir/test_textformat.vim b/src/nvim/testdir/test_textformat.vim
index 29f0433954..bf0706a0c2 100644
--- a/src/nvim/testdir/test_textformat.vim
+++ b/src/nvim/testdir/test_textformat.vim
@@ -975,6 +975,13 @@ func Test_fo_a_w()
exe "normal f4xx"
call assert_equal(['1 2 5 6 7 ', '8 9'], getline(1, 2))
+ " using "cw" leaves cursor in right spot
+ call setline(1, ['Now we g whether that nation, or',
+ \ 'any nation so conceived and,'])
+ set fo=tcqa tw=35
+ exe "normal 2G0cwx\<Esc>"
+ call assert_equal(['Now we g whether that nation, or x', 'nation so conceived and,'], getline(1, 2))
+
set tw=0
set fo&
%bw!
diff --git a/src/nvim/testdir/test_textobjects.vim b/src/nvim/testdir/test_textobjects.vim
index 9b800d0fa9..c259453b5e 100644
--- a/src/nvim/testdir/test_textobjects.vim
+++ b/src/nvim/testdir/test_textobjects.vim
@@ -89,101 +89,109 @@ endfunc
" Tests for string and html text objects
func Test_string_html_objects()
- enew!
- let t = '"wo\"rd\\" foo'
- put =t
- normal! da"
- call assert_equal('foo', getline('.'))
-
- let t = "'foo' 'bar' 'piep'"
- put =t
- normal! 0va'a'rx
- call assert_equal("xxxxxxxxxxxx'piep'", getline('.'))
-
- let t = "bla bla `quote` blah"
- put =t
- normal! 02f`da`
- call assert_equal("bla bla blah", getline('.'))
-
- let t = 'out " in "noXno"'
- put =t
- normal! 0fXdi"
- call assert_equal('out " in ""', getline('.'))
-
- let t = "\"'\" 'blah' rep 'buh'"
- put =t
- normal! 03f'vi'ry
- call assert_equal("\"'\" 'blah'yyyyy'buh'", getline('.'))
-
- set quoteescape=+*-
- let t = "bla `s*`d-`+++`l**` b`la"
- put =t
- normal! di`
- call assert_equal("bla `` b`la", getline('.'))
-
- let t = 'voo "nah" sdf " asdf" sdf " sdf" sd'
- put =t
- normal! $F"va"oha"i"rz
- call assert_equal('voo "zzzzzzzzzzzzzzzzzzzzzzzzzzzzsd', getline('.'))
-
- let t = "-<b>asdf<i>Xasdf</i>asdf</b>-"
- put =t
- normal! fXdit
- call assert_equal('-<b>asdf<i></i>asdf</b>-', getline('.'))
-
- let t = "-<b>asdX<i>a<i />sdf</i>asdf</b>-"
- put =t
- normal! 0fXdit
- call assert_equal('-<b></b>-', getline('.'))
-
- let t = "-<b>asdf<i>Xasdf</i>asdf</b>-"
- put =t
- normal! fXdat
- call assert_equal('-<b>asdfasdf</b>-', getline('.'))
-
- let t = "-<b>asdX<i>as<b />df</i>asdf</b>-"
- put =t
- normal! 0fXdat
- call assert_equal('--', getline('.'))
-
- let t = "-<b>\ninnertext object\n</b>"
- put =t
- normal! dit
- call assert_equal('-<b></b>', getline('.'))
-
- " copy the tag block from leading indentation before the start tag
- let t = " <b>\ntext\n</b>"
- $put =t
- normal! 2kvaty
- call assert_equal("<b>\ntext\n</b>", @")
-
- " copy the tag block from the end tag
- let t = "<title>\nwelcome\n</title>"
- $put =t
- normal! $vaty
- call assert_equal("<title>\nwelcome\n</title>", @")
-
- " copy the outer tag block from a tag without an end tag
- let t = "<html>\n<title>welcome\n</html>"
- $put =t
- normal! k$vaty
- call assert_equal("<html>\n<title>welcome\n</html>", @")
-
- " nested tag that has < in a different line from >
- let t = "<div><div\n></div></div>"
- $put =t
- normal! k0vaty
- call assert_equal("<div><div\n></div></div>", @")
-
- " nested tag with attribute that has < in a different line from >
- let t = "<div><div\nattr=\"attr\"\n></div></div>"
- $put =t
- normal! 2k0vaty
- call assert_equal("<div><div\nattr=\"attr\"\n></div></div>", @")
-
- set quoteescape&
- enew!
+ " Nvim only supports set encoding=utf-8
+ " for e in ['utf-8', 'latin1', 'cp932']
+ for e in ['utf-8']
+ enew!
+ exe 'set enc=' .. e
+
+ let t = '"wo\"rd\\" foo'
+ put =t
+ normal! da"
+ call assert_equal('foo', getline('.'), e)
+
+ let t = "'foo' 'bar' 'piep'"
+ put =t
+ normal! 0va'a'rx
+ call assert_equal("xxxxxxxxxxxx'piep'", getline('.'), e)
+
+ let t = "bla bla `quote` blah"
+ put =t
+ normal! 02f`da`
+ call assert_equal("bla bla blah", getline('.'), e)
+
+ let t = 'out " in "noXno"'
+ put =t
+ normal! 0fXdi"
+ call assert_equal('out " in ""', getline('.'), e)
+
+ let t = "\"'\" 'blah' rep 'buh'"
+ put =t
+ normal! 03f'vi'ry
+ call assert_equal("\"'\" 'blah'yyyyy'buh'", getline('.'), e)
+
+ set quoteescape=+*-
+ let t = "bla `s*`d-`+++`l**` b`la"
+ put =t
+ normal! di`
+ call assert_equal("bla `` b`la", getline('.'), e)
+
+ let t = 'voo "nah" sdf " asdf" sdf " sdf" sd'
+ put =t
+ normal! $F"va"oha"i"rz
+ call assert_equal('voo "zzzzzzzzzzzzzzzzzzzzzzzzzzzzsd', getline('.'), e)
+
+ let t = "-<b>asdf<i>Xasdf</i>asdf</b>-"
+ put =t
+ normal! fXdit
+ call assert_equal('-<b>asdf<i></i>asdf</b>-', getline('.'), e)
+
+ let t = "-<b>asdX<i>a<i />sdf</i>asdf</b>-"
+ put =t
+ normal! 0fXdit
+ call assert_equal('-<b></b>-', getline('.'), e)
+
+ let t = "-<b>asdf<i>Xasdf</i>asdf</b>-"
+ put =t
+ normal! fXdat
+ call assert_equal('-<b>asdfasdf</b>-', getline('.'), e)
+
+ let t = "-<b>asdX<i>as<b />df</i>asdf</b>-"
+ put =t
+ normal! 0fXdat
+ call assert_equal('--', getline('.'), e)
+
+ let t = "-<b>\ninnertext object\n</b>"
+ put =t
+ normal! dit
+ call assert_equal('-<b></b>', getline('.'), e)
+
+ " copy the tag block from leading indentation before the start tag
+ let t = " <b>\ntext\n</b>"
+ $put =t
+ normal! 2kvaty
+ call assert_equal("<b>\ntext\n</b>", @", e)
+
+ " copy the tag block from the end tag
+ let t = "<title>\nwelcome\n</title>"
+ $put =t
+ normal! $vaty
+ call assert_equal("<title>\nwelcome\n</title>", @", e)
+
+ " copy the outer tag block from a tag without an end tag
+ let t = "<html>\n<title>welcome\n</html>"
+ $put =t
+ normal! k$vaty
+ call assert_equal("<html>\n<title>welcome\n</html>", @", e)
+
+ " nested tag that has < in a different line from >
+ let t = "<div><div\n></div></div>"
+ $put =t
+ normal! k0vaty
+ call assert_equal("<div><div\n></div></div>", @", e)
+
+ " nested tag with attribute that has < in a different line from >
+ let t = "<div><div\nattr=\"attr\"\n></div></div>"
+ $put =t
+ normal! 2k0vaty
+ call assert_equal("<div><div\nattr=\"attr\"\n></div></div>", @", e)
+
+ set quoteescape&
+ endfor
+
+ set enc=utf-8
+ bwipe!
endfunc
func Test_empty_html_tag()
@@ -333,3 +341,84 @@ func Test_sentence_with_cursor_on_delimiter()
%delete _
endfunc
+
+" Test for quote (', " and `) textobjects
+func Test_textobj_quote()
+ new
+
+ " Test for i" when cursor is in front of a quoted object
+ call append(0, 'foo "bar"')
+ norm! 1gg0di"
+ call assert_equal(['foo ""', ''], getline(1,'$'))
+
+ " Test for visually selecting an inner quote
+ %d
+ " extend visual selection from one quote to the next
+ call setline(1, 'color "red" color "blue"')
+ call cursor(1, 7)
+ normal v4li"y
+ call assert_equal('"red" color "blue', @")
+
+ " try to extend visual selection from one quote to a non-existing quote
+ call setline(1, 'color "red" color blue')
+ call cursor(1, 7)
+ call feedkeys('v4li"y', 'xt')
+ call assert_equal('"red"', @")
+
+ " try to extend visual selection from one quote to a next partial quote
+ call setline(1, 'color "red" color "blue')
+ call cursor(1, 7)
+ normal v4li"y
+ call assert_equal('"red" color ', @")
+
+ " select a quote backwards in visual mode
+ call cursor(1, 12)
+ normal vhi"y
+ call assert_equal('red" ', @")
+ call assert_equal(8, col('.'))
+
+ " select a quote backwards in visual mode from outside the quote
+ call cursor(1, 17)
+ normal v2hi"y
+ call assert_equal('red', @")
+ call assert_equal(8, col('.'))
+
+ " visually selecting a quote with 'selection' set to 'exclusive'
+ call setline(1, 'He said "How are you?"')
+ set selection=exclusive
+ normal 012lv2li"y
+ call assert_equal('How are you?', @")
+ set selection&
+
+ " try copy a quote object with a single quote in the line
+ call setline(1, "Smith's car")
+ call cursor(1, 6)
+ call assert_beeps("normal yi'")
+ call assert_beeps("normal 2lyi'")
+
+ " selecting space before and after a quoted string
+ call setline(1, "some 'special' string")
+ normal 0ya'
+ call assert_equal("'special' ", @")
+ call setline(1, "some 'special'string")
+ normal 0ya'
+ call assert_equal(" 'special'", @")
+
+ " quoted string with odd or even number of backslashes.
+ call setline(1, 'char *s = "foo\"bar"')
+ normal $hhyi"
+ call assert_equal('foo\"bar', @")
+ call setline(1, 'char *s = "foo\\"bar"')
+ normal $hhyi"
+ call assert_equal('bar', @")
+ call setline(1, 'char *s = "foo\\\"bar"')
+ normal $hhyi"
+ call assert_equal('foo\\\"bar', @")
+ call setline(1, 'char *s = "foo\\\\"bar"')
+ normal $hhyi"
+ call assert_equal('bar', @")
+
+ close!
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_undo.vim b/src/nvim/testdir/test_undo.vim
index 54caed3983..c7dcaa0f36 100644
--- a/src/nvim/testdir/test_undo.vim
+++ b/src/nvim/testdir/test_undo.vim
@@ -368,7 +368,6 @@ endfunc
" Check that reading a truncted undo file doesn't hang.
func Test_undofile_truncated()
- throw 'skipped: TODO: '
new
call setline(1, 'hello')
set ul=100
diff --git a/src/nvim/testdir/test_user_func.vim b/src/nvim/testdir/test_user_func.vim
index 7dcd92a54b..5231ef7b4f 100644
--- a/src/nvim/testdir/test_user_func.vim
+++ b/src/nvim/testdir/test_user_func.vim
@@ -47,7 +47,7 @@ func FuncWithRef(a)
endfunc
func Test_user_func()
- let g:FuncRef=function("FuncWithRef")
+ let g:FuncRef = function("FuncWithRef")
let g:counter = 0
inoremap <expr> ( ListItem()
inoremap <expr> [ ListReset()
@@ -62,6 +62,14 @@ func Test_user_func()
call assert_equal(9, g:retval)
call assert_equal(333, g:FuncRef(333))
+ let g:retval = "nop"
+ call assert_equal('xxx4asdf', "xxx"->Table(4, "asdf"))
+ call assert_equal('fail', 45->Compute(0, "retval"))
+ call assert_equal('nop', g:retval)
+ call assert_equal('ok', 45->Compute(5, "retval"))
+ call assert_equal(9, g:retval)
+ " call assert_equal(333, 333->g:FuncRef())
+
enew
normal oXX+-XX
@@ -150,6 +158,14 @@ func Test_default_arg()
\ execute('func Args2'))
endfunc
+func s:addFoo(lead)
+ return a:lead .. 'foo'
+endfunc
+
+func Test_user_method()
+ eval 'bar'->s:addFoo()->assert_equal('barfoo')
+endfunc
+
func Test_failed_call_in_try()
try | call UnknownFunc() | catch | endtry
endfunc
diff --git a/src/nvim/testdir/test_usercommands.vim b/src/nvim/testdir/test_usercommands.vim
index 4621207d19..29e578ac6d 100644
--- a/src/nvim/testdir/test_usercommands.vim
+++ b/src/nvim/testdir/test_usercommands.vim
@@ -238,6 +238,8 @@ func Test_CmdErrors()
call assert_fails('com! -complete=custom DoCmd :', 'E467:')
call assert_fails('com! -complete=customlist DoCmd :', 'E467:')
call assert_fails('com! -complete=behave,CustomComplete DoCmd :', 'E468:')
+ call assert_fails('com! -complete=file DoCmd :', 'E1208:')
+ call assert_fails('com! -nargs=0 -complete=file DoCmd :', 'E1208:')
call assert_fails('com! -nargs=x DoCmd :', 'E176:')
call assert_fails('com! -count=1 -count=2 DoCmd :', 'E177:')
call assert_fails('com! -count=x DoCmd :', 'E178:')
@@ -306,27 +308,33 @@ func Test_CmdCompletion()
call feedkeys(":com DoC\<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"com DoC', @:)
- com! -complete=behave DoCmd :
+ com! -nargs=1 -complete=behave DoCmd :
call feedkeys(":DoCmd \<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"DoCmd mswin xterm', @:)
- " This does not work. Why?
- "call feedkeys(":DoCmd x\<C-A>\<C-B>\"\<CR>", 'tx')
- "call assert_equal('"DoCmd xterm', @:)
-
- com! -complete=custom,CustomComplete DoCmd :
+ com! -nargs=* -complete=custom,CustomComplete DoCmd :
call feedkeys(":DoCmd \<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"DoCmd January February Mars', @:)
- com! -complete=customlist,CustomCompleteList DoCmd :
+ com! -nargs=? -complete=customlist,CustomCompleteList DoCmd :
call feedkeys(":DoCmd \<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"DoCmd Monday Tuesday Wednesday', @:)
- com! -complete=custom,CustomCompleteList DoCmd :
+ com! -nargs=+ -complete=custom,CustomCompleteList DoCmd :
call assert_fails("call feedkeys(':DoCmd \<C-D>', 'tx')", 'E730:')
- com! -complete=customlist,CustomComp DoCmd :
+ com! -nargs=+ -complete=customlist,CustomComp DoCmd :
call assert_fails("call feedkeys(':DoCmd \<C-D>', 'tx')", 'E117:')
+
+ " custom completion without a function
+ com! -nargs=? -complete=custom, DoCmd
+ call assert_beeps("call feedkeys(':DoCmd \t', 'tx')")
+
+ " custom completion failure with the wrong function
+ com! -nargs=? -complete=custom,min DoCmd
+ call assert_fails("call feedkeys(':DoCmd \t', 'tx')", 'E118:')
+
+ delcom DoCmd
endfunc
func CallExecute(A, L, P)
@@ -459,21 +467,21 @@ func Test_command_list()
\ execute('command DoCmd'))
" Test with various -complete= argument values (non-exhaustive list)
- command! -complete=arglist DoCmd :
+ command! -nargs=1 -complete=arglist DoCmd :
call assert_equal("\n Name Args Address Complete Definition"
- \ .. "\n DoCmd 0 arglist :",
+ \ .. "\n DoCmd 1 arglist :",
\ execute('command DoCmd'))
- command! -complete=augroup DoCmd :
+ command! -nargs=* -complete=augroup DoCmd :
call assert_equal("\n Name Args Address Complete Definition"
- \ .. "\n DoCmd 0 augroup :",
+ \ .. "\n DoCmd * augroup :",
\ execute('command DoCmd'))
- command! -complete=custom,CustomComplete DoCmd :
+ command! -nargs=? -complete=custom,CustomComplete DoCmd :
call assert_equal("\n Name Args Address Complete Definition"
- \ .. "\n DoCmd 0 custom :",
+ \ .. "\n DoCmd ? custom :",
\ execute('command DoCmd'))
- command! -complete=customlist,CustomComplete DoCmd :
+ command! -nargs=+ -complete=customlist,CustomComplete DoCmd :
call assert_equal("\n Name Args Address Complete Definition"
- \ .. "\n DoCmd 0 customlist :",
+ \ .. "\n DoCmd + customlist :",
\ execute('command DoCmd'))
" Test with various -narg= argument values.
diff --git a/src/nvim/testdir/test_utf8.vim b/src/nvim/testdir/test_utf8.vim
index c51fb3a759..735efac36d 100644
--- a/src/nvim/testdir/test_utf8.vim
+++ b/src/nvim/testdir/test_utf8.vim
@@ -1,5 +1,6 @@
" Tests for Unicode manipulations
+source view_util.vim
" Visual block Insert adjusts for multi-byte char
func Test_visual_block_insert()
@@ -61,6 +62,40 @@ func Test_getvcol()
call assert_equal(2, virtcol("']"))
endfunc
+func Test_screenchar_utf8()
+ new
+
+ " 1-cell, with composing characters
+ call setline(1, ["ABC\u0308"])
+ redraw
+ call assert_equal([0x0041], screenchars(1, 1))
+ call assert_equal([0x0042], screenchars(1, 2))
+ call assert_equal([0x0043, 0x0308], screenchars(1, 3))
+ call assert_equal("A", screenstring(1, 1))
+ call assert_equal("B", screenstring(1, 2))
+ call assert_equal("C\u0308", screenstring(1, 3))
+
+ " 2-cells, with composing characters
+ let text = "\u3042\u3044\u3046\u3099"
+ call setline(1, text)
+ redraw
+ call assert_equal([0x3042], screenchars(1, 1))
+ call assert_equal([0], screenchars(1, 2))
+ call assert_equal([0x3044], screenchars(1, 3))
+ call assert_equal([0], screenchars(1, 4))
+ call assert_equal([0x3046, 0x3099], screenchars(1, 5))
+
+ call assert_equal("\u3042", screenstring(1, 1))
+ call assert_equal("", screenstring(1, 2))
+ call assert_equal("\u3044", screenstring(1, 3))
+ call assert_equal("", screenstring(1, 4))
+ call assert_equal("\u3046\u3099", screenstring(1, 5))
+
+ call assert_equal([text . ' '], ScreenLines(1, 8))
+
+ bwipe!
+endfunc
+
func Test_list2str_str2list_utf8()
" One Unicode codepoint
let s = "\u3042\u3044"
diff --git a/src/nvim/testdir/test_vimscript.vim b/src/nvim/testdir/test_vimscript.vim
index 5922660ef9..b18ce563d3 100644
--- a/src/nvim/testdir/test_vimscript.vim
+++ b/src/nvim/testdir/test_vimscript.vim
@@ -1152,6 +1152,10 @@ func Test_type()
call assert_equal(v:t_float, type(0.0))
call assert_equal(v:t_bool, type(v:false))
call assert_equal(v:t_bool, type(v:true))
+ call assert_equal(v:t_string, type(v:_null_string))
+ call assert_equal(v:t_list, type(v:_null_list))
+ call assert_equal(v:t_dict, type(v:_null_dict))
+ call assert_equal(v:t_blob, type(v:_null_blob))
endfunc
"-------------------------------------------------------------------------------
@@ -1372,6 +1376,7 @@ func Test_bitwise_functions()
" and
call assert_equal(127, and(127, 127))
call assert_equal(16, and(127, 16))
+ eval 127->and(16)->assert_equal(16)
call assert_equal(0, and(127, 128))
call assert_fails("call and(1.0, 1)", 'E805:')
call assert_fails("call and([], 1)", 'E745:')
@@ -1382,6 +1387,7 @@ func Test_bitwise_functions()
" or
call assert_equal(23, or(16, 7))
call assert_equal(15, or(8, 7))
+ eval 8->or(7)->assert_equal(15)
call assert_equal(123, or(0, 123))
call assert_fails("call or(1.0, 1)", 'E805:')
call assert_fails("call or([], 1)", 'E745:')
@@ -1392,6 +1398,7 @@ func Test_bitwise_functions()
" xor
call assert_equal(0, xor(127, 127))
call assert_equal(111, xor(127, 16))
+ eval 127->xor(16)->assert_equal(111)
call assert_equal(255, xor(127, 128))
call assert_fails("call xor(1.0, 1)", 'E805:')
call assert_fails("call xor([], 1)", 'E745:')
@@ -1401,6 +1408,7 @@ func Test_bitwise_functions()
call assert_fails("call xor(1, {})", 'E728:')
" invert
call assert_equal(65408, and(invert(127), 65535))
+ eval 127->invert()->and(65535)->assert_equal(65408)
call assert_equal(65519, and(invert(16), 65535))
call assert_equal(65407, and(invert(128), 65535))
call assert_fails("call invert(1.0)", 'E805:')
diff --git a/src/nvim/testdir/test_visual.vim b/src/nvim/testdir/test_visual.vim
index b7c5717bd2..dbabdcf427 100644
--- a/src/nvim/testdir/test_visual.vim
+++ b/src/nvim/testdir/test_visual.vim
@@ -2,6 +2,7 @@
source shared.vim
source check.vim
+source screendump.vim
func Test_block_shift_multibyte()
" Uses double-wide character.
@@ -860,6 +861,15 @@ func Test_visual_block_mode()
set tabstop& shiftwidth&
endfunc
+func Test_visual_force_motion_feedkeys()
+ onoremap <expr> i- execute('let g:mode = mode(1)')
+ call feedkeys('dvi-', 'x')
+ call assert_equal('nov', g:mode)
+ call feedkeys('di-', 'x')
+ call assert_equal('no', g:mode)
+ ounmap i-
+endfunc
+
" Test block-insert using cursor keys for movement
func Test_visual_block_insert_cursor_keys()
new
@@ -1082,5 +1092,25 @@ func Test_visual_put_blockedit_zy_and_zp()
bw!
endfunc
+func Test_visual_block_with_virtualedit()
+ CheckScreendump
+
+ let lines =<< trim END
+ call setline(1, ['aaaaaa', 'bbbb', 'cc'])
+ set virtualedit=block
+ normal G
+ END
+ call writefile(lines, 'XTest_block')
+
+ let buf = RunVimInTerminal('-S XTest_block', {'rows': 8, 'cols': 50})
+ call term_sendkeys(buf, "\<C-V>gg$")
+ call VerifyScreenDump(buf, 'Test_visual_block_with_virtualedit', {})
+
+ " clean up
+ call term_sendkeys(buf, "\<Esc>")
+ call StopVimInTerminal(buf)
+ call delete('XTest_beval')
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_window_cmd.vim b/src/nvim/testdir/test_window_cmd.vim
index a522705238..039de0c623 100644
--- a/src/nvim/testdir/test_window_cmd.vim
+++ b/src/nvim/testdir/test_window_cmd.vim
@@ -608,7 +608,7 @@ func Test_window_prevwin()
" reset
q
call delete('tmp.txt')
- set hidden&vim autoread&vim
+ set nohidden autoread&vim
delfunc Fun_RenewFile
endfunc
diff --git a/src/nvim/testdir/test_writefile.vim b/src/nvim/testdir/test_writefile.vim
index 6922e2185d..aa7882d129 100644
--- a/src/nvim/testdir/test_writefile.vim
+++ b/src/nvim/testdir/test_writefile.vim
@@ -17,6 +17,8 @@ func Test_writefile()
call assert_equal("morning", l[3])
call assert_equal("vimmers", l[4])
call delete(f)
+
+ call assert_fails('call writefile("text", "Xfile")', 'E475: Invalid argument: writefile() first argument must be a List or a Blob')
endfunc
func Test_writefile_ignore_regexp_error()
@@ -189,6 +191,14 @@ func Test_saveas()
close!
enew | only
call delete('Xfile')
+
+ " :saveas should detect and set the file type.
+ syntax on
+ saveas! Xsaveas.pl
+ call assert_equal('perl', &filetype)
+ syntax off
+ %bw!
+ call delete('Xsaveas.pl')
endfunc
func Test_write_errors()
diff --git a/src/nvim/testdir/view_util.vim b/src/nvim/testdir/view_util.vim
index 1def201a05..1cdce21602 100644
--- a/src/nvim/testdir/view_util.vim
+++ b/src/nvim/testdir/view_util.vim
@@ -16,6 +16,7 @@ func Screenline(lnum)
return matchstr(line, '^.\{-}\ze\s*$')
endfunc
+" Get text on the screen, including composing characters.
" ScreenLines(lnum, width) or
" ScreenLines([start, end], width)
function! ScreenLines(lnum, width) abort
@@ -29,7 +30,7 @@ function! ScreenLines(lnum, width) abort
endif
let lines = []
for l in range(start, end)
- let lines += [join(map(range(1, a:width), 'nr2char(screenchar(l, v:val))'), '')]
+ let lines += [join(map(range(1, a:width), 'screenstring(l, v:val)'), '')]
endfor
return lines
endfunction
diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c
index 6705ab98c2..ec277f7a4e 100644
--- a/src/nvim/tui/input.c
+++ b/src/nvim/tui/input.c
@@ -2,19 +2,19 @@
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
-#include "nvim/tui/input.h"
-#include "nvim/vim.h"
-#include "nvim/api/vim.h"
#include "nvim/api/private/helpers.h"
+#include "nvim/api/vim.h"
#include "nvim/ascii.h"
-#include "nvim/charset.h"
-#include "nvim/main.h"
-#include "nvim/macros.h"
#include "nvim/aucmd.h"
+#include "nvim/charset.h"
#include "nvim/ex_docmd.h"
+#include "nvim/macros.h"
+#include "nvim/main.h"
#include "nvim/option.h"
-#include "nvim/os/os.h"
#include "nvim/os/input.h"
+#include "nvim/os/os.h"
+#include "nvim/tui/input.h"
+#include "nvim/vim.h"
#ifdef WIN32
# include "nvim/os/os_win_console.h"
#endif
@@ -53,7 +53,7 @@ void tinput_init(TermInput *input, Loop *loop)
// ls *.md | xargs nvim
#ifdef WIN32
if (!os_isatty(input->in_fd)) {
- input->in_fd = os_get_conin_fd();
+ input->in_fd = os_get_conin_fd();
}
#else
if (!os_isatty(input->in_fd) && os_isatty(STDERR_FILENO)) {
@@ -279,25 +279,25 @@ static void forward_mouse_event(TermInput *input, TermKeyKey *key)
}
switch (ev) {
- case TERMKEY_MOUSE_PRESS:
- if (button == 4) {
- len += (size_t)snprintf(buf + len, sizeof(buf) - len, "ScrollWheelUp");
- } else if (button == 5) {
- len += (size_t)snprintf(buf + len, sizeof(buf) - len,
- "ScrollWheelDown");
- } else {
- len += (size_t)snprintf(buf + len, sizeof(buf) - len, "Mouse");
- last_pressed_button = button;
- }
- break;
- case TERMKEY_MOUSE_DRAG:
- len += (size_t)snprintf(buf + len, sizeof(buf) - len, "Drag");
- break;
- case TERMKEY_MOUSE_RELEASE:
- len += (size_t)snprintf(buf + len, sizeof(buf) - len, "Release");
- break;
- case TERMKEY_MOUSE_UNKNOWN:
- abort();
+ case TERMKEY_MOUSE_PRESS:
+ if (button == 4) {
+ len += (size_t)snprintf(buf + len, sizeof(buf) - len, "ScrollWheelUp");
+ } else if (button == 5) {
+ len += (size_t)snprintf(buf + len, sizeof(buf) - len,
+ "ScrollWheelDown");
+ } else {
+ len += (size_t)snprintf(buf + len, sizeof(buf) - len, "Mouse");
+ last_pressed_button = button;
+ }
+ break;
+ case TERMKEY_MOUSE_DRAG:
+ len += (size_t)snprintf(buf + len, sizeof(buf) - len, "Drag");
+ break;
+ case TERMKEY_MOUSE_RELEASE:
+ len += (size_t)snprintf(buf + len, sizeof(buf) - len, "Release");
+ break;
+ case TERMKEY_MOUSE_UNKNOWN:
+ abort();
}
len += (size_t)snprintf(buf + len, sizeof(buf) - len, "><%d,%d>", col, row);
@@ -428,7 +428,7 @@ static bool handle_forced_escape(TermInput *input)
// skip the ESC and NUL and push one <esc> to the input buffer
size_t rcnt;
termkey_push_bytes(input->tk, rbuffer_read_ptr(input->read_stream.buffer,
- &rcnt), 1);
+ &rcnt), 1);
rbuffer_consumed(input->read_stream.buffer, 2);
tk_getkeys(input, true);
return true;
@@ -618,8 +618,7 @@ static void handle_raw_buffer(TermInput *input, bool force)
} while (rbuffer_size(input->read_stream.buffer));
}
-static void tinput_read_cb(Stream *stream, RBuffer *buf, size_t count_,
- void *data, bool eof)
+static void tinput_read_cb(Stream *stream, RBuffer *buf, size_t count_, void *data, bool eof)
{
TermInput *input = data;
@@ -637,7 +636,7 @@ static void tinput_read_cb(Stream *stream, RBuffer *buf, size_t count_,
// If 'ttimeout' is not set, start the timer with a timeout of 0 to process
// the next input.
long ms = input->ttimeout ?
- (input->ttimeoutlen >= 0 ? input->ttimeoutlen : 0) : 0;
+ (input->ttimeoutlen >= 0 ? input->ttimeoutlen : 0) : 0;
// Stop the current timer if already running
time_watcher_stop(&input->timer_handle);
time_watcher_start(&input->timer_handle, tinput_timer_cb, (uint32_t)ms, 0);
diff --git a/src/nvim/tui/terminfo.c b/src/nvim/tui/terminfo.c
index ff2a357752..ce48059b94 100644
--- a/src/nvim/tui/terminfo.c
+++ b/src/nvim/tui/terminfo.c
@@ -5,11 +5,10 @@
#include <stdbool.h>
#include <string.h>
-
#include <unibilium.h>
-#include "nvim/log.h"
#include "nvim/globals.h"
+#include "nvim/log.h"
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/option.h"
@@ -29,12 +28,12 @@ bool terminfo_is_term_family(const char *term, const char *family)
size_t tlen = strlen(term);
size_t flen = strlen(family);
return tlen >= flen
- && 0 == memcmp(term, family, flen)
- // Per commentary in terminfo, minus is the only valid suffix separator.
- // The screen terminfo may have a terminal name like screen.xterm. By making
- // the dot(.) a valid separator, such terminal names will also be the
- // terminal family of the screen.
- && ('\0' == term[flen] || '-' == term[flen] || '.' == term[flen]);
+ && 0 == memcmp(term, family, flen)
+ // Per commentary in terminfo, minus is the only valid suffix separator.
+ // The screen terminfo may have a terminal name like screen.xterm. By making
+ // the dot(.) a valid separator, such terminal names will also be the
+ // terminal family of the screen.
+ && ('\0' == term[flen] || '-' == term[flen] || '.' == term[flen]);
}
bool terminfo_is_bsd_console(const char *term)
diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c
index 6e885279a9..803ff23cea 100644
--- a/src/nvim/tui/tui.c
+++ b/src/nvim/tui/tui.c
@@ -4,47 +4,45 @@
// Terminal UI functions. Invoked (by ui_bridge.c) on the TUI thread.
#include <assert.h>
+#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
-#include <limits.h>
-
-#include <uv.h>
#include <unibilium.h>
+#include <uv.h>
#if defined(HAVE_TERMIOS_H)
# include <termios.h>
#endif
-#include "nvim/lib/kvec.h"
-
+#include "nvim/api/private/helpers.h"
+#include "nvim/api/vim.h"
#include "nvim/ascii.h"
-#include "nvim/vim.h"
-#include "nvim/log.h"
-#include "nvim/ui.h"
+#include "nvim/event/loop.h"
+#include "nvim/event/signal.h"
#include "nvim/highlight.h"
-#include "nvim/map.h"
+#include "nvim/lib/kvec.h"
+#include "nvim/log.h"
#include "nvim/main.h"
+#include "nvim/map.h"
#include "nvim/memory.h"
#include "nvim/option.h"
-#include "nvim/api/vim.h"
-#include "nvim/api/private/helpers.h"
-#include "nvim/event/loop.h"
-#include "nvim/event/signal.h"
#include "nvim/os/input.h"
#include "nvim/os/os.h"
#include "nvim/os/signal.h"
#include "nvim/os/tty.h"
+#include "nvim/ui.h"
+#include "nvim/vim.h"
#ifdef WIN32
# include "nvim/os/os_win_console.h"
#endif
+#include "nvim/cursor_shape.h"
+#include "nvim/macros.h"
#include "nvim/strings.h"
#include "nvim/syntax.h"
-#include "nvim/ui_bridge.h"
-#include "nvim/ugrid.h"
#include "nvim/tui/input.h"
-#include "nvim/tui/tui.h"
#include "nvim/tui/terminfo.h"
-#include "nvim/cursor_shape.h"
-#include "nvim/macros.h"
+#include "nvim/tui/tui.h"
+#include "nvim/ugrid.h"
+#include "nvim/ui_bridge.h"
// Space reserved in two output buffers to make the cursor normal or invisible
// when flushing. No existing terminal will require 32 bytes to do that.
@@ -53,20 +51,20 @@
#define TOO_MANY_EVENTS 1000000
#define STARTS_WITH(str, prefix) \
- (strlen(str) >= (sizeof(prefix) - 1) \
- && 0 == memcmp((str), (prefix), sizeof(prefix) - 1))
+ (strlen(str) >= (sizeof(prefix) - 1) \
+ && 0 == memcmp((str), (prefix), sizeof(prefix) - 1))
#define TMUX_WRAP(is_tmux, seq) \
- ((is_tmux) ? "\x1bPtmux;\x1b" seq "\x1b\\" : seq)
+ ((is_tmux) ? "\x1bPtmux;\x1b" seq "\x1b\\" : seq)
#define LINUXSET0C "\x1b[?0c"
#define LINUXSET1C "\x1b[?1c"
#ifdef NVIM_UNIBI_HAS_VAR_FROM
-#define UNIBI_SET_NUM_VAR(var, num) \
+# define UNIBI_SET_NUM_VAR(var, num) \
do { \
- (var) = unibi_var_from_num((num)); \
+ (var) = unibi_var_from_num((num)); \
} while (0)
#else
-#define UNIBI_SET_NUM_VAR(var, num) (var).i = (num);
+# define UNIBI_SET_NUM_VAR(var, num) (var).i = (num);
#endif
typedef struct {
@@ -180,8 +178,7 @@ UI *tui_start(void)
return ui_bridge_attach(ui, tui_main, tui_scheduler);
}
-static size_t unibi_pre_fmt_str(TUIData *data, unsigned int unibi_index,
- char * buf, size_t len)
+static size_t unibi_pre_fmt_str(TUIData *data, unsigned int unibi_index, char * buf, size_t len)
{
const char *str = unibi_get_str(data->ut, unibi_index);
if (!str) {
@@ -263,10 +260,10 @@ static void terminfo_start(UI *ui)
long vtev = vte_version_env ? strtol(vte_version_env, NULL, 10) : 0;
bool iterm_env = termprg && strstr(termprg, "iTerm.app");
bool nsterm = (termprg && strstr(termprg, "Apple_Terminal"))
- || terminfo_is_term_family(term, "nsterm");
+ || terminfo_is_term_family(term, "nsterm");
bool konsole = terminfo_is_term_family(term, "konsole")
- || os_getenv("KONSOLE_PROFILE_NAME")
- || os_getenv("KONSOLE_DBUS_SESSION");
+ || os_getenv("KONSOLE_PROFILE_NAME")
+ || os_getenv("KONSOLE_DBUS_SESSION");
const char *konsolev_env = os_getenv("KONSOLE_VERSION");
long konsolev = konsolev_env ? strtol(konsolev_env, NULL, 10)
: (konsole ? 1 : 0);
@@ -508,15 +505,15 @@ static bool attrs_differ(UI *ui, int id1, int id2, bool rgb)
if (rgb) {
return a1.rgb_fg_color != a2.rgb_fg_color
- || a1.rgb_bg_color != a2.rgb_bg_color
- || a1.rgb_ae_attr != a2.rgb_ae_attr
- || a1.rgb_sp_color != a2.rgb_sp_color;
+ || a1.rgb_bg_color != a2.rgb_bg_color
+ || a1.rgb_ae_attr != a2.rgb_ae_attr
+ || a1.rgb_sp_color != a2.rgb_sp_color;
} else {
return a1.cterm_fg_color != a2.cterm_fg_color
- || a1.cterm_bg_color != a2.cterm_bg_color
- || a1.cterm_ae_attr != a2.cterm_ae_attr
- || (a1.cterm_ae_attr & (HL_UNDERLINE|HL_UNDERCURL)
- && a1.rgb_sp_color != a2.rgb_sp_color);
+ || a1.cterm_bg_color != a2.cterm_bg_color
+ || a1.cterm_ae_attr != a2.cterm_ae_attr
+ || (a1.cterm_ae_attr & (HL_UNDERLINE|HL_UNDERCURL)
+ && a1.rgb_sp_color != a2.rgb_sp_color);
}
}
@@ -593,10 +590,10 @@ static void update_attrs(UI *ui, int attr_id)
if ((undercurl || underline) && data->unibi_ext.set_underline_color != -1) {
int color = attrs.rgb_sp_color;
if (color != -1) {
- UNIBI_SET_NUM_VAR(data->params[0], (color >> 16) & 0xff); // red
- UNIBI_SET_NUM_VAR(data->params[1], (color >> 8) & 0xff); // green
- UNIBI_SET_NUM_VAR(data->params[2], color & 0xff); // blue
- unibi_out_ext(ui, data->unibi_ext.set_underline_color);
+ UNIBI_SET_NUM_VAR(data->params[0], (color >> 16) & 0xff); // red
+ UNIBI_SET_NUM_VAR(data->params[1], (color >> 8) & 0xff); // green
+ UNIBI_SET_NUM_VAR(data->params[2], color & 0xff); // blue
+ unibi_out_ext(ui, data->unibi_ext.set_underline_color);
}
}
@@ -639,14 +636,14 @@ static void update_attrs(UI *ui, int attr_id)
data->default_attr = fg == -1 && bg == -1
- && !bold && !italic && !underline && !undercurl && !reverse && !standout
- && !strikethrough;
+ && !bold && !italic && !underline && !undercurl && !reverse && !standout
+ && !strikethrough;
// Non-BCE terminals can't clear with non-default background color. Some BCE
// terminals don't support attributes either, so don't rely on it. But assume
// italic and bold has no effect if there is no text.
data->can_clear_attr = !reverse && !standout && !underline && !undercurl
- && !strikethrough && (data->bce || bg == -1);
+ && !strikethrough && (data->bce || bg == -1);
}
static void final_column_wrap(UI *ui)
@@ -802,8 +799,7 @@ safe_move:
ugrid_goto(grid, row, col);
}
-static void clear_region(UI *ui, int top, int bot, int left, int right,
- int attr_id)
+static void clear_region(UI *ui, int top, int bot, int left, int right, int attr_id)
{
TUIData *data = ui->data;
UGrid *grid = &data->grid;
@@ -1006,7 +1002,7 @@ static void tui_mode_info_set(UI *ui, bool guicursor_enabled, Array args)
static void tui_update_menu(UI *ui)
{
- // Do nothing; menus are for GUI only
+ // Do nothing; menus are for GUI only
}
static void tui_busy_start(UI *ui)
@@ -1025,7 +1021,7 @@ static void tui_mouse_on(UI *ui)
if (!data->mouse_enabled) {
#ifdef WIN32
// Windows versions with vtp(ENABLE_VIRTUAL_TERMINAL_PROCESSING) and
- // no vti(ENABLE_VIRTUAL_TERMINAL_INPUT) will need to use mouse traking of
+ // no vti(ENABLE_VIRTUAL_TERMINAL_INPUT) will need to use mouse tracking of
// libuv. For this reason, vtp (vterm) state of libuv is temporarily
// disabled because the control sequence needs to be processed by libuv
// instead of Windows vtp.
@@ -1048,7 +1044,7 @@ static void tui_mouse_off(UI *ui)
if (data->mouse_enabled) {
#ifdef WIN32
// Windows versions with vtp(ENABLE_VIRTUAL_TERMINAL_PROCESSING) and
- // no vti(ENABLE_VIRTUAL_TERMINAL_INPUT) will need to use mouse traking of
+ // no vti(ENABLE_VIRTUAL_TERMINAL_INPUT) will need to use mouse tracking of
// libuv. For this reason, vtp (vterm) state of libuv is temporarily
// disabled because the control sequence needs to be processed by libuv
// instead of Windows vtp.
@@ -1096,10 +1092,14 @@ static void tui_set_mode(UI *ui, ModeShape mode)
int shape;
switch (c.shape) {
- default: abort(); break;
- case SHAPE_BLOCK: shape = 1; break;
- case SHAPE_HOR: shape = 3; break;
- case SHAPE_VER: shape = 5; break;
+ default:
+ abort(); break;
+ case SHAPE_BLOCK:
+ shape = 1; break;
+ case SHAPE_HOR:
+ shape = 3; break;
+ case SHAPE_VER:
+ shape = 5; break;
}
UNIBI_SET_NUM_VAR(data->params[0], shape + (int)(c.blinkon == 0));
unibi_out_ext(ui, data->unibi_ext.set_cursor_style);
@@ -1123,9 +1123,9 @@ static void tui_mode_change(UI *ui, String mode, Integer mode_idx)
data->showing_mode = (ModeShape)mode_idx;
}
-static void tui_grid_scroll(UI *ui, Integer g, Integer startrow, Integer endrow,
- Integer startcol, Integer endcol,
- Integer rows, Integer cols FUNC_ATTR_UNUSED)
+static void tui_grid_scroll(UI *ui, Integer g, Integer startrow, // -V751
+ Integer endrow, Integer startcol, Integer endcol, Integer rows,
+ Integer cols FUNC_ATTR_UNUSED)
{
TUIData *data = ui->data;
UGrid *grid = &data->grid;
@@ -1134,16 +1134,16 @@ static void tui_grid_scroll(UI *ui, Integer g, Integer startrow, Integer endrow,
bool fullwidth = left == 0 && right == ui->width-1;
data->scroll_region_is_full_screen = fullwidth
- && top == 0 && bot == ui->height-1;
+ && top == 0 && bot == ui->height-1;
ugrid_scroll(grid, top, bot, left, right, (int)rows);
bool can_scroll = data->can_scroll
- && (data->scroll_region_is_full_screen
- || (data->can_change_scroll_region
- && ((left == 0 && right == ui->width - 1)
- || data->can_set_lr_margin
- || data->can_set_left_right_margin)));
+ && (data->scroll_region_is_full_screen
+ || (data->can_change_scroll_region
+ && ((left == 0 && right == ui->width - 1)
+ || data->can_set_lr_margin
+ || data->can_set_left_right_margin)));
if (can_scroll) {
// Change terminal scroll region and move cursor to the top
@@ -1184,8 +1184,7 @@ static void tui_grid_scroll(UI *ui, Integer g, Integer startrow, Integer endrow,
}
}
-static void tui_hl_attr_define(UI *ui, Integer id, HlAttrs attrs,
- HlAttrs cterm_attrs, Array info)
+static void tui_hl_attr_define(UI *ui, Integer id, HlAttrs attrs, HlAttrs cterm_attrs, Array info)
{
TUIData *data = ui->data;
kv_a(data->attrs, (size_t)id) = attrs;
@@ -1201,8 +1200,7 @@ static void tui_visual_bell(UI *ui)
unibi_out(ui, unibi_flash_screen);
}
-static void tui_default_colors_set(UI *ui, Integer rgb_fg, Integer rgb_bg,
- Integer rgb_sp,
+static void tui_default_colors_set(UI *ui, Integer rgb_fg, Integer rgb_bg, Integer rgb_sp,
Integer cterm_fg, Integer cterm_bg)
{
TUIData *data = ui->data;
@@ -1379,9 +1377,8 @@ static void tui_option_set(UI *ui, String name, Object value)
}
}
-static void tui_raw_line(UI *ui, Integer g, Integer linerow, Integer startcol,
- Integer endcol, Integer clearcol, Integer clearattr,
- LineFlags flags, const schar_T *chunk,
+static void tui_raw_line(UI *ui, Integer g, Integer linerow, Integer startcol, Integer endcol,
+ Integer clearcol, Integer clearattr, LineFlags flags, const schar_T *chunk,
const sattr_T *attrs)
{
TUIData *data = ui->data;
@@ -1461,8 +1458,8 @@ static void tui_guess_size(UI *ui)
did_user_set_dimensions = true;
assert(Columns >= INT_MIN && Columns <= INT_MAX);
assert(Rows >= INT_MIN && Rows <= INT_MAX);
- width = (int)Columns;
- height = (int)Rows;
+ width = Columns;
+ height = Rows;
goto end;
}
@@ -1486,7 +1483,7 @@ static void tui_guess_size(UI *ui)
height = unibi_get_num(data->ut, unibi_lines);
width = unibi_get_num(data->ut, unibi_columns);
-end:
+ end:
if (width <= 0 || height <= 0) {
// use the defaults
width = DFLT_COLS;
@@ -1561,8 +1558,7 @@ static void out(void *ctx, const char *str, size_t len)
data->bufpos += len;
}
-static void unibi_set_if_empty(unibi_term *ut, enum unibi_string str,
- const char *val)
+static void unibi_set_if_empty(unibi_term *ut, enum unibi_string str, const char *val)
{
if (!unibi_get_str(ut, str)) {
unibi_set_str(ut, str, val);
@@ -1596,9 +1592,8 @@ static int unibi_find_ext_bool(unibi_term *ut, const char *name)
/// Patches the terminfo records after loading from system or built-in db.
/// Several entries in terminfo are known to be deficient or outright wrong;
/// and several terminal emulators falsely announce incorrect terminal types.
-static void patch_terminfo_bugs(TUIData *data, const char *term,
- const char *colorterm, long vte_version,
- long konsolev, bool iterm_env, bool nsterm)
+static void patch_terminfo_bugs(TUIData *data, const char *term, const char *colorterm,
+ long vte_version, long konsolev, bool iterm_env, bool nsterm)
{
unibi_term *ut = data->ut;
const char *xterm_version = os_getenv("XTERM_VERSION");
@@ -1606,8 +1601,8 @@ static void patch_terminfo_bugs(TUIData *data, const char *term,
bool roxterm = !!os_getenv("ROXTERM_ID");
#endif
bool xterm = terminfo_is_term_family(term, "xterm")
- // Treat Terminal.app as generic xterm-like, for now.
- || nsterm;
+ // Treat Terminal.app as generic xterm-like, for now.
+ || nsterm;
bool kitty = terminfo_is_term_family(term, "xterm-kitty");
bool linuxvt = terminfo_is_term_family(term, "linux");
bool bsdvt = terminfo_is_bsd_console(term);
@@ -1618,18 +1613,18 @@ static void patch_terminfo_bugs(TUIData *data, const char *term,
bool tmux = terminfo_is_term_family(term, "tmux") || !!os_getenv("TMUX");
bool st = terminfo_is_term_family(term, "st");
bool gnome = terminfo_is_term_family(term, "gnome")
- || terminfo_is_term_family(term, "vte");
+ || terminfo_is_term_family(term, "vte");
bool iterm = terminfo_is_term_family(term, "iterm")
- || terminfo_is_term_family(term, "iterm2")
- || terminfo_is_term_family(term, "iTerm.app")
- || terminfo_is_term_family(term, "iTerm2.app");
+ || terminfo_is_term_family(term, "iterm2")
+ || terminfo_is_term_family(term, "iTerm.app")
+ || terminfo_is_term_family(term, "iTerm2.app");
bool alacritty = terminfo_is_term_family(term, "alacritty");
// None of the following work over SSH; see :help TERM .
bool iterm_pretending_xterm = xterm && iterm_env;
bool gnome_pretending_xterm = xterm && colorterm
- && strstr(colorterm, "gnome-terminal");
+ && strstr(colorterm, "gnome-terminal");
bool mate_pretending_xterm = xterm && colorterm
- && strstr(colorterm, "mate-terminal");
+ && strstr(colorterm, "mate-terminal");
bool true_xterm = xterm && !!xterm_version && !bsdvt;
bool cygwin = terminfo_is_term_family(term, "cygwin");
@@ -1839,8 +1834,8 @@ static void patch_terminfo_bugs(TUIData *data, const char *term,
data->unibi_ext.set_cursor_style =
(int)unibi_add_ext_str(ut, "Ss", "\x1b[%p1%d q");
if (-1 == data->unibi_ext.reset_cursor_style) {
- data->unibi_ext.reset_cursor_style = (int)unibi_add_ext_str(ut, "Se",
- "");
+ data->unibi_ext.reset_cursor_style = (int)unibi_add_ext_str(ut, "Se",
+ "");
}
unibi_set_ext_str(ut, (size_t)data->unibi_ext.reset_cursor_style,
"\x1b[ q");
@@ -1849,25 +1844,25 @@ static void patch_terminfo_bugs(TUIData *data, const char *term,
// does not support DECSCUSR.
// See http://linuxgazette.net/137/anonymous.html for more info
data->unibi_ext.set_cursor_style = (int)unibi_add_ext_str(ut, "Ss",
- "\x1b[?"
- "%?"
- // The parameter passed to Ss is the DECSCUSR parameter, so the
- // terminal capability has to translate into the Linux idiosyncratic
- // parameter.
- //
- // linuxvt only supports block and underline. It is also only
- // possible to have a steady block (no steady underline)
- "%p1%{2}%<" "%t%{8}" // blink block
- "%e%p1%{2}%=" "%t%{112}" // steady block
- "%e%p1%{3}%=" "%t%{4}" // blink underline (set to half block)
- "%e%p1%{4}%=" "%t%{4}" // steady underline
- "%e%p1%{5}%=" "%t%{2}" // blink bar (set to underline)
- "%e%p1%{6}%=" "%t%{2}" // steady bar
- "%e%{0}" // anything else
- "%;" "%dc");
+ "\x1b[?"
+ "%?"
+ // The parameter passed to Ss is the DECSCUSR parameter, so the
+ // terminal capability has to translate into the Linux idiosyncratic
+ // parameter.
+ //
+ // linuxvt only supports block and underline. It is also only
+ // possible to have a steady block (no steady underline)
+ "%p1%{2}%<" "%t%{8}" // blink block
+ "%e%p1%{2}%=" "%t%{112}" // steady block
+ "%e%p1%{3}%=" "%t%{4}" // blink underline (set to half block)
+ "%e%p1%{4}%=" "%t%{4}" // steady underline
+ "%e%p1%{5}%=" "%t%{2}" // blink bar (set to underline)
+ "%e%p1%{6}%=" "%t%{2}" // steady bar
+ "%e%{0}" // anything else
+ "%;" "%dc");
if (-1 == data->unibi_ext.reset_cursor_style) {
- data->unibi_ext.reset_cursor_style = (int)unibi_add_ext_str(ut, "Se",
- "");
+ data->unibi_ext.reset_cursor_style = (int)unibi_add_ext_str(ut, "Se",
+ "");
}
unibi_set_ext_str(ut, (size_t)data->unibi_ext.reset_cursor_style,
"\x1b[?c");
@@ -1875,34 +1870,34 @@ static void patch_terminfo_bugs(TUIData *data, const char *term,
// Konsole before version 18.07.70: set up a nonce profile. This has
// side-effects on temporary font resizing. #6798
data->unibi_ext.set_cursor_style = (int)unibi_add_ext_str(ut, "Ss",
- TMUX_WRAP(tmux, "\x1b]50;CursorShape=%?"
- "%p1%{3}%<" "%t%{0}" // block
- "%e%p1%{5}%<" "%t%{2}" // underline
- "%e%{1}" // everything else is bar
- "%;%d;BlinkingCursorEnabled=%?"
- "%p1%{1}%<" "%t%{1}" // Fortunately if we exclude zero as special,
- "%e%p1%{1}%&" // in all other cases we can treat bit #0 as a flag.
- "%;%d\x07"));
+ TMUX_WRAP(tmux,
+ "\x1b]50;CursorShape=%?"
+ "%p1%{3}%<" "%t%{0}" // block
+ "%e%p1%{5}%<" "%t%{2}" // underline
+ "%e%{1}" // everything else is bar
+ "%;%d;BlinkingCursorEnabled=%?"
+ "%p1%{1}%<" "%t%{1}" // Fortunately if we exclude zero as special,
+ "%e%p1%{1}%&" // in all other cases we can treat bit #0 as a flag.
+ "%;%d\x07"));
if (-1 == data->unibi_ext.reset_cursor_style) {
- data->unibi_ext.reset_cursor_style = (int)unibi_add_ext_str(ut, "Se",
- "");
+ data->unibi_ext.reset_cursor_style = (int)unibi_add_ext_str(ut, "Se",
+ "");
}
unibi_set_ext_str(ut, (size_t)data->unibi_ext.reset_cursor_style,
- "\x1b]50;\x07");
+ "\x1b]50;\x07");
}
}
}
/// This adds stuff that is not in standard terminfo as extended unibilium
/// capabilities.
-static void augment_terminfo(TUIData *data, const char *term,
- long vte_version,
- long konsolev, bool iterm_env, bool nsterm)
+static void augment_terminfo(TUIData *data, const char *term, long vte_version, long konsolev,
+ bool iterm_env, bool nsterm)
{
unibi_term *ut = data->ut;
bool xterm = terminfo_is_term_family(term, "xterm")
- // Treat Terminal.app as generic xterm-like, for now.
- || nsterm;
+ // Treat Terminal.app as generic xterm-like, for now.
+ || nsterm;
bool bsdvt = terminfo_is_bsd_console(term);
bool dtterm = terminfo_is_term_family(term, "dtterm");
bool rxvt = terminfo_is_term_family(term, "rxvt");
@@ -1911,9 +1906,9 @@ static void augment_terminfo(TUIData *data, const char *term,
bool screen = terminfo_is_term_family(term, "screen");
bool tmux = terminfo_is_term_family(term, "tmux") || !!os_getenv("TMUX");
bool iterm = terminfo_is_term_family(term, "iterm")
- || terminfo_is_term_family(term, "iterm2")
- || terminfo_is_term_family(term, "iTerm.app")
- || terminfo_is_term_family(term, "iTerm2.app");
+ || terminfo_is_term_family(term, "iterm2")
+ || terminfo_is_term_family(term, "iTerm.app")
+ || terminfo_is_term_family(term, "iTerm2.app");
bool alacritty = terminfo_is_term_family(term, "alacritty");
// None of the following work over SSH; see :help TERM .
bool iterm_pretending_xterm = xterm && iterm_env;
@@ -1928,19 +1923,18 @@ static void augment_terminfo(TUIData *data, const char *term,
|| teraterm // per TeraTerm "Supported Control Functions" doco
|| rxvt) { // per command.C
data->unibi_ext.resize_screen = (int)unibi_add_ext_str(ut,
- "ext.resize_screen",
- "\x1b[8;%p1%d;%p2%dt");
+ "ext.resize_screen",
+ "\x1b[8;%p1%d;%p2%dt");
}
if (putty || xterm || rxvt) {
data->unibi_ext.reset_scroll_region = (int)unibi_add_ext_str(ut,
- "ext.reset_scroll_region",
- "\x1b[r");
+ "ext.reset_scroll_region",
+ "\x1b[r");
}
// terminfo describes strikethrough modes as rmxx/smxx with respect
// to the ECMA-48 strikeout/crossed-out attributes.
- data->unibi_ext.enter_strikethrough_mode = (int)unibi_find_ext_str(
- ut, "smxx");
+ data->unibi_ext.enter_strikethrough_mode = unibi_find_ext_str(ut, "smxx");
// Dickey ncurses terminfo does not include the setrgbf and setrgbb
// capabilities, proposed by Rüdiger Sonderfeld on 2013-10-15. Adding
@@ -1955,29 +1949,29 @@ static void augment_terminfo(TUIData *data, const char *term,
// can use colons like ISO 8613-6:1994/ITU T.416:1993 says.
bool has_colon_rgb = !tmux && !screen
- && !vte_version // VTE colon-support has a big memory leak. #7573
- && (iterm || iterm_pretending_xterm // per VT100Terminal.m
- // per http://invisible-island.net/xterm/xterm.log.html#xterm_282
- || true_xterm);
+ && !vte_version // VTE colon-support has a big memory leak. #7573
+ && (iterm || iterm_pretending_xterm // per VT100Terminal.m
+ // per http://invisible-island.net/xterm/xterm.log.html#xterm_282
+ || true_xterm);
data->unibi_ext.set_rgb_foreground = unibi_find_ext_str(ut, "setrgbf");
if (-1 == data->unibi_ext.set_rgb_foreground) {
if (has_colon_rgb) {
data->unibi_ext.set_rgb_foreground = (int)unibi_add_ext_str(ut, "setrgbf",
- "\x1b[38:2:%p1%d:%p2%d:%p3%dm");
+ "\x1b[38:2:%p1%d:%p2%d:%p3%dm");
} else {
data->unibi_ext.set_rgb_foreground = (int)unibi_add_ext_str(ut, "setrgbf",
- "\x1b[38;2;%p1%d;%p2%d;%p3%dm");
+ "\x1b[38;2;%p1%d;%p2%d;%p3%dm");
}
}
data->unibi_ext.set_rgb_background = unibi_find_ext_str(ut, "setrgbb");
if (-1 == data->unibi_ext.set_rgb_background) {
if (has_colon_rgb) {
data->unibi_ext.set_rgb_background = (int)unibi_add_ext_str(ut, "setrgbb",
- "\x1b[48:2:%p1%d:%p2%d:%p3%dm");
+ "\x1b[48:2:%p1%d:%p2%d:%p3%dm");
} else {
data->unibi_ext.set_rgb_background = (int)unibi_add_ext_str(ut, "setrgbb",
- "\x1b[48;2;%p1%d;%p2%d;%p3%dm");
+ "\x1b[48;2;%p1%d;%p2%d;%p3%dm");
}
}
@@ -1985,63 +1979,59 @@ static void augment_terminfo(TUIData *data, const char *term,
// FIXME: Bypassing tmux like this affects the cursor colour globally, in
// all panes, which is not particularly desirable. A better approach
// would use a tmux control sequence and an extra if(screen) test.
- data->unibi_ext.set_cursor_color = (int)unibi_add_ext_str(
- ut, NULL, TMUX_WRAP(tmux, "\033]Pl%p1%06x\033\\"));
+ data->unibi_ext.set_cursor_color =
+ (int)unibi_add_ext_str(ut, NULL, TMUX_WRAP(tmux, "\033]Pl%p1%06x\033\\"));
} else if ((xterm || rxvt || tmux || alacritty)
&& (vte_version == 0 || vte_version >= 3900)) {
// Supported in urxvt, newer VTE.
- data->unibi_ext.set_cursor_color = (int)unibi_add_ext_str(
- ut, "ext.set_cursor_color", "\033]12;#%p1%06x\007");
+ data->unibi_ext.set_cursor_color = (int)unibi_add_ext_str(ut, "ext.set_cursor_color",
+ "\033]12;#%p1%06x\007");
}
if (-1 != data->unibi_ext.set_cursor_color) {
- data->unibi_ext.reset_cursor_color = (int)unibi_add_ext_str(
- ut, "ext.reset_cursor_color", "\x1b]112\x07");
+ data->unibi_ext.reset_cursor_color = (int)unibi_add_ext_str(ut, "ext.reset_cursor_color",
+ "\x1b]112\x07");
}
- data->unibi_ext.save_title = (int)unibi_add_ext_str(
- ut, "ext.save_title", "\x1b[22;0t");
- data->unibi_ext.restore_title = (int)unibi_add_ext_str(
- ut, "ext.restore_title", "\x1b[23;0t");
+ data->unibi_ext.save_title = (int)unibi_add_ext_str(ut, "ext.save_title", "\x1b[22;0t");
+ data->unibi_ext.restore_title = (int)unibi_add_ext_str(ut, "ext.restore_title", "\x1b[23;0t");
/// Terminals usually ignore unrecognized private modes, and there is no
/// known ambiguity with these. So we just set them unconditionally.
- data->unibi_ext.enable_lr_margin = (int)unibi_add_ext_str(
- ut, "ext.enable_lr_margin", "\x1b[?69h");
- data->unibi_ext.disable_lr_margin = (int)unibi_add_ext_str(
- ut, "ext.disable_lr_margin", "\x1b[?69l");
- data->unibi_ext.enable_bracketed_paste = (int)unibi_add_ext_str(
- ut, "ext.enable_bpaste", "\x1b[?2004h");
- data->unibi_ext.disable_bracketed_paste = (int)unibi_add_ext_str(
- ut, "ext.disable_bpaste", "\x1b[?2004l");
+ data->unibi_ext.enable_lr_margin =
+ (int)unibi_add_ext_str(ut, "ext.enable_lr_margin", "\x1b[?69h");
+ data->unibi_ext.disable_lr_margin = (int)unibi_add_ext_str(ut, "ext.disable_lr_margin",
+ "\x1b[?69l");
+ data->unibi_ext.enable_bracketed_paste = (int)unibi_add_ext_str(ut, "ext.enable_bpaste",
+ "\x1b[?2004h");
+ data->unibi_ext.disable_bracketed_paste = (int)unibi_add_ext_str(ut, "ext.disable_bpaste",
+ "\x1b[?2004l");
// For urxvt send BOTH xterm and old urxvt sequences. #8695
- data->unibi_ext.enable_focus_reporting = (int)unibi_add_ext_str(
- ut, "ext.enable_focus",
- rxvt ? "\x1b[?1004h\x1b]777;focus;on\x7" : "\x1b[?1004h");
- data->unibi_ext.disable_focus_reporting = (int)unibi_add_ext_str(
- ut, "ext.disable_focus",
- rxvt ? "\x1b[?1004l\x1b]777;focus;off\x7" : "\x1b[?1004l");
- data->unibi_ext.enable_mouse = (int)unibi_add_ext_str(
- ut, "ext.enable_mouse", "\x1b[?1002h\x1b[?1006h");
- data->unibi_ext.disable_mouse = (int)unibi_add_ext_str(
- ut, "ext.disable_mouse", "\x1b[?1002l\x1b[?1006l");
+ data->unibi_ext.enable_focus_reporting = (int)unibi_add_ext_str(ut, "ext.enable_focus",
+ rxvt ? "\x1b[?1004h\x1b]777;focus;on\x7" : "\x1b[?1004h");
+ data->unibi_ext.disable_focus_reporting = (int)unibi_add_ext_str(ut, "ext.disable_focus",
+ rxvt ? "\x1b[?1004l\x1b]777;focus;off\x7" : "\x1b[?1004l");
+ data->unibi_ext.enable_mouse = (int)unibi_add_ext_str(ut, "ext.enable_mouse",
+ "\x1b[?1002h\x1b[?1006h");
+ data->unibi_ext.disable_mouse = (int)unibi_add_ext_str(ut, "ext.disable_mouse",
+ "\x1b[?1002l\x1b[?1006l");
// Extended underline.
// terminfo will have Smulx for this (but no support for colors yet).
data->unibi_ext.set_underline_style = unibi_find_ext_str(ut, "Smulx");
if (data->unibi_ext.set_underline_style == -1) {
- int ext_bool_Su = unibi_find_ext_bool(ut, "Su"); // used by kitty
- if (vte_version >= 5102
- || (ext_bool_Su != -1
- && unibi_get_ext_bool(ut, (size_t)ext_bool_Su))) {
- data->unibi_ext.set_underline_style = (int)unibi_add_ext_str(
- ut, "ext.set_underline_style", "\x1b[4:%p1%dm");
- }
+ int ext_bool_Su = unibi_find_ext_bool(ut, "Su"); // used by kitty
+ if (vte_version >= 5102
+ || (ext_bool_Su != -1
+ && unibi_get_ext_bool(ut, (size_t)ext_bool_Su))) {
+ data->unibi_ext.set_underline_style = (int)unibi_add_ext_str(ut, "ext.set_underline_style",
+ "\x1b[4:%p1%dm");
+ }
}
if (data->unibi_ext.set_underline_style != -1) {
- // Only support colon syntax. #9270
- data->unibi_ext.set_underline_color = (int)unibi_add_ext_str(
- ut, "ext.set_underline_color", "\x1b[58:2::%p1%d:%p2%d:%p3%dm");
+ // Only support colon syntax. #9270
+ data->unibi_ext.set_underline_color = (int)unibi_add_ext_str(ut, "ext.set_underline_color",
+ "\x1b[58:2::%p1%d:%p2%d:%p3%dm");
}
}
@@ -2121,21 +2111,20 @@ static void flush_buf(UI *ui)
static const char *tui_get_stty_erase(void)
{
static char stty_erase[2] = { 0 };
-#if defined(HAVE_TERMIOS_H)
+# if defined(HAVE_TERMIOS_H)
struct termios t;
if (tcgetattr(input_global_fd(), &t) != -1) {
stty_erase[0] = (char)t.c_cc[VERASE];
stty_erase[1] = '\0';
DLOG("stty/termios:erase=%s", stty_erase);
}
-#endif
+# endif
return stty_erase;
}
/// libtermkey hook to override terminfo entries.
/// @see TermInput.tk_ti_hook_fn
-static const char *tui_tk_ti_getstr(const char *name, const char *value,
- void *data)
+static const char *tui_tk_ti_getstr(const char *name, const char *value, void *data)
{
static const char *stty_erase = NULL;
if (stty_erase == NULL) {
diff --git a/src/nvim/ui.c b/src/nvim/ui.c
index 94b6e9e39d..09709d0f43 100644
--- a/src/nvim/ui.c
+++ b/src/nvim/ui.c
@@ -69,9 +69,16 @@ static int pending_has_mouse = -1;
#else
static size_t uilog_seen = 0;
static char uilog_last_event[1024] = { 0 };
+
+#ifndef EXITFREE
+#define entered_free_all_mem false
+#endif
+
# define UI_LOG(funname) \
do { \
- if (strequal(uilog_last_event, STR(funname))) { \
+ if (entered_free_all_mem) { \
+ /* do nothing, we cannot log now */ \
+ } else if (strequal(uilog_last_event, STR(funname))) { \
uilog_seen++; \
} else { \
if (uilog_seen > 0) { \
@@ -107,6 +114,10 @@ static char uilog_last_event[1024] = { 0 };
# include "ui_events_call.generated.h"
#endif
+#ifndef EXITFREE
+#undef entered_free_all_mem
+#endif
+
void ui_init(void)
{
default_grid.handle = 1;
diff --git a/src/nvim/ui_bridge.c b/src/nvim/ui_bridge.c
index 25f45b8fe6..bc64414ecf 100644
--- a/src/nvim/ui_bridge.c
+++ b/src/nvim/ui_bridge.c
@@ -41,6 +41,8 @@ UI *ui_bridge_attach(UI *ui, ui_main_fn ui_main, event_scheduler scheduler)
UIBridgeData *rv = xcalloc(1, sizeof(UIBridgeData));
rv->ui = ui;
rv->bridge.rgb = ui->rgb;
+ rv->bridge.width = ui->width;
+ rv->bridge.height = ui->height;
rv->bridge.stop = ui_bridge_stop;
rv->bridge.grid_resize = ui_bridge_grid_resize;
rv->bridge.grid_clear = ui_bridge_grid_clear;
diff --git a/src/nvim/ui_compositor.c b/src/nvim/ui_compositor.c
index 1ec5189795..9c9aec1cf5 100644
--- a/src/nvim/ui_compositor.c
+++ b/src/nvim/ui_compositor.c
@@ -214,7 +214,7 @@ void ui_comp_remove_grid(ScreenGrid *grid)
grid->comp_index = 0;
// recompose the area under the grid
- // inefficent when being overlapped: only draw up to grid->comp_index
+ // inefficient when being overlapped: only draw up to grid->comp_index
ui_comp_compose_grid(grid);
}
@@ -594,7 +594,7 @@ static void ui_comp_msg_set_pos(UI *ui, Integer grid, Integer row,
int first_row = MAX((int)row-(scrolled?1:0), 0);
compose_area(first_row, Rows-delta, 0, Columns);
} else {
- // scroll separator togheter with message text
+ // scroll separator together with message text
int first_row = MAX((int)row-(msg_was_scrolled?1:0), 0);
ui_composed_call_grid_scroll(1, first_row, Rows, 0, Columns, delta, 0);
if (scrolled && !msg_was_scrolled && row > 0) {
diff --git a/src/nvim/undo.c b/src/nvim/undo.c
index ffd613cec2..fb96d7e6ff 100644
--- a/src/nvim/undo.c
+++ b/src/nvim/undo.c
@@ -234,7 +234,7 @@ int u_save(linenr_T top, linenr_T bot)
if (top + 2 == bot)
u_saveline((linenr_T)(top + 1));
- return u_savecommon(top, bot, (linenr_T)0, FALSE);
+ return u_savecommon(curbuf, top, bot, (linenr_T)0, false);
}
/*
@@ -245,7 +245,7 @@ int u_save(linenr_T top, linenr_T bot)
*/
int u_savesub(linenr_T lnum)
{
- return u_savecommon(lnum - 1, lnum + 1, lnum + 1, false);
+ return u_savecommon(curbuf, lnum - 1, lnum + 1, lnum + 1, false);
}
/*
@@ -256,7 +256,7 @@ int u_savesub(linenr_T lnum)
*/
int u_inssub(linenr_T lnum)
{
- return u_savecommon(lnum - 1, lnum, lnum + 1, false);
+ return u_savecommon(curbuf, lnum - 1, lnum, lnum + 1, false);
}
/*
@@ -268,18 +268,19 @@ int u_inssub(linenr_T lnum)
*/
int u_savedel(linenr_T lnum, long nlines)
{
- return u_savecommon(lnum - 1, lnum + nlines,
- nlines == curbuf->b_ml.ml_line_count ? 2 : lnum, FALSE);
+ return u_savecommon(
+ curbuf, lnum - 1, lnum + nlines,
+ nlines == curbuf->b_ml.ml_line_count ? 2 : lnum, false);
}
/// Return true when undo is allowed. Otherwise print an error message and
/// return false.
///
/// @return true if undo is allowed.
-bool undo_allowed(void)
+bool undo_allowed(buf_T *buf)
{
- /* Don't allow changes when 'modifiable' is off. */
- if (!MODIFIABLE(curbuf)) {
+ // Don't allow changes when 'modifiable' is off.
+ if (!MODIFIABLE(buf)) {
EMSG(_(e_modifiable));
return false;
}
@@ -301,12 +302,12 @@ bool undo_allowed(void)
}
/// Get the 'undolevels' value for the current buffer.
-static long get_undolevel(void)
+static long get_undolevel(buf_T *buf)
{
- if (curbuf->b_p_ul == NO_LOCAL_UNDOLEVEL) {
+ if (buf->b_p_ul == NO_LOCAL_UNDOLEVEL) {
return p_ul;
}
- return curbuf->b_p_ul;
+ return buf->b_p_ul;
}
static inline void zero_fmark_additional_data(fmark_T *fmarks)
@@ -326,7 +327,9 @@ static inline void zero_fmark_additional_data(fmark_T *fmarks)
* Careful: may trigger autocommands that reload the buffer.
* Returns FAIL when lines could not be saved, OK otherwise.
*/
-int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload)
+int u_savecommon(buf_T *buf,
+ linenr_T top, linenr_T bot,
+ linenr_T newbot, int reload)
{
linenr_T lnum;
long i;
@@ -337,22 +340,23 @@ int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload)
long size;
if (!reload) {
- /* When making changes is not allowed return FAIL. It's a crude way
- * to make all change commands fail. */
- if (!undo_allowed())
+ // When making changes is not allowed return FAIL. It's a crude way
+ // to make all change commands fail.
+ if (!undo_allowed(buf)) {
return FAIL;
+ }
+ // Saving text for undo means we are going to make a change. Give a
+ // warning for a read-only file before making the change, so that the
+ // FileChangedRO event can replace the buffer with a read-write version
+ // (e.g., obtained from a source control system).
+ if (buf == curbuf) {
+ change_warning(buf, 0);
+ }
- /*
- * Saving text for undo means we are going to make a change. Give a
- * warning for a read-only file before making the change, so that the
- * FileChangedRO event can replace the buffer with a read-write version
- * (e.g., obtained from a source control system).
- */
- change_warning(0);
- if (bot > curbuf->b_ml.ml_line_count + 1) {
- /* This happens when the FileChangedRO autocommand changes the
- * file in a way it becomes shorter. */
+ if (bot > buf->b_ml.ml_line_count + 1) {
+ // This happens when the FileChangedRO autocommand changes the
+ // file in a way it becomes shorter.
EMSG(_("E881: Line count changed unexpectedly"));
return FAIL;
}
@@ -364,18 +368,14 @@ int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload)
size = bot - top - 1;
- /*
- * If curbuf->b_u_synced == true make a new header.
- */
- if (curbuf->b_u_synced) {
- /* Need to create new entry in b_changelist. */
- curbuf->b_new_change = true;
-
- if (get_undolevel() >= 0) {
- /*
- * Make a new header entry. Do this first so that we don't mess
- * up the undo info when out of memory.
- */
+ // If curbuf->b_u_synced == true make a new header.
+ if (buf->b_u_synced) {
+ // Need to create new entry in b_changelist.
+ buf->b_new_change = true;
+
+ if (get_undolevel(buf) >= 0) {
+ // Make a new header entry. Do this first so that we don't mess
+ // up the undo info when out of memory.
uhp = xmalloc(sizeof(u_header_T));
kv_init(uhp->uh_extmark);
#ifdef U_DEBUG
@@ -388,63 +388,73 @@ int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload)
* If we undid more than we redid, move the entry lists before and
* including curbuf->b_u_curhead to an alternate branch.
*/
- old_curhead = curbuf->b_u_curhead;
+ old_curhead = buf->b_u_curhead;
if (old_curhead != NULL) {
- curbuf->b_u_newhead = old_curhead->uh_next.ptr;
- curbuf->b_u_curhead = NULL;
+ buf->b_u_newhead = old_curhead->uh_next.ptr;
+ buf->b_u_curhead = NULL;
}
/*
* free headers to keep the size right
*/
- while (curbuf->b_u_numhead > get_undolevel()
- && curbuf->b_u_oldhead != NULL) {
- u_header_T *uhfree = curbuf->b_u_oldhead;
-
- if (uhfree == old_curhead)
- /* Can't reconnect the branch, delete all of it. */
- u_freebranch(curbuf, uhfree, &old_curhead);
- else if (uhfree->uh_alt_next.ptr == NULL)
- /* There is no branch, only free one header. */
- u_freeheader(curbuf, uhfree, &old_curhead);
- else {
- /* Free the oldest alternate branch as a whole. */
- while (uhfree->uh_alt_next.ptr != NULL)
+ while (buf->b_u_numhead > get_undolevel(buf)
+ && buf->b_u_oldhead != NULL) {
+ u_header_T *uhfree = buf->b_u_oldhead;
+
+ if (uhfree == old_curhead) {
+ // Can't reconnect the branch, delete all of it.
+ u_freebranch(buf, uhfree, &old_curhead);
+ } else if (uhfree->uh_alt_next.ptr == NULL) {
+ // There is no branch, only free one header.
+ u_freeheader(buf, uhfree, &old_curhead);
+ } else {
+ // Free the oldest alternate branch as a whole.
+ while (uhfree->uh_alt_next.ptr != NULL) {
uhfree = uhfree->uh_alt_next.ptr;
- u_freebranch(curbuf, uhfree, &old_curhead);
+ }
+ u_freebranch(buf, uhfree, &old_curhead);
}
#ifdef U_DEBUG
u_check(TRUE);
#endif
}
- if (uhp == NULL) { /* no undo at all */
- if (old_curhead != NULL)
- u_freebranch(curbuf, old_curhead, NULL);
- curbuf->b_u_synced = false;
+ if (uhp == NULL) { // no undo at all
+ if (old_curhead != NULL) {
+ u_freebranch(buf, old_curhead, NULL);
+ }
+ buf->b_u_synced = false;
return OK;
}
uhp->uh_prev.ptr = NULL;
- uhp->uh_next.ptr = curbuf->b_u_newhead;
+ uhp->uh_next.ptr = buf->b_u_newhead;
uhp->uh_alt_next.ptr = old_curhead;
if (old_curhead != NULL) {
uhp->uh_alt_prev.ptr = old_curhead->uh_alt_prev.ptr;
- if (uhp->uh_alt_prev.ptr != NULL)
+
+ if (uhp->uh_alt_prev.ptr != NULL) {
uhp->uh_alt_prev.ptr->uh_alt_next.ptr = uhp;
+ }
+
old_curhead->uh_alt_prev.ptr = uhp;
- if (curbuf->b_u_oldhead == old_curhead)
- curbuf->b_u_oldhead = uhp;
- } else
+
+ if (buf->b_u_oldhead == old_curhead) {
+ buf->b_u_oldhead = uhp;
+ }
+ } else {
uhp->uh_alt_prev.ptr = NULL;
- if (curbuf->b_u_newhead != NULL)
- curbuf->b_u_newhead->uh_prev.ptr = uhp;
+ }
+
+ if (buf->b_u_newhead != NULL) {
+ buf->b_u_newhead->uh_prev.ptr = uhp;
+ }
- uhp->uh_seq = ++curbuf->b_u_seq_last;
- curbuf->b_u_seq_cur = uhp->uh_seq;
+ uhp->uh_seq = ++buf->b_u_seq_last;
+ buf->b_u_seq_cur = uhp->uh_seq;
uhp->uh_time = time(NULL);
uhp->uh_save_nr = 0;
- curbuf->b_u_time_cur = uhp->uh_time + 1;
+ buf->b_u_time_cur = uhp->uh_time + 1;
uhp->uh_walk = 0;
uhp->uh_entry = NULL;
@@ -455,23 +465,26 @@ int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload)
else
uhp->uh_cursor_vcol = -1;
- /* save changed and buffer empty flag for undo */
- uhp->uh_flags = (curbuf->b_changed ? UH_CHANGED : 0) +
- ((curbuf->b_ml.ml_flags & ML_EMPTY) ? UH_EMPTYBUF : 0);
+ // save changed and buffer empty flag for undo
+ uhp->uh_flags = (buf->b_changed ? UH_CHANGED : 0) +
+ ((buf->b_ml.ml_flags & ML_EMPTY) ? UH_EMPTYBUF : 0);
- /* save named marks and Visual marks for undo */
- zero_fmark_additional_data(curbuf->b_namedm);
- memmove(uhp->uh_namedm, curbuf->b_namedm,
- sizeof(curbuf->b_namedm[0]) * NMARKS);
- uhp->uh_visual = curbuf->b_visual;
+ // save named marks and Visual marks for undo
+ zero_fmark_additional_data(buf->b_namedm);
+ memmove(uhp->uh_namedm, buf->b_namedm,
+ sizeof(buf->b_namedm[0]) * NMARKS);
+ uhp->uh_visual = buf->b_visual;
- curbuf->b_u_newhead = uhp;
- if (curbuf->b_u_oldhead == NULL)
- curbuf->b_u_oldhead = uhp;
- ++curbuf->b_u_numhead;
+ buf->b_u_newhead = uhp;
+
+ if (buf->b_u_oldhead == NULL) {
+ buf->b_u_oldhead = uhp;
+ }
+ buf->b_u_numhead++;
} else {
- if (get_undolevel() < 0) /* no undo at all */
+ if (get_undolevel(buf) < 0) { // no undo at all
return OK;
+ }
/*
* When saving a single line, and it has been saved just before, it
@@ -483,7 +496,7 @@ int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload)
* long.
*/
if (size == 1) {
- uep = u_get_headentry();
+ uep = u_get_headentry(buf);
prev_uep = NULL;
for (i = 0; i < 10; ++i) {
if (uep == NULL)
@@ -491,16 +504,17 @@ int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload)
/* If lines have been inserted/deleted we give up.
* Also when the line was included in a multi-line save. */
- if ((curbuf->b_u_newhead->uh_getbot_entry != uep
+ if ((buf->b_u_newhead->uh_getbot_entry != uep
? (uep->ue_top + uep->ue_size + 1
!= (uep->ue_bot == 0
- ? curbuf->b_ml.ml_line_count + 1
+ ? buf->b_ml.ml_line_count + 1
: uep->ue_bot))
- : uep->ue_lcount != curbuf->b_ml.ml_line_count)
+ : uep->ue_lcount != buf->b_ml.ml_line_count)
|| (uep->ue_size > 1
&& top >= uep->ue_top
- && top + 2 <= uep->ue_top + uep->ue_size + 1))
+ && top + 2 <= uep->ue_top + uep->ue_size + 1)) {
break;
+ }
/* If it's the same line we can skip saving it again. */
if (uep->ue_size == 1 && uep->ue_top == top) {
@@ -508,8 +522,8 @@ int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload)
/* It's not the last entry: get ue_bot for the last
* entry now. Following deleted/inserted lines go to
* the re-used entry. */
- u_getbot();
- curbuf->b_u_synced = false;
+ u_getbot(buf);
+ buf->b_u_synced = false;
/* Move the found entry to become the last entry. The
* order of undo/redo doesn't matter for the entries
@@ -518,18 +532,18 @@ int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload)
* for the found entry if the line count is changed by
* the executed command. */
prev_uep->ue_next = uep->ue_next;
- uep->ue_next = curbuf->b_u_newhead->uh_entry;
- curbuf->b_u_newhead->uh_entry = uep;
+ uep->ue_next = buf->b_u_newhead->uh_entry;
+ buf->b_u_newhead->uh_entry = uep;
}
- /* The executed command may change the line count. */
- if (newbot != 0)
+ // The executed command may change the line count.
+ if (newbot != 0) {
uep->ue_bot = newbot;
- else if (bot > curbuf->b_ml.ml_line_count)
+ } else if (bot > buf->b_ml.ml_line_count) {
uep->ue_bot = 0;
- else {
- uep->ue_lcount = curbuf->b_ml.ml_line_count;
- curbuf->b_u_newhead->uh_getbot_entry = uep;
+ } else {
+ uep->ue_lcount = buf->b_ml.ml_line_count;
+ buf->b_u_newhead->uh_getbot_entry = uep;
}
return OK;
}
@@ -538,8 +552,8 @@ int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload)
}
}
- /* find line number for ue_bot for previous u_save() */
- u_getbot();
+ // find line number for ue_bot for previous u_save()
+ u_getbot(buf);
}
/*
@@ -553,17 +567,15 @@ int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload)
uep->ue_size = size;
uep->ue_top = top;
- if (newbot != 0)
+ if (newbot != 0) {
uep->ue_bot = newbot;
- /*
- * Use 0 for ue_bot if bot is below last line.
- * Otherwise we have to compute ue_bot later.
- */
- else if (bot > curbuf->b_ml.ml_line_count)
+ // Use 0 for ue_bot if bot is below last line.
+ // Otherwise we have to compute ue_bot later.
+ } else if (bot > buf->b_ml.ml_line_count) {
uep->ue_bot = 0;
- else {
- uep->ue_lcount = curbuf->b_ml.ml_line_count;
- curbuf->b_u_newhead->uh_getbot_entry = uep;
+ } else {
+ uep->ue_lcount = buf->b_ml.ml_line_count;
+ buf->b_u_newhead->uh_getbot_entry = uep;
}
if (size > 0) {
@@ -574,17 +586,19 @@ int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload)
u_freeentry(uep, i);
return FAIL;
}
- uep->ue_array[i] = u_save_line(lnum++);
+ uep->ue_array[i] = u_save_line_buf(buf, lnum++);
}
- } else
+ } else {
uep->ue_array = NULL;
- uep->ue_next = curbuf->b_u_newhead->uh_entry;
- curbuf->b_u_newhead->uh_entry = uep;
+ }
+
+ uep->ue_next = buf->b_u_newhead->uh_entry;
+ buf->b_u_newhead->uh_entry = uep;
if (reload) {
// buffer was reloaded, notify text change subscribers
curbuf->b_u_newhead->uh_flags |= UH_RELOAD;
}
- curbuf->b_u_synced = false;
+ buf->b_u_synced = false;
undo_undoes = false;
#ifdef U_DEBUG
@@ -617,18 +631,20 @@ int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload)
static char_u e_not_open[] = N_("E828: Cannot open undo file for writing: %s");
-/*
- * Compute the hash for the current buffer text into hash[UNDO_HASH_SIZE].
- */
-void u_compute_hash(char_u *hash)
+/// Compute the hash for a buffer text into hash[UNDO_HASH_SIZE].
+///
+/// @param[in] buf The buffer used to compute the hash
+/// @param[in] hash Array of size UNDO_HASH_SIZE in which to store the value of
+/// the hash
+void u_compute_hash(buf_T *buf, char_u *hash)
{
context_sha256_T ctx;
linenr_T lnum;
char_u *p;
sha256_start(&ctx);
- for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count; ++lnum) {
- p = ml_get(lnum);
+ for (lnum = 1; lnum <= buf->b_ml.ml_line_count; lnum++) {
+ p = ml_get_buf(buf, lnum, false);
sha256_update(&ctx, p, (uint32_t)(STRLEN(p) + 1));
}
sha256_finish(&ctx, hash);
@@ -656,6 +672,7 @@ char *u_get_undo_file_name(const char *const buf_ffname, const bool reading)
#ifdef HAVE_READLINK
char fname_buf[MAXPATHL];
#endif
+ char *p;
if (ffname == NULL) {
return NULL;
@@ -688,6 +705,13 @@ char *u_get_undo_file_name(const char *const buf_ffname, const bool reading)
memmove(tail + tail_len + 1, ".un~", sizeof(".un~"));
} else {
dir_name[dir_len] = NUL;
+
+ // Remove trailing pathseps from directory name
+ p = &dir_name[dir_len - 1];
+ while (vim_ispathsep(*p)) {
+ *p-- = NUL;
+ }
+
bool has_directory = os_isdir((char_u *)dir_name);
if (!has_directory && *dirp == NUL && !reading) {
// Last directory in the list does not exist, create it.
@@ -704,7 +728,7 @@ char *u_get_undo_file_name(const char *const buf_ffname, const bool reading)
if (has_directory) {
if (munged_name == NULL) {
munged_name = xstrdup(ffname);
- for (char *p = munged_name; *p != NUL; MB_PTR_ADV(p)) {
+ for (p = munged_name; *p != NUL; MB_PTR_ADV(p)) {
if (vim_ispathsep(*p)) {
*p = '%';
}
@@ -1002,14 +1026,14 @@ static ExtmarkUndoObject *unserialize_extmark(bufinfo_T *bi, bool *error,
extup->type = type;
if (type == kExtmarkSplice) {
n_elems = (size_t)sizeof(ExtmarkSplice) / sizeof(uint8_t);
- buf = xcalloc(sizeof(uint8_t), n_elems);
+ buf = xcalloc(n_elems, sizeof(uint8_t));
if (!undo_read(bi, buf, n_elems)) {
goto error;
}
extup->data.splice = *(ExtmarkSplice *)buf;
} else if (type == kExtmarkMove) {
n_elems = (size_t)sizeof(ExtmarkMove) / sizeof(uint8_t);
- buf = xcalloc(sizeof(uint8_t), n_elems);
+ buf = xcalloc(n_elems, sizeof(uint8_t));
if (!undo_read(bi, buf, n_elems)) {
goto error;
}
@@ -1281,8 +1305,8 @@ void u_write_undo(const char *const name, const bool forceit, buf_T *const buf,
goto theend;
}
- /* Undo must be synced. */
- u_sync(TRUE);
+ // Undo must be synced.
+ u_sync(true);
/*
* Write the header.
@@ -1767,7 +1791,7 @@ void u_undo(int count)
* be compatible.
*/
if (curbuf->b_u_synced == false) {
- u_sync(TRUE);
+ u_sync(true);
count = 1;
}
@@ -1846,8 +1870,9 @@ static void u_doit(int startcount, bool quiet, bool do_buf_event)
{
int count = startcount;
- if (!undo_allowed())
+ if (!undo_allowed(curbuf)) {
return;
+ }
u_newcount = 0;
u_oldcount = 0;
@@ -1858,15 +1883,16 @@ static void u_doit(int startcount, bool quiet, bool do_buf_event)
* needed. This may cause the file to be reloaded, that must happen
* before we do anything, because it may change curbuf->b_u_curhead
* and more. */
- change_warning(0);
+ change_warning(curbuf, 0);
if (undo_undoes) {
- if (curbuf->b_u_curhead == NULL) /* first undo */
+ if (curbuf->b_u_curhead == NULL) { // first undo
curbuf->b_u_curhead = curbuf->b_u_newhead;
- else if (get_undolevel() > 0) /* multi level undo */
- /* get next undo */
+ } else if (get_undolevel(curbuf) > 0) { // multi level undo
+ // get next undo
curbuf->b_u_curhead = curbuf->b_u_curhead->uh_next.ptr;
- /* nothing to undo */
+ }
+ // nothing to undo
if (curbuf->b_u_numhead == 0 || curbuf->b_u_curhead == NULL) {
/* stick curbuf->b_u_curhead at end */
curbuf->b_u_curhead = curbuf->b_u_oldhead;
@@ -1880,8 +1906,8 @@ static void u_doit(int startcount, bool quiet, bool do_buf_event)
u_undoredo(true, do_buf_event);
} else {
- if (curbuf->b_u_curhead == NULL || get_undolevel() <= 0) {
- beep_flush(); /* nothing to redo */
+ if (curbuf->b_u_curhead == NULL || get_undolevel(curbuf) <= 0) {
+ beep_flush(); // nothing to redo
if (count == startcount - 1) {
MSG(_("Already at newest change"));
return;
@@ -1925,9 +1951,10 @@ void undo_time(long step, bool sec, bool file, bool absolute)
bool above = false;
bool did_undo = true;
- /* First make sure the current undoable change is synced. */
- if (curbuf->b_u_synced == false)
- u_sync(TRUE);
+ // First make sure the current undoable change is synced.
+ if (curbuf->b_u_synced == false) {
+ u_sync(true);
+ }
u_newcount = 0;
u_oldcount = 0;
@@ -2122,8 +2149,8 @@ target_zero:
if (uhp != NULL || target == 0) {
// First go up the tree as much as needed.
while (!got_int) {
- /* Do the change warning now, for the same reason as above. */
- change_warning(0);
+ // Do the change warning now, for the same reason as above.
+ change_warning(curbuf, 0);
uhp = curbuf->b_u_curhead;
if (uhp == NULL)
@@ -2147,7 +2174,7 @@ target_zero:
// And now go down the tree (redo), branching off where needed.
while (!got_int) {
// Do the change warning now, for the same reason as above.
- change_warning(0);
+ change_warning(curbuf, 0);
uhp = curbuf->b_u_curhead;
if (uhp == NULL) {
@@ -2414,7 +2441,7 @@ static void u_undoredo(int undo, bool do_buf_event)
curhead->uh_entry = newlist;
curhead->uh_flags = new_flags;
- if ((old_flags & UH_EMPTYBUF) && BUFEMPTY()) {
+ if ((old_flags & UH_EMPTYBUF) && buf_is_empty(curbuf)) {
curbuf->b_ml.ml_flags |= ML_EMPTY;
}
if (old_flags & UH_CHANGED) {
@@ -2583,21 +2610,20 @@ static void u_undo_end(
msgbuf);
}
-/*
- * u_sync: stop adding to the current entry list
- */
-void
-u_sync(
- int force // Also sync when no_u_sync is set.
-)
+/// u_sync: stop adding to the current entry list
+///
+/// @param force if true, also sync when no_u_sync is set.
+void u_sync(bool force)
{
- /* Skip it when already synced or syncing is disabled. */
- if (curbuf->b_u_synced || (!force && no_u_sync > 0))
+ // Skip it when already synced or syncing is disabled.
+ if (curbuf->b_u_synced || (!force && no_u_sync > 0)) {
return;
- if (get_undolevel() < 0)
- curbuf->b_u_synced = true; /* no entries, nothing to do */
- else {
- u_getbot(); /* compute ue_bot of previous u_save */
+ }
+
+ if (get_undolevel(curbuf) < 0) {
+ curbuf->b_u_synced = true; // no entries, nothing to do
+ } else {
+ u_getbot(curbuf); // compute ue_bot of previous u_save
curbuf->b_u_curhead = NULL;
}
}
@@ -2708,7 +2734,7 @@ void ex_undojoin(exarg_T *eap)
if (!curbuf->b_u_synced) {
return; // already unsynced
}
- if (get_undolevel() < 0) {
+ if (get_undolevel(curbuf) < 0) {
return; // no entries, nothing to do
} else {
curbuf->b_u_synced = false; // Append next change to last entry
@@ -2744,13 +2770,13 @@ void u_find_first_changed(void)
return;
for (lnum = 1; lnum < curbuf->b_ml.ml_line_count
- && lnum <= uep->ue_size; ++lnum)
- if (STRCMP(ml_get_buf(curbuf, lnum, FALSE),
- uep->ue_array[lnum - 1]) != 0) {
+ && lnum <= uep->ue_size; lnum++) {
+ if (STRCMP(ml_get_buf(curbuf, lnum, false), uep->ue_array[lnum - 1]) != 0) {
clearpos(&(uhp->uh_cursor));
uhp->uh_cursor.lnum = lnum;
return;
}
+ }
if (curbuf->b_ml.ml_line_count != uep->ue_size) {
/* lines added or deleted at the end, put the cursor there */
clearpos(&(uhp->uh_cursor));
@@ -2792,38 +2818,39 @@ static void u_unch_branch(u_header_T *uhp)
* Get pointer to last added entry.
* If it's not valid, give an error message and return NULL.
*/
-static u_entry_T *u_get_headentry(void)
+static u_entry_T *u_get_headentry(buf_T *buf)
{
- if (curbuf->b_u_newhead == NULL || curbuf->b_u_newhead->uh_entry == NULL) {
+ if (buf->b_u_newhead == NULL || buf->b_u_newhead->uh_entry == NULL) {
IEMSG(_("E439: undo list corrupt"));
return NULL;
}
- return curbuf->b_u_newhead->uh_entry;
+ return buf->b_u_newhead->uh_entry;
}
/*
* u_getbot(): compute the line number of the previous u_save
* It is called only when b_u_synced is false.
*/
-static void u_getbot(void)
+static void u_getbot(buf_T *buf)
{
u_entry_T *uep;
linenr_T extra;
- uep = u_get_headentry(); /* check for corrupt undo list */
- if (uep == NULL)
+ uep = u_get_headentry(buf); // check for corrupt undo list
+ if (uep == NULL) {
return;
+ }
- uep = curbuf->b_u_newhead->uh_getbot_entry;
+ uep = buf->b_u_newhead->uh_getbot_entry;
if (uep != NULL) {
/*
* the new ue_bot is computed from the number of lines that has been
* inserted (0 - deleted) since calling u_save. This is equal to the
* old line count subtracted from the current line count.
*/
- extra = curbuf->b_ml.ml_line_count - uep->ue_lcount;
+ extra = buf->b_ml.ml_line_count - uep->ue_lcount;
uep->ue_bot = uep->ue_top + uep->ue_size + 1 + extra;
- if (uep->ue_bot < 1 || uep->ue_bot > curbuf->b_ml.ml_line_count) {
+ if (uep->ue_bot < 1 || uep->ue_bot > buf->b_ml.ml_line_count) {
IEMSG(_("E440: undo line missing"));
uep->ue_bot = uep->ue_top + 1; // assume all lines deleted, will
// get all the old lines back
@@ -2831,10 +2858,10 @@ static void u_getbot(void)
// ones
}
- curbuf->b_u_newhead->uh_getbot_entry = NULL;
+ buf->b_u_newhead->uh_getbot_entry = NULL;
}
- curbuf->b_u_synced = true;
+ buf->b_u_synced = true;
}
/*
@@ -3014,10 +3041,12 @@ void u_undoline(void)
return;
}
- /* first save the line for the 'u' command */
- if (u_savecommon(curbuf->b_u_line_lnum - 1,
- curbuf->b_u_line_lnum + 1, (linenr_T)0, FALSE) == FAIL)
+ // first save the line for the 'u' command
+ if (u_savecommon(curbuf, curbuf->b_u_line_lnum - 1,
+ curbuf->b_u_line_lnum + 1, (linenr_T)0, false) == FAIL) {
return;
+ }
+
oldp = u_save_line(curbuf->b_u_line_lnum);
ml_replace(curbuf->b_u_line_lnum, curbuf->b_u_line_ptr, true);
changed_bytes(curbuf->b_u_line_lnum, 0);
@@ -3048,12 +3077,21 @@ void u_blockfree(buf_T *buf)
xfree(buf->b_u_line_ptr);
}
-/*
- * u_save_line(): allocate memory and copy line 'lnum' into it.
- */
+/// Allocate memory and copy curbuf line into it.
+///
+/// @param lnum the line to copy
static char_u *u_save_line(linenr_T lnum)
{
- return vim_strsave(ml_get(lnum));
+ return u_save_line_buf(curbuf, lnum);
+}
+
+/// Allocate memory and copy line into it
+///
+/// @param lnum line to copy
+/// @param buf buffer to copy from
+static char_u *u_save_line_buf(buf_T *buf, linenr_T lnum)
+{
+ return vim_strsave(ml_get_buf(buf, lnum, false));
}
/// Check if the 'modified' flag is set, or 'ff' has changed (only need to
@@ -3143,18 +3181,16 @@ u_header_T *u_force_get_undo_header(buf_T *buf)
if (!uhp) {
// Undo is normally invoked in change code, which already has swapped
// curbuf.
- buf_T *save_curbuf = curbuf;
- curbuf = buf;
// Args are tricky: this means replace empty range by empty range..
- u_savecommon(0, 1, 1, true);
+ u_savecommon(curbuf, 0, 1, 1, true);
+
uhp = buf->b_u_curhead;
if (!uhp) {
uhp = buf->b_u_newhead;
- if (get_undolevel() > 0 && !uhp) {
+ if (get_undolevel(curbuf) > 0 && !uhp) {
abort();
}
}
- curbuf = save_curbuf;
}
return uhp;
}
diff --git a/src/nvim/version.c b/src/nvim/version.c
index f3a30630f8..7c197f1b7f 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -13,6 +13,7 @@
#include "nvim/api/private/helpers.h"
#include "nvim/vim.h"
#include "nvim/ascii.h"
+#include "nvim/buffer.h"
#include "nvim/iconv.h"
#include "nvim/version.h"
#include "nvim/charset.h"
@@ -38,7 +39,10 @@ NVIM_VERSION_PRERELEASE
char *Version = VIM_VERSION_SHORT;
char *longVersion = NVIM_VERSION_LONG;
char *version_buildtype = "Build type: " NVIM_VERSION_BUILD_TYPE;
+// Reproducible builds: omit compile info in Release builds. #15424
+#ifndef NDEBUG
char *version_cflags = "Compilation: " NVIM_VERSION_CFLAGS;
+#endif
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "version.c.generated.h"
@@ -2142,7 +2146,9 @@ void list_version(void)
MSG(longVersion);
MSG(version_buildtype);
list_lua_version();
+#ifndef NDEBUG
MSG(version_cflags);
+#endif
#ifdef HAVE_PATHDEF
@@ -2190,7 +2196,7 @@ void list_version(void)
/// Show the intro message when not editing a file.
void maybe_intro_message(void)
{
- if (BUFEMPTY()
+ if (buf_is_empty(curbuf)
&& (curbuf->b_fname == NULL)
&& (firstwin->w_next == NULL)
&& (vim_strchr(p_shm, SHM_INTRO) == NULL)) {
diff --git a/src/nvim/vim.h b/src/nvim/vim.h
index df4ab04eb6..62536a0600 100644
--- a/src/nvim/vim.h
+++ b/src/nvim/vim.h
@@ -102,6 +102,7 @@ typedef enum {
#define VAR_TYPE_FLOAT 5
#define VAR_TYPE_BOOL 6
#define VAR_TYPE_SPECIAL 7
+#define VAR_TYPE_BLOB 10
// values for xp_context when doing command line completion
@@ -270,7 +271,7 @@ enum { FOLD_TEXT_LEN = 51 }; //!< buffer size for get_foldtext()
/// On some systems case in a file name does not matter, on others it does.
///
/// @note Does not account for maximum name lengths and things like "../dir",
-/// thus it is not 100% accurate. OS may also use different algorythm for
+/// thus it is not 100% accurate. OS may also use different algorithm for
/// case-insensitive comparison.
///
/// @param[in] x First file name to compare.
@@ -304,17 +305,6 @@ enum { FOLD_TEXT_LEN = 51 }; //!< buffer size for get_foldtext()
#include "nvim/buffer_defs.h" // buffer and windows
#include "nvim/ex_cmds_defs.h" // Ex command defines
-// Used for flags in do_in_path()
-#define DIP_ALL 0x01 // all matches, not just the first one
-#define DIP_DIR 0x02 // find directories instead of files
-#define DIP_ERR 0x04 // give an error message when none found
-#define DIP_START 0x08 // also use "start" directory in 'packpath'
-#define DIP_OPT 0x10 // also use "opt" directory in 'packpath'
-#define DIP_NORTP 0x20 // do not use 'runtimepath'
-#define DIP_NOAFTER 0x40 // skip "after" directories
-#define DIP_AFTER 0x80 // only use "after" directories
-#define DIP_LUA 0x100 // also use ".lua" files
-
// Lowest number used for window ID. Cannot have this many windows per tab.
#define LOWEST_WIN_ID 1000
diff --git a/src/nvim/viml/parser/expressions.c b/src/nvim/viml/parser/expressions.c
index e9d82ca87d..39687a8e8d 100644
--- a/src/nvim/viml/parser/expressions.c
+++ b/src/nvim/viml/parser/expressions.c
@@ -50,20 +50,19 @@
// 7. 'isident' no longer applies to environment variables, they always include
// ASCII alphanumeric characters and underscore and nothing except this.
+#include <assert.h>
#include <stdbool.h>
#include <stddef.h>
-#include <assert.h>
#include <string.h>
-#include "nvim/vim.h"
-#include "nvim/memory.h"
-#include "nvim/types.h"
-#include "nvim/charset.h"
#include "nvim/ascii.h"
#include "nvim/assert.h"
-#include "nvim/lib/kvec.h"
+#include "nvim/charset.h"
#include "nvim/eval/typval.h"
-
+#include "nvim/lib/kvec.h"
+#include "nvim/memory.h"
+#include "nvim/types.h"
+#include "nvim/vim.h"
#include "nvim/viml/parser/expressions.h"
#include "nvim/viml/parser/parser.h"
@@ -143,10 +142,8 @@ typedef enum {
/// numbers are not supported.
/// @param[in] exponent Exponent to scale by.
/// @param[in] exponent_negative True if exponent is negative.
-static inline float_T scale_number(const float_T num,
- const uint8_t base,
- const uvarnumber_T exponent,
- const bool exponent_negative)
+static inline float_T scale_number(const float_T num, const uint8_t base,
+ const uvarnumber_T exponent, const bool exponent_negative)
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_CONST
{
if (num == 0 || exponent == 0) {
@@ -200,7 +197,7 @@ LexExprToken viml_pexpr_next_token(ParserState *const pstate, const int flags)
if (ret.len < pline.size \
&& strchr("?#", pline.data[ret.len]) != NULL) { \
ret.data.cmp.ccs = \
- (ExprCaseCompareStrategy)pline.data[ret.len]; \
+ (ExprCaseCompareStrategy)pline.data[ret.len]; \
ret.len++; \
} else { \
ret.data.cmp.ccs = kCCStrategyUseOption; \
@@ -209,12 +206,12 @@ LexExprToken viml_pexpr_next_token(ParserState *const pstate, const int flags)
switch (schar) {
// Paired brackets.
#define BRACKET(typ, opning, clsing) \
- case opning: \
- case clsing: { \
- ret.type = typ; \
- ret.data.brc.closing = (schar == clsing); \
- break; \
- }
+case opning: \
+case clsing: { \
+ ret.type = typ; \
+ ret.data.brc.closing = (schar == clsing); \
+ break; \
+}
BRACKET(kExprLexParenthesis, '(', ')')
BRACKET(kExprLexBracket, '[', ']')
BRACKET(kExprLexFigureBrace, '{', '}')
@@ -222,10 +219,10 @@ LexExprToken viml_pexpr_next_token(ParserState *const pstate, const int flags)
// Single character tokens without data.
#define CHAR(typ, ch) \
- case ch: { \
- ret.type = typ; \
- break; \
- }
+case ch: { \
+ ret.type = typ; \
+ break; \
+}
CHAR(kExprLexQuestion, '?')
CHAR(kExprLexColon, ':')
CHAR(kExprLexComma, ',')
@@ -233,198 +230,265 @@ LexExprToken viml_pexpr_next_token(ParserState *const pstate, const int flags)
// Multiplication/division/modulo.
#define MUL(mul_type, ch) \
- case ch: { \
- ret.type = kExprLexMultiplication; \
- ret.data.mul.type = mul_type; \
- break; \
- }
+case ch: { \
+ ret.type = kExprLexMultiplication; \
+ ret.data.mul.type = mul_type; \
+ break; \
+}
MUL(kExprLexMulMul, '*')
MUL(kExprLexMulDiv, '/')
MUL(kExprLexMulMod, '%')
#undef MUL
#define CHARREG(typ, cond) \
- do { \
- ret.type = typ; \
- for (; (ret.len < pline.size \
- && cond(pline.data[ret.len])) \
- ; ret.len++) { \
- } \
- } while (0)
-
- // Whitespace.
- case ' ':
- case TAB: {
- CHARREG(kExprLexSpacing, ascii_iswhite);
- break;
- }
-
- // Control character, except for NUL, NL and TAB.
- case Ctrl_A: case Ctrl_B: case Ctrl_C: case Ctrl_D: case Ctrl_E:
- case Ctrl_F: case Ctrl_G: case Ctrl_H:
+ do { \
+ ret.type = typ; \
+ for (; (ret.len < pline.size \
+ && cond(pline.data[ret.len])) \
+ ; ret.len++) { \
+ } \
+ } while (0)
- case Ctrl_K: case Ctrl_L: case Ctrl_M: case Ctrl_N: case Ctrl_O:
- case Ctrl_P: case Ctrl_Q: case Ctrl_R: case Ctrl_S: case Ctrl_T:
- case Ctrl_U: case Ctrl_V: case Ctrl_W: case Ctrl_X: case Ctrl_Y:
- case Ctrl_Z: {
+ // Whitespace.
+ case ' ':
+ case TAB:
+ CHARREG(kExprLexSpacing, ascii_iswhite);
+ break;
+
+ // Control character, except for NUL, NL and TAB.
+ case Ctrl_A:
+ case Ctrl_B:
+ case Ctrl_C:
+ case Ctrl_D:
+ case Ctrl_E:
+ case Ctrl_F:
+ case Ctrl_G:
+ case Ctrl_H:
+
+ case Ctrl_K:
+ case Ctrl_L:
+ case Ctrl_M:
+ case Ctrl_N:
+ case Ctrl_O:
+ case Ctrl_P:
+ case Ctrl_Q:
+ case Ctrl_R:
+ case Ctrl_S:
+ case Ctrl_T:
+ case Ctrl_U:
+ case Ctrl_V:
+ case Ctrl_W:
+ case Ctrl_X:
+ case Ctrl_Y:
+ case Ctrl_Z:
#define ISCTRL(schar) (schar < ' ')
- CHARREG(kExprLexInvalid, ISCTRL);
- ret.data.err.type = kExprLexSpacing;
- ret.data.err.msg =
- _("E15: Invalid control character present in input: %.*s");
- break;
+ CHARREG(kExprLexInvalid, ISCTRL);
+ ret.data.err.type = kExprLexSpacing;
+ ret.data.err.msg =
+ _("E15: Invalid control character present in input: %.*s");
+ break;
#undef ISCTRL
- }
- // Number.
- case '0': case '1': case '2': case '3': case '4': case '5': case '6':
- case '7': case '8': case '9': {
- ret.data.num.is_float = false;
- ret.data.num.base = 10;
- size_t frac_start = 0;
- size_t exp_start = 0;
- size_t frac_end = 0;
- bool exp_negative = false;
- CHARREG(kExprLexNumber, ascii_isdigit);
- if (flags & kELFlagAllowFloat) {
- const LexExprToken non_float_ret = ret;
+ // Number.
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9': {
+ ret.data.num.is_float = false;
+ ret.data.num.base = 10;
+ size_t frac_start = 0;
+ size_t exp_start = 0;
+ size_t frac_end = 0;
+ bool exp_negative = false;
+ CHARREG(kExprLexNumber, ascii_isdigit);
+ if (flags & kELFlagAllowFloat) {
+ const LexExprToken non_float_ret = ret;
+ if (pline.size > ret.len + 1
+ && pline.data[ret.len] == '.'
+ && ascii_isdigit(pline.data[ret.len + 1])) {
+ ret.len++;
+ frac_start = ret.len;
+ frac_end = ret.len;
+ ret.data.num.is_float = true;
+ for (; ret.len < pline.size && ascii_isdigit(pline.data[ret.len])
+ ; ret.len++) {
+ // A small optimization: trailing zeroes in fractional part do not
+ // add anything to significand, so it is useless to include them in
+ // frac_end.
+ if (pline.data[ret.len] != '0') {
+ frac_end = ret.len + 1;
+ }
+ }
if (pline.size > ret.len + 1
- && pline.data[ret.len] == '.'
- && ascii_isdigit(pline.data[ret.len + 1])) {
+ && (pline.data[ret.len] == 'e'
+ || pline.data[ret.len] == 'E')
+ && ((pline.size > ret.len + 2
+ && (pline.data[ret.len + 1] == '+'
+ || pline.data[ret.len + 1] == '-')
+ && ascii_isdigit(pline.data[ret.len + 2]))
+ || ascii_isdigit(pline.data[ret.len + 1]))) {
ret.len++;
- frac_start = ret.len;
- frac_end = ret.len;
- ret.data.num.is_float = true;
- for (; ret.len < pline.size && ascii_isdigit(pline.data[ret.len])
- ; ret.len++) {
- // A small optimization: trailing zeroes in fractional part do not
- // add anything to significand, so it is useless to include them in
- // frac_end.
- if (pline.data[ret.len] != '0') {
- frac_end = ret.len + 1;
- }
- }
- if (pline.size > ret.len + 1
- && (pline.data[ret.len] == 'e'
- || pline.data[ret.len] == 'E')
- && ((pline.size > ret.len + 2
- && (pline.data[ret.len + 1] == '+'
- || pline.data[ret.len + 1] == '-')
- && ascii_isdigit(pline.data[ret.len + 2]))
- || ascii_isdigit(pline.data[ret.len + 1]))) {
+ if (pline.data[ret.len] == '+'
+ || (exp_negative = (pline.data[ret.len] == '-'))) {
ret.len++;
- if (pline.data[ret.len] == '+'
- || (exp_negative = (pline.data[ret.len] == '-'))) {
- ret.len++;
- }
- exp_start = ret.len;
- CHARREG(kExprLexNumber, ascii_isdigit);
}
- }
- if (pline.size > ret.len
- && (pline.data[ret.len] == '.'
- || ASCII_ISALPHA(pline.data[ret.len]))) {
- ret = non_float_ret;
+ exp_start = ret.len;
+ CHARREG(kExprLexNumber, ascii_isdigit);
}
}
- // TODO(ZyX-I): detect overflows
- if (ret.data.num.is_float) {
- // Vim used to use string2float here which in turn uses strtod(). There
- // are two problems with this approach:
- // 1. strtod() is locale-dependent. Not sure how it is worked around so
- // that I do not see relevant bugs, but it still does not look like
- // a good idea.
- // 2. strtod() does not accept length argument.
- //
- // The below variant of parsing floats was recognized as acceptable
- // because it is basically how uClibc does the thing: it generates
- // a number ignoring decimal point (but recording its position), then
- // uses recorded position to scale number down when processing exponent.
- float_T significand_part = 0;
- uvarnumber_T exp_part = 0;
- const size_t frac_size = (size_t)(frac_end - frac_start);
- for (size_t i = 0; i < frac_end; i++) {
- if (i == frac_start - 1) {
- continue;
- }
- significand_part = significand_part * 10 + (pline.data[i] - '0');
- }
- if (exp_start) {
- vim_str2nr(pline.data + exp_start, NULL, NULL, 0, NULL, &exp_part,
- (int)(ret.len - exp_start));
+ if (pline.size > ret.len
+ && (pline.data[ret.len] == '.'
+ || ASCII_ISALPHA(pline.data[ret.len]))) {
+ ret = non_float_ret;
+ }
+ }
+ // TODO(ZyX-I): detect overflows
+ if (ret.data.num.is_float) {
+ // Vim used to use string2float here which in turn uses strtod(). There
+ // are two problems with this approach:
+ // 1. strtod() is locale-dependent. Not sure how it is worked around so
+ // that I do not see relevant bugs, but it still does not look like
+ // a good idea.
+ // 2. strtod() does not accept length argument.
+ //
+ // The below variant of parsing floats was recognized as acceptable
+ // because it is basically how uClibc does the thing: it generates
+ // a number ignoring decimal point (but recording its position), then
+ // uses recorded position to scale number down when processing exponent.
+ float_T significand_part = 0;
+ uvarnumber_T exp_part = 0;
+ const size_t frac_size = (size_t)(frac_end - frac_start);
+ for (size_t i = 0; i < frac_end; i++) {
+ if (i == frac_start - 1) {
+ continue;
}
- if (exp_negative) {
- exp_part += frac_size;
+ significand_part = significand_part * 10 + (pline.data[i] - '0');
+ }
+ if (exp_start) {
+ vim_str2nr(pline.data + exp_start, NULL, NULL, 0, NULL, &exp_part,
+ (int)(ret.len - exp_start), false);
+ }
+ if (exp_negative) {
+ exp_part += frac_size;
+ } else {
+ if (exp_part < frac_size) {
+ exp_negative = true;
+ exp_part = frac_size - exp_part;
} else {
- if (exp_part < frac_size) {
- exp_negative = true;
- exp_part = frac_size - exp_part;
- } else {
- exp_part -= frac_size;
- }
+ exp_part -= frac_size;
}
- ret.data.num.val.floating = scale_number(significand_part, 10, exp_part,
- exp_negative);
- } else {
- int len;
- int prep;
- vim_str2nr(pline.data, &prep, &len, STR2NR_ALL, NULL,
- &ret.data.num.val.integer, (int)pline.size);
- ret.len = (size_t)len;
- const uint8_t bases[] = {
- [0] = 10,
- ['0'] = 8,
- ['x'] = 16, ['X'] = 16,
- ['b'] = 2, ['B'] = 2,
- };
- ret.data.num.base = bases[prep];
}
- break;
+ ret.data.num.val.floating = scale_number(significand_part, 10, exp_part,
+ exp_negative);
+ } else {
+ int len;
+ int prep;
+ vim_str2nr(pline.data, &prep, &len, STR2NR_ALL, NULL,
+ &ret.data.num.val.integer, (int)pline.size, false);
+ ret.len = (size_t)len;
+ const uint8_t bases[] = {
+ [0] = 10,
+ ['0'] = 8,
+ ['x'] = 16, ['X'] = 16,
+ ['b'] = 2, ['B'] = 2,
+ };
+ ret.data.num.base = bases[prep];
}
+ break;
+ }
#define ISWORD_OR_AUTOLOAD(x) \
- (ascii_isident(x) || (x) == AUTOLOAD_CHAR)
-
- // Environment variable.
- case '$': {
- CHARREG(kExprLexEnv, ascii_isident);
- break;
- }
-
- // Normal variable/function name.
- case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g':
- case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
- case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u':
- case 'v': case 'w': case 'x': case 'y': case 'z':
- case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G':
- case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N':
- case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U':
- case 'V': case 'W': case 'X': case 'Y': case 'Z':
- case '_': {
- ret.data.var.scope = 0;
- ret.data.var.autoload = false;
- CHARREG(kExprLexPlainIdentifier, ascii_isident);
- // "is" and "isnot" operators.
- if (!(flags & kELFlagIsNotCmp)
- && ((ret.len == 2 && memcmp(pline.data, "is", 2) == 0)
- || (ret.len == 5 && memcmp(pline.data, "isnot", 5) == 0))) {
- ret.type = kExprLexComparison;
- ret.data.cmp.type = kExprCmpIdentical;
- ret.data.cmp.inv = (ret.len == 5);
- GET_CCS(ret, pline);
+ (ascii_isident(x) || (x) == AUTOLOAD_CHAR)
+
+ // Environment variable.
+ case '$':
+ CHARREG(kExprLexEnv, ascii_isident);
+ break;
+
+ // Normal variable/function name.
+ case 'a':
+ case 'b':
+ case 'c':
+ case 'd':
+ case 'e':
+ case 'f':
+ case 'g':
+ case 'h':
+ case 'i':
+ case 'j':
+ case 'k':
+ case 'l':
+ case 'm':
+ case 'n':
+ case 'o':
+ case 'p':
+ case 'q':
+ case 'r':
+ case 's':
+ case 't':
+ case 'u':
+ case 'v':
+ case 'w':
+ case 'x':
+ case 'y':
+ case 'z':
+ case 'A':
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'E':
+ case 'F':
+ case 'G':
+ case 'H':
+ case 'I':
+ case 'J':
+ case 'K':
+ case 'L':
+ case 'M':
+ case 'N':
+ case 'O':
+ case 'P':
+ case 'Q':
+ case 'R':
+ case 'S':
+ case 'T':
+ case 'U':
+ case 'V':
+ case 'W':
+ case 'X':
+ case 'Y':
+ case 'Z':
+ case '_':
+ ret.data.var.scope = 0;
+ ret.data.var.autoload = false;
+ CHARREG(kExprLexPlainIdentifier, ascii_isident);
+ // "is" and "isnot" operators.
+ if (!(flags & kELFlagIsNotCmp)
+ && ((ret.len == 2 && memcmp(pline.data, "is", 2) == 0)
+ || (ret.len == 5 && memcmp(pline.data, "isnot", 5) == 0))) {
+ ret.type = kExprLexComparison;
+ ret.data.cmp.type = kExprCmpIdentical;
+ ret.data.cmp.inv = (ret.len == 5);
+ GET_CCS(ret, pline);
// Scope: `s:`, etc.
- } else if (ret.len == 1
- && pline.size > 1
- && memchr(EXPR_VAR_SCOPE_LIST, schar,
- sizeof(EXPR_VAR_SCOPE_LIST)) != NULL
- && pline.data[ret.len] == ':'
- && !(flags & kELFlagForbidScope)) {
- ret.len++;
- ret.data.var.scope = (ExprVarScope)schar;
- CHARREG(kExprLexPlainIdentifier, ISWORD_OR_AUTOLOAD);
- ret.data.var.autoload = (
- memchr(pline.data + 2, AUTOLOAD_CHAR, ret.len - 2)
- != NULL);
+ } else if (ret.len == 1
+ && pline.size > 1
+ && memchr(EXPR_VAR_SCOPE_LIST, schar,
+ sizeof(EXPR_VAR_SCOPE_LIST)) != NULL
+ && pline.data[ret.len] == ':'
+ && !(flags & kELFlagForbidScope)) {
+ ret.len++;
+ ret.data.var.scope = (ExprVarScope)schar;
+ CHARREG(kExprLexPlainIdentifier, ISWORD_OR_AUTOLOAD);
+ ret.data.var.autoload = (
+ memchr(pline.data + 2, AUTOLOAD_CHAR, ret.len - 2)
+ != NULL);
// Previous CHARREG stopped at autoload character in order to make it
// possible to detect `is#`. Continue now with autoload characters
// included.
@@ -432,221 +496,213 @@ LexExprToken viml_pexpr_next_token(ParserState *const pstate, const int flags)
// Warning: there is ambiguity for the lexer: `is#Foo(1)` is a call of
// function `is#Foo()`, `1is#Foo(1)` is a comparison `1 is# Foo(1)`. This
// needs to be resolved on the higher level where context is available.
- } else if (pline.size > ret.len
- && pline.data[ret.len] == AUTOLOAD_CHAR) {
- ret.data.var.autoload = true;
- CHARREG(kExprLexPlainIdentifier, ISWORD_OR_AUTOLOAD);
- }
- break;
+ } else if (pline.size > ret.len
+ && pline.data[ret.len] == AUTOLOAD_CHAR) {
+ ret.data.var.autoload = true;
+ CHARREG(kExprLexPlainIdentifier, ISWORD_OR_AUTOLOAD);
}
+ break;
#undef ISWORD_OR_AUTOLOAD
#undef CHARREG
- // Option.
- case '&': {
+ // Option.
+ case '&': {
#define OPTNAMEMISS(ret) \
- do { \
- ret.type = kExprLexInvalid; \
- ret.data.err.type = kExprLexOption; \
- ret.data.err.msg = _("E112: Option name missing: %.*s"); \
- } while (0)
- if (pline.size > 1 && pline.data[1] == '&') {
- ret.type = kExprLexAnd;
- ret.len++;
- break;
+ do { \
+ ret.type = kExprLexInvalid; \
+ ret.data.err.type = kExprLexOption; \
+ ret.data.err.msg = _("E112: Option name missing: %.*s"); \
+ } while (0)
+ if (pline.size > 1 && pline.data[1] == '&') {
+ ret.type = kExprLexAnd;
+ ret.len++;
+ break;
+ }
+ if (pline.size == 1 || !ASCII_ISALPHA(pline.data[1])) {
+ OPTNAMEMISS(ret);
+ break;
+ }
+ ret.type = kExprLexOption;
+ if (pline.size > 2
+ && pline.data[2] == ':'
+ && memchr(EXPR_OPT_SCOPE_LIST, pline.data[1],
+ sizeof(EXPR_OPT_SCOPE_LIST)) != NULL) {
+ ret.len += 2;
+ ret.data.opt.scope = (ExprOptScope)pline.data[1];
+ ret.data.opt.name = pline.data + 3;
+ } else {
+ ret.data.opt.scope = kExprOptScopeUnspecified;
+ ret.data.opt.name = pline.data + 1;
+ }
+ const char *p = ret.data.opt.name;
+ const char *const e = pline.data + pline.size;
+ if (e - p >= 4 && p[0] == 't' && p[1] == '_') {
+ ret.data.opt.len = 4;
+ ret.len += 4;
+ } else {
+ for (; p < e && ASCII_ISALPHA(*p); p++) {
}
- if (pline.size == 1 || !ASCII_ISALPHA(pline.data[1])) {
+ ret.data.opt.len = (size_t)(p - ret.data.opt.name);
+ if (ret.data.opt.len == 0) {
OPTNAMEMISS(ret);
- break;
- }
- ret.type = kExprLexOption;
- if (pline.size > 2
- && pline.data[2] == ':'
- && memchr(EXPR_OPT_SCOPE_LIST, pline.data[1],
- sizeof(EXPR_OPT_SCOPE_LIST)) != NULL) {
- ret.len += 2;
- ret.data.opt.scope = (ExprOptScope)pline.data[1];
- ret.data.opt.name = pline.data + 3;
} else {
- ret.data.opt.scope = kExprOptScopeUnspecified;
- ret.data.opt.name = pline.data + 1;
- }
- const char *p = ret.data.opt.name;
- const char *const e = pline.data + pline.size;
- if (e - p >= 4 && p[0] == 't' && p[1] == '_') {
- ret.data.opt.len = 4;
- ret.len += 4;
- } else {
- for (; p < e && ASCII_ISALPHA(*p); p++) {
- }
- ret.data.opt.len = (size_t)(p - ret.data.opt.name);
- if (ret.data.opt.len == 0) {
- OPTNAMEMISS(ret);
- } else {
- ret.len += ret.data.opt.len;
- }
+ ret.len += ret.data.opt.len;
}
- break;
-#undef OPTNAMEMISS
}
+ break;
+#undef OPTNAMEMISS
+ }
- // Register.
- case '@': {
- ret.type = kExprLexRegister;
- if (pline.size > 1) {
- ret.len++;
- ret.data.reg.name = (uint8_t)pline.data[1];
- } else {
- ret.data.reg.name = -1;
- }
- break;
+ // Register.
+ case '@':
+ ret.type = kExprLexRegister;
+ if (pline.size > 1) {
+ ret.len++;
+ ret.data.reg.name = (uint8_t)pline.data[1];
+ } else {
+ ret.data.reg.name = -1;
}
-
- // Single quoted string.
- case '\'': {
- ret.type = kExprLexSingleQuotedString;
- ret.data.str.closed = false;
- for (; ret.len < pline.size && !ret.data.str.closed; ret.len++) {
- if (pline.data[ret.len] == '\'') {
- if (ret.len + 1 < pline.size && pline.data[ret.len + 1] == '\'') {
- ret.len++;
- } else {
- ret.data.str.closed = true;
- }
+ break;
+
+ // Single quoted string.
+ case '\'':
+ ret.type = kExprLexSingleQuotedString;
+ ret.data.str.closed = false;
+ for (; ret.len < pline.size && !ret.data.str.closed; ret.len++) {
+ if (pline.data[ret.len] == '\'') {
+ if (ret.len + 1 < pline.size && pline.data[ret.len + 1] == '\'') {
+ ret.len++;
+ } else {
+ ret.data.str.closed = true;
}
}
- break;
}
-
- // Double quoted string.
- case '"': {
- ret.type = kExprLexDoubleQuotedString;
- ret.data.str.closed = false;
- for (; ret.len < pline.size && !ret.data.str.closed; ret.len++) {
- if (pline.data[ret.len] == '\\') {
- if (ret.len + 1 < pline.size) {
- ret.len++;
- }
- } else if (pline.data[ret.len] == '"') {
- ret.data.str.closed = true;
+ break;
+
+ // Double quoted string.
+ case '"':
+ ret.type = kExprLexDoubleQuotedString;
+ ret.data.str.closed = false;
+ for (; ret.len < pline.size && !ret.data.str.closed; ret.len++) {
+ if (pline.data[ret.len] == '\\') {
+ if (ret.len + 1 < pline.size) {
+ ret.len++;
}
+ } else if (pline.data[ret.len] == '"') {
+ ret.data.str.closed = true;
}
- break;
}
-
- // Unary not, (un)equality and regex (not) match comparison operators.
- case '!':
- case '=': {
- if (pline.size == 1) {
- ret.type = (schar == '!' ? kExprLexNot : kExprLexAssignment);
- ret.data.ass.type = kExprAsgnPlain;
- break;
- }
- ret.type = kExprLexComparison;
- ret.data.cmp.inv = (schar == '!');
- if (pline.data[1] == '=') {
- ret.data.cmp.type = kExprCmpEqual;
- ret.len++;
- } else if (pline.data[1] == '~') {
- ret.data.cmp.type = kExprCmpMatches;
- ret.len++;
- } else if (schar == '!') {
- ret.type = kExprLexNot;
- } else {
- ret.type = kExprLexAssignment;
- ret.data.ass.type = kExprAsgnPlain;
- }
- GET_CCS(ret, pline);
+ break;
+
+ // Unary not, (un)equality and regex (not) match comparison operators.
+ case '!':
+ case '=':
+ if (pline.size == 1) {
+ ret.type = (schar == '!' ? kExprLexNot : kExprLexAssignment);
+ ret.data.ass.type = kExprAsgnPlain;
break;
}
-
- // Less/greater [or equal to] comparison operators.
- case '>':
- case '<': {
- ret.type = kExprLexComparison;
- const bool haseqsign = (pline.size > 1 && pline.data[1] == '=');
- if (haseqsign) {
- ret.len++;
- }
- GET_CCS(ret, pline);
- ret.data.cmp.inv = (schar == '<');
- ret.data.cmp.type = ((ret.data.cmp.inv ^ haseqsign)
+ ret.type = kExprLexComparison;
+ ret.data.cmp.inv = (schar == '!');
+ if (pline.data[1] == '=') {
+ ret.data.cmp.type = kExprCmpEqual;
+ ret.len++;
+ } else if (pline.data[1] == '~') {
+ ret.data.cmp.type = kExprCmpMatches;
+ ret.len++;
+ } else if (schar == '!') {
+ ret.type = kExprLexNot;
+ } else {
+ ret.type = kExprLexAssignment;
+ ret.data.ass.type = kExprAsgnPlain;
+ }
+ GET_CCS(ret, pline);
+ break;
+
+ // Less/greater [or equal to] comparison operators.
+ case '>':
+ case '<': {
+ ret.type = kExprLexComparison;
+ const bool haseqsign = (pline.size > 1 && pline.data[1] == '=');
+ if (haseqsign) {
+ ret.len++;
+ }
+ GET_CCS(ret, pline);
+ ret.data.cmp.inv = (schar == '<');
+ ret.data.cmp.type = ((ret.data.cmp.inv ^ haseqsign)
? kExprCmpGreaterOrEqual
: kExprCmpGreater);
- break;
- }
+ break;
+ }
- // Minus sign, arrow from lambdas or augmented assignment.
- case '-': {
- if (pline.size > 1 && pline.data[1] == '>') {
- ret.len++;
- ret.type = kExprLexArrow;
- } else if (pline.size > 1 && pline.data[1] == '=') {
- ret.len++;
- ret.type = kExprLexAssignment;
- ret.data.ass.type = kExprAsgnSubtract;
- } else {
- ret.type = kExprLexMinus;
- }
- break;
+ // Minus sign, arrow from lambdas or augmented assignment.
+ case '-': {
+ if (pline.size > 1 && pline.data[1] == '>') {
+ ret.len++;
+ ret.type = kExprLexArrow;
+ } else if (pline.size > 1 && pline.data[1] == '=') {
+ ret.len++;
+ ret.type = kExprLexAssignment;
+ ret.data.ass.type = kExprAsgnSubtract;
+ } else {
+ ret.type = kExprLexMinus;
}
+ break;
+ }
// Sign or augmented assignment.
#define CHAR_OR_ASSIGN(ch, ch_type, ass_type) \
- case ch: { \
- if (pline.size > 1 && pline.data[1] == '=') { \
- ret.len++; \
- ret.type = kExprLexAssignment; \
- ret.data.ass.type = ass_type; \
- } else { \
- ret.type = ch_type; \
- } \
- break; \
- }
+case ch: { \
+ if (pline.size > 1 && pline.data[1] == '=') { \
+ ret.len++; \
+ ret.type = kExprLexAssignment; \
+ ret.data.ass.type = ass_type; \
+ } else { \
+ ret.type = ch_type; \
+ } \
+ break; \
+}
CHAR_OR_ASSIGN('+', kExprLexPlus, kExprAsgnAdd)
CHAR_OR_ASSIGN('.', kExprLexDot, kExprAsgnConcat)
#undef CHAR_OR_ASSIGN
- // Expression end because Ex command ended.
- case NUL:
- case NL: {
- if (flags & kELFlagForbidEOC) {
- ret.type = kExprLexInvalid;
- ret.data.err.msg = _("E15: Unexpected EOC character: %.*s");
- ret.data.err.type = kExprLexSpacing;
- } else {
- ret.type = kExprLexEOC;
- }
- break;
- }
-
- case '|': {
- if (pline.size >= 2 && pline.data[ret.len] == '|') {
- // "||" is or.
- ret.len++;
- ret.type = kExprLexOr;
- } else if (flags & kELFlagForbidEOC) {
- // Note: `<C-r>=1 | 2<CR>` actually yields 1 in Vim without any
- // errors. This will be changed here.
- ret.type = kExprLexInvalid;
- ret.data.err.msg = _("E15: Unexpected EOC character: %.*s");
- ret.data.err.type = kExprLexOr;
- } else {
- ret.type = kExprLexEOC;
- }
- break;
+ // Expression end because Ex command ended.
+ case NUL:
+ case NL:
+ if (flags & kELFlagForbidEOC) {
+ ret.type = kExprLexInvalid;
+ ret.data.err.msg = _("E15: Unexpected EOC character: %.*s");
+ ret.data.err.type = kExprLexSpacing;
+ } else {
+ ret.type = kExprLexEOC;
}
-
- // Everything else is not valid.
- default: {
- ret.len = (size_t)utfc_ptr2len_len((const char_u *)pline.data,
- (int)pline.size);
+ break;
+
+ case '|':
+ if (pline.size >= 2 && pline.data[ret.len] == '|') {
+ // "||" is or.
+ ret.len++;
+ ret.type = kExprLexOr;
+ } else if (flags & kELFlagForbidEOC) {
+ // Note: `<C-r>=1 | 2<CR>` actually yields 1 in Vim without any
+ // errors. This will be changed here.
ret.type = kExprLexInvalid;
- ret.data.err.type = kExprLexPlainIdentifier;
- ret.data.err.msg = _("E15: Unidentified character: %.*s");
- break;
+ ret.data.err.msg = _("E15: Unexpected EOC character: %.*s");
+ ret.data.err.type = kExprLexOr;
+ } else {
+ ret.type = kExprLexEOC;
}
+ break;
+
+ // Everything else is not valid.
+ default:
+ ret.len = (size_t)utfc_ptr2len_len((const char_u *)pline.data,
+ (int)pline.size);
+ ret.type = kExprLexInvalid;
+ ret.data.err.type = kExprLexPlainIdentifier;
+ ret.data.err.msg = _("E15: Unidentified character: %.*s");
+ break;
}
#undef GET_CCS
viml_pexpr_next_token_adv_return:
@@ -737,8 +793,7 @@ static const char *const eltkn_opt_scope_tab[] = {
///
/// @return Token represented in a string form, in a static buffer (overwritten
/// on each call).
-const char *viml_pexpr_repr_token(const ParserState *const pstate,
- const LexExprToken token,
+const char *viml_pexpr_repr_token(const ParserState *const pstate, const LexExprToken token,
size_t *const ret_size)
FUNC_ATTR_WARN_UNUSED_RESULT
{
@@ -756,10 +811,10 @@ const char *viml_pexpr_repr_token(const ParserState *const pstate,
eltkn_type_tab[token.type]);
switch (token.type) {
#define TKNARGS(tkn_type, ...) \
- case tkn_type: { \
- ADDSTR(__VA_ARGS__); \
- break; \
- }
+case tkn_type: { \
+ ADDSTR(__VA_ARGS__); \
+ break; \
+}
TKNARGS(kExprLexComparison, "(type=%s,ccs=%s,inv=%i)",
eltkn_cmp_type_tab[token.data.cmp.type],
ccs_tab[token.data.cmp.ccs],
@@ -769,7 +824,7 @@ const char *viml_pexpr_repr_token(const ParserState *const pstate,
TKNARGS(kExprLexAssignment, "(type=%s)",
expr_asgn_type_tab[token.data.ass.type])
TKNARGS(kExprLexRegister, "(name=%s)", intchar2str(token.data.reg.name))
- case kExprLexDoubleQuotedString:
+ case kExprLexDoubleQuotedString:
TKNARGS(kExprLexSingleQuotedString, "(closed=%i)",
(int)token.data.str.closed)
TKNARGS(kExprLexOption, "(scope=%s,name=%.*s)",
@@ -785,19 +840,17 @@ const char *viml_pexpr_repr_token(const ParserState *const pstate,
? (double)token.data.num.val.floating
: (double)token.data.num.val.integer))
TKNARGS(kExprLexInvalid, "(msg=%s)", token.data.err.msg)
- default: {
- // No additional arguments.
- break;
- }
+ default:
+ // No additional arguments.
+ break;
#undef TKNARGS
}
if (pstate == NULL) {
ADDSTR("::%zu", token.len);
} else {
*p++ = ':';
- memmove(
- p, &pstate->reader.lines.items[token.start.line].data[token.start.col],
- token.len);
+ memmove(p, &pstate->reader.lines.items[token.start.line].data[token.start.col],
+ token.len);
p += token.len;
*p = NUL;
}
@@ -860,7 +913,7 @@ const char *const east_node_type_tab[] = {
///
/// @param[in] ch Character to convert.
///
-/// @return Converted string, stored in a static buffer (overriden after each
+/// @return Converted string, stored in a static buffer (overridden after each
/// call).
static const char *intchar2str(const int ch)
FUNC_ATTR_WARN_UNUSED_RESULT
@@ -883,12 +936,11 @@ static const char *intchar2str(const int ch)
}
#ifdef UNIT_TESTING
-#include <stdio.h>
+# include <stdio.h>
REAL_FATTR_UNUSED
-static inline void viml_pexpr_debug_print_ast_node(
- const ExprASTNode *const *const eastnode_p,
- const char *const prefix)
+static inline void viml_pexpr_debug_print_ast_node(const ExprASTNode *const *const eastnode_p,
+ const char *const prefix)
{
if (*eastnode_p == NULL) {
fprintf(stderr, "%s %p : NULL\n", prefix, (void *)eastnode_p);
@@ -901,35 +953,33 @@ static inline void viml_pexpr_debug_print_ast_node(
}
REAL_FATTR_UNUSED
-static inline void viml_pexpr_debug_print_ast_stack(
- const ExprASTStack *const ast_stack,
- const char *const msg)
+static inline void viml_pexpr_debug_print_ast_stack(const ExprASTStack *const ast_stack,
+ const char *const msg)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_ALWAYS_INLINE
{
fprintf(stderr, "\n%sstack: %zu:\n", msg, kv_size(*ast_stack));
for (size_t i = 0; i < kv_size(*ast_stack); i++) {
- viml_pexpr_debug_print_ast_node(
- (const ExprASTNode *const *)kv_A(*ast_stack, i),
- "-");
+ viml_pexpr_debug_print_ast_node((const ExprASTNode *const *)kv_A(*ast_stack, i),
+ "-");
}
}
REAL_FATTR_UNUSED
-static inline void viml_pexpr_debug_print_token(
- const ParserState *const pstate, const LexExprToken token)
+static inline void viml_pexpr_debug_print_token(const ParserState *const pstate,
+ const LexExprToken token)
FUNC_ATTR_ALWAYS_INLINE
{
fprintf(stderr, "\ntkn: %s\n", viml_pexpr_repr_token(pstate, token, NULL));
}
-#define PSTACK(msg) \
- viml_pexpr_debug_print_ast_stack(&ast_stack, #msg)
-#define PSTACK_P(msg) \
- viml_pexpr_debug_print_ast_stack(ast_stack, #msg)
-#define PNODE_P(eastnode_p, msg) \
- viml_pexpr_debug_print_ast_node((const ExprASTNode *const *)eastnode_p, \
- (#msg))
-#define PTOKEN(tkn) \
- viml_pexpr_debug_print_token(pstate, tkn)
+# define PSTACK(msg) \
+ viml_pexpr_debug_print_ast_stack(&ast_stack, #msg)
+# define PSTACK_P(msg) \
+ viml_pexpr_debug_print_ast_stack(ast_stack, #msg)
+# define PNODE_P(eastnode_p, msg) \
+ viml_pexpr_debug_print_ast_node((const ExprASTNode *const *)eastnode_p, \
+ (#msg))
+# define PTOKEN(tkn) \
+ viml_pexpr_debug_print_token(pstate, tkn)
#endif
const uint8_t node_maxchildren[] = {
@@ -1009,50 +1059,48 @@ void viml_pexpr_free_ast(ExprAST ast)
} else if (*cur_node != NULL) {
kv_drop(ast_stack, 1);
switch ((*cur_node)->type) {
- case kExprNodeDoubleQuotedString:
- case kExprNodeSingleQuotedString: {
- xfree((*cur_node)->data.str.value);
- break;
- }
- case kExprNodeMissing:
- case kExprNodeOpMissing:
- case kExprNodeTernary:
- case kExprNodeTernaryValue:
- case kExprNodeRegister:
- case kExprNodeSubscript:
- case kExprNodeListLiteral:
- case kExprNodeUnaryPlus:
- case kExprNodeBinaryPlus:
- case kExprNodeNested:
- case kExprNodeCall:
- case kExprNodePlainIdentifier:
- case kExprNodePlainKey:
- case kExprNodeComplexIdentifier:
- case kExprNodeUnknownFigure:
- case kExprNodeLambda:
- case kExprNodeDictLiteral:
- case kExprNodeCurlyBracesIdentifier:
- case kExprNodeAssignment:
- case kExprNodeComma:
- case kExprNodeColon:
- case kExprNodeArrow:
- case kExprNodeComparison:
- case kExprNodeConcat:
- case kExprNodeConcatOrSubscript:
- case kExprNodeInteger:
- case kExprNodeFloat:
- case kExprNodeOr:
- case kExprNodeAnd:
- case kExprNodeUnaryMinus:
- case kExprNodeBinaryMinus:
- case kExprNodeNot:
- case kExprNodeMultiplication:
- case kExprNodeDivision:
- case kExprNodeMod:
- case kExprNodeOption:
- case kExprNodeEnvironment: {
- break;
- }
+ case kExprNodeDoubleQuotedString:
+ case kExprNodeSingleQuotedString:
+ xfree((*cur_node)->data.str.value);
+ break;
+ case kExprNodeMissing:
+ case kExprNodeOpMissing:
+ case kExprNodeTernary:
+ case kExprNodeTernaryValue:
+ case kExprNodeRegister:
+ case kExprNodeSubscript:
+ case kExprNodeListLiteral:
+ case kExprNodeUnaryPlus:
+ case kExprNodeBinaryPlus:
+ case kExprNodeNested:
+ case kExprNodeCall:
+ case kExprNodePlainIdentifier:
+ case kExprNodePlainKey:
+ case kExprNodeComplexIdentifier:
+ case kExprNodeUnknownFigure:
+ case kExprNodeLambda:
+ case kExprNodeDictLiteral:
+ case kExprNodeCurlyBracesIdentifier:
+ case kExprNodeAssignment:
+ case kExprNodeComma:
+ case kExprNodeColon:
+ case kExprNodeArrow:
+ case kExprNodeComparison:
+ case kExprNodeConcat:
+ case kExprNodeConcatOrSubscript:
+ case kExprNodeInteger:
+ case kExprNodeFloat:
+ case kExprNodeOr:
+ case kExprNodeAnd:
+ case kExprNodeUnaryMinus:
+ case kExprNodeBinaryMinus:
+ case kExprNodeNot:
+ case kExprNodeMultiplication:
+ case kExprNodeDivision:
+ case kExprNodeMod:
+ case kExprNodeOption:
+ case kExprNodeEnvironment:
+ break;
}
xfree(*cur_node);
*cur_node = NULL;
@@ -1204,10 +1252,8 @@ static inline ExprOpAssociativity node_ass(const ExprASTNode node)
/// @param[out] ast_err Location where error is saved, if any.
///
/// @return True if no errors occurred, false otherwise.
-static bool viml_pexpr_handle_bop(const ParserState *const pstate,
- ExprASTStack *const ast_stack,
- ExprASTNode *const bop_node,
- ExprASTWantedNode *const want_node_p,
+static bool viml_pexpr_handle_bop(const ParserState *const pstate, ExprASTStack *const ast_stack,
+ ExprASTNode *const bop_node, ExprASTWantedNode *const want_node_p,
ExprASTError *const ast_err)
FUNC_ATTR_NONNULL_ALL
{
@@ -1223,8 +1269,8 @@ static bool viml_pexpr_handle_bop(const ParserState *const pstate,
: node_lvl(*bop_node));
#ifndef NDEBUG
const ExprOpAssociativity bop_node_ass = (
- (bop_node->type == kExprNodeCall
- || bop_node->type == kExprNodeSubscript)
+ (bop_node->type == kExprNodeCall
+ || bop_node->type == kExprNodeSubscript)
? kEOpAssLeft
: node_ass(*bop_node));
#endif
@@ -1301,8 +1347,7 @@ static bool viml_pexpr_handle_bop(const ParserState *const pstate,
/// @param[in] shift Number of bytes to shift.
///
/// @return Shifted position.
-static inline ParserPosition shifted_pos(const ParserPosition pos,
- const size_t shift)
+static inline ParserPosition shifted_pos(const ParserPosition pos, const size_t shift)
FUNC_ATTR_CONST FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_WARN_UNUSED_RESULT
{
return (ParserPosition) { .line = pos.line, .col = pos.col + shift };
@@ -1316,8 +1361,7 @@ static inline ParserPosition shifted_pos(const ParserPosition pos,
/// @param[in] new_col New column.
///
/// @return Shifted position.
-static inline ParserPosition recol_pos(const ParserPosition pos,
- const size_t new_col)
+static inline ParserPosition recol_pos(const ParserPosition pos, const size_t new_col)
FUNC_ATTR_CONST FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_WARN_UNUSED_RESULT
{
return (ParserPosition) { .line = pos.line, .col = new_col };
@@ -1328,22 +1372,22 @@ static inline ParserPosition recol_pos(const ParserPosition pos,
/// Highlight current token with the given group
#define HL_CUR_TOKEN(g) \
- viml_parser_highlight(pstate, cur_token.start, cur_token.len, \
- HL(g))
+ viml_parser_highlight(pstate, cur_token.start, cur_token.len, \
+ HL(g))
/// Allocate new node, saving some values
#define NEW_NODE(type) \
- viml_pexpr_new_node(type)
+ viml_pexpr_new_node(type)
/// Set position of the given node to position from the given token
///
/// @param cur_node Node to modify.
/// @param cur_token Token to set position from.
#define POS_FROM_TOKEN(cur_node, cur_token) \
- do { \
- (cur_node)->start = cur_token.start; \
- (cur_node)->len = cur_token.len; \
- } while (0)
+ do { \
+ (cur_node)->start = cur_token.start; \
+ (cur_node)->len = cur_token.len; \
+ } while (0)
/// Allocate new node and set its position from the current token
///
@@ -1352,27 +1396,27 @@ static inline ParserPosition recol_pos(const ParserPosition pos,
/// @param cur_node Variable to save allocated node to.
/// @param typ Node type.
#define NEW_NODE_WITH_CUR_POS(cur_node, typ) \
- do { \
- (cur_node) = NEW_NODE(typ); \
- POS_FROM_TOKEN((cur_node), cur_token); \
- if (prev_token.type == kExprLexSpacing) { \
- (cur_node)->start = prev_token.start; \
- (cur_node)->len += prev_token.len; \
- } \
- } while (0)
+ do { \
+ (cur_node) = NEW_NODE(typ); \
+ POS_FROM_TOKEN((cur_node), cur_token); \
+ if (prev_token.type == kExprLexSpacing) { \
+ (cur_node)->start = prev_token.start; \
+ (cur_node)->len += prev_token.len; \
+ } \
+ } while (0)
/// Check whether it is possible to have next expression after current
///
/// For :echo: `:echo @a @a` is a valid expression. `:echo (@a @a)` is not.
#define MAY_HAVE_NEXT_EXPR \
- (kv_size(ast_stack) == 1)
+ (kv_size(ast_stack) == 1)
/// Add operator node
///
/// @param[in] cur_node Node to add.
#define ADD_OP_NODE(cur_node) \
- is_invalid |= !viml_pexpr_handle_bop(pstate, &ast_stack, cur_node, \
- &want_node, &ast.err)
+ is_invalid |= !viml_pexpr_handle_bop(pstate, &ast_stack, cur_node, \
+ &want_node, &ast.err)
/// Record missing operator: for things like
///
@@ -1384,33 +1428,33 @@ static inline ParserPosition recol_pos(const ParserPosition pos,
///
/// (parsed as OpMissing(@a, @a)).
#define OP_MISSING \
- do { \
- if (flags & kExprFlagsMulti && MAY_HAVE_NEXT_EXPR) { \
- /* Multiple expressions allowed, return without calling */ \
- /* viml_parser_advance(). */ \
- goto viml_pexpr_parse_end; \
- } else { \
- assert(*top_node_p != NULL); \
- ERROR_FROM_TOKEN_AND_MSG(cur_token, _("E15: Missing operator: %.*s")); \
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeOpMissing); \
- cur_node->len = 0; \
- ADD_OP_NODE(cur_node); \
- goto viml_pexpr_parse_process_token; \
- } \
- } while (0)
+ do { \
+ if (flags & kExprFlagsMulti && MAY_HAVE_NEXT_EXPR) { \
+ /* Multiple expressions allowed, return without calling */ \
+ /* viml_parser_advance(). */ \
+ goto viml_pexpr_parse_end; \
+ } else { \
+ assert(*top_node_p != NULL); \
+ ERROR_FROM_TOKEN_AND_MSG(cur_token, _("E15: Missing operator: %.*s")); \
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeOpMissing); \
+ cur_node->len = 0; \
+ ADD_OP_NODE(cur_node); \
+ goto viml_pexpr_parse_process_token; \
+ } \
+ } while (0)
/// Record missing value: for things like "* 5"
///
/// @param[in] msg Error message.
#define ADD_VALUE_IF_MISSING(msg) \
- do { \
- if (want_node == kENodeValue) { \
- ERROR_FROM_TOKEN_AND_MSG(cur_token, (msg)); \
- NEW_NODE_WITH_CUR_POS((*top_node_p), kExprNodeMissing); \
- (*top_node_p)->len = 0; \
- want_node = kENodeOperator; \
- } \
- } while (0)
+ do { \
+ if (want_node == kENodeValue) { \
+ ERROR_FROM_TOKEN_AND_MSG(cur_token, (msg)); \
+ NEW_NODE_WITH_CUR_POS((*top_node_p), kExprNodeMissing); \
+ (*top_node_p)->len = 0; \
+ want_node = kENodeOperator; \
+ } \
+ } while (0)
/// Set AST error, unless AST already is not correct
///
@@ -1419,10 +1463,8 @@ static inline ParserPosition recol_pos(const ParserPosition pos,
/// @param[in] msg Error message, assumed to be already translated and
/// containing a single %token "%.*s".
/// @param[in] start Position at which error occurred.
-static inline void east_set_error(const ParserState *const pstate,
- ExprASTError *const ret_ast_err,
- const char *const msg,
- const ParserPosition start)
+static inline void east_set_error(const ParserState *const pstate, ExprASTError *const ret_ast_err,
+ const char *const msg, const ParserPosition start)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_ALWAYS_INLINE
{
if (ret_ast_err->msg != NULL) {
@@ -1436,21 +1478,21 @@ static inline void east_set_error(const ParserState *const pstate,
/// Set error from the given token and given message
#define ERROR_FROM_TOKEN_AND_MSG(cur_token, msg) \
- do { \
- is_invalid = true; \
- east_set_error(pstate, &ast.err, msg, cur_token.start); \
- } while (0)
+ do { \
+ is_invalid = true; \
+ east_set_error(pstate, &ast.err, msg, cur_token.start); \
+ } while (0)
/// Like #ERROR_FROM_TOKEN_AND_MSG, but gets position from a node
#define ERROR_FROM_NODE_AND_MSG(node, msg) \
- do { \
- is_invalid = true; \
- east_set_error(pstate, &ast.err, msg, node->start); \
- } while (0)
+ do { \
+ is_invalid = true; \
+ east_set_error(pstate, &ast.err, msg, node->start); \
+ } while (0)
/// Set error from the given kExprLexInvalid token
#define ERROR_FROM_TOKEN(cur_token) \
- ERROR_FROM_TOKEN_AND_MSG(cur_token, cur_token.data.err.msg)
+ ERROR_FROM_TOKEN_AND_MSG(cur_token, cur_token.data.err.msg)
/// Select figure brace type, altering highlighting as well if needed
///
@@ -1459,16 +1501,16 @@ static inline void east_set_error(const ParserState *const pstate,
/// kExprNode prefix.
/// @param[in] hl Corresponding highlighting, passed as an argument to #HL.
#define SELECT_FIGURE_BRACE_TYPE(node, new_type, hl) \
- do { \
- ExprASTNode *const node_ = (node); \
- assert(node_->type == kExprNodeUnknownFigure \
- || node_->type == kExprNode##new_type); \
- node_->type = kExprNode##new_type; \
- if (pstate->colors) { \
- kv_A(*pstate->colors, node_->data.fig.opening_hl_idx).group = \
- HL(hl); \
- } \
- } while (0)
+ do { \
+ ExprASTNode *const node_ = (node); \
+ assert(node_->type == kExprNodeUnknownFigure \
+ || node_->type == kExprNode##new_type); \
+ node_->type = kExprNode##new_type; \
+ if (pstate->colors) { \
+ kv_A(*pstate->colors, node_->data.fig.opening_hl_idx).group = \
+ HL(hl); \
+ } \
+ } while (0)
/// Add identifier which should constitute complex identifier node
///
@@ -1479,45 +1521,45 @@ static inline void east_set_error(const ParserState *const pstate,
/// a trailing semicolon.
/// @param hl Highlighting name to use, passed as an argument to #HL.
#define ADD_IDENT(new_ident_node_code, hl) \
- do { \
- assert(want_node == kENodeOperator); \
- /* Operator: may only be curly braces name, but only under certain */ \
- /* conditions. */ \
+ do { \
+ assert(want_node == kENodeOperator); \
+ /* Operator: may only be curly braces name, but only under certain */ \
+ /* conditions. */ \
\
- /* First condition is that there is no space before a part of complex */ \
- /* identifier. */ \
- if (prev_token.type == kExprLexSpacing) { \
- OP_MISSING; \
- } \
- switch ((*top_node_p)->type) { \
- /* Second is that previous node is one of the identifiers: */ \
- /* complex, plain, curly braces. */ \
+ /* First condition is that there is no space before a part of complex */ \
+ /* identifier. */ \
+ if (prev_token.type == kExprLexSpacing) { \
+ OP_MISSING; \
+ } \
+ switch ((*top_node_p)->type) { \
+ /* Second is that previous node is one of the identifiers: */ \
+ /* complex, plain, curly braces. */ \
\
- /* TODO(ZyX-I): Extend syntax to allow ${expr}. This is needed to */ \
- /* handle environment variables like those bash uses for */ \
- /* `export -f`: their names consist not only of alphanumeric */ \
- /* characetrs. */ \
- case kExprNodeComplexIdentifier: \
- case kExprNodePlainIdentifier: \
- case kExprNodeCurlyBracesIdentifier: { \
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeComplexIdentifier); \
- cur_node->len = 0; \
- cur_node->children = *top_node_p; \
- *top_node_p = cur_node; \
- kvi_push(ast_stack, &cur_node->children->next); \
- ExprASTNode **const new_top_node_p = kv_last(ast_stack); \
- assert(*new_top_node_p == NULL); \
- new_ident_node_code; \
- *new_top_node_p = cur_node; \
- HL_CUR_TOKEN(hl); \
- break; \
- } \
- default: { \
- OP_MISSING; \
- break; \
- } \
- } \
- } while (0)
+ /* TODO(ZyX-I): Extend syntax to allow ${expr}. This is needed to */ \
+ /* handle environment variables like those bash uses for */ \
+ /* `export -f`: their names consist not only of alphanumeric */ \
+ /* characetrs. */ \
+ case kExprNodeComplexIdentifier: \
+ case kExprNodePlainIdentifier: \
+ case kExprNodeCurlyBracesIdentifier: { \
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeComplexIdentifier); \
+ cur_node->len = 0; \
+ cur_node->children = *top_node_p; \
+ *top_node_p = cur_node; \
+ kvi_push(ast_stack, &cur_node->children->next); \
+ ExprASTNode **const new_top_node_p = kv_last(ast_stack); \
+ assert(*new_top_node_p == NULL); \
+ new_ident_node_code; \
+ *new_top_node_p = cur_node; \
+ HL_CUR_TOKEN(hl); \
+ break; \
+ } \
+ default: { \
+ OP_MISSING; \
+ break; \
+ } \
+ } \
+ } while (0)
/// Determine whether given parse type is an assignment
///
@@ -1551,10 +1593,8 @@ typedef struct {
/// @param[in] ast_stack Parser AST stack, used to detect whether current
/// string is a regex.
/// @param[in] is_invalid Whether currently processed token is not valid.
-static void parse_quoted_string(ParserState *const pstate,
- ExprASTNode *const node,
- const LexExprToken token,
- const ExprASTStack ast_stack,
+static void parse_quoted_string(ParserState *const pstate, ExprASTNode *const node,
+ const LexExprToken token, const ExprASTStack ast_stack,
const bool is_invalid)
FUNC_ATTR_NONNULL_ALL
{
@@ -1577,10 +1617,10 @@ static void parse_quoted_string(ParserState *const pstate,
p = chunk_e + 2;
if (pstate->colors) {
kvi_push(shifts, ((StringShift) {
- .start = token.start.col + (size_t)(chunk_e - s),
- .orig_len = 2,
- .act_len = 1,
- .escape_not_known = false,
+ .start = token.start.col + (size_t)(chunk_e - s),
+ .orig_len = 2,
+ .act_len = 1,
+ .escape_not_known = false,
}));
}
}
@@ -1613,70 +1653,74 @@ static void parse_quoted_string(ParserState *const pstate,
break;
}
switch (*p) {
- // A "\<x>" form occupies at least 4 characters, and produces up to
- // 6 characters: reserve space for 2 extra, but do not compute actual
- // length just now, it would be costy.
- case '<': {
- size += 2;
- break;
- }
- // Hexadecimal, always single byte, but at least three bytes each.
- case 'x': case 'X': {
+ // A "\<x>" form occupies at least 4 characters, and produces up to
+ // 6 characters: reserve space for 2 extra, but do not compute actual
+ // length just now, it would be costy.
+ case '<':
+ size += 2;
+ break;
+ // Hexadecimal, always single byte, but at least three bytes each.
+ case 'x':
+ case 'X':
+ size--;
+ if (ascii_isxdigit(p[1])) {
size--;
- if (ascii_isxdigit(p[1])) {
+ if (p + 2 < e && ascii_isxdigit(p[2])) {
size--;
- if (p + 2 < e && ascii_isxdigit(p[2])) {
- size--;
- }
}
- break;
}
- // Unicode
- //
- // \uF takes 1 byte which is 2 bytes less then escape sequence.
- // \uFF: 2 bytes, 2 bytes less.
- // \uFFF: 3 bytes, 2 bytes less.
- // \uFFFF: 3 bytes, 3 bytes less.
- // \UFFFFF: 4 bytes, 3 bytes less.
- // \UFFFFFF: 5 bytes, 3 bytes less.
- // \UFFFFFFF: 6 bytes, 3 bytes less.
- // \U7FFFFFFF: 6 bytes, 4 bytes less.
- case 'u': case 'U': {
- const char *const esc_start = p;
- size_t n = (*p == 'u' ? 4 : 8);
- int nr = 0;
+ break;
+ // Unicode
+ //
+ // \uF takes 1 byte which is 2 bytes less then escape sequence.
+ // \uFF: 2 bytes, 2 bytes less.
+ // \uFFF: 3 bytes, 2 bytes less.
+ // \uFFFF: 3 bytes, 3 bytes less.
+ // \UFFFFF: 4 bytes, 3 bytes less.
+ // \UFFFFFF: 5 bytes, 3 bytes less.
+ // \UFFFFFFF: 6 bytes, 3 bytes less.
+ // \U7FFFFFFF: 6 bytes, 4 bytes less.
+ case 'u':
+ case 'U': {
+ const char *const esc_start = p;
+ size_t n = (*p == 'u' ? 4 : 8);
+ int nr = 0;
+ p++;
+ while (p + 1 < e && n-- && ascii_isxdigit(p[1])) {
p++;
- while (p + 1 < e && n-- && ascii_isxdigit(p[1])) {
- p++;
- nr = (nr << 4) + hex2nr(*p);
- }
- // Escape length: (esc_start - 1) points to "\\", esc_start to "u"
- // or "U", p to the byte after last byte. So escape sequence
- // occupies p - (esc_start - 1), but it stands for a utf_char2len
- // bytes.
- size -= (size_t)((p - (esc_start - 1)) - utf_char2len(nr));
- p--;
- break;
+ nr = (nr << 4) + hex2nr(*p);
}
- // Octal, always single byte, but at least two bytes each.
- case '0': case '1': case '2': case '3': case '4': case '5': case '6':
- case '7': {
+ // Escape length: (esc_start - 1) points to "\\", esc_start to "u"
+ // or "U", p to the byte after last byte. So escape sequence
+ // occupies p - (esc_start - 1), but it stands for a utf_char2len
+ // bytes.
+ size -= (size_t)((p - (esc_start - 1)) - utf_char2len(nr));
+ p--;
+ break;
+ }
+ // Octal, always single byte, but at least two bytes each.
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ size--;
+ p++;
+ if (*p >= '0' && *p <= '7') {
size--;
p++;
- if (*p >= '0' && *p <= '7') {
+ if (p < e && *p >= '0' && *p <= '7') {
size--;
p++;
- if (p < e && *p >= '0' && *p <= '7') {
- size--;
- p++;
- }
}
- break;
- }
- default: {
- size--;
- break;
}
+ break;
+ default:
+ size--;
+ break;
}
}
}
@@ -1705,11 +1749,11 @@ static void parse_quoted_string(ParserState *const pstate,
const char *const v_p_start = v_p;
switch (*p) {
#define SINGLE_CHAR_ESC(ch, real_ch) \
- case ch: { \
- *v_p++ = real_ch; \
- p++; \
- break; \
- }
+case ch: { \
+ *v_p++ = real_ch; \
+ p++; \
+ break; \
+}
SINGLE_CHAR_ESC('b', BS)
SINGLE_CHAR_ESC('e', ESC)
SINGLE_CHAR_ESC('f', FF)
@@ -1720,76 +1764,83 @@ static void parse_quoted_string(ParserState *const pstate,
SINGLE_CHAR_ESC('\\', '\\')
#undef SINGLE_CHAR_ESC
- // Hexadecimal or unicode.
- case 'X': case 'x': case 'u': case 'U': {
- if (p + 1 < e && ascii_isxdigit(p[1])) {
- size_t n;
- int nr;
- bool is_hex = (*p == 'x' || *p == 'X');
-
- if (is_hex) {
- n = 2;
- } else if (*p == 'u') {
- n = 4;
- } else {
- n = 8;
- }
- nr = 0;
- while (p + 1 < e && n-- && ascii_isxdigit(p[1])) {
- p++;
- nr = (nr << 4) + hex2nr(*p);
- }
- p++;
- if (is_hex) {
- *v_p++ = (char)nr;
- } else {
- v_p += utf_char2bytes(nr, (char_u *)v_p);
- }
+ // Hexadecimal or unicode.
+ case 'X':
+ case 'x':
+ case 'u':
+ case 'U':
+ if (p + 1 < e && ascii_isxdigit(p[1])) {
+ size_t n;
+ int nr;
+ bool is_hex = (*p == 'x' || *p == 'X');
+
+ if (is_hex) {
+ n = 2;
+ } else if (*p == 'u') {
+ n = 4;
} else {
- is_unknown = true;
- *v_p++ = *p;
+ n = 8;
+ }
+ nr = 0;
+ while (p + 1 < e && n-- && ascii_isxdigit(p[1])) {
p++;
+ nr = (nr << 4) + hex2nr(*p);
+ }
+ p++;
+ if (is_hex) {
+ *v_p++ = (char)nr;
+ } else {
+ v_p += utf_char2bytes(nr, (char_u *)v_p);
}
- break;
+ } else {
+ is_unknown = true;
+ *v_p++ = *p;
+ p++;
}
- // Octal: "\1", "\12", "\123".
- case '0': case '1': case '2': case '3': case '4': case '5': case '6':
- case '7': {
- uint8_t ch = (uint8_t)(*p++ - '0');
+ break;
+ // Octal: "\1", "\12", "\123".
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7': {
+ uint8_t ch = (uint8_t)(*p++ - '0');
+ if (p < e && *p >= '0' && *p <= '7') {
+ ch = (uint8_t)((ch << 3) + *p++ - '0');
if (p < e && *p >= '0' && *p <= '7') {
ch = (uint8_t)((ch << 3) + *p++ - '0');
- if (p < e && *p >= '0' && *p <= '7') {
- ch = (uint8_t)((ch << 3) + *p++ - '0');
- }
}
- *v_p++ = (char)ch;
- break;
}
- // Special key, e.g.: "\<C-W>"
- case '<': {
- const size_t special_len = (
- trans_special((const char_u **)&p, (size_t)(e - p),
- (char_u *)v_p, true, true));
- if (special_len != 0) {
- v_p += special_len;
- } else {
- is_unknown = true;
- mb_copy_char((const char_u **)&p, (char_u **)&v_p);
- }
- break;
- }
- default: {
+ *v_p++ = (char)ch;
+ break;
+ }
+ // Special key, e.g.: "\<C-W>"
+ case '<': {
+ const size_t special_len = (
+ trans_special((const char_u **)&p, (size_t)(e - p),
+ (char_u *)v_p, true, true));
+ if (special_len != 0) {
+ v_p += special_len;
+ } else {
is_unknown = true;
mb_copy_char((const char_u **)&p, (char_u **)&v_p);
- break;
}
+ break;
+ }
+ default:
+ is_unknown = true;
+ mb_copy_char((const char_u **)&p, (char_u **)&v_p);
+ break;
}
if (pstate->colors) {
kvi_push(shifts, ((StringShift) {
- .start = token.start.col + (size_t)(chunk_e - s),
- .orig_len = (size_t)(p - chunk_e),
- .act_len = (size_t)(v_p - (char *)v_p_start),
- .escape_not_known = is_unknown,
+ .start = token.start.col + (size_t)(chunk_e - s),
+ .orig_len = (size_t)(p - chunk_e),
+ .act_len = (size_t)(v_p - (char *)v_p_start),
+ .escape_not_known = is_unknown,
}));
}
}
@@ -1901,21 +1952,23 @@ ExprAST viml_pexpr_parse(ParserState *const pstate, const int flags)
size_t asgn_level = 0;
do {
const bool is_concat_or_subscript = (
- want_node == kENodeValue
- && kv_size(ast_stack) > 1
- && (*kv_Z(ast_stack, 1))->type == kExprNodeConcatOrSubscript);
+ want_node == kENodeValue
+ && kv_size(ast_stack) > 1
+ && (*kv_Z(ast_stack,
+ 1))->type == kExprNodeConcatOrSubscript);
const int lexer_additional_flags = (
- kELFlagPeek
- | ((flags & kExprFlagsDisallowEOC) ? kELFlagForbidEOC : 0)
- | ((want_node == kENodeValue
- && (kv_size(ast_stack) == 1
- || ((*kv_Z(ast_stack, 1))->type != kExprNodeConcat
- && ((*kv_Z(ast_stack, 1))->type
- != kExprNodeConcatOrSubscript))))
+ kELFlagPeek
+ | ((flags & kExprFlagsDisallowEOC) ? kELFlagForbidEOC : 0)
+ | ((want_node == kENodeValue
+ && (kv_size(ast_stack) == 1
+ || ((*kv_Z(ast_stack, 1))->type != kExprNodeConcat
+ && ((*kv_Z(ast_stack, 1))->type
+ != kExprNodeConcatOrSubscript))))
? kELFlagAllowFloat
: 0));
- LexExprToken cur_token = viml_pexpr_next_token(
- pstate, want_node_to_lexer_flags[want_node] | lexer_additional_flags);
+ LexExprToken cur_token = viml_pexpr_next_token(pstate,
+ want_node_to_lexer_flags[want_node] |
+ lexer_additional_flags);
if (cur_token.type == kExprLexEOC) {
break;
}
@@ -1924,8 +1977,8 @@ ExprAST viml_pexpr_parse(ParserState *const pstate, const int flags)
bool is_invalid = token_invalid;
viml_pexpr_parse_process_token:
// May use different flags this time.
- cur_token = viml_pexpr_next_token(
- pstate, want_node_to_lexer_flags[want_node] | lexer_additional_flags);
+ cur_token = viml_pexpr_next_token(pstate,
+ want_node_to_lexer_flags[want_node] | lexer_additional_flags);
if (tok_type == kExprLexSpacing) {
if (is_invalid) {
HL_CUR_TOKEN(Spacing);
@@ -1977,12 +2030,12 @@ viml_pexpr_parse_process_token:
// for ternary and because concatenating dictionary with anything is not
// valid. There are more cases when this will make a difference though.
const bool node_is_key = (
- is_concat_or_subscript
- && (cur_token.type == kExprLexPlainIdentifier
+ is_concat_or_subscript
+ && (cur_token.type == kExprLexPlainIdentifier
? (!cur_token.data.var.autoload
&& cur_token.data.var.scope == kExprVarScopeMissing)
: (cur_token.type == kExprLexNumber))
- && prev_token.type != kExprLexSpacing);
+ && prev_token.type != kExprLexSpacing);
if (is_concat_or_subscript && !node_is_key) {
// Note: in Vim "d. a" (this is the reason behind `prev_token.type !=
// kExprLexSpacing` part of the condition) as well as any other "d.{expr}"
@@ -1997,951 +2050,896 @@ viml_pexpr_parse_process_token:
// Pop some stack pt_stack items in case of misplaced nodes.
const bool is_single_assignment = kv_last(pt_stack) == kEPTSingleAssignment;
switch (kv_last(pt_stack)) {
- case kEPTExpr: {
- break;
- }
- case kEPTLambdaArguments: {
- if ((want_node == kENodeOperator
- && tok_type != kExprLexComma
- && tok_type != kExprLexArrow)
- || (want_node == kENodeValue
- && !(cur_token.type == kExprLexPlainIdentifier
- && cur_token.data.var.scope == kExprVarScopeMissing
- && !cur_token.data.var.autoload)
- && tok_type != kExprLexArrow)) {
- lambda_node->data.fig.type_guesses.allow_lambda = false;
- if (lambda_node->children != NULL
- && lambda_node->children->type == kExprNodeComma) {
- // If lambda has comma child this means that parser has already seen
- // at least "{arg1,", so node cannot possibly be anything, but
- // lambda.
-
- // Vim may give E121 or E720 in this case, but it does not look
- // right to have either because both are results of reevaluation
- // possibly-lambda node as a dictionary and here this is not going
- // to happen.
- ERROR_FROM_TOKEN_AND_MSG(
- cur_token,
- _("E15: Expected lambda arguments list or arrow: %.*s"));
- } else {
- // Else it may appear that possibly-lambda node is actually
- // a dictionary or curly-braces-name identifier.
- lambda_node = NULL;
- kv_drop(pt_stack, 1);
- }
+ case kEPTExpr:
+ break;
+ case kEPTLambdaArguments:
+ if ((want_node == kENodeOperator
+ && tok_type != kExprLexComma
+ && tok_type != kExprLexArrow)
+ || (want_node == kENodeValue
+ && !(cur_token.type == kExprLexPlainIdentifier
+ && cur_token.data.var.scope == kExprVarScopeMissing
+ && !cur_token.data.var.autoload)
+ && tok_type != kExprLexArrow)) {
+ lambda_node->data.fig.type_guesses.allow_lambda = false;
+ if (lambda_node->children != NULL
+ && lambda_node->children->type == kExprNodeComma) {
+ // If lambda has comma child this means that parser has already seen
+ // at least "{arg1,", so node cannot possibly be anything, but
+ // lambda.
+
+ // Vim may give E121 or E720 in this case, but it does not look
+ // right to have either because both are results of reevaluation
+ // possibly-lambda node as a dictionary and here this is not going
+ // to happen.
+ ERROR_FROM_TOKEN_AND_MSG(cur_token,
+ _("E15: Expected lambda arguments list or arrow: %.*s"));
+ } else {
+ // Else it may appear that possibly-lambda node is actually
+ // a dictionary or curly-braces-name identifier.
+ lambda_node = NULL;
+ kv_drop(pt_stack, 1);
}
- break;
}
- case kEPTSingleAssignment:
- case kEPTAssignment: {
- if (want_node == kENodeValue
- && tok_type != kExprLexBracket
- && tok_type != kExprLexPlainIdentifier
- && (tok_type != kExprLexFigureBrace || cur_token.data.brc.closing)
- && !(node_is_key && tok_type == kExprLexNumber)
- && tok_type != kExprLexEnv
- && tok_type != kExprLexOption
- && tok_type != kExprLexRegister) {
- ERROR_FROM_TOKEN_AND_MSG(
- cur_token,
- _("E15: Expected value part of assignment lvalue: %.*s"));
- kv_drop(pt_stack, 1);
- } else if (want_node == kENodeOperator
- && tok_type != kExprLexBracket
- && (tok_type != kExprLexFigureBrace
- || cur_token.data.brc.closing)
- && tok_type != kExprLexDot
- && (tok_type != kExprLexComma || !is_single_assignment)
- && tok_type != kExprLexAssignment
- // Curly brace identifiers: will contain plain identifier or
- // another curly brace in position where operator is wanted.
- && !((tok_type == kExprLexPlainIdentifier
- || (tok_type == kExprLexFigureBrace
- && !cur_token.data.brc.closing))
- && prev_token.type != kExprLexSpacing)) {
- if (flags & kExprFlagsMulti && MAY_HAVE_NEXT_EXPR) {
- goto viml_pexpr_parse_end;
- }
- ERROR_FROM_TOKEN_AND_MSG(
- cur_token,
- _("E15: Expected assignment operator or subscript: %.*s"));
- kv_drop(pt_stack, 1);
+ break;
+ case kEPTSingleAssignment:
+ case kEPTAssignment:
+ if (want_node == kENodeValue
+ && tok_type != kExprLexBracket
+ && tok_type != kExprLexPlainIdentifier
+ && (tok_type != kExprLexFigureBrace || cur_token.data.brc.closing)
+ && !(node_is_key && tok_type == kExprLexNumber)
+ && tok_type != kExprLexEnv
+ && tok_type != kExprLexOption
+ && tok_type != kExprLexRegister) {
+ ERROR_FROM_TOKEN_AND_MSG(cur_token,
+ _("E15: Expected value part of assignment lvalue: %.*s"));
+ kv_drop(pt_stack, 1);
+ } else if (want_node == kENodeOperator
+ && tok_type != kExprLexBracket
+ && (tok_type != kExprLexFigureBrace
+ || cur_token.data.brc.closing)
+ && tok_type != kExprLexDot
+ && (tok_type != kExprLexComma || !is_single_assignment)
+ && tok_type != kExprLexAssignment
+ // Curly brace identifiers: will contain plain identifier or
+ // another curly brace in position where operator is wanted.
+ && !((tok_type == kExprLexPlainIdentifier
+ || (tok_type == kExprLexFigureBrace
+ && !cur_token.data.brc.closing))
+ && prev_token.type != kExprLexSpacing)) {
+ if (flags & kExprFlagsMulti && MAY_HAVE_NEXT_EXPR) {
+ goto viml_pexpr_parse_end;
}
- assert(kv_size(pt_stack));
- break;
+ ERROR_FROM_TOKEN_AND_MSG(cur_token,
+ _("E15: Expected assignment operator or subscript: %.*s"));
+ kv_drop(pt_stack, 1);
}
+ assert(kv_size(pt_stack));
+ break;
}
assert(kv_size(pt_stack));
const ExprASTParseType cur_pt = kv_last(pt_stack);
assert(lambda_node == NULL || cur_pt == kEPTLambdaArguments);
switch (tok_type) {
- case kExprLexMissing:
- case kExprLexSpacing:
- case kExprLexEOC: {
- abort();
- }
- case kExprLexInvalid: {
- ERROR_FROM_TOKEN(cur_token);
- tok_type = cur_token.data.err.type;
- goto viml_pexpr_parse_process_token;
- }
- case kExprLexRegister: {
- if (want_node == kENodeOperator) {
- // Register in operator position: e.g. @a @a
- OP_MISSING;
- }
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeRegister);
- cur_node->data.reg.name = cur_token.data.reg.name;
- *top_node_p = cur_node;
- want_node = kENodeOperator;
- HL_CUR_TOKEN(Register);
- break;
+ case kExprLexMissing:
+ case kExprLexSpacing:
+ case kExprLexEOC:
+ abort();
+ case kExprLexInvalid:
+ ERROR_FROM_TOKEN(cur_token);
+ tok_type = cur_token.data.err.type;
+ goto viml_pexpr_parse_process_token;
+ case kExprLexRegister: {
+ if (want_node == kENodeOperator) {
+ // Register in operator position: e.g. @a @a
+ OP_MISSING;
}
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeRegister);
+ cur_node->data.reg.name = cur_token.data.reg.name;
+ *top_node_p = cur_node;
+ want_node = kENodeOperator;
+ HL_CUR_TOKEN(Register);
+ break;
+ }
#define SIMPLE_UB_OP(op) \
- case kExprLex##op: { \
- if (want_node == kENodeValue) { \
- /* Value level: assume unary operator. */ \
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeUnary##op); \
- *top_node_p = cur_node; \
- kvi_push(ast_stack, &cur_node->children); \
- HL_CUR_TOKEN(Unary##op); \
- } else { \
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeBinary##op); \
- ADD_OP_NODE(cur_node); \
- HL_CUR_TOKEN(Binary##op); \
- } \
- want_node = kENodeValue; \
- break; \
- }
+case kExprLex##op: { \
+ if (want_node == kENodeValue) { \
+ /* Value level: assume unary operator. */ \
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeUnary##op); \
+ *top_node_p = cur_node; \
+ kvi_push(ast_stack, &cur_node->children); \
+ HL_CUR_TOKEN(Unary##op); \
+ } else { \
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeBinary##op); \
+ ADD_OP_NODE(cur_node); \
+ HL_CUR_TOKEN(Binary##op); \
+ } \
+ want_node = kENodeValue; \
+ break; \
+}
SIMPLE_UB_OP(Plus)
SIMPLE_UB_OP(Minus)
#undef SIMPLE_UB_OP
#define SIMPLE_B_OP(op, msg) \
- case kExprLex##op: { \
- ADD_VALUE_IF_MISSING(_("E15: Unexpected " msg ": %.*s")); \
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNode##op); \
- HL_CUR_TOKEN(op); \
- ADD_OP_NODE(cur_node); \
- break; \
- }
+case kExprLex##op: { \
+ ADD_VALUE_IF_MISSING(_("E15: Unexpected " msg ": %.*s")); \
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNode##op); \
+ HL_CUR_TOKEN(op); \
+ ADD_OP_NODE(cur_node); \
+ break; \
+}
SIMPLE_B_OP(Or, "or operator")
SIMPLE_B_OP(And, "and operator")
#undef SIMPLE_B_OP
- case kExprLexMultiplication: {
- ADD_VALUE_IF_MISSING(
- _("E15: Unexpected multiplication-like operator: %.*s"));
- switch (cur_token.data.mul.type) {
+ case kExprLexMultiplication:
+ ADD_VALUE_IF_MISSING(_("E15: Unexpected multiplication-like operator: %.*s"));
+ switch (cur_token.data.mul.type) {
#define MUL_OP(lex_op_tail, node_op_tail) \
- case kExprLexMul##lex_op_tail: { \
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNode##node_op_tail); \
- HL_CUR_TOKEN(node_op_tail); \
- break; \
- }
- MUL_OP(Mul, Multiplication)
- MUL_OP(Div, Division)
- MUL_OP(Mod, Mod)
+case kExprLexMul##lex_op_tail: { \
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNode##node_op_tail); \
+ HL_CUR_TOKEN(node_op_tail); \
+ break; \
+}
+ MUL_OP(Mul, Multiplication)
+ MUL_OP(Div, Division)
+ MUL_OP(Mod, Mod)
#undef MUL_OP
- }
- ADD_OP_NODE(cur_node);
- break;
}
- case kExprLexOption: {
- if (want_node == kENodeOperator) {
- OP_MISSING;
- }
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeOption);
- if (cur_token.type == kExprLexInvalid) {
- assert(cur_token.len == 1
- || (cur_token.len == 3
- && pline.data[cur_token.start.col + 2] == ':'));
- cur_node->data.opt.ident = (
- pline.data + cur_token.start.col + cur_token.len);
- cur_node->data.opt.ident_len = 0;
- cur_node->data.opt.scope = (
- cur_token.len == 3
+ ADD_OP_NODE(cur_node);
+ break;
+ case kExprLexOption: {
+ if (want_node == kENodeOperator) {
+ OP_MISSING;
+ }
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeOption);
+ if (cur_token.type == kExprLexInvalid) {
+ assert(cur_token.len == 1
+ || (cur_token.len == 3
+ && pline.data[cur_token.start.col + 2] == ':'));
+ cur_node->data.opt.ident = (
+ pline.data + cur_token.start.col + cur_token.len);
+ cur_node->data.opt.ident_len = 0;
+ cur_node->data.opt.scope = (
+ cur_token.len == 3
? (ExprOptScope)pline.data[cur_token.start.col + 1]
: kExprOptScopeUnspecified);
- } else {
- cur_node->data.opt.ident = cur_token.data.opt.name;
- cur_node->data.opt.ident_len = cur_token.data.opt.len;
- cur_node->data.opt.scope = cur_token.data.opt.scope;
- }
+ } else {
+ cur_node->data.opt.ident = cur_token.data.opt.name;
+ cur_node->data.opt.ident_len = cur_token.data.opt.len;
+ cur_node->data.opt.scope = cur_token.data.opt.scope;
+ }
+ *top_node_p = cur_node;
+ want_node = kENodeOperator;
+ viml_parser_highlight(pstate, cur_token.start, 1, HL(OptionSigil));
+ const size_t scope_shift = (
+ cur_token.data.opt.scope == kExprOptScopeUnspecified ? 0 : 2);
+ if (scope_shift) {
+ viml_parser_highlight(pstate, shifted_pos(cur_token.start, 1), 1,
+ HL(OptionScope));
+ viml_parser_highlight(pstate, shifted_pos(cur_token.start, 2), 1,
+ HL(OptionScopeDelimiter));
+ }
+ viml_parser_highlight(pstate, shifted_pos(cur_token.start, scope_shift + 1),
+ cur_token.len - (scope_shift + 1), HL(OptionName));
+ break;
+ }
+ case kExprLexEnv:
+ if (want_node == kENodeOperator) {
+ OP_MISSING;
+ }
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeEnvironment);
+ cur_node->data.env.ident = pline.data + cur_token.start.col + 1;
+ cur_node->data.env.ident_len = cur_token.len - 1;
+ if (cur_node->data.env.ident_len == 0) {
+ ERROR_FROM_TOKEN_AND_MSG(cur_token,
+ _("E15: Environment variable name missing"));
+ }
+ *top_node_p = cur_node;
+ want_node = kENodeOperator;
+ viml_parser_highlight(pstate, cur_token.start, 1, HL(EnvironmentSigil));
+ viml_parser_highlight(pstate, shifted_pos(cur_token.start, 1),
+ cur_token.len - 1, HL(EnvironmentName));
+ break;
+ case kExprLexNot:
+ if (want_node == kENodeOperator) {
+ OP_MISSING;
+ }
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeNot);
+ *top_node_p = cur_node;
+ kvi_push(ast_stack, &cur_node->children);
+ HL_CUR_TOKEN(Not);
+ break;
+ case kExprLexComparison:
+ ADD_VALUE_IF_MISSING(_("E15: Expected value, got comparison operator: %.*s"));
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeComparison);
+ if (cur_token.type == kExprLexInvalid) {
+ cur_node->data.cmp.ccs = kCCStrategyUseOption;
+ cur_node->data.cmp.type = kExprCmpEqual;
+ cur_node->data.cmp.inv = false;
+ } else {
+ cur_node->data.cmp.ccs = cur_token.data.cmp.ccs;
+ cur_node->data.cmp.type = cur_token.data.cmp.type;
+ cur_node->data.cmp.inv = cur_token.data.cmp.inv;
+ }
+ ADD_OP_NODE(cur_node);
+ if (cur_token.data.cmp.ccs != kCCStrategyUseOption) {
+ viml_parser_highlight(pstate, cur_token.start, cur_token.len - 1,
+ HL(Comparison));
+ viml_parser_highlight(pstate, shifted_pos(cur_token.start, cur_token.len - 1), 1,
+ HL(ComparisonModifier));
+ } else {
+ HL_CUR_TOKEN(Comparison);
+ }
+ want_node = kENodeValue;
+ break;
+ case kExprLexComma:
+ assert(!(want_node == kENodeValue && cur_pt == kEPTLambdaArguments));
+ if (want_node == kENodeValue) {
+ // Value level: comma appearing here is not valid.
+ // Note: in Vim string(,x) will give E116, this is not the case here.
+ ERROR_FROM_TOKEN_AND_MSG(cur_token, _("E15: Expected value, got comma: %.*s"));
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeMissing);
+ cur_node->len = 0;
*top_node_p = cur_node;
want_node = kENodeOperator;
- viml_parser_highlight(pstate, cur_token.start, 1, HL(OptionSigil));
- const size_t scope_shift = (
- cur_token.data.opt.scope == kExprOptScopeUnspecified ? 0 : 2);
- if (scope_shift) {
- viml_parser_highlight(pstate, shifted_pos(cur_token.start, 1), 1,
- HL(OptionScope));
- viml_parser_highlight(pstate, shifted_pos(cur_token.start, 2), 1,
- HL(OptionScopeDelimiter));
- }
- viml_parser_highlight(
- pstate, shifted_pos(cur_token.start, scope_shift + 1),
- cur_token.len - (scope_shift + 1), HL(OptionName));
- break;
}
- case kExprLexEnv: {
- if (want_node == kENodeOperator) {
- OP_MISSING;
- }
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeEnvironment);
- cur_node->data.env.ident = pline.data + cur_token.start.col + 1;
- cur_node->data.env.ident_len = cur_token.len - 1;
- if (cur_node->data.env.ident_len == 0) {
+ if (cur_pt == kEPTLambdaArguments) {
+ assert(lambda_node != NULL);
+ assert(lambda_node->data.fig.type_guesses.allow_lambda);
+ SELECT_FIGURE_BRACE_TYPE(lambda_node, Lambda, Lambda);
+ }
+ if (kv_size(ast_stack) < 2) {
+ goto viml_pexpr_parse_invalid_comma;
+ }
+ for (size_t i = 1; i < kv_size(ast_stack); i++) {
+ ExprASTNode *const *const eastnode_p =
+ (ExprASTNode *const *)kv_Z(ast_stack, i);
+ const ExprASTNodeType eastnode_type = (*eastnode_p)->type;
+ const ExprOpLvl eastnode_lvl = node_lvl(**eastnode_p);
+ if (eastnode_type == kExprNodeLambda) {
+ assert(cur_pt == kEPTLambdaArguments
+ && want_node == kENodeOperator);
+ break;
+ } else if (eastnode_type == kExprNodeDictLiteral
+ || eastnode_type == kExprNodeListLiteral
+ || eastnode_type == kExprNodeCall) {
+ break;
+ } else if (eastnode_type == kExprNodeComma
+ || eastnode_type == kExprNodeColon
+ || eastnode_lvl > kEOpLvlComma) {
+ // Do nothing
+ } else {
+viml_pexpr_parse_invalid_comma:
ERROR_FROM_TOKEN_AND_MSG(cur_token,
- _("E15: Environment variable name missing"));
+ _("E15: Comma outside of call, lambda or literal: %.*s"));
+ break;
+ }
+ if (i == kv_size(ast_stack) - 1) {
+ goto viml_pexpr_parse_invalid_comma;
}
- *top_node_p = cur_node;
- want_node = kENodeOperator;
- viml_parser_highlight(pstate, cur_token.start, 1, HL(EnvironmentSigil));
- viml_parser_highlight(pstate, shifted_pos(cur_token.start, 1),
- cur_token.len - 1, HL(EnvironmentName));
- break;
}
- case kExprLexNot: {
- if (want_node == kENodeOperator) {
- OP_MISSING;
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeComma);
+ ADD_OP_NODE(cur_node);
+ HL_CUR_TOKEN(Comma);
+ break;
+#define EXP_VAL_COLON "E15: Expected value, got colon: %.*s"
+ case kExprLexColon: {
+ bool is_ternary = false;
+ if (kv_size(ast_stack) < 2) {
+ goto viml_pexpr_parse_invalid_colon;
+ }
+ bool can_be_ternary = true;
+ bool is_subscript = false;
+ for (size_t i = 1; i < kv_size(ast_stack); i++) {
+ ExprASTNode *const *const eastnode_p =
+ (ExprASTNode *const *)kv_Z(ast_stack, i);
+ const ExprASTNodeType eastnode_type = (*eastnode_p)->type;
+ const ExprOpLvl eastnode_lvl = node_lvl(**eastnode_p);
+ STATIC_ASSERT(kEOpLvlTernary > kEOpLvlComma,
+ "Unexpected operator priorities");
+ if (can_be_ternary && eastnode_type == kExprNodeTernaryValue
+ && !(*eastnode_p)->data.ter.got_colon) {
+ kv_drop(ast_stack, i);
+ (*eastnode_p)->start = cur_token.start;
+ (*eastnode_p)->len = cur_token.len;
+ if (prev_token.type == kExprLexSpacing) {
+ (*eastnode_p)->start = prev_token.start;
+ (*eastnode_p)->len += prev_token.len;
+ }
+ is_ternary = true;
+ (*eastnode_p)->data.ter.got_colon = true;
+ ADD_VALUE_IF_MISSING(_(EXP_VAL_COLON));
+ assert((*eastnode_p)->children != NULL);
+ assert((*eastnode_p)->children->next == NULL);
+ kvi_push(ast_stack, &(*eastnode_p)->children->next);
+ break;
+ } else if (eastnode_type == kExprNodeUnknownFigure) {
+ SELECT_FIGURE_BRACE_TYPE(*eastnode_p, DictLiteral, Dict);
+ break;
+ } else if (eastnode_type == kExprNodeDictLiteral) {
+ break;
+ } else if (eastnode_type == kExprNodeSubscript) {
+ is_subscript = true;
+ // can_be_ternary = false;
+ assert(!is_ternary);
+ break;
+ } else if (eastnode_type == kExprNodeColon) {
+ goto viml_pexpr_parse_invalid_colon;
+ } else if (eastnode_lvl >= kEOpLvlTernaryValue) {
+ // Do nothing
+ } else if (eastnode_lvl >= kEOpLvlComma) {
+ can_be_ternary = false;
+ } else {
+ goto viml_pexpr_parse_invalid_colon;
+ }
+ if (i == kv_size(ast_stack) - 1) {
+ goto viml_pexpr_parse_invalid_colon;
}
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeNot);
- *top_node_p = cur_node;
- kvi_push(ast_stack, &cur_node->children);
- HL_CUR_TOKEN(Not);
- break;
}
- case kExprLexComparison: {
- ADD_VALUE_IF_MISSING(
- _("E15: Expected value, got comparison operator: %.*s"));
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeComparison);
- if (cur_token.type == kExprLexInvalid) {
- cur_node->data.cmp.ccs = kCCStrategyUseOption;
- cur_node->data.cmp.type = kExprCmpEqual;
- cur_node->data.cmp.inv = false;
+ if (is_subscript) {
+ assert(kv_size(ast_stack) > 1);
+ // Colon immediately following subscript start: it is empty subscript
+ // part like a[:2].
+ if (want_node == kENodeValue
+ && (*kv_Z(ast_stack, 1))->type == kExprNodeSubscript) {
+ NEW_NODE_WITH_CUR_POS(*top_node_p, kExprNodeMissing);
+ (*top_node_p)->len = 0;
+ want_node = kENodeOperator;
} else {
- cur_node->data.cmp.ccs = cur_token.data.cmp.ccs;
- cur_node->data.cmp.type = cur_token.data.cmp.type;
- cur_node->data.cmp.inv = cur_token.data.cmp.inv;
+ ADD_VALUE_IF_MISSING(_(EXP_VAL_COLON));
}
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeColon);
ADD_OP_NODE(cur_node);
- if (cur_token.data.cmp.ccs != kCCStrategyUseOption) {
- viml_parser_highlight(pstate, cur_token.start, cur_token.len - 1,
- HL(Comparison));
- viml_parser_highlight(
- pstate, shifted_pos(cur_token.start, cur_token.len - 1), 1,
- HL(ComparisonModifier));
+ HL_CUR_TOKEN(SubscriptColon);
+ } else {
+ goto viml_pexpr_parse_valid_colon;
+viml_pexpr_parse_invalid_colon:
+ ERROR_FROM_TOKEN_AND_MSG(cur_token,
+ _("E15: Colon outside of dictionary or ternary operator: %.*s"));
+viml_pexpr_parse_valid_colon:
+ ADD_VALUE_IF_MISSING(_(EXP_VAL_COLON));
+ if (is_ternary) {
+ HL_CUR_TOKEN(TernaryColon);
} else {
- HL_CUR_TOKEN(Comparison);
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeColon);
+ ADD_OP_NODE(cur_node);
+ HL_CUR_TOKEN(Colon);
}
- want_node = kENodeValue;
- break;
}
- case kExprLexComma: {
- assert(!(want_node == kENodeValue && cur_pt == kEPTLambdaArguments));
- if (want_node == kENodeValue) {
- // Value level: comma appearing here is not valid.
- // Note: in Vim string(,x) will give E116, this is not the case here.
- ERROR_FROM_TOKEN_AND_MSG(
- cur_token, _("E15: Expected value, got comma: %.*s"));
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeMissing);
+ want_node = kENodeValue;
+ break;
+ }
+#undef EXP_VAL_COLON
+ case kExprLexBracket:
+ if (cur_token.data.brc.closing) {
+ ExprASTNode **new_top_node_p = NULL;
+ // Always drop the topmost value:
+ //
+ // 1. When want_node != kENodeValue topmost item on stack is
+ // a *finished* left operand, which may as well be "{@a}" which
+ // needs not be finished again.
+ // 2. Otherwise it is pointing to NULL what nobody wants.
+ kv_drop(ast_stack, 1);
+ if (!kv_size(ast_stack)) {
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeListLiteral);
cur_node->len = 0;
+ if (want_node != kENodeValue) {
+ cur_node->children = *top_node_p;
+ }
*top_node_p = cur_node;
- want_node = kENodeOperator;
- }
- if (cur_pt == kEPTLambdaArguments) {
- assert(lambda_node != NULL);
- assert(lambda_node->data.fig.type_guesses.allow_lambda);
- SELECT_FIGURE_BRACE_TYPE(lambda_node, Lambda, Lambda);
+ goto viml_pexpr_parse_bracket_closing_error;
}
- if (kv_size(ast_stack) < 2) {
- goto viml_pexpr_parse_invalid_comma;
+ if (want_node == kENodeValue) {
+ // It is OK to want value if
+ //
+ // 1. It is empty list literal, in which case top node will be
+ // ListLiteral.
+ // 2. It is list literal with trailing comma, in which case top node
+ // will be that comma.
+ // 3. It is subscript with colon, but without one of the values:
+ // e.g. "a[:]", "a[1:]", top node will be colon in this case.
+ if ((*kv_last(ast_stack))->type != kExprNodeListLiteral
+ && (*kv_last(ast_stack))->type != kExprNodeComma
+ && (*kv_last(ast_stack))->type != kExprNodeColon) {
+ ERROR_FROM_TOKEN_AND_MSG(cur_token,
+ _("E15: Expected value, got closing bracket: %.*s"));
+ }
}
- for (size_t i = 1; i < kv_size(ast_stack); i++) {
- ExprASTNode *const *const eastnode_p =
- (ExprASTNode *const *)kv_Z(ast_stack, i);
- const ExprASTNodeType eastnode_type = (*eastnode_p)->type;
- const ExprOpLvl eastnode_lvl = node_lvl(**eastnode_p);
- if (eastnode_type == kExprNodeLambda) {
- assert(cur_pt == kEPTLambdaArguments
- && want_node == kENodeOperator);
- break;
- } else if (eastnode_type == kExprNodeDictLiteral
- || eastnode_type == kExprNodeListLiteral
- || eastnode_type == kExprNodeCall) {
- break;
- } else if (eastnode_type == kExprNodeComma
- || eastnode_type == kExprNodeColon
- || eastnode_lvl > kEOpLvlComma) {
- // Do nothing
- } else {
-viml_pexpr_parse_invalid_comma:
- ERROR_FROM_TOKEN_AND_MSG(
- cur_token,
- _("E15: Comma outside of call, lambda or literal: %.*s"));
- break;
+ do {
+ new_top_node_p = kv_pop(ast_stack);
+ } while (kv_size(ast_stack)
+ && (new_top_node_p == NULL
+ || ((*new_top_node_p)->type != kExprNodeListLiteral
+ && (*new_top_node_p)->type != kExprNodeSubscript)));
+ ExprASTNode *new_top_node = *new_top_node_p;
+ switch (new_top_node->type) {
+ case kExprNodeListLiteral:
+ if (pt_is_assignment(cur_pt) && new_top_node->children == NULL) {
+ ERROR_FROM_TOKEN_AND_MSG(cur_token, _("E475: Unable to assign to empty list: %.*s"));
}
- if (i == kv_size(ast_stack) - 1) {
- goto viml_pexpr_parse_invalid_comma;
+ HL_CUR_TOKEN(List);
+ break;
+ case kExprNodeSubscript:
+ HL_CUR_TOKEN(SubscriptBracket);
+ break;
+ default:
+viml_pexpr_parse_bracket_closing_error:
+ assert(!kv_size(ast_stack));
+ ERROR_FROM_TOKEN_AND_MSG(cur_token, _("E15: Unexpected closing figure brace: %.*s"));
+ HL_CUR_TOKEN(List);
+ break;
+ }
+ kvi_push(ast_stack, new_top_node_p);
+ want_node = kENodeOperator;
+ if (kv_size(ast_stack) <= asgn_level) {
+ assert(kv_size(ast_stack) == asgn_level);
+ asgn_level = 0;
+ if (cur_pt == kEPTAssignment) {
+ assert(ast.err.msg);
+ } else if (cur_pt == kEPTExpr
+ && kv_size(pt_stack) > 1
+ && pt_is_assignment(kv_Z(pt_stack, 1))) {
+ kv_drop(pt_stack, 1);
}
}
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeComma);
- ADD_OP_NODE(cur_node);
- HL_CUR_TOKEN(Comma);
- break;
- }
-#define EXP_VAL_COLON "E15: Expected value, got colon: %.*s"
- case kExprLexColon: {
- bool is_ternary = false;
- if (kv_size(ast_stack) < 2) {
- goto viml_pexpr_parse_invalid_colon;
+ if (cur_pt == kEPTSingleAssignment && kv_size(ast_stack) == 1) {
+ kv_drop(pt_stack, 1);
}
- bool can_be_ternary = true;
- bool is_subscript = false;
- for (size_t i = 1; i < kv_size(ast_stack); i++) {
- ExprASTNode *const *const eastnode_p =
- (ExprASTNode *const *)kv_Z(ast_stack, i);
- const ExprASTNodeType eastnode_type = (*eastnode_p)->type;
- const ExprOpLvl eastnode_lvl = node_lvl(**eastnode_p);
- STATIC_ASSERT(kEOpLvlTernary > kEOpLvlComma,
- "Unexpected operator priorities");
- if (can_be_ternary && eastnode_type == kExprNodeTernaryValue
- && !(*eastnode_p)->data.ter.got_colon) {
- kv_drop(ast_stack, i);
- (*eastnode_p)->start = cur_token.start;
- (*eastnode_p)->len = cur_token.len;
- if (prev_token.type == kExprLexSpacing) {
- (*eastnode_p)->start = prev_token.start;
- (*eastnode_p)->len += prev_token.len;
- }
- is_ternary = true;
- (*eastnode_p)->data.ter.got_colon = true;
- ADD_VALUE_IF_MISSING(_(EXP_VAL_COLON));
- assert((*eastnode_p)->children != NULL);
- assert((*eastnode_p)->children->next == NULL);
- kvi_push(ast_stack, &(*eastnode_p)->children->next);
- break;
- } else if (eastnode_type == kExprNodeUnknownFigure) {
- SELECT_FIGURE_BRACE_TYPE(*eastnode_p, DictLiteral, Dict);
- break;
- } else if (eastnode_type == kExprNodeDictLiteral) {
- break;
- } else if (eastnode_type == kExprNodeSubscript) {
- is_subscript = true;
- // can_be_ternary = false;
- assert(!is_ternary);
- break;
- } else if (eastnode_type == kExprNodeColon) {
- goto viml_pexpr_parse_invalid_colon;
- } else if (eastnode_lvl >= kEOpLvlTernaryValue) {
- // Do nothing
- } else if (eastnode_lvl >= kEOpLvlComma) {
- can_be_ternary = false;
- } else {
- goto viml_pexpr_parse_invalid_colon;
- }
- if (i == kv_size(ast_stack) - 1) {
- goto viml_pexpr_parse_invalid_colon;
+ } else {
+ if (want_node == kENodeValue) {
+ // Value means list literal or list assignment.
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeListLiteral);
+ *top_node_p = cur_node;
+ kvi_push(ast_stack, &cur_node->children);
+ want_node = kENodeValue;
+ if (cur_pt == kEPTAssignment) {
+ // Additional assignment parse type allows to easily forbid nested
+ // lists.
+ kvi_push(pt_stack, kEPTSingleAssignment);
+ } else if (cur_pt == kEPTSingleAssignment) {
+ ERROR_FROM_TOKEN_AND_MSG(cur_token,
+ _("E475: Nested lists not allowed when assigning: %.*s"));
}
- }
- if (is_subscript) {
- assert(kv_size(ast_stack) > 1);
- // Colon immediately following subscript start: it is empty subscript
- // part like a[:2].
- if (want_node == kENodeValue
- && (*kv_Z(ast_stack, 1))->type == kExprNodeSubscript) {
- NEW_NODE_WITH_CUR_POS(*top_node_p, kExprNodeMissing);
- (*top_node_p)->len = 0;
- want_node = kENodeOperator;
- } else {
- ADD_VALUE_IF_MISSING(_(EXP_VAL_COLON));
+ HL_CUR_TOKEN(List);
+ } else {
+ // Operator means subscript, also in assignment. But in assignment
+ // subscript may be pretty much any expression, so need to push
+ // kEPTExpr.
+ if (prev_token.type == kExprLexSpacing) {
+ OP_MISSING;
}
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeColon);
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeSubscript);
ADD_OP_NODE(cur_node);
- HL_CUR_TOKEN(SubscriptColon);
- } else {
- goto viml_pexpr_parse_valid_colon;
-viml_pexpr_parse_invalid_colon:
- ERROR_FROM_TOKEN_AND_MSG(
- cur_token,
- _("E15: Colon outside of dictionary or ternary operator: %.*s"));
-viml_pexpr_parse_valid_colon:
- ADD_VALUE_IF_MISSING(_(EXP_VAL_COLON));
- if (is_ternary) {
- HL_CUR_TOKEN(TernaryColon);
- } else {
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeColon);
- ADD_OP_NODE(cur_node);
- HL_CUR_TOKEN(Colon);
+ HL_CUR_TOKEN(SubscriptBracket);
+ if (pt_is_assignment(cur_pt)) {
+ assert(want_node == kENodeValue); // Subtract 1 for NULL at top.
+ asgn_level = kv_size(ast_stack) - 1;
+ kvi_push(pt_stack, kEPTExpr);
}
}
- want_node = kENodeValue;
- break;
}
-#undef EXP_VAL_COLON
- case kExprLexBracket: {
- if (cur_token.data.brc.closing) {
- ExprASTNode **new_top_node_p = NULL;
- // Always drop the topmost value:
- //
- // 1. When want_node != kENodeValue topmost item on stack is
- // a *finished* left operand, which may as well be "{@a}" which
- // needs not be finished again.
- // 2. Otherwise it is pointing to NULL what nobody wants.
- kv_drop(ast_stack, 1);
- if (!kv_size(ast_stack)) {
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeListLiteral);
- cur_node->len = 0;
- if (want_node != kENodeValue) {
- cur_node->children = *top_node_p;
- }
- *top_node_p = cur_node;
- goto viml_pexpr_parse_bracket_closing_error;
- }
- if (want_node == kENodeValue) {
- // It is OK to want value if
- //
- // 1. It is empty list literal, in which case top node will be
- // ListLiteral.
- // 2. It is list literal with trailing comma, in which case top node
- // will be that comma.
- // 3. It is subscript with colon, but without one of the values:
- // e.g. "a[:]", "a[1:]", top node will be colon in this case.
- if ((*kv_last(ast_stack))->type != kExprNodeListLiteral
- && (*kv_last(ast_stack))->type != kExprNodeComma
- && (*kv_last(ast_stack))->type != kExprNodeColon) {
- ERROR_FROM_TOKEN_AND_MSG(
- cur_token,
- _("E15: Expected value, got closing bracket: %.*s"));
- }
+ break;
+ case kExprLexFigureBrace:
+ if (cur_token.data.brc.closing) {
+ ExprASTNode **new_top_node_p = NULL;
+ // Always drop the topmost value:
+ //
+ // 1. When want_node != kENodeValue topmost item on stack is
+ // a *finished* left operand, which may as well be "{@a}" which
+ // needs not be finished again.
+ // 2. Otherwise it is pointing to NULL what nobody wants.
+ kv_drop(ast_stack, 1);
+ if (!kv_size(ast_stack)) {
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeUnknownFigure);
+ cur_node->data.fig.type_guesses.allow_lambda = false;
+ cur_node->data.fig.type_guesses.allow_dict = false;
+ cur_node->data.fig.type_guesses.allow_ident = false;
+ cur_node->len = 0;
+ if (want_node != kENodeValue) {
+ cur_node->children = *top_node_p;
}
- do {
- new_top_node_p = kv_pop(ast_stack);
- } while (kv_size(ast_stack)
- && (new_top_node_p == NULL
- || ((*new_top_node_p)->type != kExprNodeListLiteral
- && (*new_top_node_p)->type != kExprNodeSubscript)));
- ExprASTNode *new_top_node = *new_top_node_p;
- switch (new_top_node->type) {
- case kExprNodeListLiteral: {
- if (pt_is_assignment(cur_pt) && new_top_node->children == NULL) {
- ERROR_FROM_TOKEN_AND_MSG(
- cur_token, _("E475: Unable to assign to empty list: %.*s"));
- }
- HL_CUR_TOKEN(List);
- break;
- }
- case kExprNodeSubscript: {
- HL_CUR_TOKEN(SubscriptBracket);
- break;
- }
- default: {
-viml_pexpr_parse_bracket_closing_error:
- assert(!kv_size(ast_stack));
- ERROR_FROM_TOKEN_AND_MSG(
- cur_token, _("E15: Unexpected closing figure brace: %.*s"));
- HL_CUR_TOKEN(List);
- break;
- }
+ *top_node_p = cur_node;
+ new_top_node_p = top_node_p;
+ goto viml_pexpr_parse_figure_brace_closing_error;
+ }
+ if (want_node == kENodeValue) {
+ if ((*kv_last(ast_stack))->type != kExprNodeUnknownFigure
+ && (*kv_last(ast_stack))->type != kExprNodeComma) {
+ // kv_last being UnknownFigure may occur for empty dictionary
+ // literal, while Comma is expected in case of non-empty one.
+ ERROR_FROM_TOKEN_AND_MSG(cur_token,
+ _("E15: Expected value, got closing figure brace: %.*s"));
}
- kvi_push(ast_stack, new_top_node_p);
- want_node = kENodeOperator;
- if (kv_size(ast_stack) <= asgn_level) {
- assert(kv_size(ast_stack) == asgn_level);
- asgn_level = 0;
- if (cur_pt == kEPTAssignment) {
- assert(ast.err.msg);
- } else if (cur_pt == kEPTExpr
- && kv_size(pt_stack) > 1
- && pt_is_assignment(kv_Z(pt_stack, 1))) {
- kv_drop(pt_stack, 1);
+ }
+ do {
+ new_top_node_p = kv_pop(ast_stack);
+ } while (kv_size(ast_stack)
+ && (new_top_node_p == NULL
+ || ((*new_top_node_p)->type != kExprNodeUnknownFigure
+ && (*new_top_node_p)->type != kExprNodeDictLiteral
+ && ((*new_top_node_p)->type
+ != kExprNodeCurlyBracesIdentifier)
+ && (*new_top_node_p)->type != kExprNodeLambda)));
+ ExprASTNode *new_top_node = *new_top_node_p;
+ switch (new_top_node->type) {
+ case kExprNodeUnknownFigure:
+ if (new_top_node->children == NULL) {
+ // No children of curly braces node indicates empty dictionary.
+ assert(want_node == kENodeValue);
+ assert(new_top_node->data.fig.type_guesses.allow_dict);
+ SELECT_FIGURE_BRACE_TYPE(new_top_node, DictLiteral, Dict);
+ HL_CUR_TOKEN(Dict);
+ } else if (new_top_node->data.fig.type_guesses.allow_ident) {
+ SELECT_FIGURE_BRACE_TYPE(new_top_node, CurlyBracesIdentifier,
+ Curly);
+ HL_CUR_TOKEN(Curly);
+ } else {
+ // If by this time type of the node has not already been
+ // guessed, but it definitely is not a curly braces name then
+ // it is invalid for sure.
+ ERROR_FROM_NODE_AND_MSG(new_top_node,
+ _("E15: Don't know what figure brace means: %.*s"));
+ if (pstate->colors) {
+ // Will reset to NvimInvalidFigureBrace.
+ kv_A(*pstate->colors,
+ new_top_node->data.fig.opening_hl_idx).group = (
+ HL(FigureBrace));
}
+ HL_CUR_TOKEN(FigureBrace);
}
- if (cur_pt == kEPTSingleAssignment && kv_size(ast_stack) == 1) {
+ break;
+ case kExprNodeDictLiteral:
+ HL_CUR_TOKEN(Dict);
+ break;
+ case kExprNodeCurlyBracesIdentifier:
+ HL_CUR_TOKEN(Curly);
+ break;
+ case kExprNodeLambda:
+ HL_CUR_TOKEN(Lambda);
+ break;
+ default:
+viml_pexpr_parse_figure_brace_closing_error:
+ assert(!kv_size(ast_stack));
+ ERROR_FROM_TOKEN_AND_MSG(cur_token, _("E15: Unexpected closing figure brace: %.*s"));
+ HL_CUR_TOKEN(FigureBrace);
+ break;
+ }
+ kvi_push(ast_stack, new_top_node_p);
+ want_node = kENodeOperator;
+ if (kv_size(ast_stack) <= asgn_level) {
+ assert(kv_size(ast_stack) == asgn_level);
+ if (cur_pt == kEPTExpr
+ && kv_size(pt_stack) > 1
+ && pt_is_assignment(kv_Z(pt_stack, 1))) {
kv_drop(pt_stack, 1);
- }
- } else {
- if (want_node == kENodeValue) {
- // Value means list literal or list assignment.
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeListLiteral);
- *top_node_p = cur_node;
- kvi_push(ast_stack, &cur_node->children);
- want_node = kENodeValue;
- if (cur_pt == kEPTAssignment) {
- // Additional assignment parse type allows to easily forbid nested
- // lists.
- kvi_push(pt_stack, kEPTSingleAssignment);
- } else if (cur_pt == kEPTSingleAssignment) {
- ERROR_FROM_TOKEN_AND_MSG(
- cur_token,
- _("E475: Nested lists not allowed when assigning: %.*s"));
- }
- HL_CUR_TOKEN(List);
- } else {
- // Operator means subscript, also in assignment. But in assignment
- // subscript may be pretty much any expression, so need to push
- // kEPTExpr.
- if (prev_token.type == kExprLexSpacing) {
- OP_MISSING;
- }
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeSubscript);
- ADD_OP_NODE(cur_node);
- HL_CUR_TOKEN(SubscriptBracket);
- if (pt_is_assignment(cur_pt)) {
- assert(want_node == kENodeValue); // Subtract 1 for NULL at top.
- asgn_level = kv_size(ast_stack) - 1;
- kvi_push(pt_stack, kEPTExpr);
- }
+ asgn_level = 0;
}
}
- break;
- }
- case kExprLexFigureBrace: {
- if (cur_token.data.brc.closing) {
- ExprASTNode **new_top_node_p = NULL;
- // Always drop the topmost value:
- //
- // 1. When want_node != kENodeValue topmost item on stack is
- // a *finished* left operand, which may as well be "{@a}" which
- // needs not be finished again.
- // 2. Otherwise it is pointing to NULL what nobody wants.
- kv_drop(ast_stack, 1);
- if (!kv_size(ast_stack)) {
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeUnknownFigure);
+ } else {
+ if (want_node == kENodeValue) {
+ HL_CUR_TOKEN(FigureBrace);
+ // Value: may be any of lambda, dictionary literal and curly braces
+ // name.
+
+ // Though if we are in an assignment this may only be a curly braces
+ // name.
+ if (pt_is_assignment(cur_pt)) {
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeCurlyBracesIdentifier);
cur_node->data.fig.type_guesses.allow_lambda = false;
cur_node->data.fig.type_guesses.allow_dict = false;
- cur_node->data.fig.type_guesses.allow_ident = false;
- cur_node->len = 0;
- if (want_node != kENodeValue) {
- cur_node->children = *top_node_p;
- }
- *top_node_p = cur_node;
- new_top_node_p = top_node_p;
- goto viml_pexpr_parse_figure_brace_closing_error;
- }
- if (want_node == kENodeValue) {
- if ((*kv_last(ast_stack))->type != kExprNodeUnknownFigure
- && (*kv_last(ast_stack))->type != kExprNodeComma) {
- // kv_last being UnknownFigure may occur for empty dictionary
- // literal, while Comma is expected in case of non-empty one.
- ERROR_FROM_TOKEN_AND_MSG(
- cur_token,
- _("E15: Expected value, got closing figure brace: %.*s"));
- }
- }
- do {
- new_top_node_p = kv_pop(ast_stack);
- } while (kv_size(ast_stack)
- && (new_top_node_p == NULL
- || ((*new_top_node_p)->type != kExprNodeUnknownFigure
- && (*new_top_node_p)->type != kExprNodeDictLiteral
- && ((*new_top_node_p)->type
- != kExprNodeCurlyBracesIdentifier)
- && (*new_top_node_p)->type != kExprNodeLambda)));
- ExprASTNode *new_top_node = *new_top_node_p;
- switch (new_top_node->type) {
- case kExprNodeUnknownFigure: {
- if (new_top_node->children == NULL) {
- // No children of curly braces node indicates empty dictionary.
- assert(want_node == kENodeValue);
- assert(new_top_node->data.fig.type_guesses.allow_dict);
- SELECT_FIGURE_BRACE_TYPE(new_top_node, DictLiteral, Dict);
- HL_CUR_TOKEN(Dict);
- } else if (new_top_node->data.fig.type_guesses.allow_ident) {
- SELECT_FIGURE_BRACE_TYPE(new_top_node, CurlyBracesIdentifier,
- Curly);
- HL_CUR_TOKEN(Curly);
- } else {
- // If by this time type of the node has not already been
- // guessed, but it definitely is not a curly braces name then
- // it is invalid for sure.
- ERROR_FROM_NODE_AND_MSG(
- new_top_node,
- _("E15: Don't know what figure brace means: %.*s"));
- if (pstate->colors) {
- // Will reset to NvimInvalidFigureBrace.
- kv_A(*pstate->colors,
- new_top_node->data.fig.opening_hl_idx).group = (
- HL(FigureBrace));
- }
- HL_CUR_TOKEN(FigureBrace);
- }
- break;
- }
- case kExprNodeDictLiteral: {
- HL_CUR_TOKEN(Dict);
- break;
- }
- case kExprNodeCurlyBracesIdentifier: {
- HL_CUR_TOKEN(Curly);
- break;
- }
- case kExprNodeLambda: {
- HL_CUR_TOKEN(Lambda);
- break;
- }
- default: {
-viml_pexpr_parse_figure_brace_closing_error:
- assert(!kv_size(ast_stack));
- ERROR_FROM_TOKEN_AND_MSG(
- cur_token, _("E15: Unexpected closing figure brace: %.*s"));
- HL_CUR_TOKEN(FigureBrace);
- break;
- }
+ cur_node->data.fig.type_guesses.allow_ident = true;
+ kvi_push(pt_stack, kEPTExpr);
+ } else {
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeUnknownFigure);
+ cur_node->data.fig.type_guesses.allow_lambda = true;
+ cur_node->data.fig.type_guesses.allow_dict = true;
+ cur_node->data.fig.type_guesses.allow_ident = true;
}
- kvi_push(ast_stack, new_top_node_p);
- want_node = kENodeOperator;
- if (kv_size(ast_stack) <= asgn_level) {
- assert(kv_size(ast_stack) == asgn_level);
- if (cur_pt == kEPTExpr
- && kv_size(pt_stack) > 1
- && pt_is_assignment(kv_Z(pt_stack, 1))) {
- kv_drop(pt_stack, 1);
- asgn_level = 0;
- }
+ if (pstate->colors) {
+ cur_node->data.fig.opening_hl_idx = kv_size(*pstate->colors) - 1;
}
+ *top_node_p = cur_node;
+ kvi_push(ast_stack, &cur_node->children);
+ kvi_push(pt_stack, kEPTLambdaArguments);
+ lambda_node = cur_node;
} else {
- if (want_node == kENodeValue) {
- HL_CUR_TOKEN(FigureBrace);
- // Value: may be any of lambda, dictionary literal and curly braces
- // name.
-
- // Though if we are in an assignment this may only be a curly braces
- // name.
+ ADD_IDENT(do {
+ NEW_NODE_WITH_CUR_POS(cur_node,
+ kExprNodeCurlyBracesIdentifier);
+ cur_node->data.fig.opening_hl_idx = kv_size(*pstate->colors);
+ cur_node->data.fig.type_guesses.allow_lambda = false;
+ cur_node->data.fig.type_guesses.allow_dict = false;
+ cur_node->data.fig.type_guesses.allow_ident = true;
+ kvi_push(ast_stack, &cur_node->children);
if (pt_is_assignment(cur_pt)) {
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeCurlyBracesIdentifier);
- cur_node->data.fig.type_guesses.allow_lambda = false;
- cur_node->data.fig.type_guesses.allow_dict = false;
- cur_node->data.fig.type_guesses.allow_ident = true;
kvi_push(pt_stack, kEPTExpr);
- } else {
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeUnknownFigure);
- cur_node->data.fig.type_guesses.allow_lambda = true;
- cur_node->data.fig.type_guesses.allow_dict = true;
- cur_node->data.fig.type_guesses.allow_ident = true;
- }
- if (pstate->colors) {
- cur_node->data.fig.opening_hl_idx = kv_size(*pstate->colors) - 1;
}
- *top_node_p = cur_node;
- kvi_push(ast_stack, &cur_node->children);
- kvi_push(pt_stack, kEPTLambdaArguments);
- lambda_node = cur_node;
- } else {
- ADD_IDENT(
- do {
- NEW_NODE_WITH_CUR_POS(cur_node,
- kExprNodeCurlyBracesIdentifier);
- cur_node->data.fig.opening_hl_idx = kv_size(*pstate->colors);
- cur_node->data.fig.type_guesses.allow_lambda = false;
- cur_node->data.fig.type_guesses.allow_dict = false;
- cur_node->data.fig.type_guesses.allow_ident = true;
- kvi_push(ast_stack, &cur_node->children);
- if (pt_is_assignment(cur_pt)) {
- kvi_push(pt_stack, kEPTExpr);
- }
- want_node = kENodeValue;
- } while (0),
- Curly);
- }
- if (pt_is_assignment(cur_pt)
- && !pt_is_assignment(kv_last(pt_stack))) {
- assert(want_node == kENodeValue); // Subtract 1 for NULL at top.
- asgn_level = kv_size(ast_stack) - 1;
- }
+ want_node = kENodeValue;
+ } while (0),
+ Curly);
+ }
+ if (pt_is_assignment(cur_pt)
+ && !pt_is_assignment(kv_last(pt_stack))) {
+ assert(want_node == kENodeValue); // Subtract 1 for NULL at top.
+ asgn_level = kv_size(ast_stack) - 1;
}
- break;
}
- case kExprLexArrow: {
- if (cur_pt == kEPTLambdaArguments) {
- kv_drop(pt_stack, 1);
- assert(kv_size(pt_stack));
- if (want_node == kENodeValue) {
- // Wanting value means trailing comma and NULL at the top of the
- // stack.
- kv_drop(ast_stack, 1);
- }
- assert(kv_size(ast_stack) >= 1);
- while ((*kv_last(ast_stack))->type != kExprNodeLambda
- && (*kv_last(ast_stack))->type != kExprNodeUnknownFigure) {
- kv_drop(ast_stack, 1);
- }
- assert((*kv_last(ast_stack)) == lambda_node);
- SELECT_FIGURE_BRACE_TYPE(lambda_node, Lambda, Lambda);
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeArrow);
- if (lambda_node->children == NULL) {
- assert(want_node == kENodeValue);
- lambda_node->children = cur_node;
- kvi_push(ast_stack, &lambda_node->children);
- } else {
- assert(lambda_node->children->next == NULL);
- lambda_node->children->next = cur_node;
- kvi_push(ast_stack, &lambda_node->children->next);
- }
- kvi_push(ast_stack, &cur_node->children);
- lambda_node = NULL;
+ break;
+ case kExprLexArrow:
+ if (cur_pt == kEPTLambdaArguments) {
+ kv_drop(pt_stack, 1);
+ assert(kv_size(pt_stack));
+ if (want_node == kENodeValue) {
+ // Wanting value means trailing comma and NULL at the top of the
+ // stack.
+ kv_drop(ast_stack, 1);
+ }
+ assert(kv_size(ast_stack) >= 1);
+ while ((*kv_last(ast_stack))->type != kExprNodeLambda
+ && (*kv_last(ast_stack))->type != kExprNodeUnknownFigure) {
+ kv_drop(ast_stack, 1);
+ }
+ assert((*kv_last(ast_stack)) == lambda_node);
+ SELECT_FIGURE_BRACE_TYPE(lambda_node, Lambda, Lambda);
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeArrow);
+ if (lambda_node->children == NULL) {
+ assert(want_node == kENodeValue);
+ lambda_node->children = cur_node;
+ kvi_push(ast_stack, &lambda_node->children);
} else {
- // Only first branch is valid.
- ADD_VALUE_IF_MISSING(_("E15: Unexpected arrow: %.*s"));
- ERROR_FROM_TOKEN_AND_MSG(
- cur_token, _("E15: Arrow outside of lambda: %.*s"));
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeArrow);
- ADD_OP_NODE(cur_node);
+ assert(lambda_node->children->next == NULL);
+ lambda_node->children->next = cur_node;
+ kvi_push(ast_stack, &lambda_node->children->next);
}
- want_node = kENodeValue;
- HL_CUR_TOKEN(Arrow);
- break;
+ kvi_push(ast_stack, &cur_node->children);
+ lambda_node = NULL;
+ } else {
+ // Only first branch is valid.
+ ADD_VALUE_IF_MISSING(_("E15: Unexpected arrow: %.*s"));
+ ERROR_FROM_TOKEN_AND_MSG(cur_token, _("E15: Arrow outside of lambda: %.*s"));
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeArrow);
+ ADD_OP_NODE(cur_node);
}
- case kExprLexPlainIdentifier: {
- const ExprVarScope scope = (cur_token.type == kExprLexInvalid
+ want_node = kENodeValue;
+ HL_CUR_TOKEN(Arrow);
+ break;
+ case kExprLexPlainIdentifier: {
+ const ExprVarScope scope = (cur_token.type == kExprLexInvalid
? kExprVarScopeMissing
: cur_token.data.var.scope);
- if (want_node == kENodeValue) {
- want_node = kENodeOperator;
- NEW_NODE_WITH_CUR_POS(cur_node,
- (node_is_key
+ if (want_node == kENodeValue) {
+ want_node = kENodeOperator;
+ NEW_NODE_WITH_CUR_POS(cur_node,
+ (node_is_key
? kExprNodePlainKey
: kExprNodePlainIdentifier));
- cur_node->data.var.scope = scope;
- const size_t scope_shift = (scope == kExprVarScopeMissing ? 0 : 2);
- cur_node->data.var.ident = (pline.data + cur_token.start.col
- + scope_shift);
- cur_node->data.var.ident_len = cur_token.len - scope_shift;
- *top_node_p = cur_node;
- if (scope_shift) {
- assert(!node_is_key);
- viml_parser_highlight(pstate, cur_token.start, 1,
- HL(IdentifierScope));
- viml_parser_highlight(pstate, shifted_pos(cur_token.start, 1), 1,
- HL(IdentifierScopeDelimiter));
- }
- viml_parser_highlight(pstate, shifted_pos(cur_token.start,
- scope_shift),
- cur_token.len - scope_shift,
- (node_is_key
+ cur_node->data.var.scope = scope;
+ const size_t scope_shift = (scope == kExprVarScopeMissing ? 0 : 2);
+ cur_node->data.var.ident = (pline.data + cur_token.start.col
+ + scope_shift);
+ cur_node->data.var.ident_len = cur_token.len - scope_shift;
+ *top_node_p = cur_node;
+ if (scope_shift) {
+ assert(!node_is_key);
+ viml_parser_highlight(pstate, cur_token.start, 1,
+ HL(IdentifierScope));
+ viml_parser_highlight(pstate, shifted_pos(cur_token.start, 1), 1,
+ HL(IdentifierScopeDelimiter));
+ }
+ viml_parser_highlight(pstate, shifted_pos(cur_token.start,
+ scope_shift),
+ cur_token.len - scope_shift,
+ (node_is_key
? HL(IdentifierKey)
: HL(IdentifierName)));
+ } else {
+ if (scope == kExprVarScopeMissing) {
+ ADD_IDENT(do {
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodePlainIdentifier);
+ cur_node->data.var.scope = scope;
+ cur_node->data.var.ident = pline.data + cur_token.start.col;
+ cur_node->data.var.ident_len = cur_token.len;
+ want_node = kENodeOperator;
+ } while (0),
+ IdentifierName);
} else {
- if (scope == kExprVarScopeMissing) {
- ADD_IDENT(
- do {
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodePlainIdentifier);
- cur_node->data.var.scope = scope;
- cur_node->data.var.ident = pline.data + cur_token.start.col;
- cur_node->data.var.ident_len = cur_token.len;
- want_node = kENodeOperator;
- } while (0),
- IdentifierName);
- } else {
- OP_MISSING;
- }
- }
- break;
- }
- case kExprLexNumber: {
- if (want_node != kENodeValue) {
OP_MISSING;
}
- if (node_is_key) {
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodePlainKey);
- cur_node->data.var.ident = pline.data + cur_token.start.col;
- cur_node->data.var.ident_len = cur_token.len;
- HL_CUR_TOKEN(IdentifierKey);
- } else if (cur_token.data.num.is_float) {
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeFloat);
- cur_node->data.flt.value = cur_token.data.num.val.floating;
- HL_CUR_TOKEN(Float);
- } else {
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeInteger);
- cur_node->data.num.value = cur_token.data.num.val.integer;
- const uint8_t prefix_length = base_to_prefix_length[
- cur_token.data.num.base];
- viml_parser_highlight(pstate, cur_token.start, prefix_length,
- HL(NumberPrefix));
- viml_parser_highlight(
- pstate, shifted_pos(cur_token.start, prefix_length),
- cur_token.len - prefix_length, HL(Number));
- }
- want_node = kENodeOperator;
- *top_node_p = cur_node;
- break;
}
- case kExprLexDot: {
- ADD_VALUE_IF_MISSING(_("E15: Unexpected dot: %.*s"));
- if (prev_token.type == kExprLexSpacing) {
- if (cur_pt == kEPTAssignment) {
- ERROR_FROM_TOKEN_AND_MSG(
- cur_token, _("E15: Cannot concatenate in assignments: %.*s"));
- }
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeConcat);
- HL_CUR_TOKEN(Concat);
- } else {
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeConcatOrSubscript);
- HL_CUR_TOKEN(ConcatOrSubscript);
+ break;
+ }
+ case kExprLexNumber:
+ if (want_node != kENodeValue) {
+ OP_MISSING;
+ }
+ if (node_is_key) {
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodePlainKey);
+ cur_node->data.var.ident = pline.data + cur_token.start.col;
+ cur_node->data.var.ident_len = cur_token.len;
+ HL_CUR_TOKEN(IdentifierKey);
+ } else if (cur_token.data.num.is_float) {
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeFloat);
+ cur_node->data.flt.value = cur_token.data.num.val.floating;
+ HL_CUR_TOKEN(Float);
+ } else {
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeInteger);
+ cur_node->data.num.value = cur_token.data.num.val.integer;
+ const uint8_t prefix_length = base_to_prefix_length[
+ cur_token.data.num.base];
+ viml_parser_highlight(pstate, cur_token.start, prefix_length,
+ HL(NumberPrefix));
+ viml_parser_highlight(pstate, shifted_pos(cur_token.start, prefix_length),
+ cur_token.len - prefix_length, HL(Number));
+ }
+ want_node = kENodeOperator;
+ *top_node_p = cur_node;
+ break;
+ case kExprLexDot:
+ ADD_VALUE_IF_MISSING(_("E15: Unexpected dot: %.*s"));
+ if (prev_token.type == kExprLexSpacing) {
+ if (cur_pt == kEPTAssignment) {
+ ERROR_FROM_TOKEN_AND_MSG(cur_token, _("E15: Cannot concatenate in assignments: %.*s"));
}
- ADD_OP_NODE(cur_node);
- break;
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeConcat);
+ HL_CUR_TOKEN(Concat);
+ } else {
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeConcatOrSubscript);
+ HL_CUR_TOKEN(ConcatOrSubscript);
}
- case kExprLexParenthesis: {
- if (cur_token.data.brc.closing) {
- if (want_node == kENodeValue) {
- if (kv_size(ast_stack) > 1) {
- const ExprASTNode *const prev_top_node = *kv_Z(ast_stack, 1);
- if (prev_top_node->type == kExprNodeCall) {
- // Function call without arguments, this is not an error.
- // But further code does not expect NULL nodes.
- kv_drop(ast_stack, 1);
- goto viml_pexpr_parse_no_paren_closing_error;
- }
+ ADD_OP_NODE(cur_node);
+ break;
+ case kExprLexParenthesis:
+ if (cur_token.data.brc.closing) {
+ if (want_node == kENodeValue) {
+ if (kv_size(ast_stack) > 1) {
+ const ExprASTNode *const prev_top_node = *kv_Z(ast_stack, 1);
+ if (prev_top_node->type == kExprNodeCall) {
+ // Function call without arguments, this is not an error.
+ // But further code does not expect NULL nodes.
+ kv_drop(ast_stack, 1);
+ goto viml_pexpr_parse_no_paren_closing_error;
}
- ERROR_FROM_TOKEN_AND_MSG(
- cur_token, _("E15: Expected value, got parenthesis: %.*s"));
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeMissing);
- cur_node->len = 0;
- *top_node_p = cur_node;
- } else {
- // Always drop the topmost value: when want_node != kENodeValue
- // topmost item on stack is a *finished* left operand, which may as
- // well be "(@a)" which needs not be finished again.
- kv_drop(ast_stack, 1);
}
+ ERROR_FROM_TOKEN_AND_MSG(cur_token, _("E15: Expected value, got parenthesis: %.*s"));
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeMissing);
+ cur_node->len = 0;
+ *top_node_p = cur_node;
+ } else {
+ // Always drop the topmost value: when want_node != kENodeValue
+ // topmost item on stack is a *finished* left operand, which may as
+ // well be "(@a)" which needs not be finished again.
+ kv_drop(ast_stack, 1);
+ }
viml_pexpr_parse_no_paren_closing_error: {}
- ExprASTNode **new_top_node_p = NULL;
- while (kv_size(ast_stack)
- && (new_top_node_p == NULL
- || ((*new_top_node_p)->type != kExprNodeNested
- && (*new_top_node_p)->type != kExprNodeCall))) {
- new_top_node_p = kv_pop(ast_stack);
- }
- if (new_top_node_p != NULL
- && ((*new_top_node_p)->type == kExprNodeNested
- || (*new_top_node_p)->type == kExprNodeCall)) {
- if ((*new_top_node_p)->type == kExprNodeNested) {
- HL_CUR_TOKEN(NestingParenthesis);
- } else {
- HL_CUR_TOKEN(CallingParenthesis);
- }
- } else {
- // “Always drop the topmost value” branch has got rid of the single
- // value stack had, so there is nothing known to enclose. Correct
- // this.
- if (new_top_node_p == NULL) {
- new_top_node_p = top_node_p;
- }
- ERROR_FROM_TOKEN_AND_MSG(
- cur_token, _("E15: Unexpected closing parenthesis: %.*s"));
+ ExprASTNode **new_top_node_p = NULL;
+ while (kv_size(ast_stack)
+ && (new_top_node_p == NULL
+ || ((*new_top_node_p)->type != kExprNodeNested
+ && (*new_top_node_p)->type != kExprNodeCall))) {
+ new_top_node_p = kv_pop(ast_stack);
+ }
+ if (new_top_node_p != NULL
+ && ((*new_top_node_p)->type == kExprNodeNested
+ || (*new_top_node_p)->type == kExprNodeCall)) {
+ if ((*new_top_node_p)->type == kExprNodeNested) {
HL_CUR_TOKEN(NestingParenthesis);
- cur_node = NEW_NODE(kExprNodeNested);
- cur_node->start = cur_token.start;
- cur_node->len = 0;
- // Unexpected closing parenthesis, assume that it was wanted to
- // enclose everything in ().
- cur_node->children = *new_top_node_p;
- *new_top_node_p = cur_node;
- assert(cur_node->next == NULL);
+ } else {
+ HL_CUR_TOKEN(CallingParenthesis);
}
- kvi_push(ast_stack, new_top_node_p);
- want_node = kENodeOperator;
} else {
- switch (want_node) {
- case kENodeValue: {
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeNested);
- *top_node_p = cur_node;
- kvi_push(ast_stack, &cur_node->children);
- HL_CUR_TOKEN(NestingParenthesis);
- break;
- }
- case kENodeOperator: {
- if (prev_token.type == kExprLexSpacing) {
- // For some reason "function (args)" is a function call, but
- // "(funcref) (args)" is not. AFAIR this somehow involves
- // compatibility and Bram was commenting that this is
- // intentionally inconsistent and he is not very happy with the
- // situation himself.
- if ((*top_node_p)->type != kExprNodePlainIdentifier
- && (*top_node_p)->type != kExprNodeComplexIdentifier
- && (*top_node_p)->type != kExprNodeCurlyBracesIdentifier) {
- OP_MISSING;
- }
- }
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeCall);
- ADD_OP_NODE(cur_node);
- HL_CUR_TOKEN(CallingParenthesis);
- break;
+ // “Always drop the topmost value” branch has got rid of the single
+ // value stack had, so there is nothing known to enclose. Correct
+ // this.
+ if (new_top_node_p == NULL) {
+ new_top_node_p = top_node_p;
+ }
+ ERROR_FROM_TOKEN_AND_MSG(cur_token, _("E15: Unexpected closing parenthesis: %.*s"));
+ HL_CUR_TOKEN(NestingParenthesis);
+ cur_node = NEW_NODE(kExprNodeNested);
+ cur_node->start = cur_token.start;
+ cur_node->len = 0;
+ // Unexpected closing parenthesis, assume that it was wanted to
+ // enclose everything in ().
+ cur_node->children = *new_top_node_p;
+ *new_top_node_p = cur_node;
+ assert(cur_node->next == NULL);
+ }
+ kvi_push(ast_stack, new_top_node_p);
+ want_node = kENodeOperator;
+ } else {
+ switch (want_node) {
+ case kENodeValue:
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeNested);
+ *top_node_p = cur_node;
+ kvi_push(ast_stack, &cur_node->children);
+ HL_CUR_TOKEN(NestingParenthesis);
+ break;
+ case kENodeOperator:
+ if (prev_token.type == kExprLexSpacing) {
+ // For some reason "function (args)" is a function call, but
+ // "(funcref) (args)" is not. AFAIR this somehow involves
+ // compatibility and Bram was commenting that this is
+ // intentionally inconsistent and he is not very happy with the
+ // situation himself.
+ if ((*top_node_p)->type != kExprNodePlainIdentifier
+ && (*top_node_p)->type != kExprNodeComplexIdentifier
+ && (*top_node_p)->type != kExprNodeCurlyBracesIdentifier) {
+ OP_MISSING;
}
}
- want_node = kENodeValue;
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeCall);
+ ADD_OP_NODE(cur_node);
+ HL_CUR_TOKEN(CallingParenthesis);
+ break;
}
- break;
- }
- case kExprLexQuestion: {
- ADD_VALUE_IF_MISSING(_("E15: Expected value, got question mark: %.*s"));
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeTernary);
- ADD_OP_NODE(cur_node);
- HL_CUR_TOKEN(Ternary);
- ExprASTNode *ter_val_node;
- NEW_NODE_WITH_CUR_POS(ter_val_node, kExprNodeTernaryValue);
- ter_val_node->data.ter.got_colon = false;
- assert(cur_node->children != NULL);
- assert(cur_node->children->next == NULL);
- assert(kv_last(ast_stack) == &cur_node->children->next);
- *kv_last(ast_stack) = ter_val_node;
- kvi_push(ast_stack, &ter_val_node->children);
- break;
+ want_node = kENodeValue;
}
- case kExprLexDoubleQuotedString:
- case kExprLexSingleQuotedString: {
- const bool is_double = (tok_type == kExprLexDoubleQuotedString);
- if (!cur_token.data.str.closed) {
- // It is weird, but Vim has two identical errors messages with
- // different error numbers: "E114: Missing quote" and
- // "E115: Missing quote".
- ERROR_FROM_TOKEN_AND_MSG(
- cur_token, (is_double
+ break;
+ case kExprLexQuestion: {
+ ADD_VALUE_IF_MISSING(_("E15: Expected value, got question mark: %.*s"));
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeTernary);
+ ADD_OP_NODE(cur_node);
+ HL_CUR_TOKEN(Ternary);
+ ExprASTNode *ter_val_node;
+ NEW_NODE_WITH_CUR_POS(ter_val_node, kExprNodeTernaryValue);
+ ter_val_node->data.ter.got_colon = false;
+ assert(cur_node->children != NULL);
+ assert(cur_node->children->next == NULL);
+ assert(kv_last(ast_stack) == &cur_node->children->next);
+ *kv_last(ast_stack) = ter_val_node;
+ kvi_push(ast_stack, &ter_val_node->children);
+ break;
+ }
+ case kExprLexDoubleQuotedString:
+ case kExprLexSingleQuotedString: {
+ const bool is_double = (tok_type == kExprLexDoubleQuotedString);
+ if (!cur_token.data.str.closed) {
+ // It is weird, but Vim has two identical errors messages with
+ // different error numbers: "E114: Missing quote" and
+ // "E115: Missing quote".
+ ERROR_FROM_TOKEN_AND_MSG(cur_token, (is_double
? _("E114: Missing double quote: %.*s")
: _("E115: Missing single quote: %.*s")));
- }
- if (want_node == kENodeOperator) {
- OP_MISSING;
- }
- NEW_NODE_WITH_CUR_POS(
- cur_node, (is_double
+ }
+ if (want_node == kENodeOperator) {
+ OP_MISSING;
+ }
+ NEW_NODE_WITH_CUR_POS(cur_node, (is_double
? kExprNodeDoubleQuotedString
: kExprNodeSingleQuotedString));
- *top_node_p = cur_node;
- parse_quoted_string(pstate, cur_node, cur_token, ast_stack, is_invalid);
- want_node = kENodeOperator;
- break;
+ *top_node_p = cur_node;
+ parse_quoted_string(pstate, cur_node, cur_token, ast_stack, is_invalid);
+ want_node = kENodeOperator;
+ break;
+ }
+ case kExprLexAssignment:
+ if (cur_pt == kEPTAssignment) {
+ kv_drop(pt_stack, 1);
+ } else if (cur_pt == kEPTSingleAssignment) {
+ kv_drop(pt_stack, 2);
+ ERROR_FROM_TOKEN_AND_MSG(cur_token,
+ _("E475: Expected closing bracket to end list assignment "
+ "lvalue: %.*s"));
+ } else {
+ ERROR_FROM_TOKEN_AND_MSG(cur_token, _("E15: Misplaced assignment: %.*s"));
}
- case kExprLexAssignment: {
- if (cur_pt == kEPTAssignment) {
- kv_drop(pt_stack, 1);
- } else if (cur_pt == kEPTSingleAssignment) {
- kv_drop(pt_stack, 2);
- ERROR_FROM_TOKEN_AND_MSG(
- cur_token,
- _("E475: Expected closing bracket to end list assignment "
- "lvalue: %.*s"));
- } else {
- ERROR_FROM_TOKEN_AND_MSG(
- cur_token, _("E15: Misplaced assignment: %.*s"));
- }
- assert(kv_size(pt_stack));
- assert(kv_last(pt_stack) == kEPTExpr);
- ADD_VALUE_IF_MISSING(_("E15: Unexpected assignment: %.*s"));
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeAssignment);
- cur_node->data.ass.type = cur_token.data.ass.type;
- switch (cur_token.data.ass.type) {
+ assert(kv_size(pt_stack));
+ assert(kv_last(pt_stack) == kEPTExpr);
+ ADD_VALUE_IF_MISSING(_("E15: Unexpected assignment: %.*s"));
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeAssignment);
+ cur_node->data.ass.type = cur_token.data.ass.type;
+ switch (cur_token.data.ass.type) {
#define HL_ASGN(asgn, hl) \
- case kExprAsgn##asgn: { HL_CUR_TOKEN(hl); break; }
- HL_ASGN(Plain, PlainAssignment)
- HL_ASGN(Add, AssignmentWithAddition)
- HL_ASGN(Subtract, AssignmentWithSubtraction)
- HL_ASGN(Concat, AssignmentWithConcatenation)
+case kExprAsgn##asgn: { HL_CUR_TOKEN(hl); break; }
+ HL_ASGN(Plain, PlainAssignment)
+ HL_ASGN(Add, AssignmentWithAddition)
+ HL_ASGN(Subtract, AssignmentWithSubtraction)
+ HL_ASGN(Concat, AssignmentWithConcatenation)
#undef HL_ASGN
- }
- ADD_OP_NODE(cur_node);
- break;
}
+ ADD_OP_NODE(cur_node);
+ break;
}
viml_pexpr_parse_cycle_end:
prev_token = cur_token;
@@ -2972,115 +2970,96 @@ viml_pexpr_parse_end:
assert(cur_node != NULL);
// TODO(ZyX-I): Rehighlight as invalid?
switch (cur_node->type) {
- case kExprNodeOpMissing:
- case kExprNodeMissing: {
- // Error should’ve been already reported.
- break;
- }
- case kExprNodeCall: {
- east_set_error(
- pstate, &ast.err,
- _("E116: Missing closing parenthesis for function call: %.*s"),
- cur_node->start);
- break;
- }
- case kExprNodeNested: {
- east_set_error(
- pstate, &ast.err,
- _("E110: Missing closing parenthesis for nested expression"
- ": %.*s"),
- cur_node->start);
- break;
- }
- case kExprNodeListLiteral: {
- // For whatever reason "[1" yields "E696: Missing comma in list" error
- // in Vim while "[1," yields E697.
- east_set_error(
- pstate, &ast.err,
- _("E697: Missing end of List ']': %.*s"),
- cur_node->start);
- break;
- }
- case kExprNodeDictLiteral: {
- // Same problem like with list literal with E722 (missing comma) vs
- // E723, but additionally just "{" yields only E15.
- east_set_error(
- pstate, &ast.err,
- _("E723: Missing end of Dictionary '}': %.*s"),
- cur_node->start);
- break;
- }
- case kExprNodeUnknownFigure: {
- east_set_error(
- pstate, &ast.err,
- _("E15: Missing closing figure brace: %.*s"),
- cur_node->start);
- break;
- }
- case kExprNodeLambda: {
- east_set_error(
- pstate, &ast.err,
- _("E15: Missing closing figure brace for lambda: %.*s"),
- cur_node->start);
- break;
- }
- case kExprNodeCurlyBracesIdentifier: {
- // Until trailing "}" it is impossible to distinguish curly braces
- // identifier and dictionary, so it must not appear in the stack like
- // this.
- abort();
- }
- case kExprNodeInteger:
- case kExprNodeFloat:
- case kExprNodeSingleQuotedString:
- case kExprNodeDoubleQuotedString:
- case kExprNodeOption:
- case kExprNodeEnvironment:
- case kExprNodeRegister:
- case kExprNodePlainIdentifier:
- case kExprNodePlainKey: {
- // These are plain values and not containers, for them it should only
- // be possible to show up in the topmost stack element, but it was
- // unconditionally popped at the start.
- abort();
- }
- case kExprNodeComma:
- case kExprNodeColon:
- case kExprNodeArrow: {
- // It is actually only valid inside something else, but everything
- // where one of the above is valid requires to be closed and thus is
- // to be caught later.
- break;
- }
- case kExprNodeSubscript:
- case kExprNodeConcatOrSubscript:
- case kExprNodeComplexIdentifier:
- case kExprNodeAssignment:
- case kExprNodeMod:
- case kExprNodeDivision:
- case kExprNodeMultiplication:
- case kExprNodeNot:
- case kExprNodeAnd:
- case kExprNodeOr:
- case kExprNodeConcat:
- case kExprNodeComparison:
- case kExprNodeUnaryMinus:
- case kExprNodeUnaryPlus:
- case kExprNodeBinaryMinus:
- case kExprNodeTernary:
- case kExprNodeBinaryPlus: {
- // It is OK to see these in the stack.
- break;
- }
- case kExprNodeTernaryValue: {
- if (!cur_node->data.ter.got_colon) {
- // Actually Vim throws E109 in more cases.
- east_set_error(
- pstate, &ast.err, _("E109: Missing ':' after '?': %.*s"),
- cur_node->start);
- }
- break;
+ case kExprNodeOpMissing:
+ case kExprNodeMissing:
+ // Error should’ve been already reported.
+ break;
+ case kExprNodeCall:
+ east_set_error(pstate, &ast.err,
+ _("E116: Missing closing parenthesis for function call: %.*s"),
+ cur_node->start);
+ break;
+ case kExprNodeNested:
+ east_set_error(pstate, &ast.err,
+ _("E110: Missing closing parenthesis for nested expression"
+ ": %.*s"),
+ cur_node->start);
+ break;
+ case kExprNodeListLiteral:
+ // For whatever reason "[1" yields "E696: Missing comma in list" error
+ // in Vim while "[1," yields E697.
+ east_set_error(pstate, &ast.err,
+ _("E697: Missing end of List ']': %.*s"),
+ cur_node->start);
+ break;
+ case kExprNodeDictLiteral:
+ // Same problem like with list literal with E722 (missing comma) vs
+ // E723, but additionally just "{" yields only E15.
+ east_set_error(pstate, &ast.err,
+ _("E723: Missing end of Dictionary '}': %.*s"),
+ cur_node->start);
+ break;
+ case kExprNodeUnknownFigure:
+ east_set_error(pstate, &ast.err,
+ _("E15: Missing closing figure brace: %.*s"),
+ cur_node->start);
+ break;
+ case kExprNodeLambda:
+ east_set_error(pstate, &ast.err,
+ _("E15: Missing closing figure brace for lambda: %.*s"),
+ cur_node->start);
+ break;
+ case kExprNodeCurlyBracesIdentifier:
+ // Until trailing "}" it is impossible to distinguish curly braces
+ // identifier and dictionary, so it must not appear in the stack like
+ // this.
+ abort();
+ case kExprNodeInteger:
+ case kExprNodeFloat:
+ case kExprNodeSingleQuotedString:
+ case kExprNodeDoubleQuotedString:
+ case kExprNodeOption:
+ case kExprNodeEnvironment:
+ case kExprNodeRegister:
+ case kExprNodePlainIdentifier:
+ case kExprNodePlainKey:
+ // These are plain values and not containers, for them it should only
+ // be possible to show up in the topmost stack element, but it was
+ // unconditionally popped at the start.
+ abort();
+ case kExprNodeComma:
+ case kExprNodeColon:
+ case kExprNodeArrow:
+ // It is actually only valid inside something else, but everything
+ // where one of the above is valid requires to be closed and thus is
+ // to be caught later.
+ break;
+ case kExprNodeSubscript:
+ case kExprNodeConcatOrSubscript:
+ case kExprNodeComplexIdentifier:
+ case kExprNodeAssignment:
+ case kExprNodeMod:
+ case kExprNodeDivision:
+ case kExprNodeMultiplication:
+ case kExprNodeNot:
+ case kExprNodeAnd:
+ case kExprNodeOr:
+ case kExprNodeConcat:
+ case kExprNodeComparison:
+ case kExprNodeUnaryMinus:
+ case kExprNodeUnaryPlus:
+ case kExprNodeBinaryMinus:
+ case kExprNodeTernary:
+ case kExprNodeBinaryPlus:
+ // It is OK to see these in the stack.
+ break;
+ case kExprNodeTernaryValue:
+ if (!cur_node->data.ter.got_colon) {
+ // Actually Vim throws E109 in more cases.
+ east_set_error(pstate, &ast.err, _("E109: Missing ':' after '?': %.*s"),
+ cur_node->start);
}
+ break;
}
}
}
diff --git a/src/nvim/window.c b/src/nvim/window.c
index d051e8e467..c0f537aab3 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -5,11 +5,8 @@
#include <inttypes.h>
#include <stdbool.h>
-#include "nvim/api/private/handle.h"
#include "nvim/api/private/helpers.h"
-#include "nvim/vim.h"
#include "nvim/ascii.h"
-#include "nvim/window.h"
#include "nvim/buffer.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
@@ -21,8 +18,10 @@
#include "nvim/ex_docmd.h"
#include "nvim/ex_eval.h"
#include "nvim/ex_getln.h"
+#include "nvim/file_search.h"
#include "nvim/fileio.h"
#include "nvim/fold.h"
+#include "nvim/garray.h"
#include "nvim/getchar.h"
#include "nvim/hashtab.h"
#include "nvim/main.h"
@@ -31,14 +30,14 @@
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/file_search.h"
-#include "nvim/garray.h"
-#include "nvim/move.h"
#include "nvim/mouse.h"
+#include "nvim/move.h"
#include "nvim/normal.h"
#include "nvim/option.h"
+#include "nvim/os/os.h"
#include "nvim/os_unix.h"
#include "nvim/path.h"
+#include "nvim/plines.h"
#include "nvim/quickfix.h"
#include "nvim/regexp.h"
#include "nvim/screen.h"
@@ -47,10 +46,11 @@
#include "nvim/strings.h"
#include "nvim/syntax.h"
#include "nvim/terminal.h"
-#include "nvim/undo.h"
#include "nvim/ui.h"
#include "nvim/ui_compositor.h"
-#include "nvim/os/os.h"
+#include "nvim/undo.h"
+#include "nvim/vim.h"
+#include "nvim/window.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -60,26 +60,29 @@
-#define NOWIN (win_T *)-1 /* non-existing window */
+#define NOWIN (win_T *)-1 // non-existing window
-# define ROWS_AVAIL (Rows - p_ch - tabline_height())
+#define ROWS_AVAIL (Rows - p_ch - tabline_height())
+/// flags for win_enter_ext()
+typedef enum {
+ WEE_UNDO_SYNC = 0x01,
+ WEE_CURWIN_INVALID = 0x02,
+ WEE_TRIGGER_NEW_AUTOCMDS = 0x04,
+ WEE_TRIGGER_ENTER_AUTOCMDS = 0x08,
+ WEE_TRIGGER_LEAVE_AUTOCMDS = 0x10,
+} wee_flags_T;
static char *m_onlyone = N_("Already only one window");
-/*
- * all CTRL-W window commands are handled here, called from normal_cmd().
- */
-void
-do_window(
- int nchar,
- long Prenum,
- int xchar /* extra char from ":wincmd gx" or NUL */
-)
+/// all CTRL-W window commands are handled here, called from normal_cmd().
+///
+/// @param xchar extra char from ":wincmd gx" or NUL
+void do_window(int nchar, long Prenum, int xchar)
{
long Prenum1;
- win_T *wp;
- char_u *ptr;
+ win_T *wp;
+ char_u *ptr;
linenr_T lnum = -1;
int type = FIND_DEFINE;
size_t len;
@@ -87,7 +90,7 @@ do_window(
Prenum1 = Prenum == 0 ? 1 : Prenum;
-# define CHECK_CMDWIN \
+#define CHECK_CMDWIN \
do { \
if (cmdwin_type != 0) { \
EMSG(_(e_cmdwin)); \
@@ -96,7 +99,7 @@ do_window(
} while (0)
switch (nchar) {
- /* split current window in two parts, horizontally */
+ // split current window in two parts, horizontally
case 'S':
case Ctrl_S:
case 's':
@@ -110,7 +113,7 @@ do_window(
(void)win_split((int)Prenum, 0);
break;
- /* split current window in two parts, vertically */
+ // split current window in two parts, vertically
case Ctrl_V:
case 'v':
CHECK_CMDWIN;
@@ -123,7 +126,7 @@ do_window(
(void)win_split((int)Prenum, WSP_VERT);
break;
- /* split current window and edit alternate file */
+ // split current window and edit alternate file
case Ctrl_HAT:
case '^':
CHECK_CMDWIN;
@@ -144,17 +147,18 @@ do_window(
}
break;
- /* open new window */
+ // open new window
case Ctrl_N:
case 'n':
CHECK_CMDWIN;
reset_VIsual_and_resel(); // stop Visual mode
newwindow:
- if (Prenum)
- /* window height */
+ if (Prenum) {
+ // window height
vim_snprintf(cbuf, sizeof(cbuf) - 5, "%" PRId64, (int64_t)Prenum);
- else
+ } else {
cbuf[0] = NUL;
+ }
if (nchar == 'v' || nchar == Ctrl_V) {
xstrlcat(cbuf, "v", sizeof(cbuf));
}
@@ -162,23 +166,23 @@ newwindow:
do_cmdline_cmd(cbuf);
break;
- /* quit current window */
+ // quit current window
case Ctrl_Q:
case 'q':
- reset_VIsual_and_resel(); /* stop Visual mode */
+ reset_VIsual_and_resel(); // stop Visual mode
cmd_with_count("quit", (char_u *)cbuf, sizeof(cbuf), Prenum);
do_cmdline_cmd(cbuf);
break;
- /* close current window */
+ // close current window
case Ctrl_C:
case 'c':
- reset_VIsual_and_resel(); /* stop Visual mode */
+ reset_VIsual_and_resel(); // stop Visual mode
cmd_with_count("close", (char_u *)cbuf, sizeof(cbuf), Prenum);
do_cmdline_cmd(cbuf);
break;
- /* close preview window */
+ // close preview window
case Ctrl_Z:
case 'z':
CHECK_CMDWIN;
@@ -186,7 +190,7 @@ newwindow:
do_cmdline_cmd("pclose");
break;
- /* cursor to preview window */
+ // cursor to preview window
case 'P':
wp = NULL;
FOR_ALL_WINDOWS_IN_TAB(wp2, curtab) {
@@ -202,7 +206,7 @@ newwindow:
}
break;
- /* close all but current window */
+ // close all but current window
case Ctrl_O:
case 'o':
CHECK_CMDWIN;
@@ -211,10 +215,10 @@ newwindow:
do_cmdline_cmd(cbuf);
break;
- /* cursor to next window with wrap around */
+ // cursor to next window with wrap around
case Ctrl_W:
case 'w':
- /* cursor to previous window with wrap around */
+ // cursor to previous window with wrap around
case 'W':
CHECK_CMDWIN;
if (ONE_WINDOW && Prenum != 1) { // just one window
@@ -222,10 +226,11 @@ newwindow:
} else {
if (Prenum) { // go to specified window
for (wp = firstwin; --Prenum > 0; ) {
- if (wp->w_next == NULL)
+ if (wp->w_next == NULL) {
break;
- else
+ } else {
wp = wp->w_next;
+ }
}
} else {
if (nchar == 'W') { // go to previous window
@@ -252,7 +257,7 @@ newwindow:
}
break;
- /* cursor to window below */
+ // cursor to window below
case 'j':
case K_DOWN:
case Ctrl_J:
@@ -260,7 +265,7 @@ newwindow:
win_goto_ver(false, Prenum1);
break;
- /* cursor to window above */
+ // cursor to window above
case 'k':
case K_UP:
case Ctrl_K:
@@ -268,7 +273,7 @@ newwindow:
win_goto_ver(true, Prenum1);
break;
- /* cursor to left window */
+ // cursor to left window
case 'h':
case K_LEFT:
case Ctrl_H:
@@ -277,7 +282,7 @@ newwindow:
win_goto_hor(true, Prenum1);
break;
- /* cursor to right window */
+ // cursor to right window
case 'l':
case K_RIGHT:
case Ctrl_L:
@@ -285,13 +290,13 @@ newwindow:
win_goto_hor(false, Prenum1);
break;
- /* move window to new tab page */
+ // move window to new tab page
case 'T':
- if (one_window())
+ if (one_window()) {
MSG(_(m_onlyone));
- else {
- tabpage_T *oldtab = curtab;
- tabpage_T *newtab;
+ } else {
+ tabpage_T *oldtab = curtab;
+ tabpage_T *newtab;
/* First create a new tab with the window, then go back to
* the old tab and close the window there. */
@@ -311,19 +316,19 @@ newwindow:
}
break;
- /* cursor to top-left window */
+ // cursor to top-left window
case 't':
case Ctrl_T:
win_goto(firstwin);
break;
- /* cursor to bottom-right window */
+ // cursor to bottom-right window
case 'b':
case Ctrl_B:
win_goto(lastwin_nofloating());
break;
- /* cursor to last accessed (previous) window */
+ // cursor to last accessed (previous) window
case 'p':
case Ctrl_P:
if (!win_valid(prevwin)) {
@@ -333,14 +338,14 @@ newwindow:
}
break;
- /* exchange current and next window */
+ // exchange current and next window
case 'x':
case Ctrl_X:
CHECK_CMDWIN;
win_exchange(Prenum);
break;
- /* rotate windows downwards */
+ // rotate windows downwards
case Ctrl_R:
case 'r':
CHECK_CMDWIN;
@@ -348,14 +353,14 @@ newwindow:
win_rotate(false, (int)Prenum1); // downwards
break;
- /* rotate windows upwards */
+ // rotate windows upwards
case 'R':
CHECK_CMDWIN;
reset_VIsual_and_resel(); // stop Visual mode
win_rotate(true, (int)Prenum1); // upwards
break;
- /* move window to the very top/bottom/left/right */
+ // move window to the very top/bottom/left/right
case 'K':
case 'J':
case 'H':
@@ -366,43 +371,43 @@ newwindow:
| ((nchar == 'H' || nchar == 'K') ? WSP_TOP : WSP_BOT));
break;
- /* make all windows the same height */
+ // make all windows the same height
case '=':
win_equal(NULL, false, 'b');
break;
- /* increase current window height */
+ // increase current window height
case '+':
win_setheight(curwin->w_height + (int)Prenum1);
break;
- /* decrease current window height */
+ // decrease current window height
case '-':
win_setheight(curwin->w_height - (int)Prenum1);
break;
- /* set current window height */
+ // set current window height
case Ctrl__:
case '_':
win_setheight(Prenum ? (int)Prenum : Rows-1);
break;
- /* increase current window width */
+ // increase current window width
case '>':
win_setwidth(curwin->w_width + (int)Prenum1);
break;
- /* decrease current window width */
+ // decrease current window width
case '<':
win_setwidth(curwin->w_width - (int)Prenum1);
break;
- /* set current window width */
+ // set current window width
case '|':
win_setwidth(Prenum != 0 ? (int)Prenum : Columns);
break;
- /* jump to tag and split window if tag exists (in preview window) */
+ // jump to tag and split window if tag exists (in preview window)
case '}':
CHECK_CMDWIN;
if (Prenum) {
@@ -415,10 +420,11 @@ newwindow:
case Ctrl_RSB:
CHECK_CMDWIN;
// Keep visual mode, can select words to use as a tag.
- if (Prenum)
+ if (Prenum) {
postponed_split = Prenum;
- else
+ } else {
postponed_split = -1;
+ }
if (nchar != '}') {
g_do_tagpreview = 0;
@@ -429,7 +435,7 @@ newwindow:
do_nv_ident(Ctrl_RSB, NUL);
break;
- /* edit file name under cursor in a new window */
+ // edit file name under cursor in a new window
case 'f':
case 'F':
case Ctrl_F:
@@ -460,7 +466,7 @@ wingotofile:
/* Go to the first occurrence of the identifier under cursor along path in a
* new window -- webb
*/
- case 'i': /* Go to any match */
+ case 'i': // Go to any match
case Ctrl_I:
type = FIND_ANY;
FALLTHROUGH;
@@ -484,7 +490,7 @@ wingotofile:
break;
- /* CTRL-W g extended commands */
+ // CTRL-W g extended commands
case 'g':
case Ctrl_G:
CHECK_CMDWIN;
@@ -498,18 +504,20 @@ wingotofile:
switch (xchar) {
case '}':
xchar = Ctrl_RSB;
- if (Prenum)
+ if (Prenum) {
g_do_tagpreview = Prenum;
- else
+ } else {
g_do_tagpreview = p_pvh;
+ }
FALLTHROUGH;
case ']':
case Ctrl_RSB:
// Keep visual mode, can select words to use as a tag.
- if (Prenum)
+ if (Prenum) {
postponed_split = Prenum;
- else
+ } else {
postponed_split = -1;
+ }
/* Execute the command right here, required when
* "wincmd g}" was used in a function. */
@@ -520,8 +528,8 @@ wingotofile:
goto_tabpage_lastused();
break;
- case 'f': /* CTRL-W gf: "gf" in a new tab page */
- case 'F': /* CTRL-W gF: "gF" in a new tab page */
+ case 'f': // CTRL-W gf: "gf" in a new tab page
+ case 'F': // CTRL-W gF: "gF" in a new tab page
cmdmod.tab = tabpage_index(curtab) + 1;
nchar = xchar;
goto wingotofile;
@@ -555,13 +563,13 @@ wingotofile:
}
break;
- default: beep_flush();
+ default:
+ beep_flush();
break;
}
}
-static void cmd_with_count(char *cmd, char_u *bufp, size_t bufsize,
- int64_t Prenum)
+static void cmd_with_count(char *cmd, char_u *bufp, size_t bufsize, int64_t Prenum)
{
size_t len = xstrlcpy((char *)bufp, cmd, bufsize);
@@ -676,7 +684,7 @@ void win_set_minimal_style(win_T *wp)
}
// signcolumn: use 'auto'
- if (wp->w_p_scl[0] != 'a') {
+ if (wp->w_p_scl[0] != 'a' || STRLEN(wp->w_p_scl) >= 8) {
xfree(wp->w_p_scl);
wp->w_p_scl = (char_u *)xstrdup("auto");
}
@@ -737,6 +745,37 @@ void win_config_float(win_T *wp, FloatConfig fconfig)
redraw_later(wp, NOT_VALID);
}
+ // compute initial position
+ if (wp->w_float_config.relative == kFloatRelativeWindow) {
+ int row = wp->w_float_config.row;
+ int col = wp->w_float_config.col;
+ Error dummy = ERROR_INIT;
+ win_T *parent = find_window_by_handle(wp->w_float_config.window, &dummy);
+ if (parent) {
+ row += parent->w_winrow;
+ col += parent->w_wincol;
+ ScreenGrid *grid = &parent->w_grid;
+ int row_off = 0, col_off = 0;
+ screen_adjust_grid(&grid, &row_off, &col_off);
+ row += row_off;
+ col += col_off;
+ }
+ api_clear_error(&dummy);
+ if (wp->w_float_config.bufpos.lnum >= 0) {
+ pos_T pos = { wp->w_float_config.bufpos.lnum + 1,
+ wp->w_float_config.bufpos.col, 0 };
+ int trow, tcol, tcolc, tcole;
+ textpos2screenpos(wp, &pos, &trow, &tcol, &tcolc, &tcole, true);
+ row += trow - 1;
+ col += tcol - 1;
+ }
+ wp->w_winrow = row;
+ wp->w_wincol = col;
+ } else {
+ wp->w_winrow = fconfig.row;
+ wp->w_wincol = fconfig.col;
+ }
+
// changing border style while keeping border only requires redrawing border
if (fconfig.border) {
wp->w_redr_border = true;
@@ -770,7 +809,6 @@ int win_fdccol_count(win_T *wp)
}
}
-
void ui_ext_win_position(win_T *wp)
{
if (!wp->w_floating) {
@@ -817,6 +855,8 @@ void ui_ext_win_position(win_T *wp)
int comp_row = (int)row - (south ? wp->w_height : 0);
int comp_col = (int)col - (east ? wp->w_width : 0);
+ comp_row += grid->comp_row;
+ comp_col += grid->comp_col;
comp_row = MAX(MIN(comp_row, Rows-wp->w_height_outer-1), 0);
comp_col = MAX(MIN(comp_col, Columns-wp->w_width_outer), 0);
wp->w_winrow = comp_row;
@@ -834,21 +874,21 @@ void ui_ext_win_position(win_T *wp)
} else {
ui_call_win_external_pos(wp->w_grid_alloc.handle, wp->handle);
}
-
}
void ui_ext_win_viewport(win_T *wp)
{
if ((wp == curwin || ui_has(kUIMultigrid)) && wp->w_viewport_invalid) {
int botline = wp->w_botline;
- if (botline == wp->w_buffer->b_ml.ml_line_count+1
- && wp->w_empty_rows == 0) {
+ int line_count = wp->w_buffer->b_ml.ml_line_count;
+ if (botline == line_count+1 && wp->w_empty_rows == 0) {
// TODO(bfredl): The might be more cases to consider, like how does this
// interact with incomplete final line? Diff filler lines?
botline = wp->w_buffer->b_ml.ml_line_count;
}
ui_call_win_viewport(wp->w_grid_alloc.handle, wp->handle, wp->w_topline-1,
- botline, wp->w_cursor.lnum-1, wp->w_cursor.col);
+ botline, wp->w_cursor.lnum-1, wp->w_cursor.col,
+ line_count);
wp->w_viewport_invalid = false;
}
}
@@ -870,11 +910,12 @@ void ui_ext_win_viewport(win_T *wp)
*/
int win_split(int size, int flags)
{
- /* When the ":tab" modifier was used open a new tab page instead. */
- if (may_open_tabpage() == OK)
+ // When the ":tab" modifier was used open a new tab page instead.
+ if (may_open_tabpage() == OK) {
return OK;
+ }
- /* Add flags from ":vertical", ":topleft" and ":botright". */
+ // Add flags from ":vertical", ":topleft" and ":botright".
flags |= cmdmod.split;
if ((flags & WSP_TOP) && (flags & WSP_BOT)) {
EMSG(_("E442: Can't split topleft and botright at the same time"));
@@ -883,10 +924,11 @@ int win_split(int size, int flags)
/* When creating the help window make a snapshot of the window layout.
* Otherwise clear the snapshot, it's now invalid. */
- if (flags & WSP_HELP)
+ if (flags & WSP_HELP) {
make_snapshot(SNAP_HELP_IDX);
- else
+ } else {
clear_snapshot(curtab, SNAP_HELP_IDX);
+ }
return win_split_ins(size, flags, NULL, 0);
}
@@ -899,17 +941,17 @@ int win_split(int size, int flags)
*/
int win_split_ins(int size, int flags, win_T *new_wp, int dir)
{
- win_T *wp = new_wp;
- win_T *oldwin;
+ win_T *wp = new_wp;
+ win_T *oldwin;
int new_size = size;
int i;
int need_status = 0;
- int do_equal = FALSE;
+ bool do_equal = false;
int needed;
int available;
int oldwin_height = 0;
int layout;
- frame_T *frp, *curfrp, *frp2, *prevfrp;
+ frame_T *frp, *curfrp, *frp2, *prevfrp;
int before;
int minheight;
int wmh1;
@@ -981,8 +1023,9 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
EMSG(_(e_noroom));
return FAIL;
}
- if (new_size == 0)
+ if (new_size == 0) {
new_size = oldwin->w_width / 2;
+ }
if (new_size > available - minwidth - 1) {
new_size = available - minwidth - 1;
}
@@ -990,9 +1033,10 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
new_size = wmw1;
}
- /* if it doesn't fit in the current window, need win_equal() */
- if (oldwin->w_width - new_size - 1 < p_wmw)
- do_equal = TRUE;
+ // if it doesn't fit in the current window, need win_equal()
+ if (oldwin->w_width - new_size - 1 < p_wmw) {
+ do_equal = true;
+ }
// We don't like to take lines for the new window from a
// 'winfixwidth' window. Take them from a window to the left or right
@@ -1009,9 +1053,9 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
while (frp != NULL) {
if (frp->fr_win != oldwin && frp->fr_win != NULL
&& (frp->fr_win->w_width > new_size
- || frp->fr_win->w_width > oldwin->w_width
- - new_size - 1)) {
- do_equal = TRUE;
+ || frp->fr_win->w_width > (oldwin->w_width
+ - new_size - 1))) {
+ do_equal = true;
break;
}
frp = frp->fr_next;
@@ -1064,8 +1108,9 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
oldwin->w_status_height = STATUS_HEIGHT;
oldwin_height -= STATUS_HEIGHT;
}
- if (new_size == 0)
+ if (new_size == 0) {
new_size = oldwin_height / 2;
+ }
if (new_size > available - minheight - STATUS_HEIGHT) {
new_size = available - minheight - STATUS_HEIGHT;
@@ -1074,9 +1119,10 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
new_size = wmh1;
}
- /* if it doesn't fit in the current window, need win_equal() */
- if (oldwin_height - new_size - STATUS_HEIGHT < p_wmh)
- do_equal = TRUE;
+ // if it doesn't fit in the current window, need win_equal()
+ if (oldwin_height - new_size - STATUS_HEIGHT < p_wmh) {
+ do_equal = true;
+ }
/* We don't like to take lines for the new window from a
* 'winfixheight' window. Take them from a window above or below
@@ -1088,10 +1134,11 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
did_set_fraction = true;
win_setheight_win(oldwin->w_height + new_size + STATUS_HEIGHT,
- oldwin);
+ oldwin);
oldwin_height = oldwin->w_height;
- if (need_status)
+ if (need_status) {
oldwin_height -= STATUS_HEIGHT;
+ }
}
/* Only make all windows the same height if one of them (except oldwin)
@@ -1105,7 +1152,7 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
&& (frp->fr_win->w_height > new_size
|| frp->fr_win->w_height > oldwin_height - new_size
- STATUS_HEIGHT)) {
- do_equal = TRUE;
+ do_equal = true;
break;
}
frp = frp->fr_next;
@@ -1120,28 +1167,29 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
&& ((flags & WSP_BOT)
|| (flags & WSP_BELOW)
|| (!(flags & WSP_ABOVE)
- && (
- (flags & WSP_VERT) ? p_spr :
- p_sb)))) {
- /* new window below/right of current one */
- if (new_wp == NULL)
- wp = win_alloc(oldwin, FALSE);
- else
+ && ((flags & WSP_VERT) ? p_spr : p_sb)))) {
+ // new window below/right of current one
+ if (new_wp == NULL) {
+ wp = win_alloc(oldwin, false);
+ } else {
win_append(oldwin, wp);
+ }
} else {
- if (new_wp == NULL)
- wp = win_alloc(oldwin->w_prev, FALSE);
- else
+ if (new_wp == NULL) {
+ wp = win_alloc(oldwin->w_prev, false);
+ } else {
win_append(oldwin->w_prev, wp);
+ }
}
if (new_wp == NULL) {
- if (wp == NULL)
+ if (wp == NULL) {
return FAIL;
+ }
new_frame(wp);
- /* make the contents of the new window the same as the current one */
+ // make the contents of the new window the same as the current one
win_init(wp, curwin, flags);
} else if (wp->w_floating) {
new_frame(wp);
@@ -1157,25 +1205,29 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
if ((topframe->fr_layout == FR_COL && (flags & WSP_VERT) == 0)
|| (topframe->fr_layout == FR_ROW && (flags & WSP_VERT) != 0)) {
curfrp = topframe->fr_child;
- if (flags & WSP_BOT)
- while (curfrp->fr_next != NULL)
+ if (flags & WSP_BOT) {
+ while (curfrp->fr_next != NULL) {
curfrp = curfrp->fr_next;
- } else
+ }
+ }
+ } else {
curfrp = topframe;
+ }
before = (flags & WSP_TOP);
} else {
curfrp = oldwin->w_frame;
- if (flags & WSP_BELOW)
+ if (flags & WSP_BELOW) {
before = FALSE;
- else if (flags & WSP_ABOVE)
+ } else if (flags & WSP_ABOVE) {
before = TRUE;
- else if (flags & WSP_VERT)
+ } else if (flags & WSP_VERT) {
before = !p_spr;
- else
+ } else {
before = !p_sb;
+ }
}
if (curfrp->fr_parent == NULL || curfrp->fr_parent->fr_layout != layout) {
- /* Need to create a new frame in the tree to make a branch. */
+ // Need to create a new frame in the tree to make a branch.
frp = xcalloc(1, sizeof(frame_T));
*frp = *curfrp;
curfrp->fr_layout = layout;
@@ -1194,17 +1246,19 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
}
}
- if (new_wp == NULL)
+ if (new_wp == NULL) {
frp = wp->w_frame;
- else
+ } else {
frp = new_wp->w_frame;
+ }
frp->fr_parent = curfrp->fr_parent;
- /* Insert the new frame at the right place in the frame list. */
- if (before)
+ // Insert the new frame at the right place in the frame list.
+ if (before) {
frame_insert(curfrp, frp);
- else
+ } else {
frame_append(curfrp, frp);
+ }
/* Set w_fraction now so that the cursor keeps the same relative
* vertical position. */
@@ -1221,12 +1275,12 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
oldwin->w_status_height = need_status;
}
if (flags & (WSP_TOP | WSP_BOT)) {
- /* set height and row of new window to full height */
+ // set height and row of new window to full height
wp->w_winrow = tabline_height();
win_new_height(wp, curfrp->fr_height - (p_ls > 0));
wp->w_status_height = (p_ls > 0);
} else {
- /* height and row of new window is same as current window */
+ // height and row of new window is same as current window
wp->w_winrow = oldwin->w_winrow;
win_new_height(wp, oldwin->w_height);
wp->w_status_height = oldwin->w_status_height;
@@ -1236,30 +1290,33 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
/* "new_size" of the current window goes to the new window, use
* one column for the vertical separator */
win_new_width(wp, new_size);
- if (before)
+ if (before) {
wp->w_vsep_width = 1;
- else {
+ } else {
wp->w_vsep_width = oldwin->w_vsep_width;
oldwin->w_vsep_width = 1;
}
if (flags & (WSP_TOP | WSP_BOT)) {
- if (flags & WSP_BOT)
+ if (flags & WSP_BOT) {
frame_add_vsep(curfrp);
- /* Set width of neighbor frame */
+ }
+ // Set width of neighbor frame
frame_new_width(curfrp, curfrp->fr_width
- - (new_size + ((flags & WSP_TOP) != 0)), flags & WSP_TOP,
- FALSE);
- } else
+ - (new_size + ((flags & WSP_TOP) != 0)), flags & WSP_TOP,
+ false);
+ } else {
win_new_width(oldwin, oldwin->w_width - (new_size + 1));
- if (before) { /* new window left of current one */
+ }
+ if (before) { // new window left of current one
wp->w_wincol = oldwin->w_wincol;
oldwin->w_wincol += new_size + 1;
- } else /* new window right of current one */
+ } else { // new window right of current one
wp->w_wincol = oldwin->w_wincol + oldwin->w_width + 1;
+ }
frame_fix_width(oldwin);
frame_fix_width(wp);
} else {
- /* width and column of new window is same as current window */
+ // width and column of new window is same as current window
if (flags & (WSP_TOP | WSP_BOT)) {
wp->w_wincol = 0;
win_new_width(wp, Columns);
@@ -1295,14 +1352,16 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
oldwin->w_status_height = STATUS_HEIGHT;
}
}
- if (flags & WSP_BOT)
+ if (flags & WSP_BOT) {
frame_add_statusline(curfrp);
+ }
frame_fix_height(wp);
frame_fix_height(oldwin);
}
- if (flags & (WSP_TOP | WSP_BOT))
+ if (flags & (WSP_TOP | WSP_BOT)) {
(void)win_comp_pos();
+ }
// Both windows need redrawing. Update all status lines, in case they
// show something related to the window count or position.
@@ -1313,41 +1372,42 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
if (need_status) {
msg_row = Rows - 1;
msg_col = sc_col;
- msg_clr_eos_force(); /* Old command/ruler may still be there */
+ msg_clr_eos_force(); // Old command/ruler may still be there
comp_col();
msg_row = Rows - 1;
- msg_col = 0; /* put position back at start of line */
+ msg_col = 0; // put position back at start of line
}
/*
* equalize the window sizes.
*/
- if (do_equal || dir != 0)
+ if (do_equal || dir != 0) {
win_equal(wp, true,
- (flags & WSP_VERT) ? (dir == 'v' ? 'b' : 'h')
- : dir == 'h' ? 'b' :
- 'v');
+ (flags & WSP_VERT) ? (dir == 'v' ? 'b' : 'h')
+ : dir == 'h' ? 'b' :
+ 'v');
+ }
/* Don't change the window height/width to 'winheight' / 'winwidth' if a
* size was given. */
if (flags & WSP_VERT) {
i = p_wiw;
- if (size != 0)
+ if (size != 0) {
p_wiw = size;
-
+ }
} else {
i = p_wh;
- if (size != 0)
+ if (size != 0) {
p_wh = size;
+ }
}
// Keep same changelist position in new window.
wp->w_changelistidx = oldwin->w_changelistidx;
- /*
- * make the new window the current window
- */
- win_enter_ext(wp, false, false, true, true, true);
+ // make the new window the current window
+ win_enter_ext(wp, WEE_TRIGGER_NEW_AUTOCMDS | WEE_TRIGGER_ENTER_AUTOCMDS
+ | WEE_TRIGGER_LEAVE_AUTOCMDS);
if (flags & WSP_VERT) {
p_wiw = i;
} else {
@@ -1394,7 +1454,7 @@ static void win_init(win_T *newp, win_T *oldp, int flags)
newp->w_prev_fraction_row = oldp->w_prev_fraction_row;
copy_jumplist(oldp, newp);
if (flags & WSP_NEWLOC) {
- /* Don't copy the location list. */
+ // Don't copy the location list.
newp->w_llist = NULL;
newp->w_llist_ref = NULL;
} else {
@@ -1403,7 +1463,7 @@ static void win_init(win_T *newp, win_T *oldp, int flags)
newp->w_localdir = (oldp->w_localdir == NULL)
? NULL : vim_strsave(oldp->w_localdir);
- /* copy tagstack and folds */
+ // copy tagstack and folds
for (i = 0; i < oldp->w_tagstacklen; i++) {
taggy_T *tag = &newp->w_tagstack[i];
*tag = oldp->w_tagstack[i];
@@ -1429,16 +1489,16 @@ static void win_init(win_T *newp, win_T *oldp, int flags)
*/
static void win_init_some(win_T *newp, win_T *oldp)
{
- /* Use the same argument list. */
+ // Use the same argument list.
newp->w_alist = oldp->w_alist;
++newp->w_alist->al_refcount;
newp->w_arg_idx = oldp->w_arg_idx;
- /* copy options from existing window */
+ // copy options from existing window
win_copy_options(oldp, newp);
}
-/// Return TRUE if "win" is floating window in the current tab page.
+/// Return true if "win" is floating window in the current tab page.
///
/// @param win window to check
bool win_valid_floating(const win_T *win)
@@ -1516,17 +1576,14 @@ int win_count(void)
return count;
}
-/*
- * Make "count" windows on the screen.
- * Return actual number of windows on the screen.
- * Must be called when there is just one window, filling the whole screen
- * (excluding the command line).
- */
-int
-make_windows (
- int count,
- int vertical /* split windows vertically if TRUE */
-)
+/// Make "count" windows on the screen.
+/// Must be called when there is just one window, filling the whole screen
+/// (excluding the command line).
+///
+/// @param vertical split windows vertically if true
+///
+/// @return actual number of windows on the screen.
+int make_windows(int count, bool vertical)
{
int maxcount;
int todo;
@@ -1543,16 +1600,19 @@ make_windows (
- (p_wh - p_wmh)) / (p_wmh + STATUS_HEIGHT);
}
- if (maxcount < 2)
+ if (maxcount < 2) {
maxcount = 2;
- if (count > maxcount)
+ }
+ if (count > maxcount) {
count = maxcount;
+ }
/*
* add status line now, otherwise first window will be too big
*/
- if (count > 1)
- last_status(TRUE);
+ if (count > 1) {
+ last_status(true);
+ }
/*
* Don't execute autocommands while creating the windows. Must do that
@@ -1560,22 +1620,25 @@ make_windows (
*/
block_autocmds();
- /* todo is number of windows left to create */
- for (todo = count - 1; todo > 0; --todo)
+ // todo is number of windows left to create
+ for (todo = count - 1; todo > 0; --todo) {
if (vertical) {
if (win_split(curwin->w_width - (curwin->w_width - todo)
- / (todo + 1) - 1, WSP_VERT | WSP_ABOVE) == FAIL)
+ / (todo + 1) - 1, WSP_VERT | WSP_ABOVE) == FAIL) {
break;
+ }
} else {
if (win_split(curwin->w_height - (curwin->w_height - todo
* STATUS_HEIGHT) / (todo + 1)
- - STATUS_HEIGHT, WSP_ABOVE) == FAIL)
+ - STATUS_HEIGHT, WSP_ABOVE) == FAIL) {
break;
+ }
}
+ }
unblock_autocmds();
- /* return actual number of windows */
+ // return actual number of windows
return count - todo;
}
@@ -1584,10 +1647,10 @@ make_windows (
*/
static void win_exchange(long Prenum)
{
- frame_T *frp;
- frame_T *frp2;
- win_T *wp;
- win_T *wp2;
+ frame_T *frp;
+ frame_T *frp2;
+ win_T *wp;
+ win_T *wp2;
int temp;
if (curwin->w_floating) {
@@ -1607,17 +1670,20 @@ static void win_exchange(long Prenum)
*/
if (Prenum) {
frp = curwin->w_frame->fr_parent->fr_child;
- while (frp != NULL && --Prenum > 0)
+ while (frp != NULL && --Prenum > 0) {
frp = frp->fr_next;
- } else if (curwin->w_frame->fr_next != NULL) /* Swap with next */
+ }
+ } else if (curwin->w_frame->fr_next != NULL) { // Swap with next
frp = curwin->w_frame->fr_next;
- else /* Swap last window in row/col with previous */
+ } else { // Swap last window in row/col with previous
frp = curwin->w_frame->fr_prev;
+ }
/* We can only exchange a window with another window, not with a frame
* containing windows. */
- if (frp == NULL || frp->fr_win == NULL || frp->fr_win == curwin)
+ if (frp == NULL || frp->fr_win == NULL || frp->fr_win == curwin) {
return;
+ }
wp = frp->fr_win;
/*
@@ -1640,10 +1706,11 @@ static void win_exchange(long Prenum)
win_remove(wp, NULL);
frame_remove(wp->w_frame);
win_append(wp2, wp);
- if (frp2 == NULL)
+ if (frp2 == NULL) {
frame_insert(wp->w_frame->fr_parent->fr_child, wp->w_frame);
- else
+ } else {
frame_append(frp2, wp->w_frame);
+ }
}
temp = curwin->w_status_height;
curwin->w_status_height = wp->w_status_height;
@@ -1652,23 +1719,12 @@ static void win_exchange(long Prenum)
curwin->w_vsep_width = wp->w_vsep_width;
wp->w_vsep_width = temp;
- /* If the windows are not in the same frame, exchange the sizes to avoid
- * messing up the window layout. Otherwise fix the frame sizes. */
- if (curwin->w_frame->fr_parent != wp->w_frame->fr_parent) {
- temp = curwin->w_height;
- curwin->w_height = wp->w_height;
- wp->w_height = temp;
- temp = curwin->w_width;
- curwin->w_width = wp->w_width;
- wp->w_width = temp;
- } else {
- frame_fix_height(curwin);
- frame_fix_height(wp);
- frame_fix_width(curwin);
- frame_fix_width(wp);
- }
+ frame_fix_height(curwin);
+ frame_fix_height(wp);
+ frame_fix_width(curwin);
+ frame_fix_width(wp);
- (void)win_comp_pos(); /* recompute window positions */
+ (void)win_comp_pos(); // recompute window positions
win_enter(wp, true);
redraw_later(curwin, NOT_VALID);
@@ -1679,9 +1735,9 @@ static void win_exchange(long Prenum)
// if upwards false the first window becomes the second one
static void win_rotate(bool upwards, int count)
{
- win_T *wp1;
- win_T *wp2;
- frame_T *frp;
+ win_T *wp1;
+ win_T *wp2;
+ frame_T *frp;
int n;
if (curwin->w_floating) {
@@ -1704,8 +1760,8 @@ static void win_rotate(bool upwards, int count)
}
while (count--) {
- if (upwards) { /* first window becomes last window */
- /* remove first window/frame from the list */
+ if (upwards) { // first window becomes last window
+ // remove first window/frame from the list
frp = curwin->w_frame->fr_parent->fr_child;
assert(frp != NULL);
wp1 = frp->fr_win;
@@ -1713,30 +1769,32 @@ static void win_rotate(bool upwards, int count)
frame_remove(frp);
assert(frp->fr_parent->fr_child);
- /* find last frame and append removed window/frame after it */
- for (; frp->fr_next != NULL; frp = frp->fr_next)
+ // find last frame and append removed window/frame after it
+ for (; frp->fr_next != NULL; frp = frp->fr_next) {
;
+ }
win_append(frp->fr_win, wp1);
frame_append(frp, wp1->w_frame);
- wp2 = frp->fr_win; /* previously last window */
- } else { /* last window becomes first window */
- /* find last window/frame in the list and remove it */
+ wp2 = frp->fr_win; // previously last window
+ } else { // last window becomes first window
+ // find last window/frame in the list and remove it
for (frp = curwin->w_frame; frp->fr_next != NULL;
- frp = frp->fr_next)
+ frp = frp->fr_next) {
;
+ }
wp1 = frp->fr_win;
- wp2 = wp1->w_prev; /* will become last window */
+ wp2 = wp1->w_prev; // will become last window
win_remove(wp1, NULL);
frame_remove(frp);
assert(frp->fr_parent->fr_child);
- /* append the removed window/frame before the first in the list */
+ // append the removed window/frame before the first in the list
win_append(frp->fr_parent->fr_child->fr_win->w_prev, wp1);
frame_insert(frp->fr_parent->fr_child, frp);
}
- /* exchange status height and vsep width of old and new last window */
+ // exchange status height and vsep width of old and new last window
n = wp2->w_status_height;
wp2->w_status_height = wp1->w_status_height;
wp1->w_status_height = n;
@@ -1748,7 +1806,7 @@ static void win_rotate(bool upwards, int count)
frame_fix_width(wp1);
frame_fix_width(wp2);
- /* recompute w_winrow and w_wincol for all windows */
+ // recompute w_winrow and w_wincol for all windows
(void)win_comp_pos();
}
@@ -1785,17 +1843,17 @@ static void win_totop(int size, int flags)
(void)winframe_remove(curwin, &dir, NULL);
}
win_remove(curwin, NULL);
- last_status(FALSE); /* may need to remove last status line */
- (void)win_comp_pos(); /* recompute window positions */
+ last_status(false); // may need to remove last status line
+ (void)win_comp_pos(); // recompute window positions
- /* Split a window on the desired side and put the window there. */
+ // Split a window on the desired side and put the window there.
(void)win_split_ins(size, flags, curwin, dir);
if (!(flags & WSP_VERT)) {
win_setheight(height);
- if (p_ea)
+ if (p_ea) {
win_equal(curwin, true, 'v');
+ }
}
-
}
/*
@@ -1806,11 +1864,12 @@ void win_move_after(win_T *win1, win_T *win2)
{
int height;
- /* check if the arguments are reasonable */
- if (win1 == win2)
+ // check if the arguments are reasonable
+ if (win1 == win2) {
return;
+ }
- /* check if there is something to do */
+ // check if there is something to do
if (win2->w_next != win1) {
/* may need move the status line/vertical separator of the last window
* */
@@ -1853,58 +1912,54 @@ void win_move_after(win_T *win1, win_T *win2)
win2->w_pos_changed = true;
}
-/*
- * Make all windows the same height.
- * 'next_curwin' will soon be the current window, make sure it has enough
- * rows.
- */
-void win_equal(
- win_T *next_curwin, // pointer to current window to be or NULL
- bool current, // do only frame with current window
- int dir // 'v' for vertically, 'h' for horizontally,
- // 'b' for both, 0 for using p_ead
-)
-{
- if (dir == 0)
+/// Make all windows the same height.
+///'next_curwin' will soon be the current window, make sure it has enough rows.
+///
+/// @param next_curwin pointer to current window to be or NULL
+/// @param current do only frame with current window
+/// @param dir 'v' for vertically, 'h' for horizontally, 'b' for both, 0 for using p_ead
+void win_equal(win_T *next_curwin, bool current, int dir)
+{
+ if (dir == 0) {
dir = *p_ead;
+ }
win_equal_rec(next_curwin == NULL ? curwin : next_curwin, current,
topframe, dir, 0, tabline_height(),
Columns, topframe->fr_height);
}
-/*
- * Set a frame to a new position and height, spreading the available room
- * equally over contained frames.
- * The window "next_curwin" (if not NULL) should at least get the size from
- * 'winheight' and 'winwidth' if possible.
- */
-static void win_equal_rec(
- win_T *next_curwin, /* pointer to current window to be or NULL */
- bool current, /* do only frame with current window */
- frame_T *topfr, /* frame to set size off */
- int dir, /* 'v', 'h' or 'b', see win_equal() */
- int col, /* horizontal position for frame */
- int row, /* vertical position for frame */
- int width, /* new width of frame */
- int height /* new height of frame */
-)
+/// Set a frame to a new position and height, spreading the available room
+/// equally over contained frames.
+/// The window "next_curwin" (if not NULL) should at least get the size from
+/// 'winheight' and 'winwidth' if possible.
+///
+/// @param next_curwin pointer to current window to be or NULL
+/// @param current do only frame with current window
+/// @param topfr frame to set size off
+/// @param dir 'v', 'h' or 'b', see win_equal()
+/// @param col horizontal position for frame
+/// @param row vertical position for frame
+/// @param width new width of frame
+/// @param height new height of frame
+static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int dir, int col,
+ int row, int width, int height)
{
int n, m;
int extra_sep = 0;
int wincount, totwincount = 0;
- frame_T *fr;
+ frame_T *fr;
int next_curwin_size = 0;
int room = 0;
int new_size;
int has_next_curwin = 0;
- int hnc;
+ bool hnc;
if (topfr->fr_layout == FR_LEAF) {
/* Set the width/height of this frame.
* Redraw when size or position changes */
if (topfr->fr_height != height || topfr->fr_win->w_winrow != row
- || topfr->fr_width != width || topfr->fr_win->w_wincol != col
- ) {
+ || topfr->fr_width != width ||
+ topfr->fr_win->w_wincol != col) {
topfr->fr_win->w_winrow = row;
frame_new_height(topfr, height, false, false);
topfr->fr_win->w_wincol = col;
@@ -1915,15 +1970,16 @@ static void win_equal_rec(
topfr->fr_width = width;
topfr->fr_height = height;
- if (dir != 'v') { /* equalize frame widths */
+ if (dir != 'v') { // equalize frame widths
/* Compute the maximum number of windows horizontally in this
* frame. */
n = frame_minwidth(topfr, NOWIN);
- /* add one for the rightmost window, it doesn't have a separator */
- if (col + width == Columns)
+ // add one for the rightmost window, it doesn't have a separator
+ if (col + width == Columns) {
extra_sep = 1;
- else
+ } else {
extra_sep = 0;
+ }
totwincount = (n + extra_sep) / (p_wmw + 1);
has_next_curwin = frame_has_win(topfr, next_curwin);
@@ -1951,12 +2007,14 @@ static void win_equal_rec(
if (frame_has_win(fr, next_curwin)) {
room += p_wiw - p_wmw;
next_curwin_size = 0;
- if (new_size < p_wiw)
+ if (new_size < p_wiw) {
new_size = p_wiw;
- } else
- /* These windows don't use up room. */
+ }
+ } else {
+ // These windows don't use up room.
totwincount -= (n + (fr->fr_next == NULL
? extra_sep : 0)) / (p_wmw + 1);
+ }
room -= new_size - n;
if (room < 0) {
new_size += room;
@@ -1965,58 +2023,64 @@ static void win_equal_rec(
fr->fr_newwidth = new_size;
}
if (next_curwin_size == -1) {
- if (!has_next_curwin)
+ if (!has_next_curwin) {
next_curwin_size = 0;
- else if (totwincount > 1
- && (room + (totwincount - 2))
- / (totwincount - 1) > p_wiw) {
+ } else if (totwincount > 1
+ && (room + (totwincount - 2))
+ / (totwincount - 1) > p_wiw) {
/* Can make all windows wider than 'winwidth', spread
* the room equally. */
next_curwin_size = (room + p_wiw
+ (totwincount - 1) * p_wmw
+ (totwincount - 1)) / totwincount;
room -= next_curwin_size - p_wiw;
- } else
+ } else {
next_curwin_size = p_wiw;
+ }
}
}
- if (has_next_curwin)
- --totwincount; /* don't count curwin */
+ if (has_next_curwin) {
+ --totwincount; // don't count curwin
+ }
}
FOR_ALL_FRAMES(fr, topfr->fr_child) {
wincount = 1;
- if (fr->fr_next == NULL)
- /* last frame gets all that remains (avoid roundoff error) */
+ if (fr->fr_next == NULL) {
+ // last frame gets all that remains (avoid roundoff error)
new_size = width;
- else if (dir == 'v')
+ } else if (dir == 'v') {
new_size = fr->fr_width;
- else if (frame_fixed_width(fr)) {
+ } else if (frame_fixed_width(fr)) {
new_size = fr->fr_newwidth;
- wincount = 0; /* doesn't count as a sizeable window */
+ wincount = 0; // doesn't count as a sizeable window
} else {
- /* Compute the maximum number of windows horiz. in "fr". */
+ // Compute the maximum number of windows horiz. in "fr".
n = frame_minwidth(fr, NOWIN);
wincount = (n + (fr->fr_next == NULL ? extra_sep : 0))
/ (p_wmw + 1);
m = frame_minwidth(fr, next_curwin);
- if (has_next_curwin)
+ if (has_next_curwin) {
hnc = frame_has_win(fr, next_curwin);
- else
- hnc = FALSE;
- if (hnc) /* don't count next_curwin */
- --wincount;
- if (totwincount == 0)
+ } else {
+ hnc = false;
+ }
+ if (hnc) { // don't count next_curwin
+ wincount--;
+ }
+ if (totwincount == 0) {
new_size = room;
- else
+ } else {
new_size = (wincount * room + (totwincount / 2)) / totwincount;
- if (hnc) { /* add next_curwin size */
+ }
+ if (hnc) { // add next_curwin size
next_curwin_size -= p_wiw - (m - n);
new_size += next_curwin_size;
room -= new_size - next_curwin_size;
- } else
+ } else {
room -= new_size;
+ }
new_size += n;
}
@@ -2024,25 +2088,27 @@ static void win_equal_rec(
* window, unless equalizing all frames. */
if (!current || dir != 'v' || topfr->fr_parent != NULL
|| (new_size != fr->fr_width)
- || frame_has_win(fr, next_curwin))
+ || frame_has_win(fr, next_curwin)) {
win_equal_rec(next_curwin, current, fr, dir, col, row,
- new_size, height);
+ new_size, height);
+ }
col += new_size;
width -= new_size;
totwincount -= wincount;
}
- } else { /* topfr->fr_layout == FR_COL */
+ } else { // topfr->fr_layout == FR_COL
topfr->fr_width = width;
topfr->fr_height = height;
- if (dir != 'h') { /* equalize frame heights */
- /* Compute maximum number of windows vertically in this frame. */
+ if (dir != 'h') { // equalize frame heights
+ // Compute maximum number of windows vertically in this frame.
n = frame_minheight(topfr, NOWIN);
- /* add one for the bottom window if it doesn't have a statusline */
- if (row + height == cmdline_row && p_ls == 0)
+ // add one for the bottom window if it doesn't have a statusline
+ if (row + height == cmdline_row && p_ls == 0) {
extra_sep = 1;
- else
+ } else {
extra_sep = 0;
+ }
totwincount = (n + extra_sep) / (p_wmh + 1);
has_next_curwin = frame_has_win(topfr, next_curwin);
@@ -2072,12 +2138,14 @@ static void win_equal_rec(
if (frame_has_win(fr, next_curwin)) {
room += p_wh - p_wmh;
next_curwin_size = 0;
- if (new_size < p_wh)
+ if (new_size < p_wh) {
new_size = p_wh;
- } else
- /* These windows don't use up room. */
+ }
+ } else {
+ // These windows don't use up room.
totwincount -= (n + (fr->fr_next == NULL
? extra_sep : 0)) / (p_wmh + 1);
+ }
room -= new_size - n;
if (room < 0) {
new_size += room;
@@ -2086,67 +2154,74 @@ static void win_equal_rec(
fr->fr_newheight = new_size;
}
if (next_curwin_size == -1) {
- if (!has_next_curwin)
+ if (!has_next_curwin) {
next_curwin_size = 0;
- else if (totwincount > 1
- && (room + (totwincount - 2))
- / (totwincount - 1) > p_wh) {
+ } else if (totwincount > 1
+ && (room + (totwincount - 2))
+ / (totwincount - 1) > p_wh) {
/* can make all windows higher than 'winheight',
* spread the room equally. */
next_curwin_size = (room + p_wh
+ (totwincount - 1) * p_wmh
+ (totwincount - 1)) / totwincount;
room -= next_curwin_size - p_wh;
- } else
+ } else {
next_curwin_size = p_wh;
+ }
}
}
- if (has_next_curwin)
- --totwincount; /* don't count curwin */
+ if (has_next_curwin) {
+ --totwincount; // don't count curwin
+ }
}
FOR_ALL_FRAMES(fr, topfr->fr_child) {
wincount = 1;
- if (fr->fr_next == NULL)
- /* last frame gets all that remains (avoid roundoff error) */
+ if (fr->fr_next == NULL) {
+ // last frame gets all that remains (avoid roundoff error)
new_size = height;
- else if (dir == 'h')
+ } else if (dir == 'h') {
new_size = fr->fr_height;
- else if (frame_fixed_height(fr)) {
+ } else if (frame_fixed_height(fr)) {
new_size = fr->fr_newheight;
- wincount = 0; /* doesn't count as a sizeable window */
+ wincount = 0; // doesn't count as a sizeable window
} else {
- /* Compute the maximum number of windows vert. in "fr". */
+ // Compute the maximum number of windows vert. in "fr".
n = frame_minheight(fr, NOWIN);
wincount = (n + (fr->fr_next == NULL ? extra_sep : 0))
/ (p_wmh + 1);
m = frame_minheight(fr, next_curwin);
- if (has_next_curwin)
+ if (has_next_curwin) {
hnc = frame_has_win(fr, next_curwin);
- else
- hnc = FALSE;
- if (hnc) /* don't count next_curwin */
- --wincount;
- if (totwincount == 0)
+ } else {
+ hnc = false;
+ }
+ if (hnc) { // don't count next_curwin
+ wincount--;
+ }
+ if (totwincount == 0) {
new_size = room;
- else
+ } else {
new_size = (wincount * room + (totwincount / 2)) / totwincount;
- if (hnc) { /* add next_curwin size */
+ }
+ if (hnc) { // add next_curwin size
next_curwin_size -= p_wh - (m - n);
new_size += next_curwin_size;
room -= new_size - next_curwin_size;
- } else
+ } else {
room -= new_size;
+ }
new_size += n;
}
/* Skip frame that is full width when splitting or closing a
* window, unless equalizing all frames. */
if (!current || dir != 'h' || topfr->fr_parent != NULL
|| (new_size != fr->fr_height)
- || frame_has_win(fr, next_curwin))
+ || frame_has_win(fr, next_curwin)) {
win_equal_rec(next_curwin, current, fr, dir, col, row,
- width, new_size);
+ width, new_size);
+ }
row += new_size;
height -= new_size;
totwincount -= wincount;
@@ -2159,7 +2234,7 @@ static void win_equal_rec(
/// @param keep_curwin don't close `curwin`
void close_windows(buf_T *buf, int keep_curwin)
{
- tabpage_T *tp, *nexttp;
+ tabpage_T *tp, *nexttp;
int h = tabline_height();
++RedrawingDisabled;
@@ -2172,13 +2247,14 @@ void close_windows(buf_T *buf, int keep_curwin)
break;
}
- /* Start all over, autocommands may change the window layout. */
+ // Start all over, autocommands may change the window layout.
wp = firstwin;
- } else
+ } else {
wp = wp->w_next;
+ }
}
- /* Also check windows in other tab pages. */
+ // Also check windows in other tab pages.
for (tp = first_tabpage; tp != NULL; tp = nexttp) {
nexttp = tp->tp_next;
if (tp != curtab) {
@@ -2252,14 +2328,13 @@ bool last_nonfloat(win_T *wp) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
/// last window in the tabpage
///
/// @return true when the window was closed already.
-static bool close_last_window_tabpage(win_T *win, bool free_buf,
- tabpage_T *prev_curtab)
+static bool close_last_window_tabpage(win_T *win, bool free_buf, tabpage_T *prev_curtab)
FUNC_ATTR_NONNULL_ARG(1)
{
if (!ONE_WINDOW) {
return false;
}
- buf_T *old_curbuf = curbuf;
+ buf_T *old_curbuf = curbuf;
Terminal *term = win->w_buffer ? win->w_buffer->terminal : NULL;
if (term) {
@@ -2275,8 +2350,8 @@ static bool close_last_window_tabpage(win_T *win, bool free_buf,
* Don't trigger autocommands yet, they may use wrong values, so do
* that below.
*/
- goto_tabpage_tp(alt_tabpage(), FALSE, TRUE);
- redraw_tabline = TRUE;
+ goto_tabpage_tp(alt_tabpage(), false, true);
+ redraw_tabline = true;
// save index for tabclosed event
char_u prev_idx[NUMBUFLEN];
@@ -2288,8 +2363,9 @@ static bool close_last_window_tabpage(win_T *win, bool free_buf,
int h = tabline_height();
win_close_othertab(win, free_buf, prev_curtab);
- if (h != tabline_height())
+ if (h != tabline_height()) {
shell_new_rows();
+ }
}
// Since goto_tabpage_tp above did not trigger *Enter autocommands, do
@@ -2309,12 +2385,12 @@ static bool close_last_window_tabpage(win_T *win, bool free_buf,
// Returns FAIL when the window was not closed.
int win_close(win_T *win, bool free_buf)
{
- win_T *wp;
- int other_buffer = FALSE;
- int close_curwin = FALSE;
+ win_T *wp;
+ bool other_buffer = false;
+ bool close_curwin = false;
int dir;
bool help_window = false;
- tabpage_T *prev_curtab = curtab;
+ tabpage_T *prev_curtab = curtab;
frame_T *win_frame = win->w_floating ? NULL : win->w_frame->fr_parent;
const bool had_diffmode = win->w_p_diff;
@@ -2345,8 +2421,9 @@ int win_close(win_T *win, bool free_buf)
/* When closing the last window in a tab page first go to another tab page
* and then close the window and the tab page to avoid that curwin and
* curtab are invalid while we are freeing memory. */
- if (close_last_window_tabpage(win, free_buf, prev_curtab))
+ if (close_last_window_tabpage(win, free_buf, prev_curtab)) {
return FAIL;
+ }
/* When closing the help window, try restoring a snapshot after closing
* the window. Otherwise clear the snapshot, it's now invalid. */
@@ -2376,14 +2453,16 @@ int win_close(win_T *win, bool free_buf)
* to be the last one left, return now.
*/
if (wp->w_buffer != curbuf) {
- other_buffer = TRUE;
+ other_buffer = true;
win->w_closing = true;
- apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf);
- if (!win_valid(win))
+ apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, false, curbuf);
+ if (!win_valid(win)) {
return FAIL;
+ }
win->w_closing = false;
- if (last_window())
+ if (last_window()) {
return FAIL;
+ }
}
win->w_closing = true;
apply_autocmds(EVENT_WINLEAVE, NULL, NULL, false, curbuf);
@@ -2391,11 +2470,13 @@ int win_close(win_T *win, bool free_buf)
return FAIL;
}
win->w_closing = false;
- if (last_window())
+ if (last_window()) {
return FAIL;
- /* autocmds may abort script processing */
- if (aborting())
+ }
+ // autocmds may abort script processing
+ if (aborting()) {
return FAIL;
+ }
}
bool was_floating = win->w_floating;
@@ -2502,12 +2583,14 @@ int win_close(win_T *win, bool free_buf)
* finding another window to go to.
*/
for (;; ) {
- if (wp->w_next == NULL)
+ if (wp->w_next == NULL) {
wp = firstwin;
- else
+ } else {
wp = wp->w_next;
- if (wp == curwin)
+ }
+ if (wp == curwin) {
break;
+ }
if (!wp->w_p_pvw && !bt_quickfix(wp->w_buffer)) {
curwin = wp;
break;
@@ -2515,7 +2598,7 @@ int win_close(win_T *win, bool free_buf)
}
}
curbuf = curwin->w_buffer;
- close_curwin = TRUE;
+ close_curwin = true;
// The cursor position may be invalid if the buffer changed after last
// using the window.
@@ -2533,7 +2616,8 @@ int win_close(win_T *win, bool free_buf)
}
if (close_curwin) {
- win_enter_ext(wp, false, true, false, true, true);
+ win_enter_ext(wp, WEE_CURWIN_INVALID | WEE_TRIGGER_ENTER_AUTOCMDS
+ | WEE_TRIGGER_LEAVE_AUTOCMDS);
if (other_buffer) {
// careful: after this wp and win may be invalid!
apply_autocmds(EVENT_BUFENTER, NULL, NULL, false, curbuf);
@@ -2544,12 +2628,13 @@ int win_close(win_T *win, bool free_buf)
* If last window has a status line now and we don't want one,
* remove the status line.
*/
- last_status(FALSE);
+ last_status(false);
/* After closing the help window, try restoring the window layout from
* before it was opened. */
- if (help_window)
+ if (help_window) {
restore_snapshot(SNAP_HELP_IDX, close_curwin);
+ }
// If the window had 'diff' set and now there is only one window left in
// the tab page with 'diff' set, and "closeoff" is in 'diffopt', then
@@ -2596,8 +2681,8 @@ static void do_autocmd_winclosed(win_T *win)
void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp)
{
int dir;
- tabpage_T *ptp = NULL;
- int free_tp = FALSE;
+ tabpage_T *ptp = NULL;
+ bool free_tp = false;
// Get here with win->w_buffer == NULL when win_close() detects the tab page
// changed.
@@ -2620,26 +2705,28 @@ void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp)
/* Careful: Autocommands may have closed the tab page or made it the
* current tab page. */
- for (ptp = first_tabpage; ptp != NULL && ptp != tp; ptp = ptp->tp_next)
+ for (ptp = first_tabpage; ptp != NULL && ptp != tp; ptp = ptp->tp_next) {
;
- if (ptp == NULL || tp == curtab)
+ }
+ if (ptp == NULL || tp == curtab) {
return;
+ }
- /* Autocommands may have closed the window already. */
+ // Autocommands may have closed the window already.
{
bool found_window = false;
FOR_ALL_WINDOWS_IN_TAB(wp, tp) {
if (wp == win) {
- found_window = true;
- break;
+ found_window = true;
+ break;
}
}
if (!found_window) {
- return;
+ return;
}
}
- /* When closing the last window in a tab page remove the tab page. */
+ // When closing the last window in a tab page remove the tab page.
if (tp->tp_firstwin == tp->tp_lastwin) {
char_u prev_idx[NUMBUFLEN];
if (has_event(EVENT_TABCLOSED)) {
@@ -2666,23 +2753,24 @@ void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp)
}
}
- /* Free the memory used for the window. */
+ // Free the memory used for the window.
win_free_mem(win, &dir, tp);
- if (free_tp)
+ if (free_tp) {
free_tabpage(tp);
+ }
}
-// Free the memory used for a window.
-// Returns a pointer to the window that got the freed up space.
-static win_T *win_free_mem(
- win_T *win,
- int *dirp, // set to 'v' or 'h' for direction if 'ea'
- tabpage_T *tp // tab page "win" is in, NULL for current
-)
+/// Free the memory used for a window.
+///
+/// @param dirp set to 'v' or 'h' for direction if 'ea'
+/// @param tp tab page "win" is in, NULL for current
+///
+/// @return a pointer to the window that got the freed up space.
+static win_T *win_free_mem(win_T *win, int *dirp, tabpage_T *tp)
{
- frame_T *frp;
- win_T *wp;
+ frame_T *frp;
+ win_T *wp;
if (!win->w_floating) {
// Remove the window and its frame from the tree of frames.
@@ -2702,7 +2790,11 @@ static win_T *win_free_mem(
// When deleting the current window of another tab page select a new
// current window.
if (tp != NULL && win == tp->tp_curwin) {
- tp->tp_curwin = wp;
+ if (win_valid(tp->tp_prevwin) && tp->tp_prevwin != win) {
+ tp->tp_curwin = tp->tp_prevwin;
+ } else {
+ tp->tp_curwin = tp->tp_firstwin;
+ }
}
return wp;
@@ -2713,8 +2805,9 @@ void win_free_all(void)
{
int dummy;
- while (first_tabpage->tp_next != NULL)
+ while (first_tabpage->tp_next != NULL) {
tabpage_close(TRUE);
+ }
while (lastwin != NULL && lastwin->w_floating) {
win_T *wp = lastwin;
@@ -2730,8 +2823,9 @@ void win_free_all(void)
aucmd_win = NULL;
}
- while (firstwin != NULL)
+ while (firstwin != NULL) {
(void)win_free_mem(firstwin, &dummy, NULL);
+ }
// No window should be used after this. Set curwin to NULL to crash
// instead of using freed memory.
@@ -2740,26 +2834,24 @@ void win_free_all(void)
#endif
-/*
- * Remove a window and its frame from the tree of frames.
- * Returns a pointer to the window that got the freed up space.
- */
-win_T *
-winframe_remove (
- win_T *win,
- int *dirp, /* set to 'v' or 'h' for direction if 'ea' */
- tabpage_T *tp /* tab page "win" is in, NULL for current */
-)
+/// Remove a window and its frame from the tree of frames.
+///
+/// @param dirp set to 'v' or 'h' for direction if 'ea'
+/// @param tp tab page "win" is in, NULL for current
+///
+/// @return a pointer to the window that got the freed up space.
+win_T *winframe_remove(win_T *win, int *dirp, tabpage_T *tp)
{
- frame_T *frp, *frp2, *frp3;
- frame_T *frp_close = win->w_frame;
- win_T *wp;
+ frame_T *frp, *frp2, *frp3;
+ frame_T *frp_close = win->w_frame;
+ win_T *wp;
/*
* If there is only one window there is nothing to remove.
*/
- if (tp == NULL ? ONE_WINDOW : tp->tp_firstwin == tp->tp_lastwin)
+ if (tp == NULL ? ONE_WINDOW : tp->tp_firstwin == tp->tp_lastwin) {
return NULL;
+ }
/*
* Remove the window from its frame.
@@ -2767,7 +2859,7 @@ winframe_remove (
frp2 = win_altframe(win, tp);
wp = frame2win(frp2);
- /* Remove this frame from the list of frames. */
+ // Remove this frame from the list of frames.
frame_remove(frp_close);
if (frp_close->fr_parent->fr_layout == FR_COL) {
@@ -2797,7 +2889,7 @@ winframe_remove (
}
}
frame_new_height(frp2, frp2->fr_height + frp_close->fr_height,
- frp2 == frp_close->fr_next ? TRUE : FALSE, FALSE);
+ frp2 == frp_close->fr_next, false);
*dirp = 'v';
} else {
/* When 'winfixwidth' is set, try to find another frame in the column
@@ -2826,7 +2918,7 @@ winframe_remove (
}
}
frame_new_width(frp2, frp2->fr_width + frp_close->fr_width,
- frp2 == frp_close->fr_next ? TRUE : FALSE, FALSE);
+ frp2 == frp_close->fr_next, false);
*dirp = 'h';
}
@@ -2848,8 +2940,9 @@ winframe_remove (
frp->fr_parent = frp2->fr_parent;
}
frp2->fr_parent->fr_win = frp2->fr_win;
- if (frp2->fr_win != NULL)
+ if (frp2->fr_win != NULL) {
frp2->fr_win->w_frame = frp2->fr_parent;
+ }
frp = frp2->fr_parent;
if (topframe->fr_child == frp2) {
topframe->fr_child = frp;
@@ -2860,18 +2953,21 @@ winframe_remove (
if (frp2 != NULL && frp2->fr_layout == frp->fr_layout) {
/* The frame above the parent has the same layout, have to merge
* the frames into this list. */
- if (frp2->fr_child == frp)
+ if (frp2->fr_child == frp) {
frp2->fr_child = frp->fr_child;
+ }
assert(frp->fr_child);
frp->fr_child->fr_prev = frp->fr_prev;
- if (frp->fr_prev != NULL)
+ if (frp->fr_prev != NULL) {
frp->fr_prev->fr_next = frp->fr_child;
+ }
for (frp3 = frp->fr_child;; frp3 = frp3->fr_next) {
frp3->fr_parent = frp2;
if (frp3->fr_next == NULL) {
frp3->fr_next = frp->fr_next;
- if (frp->fr_next != NULL)
+ if (frp->fr_next != NULL) {
frp->fr_next->fr_prev = frp3;
+ }
break;
}
}
@@ -2885,21 +2981,19 @@ winframe_remove (
return wp;
}
-// Return a pointer to the frame that will receive the empty screen space that
-// is left over after "win" is closed.
-//
-// If 'splitbelow' or 'splitright' is set, the space goes above or to the left
-// by default. Otherwise, the free space goes below or to the right. The
-// result is that opening a window and then immediately closing it will
-// preserve the initial window layout. The 'wfh' and 'wfw' settings are
-// respected when possible.
-static frame_T *
-win_altframe (
- win_T *win,
- tabpage_T *tp /* tab page "win" is in, NULL for current */
-)
-{
- frame_T *frp;
+/// If 'splitbelow' or 'splitright' is set, the space goes above or to the left
+/// by default. Otherwise, the free space goes below or to the right. The
+/// result is that opening a window and then immediately closing it will
+/// preserve the initial window layout. The 'wfh' and 'wfw' settings are
+/// respected when possible.
+///
+/// @param tp tab page "win" is in, NULL for current
+///
+/// @return a pointer to the frame that will receive the empty screen space that
+/// is left over after "win" is closed.
+static frame_T *win_altframe(win_T *win, tabpage_T *tp)
+{
+ frame_T *frp;
if (tp == NULL ? ONE_WINDOW : tp->tp_firstwin == tp->tp_lastwin) {
return alt_tabpage()->tp_curwin->w_frame;
@@ -2941,15 +3035,17 @@ win_altframe (
*/
static tabpage_T *alt_tabpage(void)
{
- tabpage_T *tp;
+ tabpage_T *tp;
- /* Use the next tab page if possible. */
- if (curtab->tp_next != NULL)
+ // Use the next tab page if possible.
+ if (curtab->tp_next != NULL) {
return curtab->tp_next;
+ }
- /* Find the last but one tab page. */
- for (tp = first_tabpage; tp->tp_next != curtab; tp = tp->tp_next)
+ // Find the last but one tab page.
+ for (tp = first_tabpage; tp->tp_next != curtab; tp = tp->tp_next) {
;
+ }
return tp;
}
@@ -2958,8 +3054,9 @@ static tabpage_T *alt_tabpage(void)
*/
static win_T *frame2win(frame_T *frp)
{
- while (frp->fr_win == NULL)
+ while (frp->fr_win == NULL) {
frp = frp->fr_child;
+ }
return frp->fr_win;
}
@@ -2982,21 +3079,16 @@ static bool frame_has_win(const frame_T *frp, const win_T *wp)
return false;
}
-/*
- * Set a new height for a frame. Recursively sets the height for contained
- * frames and windows. Caller must take care of positions.
- */
-static void
-frame_new_height (
- frame_T *topfrp,
- int height,
- int topfirst, /* resize topmost contained frame first */
- int wfh /* obey 'winfixheight' when there is a choice;
- may cause the height not to be set */
-)
+/// Set a new height for a frame. Recursively sets the height for contained
+/// frames and windows. Caller must take care of positions.
+///
+/// @param topfirst resize topmost contained frame first.
+/// @param wfh obey 'winfixheight' when there is a choice;
+/// may cause the height not to be set.
+static void frame_new_height(frame_T *topfrp, int height, bool topfirst, bool wfh)
FUNC_ATTR_NONNULL_ALL
{
- frame_T *frp;
+ frame_T *frp;
int extra_lines;
int h;
@@ -3010,37 +3102,42 @@ frame_new_height (
FOR_ALL_FRAMES(frp, topfrp->fr_child) {
frame_new_height(frp, height, topfirst, wfh);
if (frp->fr_height > height) {
- /* Could not fit the windows, make the whole row higher. */
+ // Could not fit the windows, make the whole row higher.
height = frp->fr_height;
break;
}
}
} while (frp != NULL);
- } else { /* fr_layout == FR_COL */
+ } else { // fr_layout == FR_COL
/* Complicated case: Resize a column of frames. Resize the bottom
* frame first, frames above that when needed. */
frp = topfrp->fr_child;
- if (wfh)
- /* Advance past frames with one window with 'wfh' set. */
+ if (wfh) {
+ // Advance past frames with one window with 'wfh' set.
while (frame_fixed_height(frp)) {
frp = frp->fr_next;
- if (frp == NULL)
- return; /* no frame without 'wfh', give up */
+ if (frp == NULL) {
+ return; // no frame without 'wfh', give up
+ }
}
+ }
if (!topfirst) {
- /* Find the bottom frame of this column */
- while (frp->fr_next != NULL)
+ // Find the bottom frame of this column
+ while (frp->fr_next != NULL) {
frp = frp->fr_next;
- if (wfh)
- /* Advance back for frames with one window with 'wfh' set. */
- while (frame_fixed_height(frp))
+ }
+ if (wfh) {
+ // Advance back for frames with one window with 'wfh' set.
+ while (frame_fixed_height(frp)) {
frp = frp->fr_prev;
+ }
+ }
}
extra_lines = height - topfrp->fr_height;
if (extra_lines < 0) {
- /* reduce height of contained frames, bottom or top frame first */
+ // reduce height of contained frames, bottom or top frame first
while (frp != NULL) {
h = frame_minheight(frp, NULL);
if (frp->fr_height + extra_lines < h) {
@@ -3048,7 +3145,7 @@ frame_new_height (
frame_new_height(frp, h, topfirst, wfh);
} else {
frame_new_height(frp, frp->fr_height + extra_lines,
- topfirst, wfh);
+ topfirst, wfh);
break;
}
if (topfirst) {
@@ -3060,12 +3157,13 @@ frame_new_height (
frp = frp->fr_prev;
while (wfh && frp != NULL && frame_fixed_height(frp));
}
- /* Increase "height" if we could not reduce enough frames. */
- if (frp == NULL)
+ // Increase "height" if we could not reduce enough frames.
+ if (frp == NULL) {
height -= extra_lines;
+ }
}
} else if (extra_lines > 0) {
- /* increase height of bottom or top frame */
+ // increase height of bottom or top frame
frame_new_height(frp, frp->fr_height + extra_lines, topfirst, wfh);
}
}
@@ -3146,13 +3244,14 @@ static bool frame_fixed_width(frame_T *frp)
*/
static void frame_add_statusline(frame_T *frp)
{
- win_T *wp;
+ win_T *wp;
if (frp->fr_layout == FR_LEAF) {
wp = frp->fr_win;
if (wp->w_status_height == 0) {
- if (wp->w_height > 0) /* don't make it negative */
+ if (wp->w_height > 0) { // don't make it negative
--wp->w_height;
+ }
wp->w_status_height = STATUS_HEIGHT;
}
} else if (frp->fr_layout == FR_ROW) {
@@ -3169,33 +3268,31 @@ static void frame_add_statusline(frame_T *frp)
}
}
-/*
- * Set width of a frame. Handles recursively going through contained frames.
- * May remove separator line for windows at the right side (for win_close()).
- */
-static void
-frame_new_width (
- frame_T *topfrp,
- int width,
- int leftfirst, /* resize leftmost contained frame first */
- int wfw /* obey 'winfixwidth' when there is a choice;
- may cause the width not to be set */
-)
-{
- frame_T *frp;
+/// Set width of a frame. Handles recursively going through contained frames.
+/// May remove separator line for windows at the right side (for win_close()).
+///
+/// @param leftfirst resize leftmost contained frame first.
+/// @param wfw obey 'winfixwidth' when there is a choice;
+/// may cause the width not to be set.
+static void frame_new_width(frame_T *topfrp, int width, bool leftfirst, bool wfw)
+{
+ frame_T *frp;
int extra_cols;
int w;
- win_T *wp;
+ win_T *wp;
if (topfrp->fr_layout == FR_LEAF) {
- /* Simple case: just one window. */
+ // Simple case: just one window.
wp = topfrp->fr_win;
- /* Find out if there are any windows right of this one. */
- for (frp = topfrp; frp->fr_parent != NULL; frp = frp->fr_parent)
- if (frp->fr_parent->fr_layout == FR_ROW && frp->fr_next != NULL)
+ // Find out if there are any windows right of this one.
+ for (frp = topfrp; frp->fr_parent != NULL; frp = frp->fr_parent) {
+ if (frp->fr_parent->fr_layout == FR_ROW && frp->fr_next != NULL) {
break;
- if (frp->fr_parent == NULL)
+ }
+ }
+ if (frp->fr_parent == NULL) {
wp->w_vsep_width = 0;
+ }
win_new_width(wp, width - wp->w_vsep_width);
} else if (topfrp->fr_layout == FR_COL) {
do {
@@ -3203,37 +3300,42 @@ frame_new_width (
FOR_ALL_FRAMES(frp, topfrp->fr_child) {
frame_new_width(frp, width, leftfirst, wfw);
if (frp->fr_width > width) {
- /* Could not fit the windows, make whole column wider. */
+ // Could not fit the windows, make whole column wider.
width = frp->fr_width;
break;
}
}
} while (frp != NULL);
- } else { /* fr_layout == FR_ROW */
+ } else { // fr_layout == FR_ROW
/* Complicated case: Resize a row of frames. Resize the rightmost
* frame first, frames left of it when needed. */
frp = topfrp->fr_child;
- if (wfw)
- /* Advance past frames with one window with 'wfw' set. */
+ if (wfw) {
+ // Advance past frames with one window with 'wfw' set.
while (frame_fixed_width(frp)) {
frp = frp->fr_next;
- if (frp == NULL)
- return; /* no frame without 'wfw', give up */
+ if (frp == NULL) {
+ return; // no frame without 'wfw', give up
+ }
}
+ }
if (!leftfirst) {
- /* Find the rightmost frame of this row */
- while (frp->fr_next != NULL)
+ // Find the rightmost frame of this row
+ while (frp->fr_next != NULL) {
frp = frp->fr_next;
- if (wfw)
- /* Advance back for frames with one window with 'wfw' set. */
- while (frame_fixed_width(frp))
+ }
+ if (wfw) {
+ // Advance back for frames with one window with 'wfw' set.
+ while (frame_fixed_width(frp)) {
frp = frp->fr_prev;
+ }
+ }
}
extra_cols = width - topfrp->fr_width;
if (extra_cols < 0) {
- /* reduce frame width, rightmost frame first */
+ // reduce frame width, rightmost frame first
while (frp != NULL) {
w = frame_minwidth(frp, NULL);
if (frp->fr_width + extra_cols < w) {
@@ -3241,7 +3343,7 @@ frame_new_width (
frame_new_width(frp, w, leftfirst, wfw);
} else {
frame_new_width(frp, frp->fr_width + extra_cols,
- leftfirst, wfw);
+ leftfirst, wfw);
break;
}
if (leftfirst) {
@@ -3253,12 +3355,13 @@ frame_new_width (
frp = frp->fr_prev;
while (wfw && frp != NULL && frame_fixed_width(frp));
}
- /* Increase "width" if we could not reduce enough frames. */
- if (frp == NULL)
+ // Increase "width" if we could not reduce enough frames.
+ if (frp == NULL) {
width -= extra_cols;
+ }
}
} else if (extra_cols > 0) {
- /* increase width of rightmost frame */
+ // increase width of rightmost frame
frame_new_width(frp, frp->fr_width + extra_cols, leftfirst, wfw);
}
}
@@ -3272,13 +3375,14 @@ frame_new_width (
static void frame_add_vsep(const frame_T *frp)
FUNC_ATTR_NONNULL_ARG(1)
{
- win_T *wp;
+ win_T *wp;
if (frp->fr_layout == FR_LEAF) {
wp = frp->fr_win;
if (wp->w_vsep_width == 0) {
- if (wp->w_width > 0) /* don't make it negative */
+ if (wp->w_width > 0) { // don't make it negative
--wp->w_width;
+ }
wp->w_vsep_width = 1;
}
} else if (frp->fr_layout == FR_COL) {
@@ -3290,8 +3394,9 @@ static void frame_add_vsep(const frame_T *frp)
assert(frp->fr_layout == FR_ROW);
// Only need to handle the last frame in the row.
frp = frp->fr_child;
- while (frp->fr_next != NULL)
+ while (frp->fr_next != NULL) {
frp = frp->fr_next;
+ }
frame_add_vsep(frp);
}
}
@@ -3322,7 +3427,7 @@ static void frame_fix_height(win_T *wp)
*/
static int frame_minheight(frame_T *topfrp, win_T *next_curwin)
{
- frame_T *frp;
+ frame_T *frp;
int m;
int n;
@@ -3340,15 +3445,16 @@ static int frame_minheight(frame_T *topfrp, win_T *next_curwin)
}
}
} else if (topfrp->fr_layout == FR_ROW) {
- /* get the minimal height from each frame in this row */
+ // get the minimal height from each frame in this row
m = 0;
FOR_ALL_FRAMES(frp, topfrp->fr_child) {
n = frame_minheight(frp, next_curwin);
- if (n > m)
+ if (n > m) {
m = n;
+ }
}
} else {
- /* Add up the minimal heights for all frames in this column. */
+ // Add up the minimal heights for all frames in this column.
m = 0;
FOR_ALL_FRAMES(frp, topfrp->fr_child) {
m += frame_minheight(frp, next_curwin);
@@ -3358,41 +3464,39 @@ static int frame_minheight(frame_T *topfrp, win_T *next_curwin)
return m;
}
-/*
- * Compute the minimal width for frame "topfrp".
- * When "next_curwin" isn't NULL, use p_wiw for this window.
- * When "next_curwin" is NOWIN, don't use at least one column for the current
- * window.
- */
-static int
-frame_minwidth (
- frame_T *topfrp,
- win_T *next_curwin /* use p_wh and p_wiw for next_curwin */
-)
+/// Compute the minimal width for frame "topfrp".
+/// When "next_curwin" isn't NULL, use p_wiw for this window.
+/// When "next_curwin" is NOWIN, don't use at least one column for the current
+/// window.
+///
+/// @param next_curwin use p_wh and p_wiw for next_curwin
+static int frame_minwidth(frame_T *topfrp, win_T *next_curwin)
{
- frame_T *frp;
+ frame_T *frp;
int m, n;
if (topfrp->fr_win != NULL) {
- if (topfrp->fr_win == next_curwin)
+ if (topfrp->fr_win == next_curwin) {
m = p_wiw + topfrp->fr_win->w_vsep_width;
- else {
- /* window: minimal width of the window plus separator column */
+ } else {
+ // window: minimal width of the window plus separator column
m = p_wmw + topfrp->fr_win->w_vsep_width;
- /* Current window is minimal one column wide */
- if (p_wmw == 0 && topfrp->fr_win == curwin && next_curwin == NULL)
+ // Current window is minimal one column wide
+ if (p_wmw == 0 && topfrp->fr_win == curwin && next_curwin == NULL) {
++m;
+ }
}
} else if (topfrp->fr_layout == FR_COL) {
- /* get the minimal width from each frame in this column */
+ // get the minimal width from each frame in this column
m = 0;
FOR_ALL_FRAMES(frp, topfrp->fr_child) {
n = frame_minwidth(frp, next_curwin);
- if (n > m)
+ if (n > m) {
m = n;
+ }
}
} else {
- /* Add up the minimal widths for all frames in this row. */
+ // Add up the minimal widths for all frames in this row.
m = 0;
FOR_ALL_FRAMES(frp, topfrp->fr_child) {
m += frame_minwidth(frp, next_curwin);
@@ -3403,21 +3507,17 @@ frame_minwidth (
}
-/*
- * Try to close all windows except current one.
- * Buffers in the other windows become hidden if 'hidden' is set, or '!' is
- * used and the buffer was modified.
- *
- * Used by ":bdel" and ":only".
- */
-void
-close_others (
- int message,
- int forceit /* always hide all other windows */
-)
-{
- win_T *wp;
- win_T *nextwp;
+/// Try to close all windows except current one.
+/// Buffers in the other windows become hidden if 'hidden' is set, or '!' is
+/// used and the buffer was modified.
+///
+/// Used by ":bdel" and ":only".
+///
+/// @param forceit always hide all other windows
+void close_others(int message, int forceit)
+{
+ win_T *wp;
+ win_T *nextwp;
int r;
if (curwin->w_floating) {
@@ -3429,23 +3529,22 @@ close_others (
if (one_window() && !lastwin->w_floating) {
if (message
- && !autocmd_busy
- ) {
+ && !autocmd_busy) {
MSG(_(m_onlyone));
}
return;
}
- /* Be very careful here: autocommands may change the window layout. */
+ // Be very careful here: autocommands may change the window layout.
for (wp = firstwin; win_valid(wp); wp = nextwp) {
nextwp = wp->w_next;
- if (wp == curwin) { /* don't close current window */
+ if (wp == curwin) { // don't close current window
continue;
}
- /* Check if it's allowed to abandon this window */
+ // Check if it's allowed to abandon this window
r = can_abandon(wp->w_buffer, forceit);
- if (!win_valid(wp)) { /* autocommands messed wp up */
+ if (!win_valid(wp)) { // autocommands messed wp up
nextwp = firstwin;
continue;
}
@@ -3457,14 +3556,16 @@ close_others (
continue;
}
}
- if (bufIsChanged(wp->w_buffer))
+ if (bufIsChanged(wp->w_buffer)) {
continue;
+ }
}
win_close(wp, !buf_hide(wp->w_buffer) && !bufIsChanged(wp->w_buffer));
}
- if (message && !ONE_WINDOW)
+ if (message && !ONE_WINDOW) {
EMSG(_("E445: Other window contains changes"));
+ }
}
@@ -3484,7 +3585,7 @@ void win_init_empty(win_T *wp)
wp->w_cursor.lnum = 1;
wp->w_curswant = wp->w_cursor.col = 0;
wp->w_cursor.coladd = 0;
- wp->w_pcmark.lnum = 1; /* pcmark not cleared but set to line 1 */
+ wp->w_pcmark.lnum = 1; // pcmark not cleared but set to line 1
wp->w_pcmark.col = 0;
wp->w_prev_pcmark.lnum = 0;
wp->w_prev_pcmark.col = 0;
@@ -3502,8 +3603,9 @@ void win_init_empty(win_T *wp)
*/
int win_alloc_first(void)
{
- if (win_alloc_firstwin(NULL) == FAIL)
+ if (win_alloc_firstwin(NULL) == FAIL) {
return FAIL;
+ }
first_tabpage = alloc_tabpage();
first_tabpage->tp_topframe = topframe;
@@ -3537,7 +3639,7 @@ void win_alloc_aucmd_win(void)
*/
static int win_alloc_firstwin(win_T *oldwin)
{
- curwin = win_alloc(NULL, FALSE);
+ curwin = win_alloc(NULL, false);
if (oldwin == NULL) {
/* Very first window, need to create an empty buffer for it and
* initialize from scratch. */
@@ -3547,14 +3649,14 @@ static int win_alloc_firstwin(win_T *oldwin)
}
curwin->w_buffer = curbuf;
curwin->w_s = &(curbuf->b_s);
- curbuf->b_nwindows = 1; /* there is one window */
+ curbuf->b_nwindows = 1; // there is one window
curwin->w_alist = &global_alist;
- curwin_init(); /* init current window */
+ curwin_init(); // init current window
} else {
- /* First window in new tab page, initialize it from "oldwin". */
+ // First window in new tab page, initialize it from "oldwin".
win_init(curwin, oldwin, 0);
- /* We don't want cursor- and scroll-binding in the first window. */
+ // We don't want cursor- and scroll-binding in the first window.
RESET_BINDING(curwin);
}
@@ -3601,7 +3703,7 @@ static tabpage_T *alloc_tabpage(void)
static int last_tp_handle = 0;
tabpage_T *tp = xcalloc(1, sizeof(tabpage_T));
tp->handle = ++last_tp_handle;
- handle_register_tabpage(tp);
+ pmap_put(handle_T)(&tabpage_handles, tp->handle, tp);
// Init t: variables.
tp->tp_vars = tv_dict_alloc();
@@ -3616,11 +3718,12 @@ void free_tabpage(tabpage_T *tp)
{
int idx;
- handle_unregister_tabpage(tp);
+ pmap_del(handle_T)(&tabpage_handles, tp->handle);
diff_clear(tp);
- for (idx = 0; idx < SNAP_COUNT; ++idx)
+ for (idx = 0; idx < SNAP_COUNT; ++idx) {
clear_snapshot(tp, idx);
- vars_clear(&tp->tp_vars->dv_hashtab); /* free all t: variables */
+ }
+ vars_clear(&tp->tp_vars->dv_hashtab); // free all t: variables
hash_init(&tp->tp_vars->dv_hashtab);
unref_var_dict(tp->tp_vars);
@@ -3642,8 +3745,8 @@ void free_tabpage(tabpage_T *tp)
/// @return Was the new tabpage created successfully? FAIL or OK.
int win_new_tabpage(int after, char_u *filename)
{
- tabpage_T *old_curtab = curtab;
- tabpage_T *newtp;
+ tabpage_T *old_curtab = curtab;
+ tabpage_T *newtp;
int n;
newtp = alloc_tabpage();
@@ -3667,14 +3770,15 @@ int win_new_tabpage(int after, char_u *filename)
newtp->tp_next = first_tabpage;
first_tabpage = newtp;
} else {
- tabpage_T *tp = old_curtab;
+ tabpage_T *tp = old_curtab;
if (after > 0) {
// Put new tab page before tab page "after".
n = 2;
for (tp = first_tabpage; tp->tp_next != NULL
- && n < after; tp = tp->tp_next)
+ && n < after; tp = tp->tp_next) {
++n;
+ }
}
newtp->tp_next = tp->tp_next;
tp->tp_next = newtp;
@@ -3717,7 +3821,7 @@ int may_open_tabpage(void)
int n = (cmdmod.tab == 0) ? postponed_split_tab : cmdmod.tab;
if (n != 0) {
- cmdmod.tab = 0; /* reset it to avoid doing it twice */
+ cmdmod.tab = 0; // reset it to avoid doing it twice
postponed_split_tab = 0;
return win_new_tabpage(n, NULL);
}
@@ -3733,9 +3837,10 @@ int make_tabpages(int maxcount)
int count = maxcount;
int todo;
- /* Limit to 'tabpagemax' tabs. */
- if (count > p_tpm)
+ // Limit to 'tabpagemax' tabs.
+ if (count > p_tpm) {
count = p_tpm;
+ }
/*
* Don't execute autocommands while creating the tab pages. Must do that
@@ -3751,7 +3856,7 @@ int make_tabpages(int maxcount)
unblock_autocmds();
- /* return actual number of tab pages */
+ // return actual number of tab pages
return count - todo;
}
@@ -3812,11 +3917,12 @@ void close_tabpage(tabpage_T *tab)
*/
tabpage_T *find_tabpage(int n)
{
- tabpage_T *tp;
+ tabpage_T *tp;
int i = 1;
- for (tp = first_tabpage; tp != NULL && i != n; tp = tp->tp_next)
+ for (tp = first_tabpage; tp != NULL && i != n; tp = tp->tp_next) {
++i;
+ }
return tp;
}
@@ -3827,41 +3933,42 @@ tabpage_T *find_tabpage(int n)
int tabpage_index(tabpage_T *ftp)
{
int i = 1;
- tabpage_T *tp;
+ tabpage_T *tp;
- for (tp = first_tabpage; tp != NULL && tp != ftp; tp = tp->tp_next)
+ for (tp = first_tabpage; tp != NULL && tp != ftp; tp = tp->tp_next) {
++i;
+ }
return i;
}
-/*
- * Prepare for leaving the current tab page.
- * When autocommands change "curtab" we don't leave the tab page and return
- * FAIL.
- * Careful: When OK is returned need to get a new tab page very very soon!
- */
-static int
-leave_tabpage (
- buf_T *new_curbuf, /* what is going to be the new curbuf,
- NULL if unknown */
- int trigger_leave_autocmds
-)
+/// Prepare for leaving the current tab page.
+/// When autocommands change "curtab" we don't leave the tab page and return
+/// FAIL.
+/// Careful: When OK is returned need to get a new tab page very very soon!
+///
+/// @param new_curbuf what is going to be the new curbuf,
+/// NULL if unknown.
+/// @param trigger_leave_autocmds when true trigger *Leave autocommands.
+static int leave_tabpage(buf_T *new_curbuf, bool trigger_leave_autocmds)
{
- tabpage_T *tp = curtab;
+ tabpage_T *tp = curtab;
- reset_VIsual_and_resel(); /* stop Visual mode */
+ reset_VIsual_and_resel(); // stop Visual mode
if (trigger_leave_autocmds) {
if (new_curbuf != curbuf) {
- apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf);
- if (curtab != tp)
+ apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, false, curbuf);
+ if (curtab != tp) {
return FAIL;
+ }
}
- apply_autocmds(EVENT_WINLEAVE, NULL, NULL, FALSE, curbuf);
- if (curtab != tp)
+ apply_autocmds(EVENT_WINLEAVE, NULL, NULL, false, curbuf);
+ if (curtab != tp) {
return FAIL;
- apply_autocmds(EVENT_TABLEAVE, NULL, NULL, FALSE, curbuf);
- if (curtab != tp)
+ }
+ apply_autocmds(EVENT_TABLEAVE, NULL, NULL, false, curbuf);
+ if (curtab != tp) {
return FAIL;
+ }
}
tp->tp_curwin = curwin;
tp->tp_prevwin = prevwin;
@@ -3874,16 +3981,16 @@ leave_tabpage (
return OK;
}
-/*
- * Start using tab page "tp".
- * Only to be used after leave_tabpage() or freeing the current tab page.
- * Only trigger *Enter autocommands when trigger_enter_autocmds is TRUE.
- * Only trigger *Leave autocommands when trigger_leave_autocmds is TRUE.
- */
-static void enter_tabpage(tabpage_T *tp, buf_T *old_curbuf, int trigger_enter_autocmds, int trigger_leave_autocmds)
+/// Start using tab page "tp".
+/// Only to be used after leave_tabpage() or freeing the current tab page.
+///
+/// @param trigger_enter_autocmds when true trigger *Enter autocommands.
+/// @param trigger_leave_autocmds when true trigger *Leave autocommands.
+static void enter_tabpage(tabpage_T *tp, buf_T *old_curbuf, bool trigger_enter_autocmds,
+ bool trigger_leave_autocmds)
{
int old_off = tp->tp_firstwin->w_winrow;
- win_T *next_prevwin = tp->tp_prevwin;
+ win_T *next_prevwin = tp->tp_prevwin;
tabpage_T *old_curtab = curtab;
curtab = tp;
@@ -3892,14 +3999,15 @@ static void enter_tabpage(tabpage_T *tp, buf_T *old_curbuf, int trigger_enter_au
topframe = tp->tp_topframe;
if (old_curtab != curtab) {
- tabpage_check_windows(old_curtab);
+ tabpage_check_windows(old_curtab);
}
- /* We would like doing the TabEnter event first, but we don't have a
- * valid current window yet, which may break some commands.
- * This triggers autocommands, thus may make "tp" invalid. */
- win_enter_ext(tp->tp_curwin, false, true, false,
- trigger_enter_autocmds, trigger_leave_autocmds);
+ // We would like doing the TabEnter event first, but we don't have a
+ // valid current window yet, which may break some commands.
+ // This triggers autocommands, thus may make "tp" invalid.
+ win_enter_ext(tp->tp_curwin, WEE_CURWIN_INVALID
+ | (trigger_enter_autocmds ? WEE_TRIGGER_ENTER_AUTOCMDS : 0)
+ | (trigger_leave_autocmds ? WEE_TRIGGER_LEAVE_AUTOCMDS : 0));
prevwin = next_prevwin;
last_status(false); // status line may appear or disappear
@@ -3934,9 +4042,10 @@ static void enter_tabpage(tabpage_T *tp, buf_T *old_curbuf, int trigger_enter_au
/* Apply autocommands after updating the display, when 'rows' and
* 'columns' have been set correctly. */
if (trigger_enter_autocmds) {
- apply_autocmds(EVENT_TABENTER, NULL, NULL, FALSE, curbuf);
- if (old_curbuf != curbuf)
- apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf);
+ apply_autocmds(EVENT_TABENTER, NULL, NULL, false, curbuf);
+ if (old_curbuf != curbuf) {
+ apply_autocmds(EVENT_BUFENTER, NULL, NULL, false, curbuf);
+ }
}
redraw_all_later(NOT_VALID);
@@ -3977,8 +4086,8 @@ static void tabpage_check_windows(tabpage_T *old_curtab)
*/
void goto_tabpage(int n)
{
- tabpage_T *tp = NULL; // shut up compiler
- tabpage_T *ttp;
+ tabpage_T *tp = NULL; // shut up compiler
+ tabpage_T *ttp;
int i;
if (text_locked()) {
@@ -3987,35 +4096,39 @@ void goto_tabpage(int n)
return;
}
- /* If there is only one it can't work. */
+ // If there is only one it can't work.
if (first_tabpage->tp_next == NULL) {
- if (n > 1)
+ if (n > 1) {
beep_flush();
+ }
return;
}
if (n == 0) {
- /* No count, go to next tab page, wrap around end. */
- if (curtab->tp_next == NULL)
+ // No count, go to next tab page, wrap around end.
+ if (curtab->tp_next == NULL) {
tp = first_tabpage;
- else
+ } else {
tp = curtab->tp_next;
+ }
} else if (n < 0) {
/* "gT": go to previous tab page, wrap around end. "N gT" repeats
* this N times. */
ttp = curtab;
for (i = n; i < 0; ++i) {
for (tp = first_tabpage; tp->tp_next != ttp && tp->tp_next != NULL;
- tp = tp->tp_next)
+ tp = tp->tp_next) {
;
+ }
ttp = tp;
}
} else if (n == 9999) {
- /* Go to last tab page. */
- for (tp = first_tabpage; tp->tp_next != NULL; tp = tp->tp_next)
+ // Go to last tab page.
+ for (tp = first_tabpage; tp->tp_next != NULL; tp = tp->tp_next) {
;
+ }
} else {
- /* Go to tab page "n". */
+ // Go to tab page "n".
tp = find_tabpage(n);
if (tp == NULL) {
beep_flush();
@@ -4023,29 +4136,28 @@ void goto_tabpage(int n)
}
}
- goto_tabpage_tp(tp, TRUE, TRUE);
-
+ goto_tabpage_tp(tp, true, true);
}
-/*
- * Go to tabpage "tp".
- * Only trigger *Enter autocommands when trigger_enter_autocmds is TRUE.
- * Only trigger *Leave autocommands when trigger_leave_autocmds is TRUE.
- * Note: doesn't update the GUI tab.
- */
-void goto_tabpage_tp(tabpage_T *tp, int trigger_enter_autocmds, int trigger_leave_autocmds)
+/// Go to tabpage "tp".
+/// Note: doesn't update the GUI tab.
+///
+/// @param trigger_enter_autocmds when true trigger *Enter autocommands.
+/// @param trigger_leave_autocmds when true trigger *Leave autocommands.
+void goto_tabpage_tp(tabpage_T *tp, bool trigger_enter_autocmds, bool trigger_leave_autocmds)
{
- /* Don't repeat a message in another tab page. */
+ // Don't repeat a message in another tab page.
set_keep_msg(NULL, 0);
if (tp != curtab && leave_tabpage(tp->tp_curwin->w_buffer,
- trigger_leave_autocmds) == OK) {
- if (valid_tabpage(tp))
+ trigger_leave_autocmds) == OK) {
+ if (valid_tabpage(tp)) {
enter_tabpage(tp, curbuf, trigger_enter_autocmds,
- trigger_leave_autocmds);
- else
+ trigger_leave_autocmds);
+ } else {
enter_tabpage(curtab, curbuf, trigger_enter_autocmds,
- trigger_leave_autocmds);
+ trigger_leave_autocmds);
+ }
}
}
@@ -4064,7 +4176,7 @@ void goto_tabpage_lastused(void)
*/
void goto_tabpage_win(tabpage_T *tp, win_T *wp)
{
- goto_tabpage_tp(tp, TRUE, TRUE);
+ goto_tabpage_tp(tp, true, true);
if (curtab == tp && win_valid(wp)) {
win_enter(wp, true);
}
@@ -4120,8 +4232,8 @@ void tabpage_move(int nr)
tp_dst->tp_next = curtab;
}
- /* Need to redraw the tabline. Tab page contents doesn't change. */
- redraw_tabline = TRUE;
+ // Need to redraw the tabline. Tab page contents doesn't change.
+ redraw_tabline = true;
}
@@ -4134,20 +4246,22 @@ void tabpage_move(int nr)
*/
void win_goto(win_T *wp)
{
- win_T *owp = curwin;
+ win_T *owp = curwin;
if (text_locked()) {
beep_flush();
text_locked_msg();
return;
}
- if (curbuf_locked())
+ if (curbuf_locked()) {
return;
+ }
- if (wp->w_buffer != curbuf)
+ if (wp->w_buffer != curbuf) {
reset_VIsual_and_resel();
- else if (VIsual_active)
+ } else if (VIsual_active) {
wp->w_cursor = curwin->w_cursor;
+ }
win_enter(wp, true);
@@ -4185,9 +4299,9 @@ tabpage_T *win_find_tabpage(win_T *win)
/// @return found window
win_T *win_vert_neighbor(tabpage_T *tp, win_T *wp, bool up, long count)
{
- frame_T *fr;
- frame_T *nfr;
- frame_T *foundfr;
+ frame_T *fr;
+ frame_T *nfr;
+ frame_T *foundfr;
foundfr = wp->w_frame;
@@ -4233,9 +4347,11 @@ win_T *win_vert_neighbor(tabpage_T *tp, win_T *wp, bool up, long count)
fr = fr->fr_next;
}
}
- if (nfr->fr_layout == FR_COL && up)
- while (fr->fr_next != NULL)
+ if (nfr->fr_layout == FR_COL && up) {
+ while (fr->fr_next != NULL) {
fr = fr->fr_next;
+ }
+ }
nfr = fr;
}
}
@@ -4266,9 +4382,9 @@ static void win_goto_ver(bool up, long count)
/// @return found window
win_T *win_horz_neighbor(tabpage_T *tp, win_T *wp, bool left, long count)
{
- frame_T *fr;
- frame_T *nfr;
- frame_T *foundfr;
+ frame_T *fr;
+ frame_T *nfr;
+ frame_T *foundfr;
foundfr = wp->w_frame;
@@ -4307,15 +4423,18 @@ win_T *win_horz_neighbor(tabpage_T *tp, win_T *wp, bool left, long count)
}
fr = nfr->fr_child;
if (nfr->fr_layout == FR_COL) {
- /* Find the frame at the cursor row. */
+ // Find the frame at the cursor row.
while (fr->fr_next != NULL
&& frame2win(fr)->w_winrow + fr->fr_height
- <= wp->w_winrow + wp->w_wrow)
+ <= wp->w_winrow + wp->w_wrow) {
fr = fr->fr_next;
+ }
}
- if (nfr->fr_layout == FR_ROW && left)
- while (fr->fr_next != NULL)
+ if (nfr->fr_layout == FR_ROW && left) {
+ while (fr->fr_next != NULL) {
fr = fr->fr_next;
+ }
+ }
nfr = fr;
}
}
@@ -4341,44 +4460,45 @@ static void win_goto_hor(bool left, long count)
/// win_valid(wp).
void win_enter(win_T *wp, bool undo_sync)
{
- win_enter_ext(wp, undo_sync, false, false, true, true);
+ win_enter_ext(wp, (undo_sync ? WEE_UNDO_SYNC : 0)
+ | WEE_TRIGGER_ENTER_AUTOCMDS | WEE_TRIGGER_LEAVE_AUTOCMDS);
}
-/*
- * Make window wp the current window.
- * Can be called with "curwin_invalid" TRUE, which means that curwin has just
- * been closed and isn't valid.
- */
-static void win_enter_ext(win_T *wp, bool undo_sync, int curwin_invalid,
- int trigger_new_autocmds, int trigger_enter_autocmds,
- int trigger_leave_autocmds)
+/// Make window "wp" the current window.
+///
+/// @param flags if contains WEE_CURWIN_INVALID, it means curwin has just been
+/// closed and isn't valid.
+static void win_enter_ext(win_T *const wp, const int flags)
{
- int other_buffer = FALSE;
+ bool other_buffer = false;
+ const bool curwin_invalid = (flags & WEE_CURWIN_INVALID);
- if (wp == curwin && !curwin_invalid) /* nothing to do */
+ if (wp == curwin && !curwin_invalid) { // nothing to do
return;
+ }
- if (!curwin_invalid && trigger_leave_autocmds) {
- /*
- * Be careful: If autocommands delete the window, return now.
- */
+ if (!curwin_invalid && (flags & WEE_TRIGGER_LEAVE_AUTOCMDS)) {
+ // Be careful: If autocommands delete the window, return now.
if (wp->w_buffer != curbuf) {
- apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf);
- other_buffer = TRUE;
- if (!win_valid(wp))
+ apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, false, curbuf);
+ other_buffer = true;
+ if (!win_valid(wp)) {
return;
+ }
}
- apply_autocmds(EVENT_WINLEAVE, NULL, NULL, FALSE, curbuf);
- if (!win_valid(wp))
+ apply_autocmds(EVENT_WINLEAVE, NULL, NULL, false, curbuf);
+ if (!win_valid(wp)) {
return;
- /* autocmds may abort script processing */
- if (aborting())
+ }
+ // autocmds may abort script processing
+ if (aborting()) {
return;
+ }
}
// sync undo before leaving the current buffer
- if (undo_sync && curbuf != wp->w_buffer) {
- u_sync(FALSE);
+ if ((flags & WEE_UNDO_SYNC) && curbuf != wp->w_buffer) {
+ u_sync(false);
}
// Might need to scroll the old window before switching, e.g., when the
@@ -4390,16 +4510,17 @@ static void win_enter_ext(win_T *wp, bool undo_sync, int curwin_invalid,
buf_copy_options(wp->w_buffer, BCO_ENTER | BCO_NOHELP);
}
if (!curwin_invalid) {
- prevwin = curwin; /* remember for CTRL-W p */
+ prevwin = curwin; // remember for CTRL-W p
curwin->w_redr_status = TRUE;
}
curwin = wp;
curbuf = wp->w_buffer;
check_cursor();
- if (!virtual_active())
+ if (!virtual_active()) {
curwin->w_cursor.coladd = 0;
- changed_line_abv_curs(); /* assume cursor position needs updating */
+ }
+ changed_line_abv_curs(); // assume cursor position needs updating
// New directory is either the local directory of the window, tab or NULL.
char *new_dir = (char *)(curwin->w_localdir
@@ -4437,10 +4558,10 @@ static void win_enter_ext(win_T *wp, bool undo_sync, int curwin_invalid,
shorten_fnames(true);
}
- if (trigger_new_autocmds) {
+ if (flags & WEE_TRIGGER_NEW_AUTOCMDS) {
apply_autocmds(EVENT_WINNEW, NULL, NULL, false, curbuf);
}
- if (trigger_enter_autocmds) {
+ if (flags & WEE_TRIGGER_ENTER_AUTOCMDS) {
apply_autocmds(EVENT_WINENTER, NULL, NULL, false, curbuf);
if (other_buffer) {
apply_autocmds(EVENT_BUFENTER, NULL, NULL, false, curbuf);
@@ -4474,9 +4595,9 @@ static void win_enter_ext(win_T *wp, bool undo_sync, int curwin_invalid,
win_setwidth((int)p_wiw);
}
- setmouse(); /* in case jumped to/from help buffer */
+ setmouse(); // in case jumped to/from help buffer
- /* Change directories when the 'acd' option is set. */
+ // Change directories when the 'acd' option is set.
do_autochdir();
}
@@ -4505,12 +4626,12 @@ win_T *buf_jump_open_win(buf_T *buf)
/// @return the found window, or NULL.
win_T *buf_jump_open_tab(buf_T *buf)
{
-
// First try the current tab page.
{
win_T *wp = buf_jump_open_win(buf);
- if (wp != NULL)
+ if (wp != NULL) {
return wp;
+ }
}
FOR_ALL_TABS(tp) {
@@ -4538,11 +4659,9 @@ win_T *buf_jump_open_tab(buf_T *buf)
return NULL;
}
-/*
- * Allocate a window structure and link it in the window list when "hidden" is
- * FALSE.
- */
-static win_T *win_alloc(win_T *after, int hidden)
+/// @param hidden allocate a window structure and link it in the window if
+// false.
+static win_T *win_alloc(win_T *after, bool hidden)
{
static int last_win_id = LOWEST_WIN_ID - 1;
@@ -4550,7 +4669,7 @@ static win_T *win_alloc(win_T *after, int hidden)
win_T *new_wp = xcalloc(1, sizeof(win_T));
new_wp->handle = ++last_win_id;
- handle_register_window(new_wp);
+ pmap_put(handle_T)(&window_handles, new_wp->handle, new_wp);
grid_assign_handle(&new_wp->w_grid_alloc);
@@ -4565,13 +4684,14 @@ static win_T *win_alloc(win_T *after, int hidden)
/*
* link the window in the window list
*/
- if (!hidden)
+ if (!hidden) {
win_append(after, new_wp);
+ }
new_wp->w_wincol = 0;
new_wp->w_width = Columns;
- /* position the display and the cursor at the top of the file. */
+ // position the display and the cursor at the top of the file.
new_wp->w_topline = 1;
new_wp->w_topfill = 0;
new_wp->w_botline = 2;
@@ -4585,7 +4705,7 @@ static win_T *win_alloc(win_T *after, int hidden)
new_wp->w_p_so = -1;
new_wp->w_p_siso = -1;
- /* We won't calculate w_fraction until resizing the window */
+ // We won't calculate w_fraction until resizing the window
new_wp->w_fraction = 0;
new_wp->w_prev_fraction_row = -1;
@@ -4598,8 +4718,7 @@ static win_T *win_alloc(win_T *after, int hidden)
// Free one wininfo_T.
-void
-free_wininfo(wininfo_T *wip, buf_T *bp)
+void free_wininfo(wininfo_T *wip, buf_T *bp)
{
if (wip->wi_optset) {
clear_winopt(&wip->wi_opt);
@@ -4609,22 +4728,18 @@ free_wininfo(wininfo_T *wip, buf_T *bp)
}
-/*
- * Remove window 'wp' from the window list and free the structure.
- */
-static void
-win_free (
- win_T *wp,
- tabpage_T *tp /* tab page "win" is in, NULL for current */
-)
+/// Remove window 'wp' from the window list and free the structure.
+///
+/// @param tp tab page "win" is in, NULL for current
+static void win_free(win_T *wp, tabpage_T *tp)
{
int i;
- wininfo_T *wip;
+ wininfo_T *wip;
- handle_unregister_window(wp);
+ pmap_del(handle_T)(&window_handles, wp->handle);
clearFolding(wp);
- /* reduce the reference count to the argument list. */
+ // reduce the reference count to the argument list.
alist_unlink(wp->w_alist);
/* Don't execute autocommands while the window is halfway being deleted.
@@ -4634,7 +4749,7 @@ win_free (
clear_winopt(&wp->w_onebuf_opt);
clear_winopt(&wp->w_allbuf_opt);
- vars_clear(&wp->w_vars->dv_hashtab); /* free all w: variables */
+ vars_clear(&wp->w_vars->dv_hashtab); // free all w: variables
hash_init(&wp->w_vars->dv_hashtab);
unref_var_dict(wp->w_vars);
@@ -4665,8 +4780,10 @@ win_free (
// If there already is an entry with "wi_win" set to NULL it
// must be removed, it would never be used.
+ // Skip "wip" itself, otherwise Coverity complains.
for (wip2 = buf->b_wininfo; wip2 != NULL; wip2 = wip2->wi_next) {
- if (wip2->wi_win == NULL) {
+ // `wip2 != wip` to satisfy Coverity. #14884
+ if (wip2 != wip && wip2->wi_win == NULL) {
if (wip2->wi_next != NULL) {
wip2->wi_next->wi_prev = wip2->wi_prev;
}
@@ -4695,8 +4812,9 @@ win_free (
win_free_grid(wp, false);
- if (wp != aucmd_win)
+ if (wp != aucmd_win) {
win_remove(wp, tp);
+ }
if (autocmd_busy) {
wp->w_next = au_pending_free_win;
au_pending_free_win = wp;
@@ -4725,33 +4843,32 @@ void win_free_grid(win_T *wp, bool reinit)
*/
void win_append(win_T *after, win_T *wp)
{
- win_T *before;
+ win_T *before;
- if (after == NULL) /* after NULL is in front of the first */
+ if (after == NULL) { // after NULL is in front of the first
before = firstwin;
- else
+ } else {
before = after->w_next;
+ }
wp->w_next = before;
wp->w_prev = after;
- if (after == NULL)
+ if (after == NULL) {
firstwin = wp;
- else
+ } else {
after->w_next = wp;
- if (before == NULL)
+ }
+ if (before == NULL) {
lastwin = wp;
- else
+ } else {
before->w_prev = wp;
+ }
}
-/*
- * Remove a window from the window list.
- */
-void
-win_remove (
- win_T *wp,
- tabpage_T *tp /* tab page "win" is in, NULL for current */
-)
+/// Remove a window from the window list.
+///
+/// @param tp tab page "win" is in, NULL for current
+void win_remove(win_T *wp, tabpage_T *tp)
{
if (wp->w_prev != NULL) {
wp->w_prev->w_next = wp->w_next;
@@ -4776,8 +4893,9 @@ static void frame_append(frame_T *after, frame_T *frp)
{
frp->fr_next = after->fr_next;
after->fr_next = frp;
- if (frp->fr_next != NULL)
+ if (frp->fr_next != NULL) {
frp->fr_next->fr_prev = frp;
+ }
frp->fr_prev = after;
}
@@ -4789,10 +4907,11 @@ static void frame_insert(frame_T *before, frame_T *frp)
frp->fr_next = before;
frp->fr_prev = before->fr_prev;
before->fr_prev = frp;
- if (frp->fr_prev != NULL)
+ if (frp->fr_prev != NULL) {
frp->fr_prev->fr_next = frp;
- else
+ } else {
frp->fr_parent->fr_child = frp;
+ }
}
/*
@@ -4804,10 +4923,6 @@ static void frame_remove(frame_T *frp)
frp->fr_prev->fr_next = frp->fr_next;
} else {
frp->fr_parent->fr_child = frp->fr_next;
- // special case: topframe->fr_child == frp
- if (topframe->fr_child == frp) {
- topframe->fr_child = frp->fr_next;
- }
}
if (frp->fr_next != NULL) {
frp->fr_next->fr_prev = frp->fr_prev;
@@ -4823,22 +4938,24 @@ void shell_new_rows(void)
{
int h = (int)ROWS_AVAIL;
- if (firstwin == NULL) /* not initialized yet */
+ if (firstwin == NULL) { // not initialized yet
return;
- if (h < frame_minheight(topframe, NULL))
+ }
+ if (h < frame_minheight(topframe, NULL)) {
h = frame_minheight(topframe, NULL);
+ }
/* First try setting the heights of windows with 'winfixheight'. If
* that doesn't result in the right height, forget about that option. */
- frame_new_height(topframe, h, FALSE, TRUE);
- if (!frame_check_height(topframe, h))
- frame_new_height(topframe, h, FALSE, FALSE);
+ frame_new_height(topframe, h, false, true);
+ if (!frame_check_height(topframe, h)) {
+ frame_new_height(topframe, h, false, false);
+ }
(void)win_comp_pos(); // recompute w_winrow and w_wincol
win_reconfig_floats(); // The size of floats might change
compute_cmdrow();
curtab->tp_ch_used = p_ch;
-
}
/*
@@ -4846,8 +4963,9 @@ void shell_new_rows(void)
*/
void shell_new_columns(void)
{
- if (firstwin == NULL) /* not initialized yet */
+ if (firstwin == NULL) { // not initialized yet
return;
+ }
/* First try setting the widths of windows with 'winfixwidth'. If that
* doesn't result in the right width, forget about that option. */
@@ -4920,7 +5038,7 @@ void win_size_restore(garray_T *gap)
}
}
}
- /* recompute the window positions */
+ // recompute the window positions
(void)win_comp_pos();
}
}
@@ -4962,17 +5080,16 @@ void win_reconfig_floats(void)
*/
static void frame_comp_pos(frame_T *topfrp, int *row, int *col)
{
- win_T *wp;
- frame_T *frp;
+ win_T *wp;
+ frame_T *frp;
int startcol;
int startrow;
wp = topfrp->fr_win;
if (wp != NULL) {
if (wp->w_winrow != *row
- || wp->w_wincol != *col
- ) {
- /* position changed, redraw */
+ || wp->w_wincol != *col) {
+ // position changed, redraw
wp->w_winrow = *row;
wp->w_wincol = *col;
redraw_later(wp, NOT_VALID);
@@ -5043,7 +5160,6 @@ void win_setheight_win(int height, win_T *win)
msg_col = 0;
redraw_all_later(NOT_VALID);
}
-
}
@@ -5062,30 +5178,34 @@ void win_setheight_win(int height, win_T *win)
*/
static void frame_setheight(frame_T *curfrp, int height)
{
- int room; /* total number of lines available */
- int take; /* number of lines taken from other windows */
- int room_cmdline; /* lines available from cmdline */
+ int room; // total number of lines available
+ int take; // number of lines taken from other windows
+ int room_cmdline; // lines available from cmdline
int run;
- frame_T *frp;
+ frame_T *frp;
int h;
int room_reserved;
- /* If the height already is the desired value, nothing to do. */
- if (curfrp->fr_height == height)
+ // If the height already is the desired value, nothing to do.
+ if (curfrp->fr_height == height) {
return;
+ }
if (curfrp->fr_parent == NULL) {
- /* topframe: can only change the command line */
- if (height > ROWS_AVAIL)
+ // topframe: can only change the command line
+ if (height > ROWS_AVAIL) {
height = ROWS_AVAIL;
- if (height > 0)
- frame_new_height(curfrp, height, FALSE, FALSE);
+ }
+ if (height > 0) {
+ frame_new_height(curfrp, height, false, false);
+ }
} else if (curfrp->fr_parent->fr_layout == FR_ROW) {
/* Row of frames: Also need to resize frames left and right of this
* one. First check for the minimal height of these. */
h = frame_minheight(curfrp->fr_parent, NULL);
- if (height < h)
+ if (height < h) {
height = h;
+ }
frame_setheight(curfrp->fr_parent, height);
} else {
/*
@@ -5117,7 +5237,7 @@ static void frame_setheight(frame_T *curfrp, int height)
} else {
win_T *wp = lastwin_nofloating();
room_cmdline = Rows - p_ch
- - (wp->w_winrow + wp->w_height + wp->w_status_height);
+ - (wp->w_winrow + wp->w_height + wp->w_status_height);
if (room_cmdline < 0) {
room_cmdline = 0;
}
@@ -5131,8 +5251,8 @@ static void frame_setheight(frame_T *curfrp, int height)
break;
}
frame_setheight(curfrp->fr_parent, height
- + frame_minheight(curfrp->fr_parent, NOWIN) - (int)p_wmh - 1);
- /*NOTREACHED*/
+ + frame_minheight(curfrp->fr_parent, NOWIN) - (int)p_wmh - 1);
+ //NOTREACHED
}
/*
@@ -5143,17 +5263,20 @@ static void frame_setheight(frame_T *curfrp, int height)
/* If there is not enough room, also reduce the height of a window
* with 'winfixheight' set. */
- if (height > room + room_cmdline - room_reserved)
+ if (height > room + room_cmdline - room_reserved) {
room_reserved = room + room_cmdline - height;
+ }
/* If there is only a 'winfixheight' window and making the
* window smaller, need to make the other window taller. */
- if (take < 0 && room - curfrp->fr_height < room_reserved)
+ if (take < 0 && room - curfrp->fr_height < room_reserved) {
room_reserved = 0;
+ }
if (take > 0 && room_cmdline > 0) {
- /* use lines from cmdline first */
- if (take < room_cmdline)
+ // use lines from cmdline first
+ if (take < room_cmdline) {
room_cmdline = take;
+ }
take -= room_cmdline;
topframe->fr_height += room_cmdline;
}
@@ -5161,7 +5284,7 @@ static void frame_setheight(frame_T *curfrp, int height)
/*
* set the current frame to the new height
*/
- frame_new_height(curfrp, height, FALSE, FALSE);
+ frame_new_height(curfrp, height, false, false);
/*
* First take lines from the frames after the current frame. If
@@ -5169,38 +5292,40 @@ static void frame_setheight(frame_T *curfrp, int height)
* frame.
*/
for (run = 0; run < 2; ++run) {
- if (run == 0)
- frp = curfrp->fr_next; /* 1st run: start with next window */
- else
- frp = curfrp->fr_prev; /* 2nd run: start with prev window */
+ if (run == 0) {
+ frp = curfrp->fr_next; // 1st run: start with next window
+ } else {
+ frp = curfrp->fr_prev; // 2nd run: start with prev window
+ }
while (frp != NULL && take != 0) {
h = frame_minheight(frp, NULL);
if (room_reserved > 0
&& frp->fr_win != NULL
&& frp->fr_win->w_p_wfh) {
- if (room_reserved >= frp->fr_height)
+ if (room_reserved >= frp->fr_height) {
room_reserved -= frp->fr_height;
- else {
- if (frp->fr_height - room_reserved > take)
+ } else {
+ if (frp->fr_height - room_reserved > take) {
room_reserved = frp->fr_height - take;
+ }
take -= frp->fr_height - room_reserved;
- frame_new_height(frp, room_reserved, FALSE, FALSE);
+ frame_new_height(frp, room_reserved, false, false);
room_reserved = 0;
}
} else {
if (frp->fr_height - take < h) {
take -= frp->fr_height - h;
- frame_new_height(frp, h, FALSE, FALSE);
+ frame_new_height(frp, h, false, false);
} else {
- frame_new_height(frp, frp->fr_height - take,
- FALSE, FALSE);
+ frame_new_height(frp, frp->fr_height - take, false, false);
take = 0;
}
}
- if (run == 0)
+ if (run == 0) {
frp = frp->fr_next;
- else
+ } else {
frp = frp->fr_prev;
+ }
}
}
}
@@ -5220,10 +5345,12 @@ void win_setwidth_win(int width, win_T *wp)
/* Always keep current window at least one column wide, even when
* 'winminwidth' is zero. */
if (wp == curwin) {
- if (width < p_wmw)
+ if (width < p_wmw) {
width = p_wmw;
- if (width == 0)
+ }
+ if (width == 0) {
width = 1;
+ }
} else if (width < 0) {
width = 0;
}
@@ -5238,7 +5365,6 @@ void win_setwidth_win(int width, win_T *wp)
(void)win_comp_pos();
redraw_all_later(NOT_VALID);
}
-
}
/*
@@ -5250,27 +5376,30 @@ void win_setwidth_win(int width, win_T *wp)
*/
static void frame_setwidth(frame_T *curfrp, int width)
{
- int room; /* total number of lines available */
- int take; /* number of lines taken from other windows */
+ int room; // total number of lines available
+ int take; // number of lines taken from other windows
int run;
- frame_T *frp;
+ frame_T *frp;
int w;
int room_reserved;
- /* If the width already is the desired value, nothing to do. */
- if (curfrp->fr_width == width)
+ // If the width already is the desired value, nothing to do.
+ if (curfrp->fr_width == width) {
return;
+ }
- if (curfrp->fr_parent == NULL)
- /* topframe: can't change width */
+ if (curfrp->fr_parent == NULL) {
+ // topframe: can't change width
return;
+ }
if (curfrp->fr_parent->fr_layout == FR_COL) {
/* Column of frames: Also need to resize frames above and below of
* this one. First check for the minimal width of these. */
w = frame_minwidth(curfrp->fr_parent, NULL);
- if (width < w)
+ if (width < w) {
width = w;
+ }
frame_setwidth(curfrp->fr_parent, width);
} else {
/*
@@ -5296,14 +5425,15 @@ static void frame_setwidth(frame_T *curfrp, int width)
}
}
- if (width <= room)
+ if (width <= room) {
break;
+ }
if (run == 2 || curfrp->fr_height >= ROWS_AVAIL) {
width = room;
break;
}
frame_setwidth(curfrp->fr_parent, width
- + frame_minwidth(curfrp->fr_parent, NOWIN) - (int)p_wmw - 1);
+ + frame_minwidth(curfrp->fr_parent, NOWIN) - (int)p_wmw - 1);
}
/*
@@ -5314,17 +5444,19 @@ static void frame_setwidth(frame_T *curfrp, int width)
/* If there is not enough room, also reduce the width of a window
* with 'winfixwidth' set. */
- if (width > room - room_reserved)
+ if (width > room - room_reserved) {
room_reserved = room - width;
+ }
/* If there is only a 'winfixwidth' window and making the
* window smaller, need to make the other window narrower. */
- if (take < 0 && room - curfrp->fr_width < room_reserved)
+ if (take < 0 && room - curfrp->fr_width < room_reserved) {
room_reserved = 0;
+ }
/*
* set the current frame to the new width
*/
- frame_new_width(curfrp, width, FALSE, FALSE);
+ frame_new_width(curfrp, width, false, false);
/*
* First take lines from the frames right of the current frame. If
@@ -5332,38 +5464,40 @@ static void frame_setwidth(frame_T *curfrp, int width)
* frame.
*/
for (run = 0; run < 2; ++run) {
- if (run == 0)
- frp = curfrp->fr_next; /* 1st run: start with next window */
- else
- frp = curfrp->fr_prev; /* 2nd run: start with prev window */
+ if (run == 0) {
+ frp = curfrp->fr_next; // 1st run: start with next window
+ } else {
+ frp = curfrp->fr_prev; // 2nd run: start with prev window
+ }
while (frp != NULL && take != 0) {
w = frame_minwidth(frp, NULL);
if (room_reserved > 0
&& frp->fr_win != NULL
&& frp->fr_win->w_p_wfw) {
- if (room_reserved >= frp->fr_width)
+ if (room_reserved >= frp->fr_width) {
room_reserved -= frp->fr_width;
- else {
- if (frp->fr_width - room_reserved > take)
+ } else {
+ if (frp->fr_width - room_reserved > take) {
room_reserved = frp->fr_width - take;
+ }
take -= frp->fr_width - room_reserved;
- frame_new_width(frp, room_reserved, FALSE, FALSE);
+ frame_new_width(frp, room_reserved, false, false);
room_reserved = 0;
}
} else {
if (frp->fr_width - take < w) {
take -= frp->fr_width - w;
- frame_new_width(frp, w, FALSE, FALSE);
+ frame_new_width(frp, w, false, false);
} else {
- frame_new_width(frp, frp->fr_width - take,
- FALSE, FALSE);
+ frame_new_width(frp, frp->fr_width - take, false, false);
take = 0;
}
}
- if (run == 0)
+ if (run == 0) {
frp = frp->fr_next;
- else
+ } else {
frp = frp->fr_prev;
+ }
}
}
}
@@ -5409,69 +5543,71 @@ void win_setminwidth(void)
}
}
-/*
- * Status line of dragwin is dragged "offset" lines down (negative is up).
- */
+/// Status line of dragwin is dragged "offset" lines down (negative is up).
void win_drag_status_line(win_T *dragwin, int offset)
{
- frame_T *curfr;
- frame_T *fr;
+ frame_T *curfr;
+ frame_T *fr;
int room;
int row;
- int up; /* if TRUE, drag status line up, otherwise down */
+ bool up; // if true, drag status line up, otherwise down
int n;
fr = dragwin->w_frame;
curfr = fr;
- if (fr != topframe) { /* more than one window */
+ if (fr != topframe) { // more than one window
fr = fr->fr_parent;
/* When the parent frame is not a column of frames, its parent should
* be. */
if (fr->fr_layout != FR_COL) {
curfr = fr;
- if (fr != topframe) /* only a row of windows, may drag statusline */
+ if (fr != topframe) { // only a row of windows, may drag statusline
fr = fr->fr_parent;
+ }
}
}
/* If this is the last frame in a column, may want to resize the parent
* frame instead (go two up to skip a row of frames). */
while (curfr != topframe && curfr->fr_next == NULL) {
- if (fr != topframe)
+ if (fr != topframe) {
fr = fr->fr_parent;
+ }
curfr = fr;
- if (fr != topframe)
+ if (fr != topframe) {
fr = fr->fr_parent;
+ }
}
- if (offset < 0) { /* drag up */
- up = TRUE;
+ if (offset < 0) { // drag up
+ up = true;
offset = -offset;
- /* sum up the room of the current frame and above it */
+ // sum up the room of the current frame and above it
if (fr == curfr) {
- /* only one window */
+ // only one window
room = fr->fr_height - frame_minheight(fr, NULL);
} else {
room = 0;
for (fr = fr->fr_child;; fr = fr->fr_next) {
room += fr->fr_height - frame_minheight(fr, NULL);
- if (fr == curfr)
+ if (fr == curfr) {
break;
+ }
}
}
- fr = curfr->fr_next; /* put fr at frame that grows */
- } else { /* drag down */
- up = FALSE;
- /*
- * Only dragging the last status line can reduce p_ch.
- */
+ fr = curfr->fr_next; // put fr at frame that grows
+ } else { // drag down
+ up = false;
+ // Only dragging the last status line can reduce p_ch.
room = Rows - cmdline_row;
- if (curfr->fr_next == NULL)
+ if (curfr->fr_next == NULL) {
room -= 1;
- else
+ } else {
room -= p_ch;
- if (room < 0)
+ }
+ if (room < 0) {
room = 0;
+ }
// sum up the room of frames below of the current one
FOR_ALL_FRAMES(fr, curfr->fr_next) {
room += fr->fr_height - frame_minheight(fr, NULL);
@@ -5479,23 +5615,26 @@ void win_drag_status_line(win_T *dragwin, int offset)
fr = curfr; // put fr at window that grows
}
- if (room < offset) /* Not enough room */
- offset = room; /* Move as far as we can */
- if (offset <= 0)
+ if (room < offset) { // Not enough room
+ offset = room; // Move as far as we can
+ }
+ if (offset <= 0) {
return;
+ }
/*
* Grow frame fr by "offset" lines.
* Doesn't happen when dragging the last status line up.
*/
- if (fr != NULL)
- frame_new_height(fr, fr->fr_height + offset, up, FALSE);
-
- if (up)
- fr = curfr; /* current frame gets smaller */
- else
- fr = curfr->fr_next; /* next frame gets smaller */
+ if (fr != NULL) {
+ frame_new_height(fr, fr->fr_height + offset, up, false);
+ }
+ if (up) {
+ fr = curfr; // current frame gets smaller
+ } else {
+ fr = curfr->fr_next; // next frame gets smaller
+ }
/*
* Now make the other frames smaller.
*/
@@ -5503,15 +5642,16 @@ void win_drag_status_line(win_T *dragwin, int offset)
n = frame_minheight(fr, NULL);
if (fr->fr_height - offset <= n) {
offset -= fr->fr_height - n;
- frame_new_height(fr, n, !up, FALSE);
+ frame_new_height(fr, n, !up, false);
} else {
- frame_new_height(fr, fr->fr_height - offset, !up, FALSE);
+ frame_new_height(fr, fr->fr_height - offset, !up, false);
break;
}
- if (up)
+ if (up) {
fr = fr->fr_prev;
- else
+ } else {
fr = fr->fr_next;
+ }
}
row = win_comp_pos();
grid_fill(&default_grid, row, cmdline_row, 0, Columns, ' ', ' ', 0);
@@ -5520,8 +5660,9 @@ void win_drag_status_line(win_T *dragwin, int offset)
}
cmdline_row = row;
p_ch = Rows - cmdline_row;
- if (p_ch < 1)
+ if (p_ch < 1) {
p_ch = 1;
+ }
curtab->tp_ch_used = p_ch;
redraw_all_later(SOME_VALID);
showmode();
@@ -5532,21 +5673,23 @@ void win_drag_status_line(win_T *dragwin, int offset)
*/
void win_drag_vsep_line(win_T *dragwin, int offset)
{
- frame_T *curfr;
- frame_T *fr;
+ frame_T *curfr;
+ frame_T *fr;
int room;
- int left; /* if TRUE, drag separator line left, otherwise right */
+ bool left; // if true, drag separator line left, otherwise right
int n;
fr = dragwin->w_frame;
- if (fr == topframe) /* only one window (cannot happen?) */
+ if (fr == topframe) { // only one window (cannot happen?)
return;
+ }
curfr = fr;
fr = fr->fr_parent;
- /* When the parent frame is not a row of frames, its parent should be. */
+ // When the parent frame is not a row of frames, its parent should be.
if (fr->fr_layout != FR_ROW) {
- if (fr == topframe) /* only a column of windows (cannot happen?) */
+ if (fr == topframe) { // only a column of windows (cannot happen?)
return;
+ }
curfr = fr;
fr = fr->fr_parent;
}
@@ -5554,8 +5697,9 @@ void win_drag_vsep_line(win_T *dragwin, int offset)
/* If this is the last frame in a row, may want to resize a parent
* frame instead. */
while (curfr->fr_next == NULL) {
- if (fr == topframe)
+ if (fr == topframe) {
break;
+ }
curfr = fr;
fr = fr->fr_parent;
if (fr != topframe) {
@@ -5564,20 +5708,21 @@ void win_drag_vsep_line(win_T *dragwin, int offset)
}
}
- if (offset < 0) { /* drag left */
- left = TRUE;
+ if (offset < 0) { // drag left
+ left = true;
offset = -offset;
- /* sum up the room of the current frame and left of it */
+ // sum up the room of the current frame and left of it
room = 0;
for (fr = fr->fr_child;; fr = fr->fr_next) {
room += fr->fr_width - frame_minwidth(fr, NULL);
- if (fr == curfr)
+ if (fr == curfr) {
break;
+ }
}
- fr = curfr->fr_next; /* put fr at frame that grows */
- } else { /* drag right */
- left = FALSE;
- /* sum up the room of frames right of the current one */
+ fr = curfr->fr_next; // put fr at frame that grows
+ } else { // drag right
+ left = false;
+ // sum up the room of frames right of the current one
room = 0;
FOR_ALL_FRAMES(fr, curfr->fr_next) {
room += fr->fr_width - frame_minwidth(fr, NULL);
@@ -5600,28 +5745,29 @@ void win_drag_vsep_line(win_T *dragwin, int offset)
return; // Safety check, should not happen.
}
- /* grow frame fr by offset lines */
- frame_new_width(fr, fr->fr_width + offset, left, FALSE);
-
- /* shrink other frames: current and at the left or at the right */
- if (left)
- fr = curfr; /* current frame gets smaller */
- else
- fr = curfr->fr_next; /* next frame gets smaller */
+ // grow frame fr by offset lines
+ frame_new_width(fr, fr->fr_width + offset, left, false);
+ // shrink other frames: current and at the left or at the right
+ if (left) {
+ fr = curfr; // current frame gets smaller
+ } else {
+ fr = curfr->fr_next; // next frame gets smaller
+ }
while (fr != NULL && offset > 0) {
n = frame_minwidth(fr, NULL);
if (fr->fr_width - offset <= n) {
offset -= fr->fr_width - n;
- frame_new_width(fr, n, !left, FALSE);
+ frame_new_width(fr, n, !left, false);
} else {
- frame_new_width(fr, fr->fr_width - offset, !left, FALSE);
+ frame_new_width(fr, fr->fr_width - offset, !left, false);
break;
}
- if (left)
+ if (left) {
fr = fr->fr_prev;
- else
+ } else {
fr = fr->fr_next;
+ }
}
(void)win_comp_pos();
redraw_all_later(NOT_VALID);
@@ -5639,7 +5785,7 @@ void set_fraction(win_T *wp)
// it's halfway that line. Thus with two lines it is 25%, with three
// lines 17%, etc. Similarly for the last line: 75%, 83%, etc.
wp->w_fraction = ((long)wp->w_wrow * FRACTION_MULT + FRACTION_MULT / 2)
- / (long)wp->w_height_inner;
+ / (long)wp->w_height_inner;
}
}
@@ -5665,9 +5811,9 @@ void win_new_height(win_T *wp, int height)
void scroll_to_fraction(win_T *wp, int prev_height)
{
- linenr_T lnum;
- int sline, line_size;
- int height = wp->w_height_inner;
+ linenr_T lnum;
+ int sline, line_size;
+ int height = wp->w_height_inner;
// Don't change w_topline in any of these cases:
// - window height is 0
@@ -5676,15 +5822,16 @@ void scroll_to_fraction(win_T *wp, int prev_height)
// is visible.
if (height > 0
&& (!wp->w_p_scb || wp == curwin)
- && (height < wp->w_buffer->b_ml.ml_line_count || wp->w_topline > 1)
- ) {
+ && (height < wp->w_buffer->b_ml.ml_line_count ||
+ wp->w_topline > 1)) {
/*
* Find a value for w_topline that shows the cursor at the same
* relative position in the window as before (more or less).
*/
lnum = wp->w_cursor.lnum;
- if (lnum < 1) /* can happen when starting up */
+ if (lnum < 1) { // can happen when starting up
lnum = 1;
+ }
wp->w_wrow = ((long)wp->w_fraction * (long)height - 1L) / FRACTION_MULT;
line_size = plines_win_col(wp, lnum, (long)(wp->w_cursor.col)) - 1;
sline = wp->w_wrow - line_size;
@@ -5720,7 +5867,7 @@ void scroll_to_fraction(win_T *wp, int prev_height)
while (sline > 0 && lnum > 1) {
(void)hasFoldingWin(wp, lnum, &lnum, NULL, true, NULL);
if (lnum == 1) {
- /* first line in buffer is folded */
+ // first line in buffer is folded
line_size = 1;
--sline;
break;
@@ -5859,7 +6006,7 @@ void win_comp_scroll(win_T *wp)
void command_height(void)
{
int h;
- frame_T *frp;
+ frame_T *frp;
int old_p_ch = curtab->tp_ch_used;
/* Use the value of p_ch that we remembered. This is needed for when the
@@ -5873,15 +6020,16 @@ void command_height(void)
frp = frp->fr_parent;
}
- /* Avoid changing the height of a window with 'winfixheight' set. */
+ // Avoid changing the height of a window with 'winfixheight' set.
while (frp->fr_prev != NULL && frp->fr_layout == FR_LEAF
- && frp->fr_win->w_p_wfh)
+ && frp->fr_win->w_p_wfh) {
frp = frp->fr_prev;
+ }
if (starting != NO_SCREEN) {
cmdline_row = Rows - p_ch;
- if (p_ch > old_p_ch) { /* p_ch got bigger */
+ if (p_ch > old_p_ch) { // p_ch got bigger
while (p_ch > old_p_ch) {
if (frp == NULL) {
EMSG(_(e_noroom));
@@ -5891,14 +6039,15 @@ void command_height(void)
break;
}
h = frp->fr_height - frame_minheight(frp, NULL);
- if (h > p_ch - old_p_ch)
+ if (h > p_ch - old_p_ch) {
h = p_ch - old_p_ch;
+ }
old_p_ch += h;
frame_add_height(frp, -h);
frp = frp->fr_prev;
}
- /* Recompute window positions. */
+ // Recompute window positions.
(void)win_comp_pos();
// clear the lines added to cmdline
@@ -5906,19 +6055,21 @@ void command_height(void)
grid_fill(&default_grid, cmdline_row, Rows, 0, Columns, ' ', ' ', 0);
}
msg_row = cmdline_row;
- redraw_cmdline = TRUE;
+ redraw_cmdline = true;
return;
}
- if (msg_row < cmdline_row)
+ if (msg_row < cmdline_row) {
msg_row = cmdline_row;
- redraw_cmdline = TRUE;
+ }
+ redraw_cmdline = true;
}
frame_add_height(frp, (int)(old_p_ch - p_ch));
- /* Recompute window positions. */
- if (frp != lastwin->w_frame)
+ // Recompute window positions.
+ if (frp != lastwin->w_frame) {
(void)win_comp_pos();
+ }
}
/*
@@ -5927,11 +6078,12 @@ void command_height(void)
*/
static void frame_add_height(frame_T *frp, int n)
{
- frame_new_height(frp, frp->fr_height + n, FALSE, FALSE);
+ frame_new_height(frp, frp->fr_height + n, false, false);
for (;; ) {
frp = frp->fr_parent;
- if (frp == NULL)
+ if (frp == NULL) {
break;
+ }
frp->fr_height += n;
}
}
@@ -5946,9 +6098,10 @@ char_u *grab_file_name(long count, linenr_T *file_lnum)
int options = FNAME_MESS | FNAME_EXP | FNAME_REL | FNAME_UNESC;
if (VIsual_active) {
size_t len;
- char_u *ptr;
- if (get_visual_text(NULL, &ptr, &len) == FAIL)
+ char_u *ptr;
+ if (get_visual_text(NULL, &ptr, &len) == FAIL) {
return NULL;
+ }
// Only recognize ":123" here
if (file_lnum != NULL && ptr[len] == ':' && isdigit(ptr[len + 1])) {
char_u *p = ptr + len + 1;
@@ -5968,33 +6121,26 @@ char_u *grab_file_name(long count, linenr_T *file_lnum)
* NULL is returned if the file name or file is not found.
*
* options:
- * FNAME_MESS give error messages
- * FNAME_EXP expand to path
- * FNAME_HYP check for hypertext link
- * FNAME_INCL apply "includeexpr"
+ * FNAME_MESS give error messages
+ * FNAME_EXP expand to path
+ * FNAME_HYP check for hypertext link
+ * FNAME_INCL apply "includeexpr"
*/
char_u *file_name_at_cursor(int options, long count, linenr_T *file_lnum)
{
return file_name_in_line(get_cursor_line_ptr(),
- curwin->w_cursor.col, options, count, curbuf->b_ffname,
- file_lnum);
+ curwin->w_cursor.col, options, count, curbuf->b_ffname,
+ file_lnum);
}
-/*
- * Return the name of the file under or after ptr[col].
- * Otherwise like file_name_at_cursor().
- */
-char_u *
-file_name_in_line (
- char_u *line,
- int col,
- int options,
- long count,
- char_u *rel_fname, /* file we are searching relative to */
- linenr_T *file_lnum /* line number after the file name */
-)
-{
- char_u *ptr;
+/// @param rel_fname file we are searching relative to
+/// @param file_lnum line number after the file name
+///
+/// @return the name of the file under or after ptr[col]. Otherwise like file_name_at_cursor().
+char_u *file_name_in_line(char_u *line, int col, int options, long count, char_u *rel_fname,
+ linenr_T *file_lnum)
+{
+ char_u *ptr;
size_t len;
bool in_type = true;
bool is_url = false;
@@ -6059,8 +6205,9 @@ file_name_in_line (
* But don't remove "..", could be a directory name.
*/
if (len > 2 && vim_strchr((char_u *)".,:;!", ptr[len - 1]) != NULL
- && ptr[len - 2] != '.')
+ && ptr[len - 2] != '.') {
--len;
+ }
if (file_lnum != NULL) {
char_u *p;
@@ -6092,34 +6239,31 @@ file_name_in_line (
return find_file_name_in_path(ptr, len, options, count, rel_fname);
}
-/*
- * Add or remove a status line for the bottom window(s), according to the
- * value of 'laststatus'.
- */
-void
-last_status (
- int morewin /* pretend there are two or more windows */
-)
+/// Add or remove a status line for the bottom window(s), according to the
+/// value of 'laststatus'.
+///
+/// @param morewin pretend there are two or more windows if true.
+void last_status(bool morewin)
{
- /* Don't make a difference between horizontal or vertical split. */
+ // Don't make a difference between horizontal or vertical split.
last_status_rec(topframe, (p_ls == 2
|| (p_ls == 1 && (morewin || !one_window()))));
}
-static void last_status_rec(frame_T *fr, int statusline)
+static void last_status_rec(frame_T *fr, bool statusline)
{
- frame_T *fp;
- win_T *wp;
+ frame_T *fp;
+ win_T *wp;
if (fr->fr_layout == FR_LEAF) {
wp = fr->fr_win;
if (wp->w_status_height != 0 && !statusline) {
- /* remove status line */
+ // remove status line
win_new_height(wp, wp->w_height + 1);
wp->w_status_height = 0;
comp_col();
} else if (wp->w_status_height == 0 && statusline) {
- /* Find a frame to take a line from. */
+ // Find a frame to take a line from.
fp = fr;
while (fp->fr_height <= frame_minheight(fp, NULL)) {
if (fp == topframe) {
@@ -6128,18 +6272,20 @@ static void last_status_rec(frame_T *fr, int statusline)
}
/* In a column of frames: go to frame above. If already at
* the top or in a row of frames: go to parent. */
- if (fp->fr_parent->fr_layout == FR_COL && fp->fr_prev != NULL)
+ if (fp->fr_parent->fr_layout == FR_COL && fp->fr_prev != NULL) {
fp = fp->fr_prev;
- else
+ } else {
fp = fp->fr_parent;
+ }
}
wp->w_status_height = 1;
if (fp != fr) {
- frame_new_height(fp, fp->fr_height - 1, FALSE, FALSE);
+ frame_new_height(fp, fp->fr_height - 1, false, false);
frame_fix_height(wp);
(void)win_comp_pos();
- } else
+ } else {
win_new_height(wp, wp->w_height - 1);
+ }
comp_col();
redraw_all_later(SOME_VALID);
}
@@ -6149,9 +6295,10 @@ static void last_status_rec(frame_T *fr, int statusline)
last_status_rec(fp, statusline);
}
} else {
- /* horizontally split window, set status line for last one */
- for (fp = fr->fr_child; fp->fr_next != NULL; fp = fp->fr_next)
+ // horizontally split window, set status line for last one
+ for (fp = fr->fr_child; fp->fr_next != NULL; fp = fp->fr_next) {
;
+ }
last_status_rec(fp, statusline);
}
}
@@ -6166,8 +6313,10 @@ int tabline_height(void)
}
assert(first_tabpage);
switch (p_stal) {
- case 0: return 0;
- case 1: return (first_tabpage->tp_next == NULL) ? 0 : 1;
+ case 0:
+ return 0;
+ case 1:
+ return (first_tabpage->tp_next == NULL) ? 0 : 1;
}
return 1;
}
@@ -6178,8 +6327,9 @@ int tabline_height(void)
*/
int min_rows(void)
{
- if (firstwin == NULL) /* not initialized yet */
+ if (firstwin == NULL) { // not initialized yet
return MIN_LINES;
+ }
int total = 0;
FOR_ALL_TABS(tp) {
@@ -6189,7 +6339,7 @@ int min_rows(void)
}
}
total += tabline_height();
- total += 1; /* count the room for the command line */
+ total += 1; // count the room for the command line
return total;
}
@@ -6214,12 +6364,11 @@ bool only_one_window(void) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
return count <= 1;
}
-/*
- * Correct the cursor line number in other windows. Used after changing the
- * current buffer, and before applying autocommands.
- * When "do_curwin" is TRUE, also check current window.
- */
-void check_lnums(int do_curwin)
+/// Correct the cursor line number in other windows. Used after changing the
+/// current buffer, and before applying autocommands.
+///
+/// @param do_curwin when true, also check current window.
+void check_lnums(bool do_curwin)
{
FOR_ALL_TAB_WINDOWS(tp, wp) {
if ((do_curwin || wp != curwin) && wp->w_buffer == curbuf) {
@@ -6285,12 +6434,15 @@ static void make_snapshot_rec(frame_T *fr, frame_T **frp)
(*frp)->fr_layout = fr->fr_layout;
(*frp)->fr_width = fr->fr_width;
(*frp)->fr_height = fr->fr_height;
- if (fr->fr_next != NULL)
+ if (fr->fr_next != NULL) {
make_snapshot_rec(fr->fr_next, &((*frp)->fr_next));
- if (fr->fr_child != NULL)
+ }
+ if (fr->fr_child != NULL) {
make_snapshot_rec(fr->fr_child, &((*frp)->fr_child));
- if (fr->fr_layout == FR_LEAF && fr->fr_win == curwin)
+ }
+ if (fr->fr_layout == FR_LEAF && fr->fr_win == curwin) {
(*frp)->fr_win = curwin;
+ }
}
/*
@@ -6311,18 +6463,14 @@ static void clear_snapshot_rec(frame_T *fr)
}
}
-/*
- * Restore a previously created snapshot, if there is any.
- * This is only done if the screen size didn't change and the window layout is
- * still the same.
- */
-void
-restore_snapshot (
- int idx,
- int close_curwin /* closing current window */
-)
+/// Restore a previously created snapshot, if there is any.
+/// This is only done if the screen size didn't change and the window layout is
+/// still the same.
+///
+/// @param close_curwin closing current window
+void restore_snapshot(int idx, int close_curwin)
{
- win_T *wp;
+ win_T *wp;
if (curtab->tp_snapshot[idx] != NULL
&& curtab->tp_snapshot[idx]->fr_width == topframe->fr_width
@@ -6349,8 +6497,9 @@ static int check_snapshot_rec(frame_T *sn, frame_T *fr)
&& check_snapshot_rec(sn->fr_next, fr->fr_next) == FAIL)
|| (sn->fr_child != NULL
&& check_snapshot_rec(sn->fr_child, fr->fr_child) == FAIL)
- || (sn->fr_win != NULL && !win_valid(sn->fr_win)))
+ || (sn->fr_win != NULL && !win_valid(sn->fr_win))) {
return FAIL;
+ }
return OK;
}
@@ -6361,25 +6510,27 @@ static int check_snapshot_rec(frame_T *sn, frame_T *fr)
*/
static win_T *restore_snapshot_rec(frame_T *sn, frame_T *fr)
{
- win_T *wp = NULL;
- win_T *wp2;
+ win_T *wp = NULL;
+ win_T *wp2;
fr->fr_height = sn->fr_height;
fr->fr_width = sn->fr_width;
if (fr->fr_layout == FR_LEAF) {
- frame_new_height(fr, fr->fr_height, FALSE, FALSE);
- frame_new_width(fr, fr->fr_width, FALSE, FALSE);
+ frame_new_height(fr, fr->fr_height, false, false);
+ frame_new_width(fr, fr->fr_width, false, false);
wp = sn->fr_win;
}
if (sn->fr_next != NULL) {
wp2 = restore_snapshot_rec(sn->fr_next, fr->fr_next);
- if (wp2 != NULL)
+ if (wp2 != NULL) {
wp = wp2;
+ }
}
if (sn->fr_child != NULL) {
wp2 = restore_snapshot_rec(sn->fr_child, fr->fr_child);
- if (wp2 != NULL)
+ if (wp2 != NULL) {
wp = wp2;
+ }
}
return wp;
}
@@ -6406,23 +6557,24 @@ static win_T *get_snapshot_focus(int idx)
return win_valid(sn->fr_win) ? sn->fr_win : NULL;
}
-/*
- * Set "win" to be the curwin and "tp" to be the current tab page.
- * restore_win() MUST be called to undo, also when FAIL is returned.
- * No autocommands will be executed until restore_win() is called.
- * When "no_display" is TRUE the display won't be affected, no redraw is
- * triggered, another tabpage access is limited.
- * Returns FAIL if switching to "win" failed.
- */
-int switch_win(win_T **save_curwin, tabpage_T **save_curtab, win_T *win, tabpage_T *tp, int no_display)
+/// Set "win" to be the curwin and "tp" to be the current tab page.
+/// restore_win() MUST be called to undo, also when FAIL is returned.
+/// No autocommands will be executed until restore_win() is called.
+///
+/// @param no_display if true the display won't be affected, no redraw is
+/// triggered, another tabpage access is limited.
+///
+/// @return FAIL if switching to "win" failed.
+int switch_win(win_T **save_curwin, tabpage_T **save_curtab, win_T *win, tabpage_T *tp,
+ bool no_display)
{
block_autocmds();
return switch_win_noblock(save_curwin, save_curtab, win, tp, no_display);
}
// As switch_win() but without blocking autocommands.
-int switch_win_noblock(win_T **save_curwin, tabpage_T **save_curtab,
- win_T *win, tabpage_T *tp, int no_display)
+int switch_win_noblock(win_T **save_curwin, tabpage_T **save_curtab, win_T *win, tabpage_T *tp,
+ bool no_display)
{
*save_curwin = curwin;
if (tp != NULL) {
@@ -6433,8 +6585,9 @@ int switch_win_noblock(win_T **save_curwin, tabpage_T **save_curtab,
curtab = tp;
firstwin = curtab->tp_firstwin;
lastwin = curtab->tp_lastwin;
- } else
- goto_tabpage_tp(tp, FALSE, FALSE);
+ } else {
+ goto_tabpage_tp(tp, false, false);
+ }
}
if (!win_valid(win)) {
return FAIL;
@@ -6454,8 +6607,7 @@ void restore_win(win_T *save_curwin, tabpage_T *save_curtab, bool no_display)
}
// As restore_win() but without unblocking autocommands.
-void restore_win_noblock(win_T *save_curwin, tabpage_T *save_curtab,
- bool no_display)
+void restore_win_noblock(win_T *save_curwin, tabpage_T *save_curtab, bool no_display)
{
if (save_curtab != NULL && valid_tabpage(save_curtab)) {
if (no_display) {
@@ -6464,8 +6616,9 @@ void restore_win_noblock(win_T *save_curwin, tabpage_T *save_curtab,
curtab = save_curtab;
firstwin = curtab->tp_firstwin;
lastwin = curtab->tp_lastwin;
- } else
- goto_tabpage_tp(save_curtab, FALSE, FALSE);
+ } else {
+ goto_tabpage_tp(save_curtab, false, false);
+ }
}
if (win_valid(save_curwin)) {
curwin = save_curwin;
@@ -6510,16 +6663,15 @@ void restore_buffer(bufref_T *save_curbuf)
/// particular ID is desired
/// @param[in] conceal_char pointer to conceal replacement char
/// @return ID of added match, -1 on failure.
-int match_add(win_T *wp, const char *const grp, const char *const pat,
- int prio, int id, list_T *pos_list,
- const char *const conceal_char)
+int match_add(win_T *wp, const char *const grp, const char *const pat, int prio, int id,
+ list_T *pos_list, const char *const conceal_char)
FUNC_ATTR_NONNULL_ARG(1, 2)
{
matchitem_T *cur;
matchitem_T *prev;
matchitem_T *m;
int hlg_id;
- regprog_T *regprog = NULL;
+ regprog_T *regprog = NULL;
int rtype = SOME_VALID;
if (*grp == NUL || (pat != NULL && *pat == NUL)) {
@@ -6541,8 +6693,7 @@ int match_add(win_T *wp, const char *const grp, const char *const pat,
cur = cur->next;
}
}
- if ((hlg_id = syn_name2id((const char_u *)grp)) == 0) {
- EMSG2(_(e_nogroup), grp);
+ if ((hlg_id = syn_check_group((const char_u *)grp, strlen(grp))) == 0) {
return -1;
}
if (pat != NULL && (regprog = vim_regcomp((char_u *)pat, RE_MAGIC)) == NULL) {
@@ -6553,10 +6704,12 @@ int match_add(win_T *wp, const char *const grp, const char *const pat,
// Find available match ID.
while (id == -1) {
cur = wp->w_match_head;
- while (cur != NULL && cur->id != wp->w_next_match_id)
+ while (cur != NULL && cur->id != wp->w_next_match_id) {
cur = cur->next;
- if (cur == NULL)
+ }
+ if (cur == NULL) {
id = wp->w_next_match_id;
+ }
wp->w_next_match_id++;
}
@@ -6648,8 +6801,8 @@ int match_add(win_T *wp, const char *const grp, const char *const pat,
}
});
- // Calculate top and bottom lines for redrawing area
- if (toplnum != 0){
+ // Calculate top and bottom lines for redrawing area
+ if (toplnum != 0) {
if (wp->w_buffer->b_mod_set) {
if (wp->w_buffer->b_mod_top > toplnum) {
wp->w_buffer->b_mod_top = toplnum;
@@ -6677,10 +6830,11 @@ int match_add(win_T *wp, const char *const grp, const char *const pat,
prev = cur;
cur = cur->next;
}
- if (cur == prev)
+ if (cur == prev) {
wp->w_match_head = m;
- else
+ } else {
prev->next = m;
+ }
m->next = cur;
redraw_later(wp, rtype);
@@ -6693,8 +6847,9 @@ fail:
/// Delete match with ID 'id' in the match list of window 'wp'.
-/// Print error messages if 'perr' is TRUE.
-int match_delete(win_T *wp, int id, int perr)
+///
+/// @param perr print error messages if true.
+int match_delete(win_T *wp, int id, bool perr)
{
matchitem_T *cur = wp->w_match_head;
matchitem_T *prev = cur;
@@ -6718,10 +6873,11 @@ int match_delete(win_T *wp, int id, int perr)
}
return -1;
}
- if (cur == prev)
+ if (cur == prev) {
wp->w_match_head = cur->next;
- else
+ } else {
prev->next = cur->next;
+ }
vim_regfree(cur->match.regprog);
xfree(cur->pattern);
if (cur->pos.toplnum != 0) {
@@ -6770,8 +6926,9 @@ matchitem_T *get_match(win_T *wp, int id)
{
matchitem_T *cur = wp->w_match_head;
- while (cur != NULL && cur->id != id)
+ while (cur != NULL && cur->id != id) {
cur = cur->next;
+ }
return cur;
}
@@ -6901,13 +7058,13 @@ void win_id2tabwin(typval_T *const argvars, typval_T *const rettv)
tv_list_append_number(list, winnr);
}
-win_T * win_id2wp(typval_T *argvars)
+win_T *win_id2wp(typval_T *argvars)
{
return win_id2wp_tp(argvars, NULL);
}
// Return the window and tab pointer of window "id".
-win_T * win_id2wp_tp(typval_T *argvars, tabpage_T **tpp)
+win_T *win_id2wp_tp(typval_T *argvars, tabpage_T **tpp)
{
int id = tv_get_number(&argvars[0]);
diff --git a/src/uncrustify.cfg b/src/uncrustify.cfg
new file mode 100644
index 0000000000..5d73e70ed0
--- /dev/null
+++ b/src/uncrustify.cfg
@@ -0,0 +1,3295 @@
+# Uncrustify-0.73.0-186-03faf73c
+
+#
+# General options
+#
+
+# The type of line endings.
+#
+# Default: auto
+newlines = auto # lf/crlf/cr/auto
+
+# The original size of tabs in the input.
+#
+# Default: 8
+input_tab_size = 8 # unsigned number
+
+# The size of tabs in the output (only used if align_with_tabs=true).
+#
+# Default: 8
+output_tab_size = 8 # unsigned number
+
+# The ASCII value of the string escape char, usually 92 (\) or (Pawn) 94 (^).
+#
+# Default: 92
+string_escape_char = 92 # unsigned number
+
+# Alternate string escape char (usually only used for Pawn).
+# Only works right before the quote char.
+string_escape_char2 = 0 # unsigned number
+
+# Replace tab characters found in string literals with the escape sequence \t
+# instead.
+string_replace_tab_chars = false # true/false
+
+# Allow interpreting '>=' and '>>=' as part of a template in code like
+# 'void f(list<list<B>>=val);'. If true, 'assert(x<0 && y>=3)' will be broken.
+# Improvements to template detection may make this option obsolete.
+tok_split_gte = false # true/false
+
+# Disable formatting of NL_CONT ('\\n') ended lines (e.g. multi-line macros).
+disable_processing_nl_cont = false # true/false
+
+# Specify the marker used in comments to disable processing of part of the
+# file.
+#
+# Default: *INDENT-OFF*
+disable_processing_cmt = "uncrustify:indent-off" # string
+
+# Specify the marker used in comments to (re)enable processing in a file.
+#
+# Default: *INDENT-ON*
+enable_processing_cmt = "uncrustify:indent-on" # string
+
+# Enable parsing of digraphs.
+enable_digraphs = false # true/false
+
+# Option to allow both disable_processing_cmt and enable_processing_cmt
+# strings, if specified, to be interpreted as ECMAScript regular expressions.
+# If true, a regex search will be performed within comments according to the
+# specified patterns in order to disable/enable processing.
+processing_cmt_as_regex = false # true/false
+
+# Add or remove the UTF-8 BOM (recommend 'remove').
+utf8_bom = remove # ignore/add/remove/force/not_defined
+
+# If the file contains bytes with values between 128 and 255, but is not
+# UTF-8, then output as UTF-8.
+utf8_byte = false # true/false
+
+# Force the output encoding to UTF-8.
+utf8_force = false # true/false
+
+#
+# Spacing options
+#
+
+# Add or remove space around non-assignment symbolic operators ('+', '/', '%',
+# '<<', and so forth).
+sp_arith = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space around arithmetic operators '+' and '-'.
+#
+# Overrides sp_arith.
+sp_arith_additive = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space around assignment operator '=', '+=', etc.
+sp_assign = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space around '=' in C++11 lambda capture specifications.
+#
+# Overrides sp_assign.
+sp_cpp_lambda_assign = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space after the capture specification of a C++11 lambda when
+# an argument list is present, as in '[] <here> (int x){ ... }'.
+sp_cpp_lambda_square_paren = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space after the capture specification of a C++11 lambda with
+# no argument list is present, as in '[] <here> { ... }'.
+sp_cpp_lambda_square_brace = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space after the opening parenthesis and before the closing
+# parenthesis of a argument list of a C++11 lambda, as in
+# '[]( <here> int x <here> ){ ... }'.
+sp_cpp_lambda_argument_list = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space after the argument list of a C++11 lambda, as in
+# '[](int x) <here> { ... }'.
+sp_cpp_lambda_paren_brace = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between a lambda body and its call operator of an
+# immediately invoked lambda, as in '[]( ... ){ ... } <here> ( ... )'.
+sp_cpp_lambda_fparen = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space around assignment operator '=' in a prototype.
+#
+# If set to ignore, use sp_assign.
+sp_assign_default = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space before assignment operator '=', '+=', etc.
+#
+# Overrides sp_assign.
+sp_before_assign = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space after assignment operator '=', '+=', etc.
+#
+# Overrides sp_assign.
+sp_after_assign = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space in 'NS_ENUM ('.
+sp_enum_paren = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space around assignment '=' in enum.
+sp_enum_assign = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space before assignment '=' in enum.
+#
+# Overrides sp_enum_assign.
+sp_enum_before_assign = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space after assignment '=' in enum.
+#
+# Overrides sp_enum_assign.
+sp_enum_after_assign = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space around assignment ':' in enum.
+sp_enum_colon = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space around preprocessor '##' concatenation operator.
+#
+# Default: add
+sp_pp_concat = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space after preprocessor '#' stringify operator.
+# Also affects the '#@' charizing operator.
+sp_pp_stringify = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space before preprocessor '#' stringify operator
+# as in '#define x(y) L#y'.
+sp_before_pp_stringify = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space around boolean operators '&&' and '||'.
+sp_bool = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space around compare operator '<', '>', '==', etc.
+sp_compare = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space inside '(' and ')'.
+sp_inside_paren = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between nested parentheses, i.e. '((' vs. ') )'.
+sp_paren_paren = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between back-to-back parentheses, i.e. ')(' vs. ') ('.
+sp_cparen_oparen = ignore # ignore/add/remove/force/not_defined
+
+# Whether to balance spaces inside nested parentheses.
+sp_balance_nested_parens = false # true/false
+
+# Add or remove space between ')' and '{'.
+sp_paren_brace = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between nested braces, i.e. '{{' vs. '{ {'.
+sp_brace_brace = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space before pointer star '*'.
+sp_before_ptr_star = force # ignore/add/remove/force/not_defined
+
+# Add or remove space before pointer star '*' that isn't followed by a
+# variable name. If set to ignore, sp_before_ptr_star is used instead.
+sp_before_unnamed_ptr_star = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between pointer stars '*', as in 'int ***a;'.
+sp_between_ptr_star = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space after pointer star '*', if followed by a word.
+#
+# Overrides sp_type_func.
+sp_after_ptr_star = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space after pointer caret '^', if followed by a word.
+sp_after_ptr_block_caret = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space after pointer star '*', if followed by a qualifier.
+sp_after_ptr_star_qualifier = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space after a pointer star '*', if followed by a function
+# prototype or function definition.
+#
+# Overrides sp_after_ptr_star and sp_type_func.
+sp_after_ptr_star_func = remove # ignore/add/remove/force/not_defined
+
+# Add or remove space after a pointer star '*' in the trailing return of a
+# function prototype or function definition.
+sp_after_ptr_star_trailing = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space after a pointer star '*', if followed by an open
+# parenthesis, as in 'void* (*)()'.
+sp_ptr_star_paren = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space before a pointer star '*', if followed by a function
+# prototype or function definition.
+sp_before_ptr_star_func = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space before a pointer star '*' in the trailing return of a
+# function prototype or function definition.
+sp_before_ptr_star_trailing = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space before a reference sign '&'.
+sp_before_byref = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space before a reference sign '&' that isn't followed by a
+# variable name. If set to ignore, sp_before_byref is used instead.
+sp_before_unnamed_byref = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space after reference sign '&', if followed by a word.
+#
+# Overrides sp_type_func.
+sp_after_byref = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space after a reference sign '&', if followed by a function
+# prototype or function definition.
+#
+# Overrides sp_after_byref and sp_type_func.
+sp_after_byref_func = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space before a reference sign '&', if followed by a function
+# prototype or function definition.
+sp_before_byref_func = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between type and word. In cases where total removal of
+# whitespace would be a syntax error, a value of 'remove' is treated the same
+# as 'force'.
+#
+# This also affects some other instances of space following a type that are
+# not covered by other options; for example, between the return type and
+# parenthesis of a function type template argument, between the type and
+# parenthesis of an array parameter, or between 'decltype(...)' and the
+# following word.
+#
+# Default: force
+sp_after_type = force # ignore/add/remove/force/not_defined
+
+# Add or remove space between 'decltype(...)' and word,
+# brace or function call.
+sp_after_decltype = ignore # ignore/add/remove/force/not_defined
+
+# (D) Add or remove space before the parenthesis in the D constructs
+# 'template Foo(' and 'class Foo('.
+sp_before_template_paren = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between 'template' and '<'.
+# If set to ignore, sp_before_angle is used.
+sp_template_angle = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space before '<'.
+sp_before_angle = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space inside '<' and '>'.
+sp_inside_angle = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space inside '<>'.
+sp_inside_angle_empty = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between '>' and ':'.
+sp_angle_colon = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space after '>'.
+sp_after_angle = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between '>' and '(' as found in 'new List<byte>(foo);'.
+sp_angle_paren = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between '>' and '()' as found in 'new List<byte>();'.
+sp_angle_paren_empty = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between '>' and a word as in 'List<byte> m;' or
+# 'template <typename T> static ...'.
+sp_angle_word = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between '>' and '>' in '>>' (template stuff).
+#
+# Default: add
+sp_angle_shift = ignore # ignore/add/remove/force/not_defined
+
+# (C++11) Permit removal of the space between '>>' in 'foo<bar<int> >'. Note
+# that sp_angle_shift cannot remove the space without this option.
+sp_permit_cpp11_shift = false # true/false
+
+# Add or remove space before '(' of control statements ('if', 'for', 'switch',
+# 'while', etc.).
+sp_before_sparen = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space inside '(' and ')' of control statements.
+sp_inside_sparen = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space after '(' of control statements.
+#
+# Overrides sp_inside_sparen.
+sp_inside_sparen_open = remove # ignore/add/remove/force/not_defined
+
+# Add or remove space before ')' of control statements.
+#
+# Overrides sp_inside_sparen.
+sp_inside_sparen_close = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between '((' or '))' of control statements.
+sp_sparen_paren = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space after ')' of control statements.
+sp_after_sparen = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between ')' and '{' of control statements.
+sp_sparen_brace = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between 'do' and '{'.
+sp_do_brace_open = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between '}' and 'while'.
+sp_brace_close_while = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between 'while' and '('. Overrides sp_before_sparen.
+sp_while_paren_open = ignore # ignore/add/remove/force/not_defined
+
+# (D) Add or remove space between 'invariant' and '('.
+sp_invariant_paren = ignore # ignore/add/remove/force/not_defined
+
+# (D) Add or remove space after the ')' in 'invariant (C) c'.
+sp_after_invariant_paren = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space before empty statement ';' on 'if', 'for' and 'while'.
+sp_special_semi = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space before ';'.
+#
+# Default: remove
+sp_before_semi = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space before ';' in non-empty 'for' statements.
+sp_before_semi_for = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space before a semicolon of an empty left part of a for
+# statement, as in 'for ( <here> ; ; )'.
+sp_before_semi_for_empty = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between the semicolons of an empty middle part of a for
+# statement, as in 'for ( ; <here> ; )'.
+sp_between_semi_for_empty = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space after ';', except when followed by a comment.
+#
+# Default: add
+sp_after_semi = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space after ';' in non-empty 'for' statements.
+#
+# Default: force
+sp_after_semi_for = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space after the final semicolon of an empty part of a for
+# statement, as in 'for ( ; ; <here> )'.
+sp_after_semi_for_empty = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space before '[' (except '[]').
+sp_before_square = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space before '[' for a variable definition.
+#
+# Default: remove
+sp_before_vardef_square = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space before '[' for asm block.
+sp_before_square_asm_block = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space before '[]'.
+sp_before_squares = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space before C++17 structured bindings.
+sp_cpp_before_struct_binding = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space inside a non-empty '[' and ']'.
+sp_inside_square = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space inside '[]'.
+sp_inside_square_empty = ignore # ignore/add/remove/force/not_defined
+
+# (OC) Add or remove space inside a non-empty Objective-C boxed array '@[' and
+# ']'. If set to ignore, sp_inside_square is used.
+sp_inside_square_oc_array = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space after ',', i.e. 'a,b' vs. 'a, b'.
+sp_after_comma = add # ignore/add/remove/force/not_defined
+
+# Add or remove space before ',', i.e. 'a,b' vs. 'a ,b'.
+#
+# Default: remove
+sp_before_comma = remove # ignore/add/remove/force/not_defined
+
+# (C#) Add or remove space between ',' and ']' in multidimensional array type
+# like 'int[,,]'.
+sp_after_mdatype_commas = ignore # ignore/add/remove/force/not_defined
+
+# (C#) Add or remove space between '[' and ',' in multidimensional array type
+# like 'int[,,]'.
+sp_before_mdatype_commas = ignore # ignore/add/remove/force/not_defined
+
+# (C#) Add or remove space between ',' in multidimensional array type
+# like 'int[,,]'.
+sp_between_mdatype_commas = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between an open parenthesis and comma,
+# i.e. '(,' vs. '( ,'.
+#
+# Default: force
+sp_paren_comma = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space after the variadic '...' when preceded by a
+# non-punctuator.
+# The value REMOVE will be overriden with FORCE
+sp_after_ellipsis = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space before the variadic '...' when preceded by a
+# non-punctuator.
+# The value REMOVE will be overriden with FORCE
+sp_before_ellipsis = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between a type and '...'.
+sp_type_ellipsis = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between a '*' and '...'.
+sp_ptr_type_ellipsis = ignore # ignore/add/remove/force/not_defined
+
+# (D) Add or remove space between a type and '?'.
+sp_type_question = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between ')' and '...'.
+sp_paren_ellipsis = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between '&&' and '...'.
+sp_byref_ellipsis = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between ')' and a qualifier such as 'const'.
+sp_paren_qualifier = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between ')' and 'noexcept'.
+sp_paren_noexcept = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space after class ':'.
+sp_after_class_colon = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space before class ':'.
+sp_before_class_colon = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space after class constructor ':'.
+sp_after_constr_colon = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space before class constructor ':'.
+sp_before_constr_colon = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space before case ':'.
+#
+# Default: remove
+sp_before_case_colon = remove # ignore/add/remove/force/not_defined
+
+# Add or remove space between 'operator' and operator sign.
+sp_after_operator = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between the operator symbol and the open parenthesis, as
+# in 'operator ++('.
+sp_after_operator_sym = ignore # ignore/add/remove/force/not_defined
+
+# Overrides sp_after_operator_sym when the operator has no arguments, as in
+# 'operator *()'.
+sp_after_operator_sym_empty = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space after C/D cast, i.e. 'cast(int)a' vs. 'cast(int) a' or
+# '(int)a' vs. '(int) a'.
+sp_after_cast = remove # ignore/add/remove/force/not_defined
+
+# Add or remove spaces inside cast parentheses.
+sp_inside_paren_cast = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between the type and open parenthesis in a C++ cast,
+# i.e. 'int(exp)' vs. 'int (exp)'.
+sp_cpp_cast_paren = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between 'sizeof' and '('.
+sp_sizeof_paren = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between 'sizeof' and '...'.
+sp_sizeof_ellipsis = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between 'sizeof...' and '('.
+sp_sizeof_ellipsis_paren = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between '...' and a parameter pack.
+sp_ellipsis_parameter_pack = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between a parameter pack and '...'.
+sp_parameter_pack_ellipsis = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between 'decltype' and '('.
+sp_decltype_paren = ignore # ignore/add/remove/force/not_defined
+
+# (Pawn) Add or remove space after the tag keyword.
+sp_after_tag = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space inside enum '{' and '}'.
+sp_inside_braces_enum = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space inside struct/union '{' and '}'.
+sp_inside_braces_struct = ignore # ignore/add/remove/force/not_defined
+
+# (OC) Add or remove space inside Objective-C boxed dictionary '{' and '}'
+sp_inside_braces_oc_dict = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space after open brace in an unnamed temporary
+# direct-list-initialization.
+sp_after_type_brace_init_lst_open = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space before close brace in an unnamed temporary
+# direct-list-initialization.
+sp_before_type_brace_init_lst_close = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space inside an unnamed temporary direct-list-initialization.
+sp_inside_type_brace_init_lst = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space inside '{' and '}'.
+sp_inside_braces = add # ignore/add/remove/force/not_defined
+
+# Add or remove space inside '{}'.
+sp_inside_braces_empty = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space around trailing return operator '->'.
+sp_trailing_return = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between return type and function name. A minimum of 1
+# is forced except for pointer return types.
+sp_type_func = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between type and open brace of an unnamed temporary
+# direct-list-initialization.
+sp_type_brace_init_lst = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between function name and '(' on function declaration.
+sp_func_proto_paren = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between function name and '()' on function declaration
+# without parameters.
+sp_func_proto_paren_empty = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between function name and '(' with a typedef specifier.
+sp_func_type_paren = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between alias name and '(' of a non-pointer function type typedef.
+sp_func_def_paren = remove # ignore/add/remove/force/not_defined
+
+# Add or remove space between function name and '()' on function definition
+# without parameters.
+sp_func_def_paren_empty = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space inside empty function '()'.
+# Overrides sp_after_angle unless use_sp_after_angle_always is set to true.
+sp_inside_fparens = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space inside function '(' and ')'.
+sp_inside_fparen = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space inside the first parentheses in a function type, as in
+# 'void (*x)(...)'.
+sp_inside_tparen = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between the ')' and '(' in a function type, as in
+# 'void (*x)(...)'.
+sp_after_tparen_close = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between ']' and '(' when part of a function call.
+sp_square_fparen = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between ')' and '{' of function.
+sp_fparen_brace = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between ')' and '{' of a function call in object
+# initialization.
+#
+# Overrides sp_fparen_brace.
+sp_fparen_brace_initializer = ignore # ignore/add/remove/force/not_defined
+
+# (Java) Add or remove space between ')' and '{{' of double brace initializer.
+sp_fparen_dbrace = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between function name and '(' on function calls.
+sp_func_call_paren = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between function name and '()' on function calls without
+# parameters. If set to ignore (the default), sp_func_call_paren is used.
+sp_func_call_paren_empty = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between the user function name and '(' on function
+# calls. You need to set a keyword to be a user function in the config file,
+# like:
+# set func_call_user tr _ i18n
+sp_func_call_user_paren = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space inside user function '(' and ')'.
+sp_func_call_user_inside_fparen = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between nested parentheses with user functions,
+# i.e. '((' vs. '( ('.
+sp_func_call_user_paren_paren = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between a constructor/destructor and the open
+# parenthesis.
+sp_func_class_paren = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between a constructor without parameters or destructor
+# and '()'.
+sp_func_class_paren_empty = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between 'return' and '('.
+sp_return_paren = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between 'return' and '{'.
+sp_return_brace = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between '__attribute__' and '('.
+sp_attribute_paren = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between 'defined' and '(' in '#if defined (FOO)'.
+sp_defined_paren = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between 'throw' and '(' in 'throw (something)'.
+sp_throw_paren = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between 'throw' and anything other than '(' as in
+# '@throw [...];'.
+sp_after_throw = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between 'catch' and '(' in 'catch (something) { }'.
+# If set to ignore, sp_before_sparen is used.
+sp_catch_paren = ignore # ignore/add/remove/force/not_defined
+
+# (OC) Add or remove space between '@catch' and '('
+# in '@catch (something) { }'. If set to ignore, sp_catch_paren is used.
+sp_oc_catch_paren = ignore # ignore/add/remove/force/not_defined
+
+# (OC) Add or remove space before Objective-C protocol list
+# as in '@protocol Protocol<here><Protocol_A>' or '@interface MyClass : NSObject<here><MyProtocol>'.
+sp_before_oc_proto_list = ignore # ignore/add/remove/force/not_defined
+
+# (OC) Add or remove space between class name and '('
+# in '@interface className(categoryName)<ProtocolName>:BaseClass'
+sp_oc_classname_paren = ignore # ignore/add/remove/force/not_defined
+
+# (D) Add or remove space between 'version' and '('
+# in 'version (something) { }'. If set to ignore, sp_before_sparen is used.
+sp_version_paren = ignore # ignore/add/remove/force/not_defined
+
+# (D) Add or remove space between 'scope' and '('
+# in 'scope (something) { }'. If set to ignore, sp_before_sparen is used.
+sp_scope_paren = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between 'super' and '(' in 'super (something)'.
+#
+# Default: remove
+sp_super_paren = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between 'this' and '(' in 'this (something)'.
+#
+# Default: remove
+sp_this_paren = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between a macro name and its definition.
+sp_macro = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between a macro function ')' and its definition.
+sp_macro_func = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between 'else' and '{' if on the same line.
+sp_else_brace = add # ignore/add/remove/force/not_defined
+
+# Add or remove space between '}' and 'else' if on the same line.
+sp_brace_else = add # ignore/add/remove/force/not_defined
+
+# Add or remove space between '}' and the name of a typedef on the same line.
+sp_brace_typedef = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space before the '{' of a 'catch' statement, if the '{' and
+# 'catch' are on the same line, as in 'catch (decl) <here> {'.
+sp_catch_brace = ignore # ignore/add/remove/force/not_defined
+
+# (OC) Add or remove space before the '{' of a '@catch' statement, if the '{'
+# and '@catch' are on the same line, as in '@catch (decl) <here> {'.
+# If set to ignore, sp_catch_brace is used.
+sp_oc_catch_brace = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between '}' and 'catch' if on the same line.
+sp_brace_catch = ignore # ignore/add/remove/force/not_defined
+
+# (OC) Add or remove space between '}' and '@catch' if on the same line.
+# If set to ignore, sp_brace_catch is used.
+sp_oc_brace_catch = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between 'finally' and '{' if on the same line.
+sp_finally_brace = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between '}' and 'finally' if on the same line.
+sp_brace_finally = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between 'try' and '{' if on the same line.
+sp_try_brace = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between get/set and '{' if on the same line.
+sp_getset_brace = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between a variable and '{' for C++ uniform
+# initialization.
+sp_word_brace_init_lst = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between a variable and '{' for a namespace.
+#
+# Default: add
+sp_word_brace_ns = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space before the '::' operator.
+sp_before_dc = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space after the '::' operator.
+sp_after_dc = ignore # ignore/add/remove/force/not_defined
+
+# (D) Add or remove around the D named array initializer ':' operator.
+sp_d_array_colon = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space after the '!' (not) unary operator.
+#
+# Default: remove
+sp_not = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space after the '~' (invert) unary operator.
+#
+# Default: remove
+sp_inv = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space after the '&' (address-of) unary operator. This does not
+# affect the spacing after a '&' that is part of a type.
+#
+# Default: remove
+sp_addr = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space around the '.' or '->' operators.
+#
+# Default: remove
+sp_member = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space after the '*' (dereference) unary operator. This does
+# not affect the spacing after a '*' that is part of a type.
+#
+# Default: remove
+sp_deref = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space after '+' or '-', as in 'x = -5' or 'y = +7'.
+#
+# Default: remove
+sp_sign = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between '++' and '--' the word to which it is being
+# applied, as in '(--x)' or 'y++;'.
+#
+# Default: remove
+sp_incdec = remove # ignore/add/remove/force/not_defined
+
+# Add or remove space before a backslash-newline at the end of a line.
+#
+# Default: add
+sp_before_nl_cont = ignore # ignore/add/remove/force/not_defined
+
+# (OC) Add or remove space after the scope '+' or '-', as in '-(void) foo;'
+# or '+(int) bar;'.
+sp_after_oc_scope = ignore # ignore/add/remove/force/not_defined
+
+# (OC) Add or remove space after the colon in message specs,
+# i.e. '-(int) f:(int) x;' vs. '-(int) f: (int) x;'.
+sp_after_oc_colon = ignore # ignore/add/remove/force/not_defined
+
+# (OC) Add or remove space before the colon in message specs,
+# i.e. '-(int) f: (int) x;' vs. '-(int) f : (int) x;'.
+sp_before_oc_colon = ignore # ignore/add/remove/force/not_defined
+
+# (OC) Add or remove space after the colon in immutable dictionary expression
+# 'NSDictionary *test = @{@"foo" :@"bar"};'.
+sp_after_oc_dict_colon = ignore # ignore/add/remove/force/not_defined
+
+# (OC) Add or remove space before the colon in immutable dictionary expression
+# 'NSDictionary *test = @{@"foo" :@"bar"};'.
+sp_before_oc_dict_colon = ignore # ignore/add/remove/force/not_defined
+
+# (OC) Add or remove space after the colon in message specs,
+# i.e. '[object setValue:1];' vs. '[object setValue: 1];'.
+sp_after_send_oc_colon = ignore # ignore/add/remove/force/not_defined
+
+# (OC) Add or remove space before the colon in message specs,
+# i.e. '[object setValue:1];' vs. '[object setValue :1];'.
+sp_before_send_oc_colon = ignore # ignore/add/remove/force/not_defined
+
+# (OC) Add or remove space after the (type) in message specs,
+# i.e. '-(int)f: (int) x;' vs. '-(int)f: (int)x;'.
+sp_after_oc_type = ignore # ignore/add/remove/force/not_defined
+
+# (OC) Add or remove space after the first (type) in message specs,
+# i.e. '-(int) f:(int)x;' vs. '-(int)f:(int)x;'.
+sp_after_oc_return_type = ignore # ignore/add/remove/force/not_defined
+
+# (OC) Add or remove space between '@selector' and '(',
+# i.e. '@selector(msgName)' vs. '@selector (msgName)'.
+# Also applies to '@protocol()' constructs.
+sp_after_oc_at_sel = ignore # ignore/add/remove/force/not_defined
+
+# (OC) Add or remove space between '@selector(x)' and the following word,
+# i.e. '@selector(foo) a:' vs. '@selector(foo)a:'.
+sp_after_oc_at_sel_parens = ignore # ignore/add/remove/force/not_defined
+
+# (OC) Add or remove space inside '@selector' parentheses,
+# i.e. '@selector(foo)' vs. '@selector( foo )'.
+# Also applies to '@protocol()' constructs.
+sp_inside_oc_at_sel_parens = ignore # ignore/add/remove/force/not_defined
+
+# (OC) Add or remove space before a block pointer caret,
+# i.e. '^int (int arg){...}' vs. ' ^int (int arg){...}'.
+sp_before_oc_block_caret = ignore # ignore/add/remove/force/not_defined
+
+# (OC) Add or remove space after a block pointer caret,
+# i.e. '^int (int arg){...}' vs. '^ int (int arg){...}'.
+sp_after_oc_block_caret = ignore # ignore/add/remove/force/not_defined
+
+# (OC) Add or remove space between the receiver and selector in a message,
+# as in '[receiver selector ...]'.
+sp_after_oc_msg_receiver = ignore # ignore/add/remove/force/not_defined
+
+# (OC) Add or remove space after '@property'.
+sp_after_oc_property = ignore # ignore/add/remove/force/not_defined
+
+# (OC) Add or remove space between '@synchronized' and the open parenthesis,
+# i.e. '@synchronized(foo)' vs. '@synchronized (foo)'.
+sp_after_oc_synchronized = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space around the ':' in 'b ? t : f'.
+sp_cond_colon = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space before the ':' in 'b ? t : f'.
+#
+# Overrides sp_cond_colon.
+sp_cond_colon_before = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space after the ':' in 'b ? t : f'.
+#
+# Overrides sp_cond_colon.
+sp_cond_colon_after = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space around the '?' in 'b ? t : f'.
+sp_cond_question = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space before the '?' in 'b ? t : f'.
+#
+# Overrides sp_cond_question.
+sp_cond_question_before = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space after the '?' in 'b ? t : f'.
+#
+# Overrides sp_cond_question.
+sp_cond_question_after = ignore # ignore/add/remove/force/not_defined
+
+# In the abbreviated ternary form '(a ?: b)', add or remove space between '?'
+# and ':'.
+#
+# Overrides all other sp_cond_* options.
+sp_cond_ternary_short = ignore # ignore/add/remove/force/not_defined
+
+# Fix the spacing between 'case' and the label. Only 'ignore' and 'force' make
+# sense here.
+sp_case_label = ignore # ignore/add/remove/force/not_defined
+
+# (D) Add or remove space around the D '..' operator.
+sp_range = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space after ':' in a Java/C++11 range-based 'for',
+# as in 'for (Type var : <here> expr)'.
+sp_after_for_colon = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space before ':' in a Java/C++11 range-based 'for',
+# as in 'for (Type var <here> : expr)'.
+sp_before_for_colon = ignore # ignore/add/remove/force/not_defined
+
+# (D) Add or remove space between 'extern' and '(' as in 'extern <here> (C)'.
+sp_extern_paren = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space after the opening of a C++ comment, as in '// <here> A'.
+sp_cmt_cpp_start = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space in a C++ region marker comment, as in '// <here> BEGIN'.
+# A region marker is defined as a comment which is not preceded by other text
+# (i.e. the comment is the first non-whitespace on the line), and which starts
+# with either 'BEGIN' or 'END'.
+#
+# Overrides sp_cmt_cpp_start.
+sp_cmt_cpp_region = ignore # ignore/add/remove/force/not_defined
+
+# If true, space added with sp_cmt_cpp_start will be added after Doxygen
+# sequences like '///', '///<', '//!' and '//!<'.
+sp_cmt_cpp_doxygen = false # true/false
+
+# If true, space added with sp_cmt_cpp_start will be added after Qt translator
+# or meta-data comments like '//:', '//=', and '//~'.
+sp_cmt_cpp_qttr = false # true/false
+
+# Add or remove space between #else or #endif and a trailing comment.
+sp_endif_cmt = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space after 'new', 'delete' and 'delete[]'.
+sp_after_new = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between 'new' and '(' in 'new()'.
+sp_between_new_paren = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space between ')' and type in 'new(foo) BAR'.
+sp_after_newop_paren = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space inside parenthesis of the new operator
+# as in 'new(foo) BAR'.
+sp_inside_newop_paren = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space after the open parenthesis of the new operator,
+# as in 'new(foo) BAR'.
+#
+# Overrides sp_inside_newop_paren.
+sp_inside_newop_paren_open = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space before the close parenthesis of the new operator,
+# as in 'new(foo) BAR'.
+#
+# Overrides sp_inside_newop_paren.
+sp_inside_newop_paren_close = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space before a trailing or embedded comment.
+sp_before_tr_emb_cmt = add # ignore/add/remove/force/not_defined
+
+# Number of spaces before a trailing or embedded comment.
+sp_num_before_tr_emb_cmt = 2 # unsigned number
+
+# (Java) Add or remove space between an annotation and the open parenthesis.
+sp_annotation_paren = ignore # ignore/add/remove/force/not_defined
+
+# If true, vbrace tokens are dropped to the previous token and skipped.
+sp_skip_vbrace_tokens = false # true/false
+
+# Add or remove space after 'noexcept'.
+sp_after_noexcept = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove space after '_'.
+sp_vala_after_translation = ignore # ignore/add/remove/force/not_defined
+
+# If true, a <TAB> is inserted after #define.
+force_tab_after_define = false # true/false
+
+#
+# Indenting options
+#
+
+# The number of columns to indent per level. Usually 2, 3, 4, or 8.
+#
+# Default: 8
+indent_columns = 2 # unsigned number
+
+# The continuation indent. If non-zero, this overrides the indent of '(', '['
+# and '=' continuation indents. Negative values are OK; negative value is
+# absolute and not increased for each '(' or '[' level.
+#
+# For FreeBSD, this is set to 4.
+indent_continue = 0 # number
+
+# The continuation indent, only for class header line(s). If non-zero, this
+# overrides the indent of 'class' continuation indents.
+indent_continue_class_head = 0 # unsigned number
+
+# Whether to indent empty lines (i.e. lines which contain only spaces before
+# the newline character).
+indent_single_newlines = false # true/false
+
+# The continuation indent for func_*_param if they are true. If non-zero, this
+# overrides the indent.
+indent_param = 0 # unsigned number
+
+# How to use tabs when indenting code.
+#
+# 0: Spaces only
+# 1: Indent with tabs to brace level, align with spaces (default)
+# 2: Indent and align with tabs, using spaces when not on a tabstop
+#
+# Default: 1
+indent_with_tabs = 0 # unsigned number
+
+# Whether to indent comments that are not at a brace level with tabs on a
+# tabstop. Requires indent_with_tabs=2. If false, will use spaces.
+indent_cmt_with_tabs = false # true/false
+
+# Whether to indent strings broken by '\' so that they line up.
+indent_align_string = false # true/false
+
+# The number of spaces to indent multi-line XML strings.
+# Requires indent_align_string=true.
+indent_xml_string = 0 # unsigned number
+
+# Spaces to indent '{' from level.
+indent_brace = 0 # unsigned number
+
+# Whether braces are indented to the body level.
+indent_braces = false # true/false
+
+# Whether to disable indenting function braces if indent_braces=true.
+indent_braces_no_func = false # true/false
+
+# Whether to disable indenting class braces if indent_braces=true.
+indent_braces_no_class = false # true/false
+
+# Whether to disable indenting struct braces if indent_braces=true.
+indent_braces_no_struct = false # true/false
+
+# Whether to indent based on the size of the brace parent,
+# i.e. 'if' => 3 spaces, 'for' => 4 spaces, etc.
+indent_brace_parent = false # true/false
+
+# Whether to indent based on the open parenthesis instead of the open brace
+# in '({\n'.
+indent_paren_open_brace = false # true/false
+
+# (C#) Whether to indent the brace of a C# delegate by another level.
+indent_cs_delegate_brace = false # true/false
+
+# (C#) Whether to indent a C# delegate (to handle delegates with no brace) by
+# another level.
+indent_cs_delegate_body = false # true/false
+
+# Whether to indent the body of a 'namespace'.
+indent_namespace = false # true/false
+
+# Whether to indent only the first namespace, and not any nested namespaces.
+# Requires indent_namespace=true.
+indent_namespace_single_indent = false # true/false
+
+# The number of spaces to indent a namespace block.
+# If set to zero, use the value indent_columns
+indent_namespace_level = 0 # unsigned number
+
+# If the body of the namespace is longer than this number, it won't be
+# indented. Requires indent_namespace=true. 0 means no limit.
+indent_namespace_limit = 0 # unsigned number
+
+# Whether the 'extern "C"' body is indented.
+indent_extern = false # true/false
+
+# Whether the 'class' body is indented.
+indent_class = false # true/false
+
+# Additional indent before the leading base class colon.
+# Negative values decrease indent down to the first column.
+# Requires a newline break before colon (see pos_class_colon
+# and nl_class_colon)
+indent_before_class_colon = 0 # number
+
+# Whether to indent the stuff after a leading base class colon.
+indent_class_colon = false # true/false
+
+# Whether to indent based on a class colon instead of the stuff after the
+# colon. Requires indent_class_colon=true.
+indent_class_on_colon = false # true/false
+
+# Whether to indent the stuff after a leading class initializer colon.
+indent_constr_colon = false # true/false
+
+# Virtual indent from the ':' for member initializers.
+#
+# Default: 2
+indent_ctor_init_leading = 2 # unsigned number
+
+# Additional indent for constructor initializer list.
+# Negative values decrease indent down to the first column.
+indent_ctor_init = 0 # number
+
+# Whether to indent 'if' following 'else' as a new block under the 'else'.
+# If false, 'else\nif' is treated as 'else if' for indenting purposes.
+indent_else_if = false # true/false
+
+# Amount to indent variable declarations after a open brace.
+#
+# <0: Relative
+# >=0: Absolute
+indent_var_def_blk = 0 # number
+
+# Whether to indent continued variable declarations instead of aligning.
+indent_var_def_cont = false # true/false
+
+# Whether to indent continued shift expressions ('<<' and '>>') instead of
+# aligning. Set align_left_shift=false when enabling this.
+indent_shift = false # true/false
+
+# Whether to force indentation of function definitions to start in column 1.
+indent_func_def_force_col1 = false # true/false
+
+# Whether to indent continued function call parameters one indent level,
+# rather than aligning parameters under the open parenthesis.
+indent_func_call_param = false # true/false
+
+# Whether to indent continued function definition parameters one indent level,
+# rather than aligning parameters under the open parenthesis.
+indent_func_def_param = false # true/false
+
+# for function definitions, only if indent_func_def_param is false
+# Allows to align params when appropriate and indent them when not
+# behave as if it was true if paren position is more than this value
+# if paren position is more than the option value
+indent_func_def_param_paren_pos_threshold = 0 # unsigned number
+
+# Whether to indent continued function call prototype one indent level,
+# rather than aligning parameters under the open parenthesis.
+indent_func_proto_param = false # true/false
+
+# Whether to indent continued function call declaration one indent level,
+# rather than aligning parameters under the open parenthesis.
+indent_func_class_param = false # true/false
+
+# Whether to indent continued class variable constructors one indent level,
+# rather than aligning parameters under the open parenthesis.
+indent_func_ctor_var_param = false # true/false
+
+# Whether to indent continued template parameter list one indent level,
+# rather than aligning parameters under the open parenthesis.
+indent_template_param = false # true/false
+
+# Double the indent for indent_func_xxx_param options.
+# Use both values of the options indent_columns and indent_param.
+indent_func_param_double = false # true/false
+
+# Indentation column for standalone 'const' qualifier on a function
+# prototype.
+indent_func_const = 0 # unsigned number
+
+# Indentation column for standalone 'throw' qualifier on a function
+# prototype.
+indent_func_throw = 0 # unsigned number
+
+# How to indent within a macro followed by a brace on the same line
+# This allows reducing the indent in macros that have (for example)
+# `do { ... } while (0)` blocks bracketing them.
+#
+# true: add an indent for the brace on the same line as the macro
+# false: do not add an indent for the brace on the same line as the macro
+#
+# Default: true
+indent_macro_brace = false # true/false
+
+# The number of spaces to indent a continued '->' or '.'.
+# Usually set to 0, 1, or indent_columns.
+indent_member = 0 # unsigned number
+
+# Whether lines broken at '.' or '->' should be indented by a single indent.
+# The indent_member option will not be effective if this is set to true.
+indent_member_single = false # true/false
+
+# Spaces to indent single line ('//') comments on lines before code.
+indent_single_line_comments_before = 0 # unsigned number
+
+# Spaces to indent single line ('//') comments on lines after code.
+indent_single_line_comments_after = 0 # unsigned number
+
+# When opening a paren for a control statement (if, for, while, etc), increase
+# the indent level by this value. Negative values decrease the indent level.
+indent_sparen_extra = 0 # number
+
+# Whether to indent trailing single line ('//') comments relative to the code
+# instead of trying to keep the same absolute column.
+indent_relative_single_line_comments = true # true/false
+
+# Spaces to indent 'case' from 'switch'. Usually 0 or indent_columns.
+# It might wise to choose the same value for the option indent_case_brace.
+indent_switch_case = 0 # unsigned number
+
+# Spaces to indent '{' from 'case'. By default, the brace will appear under
+# the 'c' in case. Usually set to 0 or indent_columns. Negative values are OK.
+# It might wise to choose the same value for the option indent_switch_case.
+indent_case_brace = 0 # number
+
+# indent 'break' with 'case' from 'switch'.
+indent_switch_break_with_case = false # true/false
+
+# Whether to indent preprocessor statements inside of switch statements.
+#
+# Default: true
+indent_switch_pp = true # true/false
+
+# Spaces to shift the 'case' line, without affecting any other lines.
+# Usually 0.
+indent_case_shift = 0 # unsigned number
+
+# Whether to indent comments found in first column.
+indent_col1_comment = false # true/false
+
+# Whether to indent multi string literal in first column.
+indent_col1_multi_string_literal = false # true/false
+
+# How to indent goto labels.
+#
+# >0: Absolute column where 1 is the leftmost column
+# <=0: Subtract from brace indent
+#
+# Default: 1
+indent_label = 1 # number
+
+# How to indent access specifiers that are followed by a
+# colon.
+#
+# >0: Absolute column where 1 is the leftmost column
+# <=0: Subtract from brace indent
+#
+# Default: 1
+indent_access_spec = 1 # number
+
+# Whether to indent the code after an access specifier by one level.
+# If true, this option forces 'indent_access_spec=0'.
+indent_access_spec_body = false # true/false
+
+# If an open parenthesis is followed by a newline, whether to indent the next
+# line so that it lines up after the open parenthesis (not recommended).
+indent_paren_nl = false # true/false
+
+# How to indent a close parenthesis after a newline.
+#
+# 0: Indent to body level (default)
+# 1: Align under the open parenthesis
+# 2: Indent to the brace level
+indent_paren_close = 0 # unsigned number
+
+# Whether to indent the open parenthesis of a function definition,
+# if the parenthesis is on its own line.
+indent_paren_after_func_def = false # true/false
+
+# Whether to indent the open parenthesis of a function declaration,
+# if the parenthesis is on its own line.
+indent_paren_after_func_decl = false # true/false
+
+# Whether to indent the open parenthesis of a function call,
+# if the parenthesis is on its own line.
+indent_paren_after_func_call = true # true/false
+
+# Whether to indent a comma when inside a brace.
+# If true, aligns under the open brace.
+indent_comma_brace = false # true/false
+
+# Whether to indent a comma when inside a parenthesis.
+# If true, aligns under the open parenthesis.
+indent_comma_paren = false # true/false
+
+# Whether to indent a Boolean operator when inside a parenthesis.
+# If true, aligns under the open parenthesis.
+indent_bool_paren = false # true/false
+
+# Whether to indent a semicolon when inside a for parenthesis.
+# If true, aligns under the open for parenthesis.
+indent_semicolon_for_paren = false # true/false
+
+# Whether to align the first expression to following ones
+# if indent_bool_paren=true.
+indent_first_bool_expr = false # true/false
+
+# Whether to align the first expression to following ones
+# if indent_semicolon_for_paren=true.
+indent_first_for_expr = false # true/false
+
+# If an open square is followed by a newline, whether to indent the next line
+# so that it lines up after the open square (not recommended).
+indent_square_nl = false # true/false
+
+# (ESQL/C) Whether to preserve the relative indent of 'EXEC SQL' bodies.
+indent_preserve_sql = false # true/false
+
+# Whether to align continued statements at the '='. If false or if the '=' is
+# followed by a newline, the next line is indent one tab.
+#
+# Default: true
+indent_align_assign = true # true/false
+
+# If true, the indentation of the chunks after a '=' sequence will be set at
+# LHS token indentation column before '='.
+indent_off_after_assign = false # true/false
+
+# Whether to align continued statements at the '('. If false or the '(' is
+# followed by a newline, the next line indent is one tab.
+#
+# Default: true
+indent_align_paren = true # true/false
+
+# (OC) Whether to indent Objective-C code inside message selectors.
+indent_oc_inside_msg_sel = false # true/false
+
+# (OC) Whether to indent Objective-C blocks at brace level instead of usual
+# rules.
+indent_oc_block = false # true/false
+
+# (OC) Indent for Objective-C blocks in a message relative to the parameter
+# name.
+#
+# =0: Use indent_oc_block rules
+# >0: Use specified number of spaces to indent
+indent_oc_block_msg = 0 # unsigned number
+
+# (OC) Minimum indent for subsequent parameters
+indent_oc_msg_colon = 0 # unsigned number
+
+# (OC) Whether to prioritize aligning with initial colon (and stripping spaces
+# from lines, if necessary).
+#
+# Default: true
+indent_oc_msg_prioritize_first_colon = true # true/false
+
+# (OC) Whether to indent blocks the way that Xcode does by default
+# (from the keyword if the parameter is on its own line; otherwise, from the
+# previous indentation level). Requires indent_oc_block_msg=true.
+indent_oc_block_msg_xcode_style = false # true/false
+
+# (OC) Whether to indent blocks from where the brace is, relative to a
+# message keyword. Requires indent_oc_block_msg=true.
+indent_oc_block_msg_from_keyword = false # true/false
+
+# (OC) Whether to indent blocks from where the brace is, relative to a message
+# colon. Requires indent_oc_block_msg=true.
+indent_oc_block_msg_from_colon = false # true/false
+
+# (OC) Whether to indent blocks from where the block caret is.
+# Requires indent_oc_block_msg=true.
+indent_oc_block_msg_from_caret = false # true/false
+
+# (OC) Whether to indent blocks from where the brace caret is.
+# Requires indent_oc_block_msg=true.
+indent_oc_block_msg_from_brace = false # true/false
+
+# When indenting after virtual brace open and newline add further spaces to
+# reach this minimum indent.
+indent_min_vbrace_open = 0 # unsigned number
+
+# Whether to add further spaces after regular indent to reach next tabstop
+# when indenting after virtual brace open and newline.
+indent_vbrace_open_on_tabstop = false # true/false
+
+# How to indent after a brace followed by another token (not a newline).
+# true: indent all contained lines to match the token
+# false: indent all contained lines to match the brace
+#
+# Default: true
+indent_token_after_brace = true # true/false
+
+# Whether to indent the body of a C++11 lambda.
+indent_cpp_lambda_body = false # true/false
+
+# How to indent compound literals that are being returned.
+# true: add both the indent from return & the compound literal open brace
+# (i.e. 2 indent levels)
+# false: only indent 1 level, don't add the indent for the open brace, only
+# add the indent for the return.
+#
+# Default: true
+indent_compound_literal_return = false # true/false
+
+# (C#) Whether to indent a 'using' block if no braces are used.
+#
+# Default: true
+indent_using_block = true # true/false
+
+# How to indent the continuation of ternary operator.
+#
+# 0: Off (default)
+# 1: When the `if_false` is a continuation, indent it under `if_false`
+# 2: When the `:` is a continuation, indent it under `?`
+indent_ternary_operator = 2 # unsigned number
+
+# Whether to indent the statements inside ternary operator.
+indent_inside_ternary_operator = false # true/false
+
+# If true, the indentation of the chunks after a `return` sequence will be set at return indentation column.
+indent_off_after_return = false # true/false
+
+# If true, the indentation of the chunks after a `return new` sequence will be set at return indentation column.
+indent_off_after_return_new = false # true/false
+
+# If true, the tokens after return are indented with regular single indentation. By default (false) the indentation is after the return token.
+indent_single_after_return = false # true/false
+
+# Whether to ignore indent and alignment for 'asm' blocks (i.e. assume they
+# have their own indentation).
+indent_ignore_asm_block = false # true/false
+
+# Don't indent the close parenthesis of a function definition,
+# if the parenthesis is on its own line.
+donot_indent_func_def_close_paren = false # true/false
+
+#
+# Newline adding and removing options
+#
+
+# Whether to collapse empty blocks between '{' and '}'.
+# If true, overrides nl_inside_empty_func
+nl_collapse_empty_body = false # true/false
+
+# Don't split one-line braced assignments, as in 'foo_t f = { 1, 2 };'.
+nl_assign_leave_one_liners = false # true/false
+
+# Don't split one-line braced statements inside a 'class xx { }' body.
+nl_class_leave_one_liners = false # true/false
+
+# Don't split one-line enums, as in 'enum foo { BAR = 15 };'
+nl_enum_leave_one_liners = false # true/false
+
+# Don't split one-line get or set functions.
+nl_getset_leave_one_liners = false # true/false
+
+# (C#) Don't split one-line property get or set functions.
+nl_cs_property_leave_one_liners = false # true/false
+
+# Don't split one-line function definitions, as in 'int foo() { return 0; }'.
+# might modify nl_func_type_name
+nl_func_leave_one_liners = false # true/false
+
+# Don't split one-line C++11 lambdas, as in '[]() { return 0; }'.
+nl_cpp_lambda_leave_one_liners = false # true/false
+
+# Don't split one-line if/else statements, as in 'if(...) b++;'.
+nl_if_leave_one_liners = false # true/false
+
+# Don't split one-line while statements, as in 'while(...) b++;'.
+nl_while_leave_one_liners = false # true/false
+
+# Don't split one-line do statements, as in 'do { b++; } while(...);'.
+nl_do_leave_one_liners = false # true/false
+
+# Don't split one-line for statements, as in 'for(...) b++;'.
+nl_for_leave_one_liners = false # true/false
+
+# (OC) Don't split one-line Objective-C messages.
+nl_oc_msg_leave_one_liner = false # true/false
+
+# (OC) Add or remove newline between method declaration and '{'.
+nl_oc_mdef_brace = ignore # ignore/add/remove/force/not_defined
+
+# (OC) Add or remove newline between Objective-C block signature and '{'.
+nl_oc_block_brace = ignore # ignore/add/remove/force/not_defined
+
+# (OC) Add or remove blank line before '@interface' statement.
+nl_oc_before_interface = ignore # ignore/add/remove/force/not_defined
+
+# (OC) Add or remove blank line before '@implementation' statement.
+nl_oc_before_implementation = ignore # ignore/add/remove/force/not_defined
+
+# (OC) Add or remove blank line before '@end' statement.
+nl_oc_before_end = ignore # ignore/add/remove/force/not_defined
+
+# (OC) Add or remove newline between '@interface' and '{'.
+nl_oc_interface_brace = ignore # ignore/add/remove/force/not_defined
+
+# (OC) Add or remove newline between '@implementation' and '{'.
+nl_oc_implementation_brace = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newlines at the start of the file.
+nl_start_of_file = ignore # ignore/add/remove/force/not_defined
+
+# The minimum number of newlines at the start of the file (only used if
+# nl_start_of_file is 'add' or 'force').
+nl_start_of_file_min = 0 # unsigned number
+
+# Add or remove newline at the end of the file.
+nl_end_of_file = ignore # ignore/add/remove/force/not_defined
+
+# The minimum number of newlines at the end of the file (only used if
+# nl_end_of_file is 'add' or 'force').
+nl_end_of_file_min = 0 # unsigned number
+
+# Add or remove newline between '=' and '{'.
+nl_assign_brace = ignore # ignore/add/remove/force/not_defined
+
+# (D) Add or remove newline between '=' and '['.
+nl_assign_square = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline between '[]' and '{'.
+nl_tsquare_brace = ignore # ignore/add/remove/force/not_defined
+
+# (D) Add or remove newline after '= ['. Will also affect the newline before
+# the ']'.
+nl_after_square_assign = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline between a function call's ')' and '{', as in
+# 'list_for_each(item, &list) { }'.
+nl_fcall_brace = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline between 'enum' and '{'.
+nl_enum_brace = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline between 'enum' and 'class'.
+nl_enum_class = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline between 'enum class' and the identifier.
+nl_enum_class_identifier = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline between 'enum class' type and ':'.
+nl_enum_identifier_colon = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline between 'enum class identifier :' and type.
+nl_enum_colon_type = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline between 'struct and '{'.
+nl_struct_brace = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline between 'union' and '{'.
+nl_union_brace = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline between 'if' and '{'.
+nl_if_brace = remove # ignore/add/remove/force/not_defined
+
+# Add or remove newline between '}' and 'else'.
+nl_brace_else = remove # ignore/add/remove/force/not_defined
+
+# Add or remove newline between 'else if' and '{'. If set to ignore,
+# nl_if_brace is used instead.
+nl_elseif_brace = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline between 'else' and '{'.
+nl_else_brace = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline between 'else' and 'if'.
+nl_else_if = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline before '{' opening brace
+nl_before_opening_brace_func_class_def = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline before 'if'/'else if' closing parenthesis.
+nl_before_if_closing_paren = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline between '}' and 'finally'.
+nl_brace_finally = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline between 'finally' and '{'.
+nl_finally_brace = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline between 'try' and '{'.
+nl_try_brace = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline between get/set and '{'.
+nl_getset_brace = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline between 'for' and '{'.
+nl_for_brace = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline before the '{' of a 'catch' statement, as in
+# 'catch (decl) <here> {'.
+nl_catch_brace = ignore # ignore/add/remove/force/not_defined
+
+# (OC) Add or remove newline before the '{' of a '@catch' statement, as in
+# '@catch (decl) <here> {'. If set to ignore, nl_catch_brace is used.
+nl_oc_catch_brace = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline between '}' and 'catch'.
+nl_brace_catch = ignore # ignore/add/remove/force/not_defined
+
+# (OC) Add or remove newline between '}' and '@catch'. If set to ignore,
+# nl_brace_catch is used.
+nl_oc_brace_catch = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline between '}' and ']'.
+nl_brace_square = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline between '}' and ')' in a function invocation.
+nl_brace_fparen = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline between 'while' and '{'.
+nl_while_brace = ignore # ignore/add/remove/force/not_defined
+
+# (D) Add or remove newline between 'scope (x)' and '{'.
+nl_scope_brace = ignore # ignore/add/remove/force/not_defined
+
+# (D) Add or remove newline between 'unittest' and '{'.
+nl_unittest_brace = ignore # ignore/add/remove/force/not_defined
+
+# (D) Add or remove newline between 'version (x)' and '{'.
+nl_version_brace = ignore # ignore/add/remove/force/not_defined
+
+# (C#) Add or remove newline between 'using' and '{'.
+nl_using_brace = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline between two open or close braces. Due to general
+# newline/brace handling, REMOVE may not work.
+nl_brace_brace = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline between 'do' and '{'.
+nl_do_brace = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline between '}' and 'while' of 'do' statement.
+nl_brace_while = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline between 'switch' and '{'.
+nl_switch_brace = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline between 'synchronized' and '{'.
+nl_synchronized_brace = ignore # ignore/add/remove/force/not_defined
+
+# Add a newline between ')' and '{' if the ')' is on a different line than the
+# if/for/etc.
+#
+# Overrides nl_for_brace, nl_if_brace, nl_switch_brace, nl_while_switch and
+# nl_catch_brace.
+nl_multi_line_cond = false # true/false
+
+# Add a newline after '(' if an if/for/while/switch condition spans multiple
+# lines
+nl_multi_line_sparen_open = ignore # ignore/add/remove/force/not_defined
+
+# Add a newline before ')' if an if/for/while/switch condition spans multiple
+# lines. Overrides nl_before_if_closing_paren if both are specified.
+nl_multi_line_sparen_close = remove # ignore/add/remove/force/not_defined
+
+# Force a newline in a define after the macro name for multi-line defines.
+nl_multi_line_define = false # true/false
+
+# Whether to add a newline before 'case', and a blank line before a 'case'
+# statement that follows a ';' or '}'.
+nl_before_case = false # true/false
+
+# Whether to add a newline after a 'case' statement.
+nl_after_case = true # true/false
+
+# Add or remove newline between a case ':' and '{'.
+#
+# Overrides nl_after_case.
+nl_case_colon_brace = remove # ignore/add/remove/force/not_defined
+
+# Add or remove newline between ')' and 'throw'.
+nl_before_throw = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline between 'namespace' and '{'.
+nl_namespace_brace = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline after 'template<...>' of a template class.
+nl_template_class = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline after 'template<...>' of a template class declaration.
+#
+# Overrides nl_template_class.
+nl_template_class_decl = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline after 'template<>' of a specialized class declaration.
+#
+# Overrides nl_template_class_decl.
+nl_template_class_decl_special = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline after 'template<...>' of a template class definition.
+#
+# Overrides nl_template_class.
+nl_template_class_def = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline after 'template<>' of a specialized class definition.
+#
+# Overrides nl_template_class_def.
+nl_template_class_def_special = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline after 'template<...>' of a template function.
+nl_template_func = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline after 'template<...>' of a template function
+# declaration.
+#
+# Overrides nl_template_func.
+nl_template_func_decl = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline after 'template<>' of a specialized function
+# declaration.
+#
+# Overrides nl_template_func_decl.
+nl_template_func_decl_special = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline after 'template<...>' of a template function
+# definition.
+#
+# Overrides nl_template_func.
+nl_template_func_def = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline after 'template<>' of a specialized function
+# definition.
+#
+# Overrides nl_template_func_def.
+nl_template_func_def_special = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline after 'template<...>' of a template variable.
+nl_template_var = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline between 'template<...>' and 'using' of a templated
+# type alias.
+nl_template_using = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline between 'class' and '{'.
+nl_class_brace = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline before or after (depending on pos_class_comma,
+# may not be IGNORE) each',' in the base class list.
+nl_class_init_args = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline after each ',' in the constructor member
+# initialization. Related to nl_constr_colon, pos_constr_colon and
+# pos_constr_comma.
+nl_constr_init_args = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline before first element, after comma, and after last
+# element, in 'enum'.
+nl_enum_own_lines = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline between return type and function name in a function
+# definition.
+# might be modified by nl_func_leave_one_liners
+nl_func_type_name = remove # ignore/add/remove/force/not_defined
+
+# Add or remove newline between return type and function name inside a class
+# definition. If set to ignore, nl_func_type_name or nl_func_proto_type_name
+# is used instead.
+nl_func_type_name_class = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline between class specification and '::'
+# in 'void A::f() { }'. Only appears in separate member implementation (does
+# not appear with in-line implementation).
+nl_func_class_scope = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline between function scope and name, as in
+# 'void A :: <here> f() { }'.
+nl_func_scope_name = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline between return type and function name in a prototype.
+nl_func_proto_type_name = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline between a function name and the opening '(' in the
+# declaration.
+nl_func_paren = ignore # ignore/add/remove/force/not_defined
+
+# Overrides nl_func_paren for functions with no parameters.
+nl_func_paren_empty = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline between a function name and the opening '(' in the
+# definition.
+nl_func_def_paren = ignore # ignore/add/remove/force/not_defined
+
+# Overrides nl_func_def_paren for functions with no parameters.
+nl_func_def_paren_empty = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline between a function name and the opening '(' in the
+# call.
+nl_func_call_paren = ignore # ignore/add/remove/force/not_defined
+
+# Overrides nl_func_call_paren for functions with no parameters.
+nl_func_call_paren_empty = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline after '(' in a function declaration.
+nl_func_decl_start = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline after '(' in a function definition.
+nl_func_def_start = remove # ignore/add/remove/force/not_defined
+
+# Overrides nl_func_decl_start when there is only one parameter.
+nl_func_decl_start_single = ignore # ignore/add/remove/force/not_defined
+
+# Overrides nl_func_def_start when there is only one parameter.
+nl_func_def_start_single = ignore # ignore/add/remove/force/not_defined
+
+# Whether to add a newline after '(' in a function declaration if '(' and ')'
+# are in different lines. If false, nl_func_decl_start is used instead.
+nl_func_decl_start_multi_line = false # true/false
+
+# Whether to add a newline after '(' in a function definition if '(' and ')'
+# are in different lines. If false, nl_func_def_start is used instead.
+nl_func_def_start_multi_line = false # true/false
+
+# Add or remove newline after each ',' in a function declaration.
+nl_func_decl_args = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline after each ',' in a function definition.
+nl_func_def_args = remove # ignore/add/remove/force/not_defined
+
+# Add or remove newline after each ',' in a function call.
+nl_func_call_args = ignore # ignore/add/remove/force/not_defined
+
+# Whether to add a newline after each ',' in a function declaration if '('
+# and ')' are in different lines. If false, nl_func_decl_args is used instead.
+nl_func_decl_args_multi_line = false # true/false
+
+# Whether to add a newline after each ',' in a function definition if '('
+# and ')' are in different lines. If false, nl_func_def_args is used instead.
+nl_func_def_args_multi_line = false # true/false
+
+# Add or remove newline before the ')' in a function declaration.
+nl_func_decl_end = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline before the ')' in a function definition.
+nl_func_def_end = remove # ignore/add/remove/force/not_defined
+
+# Overrides nl_func_decl_end when there is only one parameter.
+nl_func_decl_end_single = ignore # ignore/add/remove/force/not_defined
+
+# Overrides nl_func_def_end when there is only one parameter.
+nl_func_def_end_single = ignore # ignore/add/remove/force/not_defined
+
+# Whether to add a newline before ')' in a function declaration if '(' and ')'
+# are in different lines. If false, nl_func_decl_end is used instead.
+nl_func_decl_end_multi_line = false # true/false
+
+# Whether to add a newline before ')' in a function definition if '(' and ')'
+# are in different lines. If false, nl_func_def_end is used instead.
+nl_func_def_end_multi_line = false # true/false
+
+# Add or remove newline between '()' in a function declaration.
+nl_func_decl_empty = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline between '()' in a function definition.
+nl_func_def_empty = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline between '()' in a function call.
+nl_func_call_empty = ignore # ignore/add/remove/force/not_defined
+
+# Whether to add a newline after '(' in a function call,
+# has preference over nl_func_call_start_multi_line.
+nl_func_call_start = remove # ignore/add/remove/force/not_defined
+
+# Whether to add a newline before ')' in a function call.
+nl_func_call_end = ignore # ignore/add/remove/force/not_defined
+
+# Whether to add a newline after '(' in a function call if '(' and ')' are in
+# different lines.
+nl_func_call_start_multi_line = false # true/false
+
+# Whether to add a newline after each ',' in a function call if '(' and ')'
+# are in different lines.
+nl_func_call_args_multi_line = false # true/false
+
+# Whether to add a newline before ')' in a function call if '(' and ')' are in
+# different lines.
+nl_func_call_end_multi_line = false # true/false
+
+# Whether to respect nl_func_call_XXX option in case of closure args.
+nl_func_call_args_multi_line_ignore_closures = false # true/false
+
+# Whether to add a newline after '<' of a template parameter list.
+nl_template_start = false # true/false
+
+# Whether to add a newline after each ',' in a template parameter list.
+nl_template_args = false # true/false
+
+# Whether to add a newline before '>' of a template parameter list.
+nl_template_end = false # true/false
+
+# (OC) Whether to put each Objective-C message parameter on a separate line.
+# See nl_oc_msg_leave_one_liner.
+nl_oc_msg_args = false # true/false
+
+# Add or remove newline between function signature and '{'.
+nl_fdef_brace = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline between function signature and '{',
+# if signature ends with ')'. Overrides nl_fdef_brace.
+nl_fdef_brace_cond = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline between C++11 lambda signature and '{'.
+nl_cpp_ldef_brace = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline between 'return' and the return expression.
+nl_return_expr = ignore # ignore/add/remove/force/not_defined
+
+# Whether to add a newline after semicolons, except in 'for' statements.
+nl_after_semicolon = false # true/false
+
+# (Java) Add or remove newline between the ')' and '{{' of the double brace
+# initializer.
+nl_paren_dbrace_open = ignore # ignore/add/remove/force/not_defined
+
+# Whether to add a newline after the type in an unnamed temporary
+# direct-list-initialization.
+nl_type_brace_init_lst = ignore # ignore/add/remove/force/not_defined
+
+# Whether to add a newline after the open brace in an unnamed temporary
+# direct-list-initialization.
+nl_type_brace_init_lst_open = ignore # ignore/add/remove/force/not_defined
+
+# Whether to add a newline before the close brace in an unnamed temporary
+# direct-list-initialization.
+nl_type_brace_init_lst_close = ignore # ignore/add/remove/force/not_defined
+
+# Whether to add a newline before '{'.
+nl_before_brace_open = false # true/false
+
+# Whether to add a newline after '{'.
+nl_after_brace_open = false # true/false
+
+# Whether to add a newline between the open brace and a trailing single-line
+# comment. Requires nl_after_brace_open=true.
+nl_after_brace_open_cmt = false # true/false
+
+# Whether to add a newline after a virtual brace open with a non-empty body.
+# These occur in un-braced if/while/do/for statement bodies.
+nl_after_vbrace_open = false # true/false
+
+# Whether to add a newline after a virtual brace open with an empty body.
+# These occur in un-braced if/while/do/for statement bodies.
+nl_after_vbrace_open_empty = false # true/false
+
+# Whether to add a newline after '}'. Does not apply if followed by a
+# necessary ';'.
+nl_after_brace_close = false # true/false
+
+# Whether to add a newline after a virtual brace close,
+# as in 'if (foo) a++; <here> return;'.
+nl_after_vbrace_close = false # true/false
+
+# Add or remove newline between the close brace and identifier,
+# as in 'struct { int a; } <here> b;'. Affects enumerations, unions and
+# structures. If set to ignore, uses nl_after_brace_close.
+nl_brace_struct_var = ignore # ignore/add/remove/force/not_defined
+
+# Whether to alter newlines in '#define' macros.
+nl_define_macro = false # true/false
+
+# Whether to alter newlines between consecutive parenthesis closes. The number
+# of closing parentheses in a line will depend on respective open parenthesis
+# lines.
+nl_squeeze_paren_close = false # true/false
+
+# Whether to remove blanks after '#ifxx' and '#elxx', or before '#elxx' and
+# '#endif'. Does not affect top-level #ifdefs.
+nl_squeeze_ifdef = false # true/false
+
+# Makes the nl_squeeze_ifdef option affect the top-level #ifdefs as well.
+nl_squeeze_ifdef_top_level = false # true/false
+
+# Add or remove blank line before 'if'.
+nl_before_if = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove blank line after 'if' statement. Add/Force work only if the
+# next token is not a closing brace.
+nl_after_if = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove blank line before 'for'.
+nl_before_for = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove blank line after 'for' statement.
+nl_after_for = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove blank line before 'while'.
+nl_before_while = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove blank line after 'while' statement.
+nl_after_while = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove blank line before 'switch'.
+nl_before_switch = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove blank line after 'switch' statement.
+nl_after_switch = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove blank line before 'synchronized'.
+nl_before_synchronized = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove blank line after 'synchronized' statement.
+nl_after_synchronized = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove blank line before 'do'.
+nl_before_do = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove blank line after 'do/while' statement.
+nl_after_do = ignore # ignore/add/remove/force/not_defined
+
+# Ignore nl_before_{if,for,switch,do,synchronized} if the control
+# statement is immediately after a case statement.
+# if nl_before_{if,for,switch,do} is set to remove, this option
+# does nothing.
+nl_before_ignore_after_case = false # true/false
+
+# Whether to put a blank line before 'return' statements, unless after an open
+# brace.
+nl_before_return = false # true/false
+
+# Whether to put a blank line after 'return' statements, unless followed by a
+# close brace.
+nl_after_return = false # true/false
+
+# Whether to put a blank line before a member '.' or '->' operators.
+nl_before_member = ignore # ignore/add/remove/force/not_defined
+
+# (Java) Whether to put a blank line after a member '.' or '->' operators.
+nl_after_member = ignore # ignore/add/remove/force/not_defined
+
+# Whether to double-space commented-entries in 'struct'/'union'/'enum'.
+nl_ds_struct_enum_cmt = false # true/false
+
+# Whether to force a newline before '}' of a 'struct'/'union'/'enum'.
+# (Lower priority than eat_blanks_before_close_brace.)
+nl_ds_struct_enum_close_brace = false # true/false
+
+# Add or remove newline before or after (depending on pos_class_colon) a class
+# colon, as in 'class Foo <here> : <or here> public Bar'.
+nl_class_colon = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove newline around a class constructor colon. The exact position
+# depends on nl_constr_init_args, pos_constr_colon and pos_constr_comma.
+nl_constr_colon = ignore # ignore/add/remove/force/not_defined
+
+# Whether to collapse a two-line namespace, like 'namespace foo\n{ decl; }'
+# into a single line. If true, prevents other brace newline rules from turning
+# such code into four lines. If true, it also preserves one-liner namespaces.
+nl_namespace_two_to_one_liner = false # true/false
+
+# Whether to remove a newline in simple unbraced if statements, turning them
+# into one-liners, as in 'if(b)\n i++;' => 'if(b) i++;'.
+nl_create_if_one_liner = false # true/false
+
+# Whether to remove a newline in simple unbraced for statements, turning them
+# into one-liners, as in 'for (...)\n stmt;' => 'for (...) stmt;'.
+nl_create_for_one_liner = false # true/false
+
+# Whether to remove a newline in simple unbraced while statements, turning
+# them into one-liners, as in 'while (expr)\n stmt;' => 'while (expr) stmt;'.
+nl_create_while_one_liner = false # true/false
+
+# Whether to collapse a function definition whose body (not counting braces)
+# is only one line so that the entire definition (prototype, braces, body) is
+# a single line.
+nl_create_func_def_one_liner = false # true/false
+
+# Whether to split one-line simple list definitions into three lines by
+# adding newlines, as in 'int a[12] = { <here> 0 <here> };'.
+nl_create_list_one_liner = false # true/false
+
+# Whether to split one-line simple unbraced if statements into two lines by
+# adding a newline, as in 'if(b) <here> i++;'.
+nl_split_if_one_liner = false # true/false
+
+# Whether to split one-line simple unbraced for statements into two lines by
+# adding a newline, as in 'for (...) <here> stmt;'.
+nl_split_for_one_liner = false # true/false
+
+# Whether to split one-line simple unbraced while statements into two lines by
+# adding a newline, as in 'while (expr) <here> stmt;'.
+nl_split_while_one_liner = false # true/false
+
+# Don't add a newline before a cpp-comment in a parameter list of a function
+# call.
+donot_add_nl_before_cpp_comment = false # true/false
+
+#
+# Blank line options
+#
+
+# The maximum number of consecutive newlines (3 = 2 blank lines).
+nl_max = 0 # unsigned number
+
+# The maximum number of consecutive newlines in a function.
+nl_max_blank_in_func = 0 # unsigned number
+
+# The number of newlines inside an empty function body.
+# This option overrides eat_blanks_after_open_brace and
+# eat_blanks_before_close_brace, but is ignored when
+# nl_collapse_empty_body=true
+nl_inside_empty_func = 0 # unsigned number
+
+# The number of newlines before a function prototype.
+nl_before_func_body_proto = 0 # unsigned number
+
+# The number of newlines before a multi-line function definition. Where
+# applicable, this option is overridden with eat_blanks_after_open_brace=true
+nl_before_func_body_def = 0 # unsigned number
+
+# The number of newlines before a class constructor/destructor prototype.
+nl_before_func_class_proto = 0 # unsigned number
+
+# The number of newlines before a class constructor/destructor definition.
+nl_before_func_class_def = 0 # unsigned number
+
+# The number of newlines after a function prototype.
+nl_after_func_proto = 0 # unsigned number
+
+# The number of newlines after a function prototype, if not followed by
+# another function prototype.
+nl_after_func_proto_group = 0 # unsigned number
+
+# The number of newlines after a class constructor/destructor prototype.
+nl_after_func_class_proto = 0 # unsigned number
+
+# The number of newlines after a class constructor/destructor prototype,
+# if not followed by another constructor/destructor prototype.
+nl_after_func_class_proto_group = 0 # unsigned number
+
+# Whether one-line method definitions inside a class body should be treated
+# as if they were prototypes for the purposes of adding newlines.
+#
+# Requires nl_class_leave_one_liners=true. Overrides nl_before_func_body_def
+# and nl_before_func_class_def for one-liners.
+nl_class_leave_one_liner_groups = false # true/false
+
+# The number of newlines after '}' of a multi-line function body.
+nl_after_func_body = 0 # unsigned number
+
+# The number of newlines after '}' of a multi-line function body in a class
+# declaration. Also affects class constructors/destructors.
+#
+# Overrides nl_after_func_body.
+nl_after_func_body_class = 0 # unsigned number
+
+# The number of newlines after '}' of a single line function body. Also
+# affects class constructors/destructors.
+#
+# Overrides nl_after_func_body and nl_after_func_body_class.
+nl_after_func_body_one_liner = 0 # unsigned number
+
+# The number of blank lines after a block of variable definitions at the top
+# of a function body.
+#
+# 0: No change (default).
+nl_func_var_def_blk = 0 # unsigned number
+
+# The number of newlines before a block of typedefs. If nl_after_access_spec
+# is non-zero, that option takes precedence.
+#
+# 0: No change (default).
+nl_typedef_blk_start = 0 # unsigned number
+
+# The number of newlines after a block of typedefs.
+#
+# 0: No change (default).
+nl_typedef_blk_end = 0 # unsigned number
+
+# The maximum number of consecutive newlines within a block of typedefs.
+#
+# 0: No change (default).
+nl_typedef_blk_in = 0 # unsigned number
+
+# The number of newlines before a block of variable definitions not at the top
+# of a function body. If nl_after_access_spec is non-zero, that option takes
+# precedence.
+#
+# 0: No change (default).
+nl_var_def_blk_start = 0 # unsigned number
+
+# The number of newlines after a block of variable definitions not at the top
+# of a function body.
+#
+# 0: No change (default).
+nl_var_def_blk_end = 0 # unsigned number
+
+# The maximum number of consecutive newlines within a block of variable
+# definitions.
+#
+# 0: No change (default).
+nl_var_def_blk_in = 0 # unsigned number
+
+# The minimum number of newlines before a multi-line comment.
+# Doesn't apply if after a brace open or another multi-line comment.
+nl_before_block_comment = 0 # unsigned number
+
+# The minimum number of newlines before a single-line C comment.
+# Doesn't apply if after a brace open or other single-line C comments.
+nl_before_c_comment = 0 # unsigned number
+
+# The minimum number of newlines before a CPP comment.
+# Doesn't apply if after a brace open or other CPP comments.
+nl_before_cpp_comment = 0 # unsigned number
+
+# Whether to force a newline after a multi-line comment.
+nl_after_multiline_comment = false # true/false
+
+# Whether to force a newline after a label's colon.
+nl_after_label_colon = false # true/false
+
+# The number of newlines before a struct definition.
+nl_before_struct = 0 # unsigned number
+
+# The number of newlines after '}' or ';' of a struct/enum/union definition.
+nl_after_struct = 0 # unsigned number
+
+# The number of newlines before a class definition.
+nl_before_class = 0 # unsigned number
+
+# The number of newlines after '}' or ';' of a class definition.
+nl_after_class = 0 # unsigned number
+
+# The number of newlines before a namespace.
+nl_before_namespace = 0 # unsigned number
+
+# The number of newlines after '{' of a namespace. This also adds newlines
+# before the matching '}'.
+#
+# 0: Apply eat_blanks_after_open_brace or eat_blanks_before_close_brace if
+# applicable, otherwise no change.
+#
+# Overrides eat_blanks_after_open_brace and eat_blanks_before_close_brace.
+nl_inside_namespace = 0 # unsigned number
+
+# The number of newlines after '}' of a namespace.
+nl_after_namespace = 0 # unsigned number
+
+# The number of newlines before an access specifier label. This also includes
+# the Qt-specific 'signals:' and 'slots:'. Will not change the newline count
+# if after a brace open.
+#
+# 0: No change (default).
+nl_before_access_spec = 0 # unsigned number
+
+# The number of newlines after an access specifier label. This also includes
+# the Qt-specific 'signals:' and 'slots:'. Will not change the newline count
+# if after a brace open.
+#
+# 0: No change (default).
+#
+# Overrides nl_typedef_blk_start and nl_var_def_blk_start.
+nl_after_access_spec = 0 # unsigned number
+
+# The number of newlines between a function definition and the function
+# comment, as in '// comment\n <here> void foo() {...}'.
+#
+# 0: No change (default).
+nl_comment_func_def = 0 # unsigned number
+
+# The number of newlines after a try-catch-finally block that isn't followed
+# by a brace close.
+#
+# 0: No change (default).
+nl_after_try_catch_finally = 0 # unsigned number
+
+# (C#) The number of newlines before and after a property, indexer or event
+# declaration.
+#
+# 0: No change (default).
+nl_around_cs_property = 0 # unsigned number
+
+# (C#) The number of newlines between the get/set/add/remove handlers.
+#
+# 0: No change (default).
+nl_between_get_set = 0 # unsigned number
+
+# (C#) Add or remove newline between property and the '{'.
+nl_property_brace = ignore # ignore/add/remove/force/not_defined
+
+# Whether to remove blank lines after '{'.
+eat_blanks_after_open_brace = true # true/false
+
+# Whether to remove blank lines before '}'.
+eat_blanks_before_close_brace = true # true/false
+
+# How aggressively to remove extra newlines not in preprocessor.
+#
+# 0: No change (default)
+# 1: Remove most newlines not handled by other config
+# 2: Remove all newlines and reformat completely by config
+nl_remove_extra_newlines = 0 # unsigned number
+
+# (Java) Add or remove newline after an annotation statement. Only affects
+# annotations that are after a newline.
+nl_after_annotation = ignore # ignore/add/remove/force/not_defined
+
+# (Java) Add or remove newline between two annotations.
+nl_between_annotation = ignore # ignore/add/remove/force/not_defined
+
+# The number of newlines before a whole-file #ifdef.
+#
+# 0: No change (default).
+nl_before_whole_file_ifdef = 0 # unsigned number
+
+# The number of newlines after a whole-file #ifdef.
+#
+# 0: No change (default).
+nl_after_whole_file_ifdef = 0 # unsigned number
+
+# The number of newlines before a whole-file #endif.
+#
+# 0: No change (default).
+nl_before_whole_file_endif = 0 # unsigned number
+
+# The number of newlines after a whole-file #endif.
+#
+# 0: No change (default).
+nl_after_whole_file_endif = 0 # unsigned number
+
+#
+# Positioning options
+#
+
+# The position of arithmetic operators in wrapped expressions.
+pos_arith = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force
+
+# The position of assignment in wrapped expressions. Do not affect '='
+# followed by '{'.
+pos_assign = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force
+
+# The position of Boolean operators in wrapped expressions.
+pos_bool = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force
+
+# The position of comparison operators in wrapped expressions.
+pos_compare = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force
+
+# The position of conditional operators, as in the '?' and ':' of
+# 'expr ? stmt : stmt', in wrapped expressions.
+pos_conditional = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force
+
+# The position of the comma in wrapped expressions.
+pos_comma = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force
+
+# The position of the comma in enum entries.
+pos_enum_comma = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force
+
+# The position of the comma in the base class list if there is more than one
+# line. Affects nl_class_init_args.
+pos_class_comma = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force
+
+# The position of the comma in the constructor initialization list.
+# Related to nl_constr_colon, nl_constr_init_args and pos_constr_colon.
+pos_constr_comma = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force
+
+# The position of trailing/leading class colon, between class and base class
+# list. Affects nl_class_colon.
+pos_class_colon = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force
+
+# The position of colons between constructor and member initialization.
+# Related to nl_constr_colon, nl_constr_init_args and pos_constr_comma.
+pos_constr_colon = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force
+
+# The position of shift operators in wrapped expressions.
+pos_shift = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force
+
+#
+# Line splitting options
+#
+
+# Try to limit code width to N columns.
+code_width = 100 # unsigned number
+
+# Whether to fully split long 'for' statements at semi-colons.
+ls_for_split_full = false # true/false
+
+# Whether to fully split long function prototypes/calls at commas.
+# The option ls_code_width has priority over the option ls_func_split_full.
+ls_func_split_full = false # true/false
+
+# Whether to split lines as close to code_width as possible and ignore some
+# groupings.
+# The option ls_code_width has priority over the option ls_func_split_full.
+ls_code_width = false # true/false
+
+#
+# Code alignment options (not left column spaces/tabs)
+#
+
+# Whether to keep non-indenting tabs.
+align_keep_tabs = false # true/false
+
+# Whether to use tabs for aligning.
+align_with_tabs = false # true/false
+
+# Whether to bump out to the next tab when aligning.
+align_on_tabstop = false # true/false
+
+# Whether to right-align numbers.
+align_number_right = false # true/false
+
+# Whether to keep whitespace not required for alignment.
+align_keep_extra_space = false # true/false
+
+# Whether to align variable definitions in prototypes and functions.
+align_func_params = false # true/false
+
+# The span for aligning parameter definitions in function on parameter name.
+#
+# 0: Don't align (default).
+align_func_params_span = 0 # unsigned number
+
+# The threshold for aligning function parameter definitions.
+# Use a negative number for absolute thresholds.
+#
+# 0: No limit (default).
+align_func_params_thresh = 0 # number
+
+# The gap for aligning function parameter definitions.
+align_func_params_gap = 0 # unsigned number
+
+# The span for aligning constructor value.
+#
+# 0: Don't align (default).
+align_constr_value_span = 0 # unsigned number
+
+# The threshold for aligning constructor value.
+# Use a negative number for absolute thresholds.
+#
+# 0: No limit (default).
+align_constr_value_thresh = 0 # number
+
+# The gap for aligning constructor value.
+align_constr_value_gap = 0 # unsigned number
+
+# Whether to align parameters in single-line functions that have the same
+# name. The function names must already be aligned with each other.
+align_same_func_call_params = false # true/false
+
+# The span for aligning function-call parameters for single line functions.
+#
+# 0: Don't align (default).
+align_same_func_call_params_span = 0 # unsigned number
+
+# The threshold for aligning function-call parameters for single line
+# functions.
+# Use a negative number for absolute thresholds.
+#
+# 0: No limit (default).
+align_same_func_call_params_thresh = 0 # number
+
+# The span for aligning variable definitions.
+#
+# 0: Don't align (default).
+align_var_def_span = 0 # unsigned number
+
+# How to consider (or treat) the '*' in the alignment of variable definitions.
+#
+# 0: Part of the type 'void * foo;' (default)
+# 1: Part of the variable 'void *foo;'
+# 2: Dangling 'void *foo;'
+# Dangling: the '*' will not be taken into account when aligning.
+align_var_def_star_style = 0 # unsigned number
+
+# How to consider (or treat) the '&' in the alignment of variable definitions.
+#
+# 0: Part of the type 'long & foo;' (default)
+# 1: Part of the variable 'long &foo;'
+# 2: Dangling 'long &foo;'
+# Dangling: the '&' will not be taken into account when aligning.
+align_var_def_amp_style = 0 # unsigned number
+
+# The threshold for aligning variable definitions.
+# Use a negative number for absolute thresholds.
+#
+# 0: No limit (default).
+align_var_def_thresh = 0 # number
+
+# The gap for aligning variable definitions.
+align_var_def_gap = 0 # unsigned number
+
+# Whether to align the colon in struct bit fields.
+align_var_def_colon = false # true/false
+
+# The gap for aligning the colon in struct bit fields.
+align_var_def_colon_gap = 0 # unsigned number
+
+# Whether to align any attribute after the variable name.
+align_var_def_attribute = false # true/false
+
+# Whether to align inline struct/enum/union variable definitions.
+align_var_def_inline = false # true/false
+
+# The span for aligning on '=' in assignments.
+#
+# 0: Don't align (default).
+align_assign_span = 0 # unsigned number
+
+# The span for aligning on '=' in function prototype modifier.
+#
+# 0: Don't align (default).
+align_assign_func_proto_span = 0 # unsigned number
+
+# The threshold for aligning on '=' in assignments.
+# Use a negative number for absolute thresholds.
+#
+# 0: No limit (default).
+align_assign_thresh = 0 # number
+
+# How to apply align_assign_span to function declaration "assignments", i.e.
+# 'virtual void foo() = 0' or '~foo() = {default|delete}'.
+#
+# 0: Align with other assignments (default)
+# 1: Align with each other, ignoring regular assignments
+# 2: Don't align
+align_assign_decl_func = 0 # unsigned number
+
+# The span for aligning on '=' in enums.
+#
+# 0: Don't align (default).
+align_enum_equ_span = 0 # unsigned number
+
+# The threshold for aligning on '=' in enums.
+# Use a negative number for absolute thresholds.
+#
+# 0: no limit (default).
+align_enum_equ_thresh = 0 # number
+
+# The span for aligning class member definitions.
+#
+# 0: Don't align (default).
+align_var_class_span = 0 # unsigned number
+
+# The threshold for aligning class member definitions.
+# Use a negative number for absolute thresholds.
+#
+# 0: No limit (default).
+align_var_class_thresh = 0 # number
+
+# The gap for aligning class member definitions.
+align_var_class_gap = 0 # unsigned number
+
+# The span for aligning struct/union member definitions.
+#
+# 0: Don't align (default).
+align_var_struct_span = 0 # unsigned number
+
+# The threshold for aligning struct/union member definitions.
+# Use a negative number for absolute thresholds.
+#
+# 0: No limit (default).
+align_var_struct_thresh = 0 # number
+
+# The gap for aligning struct/union member definitions.
+align_var_struct_gap = 0 # unsigned number
+
+# The span for aligning struct initializer values.
+#
+# 0: Don't align (default).
+align_struct_init_span = 0 # unsigned number
+
+# The span for aligning single-line typedefs.
+#
+# 0: Don't align (default).
+align_typedef_span = 0 # unsigned number
+
+# The minimum space between the type and the synonym of a typedef.
+align_typedef_gap = 0 # unsigned number
+
+# How to align typedef'd functions with other typedefs.
+#
+# 0: Don't mix them at all (default)
+# 1: Align the open parenthesis with the types
+# 2: Align the function type name with the other type names
+align_typedef_func = 0 # unsigned number
+
+# How to consider (or treat) the '*' in the alignment of typedefs.
+#
+# 0: Part of the typedef type, 'typedef int * pint;' (default)
+# 1: Part of type name: 'typedef int *pint;'
+# 2: Dangling: 'typedef int *pint;'
+# Dangling: the '*' will not be taken into account when aligning.
+align_typedef_star_style = 0 # unsigned number
+
+# How to consider (or treat) the '&' in the alignment of typedefs.
+#
+# 0: Part of the typedef type, 'typedef int & intref;' (default)
+# 1: Part of type name: 'typedef int &intref;'
+# 2: Dangling: 'typedef int &intref;'
+# Dangling: the '&' will not be taken into account when aligning.
+align_typedef_amp_style = 0 # unsigned number
+
+# The span for aligning comments that end lines.
+#
+# 0: Don't align (default).
+align_right_cmt_span = 0 # unsigned number
+
+# Minimum number of columns between preceding text and a trailing comment in
+# order for the comment to qualify for being aligned. Must be non-zero to have
+# an effect.
+align_right_cmt_gap = 0 # unsigned number
+
+# If aligning comments, whether to mix with comments after '}' and #endif with
+# less than three spaces before the comment.
+align_right_cmt_mix = false # true/false
+
+# Whether to only align trailing comments that are at the same brace level.
+align_right_cmt_same_level = false # true/false
+
+# Minimum column at which to align trailing comments. Comments which are
+# aligned beyond this column, but which can be aligned in a lesser column,
+# may be "pulled in".
+#
+# 0: Ignore (default).
+align_right_cmt_at_col = 0 # unsigned number
+
+# The span for aligning function prototypes.
+#
+# 0: Don't align (default).
+align_func_proto_span = 0 # unsigned number
+
+# The threshold for aligning function prototypes.
+# Use a negative number for absolute thresholds.
+#
+# 0: No limit (default).
+align_func_proto_thresh = 0 # number
+
+# Minimum gap between the return type and the function name.
+align_func_proto_gap = 0 # unsigned number
+
+# Whether to align function prototypes on the 'operator' keyword instead of
+# what follows.
+align_on_operator = false # true/false
+
+# Whether to mix aligning prototype and variable declarations. If true,
+# align_var_def_XXX options are used instead of align_func_proto_XXX options.
+align_mix_var_proto = false # true/false
+
+# Whether to align single-line functions with function prototypes.
+# Uses align_func_proto_span.
+align_single_line_func = false # true/false
+
+# Whether to align the open brace of single-line functions.
+# Requires align_single_line_func=true. Uses align_func_proto_span.
+align_single_line_brace = false # true/false
+
+# Gap for align_single_line_brace.
+align_single_line_brace_gap = 0 # unsigned number
+
+# (OC) The span for aligning Objective-C message specifications.
+#
+# 0: Don't align (default).
+align_oc_msg_spec_span = 0 # unsigned number
+
+# Whether to align macros wrapped with a backslash and a newline. This will
+# not work right if the macro contains a multi-line comment.
+align_nl_cont = false # true/false
+
+# Whether to align macro functions and variables together.
+align_pp_define_together = false # true/false
+
+# The span for aligning on '#define' bodies.
+#
+# =0: Don't align (default)
+# >0: Number of lines (including comments) between blocks
+align_pp_define_span = 0 # unsigned number
+
+# The minimum space between label and value of a preprocessor define.
+align_pp_define_gap = 0 # unsigned number
+
+# Whether to align lines that start with '<<' with previous '<<'.
+#
+# Default: true
+align_left_shift = true # true/false
+
+# Whether to align comma-separated statements following '<<' (as used to
+# initialize Eigen matrices).
+align_eigen_comma_init = false # true/false
+
+# Whether to align text after 'asm volatile ()' colons.
+align_asm_colon = false # true/false
+
+# (OC) Span for aligning parameters in an Objective-C message call
+# on the ':'.
+#
+# 0: Don't align.
+align_oc_msg_colon_span = 0 # unsigned number
+
+# (OC) Whether to always align with the first parameter, even if it is too
+# short.
+align_oc_msg_colon_first = false # true/false
+
+# (OC) Whether to align parameters in an Objective-C '+' or '-' declaration
+# on the ':'.
+align_oc_decl_colon = false # true/false
+
+# (OC) Whether to not align parameters in an Objectve-C message call if first
+# colon is not on next line of the message call (the same way Xcode does
+# aligment)
+align_oc_msg_colon_xcode_like = false # true/false
+
+#
+# Comment modification options
+#
+
+# Try to wrap comments at N columns.
+cmt_width = 0 # unsigned number
+
+# How to reflow comments.
+#
+# 0: No reflowing (apart from the line wrapping due to cmt_width) (default)
+# 1: No touching at all
+# 2: Full reflow (enable cmt_indent_multi for indent with line wrapping due to cmt_width)
+cmt_reflow_mode = 0 # unsigned number
+
+# Path to a file that contains regular expressions describing patterns for
+# which the end of one line and the beginning of the next will be folded into
+# the same sentence or paragraph during full comment reflow. The regular
+# expressions are described using ECMAScript syntax. The syntax for this
+# specification is as follows, where "..." indicates the custom regular
+# expression and "n" indicates the nth end_of_prev_line_regex and
+# beg_of_next_line_regex regular expression pair:
+#
+# end_of_prev_line_regex[1] = "...$"
+# beg_of_next_line_regex[1] = "^..."
+# end_of_prev_line_regex[2] = "...$"
+# beg_of_next_line_regex[2] = "^..."
+# .
+# .
+# .
+# end_of_prev_line_regex[n] = "...$"
+# beg_of_next_line_regex[n] = "^..."
+#
+# Note that use of this option overrides the default reflow fold regular
+# expressions, which are internally defined as follows:
+#
+# end_of_prev_line_regex[1] = "[\w,\]\)]$"
+# beg_of_next_line_regex[1] = "^[\w,\[\(]"
+# end_of_prev_line_regex[2] = "\.$"
+# beg_of_next_line_regex[2] = "^[A-Z]"
+cmt_reflow_fold_regex_file = "" # string
+
+# Whether to indent wrapped lines to the start of the encompassing paragraph
+# during full comment reflow (cmt_reflow_mode = 2). Overrides the value
+# specified by cmt_sp_after_star_cont.
+#
+# Note that cmt_align_doxygen_javadoc_tags overrides this option for
+# paragraphs associated with javadoc tags
+cmt_reflow_indent_to_paragraph_start = false # true/false
+
+# Whether to convert all tabs to spaces in comments. If false, tabs in
+# comments are left alone, unless used for indenting.
+cmt_convert_tab_to_spaces = true # true/false
+
+# Whether to apply changes to multi-line comments, including cmt_width,
+# keyword substitution and leading chars.
+#
+# Default: true
+cmt_indent_multi = true # true/false
+
+# Whether to align doxygen javadoc-style tags ('@param', '@return', etc.)
+# and corresponding fields such that groups of consecutive block tags,
+# parameter names, and descriptions align with one another. Overrides that
+# which is specified by the cmt_sp_after_star_cont. If cmt_width > 0, it may
+# be necessary to enable cmt_indent_multi and set cmt_reflow_mode = 2
+# in order to achieve the desired alignment for line-wrapping.
+cmt_align_doxygen_javadoc_tags = false # true/false
+
+# The number of spaces to insert after the star and before doxygen
+# javadoc-style tags (@param, @return, etc). Requires enabling
+# cmt_align_doxygen_javadoc_tags. Overrides that which is specified by the
+# cmt_sp_after_star_cont.
+#
+# Default: 1
+cmt_sp_before_doxygen_javadoc_tags = 1 # unsigned number
+
+# Whether to change trailing, single-line c-comments into cpp-comments.
+cmt_trailing_single_line_c_to_cpp = true # true/false
+
+# Whether to group c-comments that look like they are in a block.
+cmt_c_group = false # true/false
+
+# Whether to put an empty '/*' on the first line of the combined c-comment.
+cmt_c_nl_start = false # true/false
+
+# Whether to add a newline before the closing '*/' of the combined c-comment.
+cmt_c_nl_end = false # true/false
+
+# Whether to change cpp-comments into c-comments.
+cmt_cpp_to_c = false # true/false
+
+# Whether to group cpp-comments that look like they are in a block. Only
+# meaningful if cmt_cpp_to_c=true.
+cmt_cpp_group = false # true/false
+
+# Whether to put an empty '/*' on the first line of the combined cpp-comment
+# when converting to a c-comment.
+#
+# Requires cmt_cpp_to_c=true and cmt_cpp_group=true.
+cmt_cpp_nl_start = false # true/false
+
+# Whether to add a newline before the closing '*/' of the combined cpp-comment
+# when converting to a c-comment.
+#
+# Requires cmt_cpp_to_c=true and cmt_cpp_group=true.
+cmt_cpp_nl_end = false # true/false
+
+# Whether to put a star on subsequent comment lines.
+cmt_star_cont = false # true/false
+
+# The number of spaces to insert at the start of subsequent comment lines.
+cmt_sp_before_star_cont = 0 # unsigned number
+
+# The number of spaces to insert after the star on subsequent comment lines.
+cmt_sp_after_star_cont = 0 # unsigned number
+
+# For multi-line comments with a '*' lead, remove leading spaces if the first
+# and last lines of the comment are the same length.
+#
+# Default: true
+cmt_multi_check_last = true # true/false
+
+# For multi-line comments with a '*' lead, remove leading spaces if the first
+# and last lines of the comment are the same length AND if the length is
+# bigger as the first_len minimum.
+#
+# Default: 4
+cmt_multi_first_len_minimum = 4 # unsigned number
+
+# Path to a file that contains text to insert at the beginning of a file if
+# the file doesn't start with a C/C++ comment. If the inserted text contains
+# '$(filename)', that will be replaced with the current file's name.
+cmt_insert_file_header = "" # string
+
+# Path to a file that contains text to insert at the end of a file if the
+# file doesn't end with a C/C++ comment. If the inserted text contains
+# '$(filename)', that will be replaced with the current file's name.
+cmt_insert_file_footer = "" # string
+
+# Path to a file that contains text to insert before a function definition if
+# the function isn't preceded by a C/C++ comment. If the inserted text
+# contains '$(function)', '$(javaparam)' or '$(fclass)', these will be
+# replaced with, respectively, the name of the function, the javadoc '@param'
+# and '@return' stuff, or the name of the class to which the member function
+# belongs.
+cmt_insert_func_header = "" # string
+
+# Path to a file that contains text to insert before a class if the class
+# isn't preceded by a C/C++ comment. If the inserted text contains '$(class)',
+# that will be replaced with the class name.
+cmt_insert_class_header = "" # string
+
+# Path to a file that contains text to insert before an Objective-C message
+# specification, if the method isn't preceded by a C/C++ comment. If the
+# inserted text contains '$(message)' or '$(javaparam)', these will be
+# replaced with, respectively, the name of the function, or the javadoc
+# '@param' and '@return' stuff.
+cmt_insert_oc_msg_header = "" # string
+
+# Whether a comment should be inserted if a preprocessor is encountered when
+# stepping backwards from a function name.
+#
+# Applies to cmt_insert_oc_msg_header, cmt_insert_func_header and
+# cmt_insert_class_header.
+cmt_insert_before_preproc = false # true/false
+
+# Whether a comment should be inserted if a function is declared inline to a
+# class definition.
+#
+# Applies to cmt_insert_func_header.
+#
+# Default: true
+cmt_insert_before_inlines = true # true/false
+
+# Whether a comment should be inserted if the function is a class constructor
+# or destructor.
+#
+# Applies to cmt_insert_func_header.
+cmt_insert_before_ctor_dtor = false # true/false
+
+#
+# Code modifying options (non-whitespace)
+#
+
+# Add or remove braces on a single-line 'do' statement.
+mod_full_brace_do = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove braces on a single-line 'for' statement.
+mod_full_brace_for = add # ignore/add/remove/force/not_defined
+
+# (Pawn) Add or remove braces on a single-line function definition.
+mod_full_brace_function = ignore # ignore/add/remove/force/not_defined
+
+# Add or remove braces on a single-line 'if' statement. Braces will not be
+# removed if the braced statement contains an 'else'.
+mod_full_brace_if = add # ignore/add/remove/force/not_defined
+
+# Whether to enforce that all blocks of an 'if'/'else if'/'else' chain either
+# have, or do not have, braces. If true, braces will be added if any block
+# needs braces, and will only be removed if they can be removed from all
+# blocks.
+#
+# Overrides mod_full_brace_if.
+mod_full_brace_if_chain = false # true/false
+
+# Whether to add braces to all blocks of an 'if'/'else if'/'else' chain.
+# If true, mod_full_brace_if_chain will only remove braces from an 'if' that
+# does not have an 'else if' or 'else'.
+mod_full_brace_if_chain_only = false # true/false
+
+# Add or remove braces on single-line 'while' statement.
+mod_full_brace_while = add # ignore/add/remove/force/not_defined
+
+# Add or remove braces on single-line 'using ()' statement.
+mod_full_brace_using = ignore # ignore/add/remove/force/not_defined
+
+# Don't remove braces around statements that span N newlines
+mod_full_brace_nl = 0 # unsigned number
+
+# Whether to prevent removal of braces from 'if'/'for'/'while'/etc. blocks
+# which span multiple lines.
+#
+# Affects:
+# mod_full_brace_for
+# mod_full_brace_if
+# mod_full_brace_if_chain
+# mod_full_brace_if_chain_only
+# mod_full_brace_while
+# mod_full_brace_using
+#
+# Does not affect:
+# mod_full_brace_do
+# mod_full_brace_function
+mod_full_brace_nl_block_rem_mlcond = false # true/false
+
+# Add or remove unnecessary parenthesis on 'return' statement.
+mod_paren_on_return = ignore # ignore/add/remove/force/not_defined
+
+# (Pawn) Whether to change optional semicolons to real semicolons.
+mod_pawn_semicolon = false # true/false
+
+# Whether to fully parenthesize Boolean expressions in 'while' and 'if'
+# statement, as in 'if (a && b > c)' => 'if (a && (b > c))'.
+mod_full_paren_if_bool = false # true/false
+
+# Whether to remove superfluous semicolons.
+mod_remove_extra_semicolon = false # true/false
+
+# Whether to remove duplicate include.
+mod_remove_duplicate_include = false # true/false
+
+# If a function body exceeds the specified number of newlines and doesn't have
+# a comment after the close brace, a comment will be added.
+mod_add_long_function_closebrace_comment = 0 # unsigned number
+
+# If a namespace body exceeds the specified number of newlines and doesn't
+# have a comment after the close brace, a comment will be added.
+mod_add_long_namespace_closebrace_comment = 0 # unsigned number
+
+# If a class body exceeds the specified number of newlines and doesn't have a
+# comment after the close brace, a comment will be added.
+mod_add_long_class_closebrace_comment = 0 # unsigned number
+
+# If a switch body exceeds the specified number of newlines and doesn't have a
+# comment after the close brace, a comment will be added.
+mod_add_long_switch_closebrace_comment = 0 # unsigned number
+
+# If an #ifdef body exceeds the specified number of newlines and doesn't have
+# a comment after the #endif, a comment will be added.
+mod_add_long_ifdef_endif_comment = 0 # unsigned number
+
+# If an #ifdef or #else body exceeds the specified number of newlines and
+# doesn't have a comment after the #else, a comment will be added.
+mod_add_long_ifdef_else_comment = 0 # unsigned number
+
+# Whether to take care of the case by the mod_sort_xx options.
+mod_sort_case_sensitive = false # true/false
+
+# Whether to sort consecutive single-line 'import' statements.
+mod_sort_import = false # true/false
+
+# (C#) Whether to sort consecutive single-line 'using' statements.
+mod_sort_using = false # true/false
+
+# Whether to sort consecutive single-line '#include' statements (C/C++) and
+# '#import' statements (Objective-C). Be aware that this has the potential to
+# break your code if your includes/imports have ordering dependencies.
+mod_sort_include = true # true/false
+
+# Whether to prioritize '#include' and '#import' statements that contain
+# filename without extension when sorting is enabled.
+mod_sort_incl_import_prioritize_filename = false # true/false
+
+# Whether to prioritize '#include' and '#import' statements that does not
+# contain extensions when sorting is enabled.
+mod_sort_incl_import_prioritize_extensionless = false # true/false
+
+# Whether to prioritize '#include' and '#import' statements that contain
+# angle over quotes when sorting is enabled.
+mod_sort_incl_import_prioritize_angle_over_quotes = true # true/false
+
+# Whether to ignore file extension in '#include' and '#import' statements
+# for sorting comparison.
+mod_sort_incl_import_ignore_extension = false # true/false
+
+# Whether to group '#include' and '#import' statements when sorting is enabled.
+mod_sort_incl_import_grouping_enabled = true # true/false
+
+# Whether to move a 'break' that appears after a fully braced 'case' before
+# the close brace, as in 'case X: { ... } break;' => 'case X: { ... break; }'.
+mod_move_case_break = false # true/false
+
+# Add or remove braces around a fully braced case statement. Will only remove
+# braces if there are no variable declarations in the block.
+mod_case_brace = remove # ignore/add/remove/force/not_defined
+
+# Whether to remove a void 'return;' that appears as the last statement in a
+# function.
+mod_remove_empty_return = false # true/false
+
+# Add or remove the comma after the last value of an enumeration.
+mod_enum_last_comma = ignore # ignore/add/remove/force/not_defined
+
+# (OC) Whether to organize the properties. If true, properties will be
+# rearranged according to the mod_sort_oc_property_*_weight factors.
+mod_sort_oc_properties = false # true/false
+
+# (OC) Weight of a class property modifier.
+mod_sort_oc_property_class_weight = 0 # number
+
+# (OC) Weight of 'atomic' and 'nonatomic'.
+mod_sort_oc_property_thread_safe_weight = 0 # number
+
+# (OC) Weight of 'readwrite' when organizing properties.
+mod_sort_oc_property_readwrite_weight = 0 # number
+
+# (OC) Weight of a reference type specifier ('retain', 'copy', 'assign',
+# 'weak', 'strong') when organizing properties.
+mod_sort_oc_property_reference_weight = 0 # number
+
+# (OC) Weight of getter type ('getter=') when organizing properties.
+mod_sort_oc_property_getter_weight = 0 # number
+
+# (OC) Weight of setter type ('setter=') when organizing properties.
+mod_sort_oc_property_setter_weight = 0 # number
+
+# (OC) Weight of nullability type ('nullable', 'nonnull', 'null_unspecified',
+# 'null_resettable') when organizing properties.
+mod_sort_oc_property_nullability_weight = 0 # number
+
+#
+# Preprocessor options
+#
+
+# Add or remove indentation of preprocessor directives inside #if blocks
+# at brace level 0 (file-level).
+pp_indent = remove # ignore/add/remove/force/not_defined
+
+# Whether to indent #if/#else/#endif at the brace level. If false, these are
+# indented from column 1.
+pp_indent_at_level = false # true/false
+
+# Specifies the number of columns to indent preprocessors per level
+# at brace level 0 (file-level). If pp_indent_at_level=false, also specifies
+# the number of columns to indent preprocessors per level
+# at brace level > 0 (function-level).
+#
+# Default: 1
+pp_indent_count = 1 # unsigned number
+
+# Add or remove space after # based on pp_level of #if blocks.
+pp_space = force # ignore/add/remove/force/not_defined
+
+# Sets the number of spaces per level added with pp_space.
+pp_space_count = 0 # unsigned number
+
+# The indent for '#region' and '#endregion' in C# and '#pragma region' in
+# C/C++. Negative values decrease indent down to the first column.
+pp_indent_region = 0 # number
+
+# Whether to indent the code between #region and #endregion.
+pp_region_indent_code = false # true/false
+
+# If pp_indent_at_level=true, sets the indent for #if, #else and #endif when
+# not at file-level. Negative values decrease indent down to the first column.
+#
+# =0: Indent preprocessors using output_tab_size
+# >0: Column at which all preprocessors will be indented
+pp_indent_if = 0 # number
+
+# Whether to indent the code between #if, #else and #endif.
+pp_if_indent_code = false # true/false
+
+# Whether to indent the body of an #if that encompasses all the code in the file.
+pp_indent_in_guard = false # true/false
+
+# Whether to indent '#define' at the brace level. If false, these are
+# indented from column 1.
+pp_define_at_level = false # true/false
+
+# Whether to ignore the '#define' body while formatting.
+pp_ignore_define_body = false # true/false
+
+# Whether to indent case statements between #if, #else, and #endif.
+# Only applies to the indent of the preprocesser that the case statements
+# directly inside of.
+#
+# Default: true
+pp_indent_case = true # true/false
+
+# Whether to indent whole function definitions between #if, #else, and #endif.
+# Only applies to the indent of the preprocesser that the function definition
+# is directly inside of.
+#
+# Default: true
+pp_indent_func_def = true # true/false
+
+# Whether to indent extern C blocks between #if, #else, and #endif.
+# Only applies to the indent of the preprocesser that the extern block is
+# directly inside of.
+#
+# Default: true
+pp_indent_extern = true # true/false
+
+# Whether to indent braces directly inside #if, #else, and #endif.
+# Only applies to the indent of the preprocesser that the braces are directly
+# inside of.
+#
+# Default: true
+pp_indent_brace = true # true/false
+
+#
+# Sort includes options
+#
+
+# The regex for include category with priority 0.
+include_category_0 = "" # string
+
+# The regex for include category with priority 1.
+include_category_1 = "" # string
+
+# The regex for include category with priority 2.
+include_category_2 = "" # string
+
+#
+# Use or Do not Use options
+#
+
+# true: indent_func_call_param will be used (default)
+# false: indent_func_call_param will NOT be used
+#
+# Default: true
+use_indent_func_call_param = true # true/false
+
+# The value of the indentation for a continuation line is calculated
+# differently if the statement is:
+# - a declaration: your case with QString fileName ...
+# - an assignment: your case with pSettings = new QSettings( ...
+#
+# At the second case the indentation value might be used twice:
+# - at the assignment
+# - at the function call (if present)
+#
+# To prevent the double use of the indentation value, use this option with the
+# value 'true'.
+#
+# true: indent_continue will be used only once
+# false: indent_continue will be used every time (default)
+use_indent_continue_only_once = false # true/false
+
+# The value might be used twice:
+# - at the assignment
+# - at the opening brace
+#
+# To prevent the double use of the indentation value, use this option with the
+# value 'true'.
+#
+# true: indentation will be used only once
+# false: indentation will be used every time (default)
+indent_cpp_lambda_only_once = false # true/false
+
+# Whether sp_after_angle takes precedence over sp_inside_fparen. This was the
+# historic behavior, but is probably not the desired behavior, so this is off
+# by default.
+use_sp_after_angle_always = false # true/false
+
+# Whether to apply special formatting for Qt SIGNAL/SLOT macros. Essentially,
+# this tries to format these so that they match Qt's normalized form (i.e. the
+# result of QMetaObject::normalizedSignature), which can slightly improve the
+# performance of the QObject::connect call, rather than how they would
+# otherwise be formatted.
+#
+# See options_for_QT.cpp for details.
+#
+# Default: true
+use_options_overriding_for_qt_macros = true # true/false
+
+# If true: the form feed character is removed from the list of whitespace
+# characters. See https://en.cppreference.com/w/cpp/string/byte/isspace.
+use_form_feed_no_more_as_whitespace_character = false # true/false
+
+#
+# Warn levels - 1: error, 2: warning (default), 3: note
+#
+
+# (C#) Warning is given if doing tab-to-\t replacement and we have found one
+# in a C# verbatim string literal.
+#
+# Default: 2
+warn_level_tabs_found_in_verbatim_string_literals = 2 # unsigned number
+
+# Limit the number of loops.
+# Used by uncrustify.cpp to exit from infinite loop.
+# 0: no limit.
+debug_max_number_of_loops = 0 # number
+
+# Set the number of the line to protocol;
+# Used in the function prot_the_line if the 2. parameter is zero.
+# 0: nothing protocol.
+debug_line_number_to_protocol = 0 # number
+
+# Set the number of second(s) before terminating formatting the current file,
+# 0: no timeout.
+# only for linux
+debug_timeout = 0 # number
+
+# Set the number of characters to be printed if the text is too long,
+# 0: do not truncate.
+debug_truncate = 0 # unsigned number
+
+# Meaning of the settings:
+# Ignore - do not do any changes
+# Add - makes sure there is 1 or more space/brace/newline/etc
+# Force - makes sure there is exactly 1 space/brace/newline/etc,
+# behaves like Add in some contexts
+# Remove - removes space/brace/newline/etc
+#
+#
+# - Token(s) can be treated as specific type(s) with the 'set' option:
+# `set tokenType tokenString [tokenString...]`
+#
+# Example:
+# `set BOOL __AND__ __OR__`
+#
+# tokenTypes are defined in src/token_enum.h, use them without the
+# 'CT_' prefix: 'CT_BOOL' => 'BOOL'
+#
+#
+# - Token(s) can be treated as type(s) with the 'type' option.
+# `type tokenString [tokenString...]`
+#
+# Example:
+# `type int c_uint_8 Rectangle`
+#
+# This can also be achieved with `set TYPE int c_uint_8 Rectangle`
+#
+#
+# To embed whitespace in tokenStrings use the '\' escape character, or quote
+# the tokenStrings. These quotes are supported: "'`
+#
+#
+# - Support for the auto detection of languages through the file ending can be
+# added using the 'file_ext' command.
+# `file_ext langType langString [langString..]`
+#
+# Example:
+# `file_ext CPP .ch .cxx .cpp.in`
+#
+# langTypes are defined in uncrusify_types.h in the lang_flag_e enum, use
+# them without the 'LANG_' prefix: 'LANG_CPP' => 'CPP'
+#
+#
+# - Custom macro-based indentation can be set up using 'macro-open',
+# 'macro-else' and 'macro-close'.
+# `(macro-open | macro-else | macro-close) tokenString`
+#
+# Example:
+# `macro-open BEGIN_TEMPLATE_MESSAGE_MAP`
+# `macro-open BEGIN_MESSAGE_MAP`
+# `macro-close END_MESSAGE_MAP`
+#
+#
+set QUESTION FUNC_API_CHECK_TEXTLOCK
+set QUESTION FUNC_API_DEPRECATED_SINCE
+set QUESTION FUNC_API_FAST
+set QUESTION FUNC_API_LUA_ONLY
+set QUESTION FUNC_API_NOEXPORT
+set QUESTION FUNC_API_REMOTE_ONLY
+set QUESTION FUNC_API_SINCE
+set QUESTION FUNC_ATTR_ALWAYS_INLINE
+set QUESTION FUNC_ATTR_CONST
+set QUESTION FUNC_ATTR_MALLOC
+set QUESTION FUNC_ATTR_NONNULL_ALL
+set QUESTION FUNC_ATTR_NONNULL_ARG
+set QUESTION FUNC_ATTR_NONNULL_RET
+set QUESTION FUNC_ATTR_NORETURN
+set QUESTION FUNC_ATTR_NO_SANITIZE_UNDEFINED
+set QUESTION FUNC_ATTR_PRINTF
+set QUESTION FUNC_ATTR_PURE
+set QUESTION FUNC_ATTR_UNUSED
+set QUESTION FUNC_ATTR_WARN_UNUSED_RESULT
+set QUESTION REAL_FATTR_ALWAYS_INLINE
+set QUESTION REAL_FATTR_CONST
+set QUESTION REAL_FATTR_NONNULL_ALL
+set QUESTION REAL_FATTR_PURE
+set QUESTION REAL_FATTR_WARN_UNUSED_RESULT
+# option(s) with 'not default' value: 62
+#
diff --git a/src/nvim/xdiff/COPYING b/src/xdiff/COPYING
index f3f1b3b65e..f3f1b3b65e 100644
--- a/src/nvim/xdiff/COPYING
+++ b/src/xdiff/COPYING
diff --git a/src/nvim/xdiff/README.txt b/src/xdiff/README.txt
index 1afe74095b..95b2242b87 100644
--- a/src/nvim/xdiff/README.txt
+++ b/src/xdiff/README.txt
@@ -1,6 +1,6 @@
The files in this directory come from the xdiff implementation in git.
You can find it here: https://github.com/git/git/tree/master/xdiff
-The files were last updated 2018 September 10.
+The files were last updated August 31, 2021 from git release v.2.33.0
This is originally based on libxdiff, which can be found here:
http://www.xmailserver.org/xdiff-lib.html
diff --git a/src/nvim/xdiff/xdiff.h b/src/xdiff/xdiff.h
index 8ff4a05bfb..49985a0e9a 100644
--- a/src/nvim/xdiff/xdiff.h
+++ b/src/xdiff/xdiff.h
@@ -25,9 +25,9 @@
#ifdef __cplusplus
extern "C" {
-#endif // #ifdef __cplusplus
+#endif /* #ifdef __cplusplus */
-// xpparm_t.flags
+/* xpparm_t.flags */
#define XDF_NEED_MINIMAL (1 << 0)
#define XDF_IGNORE_WHITESPACE (1 << 1)
@@ -48,22 +48,23 @@ extern "C" {
#define XDF_INDENT_HEURISTIC (1 << 23)
-// xdemitconf_t.flags
+/* xdemitconf_t.flags */
#define XDL_EMIT_FUNCNAMES (1 << 0)
+#define XDL_EMIT_NO_HUNK_HDR (1 << 1)
#define XDL_EMIT_FUNCCONTEXT (1 << 2)
-// merge simplification levels
+/* merge simplification levels */
#define XDL_MERGE_MINIMAL 0
#define XDL_MERGE_EAGER 1
#define XDL_MERGE_ZEALOUS 2
#define XDL_MERGE_ZEALOUS_ALNUM 3
-// merge favor modes
+/* merge favor modes */
#define XDL_MERGE_FAVOR_OURS 1
#define XDL_MERGE_FAVOR_THEIRS 2
#define XDL_MERGE_FAVOR_UNION 3
-// merge output styles
+/* merge output styles */
#define XDL_MERGE_DIFF3 1
typedef struct s_mmfile {
@@ -79,14 +80,24 @@ typedef struct s_mmbuffer {
typedef struct s_xpparam {
unsigned long flags;
- // See Documentation/diff-options.txt.
+ /* -I<regex> */
+ #if 0 // unused by Vim
+ regex_t **ignore_regex;
+ size_t ignore_regex_nr;
+#endif
+
+ /* See Documentation/diff-options.txt. */
char **anchors;
size_t anchors_nr;
} xpparam_t;
typedef struct s_xdemitcb {
void *priv;
- int (*outf)(void *, mmbuffer_t *, int);
+ int (*out_hunk)(void *,
+ long old_begin, long old_nr,
+ long new_begin, long new_nr,
+ const char *func, long funclen);
+ int (*out_line)(void *, mmbuffer_t *, int);
} xdemitcb_t;
typedef long (*find_func_t)(const char *line, long line_len, char *buffer, long buffer_size, void *priv);
@@ -108,7 +119,7 @@ typedef struct s_bdiffparam {
long bsize;
} bdiffparam_t;
-#include "../memory.h"
+#include "../nvim/memory.h"
#define xdl_malloc(x) xmalloc((x))
#define xdl_free(ptr) xfree(ptr)
@@ -126,9 +137,9 @@ typedef struct s_xmparam {
int level;
int favor;
int style;
- const char *ancestor; // label for orig
- const char *file1; // label for mf1
- const char *file2; // label for mf2
+ const char *ancestor; /* label for orig */
+ const char *file1; /* label for mf1 */
+ const char *file2; /* label for mf2 */
} xmparam_t;
#define DEFAULT_CONFLICT_MARKER_SIZE 7
@@ -138,6 +149,6 @@ int xdl_merge(mmfile_t *orig, mmfile_t *mf1, mmfile_t *mf2,
#ifdef __cplusplus
}
-#endif // #ifdef __cplusplus
+#endif /* #ifdef __cplusplus */
-#endif // #if !defined(XDIFF_H)
+#endif /* #if !defined(XDIFF_H) */
diff --git a/src/nvim/xdiff/xdiffi.c b/src/xdiff/xdiffi.c
index 3806903986..cfcbb5d982 100644
--- a/src/nvim/xdiff/xdiffi.c
+++ b/src/xdiff/xdiffi.c
@@ -38,9 +38,9 @@ typedef struct s_xdpsplit {
* Basically considers a "box" (off1, off2, lim1, lim2) and scan from both
* the forward diagonal starting from (off1, off2) and the backward diagonal
* starting from (lim1, lim2). If the K values on the same diagonal crosses
- * returns the furthest point of reach. We might end up having to expensive
- * cases using this algorithm is full, so a little bit of heuristic is needed
- * to cut the search and to return a suboptimal point.
+ * returns the furthest point of reach. We might encounter expensive edge cases
+ * using this algorithm, so a little bit of heuristic is needed to cut the
+ * search and to return a suboptimal point.
*/
static long xdl_split(unsigned long const *ha1, long off1, long lim1,
unsigned long const *ha2, long off2, long lim2,
@@ -63,11 +63,13 @@ static long xdl_split(unsigned long const *ha1, long off1, long lim1,
int got_snake = 0;
/*
- * We need to extent the diagonal "domain" by one. If the next
+ * We need to extend the diagonal "domain" by one. If the next
* values exits the box boundaries we need to change it in the
- * opposite direction because (max - min) must be a power of two.
+ * opposite direction because (max - min) must be a power of
+ * two.
+ *
* Also we initialize the external K value to -1 so that we can
- * avoid extra conditions check inside the core loop.
+ * avoid extra conditions in the check inside the core loop.
*/
if (fmin > dmin)
kvdf[--fmin - 1] = -1;
@@ -98,11 +100,13 @@ static long xdl_split(unsigned long const *ha1, long off1, long lim1,
}
/*
- * We need to extent the diagonal "domain" by one. If the next
+ * We need to extend the diagonal "domain" by one. If the next
* values exits the box boundaries we need to change it in the
- * opposite direction because (max - min) must be a power of two.
+ * opposite direction because (max - min) must be a power of
+ * two.
+ *
* Also we initialize the external K value to -1 so that we can
- * avoid extra conditions check inside the core loop.
+ * avoid extra conditions in the check inside the core loop.
*/
if (bmin > dmin)
kvdb[--bmin - 1] = XDL_LINE_MAX;
@@ -138,7 +142,7 @@ static long xdl_split(unsigned long const *ha1, long off1, long lim1,
/*
* If the edit cost is above the heuristic trigger and if
* we got a good snake, we sample current diagonals to see
- * if some of the, have reached an "interesting" path. Our
+ * if some of them have reached an "interesting" path. Our
* measure is a function of the distance from the diagonal
* corner (i1 + i2) penalized with the distance from the
* mid diagonal itself. If this value is above the current
@@ -196,8 +200,9 @@ static long xdl_split(unsigned long const *ha1, long off1, long lim1,
}
/*
- * Enough is enough. We spent too much time here and now we collect
- * the furthest reaching path using the (i1 + i2) measure.
+ * Enough is enough. We spent too much time here and now we
+ * collect the furthest reaching path using the (i1 + i2)
+ * measure.
*/
if (ec >= xenv->mxcost) {
long fbest, fbest1, bbest, bbest1;
@@ -244,9 +249,9 @@ static long xdl_split(unsigned long const *ha1, long off1, long lim1,
/*
- * Rule: "Divide et Impera". Recursively split the box in sub-boxes by calling
- * the box splitting function. Note that the real job (marking changed lines)
- * is done in the two boundary reaching checks.
+ * Rule: "Divide et Impera" (divide & conquer). Recursively split the box in
+ * sub-boxes by calling the box splitting function. Note that the real job
+ * (marking changed lines) is done in the two boundary reaching checks.
*/
int xdl_recs_cmp(diffdata_t *dd1, long off1, long lim1,
diffdata_t *dd2, long off2, long lim2,
@@ -323,7 +328,9 @@ int xdl_do_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
}
/*
- * Allocate and setup K vectors to be used by the differential algorithm.
+ * Allocate and setup K vectors to be used by the differential
+ * algorithm.
+ *
* One is to store the forward path and one to store the backward path.
*/
ndiags = xe->xdf1.nreff + xe->xdf2.nreff + 3;
@@ -418,13 +425,13 @@ static int xget_indent(xrecord_t *rec)
ret += 1;
else if (c == '\t')
ret += 8 - ret % 8;
- // ignore other whitespace characters
+ /* ignore other whitespace characters */
if (ret >= MAX_INDENT)
return MAX_INDENT;
}
- // The line contains only whitespace.
+ /* The line contains only whitespace. */
return -1;
}
@@ -435,7 +442,7 @@ static int xget_indent(xrecord_t *rec)
*/
#define MAX_BLANKS 20
-// Characteristics measured about a hypothetical split position.
+/* Characteristics measured about a hypothetical split position. */
struct split_measurement {
/*
* Is the split at the end of the file (aside from any blank lines)?
@@ -443,8 +450,8 @@ struct split_measurement {
int end_of_file;
/*
- * How much is the line immediately following the split indented (or -1 if
- * the line is blank):
+ * How much is the line immediately following the split indented (or -1
+ * if the line is blank):
*/
int indent;
@@ -454,8 +461,8 @@ struct split_measurement {
int pre_blank;
/*
- * How much is the nearest non-blank line above the split indented (or -1
- * if there is no such line)?
+ * How much is the nearest non-blank line above the split indented (or
+ * -1 if there is no such line)?
*/
int pre_indent;
@@ -472,10 +479,10 @@ struct split_measurement {
};
struct split_score {
- // The effective indent of this split (smaller is preferred).
+ /* The effective indent of this split (smaller is preferred). */
int effective_indent;
- // Penalty for this split (smaller is preferred).
+ /* Penalty for this split (smaller is preferred). */
int penalty;
};
@@ -534,16 +541,16 @@ static void measure_split(const xdfile_t *xdf, long split,
* integer math.
*/
-// Penalty if there are no non-blank lines before the split
+/* Penalty if there are no non-blank lines before the split */
#define START_OF_FILE_PENALTY 1
-// Penalty if there are no non-blank lines after the split
+/* Penalty if there are no non-blank lines after the split */
#define END_OF_FILE_PENALTY 21
-// Multiplier for the number of blank lines around the split
+/* Multiplier for the number of blank lines around the split */
#define TOTAL_BLANK_WEIGHT (-30)
-// Multiplier for the number of blank lines after the split
+/* Multiplier for the number of blank lines after the split */
#define POST_BLANK_WEIGHT 6
/*
@@ -581,13 +588,13 @@ static void measure_split(const xdfile_t *xdf, long split,
/*
* Compute a badness score for the hypothetical split whose measurements are
- * stored in m. The weight factors were determined empirically using the tools and
- * corpus described in
+ * stored in m. The weight factors were determined empirically using the tools
+ * and corpus described in
*
* https://github.com/mhagger/diff-slider-tools
*
- * Also see that project if you want to improve the weights based on, for example,
- * a larger or more diverse corpus.
+ * Also see that project if you want to improve the weights based on, for
+ * example, a larger or more diverse corpus.
*/
static void score_add_split(const struct split_measurement *m, struct split_score *s)
{
@@ -610,7 +617,7 @@ static void score_add_split(const struct split_measurement *m, struct split_scor
post_blank = (m->indent == -1) ? 1 + m->post_blank : 0;
total_blank = m->pre_blank + post_blank;
- // Penalties based on nearby blank lines:
+ /* Penalties based on nearby blank lines: */
s->penalty += TOTAL_BLANK_WEIGHT * total_blank;
s->penalty += POST_BLANK_WEIGHT * post_blank;
@@ -621,13 +628,13 @@ static void score_add_split(const struct split_measurement *m, struct split_scor
any_blanks = (total_blank != 0);
- // Note that the effective indent is -1 at the end of the file:
+ /* Note that the effective indent is -1 at the end of the file: */
s->effective_indent += indent;
if (indent == -1) {
- // No additional adjustments needed.
+ /* No additional adjustments needed. */
} else if (m->pre_indent == -1) {
- // No additional adjustments needed.
+ /* No additional adjustments needed. */
} else if (indent > m->pre_indent) {
/*
* The line is indented more than its predecessor.
@@ -669,7 +676,7 @@ static void score_add_split(const struct split_measurement *m, struct split_scor
static int score_cmp(struct split_score *s1, struct split_score *s2)
{
- // -1 if s1.effective_indent < s2->effective_indent, etc.
+ /* -1 if s1.effective_indent < s2->effective_indent, etc. */
int cmp_indents = ((s1->effective_indent > s2->effective_indent) -
(s1->effective_indent < s2->effective_indent));
@@ -809,13 +816,16 @@ int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags) {
group_init(xdfo, &go);
while (1) {
- // If the group is empty in the to-be-compacted file, skip it:
+ /*
+ * If the group is empty in the to-be-compacted file, skip it:
+ */
if (g.end == g.start)
goto next;
/*
* Now shift the change up and then down as far as possible in
- * each direction. If it bumps into any other changes, merge them.
+ * each direction. If it bumps into any other changes, merge
+ * them.
*/
do {
groupsize = g.end - g.start;
@@ -828,7 +838,7 @@ int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags) {
*/
end_matching_other = -1;
- // Shift the group backward as much as possible:
+ /* Shift the group backward as much as possible: */
while (!group_slide_up(xdf, &g, flags))
if (group_previous(xdfo, &go))
xdl_bug("group sync broken sliding up");
@@ -842,7 +852,7 @@ int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags) {
if (go.end > go.start)
end_matching_other = g.end;
- // Now shift the group forward as far as possible:
+ /* Now shift the group forward as far as possible: */
while (1) {
if (group_slide_down(xdf, &g, flags))
break;
@@ -858,17 +868,17 @@ int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags) {
* If the group can be shifted, then we can possibly use this
* freedom to produce a more intuitive diff.
*
- * The group is currently shifted as far down as possible, so the
- * heuristics below only have to handle upwards shifts.
+ * The group is currently shifted as far down as possible, so
+ * the heuristics below only have to handle upwards shifts.
*/
if (g.end == earliest_end) {
- // no shifting was possible
+ /* no shifting was possible */
} else if (end_matching_other != -1) {
/*
- * Move the possibly merged group of changes back to line
- * up with the last group of changes from the other file
- * that it can align with.
+ * Move the possibly merged group of changes back to
+ * line up with the last group of changes from the
+ * other file that it can align with.
*/
while (go.end == go.start) {
if (group_slide_up(xdf, &g, flags))
@@ -879,14 +889,15 @@ int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags) {
} else if (flags & XDF_INDENT_HEURISTIC) {
/*
* Indent heuristic: a group of pure add/delete lines
- * implies two splits, one between the end of the "before"
- * context and the start of the group, and another between
- * the end of the group and the beginning of the "after"
- * context. Some splits are aesthetically better and some
- * are worse. We compute a badness "score" for each split,
- * and add the scores for the two splits to define a
- * "score" for each position that the group can be shifted
- * to. Then we pick the shift with the lowest score.
+ * implies two splits, one between the end of the
+ * "before" context and the start of the group, and
+ * another between the end of the group and the
+ * beginning of the "after" context. Some splits are
+ * aesthetically better and some are worse. We compute
+ * a badness "score" for each split, and add the scores
+ * for the two splits to define a "score" for each
+ * position that the group can be shifted to. Then we
+ * pick the shift with the lowest score.
*/
long shift, best_shift = -1;
struct split_score best_score;
@@ -921,7 +932,7 @@ int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags) {
}
next:
- // Move past the just-processed group:
+ /* Move past the just-processed group: */
if (group_next(xdf, &g))
break;
if (group_next(xdfo, &go))
@@ -987,7 +998,7 @@ static int xdl_call_hunk_func(xdfenv_t *xe UNUSED, xdchange_t *xscr, xdemitcb_t
return 0;
}
-static void xdl_mark_ignorable(xdchange_t *xscr, xdfenv_t *xe, long flags)
+static void xdl_mark_ignorable_lines(xdchange_t *xscr, xdfenv_t *xe, long flags)
{
xdchange_t *xch;
@@ -1008,6 +1019,48 @@ static void xdl_mark_ignorable(xdchange_t *xscr, xdfenv_t *xe, long flags)
}
}
+#if 0 // unused by Vim
+static int record_matches_regex(xrecord_t *rec, xpparam_t const *xpp) {
+ regmatch_t regmatch;
+ int i;
+
+ for (i = 0; i < xpp->ignore_regex_nr; i++)
+ if (!regexec_buf(xpp->ignore_regex[i], rec->ptr, rec->size, 1,
+ &regmatch, 0))
+ return 1;
+
+ return 0;
+}
+
+static void xdl_mark_ignorable_regex(xdchange_t *xscr, const xdfenv_t *xe,
+ xpparam_t const *xpp)
+{
+ xdchange_t *xch;
+
+ for (xch = xscr; xch; xch = xch->next) {
+ xrecord_t **rec;
+ int ignore = 1;
+ long i;
+
+ /*
+ * Do not override --ignore-blank-lines.
+ */
+ if (xch->ignore)
+ continue;
+
+ rec = &xe->xdf1.recs[xch->i1];
+ for (i = 0; i < xch->chg1 && ignore; i++)
+ ignore = record_matches_regex(rec[i], xpp);
+
+ rec = &xe->xdf2.recs[xch->i2];
+ for (i = 0; i < xch->chg2 && ignore; i++)
+ ignore = record_matches_regex(rec[i], xpp);
+
+ xch->ignore = ignore;
+ }
+}
+#endif
+
int xdl_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
xdemitconf_t const *xecfg, xdemitcb_t *ecb) {
xdchange_t *xscr;
@@ -1027,7 +1080,12 @@ int xdl_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
}
if (xscr) {
if (xpp->flags & XDF_IGNORE_BLANK_LINES)
- xdl_mark_ignorable(xscr, &xe, xpp->flags);
+ xdl_mark_ignorable_lines(xscr, &xe, xpp->flags);
+
+#if 0
+ if (xpp->ignore_regex)
+ xdl_mark_ignorable_regex(xscr, &xe, xpp);
+#endif
if (ef(&xe, xscr, ecb, xecfg) < 0) {
diff --git a/src/nvim/xdiff/xdiffi.h b/src/xdiff/xdiffi.h
index 467a1e85cd..8f1c7c8b04 100644
--- a/src/nvim/xdiff/xdiffi.h
+++ b/src/xdiff/xdiffi.h
@@ -61,4 +61,4 @@ int xdl_do_patience_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
int xdl_do_histogram_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
xdfenv_t *env);
-#endif // #if !defined(XDIFFI_H)
+#endif /* #if !defined(XDIFFI_H) */
diff --git a/src/nvim/xdiff/xemit.c b/src/xdiff/xemit.c
index f1a45139cc..b578e7a9d5 100644
--- a/src/nvim/xdiff/xemit.c
+++ b/src/xdiff/xemit.c
@@ -54,9 +54,9 @@ xdchange_t *xdl_get_hunk(xdchange_t **xscr, xdemitconf_t const *xecfg)
xdchange_t *xch, *xchp, *lxch;
long max_common = 2 * xecfg->ctxlen + xecfg->interhunkctxlen;
long max_ignorable = xecfg->ctxlen;
- unsigned long ignored = 0; // number of ignored blank lines
+ unsigned long ignored = 0; /* number of ignored blank lines */
- // remove ignorable changes that are too far before other changes
+ /* remove ignorable changes that are too far before other changes */
for (xchp = *xscr; xchp && xchp->ignore; xchp = xchp->next) {
xch = xchp->next;
@@ -99,9 +99,9 @@ xdchange_t *xdl_get_hunk(xdchange_t **xscr, xdemitconf_t const *xecfg)
static long def_ff(const char *rec, long len, char *buf, long sz, void *priv UNUSED)
{
if (len > 0 &&
- (isalpha((unsigned char)*rec) || // identifier?
- *rec == '_' || // also identifier?
- *rec == '$')) { // identifiers from VMS and other esoterico
+ (isalpha((unsigned char)*rec) || /* identifier? */
+ *rec == '_' || /* also identifier? */
+ *rec == '$')) { /* identifiers from VMS and other esoterico */
if (len > sz)
len = sz;
while (0 < len && isspace((unsigned char)rec[len - 1]))
@@ -197,7 +197,7 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
if (xecfg->flags & XDL_EMIT_FUNCCONTEXT) {
long fs1, i1 = xch->i1;
- // Appended chunk?
+ /* Appended chunk? */
if (i1 >= xe->xdf1.nrec) {
long i2 = xch->i2;
@@ -225,8 +225,23 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
if (fs1 < 0)
fs1 = 0;
if (fs1 < s1) {
- s2 -= s1 - fs1;
+ s2 = XDL_MAX(s2 - (s1 - fs1), 0);
s1 = fs1;
+
+ /*
+ * Did we extend context upwards into an
+ * ignored change?
+ */
+ while (xchp != xch &&
+ xchp->i1 + xchp->chg1 <= s1 &&
+ xchp->i2 + xchp->chg2 <= s2)
+ xchp = xchp->next;
+
+ /* If so, show it after all. */
+ if (xchp != xch) {
+ xch = xchp;
+ goto pre_context_calculation;
+ }
}
}
@@ -249,7 +264,7 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
if (fe1 < 0)
fe1 = xe->xdf1.nrec;
if (fe1 > e1) {
- e2 += fe1 - e1;
+ e2 = XDL_MIN(e2 + (fe1 - e1), xe->xdf2.nrec);
e1 = fe1;
}
@@ -281,7 +296,8 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
funclineprev = s1 - 1;
}
#endif
- if (xdl_emit_hunk_hdr(s1 + 1, e1 - s1, s2 + 1, e2 - s2,
+ if (!(xecfg->flags & XDL_EMIT_NO_HUNK_HDR) &&
+ xdl_emit_hunk_hdr(s1 + 1, e1 - s1, s2 + 1, e2 - s2,
func_line.buf, func_line.len, ecb) < 0)
return -1;
diff --git a/src/nvim/xdiff/xemit.h b/src/xdiff/xemit.h
index 3ce7e3dd50..1b9887e670 100644
--- a/src/nvim/xdiff/xemit.h
+++ b/src/xdiff/xemit.h
@@ -33,4 +33,4 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
-#endif // #if !defined(XEMIT_H)
+#endif /* #if !defined(XEMIT_H) */
diff --git a/src/nvim/xdiff/xhistogram.c b/src/xdiff/xhistogram.c
index 28cf8258e5..8598a8550d 100644
--- a/src/nvim/xdiff/xhistogram.c
+++ b/src/xdiff/xhistogram.c
@@ -42,8 +42,6 @@
*/
#include "xinclude.h"
-#include "xtypes.h"
-#include "xdiff.h"
#define MAX_PTR INT_MAX
#define MAX_CNT INT_MAX
@@ -55,8 +53,8 @@ struct histindex {
struct record {
unsigned int ptr, cnt;
struct record *next;
- } **records, // an occurrence
- **line_map; // map of line to record chain
+ } **records, /* an occurrence */
+ **line_map; /* map of line to record chain */
chastore_t rcha;
unsigned int *next_ptrs;
unsigned int table_bits,
@@ -128,7 +126,7 @@ static int scanA(struct histindex *index, int line1, int count1)
*/
NEXT_PTR(index, ptr) = rec->ptr;
rec->ptr = ptr;
- // cap rec->cnt at MAX_CNT
+ /* cap rec->cnt at MAX_CNT */
rec->cnt = XDL_MIN(MAX_CNT, rec->cnt + 1);
LINE_MAP(index, ptr) = rec;
goto continue_scan;
@@ -154,7 +152,7 @@ static int scanA(struct histindex *index, int line1, int count1)
LINE_MAP(index, ptr) = rec;
continue_scan:
- ; // no op
+ ; /* no op */
}
return 0;
@@ -237,6 +235,8 @@ static int fall_back_to_classic_diff(xpparam_t const *xpp, xdfenv_t *env,
int line1, int count1, int line2, int count2)
{
xpparam_t xpparam;
+
+ memset(&xpparam, 0, sizeof(xpparam));
xpparam.flags = xpp->flags & ~XDF_DIFF_ALGORITHM_MASK;
return xdl_fall_back_diff(env, &xpparam,
@@ -266,7 +266,7 @@ static int find_lcs(xpparam_t const *xpp, xdfenv_t *env,
index.records = NULL;
index.line_map = NULL;
- // in case of early xdl_cha_free()
+ /* in case of early xdl_cha_free() */
index.rcha.head = NULL;
index.table_bits = xdl_hashbits(count1);
@@ -288,7 +288,7 @@ static int find_lcs(xpparam_t const *xpp, xdfenv_t *env,
goto cleanup;
memset(index.next_ptrs, 0, sz);
- // lines / 4 + 1 comes from xprepare.c:xdl_prepare_ctx()
+ /* lines / 4 + 1 comes from xprepare.c:xdl_prepare_ctx() */
if (xdl_cha_init(&index.rcha, sizeof(struct record), count1 / 4 + 1) < 0)
goto cleanup;
diff --git a/src/nvim/xdiff/xinclude.h b/src/xdiff/xinclude.h
index 5a359d1431..a412404bfe 100644
--- a/src/nvim/xdiff/xinclude.h
+++ b/src/xdiff/xinclude.h
@@ -40,6 +40,7 @@
#if !defined(XINCLUDE_H)
#define XINCLUDE_H
+// This effectively re-verts b46054b3746271d23feab0 from git
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
@@ -48,7 +49,10 @@
#endif
#include <string.h>
#include <limits.h>
-
+// This include comes from git, so uncomment it
+#if 0
+#include "git-compat-util.h"
+#endif
#include "xmacros.h"
#include "xdiff.h"
#include "xtypes.h"
@@ -58,4 +62,4 @@
#include "xemit.h"
-#endif // #if !defined(XINCLUDE_H)
+#endif /* #if !defined(XINCLUDE_H) */
diff --git a/src/nvim/xdiff/xmacros.h b/src/xdiff/xmacros.h
index 1167ebbb05..2809a28ca9 100644
--- a/src/nvim/xdiff/xmacros.h
+++ b/src/xdiff/xmacros.h
@@ -51,4 +51,4 @@ do { \
} while (0)
-#endif // #if !defined(XMACROS_H)
+#endif /* #if !defined(XMACROS_H) */
diff --git a/src/nvim/xdiff/xpatience.c b/src/xdiff/xpatience.c
index f6c84c67d8..f78c897ad8 100644
--- a/src/nvim/xdiff/xpatience.c
+++ b/src/xdiff/xpatience.c
@@ -20,8 +20,6 @@
*
*/
#include "xinclude.h"
-#include "xtypes.h"
-#include "xdiff.h"
/*
* The basic idea of patience diff is to find lines that are unique in
@@ -69,7 +67,7 @@ struct hashmap {
*/
unsigned anchor : 1;
} *entries, *first, *last;
- // were common records found?
+ /* were common records found? */
unsigned long has_matches;
mmfile_t *file1, *file2;
xdfenv_t *env;
@@ -78,21 +76,21 @@ struct hashmap {
static int is_anchor(xpparam_t const *xpp, const char *line)
{
- size_t i;
- for (i = 0; i < xpp->anchors_nr; i++) {
+ int i;
+ for (i = 0; i < (int)xpp->anchors_nr; i++) {
if (!strncmp(line, xpp->anchors[i], strlen(xpp->anchors[i])))
return 1;
}
return 0;
}
-// The argument "pass" is 1 for the first file, 2 for the second.
+/* The argument "pass" is 1 for the first file, 2 for the second. */
static void insert_record(xpparam_t const *xpp, int line, struct hashmap *map,
int pass)
{
xrecord_t **records = pass == 1 ?
map->env->xdf1.recs : map->env->xdf2.recs;
- xrecord_t *record = records[line - 1], *other;
+ xrecord_t *record = records[line - 1];
/*
* After xdl_prepare_env() (or more precisely, due to
* xdl_classify_record()), the "ha" member of the records (AKA lines)
@@ -106,11 +104,7 @@ static void insert_record(xpparam_t const *xpp, int line, struct hashmap *map,
int index = (int)((record->ha << 1) % map->alloc);
while (map->entries[index].line1) {
- other = map->env->xdf1.recs[map->entries[index].line1 - 1];
- if (map->entries[index].hash != record->ha ||
- !xdl_recmatch(record->ptr, record->size,
- other->ptr, other->size,
- map->xpp->flags)) {
+ if (map->entries[index].hash != record->ha) {
if (++index >= map->alloc)
index = 0;
continue;
@@ -155,7 +149,7 @@ static int fill_hashmap(mmfile_t *file1, mmfile_t *file2,
result->xpp = xpp;
result->env = env;
- // We know exactly how large we want the hash map
+ /* We know exactly how large we want the hash map */
result->alloc = count1 * 2;
result->entries = (struct entry *)
xdl_malloc(result->alloc * sizeof(struct entry));
@@ -163,11 +157,11 @@ static int fill_hashmap(mmfile_t *file1, mmfile_t *file2,
return -1;
memset(result->entries, 0, result->alloc * sizeof(struct entry));
- // First, fill with entries from the first file
+ /* First, fill with entries from the first file */
while (count1--)
insert_record(xpp, line1++, result, 1);
- // Then search for matches in the second file
+ /* Then search for matches in the second file */
while (count2--)
insert_record(xpp, line2++, result, 2);
@@ -185,13 +179,13 @@ static int binary_search(struct entry **sequence, int longest,
while (left + 1 < right) {
int middle = left + (right - left) / 2;
- // by construction, no two entries can be equal
+ /* by construction, no two entries can be equal */
if (sequence[middle]->line2 > entry->line2)
right = middle;
else
left = middle;
}
- // return the index in "sequence", _not_ the sequence length
+ /* return the index in "sequence", _not_ the sequence length */
return left;
}
@@ -206,9 +200,10 @@ static int binary_search(struct entry **sequence, int longest,
*/
static struct entry *find_longest_common_sequence(struct hashmap *map)
{
- struct entry **sequence = (struct entry **)xdl_malloc(map->nr * sizeof(struct entry *));
+ struct entry **sequence = xdl_malloc(map->nr * sizeof(struct entry *));
int longest = 0, i;
struct entry *entry;
+
/*
* If not -1, this entry in sequence must never be overridden.
* Therefore, overriding entries before this has no effect, so
@@ -237,13 +232,13 @@ static struct entry *find_longest_common_sequence(struct hashmap *map)
}
}
- // No common unique lines were found
+ /* No common unique lines were found */
if (!longest) {
xdl_free(sequence);
return NULL;
}
- // Iterate starting at the last element, adjusting the "next" members
+ /* Iterate starting at the last element, adjusting the "next" members */
entry = sequence[longest - 1];
entry->next = NULL;
while (entry->previous) {
@@ -258,8 +253,7 @@ static int match(struct hashmap *map, int line1, int line2)
{
xrecord_t *record1 = map->env->xdf1.recs[line1 - 1];
xrecord_t *record2 = map->env->xdf2.recs[line2 - 1];
- return xdl_recmatch(record1->ptr, record1->size,
- record2->ptr, record2->size, map->xpp->flags);
+ return record1->ha == record2->ha;
}
static int patience_diff(mmfile_t *file1, mmfile_t *file2,
@@ -273,7 +267,7 @@ static int walk_common_sequence(struct hashmap *map, struct entry *first,
int next1, next2;
for (;;) {
- // Try to grow the line ranges of common lines
+ /* Try to grow the line ranges of common lines */
if (first) {
next1 = first->line1;
next2 = first->line2;
@@ -292,11 +286,8 @@ static int walk_common_sequence(struct hashmap *map, struct entry *first,
line2++;
}
- // Recurse
+ /* Recurse */
if (next1 > line1 || next2 > line2) {
- struct hashmap submap;
-
- memset(&submap, 0, sizeof(submap));
if (patience_diff(map->file1, map->file2,
map->xpp, map->env,
line1, next1 - line1,
@@ -323,6 +314,8 @@ static int fall_back_to_classic_diff(struct hashmap *map,
int line1, int count1, int line2, int count2)
{
xpparam_t xpp;
+
+ memset(&xpp, 0, sizeof(xpp));
xpp.flags = map->xpp->flags & ~XDF_DIFF_ALGORITHM_MASK;
return xdl_fall_back_diff(map->env, &xpp,
@@ -343,7 +336,7 @@ static int patience_diff(mmfile_t *file1, mmfile_t *file2,
struct entry *first;
int result = 0;
- // trivial case: one side is empty
+ /* trivial case: one side is empty */
if (!count1) {
while(count2--)
env->xdf2.rchg[line2++ - 1] = 1;
@@ -359,7 +352,7 @@ static int patience_diff(mmfile_t *file1, mmfile_t *file2,
line1, count1, line2, count2))
return -1;
- // are there any matching lines at all?
+ /* are there any matching lines at all? */
if (!map.has_matches) {
while(count1--)
env->xdf1.rchg[line1++ - 1] = 1;
@@ -387,7 +380,7 @@ int xdl_do_patience_diff(mmfile_t *file1, mmfile_t *file2,
if (xdl_prepare_env(file1, file2, xpp, env) < 0)
return -1;
- // environment is cleaned up in xdl_diff()
+ /* environment is cleaned up in xdl_diff() */
return patience_diff(file1, file2, xpp, env,
1, env->xdf1.nrec, 1, env->xdf2.nrec);
}
diff --git a/src/nvim/xdiff/xprepare.c b/src/xdiff/xprepare.c
index abeb8fb84e..abeb8fb84e 100644
--- a/src/nvim/xdiff/xprepare.c
+++ b/src/xdiff/xprepare.c
diff --git a/src/nvim/xdiff/xprepare.h b/src/xdiff/xprepare.h
index b67b3b25ab..947d9fc1bb 100644
--- a/src/nvim/xdiff/xprepare.h
+++ b/src/xdiff/xprepare.h
@@ -31,4 +31,4 @@ void xdl_free_env(xdfenv_t *xe);
-#endif // #if !defined(XPREPARE_H)
+#endif /* #if !defined(XPREPARE_H) */
diff --git a/src/nvim/xdiff/xtypes.h b/src/xdiff/xtypes.h
index 026999c1bf..8442bd436e 100644
--- a/src/nvim/xdiff/xtypes.h
+++ b/src/xdiff/xtypes.h
@@ -64,4 +64,4 @@ typedef struct s_xdfenv {
-#endif // #if !defined(XTYPES_H)
+#endif /* #if !defined(XTYPES_H) */
diff --git a/src/nvim/xdiff/xutils.c b/src/xdiff/xutils.c
index e8c7d2f884..f13a854536 100644
--- a/src/nvim/xdiff/xutils.c
+++ b/src/xdiff/xutils.c
@@ -20,13 +20,9 @@
*
*/
-#include <limits.h>
-#include <assert.h>
#include "xinclude.h"
-
-
long xdl_bogosqrt(long n) {
long i;
@@ -54,7 +50,7 @@ int xdl_emit_diffrec(char const *rec, long size, char const *pre, long psize,
mb[2].size = (long)strlen(mb[2].ptr);
i++;
}
- if (ecb->outf(ecb->priv, mb, i) < 0) {
+ if (ecb->out_line(ecb->priv, mb, i) < 0) {
return -1;
}
@@ -168,7 +164,7 @@ static int ends_with_optional_cr(const char *l, long s, long i)
s--;
if (s == i)
return 1;
- // do not ignore CR at the end of an incomplete line
+ /* do not ignore CR at the end of an incomplete line */
if (complete && s == i + 1 && l[i] == '\r')
return 1;
return 0;
@@ -208,7 +204,7 @@ int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags)
} else if (flags & XDF_IGNORE_WHITESPACE_CHANGE) {
while (i1 < s1 && i2 < s2) {
if (XDL_ISSPACE(l1[i1]) && XDL_ISSPACE(l2[i2])) {
- // Skip matching spaces and try again
+ /* Skip matching spaces and try again */
while (i1 < s1 && XDL_ISSPACE(l1[i1]))
i1++;
while (i2 < s2 && XDL_ISSPACE(l2[i2]))
@@ -224,7 +220,7 @@ int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags)
i2++;
}
} else if (flags & XDF_IGNORE_CR_AT_EOL) {
- // Find the first difference and see how the line ends
+ /* Find the first difference and see how the line ends */
while (i1 < s1 && i2 < s2 && l1[i1] == l2[i2]) {
i1++;
i2++;
@@ -261,7 +257,7 @@ static unsigned long xdl_hash_record_with_whitespace(char const **data,
for (; ptr < top && *ptr != '\n'; ptr++) {
if (cr_at_eol_only) {
- // do not ignore CR at the end of an incomplete line
+ /* do not ignore CR at the end of an incomplete line */
if (*ptr == '\r' &&
(ptr + 1 < top && ptr[1] == '\n'))
continue;
@@ -274,7 +270,7 @@ static unsigned long xdl_hash_record_with_whitespace(char const **data,
ptr++;
at_eol = (top <= ptr + 1 || ptr[1] == '\n');
if (flags & XDF_IGNORE_WHITESPACE)
- ; // already handled
+ ; /* already handled */
else if (flags & XDF_IGNORE_WHITESPACE_CHANGE
&& !at_eol) {
ha += (ha << 5);
@@ -344,8 +340,9 @@ int xdl_num_out(char *out, long val) {
return str - out;
}
-int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2,
- const char *func, long funclen, xdemitcb_t *ecb) {
+static int xdl_format_hunk_hdr(long s1, long c1, long s2, long c2,
+ const char *func, long funclen,
+ xdemitcb_t *ecb) {
int nb = 0;
mmbuffer_t mb;
char buf[128];
@@ -387,9 +384,21 @@ int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2,
mb.ptr = buf;
mb.size = nb;
- if (ecb->outf(ecb->priv, &mb, 1) < 0)
+ if (ecb->out_line(ecb->priv, &mb, 1) < 0)
return -1;
+ return 0;
+}
+int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2,
+ const char *func, long funclen,
+ xdemitcb_t *ecb) {
+ if (!ecb->out_hunk)
+ return xdl_format_hunk_hdr(s1, c1, s2, c2, func, funclen, ecb);
+ if (ecb->out_hunk(ecb->priv,
+ c1 ? s1 : s1 - 1, c1,
+ c2 ? s2 : s2 - 1, c2,
+ func, funclen) < 0)
+ return -1;
return 0;
}
diff --git a/src/nvim/xdiff/xutils.h b/src/xdiff/xutils.h
index 0bebd93022..fba7bae03c 100644
--- a/src/nvim/xdiff/xutils.h
+++ b/src/xdiff/xutils.h
@@ -44,4 +44,4 @@ int xdl_fall_back_diff(xdfenv_t *diff_env, xpparam_t const *xpp,
-#endif // #if !defined(XUTILS_H)
+#endif /* #if !defined(XUTILS_H) */