aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/eval.c15
-rw-r--r--src/nvim/eval_defs.h2
-rw-r--r--src/nvim/ex_cmds.c92
-rw-r--r--src/nvim/ex_getln.c40
-rw-r--r--src/nvim/option.c3
-rw-r--r--src/nvim/os/env.c17
-rw-r--r--src/nvim/terminal.c2
-rw-r--r--src/nvim/version.c6
8 files changed, 103 insertions, 74 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 9d8421ef04..4ab31985b5 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -5560,8 +5560,10 @@ static int free_unref_items(int copyID)
bool did_free = false;
// Go through the list of dicts and free items without the copyID.
+ // Don't free dicts that are referenced internally.
for (dict_T *dd = first_dict; dd != NULL; ) {
- if ((dd->dv_copyID & COPYID_MASK) != (copyID & COPYID_MASK)) {
+ if ((dd->dv_copyID & COPYID_MASK) != (copyID & COPYID_MASK)
+ && !dd->internal_refcount) {
// Free the Dictionary and ordinary items it contains, but don't
// recurse into Lists and Dictionaries, they will be in the list
// of dicts or list of lists. */
@@ -5671,6 +5673,7 @@ dict_T *dict_alloc(void) FUNC_ATTR_NONNULL_RET
d->dv_scope = 0;
d->dv_refcount = 0;
d->dv_copyID = 0;
+ d->internal_refcount = 0;
return d;
}
@@ -10969,6 +10972,9 @@ static void f_jobwait(typval_T *argvars, typval_T *rettv)
}
}
+ // poll to ensure any pending callbacks from the last job are invoked
+ event_poll(0);
+
for (listitem_T *arg = args->lv_first; arg != NULL; arg = arg->li_next) {
Job *job = NULL;
if (arg->li_tv.v_type != VAR_NUMBER
@@ -20064,6 +20070,7 @@ static inline void common_job_callbacks(dict_T *vopts, ufunc_T **on_stdout,
return;
}
+ vopts->internal_refcount++;
vopts->dv_refcount++;
}
@@ -20097,7 +20104,11 @@ static inline void free_term_job_data(TerminalJobData *data) {
if (data->on_exit) {
user_func_unref(data->on_exit);
}
- dict_unref(data->self);
+
+ if (data->self) {
+ data->self->internal_refcount--;
+ dict_unref(data->self);
+ }
free(data);
}
diff --git a/src/nvim/eval_defs.h b/src/nvim/eval_defs.h
index d2de830d6c..34a36004d6 100644
--- a/src/nvim/eval_defs.h
+++ b/src/nvim/eval_defs.h
@@ -111,6 +111,8 @@ struct dictvar_S {
dict_T *dv_copydict; /* copied dict used by deepcopy() */
dict_T *dv_used_next; /* next dict in used dicts list */
dict_T *dv_used_prev; /* previous dict in used dicts list */
+ int internal_refcount; // number of internal references to
+ // prevent garbage collection
};
#endif // NVIM_EVAL_DEFS_H
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index e687eab3c4..c686c5effa 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -2790,51 +2790,13 @@ do_ecmd (
oldbuf = (flags & ECMD_OLDBUF);
}
+ buf = curbuf;
if ((flags & ECMD_SET_HELP) || keep_help_flag) {
- char_u *p;
-
- curbuf->b_help = true;
- set_string_option_direct((char_u *)"buftype", -1,
- (char_u *)"help", OPT_FREE|OPT_LOCAL, 0);
-
- /*
- * Always set these options after jumping to a help tag, because the
- * user may have an autocommand that gets in the way.
- * Accept all ASCII chars for keywords, except ' ', '*', '"', '|', and
- * latin1 word characters (for translated help files).
- * Only set it when needed, buf_init_chartab() is some work.
- */
- p =
- (char_u *)"!-~,^*,^|,^\",192-255";
- if (STRCMP(curbuf->b_p_isk, p) != 0) {
- set_string_option_direct((char_u *)"isk", -1, p,
- OPT_FREE|OPT_LOCAL, 0);
- check_buf_options(curbuf);
- (void)buf_init_chartab(curbuf, FALSE);
- }
-
- curbuf->b_p_ts = 8; /* 'tabstop' is 8 */
- curwin->w_p_list = FALSE; /* no list mode */
-
- curbuf->b_p_ma = FALSE; /* not modifiable */
- curbuf->b_p_bin = FALSE; /* reset 'bin' before reading file */
- curwin->w_p_nu = 0; /* no line numbers */
- curwin->w_p_rnu = 0; /* no relative line numbers */
- RESET_BINDING(curwin); /* no scroll or cursor binding */
- curwin->w_p_arab = FALSE; /* no arabic mode */
- curwin->w_p_rl = FALSE; /* help window is left-to-right */
- curwin->w_p_fen = FALSE; /* No folding in the help window */
- curwin->w_p_diff = FALSE; /* No 'diff' */
- curwin->w_p_spell = FALSE; /* No spell checking */
-
- buf = curbuf;
- set_buflisted(FALSE);
- } else {
- buf = curbuf;
- /* Don't make a buffer listed if it's a help buffer. Useful when
- * using CTRL-O to go back to a help file. */
- if (!curbuf->b_help)
- set_buflisted(TRUE);
+ prepare_help_buffer();
+ } else if (!curbuf->b_help) {
+ // Don't make a buffer listed if it's a help buffer. Useful when using
+ // CTRL-O to go back to a help file.
+ set_buflisted(TRUE);
}
/* If autocommands change buffers under our fingers, forget about
@@ -5046,6 +5008,46 @@ int find_help_tags(char_u *arg, int *num_matches, char_u ***matches, int keep_la
return OK;
}
+/// Called when starting to edit a buffer for a help file.
+static void prepare_help_buffer(void)
+{
+ curbuf->b_help = true;
+ set_string_option_direct((char_u *)"buftype", -1, (char_u *)"help",
+ OPT_FREE|OPT_LOCAL, 0);
+
+ // Always set these options after jumping to a help tag, because the
+ // user may have an autocommand that gets in the way.
+ // Accept all ASCII chars for keywords, except ' ', '*', '"', '|', and
+ // latin1 word characters (for translated help files).
+ // Only set it when needed, buf_init_chartab() is some work.
+ char_u *p = (char_u *)"!-~,^*,^|,^\",192-255";
+ if (STRCMP(curbuf->b_p_isk, p) != 0) {
+ set_string_option_direct((char_u *)"isk", -1, p, OPT_FREE|OPT_LOCAL, 0);
+ check_buf_options(curbuf);
+ (void)buf_init_chartab(curbuf, FALSE);
+ }
+
+ // Don't use the global foldmethod.
+ set_string_option_direct((char_u *)"fdm", -1, (char_u *)"manual",
+ OPT_FREE|OPT_LOCAL, 0);
+
+ curbuf->b_p_ts = 8; // 'tabstop' is 8.
+ curwin->w_p_list = FALSE; // No list mode.
+
+ curbuf->b_p_ma = FALSE; // Not modifiable.
+ curbuf->b_p_bin = FALSE; // Reset 'bin' before reading file.
+ curwin->w_p_nu = 0; // No line numbers.
+ curwin->w_p_rnu = 0; // No relative line numbers.
+ RESET_BINDING(curwin); // No scroll or cursor binding.
+ curwin->w_p_arab = FALSE; // No arabic mode.
+ curwin->w_p_rl = FALSE; // Help window is left-to-right.
+ curwin->w_p_fen = FALSE; // No folding in the help window.
+ curwin->w_p_diff = FALSE; // No 'diff'.
+ curwin->w_p_spell = FALSE; // No spell checking.
+
+ set_buflisted(FALSE);
+}
+
/*
* After reading a help file: May cleanup a help buffer when syntax
* highlighting is not used.
@@ -6316,5 +6318,3 @@ void set_context_in_sign_cmd(expand_T *xp, char_u *arg)
}
}
}
-
-// vim: tabstop=8
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index a5d0d0be16..d430509cfd 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -1702,6 +1702,7 @@ getexmodeline (
int vcol = 0;
char_u *p;
int prev_char;
+ int len;
/* always start in column 0; write a newline if necessary */
compute_cmdrow();
@@ -1761,10 +1762,16 @@ getexmodeline (
if (c1 == '\r')
c1 = '\n';
- if (c1 == BS || c1 == K_BS
- || c1 == DEL || c1 == K_DEL || c1 == K_KDEL) {
+ if (c1 == BS || c1 == K_BS || c1 == DEL || c1 == K_DEL || c1 == K_KDEL) {
if (!GA_EMPTY(&line_ga)) {
- --line_ga.ga_len;
+ if (has_mbyte) {
+ p = (char_u *)line_ga.ga_data;
+ p[line_ga.ga_len] = NUL;
+ len = (*mb_head_off)(p, p + line_ga.ga_len - 1) + 1;
+ line_ga.ga_len -= len;
+ } else {
+ line_ga.ga_len--;
+ }
goto redraw;
}
continue;
@@ -1797,15 +1804,19 @@ redraw:
/* redraw the line */
msg_col = startcol;
vcol = 0;
- for (p = (char_u *)line_ga.ga_data;
- p < (char_u *)line_ga.ga_data + line_ga.ga_len; ++p) {
+ p = (char_u *)line_ga.ga_data;
+ p[line_ga.ga_len] = NUL;
+ while (p < (char_u *)line_ga.ga_data + line_ga.ga_len) {
if (*p == TAB) {
do {
msg_putchar(' ');
} while (++vcol % 8);
+ p++;
} else {
- msg_outtrans_len(p, 1);
- vcol += char2cells(*p);
+ len = MB_PTR2LEN(p);
+ msg_outtrans_len(p, len);
+ vcol += ptr2cells(p);
+ p += len;
}
}
msg_clr_eos();
@@ -1847,9 +1858,15 @@ redraw:
}
}
- if (IS_SPECIAL(c1))
+ if (IS_SPECIAL(c1)) {
c1 = '?';
- ((char_u *)line_ga.ga_data)[line_ga.ga_len] = c1;
+ }
+ if (has_mbyte) {
+ len = (*mb_char2bytes)(c1, (char_u *)line_ga.ga_data + line_ga.ga_len);
+ } else {
+ len = 1;
+ ((char_u *)line_ga.ga_data)[line_ga.ga_len] = c1;
+ }
if (c1 == '\n')
msg_putchar('\n');
else if (c1 == TAB) {
@@ -1858,11 +1875,10 @@ redraw:
msg_putchar(' ');
} while (++vcol % 8);
} else {
- msg_outtrans_len(
- ((char_u *)line_ga.ga_data) + line_ga.ga_len, 1);
+ msg_outtrans_len(((char_u *)line_ga.ga_data) + line_ga.ga_len, len);
vcol += char2cells(c1);
}
- ++line_ga.ga_len;
+ line_ga.ga_len += len;
escaped = FALSE;
ui_cursor_goto(msg_row, msg_col);
diff --git a/src/nvim/option.c b/src/nvim/option.c
index 4f955fee4e..2d016d8350 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -5354,6 +5354,9 @@ set_num_option (
if (p_hi < 0) {
errmsg = e_positive;
p_hi = 0;
+ } else if (p_hi > 10000) {
+ errmsg = e_invarg;
+ p_hi = 10000;
}
if (p_re < 0 || p_re > 2) {
errmsg = e_invarg;
diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c
index 3bea2908d5..30e44341a9 100644
--- a/src/nvim/os/env.c
+++ b/src/nvim/os/env.c
@@ -243,19 +243,16 @@ void expand_env_esc(char_u *srcp, char_u *dst, int dstlen, bool esc, bool one,
// Verify that we have found the end of a UNIX ${VAR} style variable
if (src[1] == '{' && *tail != '}') {
var = NULL;
- } else if (src[1] == '{') {
- ++tail;
- }
-#elif defined(MSWIN)
- // Verify that we have found the end of a Windows %VAR% style variable
- if (src[0] == '%' && *tail != '%') {
- var = NULL;
- } else if (src[0] == '%') {
- ++tail;
- }
+ } else {
+ if (src[1] == '{') {
+ ++tail;
+ }
#endif
*var = NUL;
var = vim_getenv(dst, &mustfree);
+#if defined(UNIX)
+ }
+#endif
} else if ( src[1] == NUL /* home directory */
|| vim_ispathsep(src[1])
|| vim_strchr((char_u *)" ,\t\n", src[1]) != NULL) {
diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c
index 87b2d8ff99..daba7b943f 100644
--- a/src/nvim/terminal.c
+++ b/src/nvim/terminal.c
@@ -1126,4 +1126,4 @@ static int get_config_int(Terminal *term, char *key)
// }}}
-// vim: foldmethod=marker foldenable
+// vim: foldmethod=marker
diff --git a/src/nvim/version.c b/src/nvim/version.c
index c2a196e5d2..8cdc06dba5 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -225,7 +225,7 @@ static int included_patches[] = {
518,
517,
516,
- //515,
+ 515,
514,
513,
//512 NA
@@ -404,7 +404,7 @@ static int included_patches[] = {
339,
338,
337,
- //336,
+ 336,
335,
334,
//333 NA
@@ -416,7 +416,7 @@ static int included_patches[] = {
327,
//326 NA
325,
- //324,
+ 324,
323,
//322 NA
//321 NA