diff options
Diffstat (limited to 'src')
55 files changed, 1154 insertions, 798 deletions
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/private/dispatch.c b/src/nvim/api/private/dispatch.c index eae4581f42..9f16da4078 100644 --- a/src/nvim/api/private/dispatch.c +++ b/src/nvim/api/private/dispatch.c @@ -21,12 +21,12 @@ #include "nvim/api/window.h" #include "nvim/api/deprecated.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) { - map_put(String, MsgpackRpcRequestHandler)(methods, method, handler); + map_put(String, MsgpackRpcRequestHandler)(&methods, method, handler); } /// @param name API method name @@ -37,7 +37,7 @@ MsgpackRpcRequestHandler msgpack_rpc_get_handler_for(const char *name, { 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", 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 3ec6151090..eedcfd69b8 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -9,7 +9,6 @@ #include "nvim/api/private/helpers.h" #include "nvim/api/private/defs.h" -#include "nvim/api/private/handle.h" #include "nvim/api/vim.h" #include "nvim/msgpack_rpc/helpers.h" #include "nvim/lua/executor.h" @@ -1725,7 +1724,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; } 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/ui.c b/src/nvim/api/ui.c index 63e6ad883a..713980ca68 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -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. @@ -95,7 +89,7 @@ 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; @@ -172,7 +166,7 @@ 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); } @@ -195,7 +189,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; @@ -208,7 +202,7 @@ 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,7 +214,7 @@ 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(); @@ -230,12 +224,12 @@ 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); } @@ -310,7 +304,7 @@ 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 +322,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 +333,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"); @@ -369,13 +363,13 @@ 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"); diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 400dbb126c..90c43a1b04 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -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 @@ -1568,14 +1562,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 +1584,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)); }) 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/autocmd.c b/src/nvim/autocmd.c index bec9808183..417953eb14 100644 --- a/src/nvim/autocmd.c +++ b/src/nvim/autocmd.c @@ -5,7 +5,7 @@ #include "nvim/autocmd.h" -#include "nvim/api/private/handle.h" +#include "nvim/api/private/helpers.h" #include "nvim/ascii.h" #include "nvim/buffer.h" #include "nvim/charset.h" @@ -1150,7 +1150,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() @@ -1191,7 +1191,7 @@ void aucmd_restbuf(aco_save_T *aco) 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); diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 29d4fc786a..fdb3ffdc7e 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -24,7 +24,6 @@ #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" @@ -532,7 +531,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. @@ -757,7 +756,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); @@ -1841,7 +1840,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) { diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index b03d69a04c..0ae8dd3664 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -863,8 +863,8 @@ 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 // array of channel_id:s which have asked to receive updates for this // buffer. diff --git a/src/nvim/change.c b/src/nvim/change.c index 41e1e3911b..13b86e9244 100644 --- a/src/nvim/change.c +++ b/src/nvim/change.c @@ -1837,7 +1837,7 @@ 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; diff --git a/src/nvim/channel.c b/src/nvim/channel.c index a0db1bcdfd..6f12d2eab8 100644 --- a/src/nvim/channel.c +++ b/src/nvim/channel.c @@ -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); }); } @@ -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; } @@ -249,7 +244,7 @@ static void free_channel_event(void **argv) callback_reader_free(&chan->on_stderr); callback_free(&chan->on_exit); - pmap_del(uint64_t)(channels, chan->id); + pmap_del(uint64_t)(&channels, chan->id); multiqueue_free(chan->events); xfree(chan); } @@ -259,7 +254,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)) { @@ -698,9 +693,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. @@ -901,7 +894,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 df858e1602..9bc0df3615 100644 --- a/src/nvim/channel.h +++ b/src/nvim/channel.h @@ -89,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" @@ -98,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/decoration.c b/src/nvim/decoration.c index 74cb9a26b7..5168ed6d0f 100644 --- a/src/nvim/decoration.c +++ b/src/nvim/decoration.c @@ -13,12 +13,7 @@ # 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. @@ -77,7 +72,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; @@ -150,7 +145,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); } diff --git a/src/nvim/edit.c b/src/nvim/edit.c index fec8da2c3c..ffe60ab043 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -1652,8 +1652,8 @@ 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()); @@ -8124,8 +8124,7 @@ 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); diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 789936fdff..5e18a77b6d 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -265,7 +265,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,7 +326,6 @@ void eval_init(void) { vimvars[VV_VERSION].vv_nr = VIM_VERSION_100; - timers = pmap_new(uint64_t)(); struct vimvar *p; init_var_dict(&globvardict, &globvars_var, VAR_DEF_SCOPE); @@ -4883,7 +4882,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 +4892,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); }) } @@ -7304,7 +7303,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 +7330,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); } @@ -7413,7 +7412,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 +7434,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 +7448,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); }) } diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 0c099085a0..f7a1327c87 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -715,7 +715,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; @@ -766,10 +766,11 @@ void ex_retab(exarg_T *eap) 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 */ @@ -824,7 +825,7 @@ void ex_retab(exarg_T *eap) col = start_col + len; } } - got_tab = FALSE; + got_tab = false; num_spaces = 0; } if (ptr[col] == NUL) @@ -1386,11 +1387,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 { /* @@ -3835,7 +3836,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; @@ -5171,21 +5172,21 @@ void fix_help_buffer(void) if (in_example && len > 0 && !ascii_iswhite(line[0])) { /* End of example: non-white or '<' in first column. */ if (line[0] == '<') { - /* blank-out a '<' in the first column */ - line = ml_get_buf(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] = ' '; } } @@ -5204,10 +5205,11 @@ void fix_help_buffer(void) && 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) + 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. */ diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 7cab3eb650..0f98c9cd34 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -5734,18 +5734,13 @@ HistoryType get_histtype(const char *const name, const size_t len, 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; diff --git a/src/nvim/extmark.c b/src/nvim/extmark.c index 4b2dccd8a4..b4f22dbf33 100644 --- a/src/nvim/extmark.c +++ b/src/nvim/extmark.c @@ -48,20 +48,7 @@ #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); } @@ -195,7 +182,7 @@ 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 +202,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 +215,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,7 +224,7 @@ 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; } @@ -261,7 +245,7 @@ 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); @@ -276,7 +260,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 +270,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; } @@ -383,7 +367,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,17 +379,17 @@ 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); } diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index ee8be8429f..3d058e1d09 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -11,7 +11,7 @@ #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" diff --git a/src/nvim/fold.c b/src/nvim/fold.c index 6989c29d57..51a8a85aa0 100644 --- a/src/nvim/fold.c +++ b/src/nvim/fold.c @@ -2961,7 +2961,7 @@ static void foldlevelIndent(fline_T *flp) 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 */ @@ -3123,7 +3123,7 @@ static void foldlevelMarker(fline_T *flp) 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) { diff --git a/src/nvim/generators/gen_api_dispatch.lua b/src/nvim/generators/gen_api_dispatch.lua index 1d41cabfa4..c14b465f92 100644 --- a/src/nvim/generators/gen_api_dispatch.lua +++ b/src/nvim/generators/gen_api_dispatch.lua @@ -321,8 +321,6 @@ end output:write([[ void msgpack_rpc_init_method_table(void) { - methods = map_new(String, MsgpackRpcRequestHandler)(); - ]]) for i = 1, #functions do diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index 2b6c5b9f37..28f58e2c34 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -52,7 +52,6 @@ #include "nvim/os/input.h" #include "nvim/os/os.h" #include "nvim/os/fileio.h" -#include "nvim/api/private/handle.h" /// Index in scriptin diff --git a/src/nvim/highlight.c b/src/nvim/highlight.c index 29ee7aae56..7341ac9393 100644 --- a/src/nvim/highlight.c +++ b/src/nvim/highlight.c @@ -25,22 +25,16 @@ 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 })); @@ -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) { @@ -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; diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index 5799c3ee98..cbc2273bc9 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -13,7 +13,6 @@ #include "nvim/func_attr.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" @@ -40,6 +39,7 @@ #include "nvim/lua/converter.h" #include "nvim/lua/executor.h" #include "nvim/lua/treesitter.h" +#include "nvim/lua/xdiff.h" #include "luv/luv.h" @@ -68,7 +68,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 @@ -517,6 +518,10 @@ static int nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL // internal vim._treesitter... API nlua_add_treesitter(lstate); + // vim.diff + lua_pushcfunction(lstate, &nlua_xdl_diff); + lua_setfield(lstate, -2, "diff"); + lua_setglobal(lstate, "vim"); { @@ -564,7 +569,7 @@ 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 @@ -595,10 +600,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 @@ -997,9 +1002,9 @@ LuaRef nlua_ref(lua_State *lstate, int index) if (ref > 0) { nlua_refcount++; #ifdef NLUA_TRACK_REFS - if (nlua_ref_markers) { + if (nlua_track_refs) { // dummy allocation to make LeakSanitizer track our luarefs - pmap_put(handle_T)(nlua_ref_markers, ref, xmalloc(3)); + pmap_put(handle_T)(&nlua_ref_markers, ref, xmalloc(3)); } #endif } @@ -1013,8 +1018,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); diff --git a/src/nvim/lua/treesitter.c b/src/nvim/lua/treesitter.c index 2dfcd9a958..ed475c324f 100644 --- a/src/nvim/lua/treesitter.c +++ b/src/nvim/lua/treesitter.c @@ -18,7 +18,7 @@ #include "tree_sitter/api.h" #include "nvim/lua/treesitter.h" -#include "nvim/api/private/handle.h" +#include "nvim/api/private/helpers.h" #include "nvim/memline.h" #include "nvim/buffer.h" @@ -105,7 +105,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) { @@ -123,8 +123,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); @@ -137,7 +135,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; } @@ -146,7 +144,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; } @@ -189,7 +187,7 @@ int tslua_add_language(lua_State *L) 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; @@ -199,7 +197,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); } @@ -247,7 +245,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); } @@ -1175,7 +1173,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); } diff --git a/src/nvim/lua/vim.lua b/src/nvim/lua/vim.lua index 8cecaa51dd..ed435439a4 100644 --- a/src/nvim/lua/vim.lua +++ b/src/nvim/lua/vim.lua @@ -178,8 +178,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 +203,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() @@ -279,7 +279,7 @@ function vim.schedule_wrap(cb) end --- <Docs described in |vim.empty_dict()| > ---@private +---@private function vim.empty_dict() return setmetatable({}, vim._empty_dict_mt) end @@ -338,12 +338,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 +390,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 +408,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 @@ -429,21 +430,21 @@ local on_keystroke_callbacks = {} --- Register a lua {fn} with an {id} to be run after every keystroke. --- ---@param fn function: Function to call. It should take one argument, which is a string. +---@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| --- --- 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 +---@param ns_id number? Namespace ID. If not passed or 0, will generate and return a new --- namespace ID from |nvim_create_namesapce()| --- ---@return number Namespace ID associated with {fn} +---@return number Namespace ID associated with {fn} --- ---@note {fn} will be automatically removed if an error occurs while calling. +---@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 +---@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) vim.validate { fn = { fn, 'c', true}, @@ -459,7 +460,7 @@ function vim.register_keystroke_callback(fn, ns_id) end --- Function that executes the keystroke callbacks. ---@private +---@private function vim._log_keystroke(char) local failed_ns_ids = {} local failed_messages = {} diff --git a/src/nvim/lua/xdiff.c b/src/nvim/lua/xdiff.c new file mode 100644 index 0000000000..d50f874a82 --- /dev/null +++ b/src/nvim/lua/xdiff.c @@ -0,0 +1,334 @@ +#include <lua.h> +#include <lualib.h> +#include <lauxlib.h> + +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <string.h> + +#include "nvim/vim.h" +#include "nvim/xdiff/xdiff.h" +#include "nvim/lua/xdiff.h" +#include "nvim/lua/converter.h" +#include "nvim/lua/executor.h" +#include "nvim/api/private/helpers.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/nvim/xdiff/xemit.c:284 + // src/nvim/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/nvim/xdiff/xemit.c:284 + // src/nvim/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(¶ms, 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, ¶ms, &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.outf = 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, ¶ms, &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/main.c b/src/nvim/main.c index 136608afdf..9fc82a75af 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -78,7 +78,6 @@ #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" #ifndef WIN32 # include "nvim/os/pty_process_unix.h" @@ -126,8 +125,6 @@ void event_init(void) signal_init(); // finish mspgack-rpc initialization channel_init(); - remote_ui_init(); - api_vim_init(); terminal_init(); ui_init(); } @@ -160,13 +157,10 @@ 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. highlight_init(); - syntax_init(); #ifdef WIN32 OSVERSIONINFO ovi; diff --git a/src/nvim/map.c b/src/nvim/map.c index 86dc257e40..ccd332192e 100644 --- a/src/nvim/map.c +++ b/src/nvim/map.c @@ -54,56 +54,48 @@ 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() \ + void map_##T##_##U##_destroy(Map(T, U) *map) \ { \ - Map(T, U) *rv = xmalloc(sizeof(Map(T, U))); \ - rv->table = kh_init(T##_##U##_map); \ - return rv; \ - } \ - \ - void map_##T##_##U##_free(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 +104,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 +123,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 +133,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) @@ -199,7 +191,7 @@ 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 a35a2c1672..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); \ @@ -45,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; @@ -58,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 @@ -68,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) @@ -80,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/marktree.c b/src/nvim/marktree.c index d0d843cbf8..a04f250fc3 100644 --- a/src/nvim/marktree.c +++ b/src/nvim/marktree.c @@ -250,7 +250,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 +546,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; diff --git a/src/nvim/marktree.h b/src/nvim/marktree.h index 3b83e3c44d..7af23765c3 100644 --- a/src/nvim/marktree.h +++ b/src/nvim/marktree.h @@ -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/memline.c b/src/nvim/memline.c index 8229b8f6bc..4d435bc99f 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -382,7 +382,7 @@ error: */ void ml_setname(buf_T *buf) { - int success = FALSE; + bool success = false; memfile_T *mfp; char_u *fname; char_u *dirp; @@ -418,7 +418,7 @@ void ml_setname(buf_T *buf) /* 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 */ @@ -429,7 +429,7 @@ void ml_setname(buf_T *buf) /* 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); @@ -758,12 +758,12 @@ void ml_recover(bool checkext) blocknr_T bnum; int page_count; int len; - int directly; + bool directly; linenr_T lnum; char_u *p; int i; long error; - int cannot_open; + bool cannot_open; linenr_T line_count; bool has_error; int idx; @@ -771,7 +771,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; @@ -791,10 +791,10 @@ void ml_recover(bool checkext) && 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 */ len = recover_names(fname, FALSE, 0, NULL); @@ -1018,12 +1018,13 @@ void ml_recover(bool checkext) buf->b_ml.ml_stack = NULL; 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 */ @@ -1796,7 +1797,7 @@ theend: */ char_u *ml_get(linenr_T lnum) { - return ml_get_buf(curbuf, lnum, FALSE); + return ml_get_buf(curbuf, lnum, false); } /* @@ -2096,7 +2097,7 @@ static int ml_append_int( 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; @@ -2113,22 +2114,22 @@ static int ml_append_int( */ 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; } } @@ -2761,7 +2762,7 @@ static void ml_flush_line(buf_T *buf) int start; int count; int i; - static int entered = FALSE; + static bool entered = false; if (buf->b_ml.ml_line_lnum == 0 || buf->b_ml.ml_mfp == NULL) return; /* nothing to do */ @@ -2770,7 +2771,7 @@ static void ml_flush_line(buf_T *buf) /* This code doesn't work recursively. */ if (entered) return; - entered = TRUE; + entered = true; buf->flush_count++; @@ -2833,7 +2834,7 @@ static void ml_flush_line(buf_T *buf) } xfree(new_line); - entered = FALSE; + entered = false; } buf->b_ml.ml_line_lnum = 0; diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c index a2d8859c68..e5743f345b 100644 --- a/src/nvim/msgpack_rpc/channel.c +++ b/src/nvim/msgpack_rpc/channel.c @@ -38,7 +38,7 @@ #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 +48,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 +59,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); @@ -183,11 +181,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); @@ -497,7 +495,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,7 +526,7 @@ 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); @@ -536,7 +534,7 @@ static void unsubscribe(Channel *channel, char *event) } 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 +542,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 +581,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); } 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/normal.c b/src/nvim/normal.c index 2a530db934..7b2f77a6f9 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -4931,7 +4931,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 { @@ -5028,6 +5029,17 @@ 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); diff --git a/src/nvim/ops.c b/src/nvim/ops.c index a6eda26d75..178b454e4e 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -1121,18 +1121,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; @@ -1567,8 +1562,8 @@ 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) @@ -1593,7 +1588,7 @@ int op_delete(oparg_T *oap) 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" */ } diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c index 008f5ef63b..92b5e14824 100644 --- a/src/nvim/os/env.c +++ b/src/nvim/os/env.c @@ -35,12 +35,11 @@ // 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); diff --git a/src/nvim/os_unix.c b/src/nvim/os_unix.c index be4bd9709b..44274e8f1d 100644 --- a/src/nvim/os_unix.c +++ b/src/nvim/os_unix.c @@ -7,7 +7,6 @@ #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" diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index c3cd210538..4da81f29e3 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -403,8 +403,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 +423,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 +443,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 +467,27 @@ static void add_pack_plugin(char_u *fname, void *cookie) } if (cookie != &APP_ADD_DIR) { - load_pack_plugin(fname); + load_pack_plugin(opt, fname); } } +static void add_start_pack_plugin(char_u *fname, void *cookie) +{ + add_pack_plugin(false, fname, cookie); +} + +static void add_opt_pack_plugin(char_u *fname, void *cookie) +{ + add_pack_plugin(true, fname, cookie); +} + /// Add all packages in the "start" directory to 'runtimepath'. void add_pack_start_dirs(void) { do_in_path(p_pp, (char_u *)"pack/*/start/*", DIP_ALL + DIP_DIR, // NOLINT - add_pack_plugin, &APP_ADD_DIR); + add_start_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_start_pack_plugin, &APP_ADD_DIR); } /// Load plugins from all packages in the "start" directory. @@ -483,9 +495,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" @@ -522,7 +534,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); } } diff --git a/src/nvim/screen.c b/src/nvim/screen.c index e4030b76a3..208ae3488f 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -324,8 +324,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, @@ -578,7 +577,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; @@ -597,7 +596,7 @@ 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); @@ -635,7 +634,7 @@ int update_screen(int type) /* 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); @@ -747,8 +746,7 @@ 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 */ @@ -756,8 +754,8 @@ static void win_update(win_T *wp, Providers *providers) 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 @@ -1339,7 +1337,7 @@ static void win_update(win_T *wp, Providers *providers) /* stop updating when hit the end of the file */ if (lnum > buf->b_ml.ml_line_count) { - eof = TRUE; + eof = true; break; } @@ -1596,7 +1594,7 @@ static void win_update(win_T *wp, Providers *providers) } if (lnum > buf->b_ml.ml_line_count) { - eof = TRUE; + eof = true; break; } } @@ -1841,10 +1839,10 @@ 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) ++*color_cols; @@ -2062,7 +2060,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, 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 @@ -2139,7 +2137,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, 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 @@ -2430,7 +2428,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, line_attr_lowprio_save = line_attr_lowprio; } - line = ml_get_buf(wp->w_buffer, lnum, FALSE); + line = ml_get_buf(wp->w_buffer, lnum, false); ptr = line; if (has_spell && !number_only) { @@ -2562,8 +2560,8 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, wp->w_cursor.col = linecol; 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) { @@ -3095,9 +3093,9 @@ 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) { @@ -3408,9 +3406,9 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, } 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) { @@ -3834,7 +3832,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; @@ -3847,7 +3845,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) { @@ -4953,12 +4951,12 @@ win_redr_status_matches ( int fillchar; int attr; int i; - int highlight = TRUE; + bool highlight = true; char_u *selstart = NULL; int selstart_col = 0; char_u *selend = NULL; static int first_match = 0; - int add_left = FALSE; + bool add_left = false; char_u *s; int emenu; int l; @@ -4970,7 +4968,7 @@ win_redr_status_matches ( if (match == -1) { /* don't show match but original text */ match = 0; - highlight = FALSE; + highlight = false; } /* count 1 for the ending ">" */ clen = status_match_len(xp, L_MATCH(match)) + 3; @@ -4979,7 +4977,7 @@ win_redr_status_matches ( 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) @@ -4997,8 +4995,9 @@ win_redr_status_matches ( break; } } - if (i == num_matches) - add_left = TRUE; + if (i == num_matches) { + add_left = true; + } } } if (add_left) @@ -5215,7 +5214,7 @@ static void win_redr_status(win_T *wp) grid_puts(&default_grid, NameBuff, row, (int)(this_ru_col - STRLEN(NameBuff) - 1), attr); - win_redr_ruler(wp, TRUE); + win_redr_ruler(wp, true); } /* @@ -5238,14 +5237,14 @@ 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) return; - entered = TRUE; + entered = true; did_emsg = false; win_redr_custom(wp, false); @@ -5261,12 +5260,11 @@ 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; @@ -5276,30 +5274,28 @@ int stl_connected(win_T *wp) 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; - 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; @@ -5339,7 +5335,7 @@ win_redr_custom ( bool draw_ruler ) { - static int entered = FALSE; + static bool entered = false; int attr; int curattr; int row; @@ -5365,7 +5361,7 @@ win_redr_custom ( * Avoid trouble by not allowing recursion. */ if (entered) return; - entered = TRUE; + entered = true; /* setup environment for the task at hand */ if (wp == NULL) { @@ -5500,7 +5496,7 @@ win_redr_custom ( } theend: - entered = FALSE; + entered = false; } static void win_redr_border(win_T *wp) @@ -6065,7 +6061,7 @@ next_search_hl ( 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; @@ -7333,11 +7329,10 @@ 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()) return; @@ -7357,7 +7352,7 @@ void showruler(int always) 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; @@ -7619,11 +7614,11 @@ static void margin_columns_win(win_T *wp, int *left_col, int *right_col) /// 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; } @@ -7643,7 +7638,7 @@ void screen_resize(int width, int height) if (curwin->w_buffer == NULL) return; - ++busy; + recursive = true; Rows = height; Columns = width; @@ -7662,7 +7657,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(); @@ -7694,8 +7689,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); @@ -7720,7 +7716,7 @@ void screen_resize(int width, int height) } ui_flush(); } - busy--; + recursive = false; } /// Check if the new Nvim application "shell" dimensions are valid. @@ -7778,4 +7774,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 b712e09861..b0ee41b245 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -98,7 +98,7 @@ 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 bool mr_pattern_alloced = false; // mr_pattern was allocated /* * Type used by find_pattern_in_path() to remember which included files have @@ -159,19 +159,21 @@ search_regcomp( 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, @@ -293,7 +295,7 @@ void free_search_patterns(void) if (mr_pattern_alloced) { xfree(mr_pattern); - mr_pattern_alloced = FALSE; + mr_pattern_alloced = false; mr_pattern = NULL; } } @@ -556,12 +558,12 @@ 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 @@ -659,11 +661,12 @@ int searchit( matchpos = regmatch.startpos[0]; endpos = regmatch.endpos[0]; submatch = first_submatch(®match); - /* "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 +674,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 +697,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; @@ -750,7 +751,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 @@ -842,10 +843,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--; @@ -888,7 +888,7 @@ int searchit( if ((options & SEARCH_PEEK) && ((lnum - pos->lnum) & 0x3f) == 0 && char_avail()) { - break_loop = TRUE; + break_loop = true; break; } @@ -962,9 +962,10 @@ int searchit( /* 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; @@ -1465,7 +1466,7 @@ int search_for_exact_line(buf_T *buf, pos_T *pos, Direction dir, char_u *pat) break; 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); @@ -1506,7 +1507,7 @@ int searchc(cmdarg_T *cap, int t_cmd) int col; 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 */ @@ -1539,8 +1540,9 @@ int searchc(cmdarg_T *cap, int t_cmd) /* 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) @@ -2257,22 +2259,25 @@ 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 p = NULL; @@ -2855,17 +2860,13 @@ finished: 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 i; @@ -2903,16 +2904,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; } /* @@ -2947,14 +2949,10 @@ 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); @@ -3053,8 +3051,9 @@ current_word( 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 { @@ -3126,9 +3125,9 @@ 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; @@ -3148,23 +3147,24 @@ 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" */ count *= 2; @@ -3185,13 +3185,13 @@ 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); @@ -3218,10 +3218,10 @@ extend: 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; } @@ -3232,10 +3232,11 @@ extend: 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) { /* @@ -3293,7 +3294,7 @@ current_block( pos_T *end_pos; pos_T old_start, old_end; char_u *save_cpo; - int sol = FALSE; /* '{' at start of line */ + bool sol = false; // '{' at start of line old_pos = curwin->w_cursor; old_end = curwin->w_cursor; /* remember where we started */ @@ -3351,7 +3352,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; } @@ -3410,11 +3411,10 @@ current_block( } -/* - * 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; @@ -3444,14 +3444,16 @@ 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 '/' */ for (;; ) { - if (inc(&pos) < 0) - return FALSE; + if (inc(&pos) < 0) { + return false; + } c = *ml_get_pos(&pos); if (c == '>') break; @@ -3502,16 +3504,20 @@ current_tagblock( 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; } @@ -4667,7 +4673,7 @@ find_pattern_in_path( 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; @@ -4904,7 +4910,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)) { /* @@ -4915,7 +4921,7 @@ search_line: p = def_regmatch.endp[0]; while (*p && !vim_iswordc(*p)) p++; - define_matched = TRUE; + define_matched = true; } /* diff --git a/src/nvim/spell.c b/src/nvim/spell.c index 28276884b0..610a359141 100644 --- a/src/nvim/spell.c +++ b/src/nvim/spell.c @@ -1399,7 +1399,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) { @@ -1425,7 +1425,7 @@ 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 @@ -1433,7 +1433,7 @@ spell_move_to ( STRCPY(buf, line); 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; diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c index 15271e831c..8b95178c84 100644 --- a/src/nvim/spellfile.c +++ b/src/nvim/spellfile.c @@ -5035,7 +5035,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)); diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index 1d45df8ebd..bdbbc4aacf 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -91,7 +91,7 @@ typedef struct hl_group { // builtin |highlight-groups| static garray_T highlight_ga = GA_EMPTY_INIT_VALUE; -Map(cstr_t, int) *highlight_unames; +Map(cstr_t, int) highlight_unames = MAP_INIT; static inline struct hl_group * HL_TABLE(void) { @@ -365,31 +365,26 @@ 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; +static bool syn_time_on = false; # define IF_SYN_TIME(p) (p) -void syntax_init(void) -{ - highlight_unames = map_new(cstr_t, int)(); -} - // Set the timeout used for syntax highlighting. // Use NULL to reset, no timeout. void syn_set_timeout(proftime_T *tm) @@ -815,7 +810,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; @@ -886,7 +881,7 @@ static int syn_match_linecont(linenr_T lnum) */ static void syn_start_line(void) { - current_finished = FALSE; + current_finished = false; current_col = 0; /* @@ -894,7 +889,7 @@ static void syn_start_line(void) * previous line and regions that have "keepend". */ if (!GA_EMPTY(¤t_state)) { - syn_update_ends(TRUE); + syn_update_ends(true); check_state_ends(); } @@ -903,15 +898,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 @@ -946,8 +939,8 @@ static void syn_update_ends(int startofline) 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) @@ -958,8 +951,9 @@ static void syn_update_ends(int startofline) 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(); @@ -1157,17 +1151,15 @@ 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; disptick_T tick; - int above; int dist; - int retval = FALSE; + bool retval = false; if (syn_block->b_sst_first == NULL) { return retval; @@ -1185,16 +1177,17 @@ 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) 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; + } } } @@ -1209,7 +1202,7 @@ static int syn_stack_cleanup(void) prev->sst_next = p->sst_next; syn_stack_free_entry(syn_block, p); p = prev; - retval = TRUE; + retval = true; } } return retval; @@ -1345,7 +1338,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; } @@ -1390,11 +1383,10 @@ 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; @@ -1402,7 +1394,7 @@ static int syn_stack_equal(synstate_T *sp) /* 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. */ @@ -1449,10 +1441,11 @@ static int syn_stack_equal(synstate_T *sp) if (j != NSUBEXP) break; } - if (i < 0) - return TRUE; + if (i < 0) { + return true; + } - return FALSE; + return false; } /* @@ -1495,14 +1488,13 @@ static void validate_current_state(void) ga_set_growsize(¤t_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; + bool retval = true; synstate_T *sp; /* @@ -1525,8 +1517,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. @@ -1683,15 +1676,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 (line[current_col] == NUL || line[current_col + 1] == NUL) { - current_finished = TRUE; - current_state_stored = FALSE; + current_finished = true; + current_state_stored = false; } /* @@ -2157,16 +2150,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; } } @@ -2174,11 +2165,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; } /* @@ -2214,8 +2205,8 @@ static stateitem_T *push_next_match(void) 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; @@ -2321,9 +2312,10 @@ static void check_state_ends(void) break; if (had_extend && keepend_level >= 0) { - syn_update_ends(FALSE); - if (GA_EMPTY(¤t_state)) + syn_update_ends(false); + if (GA_EMPTY(¤t_state)) { break; + } } cur_si = &CUR_STATE(current_state.ga_len - 1); @@ -2341,7 +2333,7 @@ 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 @@ -2457,18 +2449,14 @@ static void check_keepend(void) } } -/* - * 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; @@ -2576,7 +2564,7 @@ find_endpos( regmmatch_T best_regmatch; /* startpos/endpos of best match */ lpos_T pos; char_u *line; - int had_match = false; + bool had_match = false; char_u buf_chartab[32]; // chartab array for syn option iskeyword /* just in case we are invoked for a keyword */ @@ -2758,7 +2746,7 @@ find_endpos( *flagsp = spp->sp_flags; - had_match = TRUE; + had_match = true; break; } @@ -2821,12 +2809,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) { @@ -2872,10 +2860,10 @@ syn_add_start_off( 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 */ 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) { @@ -2896,7 +2884,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); } /* @@ -2908,7 +2896,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(); @@ -4247,7 +4235,7 @@ static void syn_cmd_include(exarg_T *eap, int syncing) 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) @@ -4547,9 +4535,9 @@ syn_cmd_region( 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; @@ -4607,7 +4595,7 @@ syn_cmd_region( } rest = skipwhite(rest + 1); if (*rest == NUL) { - not_enough = TRUE; + not_enough = true; break; } @@ -4618,7 +4606,7 @@ syn_cmd_region( else { matchgroup_id = syn_check_group(rest, (int)(p - rest)); if (matchgroup_id == 0) { - illegal = TRUE; + illegal = true; break; } } @@ -4712,8 +4700,8 @@ syn_cmd_region( } 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 } } } @@ -5865,16 +5853,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) @@ -6426,7 +6415,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; @@ -6467,7 +6456,7 @@ int load_colors(char_u *name) { 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 @@ -7119,7 +7108,7 @@ void free_highlight(void) xfree(HL_TABLE()[i].sg_name_u); } ga_clear(&highlight_ga); - map_free(cstr_t, int)(highlight_unames); + map_destroy(cstr_t, int)(&highlight_unames); } #endif @@ -7137,11 +7126,10 @@ 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 @@ -7505,7 +7493,7 @@ int syn_name2id_len(const char_u *name, size_t len) // 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); + return map_get(cstr_t, int)(&highlight_unames, name_u); } /// Lookup a highlight group name and return its attributes. @@ -7609,7 +7597,7 @@ static int syn_add_group(char_u *name) int id = highlight_ga.ga_len; // ID is index plus one - map_put(cstr_t, int)(highlight_unames, name_up, id); + map_put(cstr_t, int)(&highlight_unames, name_up, id); return id; } @@ -7620,7 +7608,7 @@ static void syn_unadd_group(void) { highlight_ga.ga_len--; HlGroup *item = &HL_TABLE()[highlight_ga.ga_len]; - map_del(cstr_t, int)(highlight_unames, item->sg_name_u); + map_del(cstr_t, int)(&highlight_unames, item->sg_name_u); xfree(item->sg_name); xfree(item->sg_name_u); } @@ -7883,8 +7871,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) { diff --git a/src/nvim/tag.c b/src/nvim/tag.c index d6c6b064b2..a971849f4c 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); @@ -1621,7 +1621,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 +1638,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 +1795,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 +1878,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 +1971,7 @@ parse_line: i = parse_tag_line(lbuf, &tagp); if (i == FAIL) { - line_error = TRUE; + line_error = true; break; } @@ -2175,7 +2176,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 +2184,7 @@ parse_line: */ if (match_count >= mincount) { retval = OK; - stop_searching = TRUE; + stop_searching = true; } if (stop_searching || use_cscope) 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/test_filetype.vim b/src/nvim/testdir/test_filetype.vim index c155dbad50..4d29d18330 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'], @@ -809,4 +808,21 @@ 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 + " 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/undo.c b/src/nvim/undo.c index c4b48a6ee2..e1a7dbb2d3 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -2762,13 +2762,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)); diff --git a/src/nvim/window.c b/src/nvim/window.c index fefbab822e..eddbe14da2 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -5,7 +5,6 @@ #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" @@ -2605,7 +2604,7 @@ void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp) { int dir; tabpage_T *ptp = NULL; - int free_tp = FALSE; + bool free_tp = false; // Get here with win->w_buffer == NULL when win_close() detects the tab page // changed. @@ -2710,7 +2709,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; @@ -3601,7 +3604,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,7 +3619,7 @@ 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) clear_snapshot(tp, idx); @@ -4545,7 +4548,7 @@ static win_T *win_alloc(win_T *after, bool 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); @@ -4616,7 +4619,7 @@ win_free ( int i; 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. */ |