aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/clint.py7
-rw-r--r--src/nvim/api/keysets_defs.h4
-rw-r--r--src/nvim/api/win_config.c34
-rw-r--r--src/nvim/arglist.c11
-rw-r--r--src/nvim/buffer_defs.h28
-rw-r--r--src/nvim/edit.c8
-rw-r--r--src/nvim/globals.h2
-rw-r--r--src/nvim/main.c13
-rw-r--r--src/nvim/normal.c4
-rw-r--r--src/nvim/popupmenu.c2
-rw-r--r--src/nvim/profile.c48
-rw-r--r--src/nvim/sign.c4
-rw-r--r--src/nvim/window.c10
-rw-r--r--src/nvim/winfloat.c4
14 files changed, 125 insertions, 54 deletions
diff --git a/src/clint.py b/src/clint.py
index 78eabb698f..062901b43a 100755
--- a/src/clint.py
+++ b/src/clint.py
@@ -152,8 +152,10 @@ _ERROR_CATEGORIES = [
'build/endif_comment',
'build/header_guard',
'build/include_defs',
+ 'build/defs_header',
'build/printf_format',
'build/storage_class',
+ 'build/init_macro',
'readability/bool',
'readability/multiline_comment',
'readability/multiline_string',
@@ -2086,6 +2088,11 @@ def CheckLanguage(filename, clean_lines, linenum, error):
" named ('k' followed by CamelCase) compile-time constant for"
" the size.")
+ # INIT() macro should only be used in header files.
+ if not filename.endswith('.h') and Search(r' INIT\(', line):
+ error(filename, linenum, 'build/init_macro', 4,
+ 'INIT() macro should only be used in header files.')
+
# Detect TRUE and FALSE.
match = Search(r'\b(TRUE|FALSE)\b', line)
if match:
diff --git a/src/nvim/api/keysets_defs.h b/src/nvim/api/keysets_defs.h
index 2f1b38d1e5..0ba33ca9a7 100644
--- a/src/nvim/api/keysets_defs.h
+++ b/src/nvim/api/keysets_defs.h
@@ -108,7 +108,7 @@ typedef struct {
} Dict(user_command);
typedef struct {
- OptionalKeys is_set__float_config_;
+ OptionalKeys is_set__win_config_;
Float row;
Float col;
Integer width;
@@ -131,7 +131,7 @@ typedef struct {
Boolean noautocmd;
Boolean fixed;
Boolean hide;
-} Dict(float_config);
+} Dict(win_config);
typedef struct {
Boolean is_lua;
diff --git a/src/nvim/api/win_config.c b/src/nvim/api/win_config.c
index 8e299d264c..8841bd225b 100644
--- a/src/nvim/api/win_config.c
+++ b/src/nvim/api/win_config.c
@@ -200,10 +200,10 @@
/// @param[out] err Error details, if any
///
/// @return Window handle, or 0 on error
-Window nvim_open_win(Buffer buffer, Boolean enter, Dict(float_config) *config, Error *err)
+Window nvim_open_win(Buffer buffer, Boolean enter, Dict(win_config) *config, Error *err)
FUNC_API_SINCE(6) FUNC_API_TEXTLOCK_ALLOW_CMDWIN
{
-#define HAS_KEY_X(d, key) HAS_KEY(d, float_config, key)
+#define HAS_KEY_X(d, key) HAS_KEY(d, win_config, key)
buf_T *buf = find_buffer_by_handle(buffer, err);
if (!buf) {
return 0;
@@ -213,7 +213,7 @@ Window nvim_open_win(Buffer buffer, Boolean enter, Dict(float_config) *config, E
return 0;
}
- FloatConfig fconfig = FLOAT_CONFIG_INIT;
+ WinConfig fconfig = WIN_CONFIG_INIT;
if (!parse_float_config(config, &fconfig, false, true, err)) {
return 0;
}
@@ -332,10 +332,10 @@ static int win_split_flags(WinSplit split, bool toplevel)
/// @param config Map defining the window configuration,
/// see |nvim_open_win()|
/// @param[out] err Error details, if any
-void nvim_win_set_config(Window window, Dict(float_config) *config, Error *err)
+void nvim_win_set_config(Window window, Dict(win_config) *config, Error *err)
FUNC_API_SINCE(6)
{
-#define HAS_KEY_X(d, key) HAS_KEY(d, float_config, key)
+#define HAS_KEY_X(d, key) HAS_KEY(d, win_config, key)
win_T *win = find_window_by_handle(window, err);
if (!win) {
return;
@@ -345,7 +345,7 @@ void nvim_win_set_config(Window window, Dict(float_config) *config, Error *err)
bool has_split = HAS_KEY_X(config, split);
bool has_vertical = HAS_KEY_X(config, vertical);
// reuse old values, if not overridden
- FloatConfig fconfig = win->w_float_config;
+ WinConfig fconfig = win->w_float_config;
bool to_split = config->relative.size == 0
&& !(HAS_KEY_X(config, external) ? config->external : fconfig.external)
@@ -539,8 +539,8 @@ void nvim_win_set_config(Window window, Dict(float_config) *config, Error *err)
#undef HAS_KEY_X
}
-#define PUT_KEY_X(d, key, value) PUT_KEY(d, float_config, key, value)
-static void config_put_bordertext(Dict(float_config) *config, FloatConfig *fconfig,
+#define PUT_KEY_X(d, key, value) PUT_KEY(d, win_config, key, value)
+static void config_put_bordertext(Dict(win_config) *config, WinConfig *fconfig,
BorderTextType bordertext_type, Arena *arena)
{
VirtText vt;
@@ -591,7 +591,7 @@ static void config_put_bordertext(Dict(float_config) *config, FloatConfig *fconf
/// @param window Window handle, or 0 for current window
/// @param[out] err Error details, if any
/// @return Map defining the window configuration, see |nvim_open_win()|
-Dict(float_config) nvim_win_get_config(Window window, Arena *arena, Error *err)
+Dict(win_config) nvim_win_get_config(Window window, Arena *arena, Error *err)
FUNC_API_SINCE(6)
{
/// Keep in sync with FloatRelative in buffer_defs.h
@@ -600,14 +600,14 @@ Dict(float_config) nvim_win_get_config(Window window, Arena *arena, Error *err)
/// Keep in sync with WinSplit in buffer_defs.h
static const char *const win_split_str[] = { "left", "right", "above", "below" };
- Dict(float_config) rv = { 0 };
+ Dict(win_config) rv = { 0 };
win_T *wp = find_window_by_handle(window, err);
if (!wp) {
return rv;
}
- FloatConfig *config = &wp->w_float_config;
+ WinConfig *config = &wp->w_float_config;
PUT_KEY_X(rv, focusable, config->focusable);
PUT_KEY_X(rv, external, config->external);
@@ -734,8 +734,8 @@ static bool parse_float_bufpos(Array bufpos, lpos_T *out)
return true;
}
-static void parse_bordertext(Object bordertext, BorderTextType bordertext_type,
- FloatConfig *fconfig, Error *err)
+static void parse_bordertext(Object bordertext, BorderTextType bordertext_type, WinConfig *fconfig,
+ Error *err)
{
if (bordertext.type != kObjectTypeString && bordertext.type != kObjectTypeArray) {
api_set_error(err, kErrorTypeValidation, "title/footer must be string or array");
@@ -793,7 +793,7 @@ static void parse_bordertext(Object bordertext, BorderTextType bordertext_type,
}
static bool parse_bordertext_pos(String bordertext_pos, BorderTextType bordertext_type,
- FloatConfig *fconfig, Error *err)
+ WinConfig *fconfig, Error *err)
{
AlignTextPos *align;
switch (bordertext_type) {
@@ -832,7 +832,7 @@ static bool parse_bordertext_pos(String bordertext_pos, BorderTextType bordertex
return true;
}
-static void parse_border_style(Object style, FloatConfig *fconfig, Error *err)
+static void parse_border_style(Object style, WinConfig *fconfig, Error *err)
{
struct {
const char *name;
@@ -937,10 +937,10 @@ static void parse_border_style(Object style, FloatConfig *fconfig, Error *err)
}
}
-static bool parse_float_config(Dict(float_config) *config, FloatConfig *fconfig, bool reconf,
+static bool parse_float_config(Dict(win_config) *config, WinConfig *fconfig, bool reconf,
bool new_win, Error *err)
{
-#define HAS_KEY_X(d, key) HAS_KEY(d, float_config, key)
+#define HAS_KEY_X(d, key) HAS_KEY(d, win_config, key)
bool has_relative = false, relative_is_win = false, is_split = false;
if (config->relative.size > 0) {
if (!parse_float_relative(config->relative, &fconfig->relative)) {
diff --git a/src/nvim/arglist.c b/src/nvim/arglist.c
index e9108f72cc..a02c22deae 100644
--- a/src/nvim/arglist.c
+++ b/src/nvim/arglist.c
@@ -1093,11 +1093,6 @@ static void do_arg_all(int count, int forceit, int keep_tabs)
// When the ":tab" modifier was used do this for all tab pages.
arg_all_close_unused_windows(&aall);
- // Now set the last used tabpage to where we started.
- if (valid_tabpage(new_lu_tp)) {
- lastused_tabpage = new_lu_tp;
- }
-
// Open a window for files in the argument list that don't have one.
// ARGCOUNT may change while doing this, because of autocommands.
if (count > aall.opened_len || count <= 0) {
@@ -1134,6 +1129,12 @@ static void do_arg_all(int count, int forceit, int keep_tabs)
if (valid_tabpage(aall.new_curtab)) {
goto_tabpage_tp(aall.new_curtab, true, true);
}
+
+ // Now set the last used tabpage to where we started.
+ if (valid_tabpage(new_lu_tp)) {
+ lastused_tabpage = new_lu_tp;
+ }
+
if (win_valid(aall.new_curwin)) {
win_enter(aall.new_curwin, false);
}
diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h
index ea014c3918..adbece20f2 100644
--- a/src/nvim/buffer_defs.h
+++ b/src/nvim/buffer_defs.h
@@ -941,19 +941,19 @@ typedef struct {
bool noautocmd;
bool fixed;
bool hide;
-} FloatConfig;
-
-#define FLOAT_CONFIG_INIT ((FloatConfig){ .height = 0, .width = 0, \
- .bufpos = { -1, 0 }, \
- .row = 0, .col = 0, .anchor = 0, \
- .relative = 0, .external = false, \
- .focusable = true, \
- .split = 0, \
- .zindex = kZIndexFloatDefault, \
- .style = kWinStyleUnused, \
- .noautocmd = false, \
- .hide = false, \
- .fixed = false })
+} WinConfig;
+
+#define WIN_CONFIG_INIT ((WinConfig){ .height = 0, .width = 0, \
+ .bufpos = { -1, 0 }, \
+ .row = 0, .col = 0, .anchor = 0, \
+ .relative = 0, .external = false, \
+ .focusable = true, \
+ .split = 0, \
+ .zindex = kZIndexFloatDefault, \
+ .style = kWinStyleUnused, \
+ .noautocmd = false, \
+ .hide = false, \
+ .fixed = false })
// Structure to store last cursor position and topline. Used by check_lnums()
// and reset_lnums().
@@ -1278,7 +1278,7 @@ struct window_S {
bool w_pos_changed; // true if window position changed
bool w_floating; ///< whether the window is floating
bool w_float_is_info; // the floating window is info float
- FloatConfig w_float_config;
+ WinConfig w_float_config;
// w_fraction is the fractional row of the cursor within the window, from
// 0 at the top row to FRACTION_MULT at the last row.
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index 41df039b85..b7b32883c2 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.c
@@ -363,7 +363,13 @@ static void insert_enter(InsertState *s)
ins_apply_autocmds(EVENT_INSERTLEAVE);
}
did_cursorhold = false;
- curbuf->b_last_changedtick = buf_get_changedtick(curbuf);
+
+ // ins_redraw() triggers TextChangedI only when no characters
+ // are in the typeahead buffer, so only reset curbuf->b_last_changedtick
+ // if the TextChangedI was not blocked by char_avail() (e.g. using :norm!)
+ if (!char_avail()) {
+ curbuf->b_last_changedtick = buf_get_changedtick(curbuf);
+ }
}
static int insert_check(VimState *state)
diff --git a/src/nvim/globals.h b/src/nvim/globals.h
index a06e9fe542..bcac32a252 100644
--- a/src/nvim/globals.h
+++ b/src/nvim/globals.h
@@ -979,6 +979,8 @@ EXTERN const char bot_top_msg[] INIT(= N_("search hit BOTTOM, continuing at TOP"
EXTERN const char line_msg[] INIT(= N_(" line "));
EXTERN FILE *time_fd INIT(= NULL); // where to write startup timing
+#define STARTUP_TIME_BUF_SIZE 8192
+EXTERN char *startuptime_buf INIT(= NULL); // --startuptime buffer
// Some compilers warn for not using a return value, but in some situations we
// can't do anything useful with the value. Assign to this variable to avoid
diff --git a/src/nvim/main.c b/src/nvim/main.c
index f858313682..f2893dc9e3 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -399,6 +399,7 @@ int main(int argc, char **argv)
}
if (ui_client_channel_id) {
+ time_finish();
ui_client_run(remote_ui); // NORETURN
}
assert(!ui_client_channel_id && !use_builtin_ui);
@@ -695,6 +696,9 @@ void getout(int exitval)
assert(!ui_client_channel_id);
exiting = true;
+ // make sure startuptimes have been flushed
+ time_finish();
+
// On error during Ex mode, exit with a non-zero code.
// POSIX requires this, although it's not 100% clear from the standard.
if (exmode_active) {
@@ -1495,9 +1499,16 @@ static void init_params(mparm_T *paramp, int argc, char **argv)
/// Initialize global startuptime file if "--startuptime" passed as an argument.
static void init_startuptime(mparm_T *paramp)
{
+ bool is_embed = false;
+ for (int i = 1; i < paramp->argc - 1; i++) {
+ if (STRICMP(paramp->argv[i], "--embed") == 0) {
+ is_embed = true;
+ break;
+ }
+ }
for (int i = 1; i < paramp->argc - 1; i++) {
if (STRICMP(paramp->argv[i], "--startuptime") == 0) {
- time_fd = fopen(paramp->argv[i + 1], "a");
+ time_init(paramp->argv[i + 1], is_embed ? "Embedded" : "Primary/TUI");
time_start("--- NVIM STARTING ---");
break;
}
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index 9966e6129c..8b6ef62873 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -1451,9 +1451,7 @@ static int normal_check(VimState *state)
// has been done, close any file for startup messages.
if (time_fd != NULL) {
TIME_MSG("first screen update");
- TIME_MSG("--- NVIM STARTED ---");
- fclose(time_fd);
- time_fd = NULL;
+ time_finish();
}
// After the first screen update may start triggering WinScrolled
// autocmd events. Store all the scroll positions and sizes now.
diff --git a/src/nvim/popupmenu.c b/src/nvim/popupmenu.c
index e24ebec458..d116b46d88 100644
--- a/src/nvim/popupmenu.c
+++ b/src/nvim/popupmenu.c
@@ -669,7 +669,7 @@ void pum_redraw(void)
/// @return NULL when no enough room to show
static win_T *pum_create_float_preview(bool enter)
{
- FloatConfig config = FLOAT_CONFIG_INIT;
+ WinConfig config = WIN_CONFIG_INIT;
config.relative = kFloatRelativeEditor;
// when pum_above is SW otherwise is NW
config.anchor = pum_above ? kFloatAnchorSouth : 0;
diff --git a/src/nvim/profile.c b/src/nvim/profile.c
index f7776ef74f..84b58de4a3 100644
--- a/src/nvim/profile.c
+++ b/src/nvim/profile.c
@@ -907,7 +907,7 @@ void time_start(const char *message)
// initialize the global variables
g_prev_time = g_start_time = profile_start();
- fprintf(time_fd, "\n\ntimes in msec\n");
+ fprintf(time_fd, "\ntimes in msec\n");
fprintf(time_fd, " clock self+sourced self: sourced script\n");
fprintf(time_fd, " clock elapsed: other lines\n\n");
@@ -944,3 +944,49 @@ void time_msg(const char *mesg, const proftime_T *start)
g_prev_time = now;
fprintf(time_fd, ": %s\n", mesg);
}
+
+/// Initializes the time time_fd stream used to write startup times
+///
+/// @param startup_time_file the startuptime report file path
+/// @param process_name the name of the current process to write in the report.
+void time_init(const char *startup_time_file, const char *process_name)
+{
+ time_fd = fopen(startup_time_file, "a");
+ if (time_fd == NULL) {
+ semsg(_(e_notopen), startup_time_file);
+ return;
+ }
+ startuptime_buf = xmalloc(sizeof(char) * (STARTUP_TIME_BUF_SIZE + 1));
+ // The startuptime file is (potentially) written by multiple nvim processes concurrently. So
+ // startuptime info is buffered, and flushed to disk only after startup completed. To achieve that
+ // we set a buffer big enough to store all startup times. The `_IOFBF` mode ensures the buffer is
+ // not auto-flushed ("controlled buffering").
+ // The times are flushed to disk manually when "time_finish" is called.
+ int r = setvbuf(time_fd, startuptime_buf, _IOFBF, STARTUP_TIME_BUF_SIZE + 1);
+ if (r != 0) {
+ xfree(startuptime_buf);
+ fclose(time_fd);
+ time_fd = NULL;
+ // Might as well ELOG also I guess.
+ ELOG("time_init: setvbuf failed: %d %s", r, uv_err_name(r));
+ semsg("time_init: setvbuf failed: %d %s", r, uv_err_name(r));
+ return;
+ }
+ fprintf(time_fd, "--- Startup times for process: %s ---\n", process_name);
+}
+
+/// Flushes the startuptimes to disk for the current process
+void time_finish(void)
+{
+ if (time_fd == NULL) {
+ return;
+ }
+ assert(startuptime_buf != NULL);
+ TIME_MSG("--- NVIM STARTED ---\n");
+
+ // flush buffer to disk
+ fclose(time_fd);
+ time_fd = NULL;
+
+ XFREE_CLEAR(startuptime_buf);
+}
diff --git a/src/nvim/sign.c b/src/nvim/sign.c
index 5b4d4191b9..9caacd8115 100644
--- a/src/nvim/sign.c
+++ b/src/nvim/sign.c
@@ -55,8 +55,8 @@
# include "sign.c.generated.h"
#endif
-static PMap(cstr_t) sign_map INIT( = MAP_INIT);
-static kvec_t(Integer) sign_ns INIT( = MAP_INIT);
+static PMap(cstr_t) sign_map = MAP_INIT;
+static kvec_t(Integer) sign_ns = KV_INITIAL_VALUE;
static char *cmds[] = {
"define",
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 06d2bcac0d..a188d75000 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -669,7 +669,7 @@ wingotofile:
beep_flush();
break;
}
- FloatConfig config = FLOAT_CONFIG_INIT;
+ WinConfig config = WIN_CONFIG_INIT;
config.width = curwin->w_width;
config.height = curwin->w_height;
config.external = true;
@@ -763,7 +763,7 @@ void ui_ext_win_position(win_T *wp, bool validate)
return;
}
- FloatConfig c = wp->w_float_config;
+ WinConfig c = wp->w_float_config;
if (!c.external) {
ScreenGrid *grid = &default_grid;
Float row = c.row;
@@ -1213,7 +1213,7 @@ win_T *win_split_ins(int size, int flags, win_T *new_wp, int dir)
new_frame(wp);
wp->w_floating = false;
// non-floating window doesn't store float config or have a border.
- wp->w_float_config = FLOAT_CONFIG_INIT;
+ wp->w_float_config = WIN_CONFIG_INIT;
CLEAR_FIELD(wp->w_border_adj);
}
@@ -3879,7 +3879,7 @@ void win_alloc_first(void)
void win_alloc_aucmd_win(int idx)
{
Error err = ERROR_INIT;
- FloatConfig fconfig = FLOAT_CONFIG_INIT;
+ WinConfig fconfig = WIN_CONFIG_INIT;
fconfig.width = Columns;
fconfig.height = 5;
fconfig.focusable = false;
@@ -4983,7 +4983,7 @@ win_T *win_alloc(win_T *after, bool hidden)
new_wp->w_cursor.lnum = 1;
new_wp->w_scbind_pos = 1;
new_wp->w_floating = 0;
- new_wp->w_float_config = FLOAT_CONFIG_INIT;
+ new_wp->w_float_config = WIN_CONFIG_INIT;
new_wp->w_viewport_invalid = true;
new_wp->w_viewport_last_topline = 1;
diff --git a/src/nvim/winfloat.c b/src/nvim/winfloat.c
index 1d22590ac0..f22c0f3cfa 100644
--- a/src/nvim/winfloat.c
+++ b/src/nvim/winfloat.c
@@ -38,7 +38,7 @@
/// @param last make the window the last one in the window list.
/// Only used when allocating the autocommand window.
/// @param config must already have been validated!
-win_T *win_new_float(win_T *wp, bool last, FloatConfig fconfig, Error *err)
+win_T *win_new_float(win_T *wp, bool last, WinConfig fconfig, Error *err)
{
if (wp == NULL) {
wp = win_alloc(last ? lastwin : lastwin_nofloating(), false);
@@ -138,7 +138,7 @@ int win_border_width(win_T *wp)
return wp->w_border_adj[1] + wp->w_border_adj[3];
}
-void win_config_float(win_T *wp, FloatConfig fconfig)
+void win_config_float(win_T *wp, WinConfig fconfig)
{
wp->w_width = MAX(fconfig.width, 1);
wp->w_height = MAX(fconfig.height, 1);