mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge pull request #1661 from philix/early_exit
Reduce indentation level by early returning or continuing loop
This commit is contained in:
commit
ec6afbf4e6
@ -238,25 +238,27 @@ open_buffer (
|
||||
}
|
||||
apply_autocmds_retval(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf, &retval);
|
||||
|
||||
if (retval != FAIL) {
|
||||
/*
|
||||
* The autocommands may have changed the current buffer. Apply the
|
||||
* modelines to the correct buffer, if it still exists and is loaded.
|
||||
*/
|
||||
if (buf_valid(old_curbuf) && old_curbuf->b_ml.ml_mfp != NULL) {
|
||||
aco_save_T aco;
|
||||
if (retval == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
/* Go to the buffer that was opened. */
|
||||
aucmd_prepbuf(&aco, old_curbuf);
|
||||
do_modelines(0);
|
||||
curbuf->b_flags &= ~(BF_CHECK_RO | BF_NEVERLOADED);
|
||||
/*
|
||||
* The autocommands may have changed the current buffer. Apply the
|
||||
* modelines to the correct buffer, if it still exists and is loaded.
|
||||
*/
|
||||
if (buf_valid(old_curbuf) && old_curbuf->b_ml.ml_mfp != NULL) {
|
||||
aco_save_T aco;
|
||||
|
||||
apply_autocmds_retval(EVENT_BUFWINENTER, NULL, NULL, FALSE, curbuf,
|
||||
&retval);
|
||||
/* Go to the buffer that was opened. */
|
||||
aucmd_prepbuf(&aco, old_curbuf);
|
||||
do_modelines(0);
|
||||
curbuf->b_flags &= ~(BF_CHECK_RO | BF_NEVERLOADED);
|
||||
|
||||
/* restore curwin/curbuf and a few other things */
|
||||
aucmd_restbuf(&aco);
|
||||
}
|
||||
apply_autocmds_retval(EVENT_BUFWINENTER, NULL, NULL, FALSE, curbuf,
|
||||
&retval);
|
||||
|
||||
/* restore curwin/curbuf and a few other things */
|
||||
aucmd_restbuf(&aco);
|
||||
}
|
||||
|
||||
return retval;
|
||||
@ -2103,14 +2105,10 @@ void get_winopts(buf_T *buf)
|
||||
*/
|
||||
pos_T *buflist_findfpos(buf_T *buf)
|
||||
{
|
||||
wininfo_T *wip;
|
||||
static pos_T no_position = INIT_POS_T(1, 0, 0);
|
||||
|
||||
wip = find_wininfo(buf, FALSE);
|
||||
if (wip != NULL)
|
||||
return &(wip->wi_fpos);
|
||||
else
|
||||
return &no_position;
|
||||
wininfo_T *wip = find_wininfo(buf, FALSE);
|
||||
return (wip == NULL) ? &no_position : &(wip->wi_fpos);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -4091,66 +4089,69 @@ chk_modeline (
|
||||
prev = *s;
|
||||
}
|
||||
|
||||
if (*s) {
|
||||
do /* skip over "ex:", "vi:" or "vim:" */
|
||||
++s;
|
||||
while (s[-1] != ':');
|
||||
|
||||
s = linecopy = vim_strsave(s); /* copy the line, it will change */
|
||||
|
||||
save_sourcing_lnum = sourcing_lnum;
|
||||
save_sourcing_name = sourcing_name;
|
||||
sourcing_lnum = lnum; /* prepare for emsg() */
|
||||
sourcing_name = (char_u *)"modelines";
|
||||
|
||||
end = FALSE;
|
||||
while (end == FALSE) {
|
||||
s = skipwhite(s);
|
||||
if (*s == NUL)
|
||||
break;
|
||||
|
||||
/*
|
||||
* Find end of set command: ':' or end of line.
|
||||
* Skip over "\:", replacing it with ":".
|
||||
*/
|
||||
for (e = s; *e != ':' && *e != NUL; ++e)
|
||||
if (e[0] == '\\' && e[1] == ':')
|
||||
STRMOVE(e, e + 1);
|
||||
if (*e == NUL)
|
||||
end = TRUE;
|
||||
|
||||
/*
|
||||
* If there is a "set" command, require a terminating ':' and
|
||||
* ignore the stuff after the ':'.
|
||||
* "vi:set opt opt opt: foo" -- foo not interpreted
|
||||
* "vi:opt opt opt: foo" -- foo interpreted
|
||||
* Accept "se" for compatibility with Elvis.
|
||||
*/
|
||||
if (STRNCMP(s, "set ", (size_t)4) == 0
|
||||
|| STRNCMP(s, "se ", (size_t)3) == 0) {
|
||||
if (*e != ':') /* no terminating ':'? */
|
||||
break;
|
||||
end = TRUE;
|
||||
s = vim_strchr(s, ' ') + 1;
|
||||
}
|
||||
*e = NUL; /* truncate the set command */
|
||||
|
||||
if (*s != NUL) { /* skip over an empty "::" */
|
||||
save_SID = current_SID;
|
||||
current_SID = SID_MODELINE;
|
||||
retval = do_set(s, OPT_MODELINE | OPT_LOCAL | flags);
|
||||
current_SID = save_SID;
|
||||
if (retval == FAIL) /* stop if error found */
|
||||
break;
|
||||
}
|
||||
s = e + 1; /* advance to next part */
|
||||
}
|
||||
|
||||
sourcing_lnum = save_sourcing_lnum;
|
||||
sourcing_name = save_sourcing_name;
|
||||
|
||||
free(linecopy);
|
||||
if (!*s) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
do /* skip over "ex:", "vi:" or "vim:" */
|
||||
++s;
|
||||
while (s[-1] != ':');
|
||||
|
||||
s = linecopy = vim_strsave(s); /* copy the line, it will change */
|
||||
|
||||
save_sourcing_lnum = sourcing_lnum;
|
||||
save_sourcing_name = sourcing_name;
|
||||
sourcing_lnum = lnum; /* prepare for emsg() */
|
||||
sourcing_name = (char_u *)"modelines";
|
||||
|
||||
end = FALSE;
|
||||
while (end == FALSE) {
|
||||
s = skipwhite(s);
|
||||
if (*s == NUL)
|
||||
break;
|
||||
|
||||
/*
|
||||
* Find end of set command: ':' or end of line.
|
||||
* Skip over "\:", replacing it with ":".
|
||||
*/
|
||||
for (e = s; *e != ':' && *e != NUL; ++e)
|
||||
if (e[0] == '\\' && e[1] == ':')
|
||||
STRMOVE(e, e + 1);
|
||||
if (*e == NUL)
|
||||
end = TRUE;
|
||||
|
||||
/*
|
||||
* If there is a "set" command, require a terminating ':' and
|
||||
* ignore the stuff after the ':'.
|
||||
* "vi:set opt opt opt: foo" -- foo not interpreted
|
||||
* "vi:opt opt opt: foo" -- foo interpreted
|
||||
* Accept "se" for compatibility with Elvis.
|
||||
*/
|
||||
if (STRNCMP(s, "set ", (size_t)4) == 0
|
||||
|| STRNCMP(s, "se ", (size_t)3) == 0) {
|
||||
if (*e != ':') /* no terminating ':'? */
|
||||
break;
|
||||
end = TRUE;
|
||||
s = vim_strchr(s, ' ') + 1;
|
||||
}
|
||||
*e = NUL; /* truncate the set command */
|
||||
|
||||
if (*s != NUL) { /* skip over an empty "::" */
|
||||
save_SID = current_SID;
|
||||
current_SID = SID_MODELINE;
|
||||
retval = do_set(s, OPT_MODELINE | OPT_LOCAL | flags);
|
||||
current_SID = save_SID;
|
||||
if (retval == FAIL) /* stop if error found */
|
||||
break;
|
||||
}
|
||||
s = e + 1; /* advance to next part */
|
||||
}
|
||||
|
||||
sourcing_lnum = save_sourcing_lnum;
|
||||
sourcing_name = save_sourcing_name;
|
||||
|
||||
free(linecopy);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -579,24 +579,25 @@ static int diff_check_sanity(tabpage_T *tp, diff_T *dp)
|
||||
static void diff_redraw(int dofold)
|
||||
{
|
||||
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
|
||||
if (wp->w_p_diff) {
|
||||
redraw_win_later(wp, SOME_VALID);
|
||||
if (dofold && foldmethodIsDiff(wp)) {
|
||||
foldUpdateAll(wp);
|
||||
}
|
||||
if (!wp->w_p_diff) {
|
||||
continue;
|
||||
}
|
||||
redraw_win_later(wp, SOME_VALID);
|
||||
if (dofold && foldmethodIsDiff(wp)) {
|
||||
foldUpdateAll(wp);
|
||||
}
|
||||
|
||||
/* A change may have made filler lines invalid, need to take care
|
||||
* of that for other windows. */
|
||||
int n = diff_check(wp, wp->w_topline);
|
||||
/* A change may have made filler lines invalid, need to take care
|
||||
* of that for other windows. */
|
||||
int n = diff_check(wp, wp->w_topline);
|
||||
|
||||
if (((wp != curwin) && (wp->w_topfill > 0)) || (n > 0)) {
|
||||
if (wp->w_topfill > n) {
|
||||
wp->w_topfill = (n < 0 ? 0 : n);
|
||||
} else if ((n > 0) && (n > wp->w_topfill)) {
|
||||
wp->w_topfill = n;
|
||||
}
|
||||
check_topfill(wp, FALSE);
|
||||
if (((wp != curwin) && (wp->w_topfill > 0)) || (n > 0)) {
|
||||
if (wp->w_topfill > n) {
|
||||
wp->w_topfill = (n < 0 ? 0 : n);
|
||||
} else if ((n > 0) && (n > wp->w_topfill)) {
|
||||
wp->w_topfill = n;
|
||||
}
|
||||
check_topfill(wp, FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
203
src/nvim/edit.c
203
src/nvim/edit.c
@ -2565,75 +2565,76 @@ static void ins_compl_files(int count, char_u **files, int thesaurus, int flags,
|
||||
(void)msg_trunc_attr(IObuff, TRUE, hl_attr(HLF_R));
|
||||
}
|
||||
|
||||
if (fp != NULL) {
|
||||
/*
|
||||
* Read dictionary file line by line.
|
||||
* Check each line for a match.
|
||||
*/
|
||||
while (!got_int && !compl_interrupted
|
||||
&& !vim_fgets(buf, LSIZE, fp)) {
|
||||
ptr = buf;
|
||||
while (vim_regexec(regmatch, buf, (colnr_T)(ptr - buf))) {
|
||||
ptr = regmatch->startp[0];
|
||||
if (ctrl_x_mode == CTRL_X_WHOLE_LINE)
|
||||
ptr = find_line_end(ptr);
|
||||
else
|
||||
ptr = find_word_end(ptr);
|
||||
add_r = ins_compl_add_infercase(regmatch->startp[0],
|
||||
(int)(ptr - regmatch->startp[0]),
|
||||
p_ic, files[i], *dir, 0);
|
||||
if (thesaurus) {
|
||||
char_u *wstart;
|
||||
|
||||
/*
|
||||
* Add the other matches on the line
|
||||
*/
|
||||
ptr = buf;
|
||||
while (!got_int) {
|
||||
/* Find start of the next word. Skip white
|
||||
* space and punctuation. */
|
||||
ptr = find_word_start(ptr);
|
||||
if (*ptr == NUL || *ptr == NL)
|
||||
break;
|
||||
wstart = ptr;
|
||||
|
||||
/* Find end of the word. */
|
||||
if (has_mbyte)
|
||||
/* Japanese words may have characters in
|
||||
* different classes, only separate words
|
||||
* with single-byte non-word characters. */
|
||||
while (*ptr != NUL) {
|
||||
int l = (*mb_ptr2len)(ptr);
|
||||
|
||||
if (l < 2 && !vim_iswordc(*ptr))
|
||||
break;
|
||||
ptr += l;
|
||||
}
|
||||
else
|
||||
ptr = find_word_end(ptr);
|
||||
|
||||
/* Add the word. Skip the regexp match. */
|
||||
if (wstart != regmatch->startp[0])
|
||||
add_r = ins_compl_add_infercase(wstart,
|
||||
(int)(ptr - wstart),
|
||||
p_ic, files[i], *dir, 0);
|
||||
}
|
||||
}
|
||||
if (add_r == OK)
|
||||
/* if dir was BACKWARD then honor it just once */
|
||||
*dir = FORWARD;
|
||||
else if (add_r == FAIL)
|
||||
break;
|
||||
/* avoid expensive call to vim_regexec() when at end
|
||||
* of line */
|
||||
if (*ptr == '\n' || got_int)
|
||||
break;
|
||||
}
|
||||
line_breakcheck();
|
||||
ins_compl_check_keys(50);
|
||||
}
|
||||
fclose(fp);
|
||||
if (fp == NULL) {
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* Read dictionary file line by line.
|
||||
* Check each line for a match.
|
||||
*/
|
||||
while (!got_int && !compl_interrupted
|
||||
&& !vim_fgets(buf, LSIZE, fp)) {
|
||||
ptr = buf;
|
||||
while (vim_regexec(regmatch, buf, (colnr_T)(ptr - buf))) {
|
||||
ptr = regmatch->startp[0];
|
||||
if (ctrl_x_mode == CTRL_X_WHOLE_LINE)
|
||||
ptr = find_line_end(ptr);
|
||||
else
|
||||
ptr = find_word_end(ptr);
|
||||
add_r = ins_compl_add_infercase(regmatch->startp[0],
|
||||
(int)(ptr - regmatch->startp[0]),
|
||||
p_ic, files[i], *dir, 0);
|
||||
if (thesaurus) {
|
||||
char_u *wstart;
|
||||
|
||||
/*
|
||||
* Add the other matches on the line
|
||||
*/
|
||||
ptr = buf;
|
||||
while (!got_int) {
|
||||
/* Find start of the next word. Skip white
|
||||
* space and punctuation. */
|
||||
ptr = find_word_start(ptr);
|
||||
if (*ptr == NUL || *ptr == NL)
|
||||
break;
|
||||
wstart = ptr;
|
||||
|
||||
/* Find end of the word. */
|
||||
if (has_mbyte)
|
||||
/* Japanese words may have characters in
|
||||
* different classes, only separate words
|
||||
* with single-byte non-word characters. */
|
||||
while (*ptr != NUL) {
|
||||
int l = (*mb_ptr2len)(ptr);
|
||||
|
||||
if (l < 2 && !vim_iswordc(*ptr))
|
||||
break;
|
||||
ptr += l;
|
||||
}
|
||||
else
|
||||
ptr = find_word_end(ptr);
|
||||
|
||||
/* Add the word. Skip the regexp match. */
|
||||
if (wstart != regmatch->startp[0])
|
||||
add_r = ins_compl_add_infercase(wstart,
|
||||
(int)(ptr - wstart),
|
||||
p_ic, files[i], *dir, 0);
|
||||
}
|
||||
}
|
||||
if (add_r == OK)
|
||||
/* if dir was BACKWARD then honor it just once */
|
||||
*dir = FORWARD;
|
||||
else if (add_r == FAIL)
|
||||
break;
|
||||
/* avoid expensive call to vim_regexec() when at end
|
||||
* of line */
|
||||
if (*ptr == '\n' || got_int)
|
||||
break;
|
||||
}
|
||||
line_breakcheck();
|
||||
ins_compl_check_keys(50);
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
@ -7027,41 +7028,43 @@ static void ins_ctrl_(void)
|
||||
*/
|
||||
static int ins_start_select(int c)
|
||||
{
|
||||
if (km_startsel)
|
||||
switch (c) {
|
||||
case K_KHOME:
|
||||
case K_KEND:
|
||||
case K_PAGEUP:
|
||||
case K_KPAGEUP:
|
||||
case K_PAGEDOWN:
|
||||
case K_KPAGEDOWN:
|
||||
if (!(mod_mask & MOD_MASK_SHIFT))
|
||||
break;
|
||||
/* FALLTHROUGH */
|
||||
case K_S_LEFT:
|
||||
case K_S_RIGHT:
|
||||
case K_S_UP:
|
||||
case K_S_DOWN:
|
||||
case K_S_END:
|
||||
case K_S_HOME:
|
||||
/* Start selection right away, the cursor can move with
|
||||
* CTRL-O when beyond the end of the line. */
|
||||
start_selection();
|
||||
if (!km_startsel) {
|
||||
return FALSE;
|
||||
}
|
||||
switch (c) {
|
||||
case K_KHOME:
|
||||
case K_KEND:
|
||||
case K_PAGEUP:
|
||||
case K_KPAGEUP:
|
||||
case K_PAGEDOWN:
|
||||
case K_KPAGEDOWN:
|
||||
if (!(mod_mask & MOD_MASK_SHIFT))
|
||||
break;
|
||||
/* FALLTHROUGH */
|
||||
case K_S_LEFT:
|
||||
case K_S_RIGHT:
|
||||
case K_S_UP:
|
||||
case K_S_DOWN:
|
||||
case K_S_END:
|
||||
case K_S_HOME:
|
||||
/* Start selection right away, the cursor can move with
|
||||
* CTRL-O when beyond the end of the line. */
|
||||
start_selection();
|
||||
|
||||
/* Execute the key in (insert) Select mode. */
|
||||
stuffcharReadbuff(Ctrl_O);
|
||||
if (mod_mask) {
|
||||
char_u buf[4];
|
||||
/* Execute the key in (insert) Select mode. */
|
||||
stuffcharReadbuff(Ctrl_O);
|
||||
if (mod_mask) {
|
||||
char_u buf[4];
|
||||
|
||||
buf[0] = K_SPECIAL;
|
||||
buf[1] = KS_MODIFIER;
|
||||
buf[2] = mod_mask;
|
||||
buf[3] = NUL;
|
||||
stuffReadbuff(buf);
|
||||
}
|
||||
stuffcharReadbuff(c);
|
||||
return TRUE;
|
||||
buf[0] = K_SPECIAL;
|
||||
buf[1] = KS_MODIFIER;
|
||||
buf[2] = mod_mask;
|
||||
buf[3] = NUL;
|
||||
stuffReadbuff(buf);
|
||||
}
|
||||
stuffcharReadbuff(c);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -5987,29 +5987,30 @@ static char_u *dict2string(typval_T *tv, int copyID)
|
||||
|
||||
todo = (int)d->dv_hashtab.ht_used;
|
||||
for (hi = d->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) {
|
||||
if (!HASHITEM_EMPTY(hi)) {
|
||||
--todo;
|
||||
|
||||
if (first)
|
||||
first = FALSE;
|
||||
else
|
||||
ga_concat(&ga, (char_u *)", ");
|
||||
|
||||
tofree = string_quote(hi->hi_key, FALSE);
|
||||
if (tofree != NULL) {
|
||||
ga_concat(&ga, tofree);
|
||||
free(tofree);
|
||||
}
|
||||
ga_concat(&ga, (char_u *)": ");
|
||||
s = tv2string(&HI2DI(hi)->di_tv, &tofree, numbuf, copyID);
|
||||
if (s != NULL)
|
||||
ga_concat(&ga, s);
|
||||
free(tofree);
|
||||
if (s == NULL || did_echo_string_emsg) {
|
||||
break;
|
||||
}
|
||||
line_breakcheck();
|
||||
if (HASHITEM_EMPTY(hi)) {
|
||||
continue;
|
||||
}
|
||||
--todo;
|
||||
|
||||
if (first)
|
||||
first = FALSE;
|
||||
else
|
||||
ga_concat(&ga, (char_u *)", ");
|
||||
|
||||
tofree = string_quote(hi->hi_key, FALSE);
|
||||
if (tofree != NULL) {
|
||||
ga_concat(&ga, tofree);
|
||||
free(tofree);
|
||||
}
|
||||
ga_concat(&ga, (char_u *)": ");
|
||||
s = tv2string(&HI2DI(hi)->di_tv, &tofree, numbuf, copyID);
|
||||
if (s != NULL)
|
||||
ga_concat(&ga, s);
|
||||
free(tofree);
|
||||
if (s == NULL || did_echo_string_emsg) {
|
||||
break;
|
||||
}
|
||||
line_breakcheck();
|
||||
}
|
||||
if (todo > 0) {
|
||||
free(ga.ga_data);
|
||||
|
@ -2375,34 +2375,35 @@ void do_wqall(exarg_T *eap)
|
||||
exiting = TRUE;
|
||||
|
||||
FOR_ALL_BUFFERS(buf) {
|
||||
if (bufIsChanged(buf)) {
|
||||
/*
|
||||
* Check if there is a reason the buffer cannot be written:
|
||||
* 1. if the 'write' option is set
|
||||
* 2. if there is no file name (even after browsing)
|
||||
* 3. if the 'readonly' is set (even after a dialog)
|
||||
* 4. if overwriting is allowed (even after a dialog)
|
||||
*/
|
||||
if (not_writing()) {
|
||||
++error;
|
||||
break;
|
||||
}
|
||||
if (buf->b_ffname == NULL) {
|
||||
EMSGN(_("E141: No file name for buffer %" PRId64), buf->b_fnum);
|
||||
++error;
|
||||
} else if (check_readonly(&eap->forceit, buf)
|
||||
|| check_overwrite(eap, buf, buf->b_fname, buf->b_ffname,
|
||||
FALSE) == FAIL) {
|
||||
++error;
|
||||
} else {
|
||||
if (buf_write_all(buf, eap->forceit) == FAIL)
|
||||
++error;
|
||||
/* an autocommand may have deleted the buffer */
|
||||
if (!buf_valid(buf))
|
||||
buf = firstbuf;
|
||||
}
|
||||
eap->forceit = save_forceit; /* check_overwrite() may set it */
|
||||
if (!bufIsChanged(buf)) {
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* Check if there is a reason the buffer cannot be written:
|
||||
* 1. if the 'write' option is set
|
||||
* 2. if there is no file name (even after browsing)
|
||||
* 3. if the 'readonly' is set (even after a dialog)
|
||||
* 4. if overwriting is allowed (even after a dialog)
|
||||
*/
|
||||
if (not_writing()) {
|
||||
++error;
|
||||
break;
|
||||
}
|
||||
if (buf->b_ffname == NULL) {
|
||||
EMSGN(_("E141: No file name for buffer %" PRId64), buf->b_fnum);
|
||||
++error;
|
||||
} else if (check_readonly(&eap->forceit, buf)
|
||||
|| check_overwrite(eap, buf, buf->b_fname, buf->b_ffname,
|
||||
FALSE) == FAIL) {
|
||||
++error;
|
||||
} else {
|
||||
if (buf_write_all(buf, eap->forceit) == FAIL)
|
||||
++error;
|
||||
/* an autocommand may have deleted the buffer */
|
||||
if (!buf_valid(buf))
|
||||
buf = firstbuf;
|
||||
}
|
||||
eap->forceit = save_forceit; /* check_overwrite() may set it */
|
||||
}
|
||||
if (exiting) {
|
||||
if (!error)
|
||||
@ -3328,12 +3329,11 @@ void ex_z(exarg_T *eap)
|
||||
if (!VIM_ISDIGIT(*x)) {
|
||||
EMSG(_("E144: non-numeric argument to :z"));
|
||||
return;
|
||||
} else {
|
||||
bigness = atoi((char *)x);
|
||||
p_window = bigness;
|
||||
if (*kind == '=')
|
||||
bigness += 2;
|
||||
}
|
||||
bigness = atoi((char *)x);
|
||||
p_window = bigness;
|
||||
if (*kind == '=')
|
||||
bigness += 2;
|
||||
}
|
||||
|
||||
/* the number of '-' and '+' multiplies the distance */
|
||||
@ -5232,61 +5232,62 @@ void fix_help_buffer(void)
|
||||
if (fnames[fi] == NULL)
|
||||
continue;
|
||||
fd = mch_fopen((char *)fnames[fi], "r");
|
||||
if (fd != NULL) {
|
||||
vim_fgets(IObuff, IOSIZE, fd);
|
||||
if (IObuff[0] == '*'
|
||||
&& (s = vim_strchr(IObuff + 1, '*'))
|
||||
!= NULL) {
|
||||
int this_utf = MAYBE;
|
||||
/* Change tag definition to a
|
||||
* reference and remove <CR>/<NL>. */
|
||||
IObuff[0] = '|';
|
||||
*s = '|';
|
||||
while (*s != NUL) {
|
||||
if (*s == '\r' || *s == '\n')
|
||||
*s = NUL;
|
||||
/* The text is utf-8 when a byte
|
||||
* above 127 is found and no
|
||||
* illegal byte sequence is found.
|
||||
*/
|
||||
if (*s >= 0x80 && this_utf != FALSE) {
|
||||
int l;
|
||||
|
||||
this_utf = TRUE;
|
||||
l = utf_ptr2len(s);
|
||||
if (l == 1)
|
||||
this_utf = FALSE;
|
||||
s += l - 1;
|
||||
}
|
||||
++s;
|
||||
}
|
||||
/* The help file is latin1 or utf-8;
|
||||
* conversion to the current
|
||||
* 'encoding' may be required. */
|
||||
vc.vc_type = CONV_NONE;
|
||||
convert_setup(&vc, (char_u *)(
|
||||
this_utf == TRUE ? "utf-8"
|
||||
: "latin1"), p_enc);
|
||||
if (vc.vc_type == CONV_NONE)
|
||||
/* No conversion needed. */
|
||||
cp = IObuff;
|
||||
else {
|
||||
/* Do the conversion. If it fails
|
||||
* use the unconverted text. */
|
||||
cp = string_convert(&vc, IObuff,
|
||||
NULL);
|
||||
if (cp == NULL)
|
||||
cp = IObuff;
|
||||
}
|
||||
convert_setup(&vc, NULL, NULL);
|
||||
|
||||
ml_append(lnum, cp, (colnr_T)0, FALSE);
|
||||
if (cp != IObuff)
|
||||
free(cp);
|
||||
++lnum;
|
||||
}
|
||||
fclose(fd);
|
||||
if (fd == NULL) {
|
||||
continue;
|
||||
}
|
||||
vim_fgets(IObuff, IOSIZE, fd);
|
||||
if (IObuff[0] == '*'
|
||||
&& (s = vim_strchr(IObuff + 1, '*'))
|
||||
!= NULL) {
|
||||
int this_utf = MAYBE;
|
||||
/* Change tag definition to a
|
||||
* reference and remove <CR>/<NL>. */
|
||||
IObuff[0] = '|';
|
||||
*s = '|';
|
||||
while (*s != NUL) {
|
||||
if (*s == '\r' || *s == '\n')
|
||||
*s = NUL;
|
||||
/* The text is utf-8 when a byte
|
||||
* above 127 is found and no
|
||||
* illegal byte sequence is found.
|
||||
*/
|
||||
if (*s >= 0x80 && this_utf != FALSE) {
|
||||
int l;
|
||||
|
||||
this_utf = TRUE;
|
||||
l = utf_ptr2len(s);
|
||||
if (l == 1)
|
||||
this_utf = FALSE;
|
||||
s += l - 1;
|
||||
}
|
||||
++s;
|
||||
}
|
||||
/* The help file is latin1 or utf-8;
|
||||
* conversion to the current
|
||||
* 'encoding' may be required. */
|
||||
vc.vc_type = CONV_NONE;
|
||||
convert_setup(&vc, (char_u *)(
|
||||
this_utf == TRUE ? "utf-8"
|
||||
: "latin1"), p_enc);
|
||||
if (vc.vc_type == CONV_NONE)
|
||||
/* No conversion needed. */
|
||||
cp = IObuff;
|
||||
else {
|
||||
/* Do the conversion. If it fails
|
||||
* use the unconverted text. */
|
||||
cp = string_convert(&vc, IObuff,
|
||||
NULL);
|
||||
if (cp == NULL)
|
||||
cp = IObuff;
|
||||
}
|
||||
convert_setup(&vc, NULL, NULL);
|
||||
|
||||
ml_append(lnum, cp, (colnr_T)0, FALSE);
|
||||
if (cp != IObuff)
|
||||
free(cp);
|
||||
++lnum;
|
||||
}
|
||||
fclose(fd);
|
||||
}
|
||||
FreeWild(fcount, fnames);
|
||||
}
|
||||
@ -5368,32 +5369,33 @@ void ex_helptags(exarg_T *eap)
|
||||
ga_init(&ga, 1, 10);
|
||||
for (int i = 0; i < filecount; ++i) {
|
||||
len = (int)STRLEN(files[i]);
|
||||
if (len > 4) {
|
||||
if (STRICMP(files[i] + len - 4, ".txt") == 0) {
|
||||
/* ".txt" -> language "en" */
|
||||
lang[0] = 'e';
|
||||
lang[1] = 'n';
|
||||
} else if (files[i][len - 4] == '.'
|
||||
&& ASCII_ISALPHA(files[i][len - 3])
|
||||
&& ASCII_ISALPHA(files[i][len - 2])
|
||||
&& TOLOWER_ASC(files[i][len - 1]) == 'x') {
|
||||
/* ".abx" -> language "ab" */
|
||||
lang[0] = TOLOWER_ASC(files[i][len - 3]);
|
||||
lang[1] = TOLOWER_ASC(files[i][len - 2]);
|
||||
} else
|
||||
continue;
|
||||
if (len <= 4) {
|
||||
continue;
|
||||
}
|
||||
if (STRICMP(files[i] + len - 4, ".txt") == 0) {
|
||||
/* ".txt" -> language "en" */
|
||||
lang[0] = 'e';
|
||||
lang[1] = 'n';
|
||||
} else if (files[i][len - 4] == '.'
|
||||
&& ASCII_ISALPHA(files[i][len - 3])
|
||||
&& ASCII_ISALPHA(files[i][len - 2])
|
||||
&& TOLOWER_ASC(files[i][len - 1]) == 'x') {
|
||||
/* ".abx" -> language "ab" */
|
||||
lang[0] = TOLOWER_ASC(files[i][len - 3]);
|
||||
lang[1] = TOLOWER_ASC(files[i][len - 2]);
|
||||
} else
|
||||
continue;
|
||||
|
||||
int j;
|
||||
/* Did we find this language already? */
|
||||
for (j = 0; j < ga.ga_len; j += 2)
|
||||
if (STRNCMP(lang, ((char_u *)ga.ga_data) + j, 2) == 0)
|
||||
break;
|
||||
if (j == ga.ga_len) {
|
||||
/* New language, add it. */
|
||||
ga_grow(&ga, 2);
|
||||
((char_u *)ga.ga_data)[ga.ga_len++] = lang[0];
|
||||
((char_u *)ga.ga_data)[ga.ga_len++] = lang[1];
|
||||
}
|
||||
int j;
|
||||
/* Did we find this language already? */
|
||||
for (j = 0; j < ga.ga_len; j += 2)
|
||||
if (STRNCMP(lang, ((char_u *)ga.ga_data) + j, 2) == 0)
|
||||
break;
|
||||
if (j == ga.ga_len) {
|
||||
/* New language, add it. */
|
||||
ga_grow(&ga, 2);
|
||||
((char_u *)ga.ga_data)[ga.ga_len++] = lang[0];
|
||||
((char_u *)ga.ga_data)[ga.ga_len++] = lang[1];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7748,24 +7748,25 @@ static char_u *arg_all(void)
|
||||
len = 0;
|
||||
for (idx = 0; idx < ARGCOUNT; ++idx) {
|
||||
p = alist_name(&ARGLIST[idx]);
|
||||
if (p != NULL) {
|
||||
if (len > 0) {
|
||||
/* insert a space in between names */
|
||||
if (p == NULL) {
|
||||
continue;
|
||||
}
|
||||
if (len > 0) {
|
||||
/* insert a space in between names */
|
||||
if (retval != NULL)
|
||||
retval[len] = ' ';
|
||||
++len;
|
||||
}
|
||||
for (; *p != NUL; ++p) {
|
||||
if (*p == ' ' || *p == '\\') {
|
||||
/* insert a backslash */
|
||||
if (retval != NULL)
|
||||
retval[len] = ' ';
|
||||
++len;
|
||||
}
|
||||
for (; *p != NUL; ++p) {
|
||||
if (*p == ' ' || *p == '\\') {
|
||||
/* insert a backslash */
|
||||
if (retval != NULL)
|
||||
retval[len] = '\\';
|
||||
++len;
|
||||
}
|
||||
if (retval != NULL)
|
||||
retval[len] = *p;
|
||||
retval[len] = '\\';
|
||||
++len;
|
||||
}
|
||||
if (retval != NULL)
|
||||
retval[len] = *p;
|
||||
++len;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -246,28 +246,24 @@ int cause_errthrow(char_u *mesg, int severe, int *ignore)
|
||||
plist = &(*plist)->next;
|
||||
|
||||
elem = xmalloc(sizeof(struct msglist));
|
||||
{
|
||||
elem->msg = vim_strsave(mesg);
|
||||
{
|
||||
elem->next = NULL;
|
||||
elem->throw_msg = NULL;
|
||||
*plist = elem;
|
||||
if (plist == msg_list || severe) {
|
||||
char_u *tmsg;
|
||||
elem->msg = vim_strsave(mesg);
|
||||
elem->next = NULL;
|
||||
elem->throw_msg = NULL;
|
||||
*plist = elem;
|
||||
if (plist == msg_list || severe) {
|
||||
char_u *tmsg;
|
||||
|
||||
/* Skip the extra "Vim " prefix for message "E458". */
|
||||
tmsg = elem->msg;
|
||||
if (STRNCMP(tmsg, "Vim E", 5) == 0
|
||||
&& VIM_ISDIGIT(tmsg[5])
|
||||
&& VIM_ISDIGIT(tmsg[6])
|
||||
&& VIM_ISDIGIT(tmsg[7])
|
||||
&& tmsg[8] == ':'
|
||||
&& tmsg[9] == ' ')
|
||||
(*msg_list)->throw_msg = &tmsg[4];
|
||||
else
|
||||
(*msg_list)->throw_msg = tmsg;
|
||||
}
|
||||
}
|
||||
/* Skip the extra "Vim " prefix for message "E458". */
|
||||
tmsg = elem->msg;
|
||||
if (STRNCMP(tmsg, "Vim E", 5) == 0
|
||||
&& VIM_ISDIGIT(tmsg[5])
|
||||
&& VIM_ISDIGIT(tmsg[6])
|
||||
&& VIM_ISDIGIT(tmsg[7])
|
||||
&& tmsg[8] == ':'
|
||||
&& tmsg[9] == ' ')
|
||||
(*msg_list)->throw_msg = &tmsg[4];
|
||||
else
|
||||
(*msg_list)->throw_msg = tmsg;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
|
@ -533,63 +533,64 @@ readfile (
|
||||
curbuf->b_p_ro = TRUE; /* must use "w!" now */
|
||||
} else
|
||||
#endif
|
||||
if (newfile) {
|
||||
if (perm < 0
|
||||
if (!newfile) {
|
||||
return FAIL;
|
||||
}
|
||||
if (perm < 0
|
||||
#ifdef ENOENT
|
||||
&& errno == ENOENT
|
||||
&& errno == ENOENT
|
||||
#endif
|
||||
) {
|
||||
/*
|
||||
* Set the 'new-file' flag, so that when the file has
|
||||
* been created by someone else, a ":w" will complain.
|
||||
*/
|
||||
curbuf->b_flags |= BF_NEW;
|
||||
) {
|
||||
/*
|
||||
* Set the 'new-file' flag, so that when the file has
|
||||
* been created by someone else, a ":w" will complain.
|
||||
*/
|
||||
curbuf->b_flags |= BF_NEW;
|
||||
|
||||
/* Create a swap file now, so that other Vims are warned
|
||||
* that we are editing this file. Don't do this for a
|
||||
* "nofile" or "nowrite" buffer type. */
|
||||
if (!bt_dontwrite(curbuf)) {
|
||||
check_need_swap(newfile);
|
||||
/* SwapExists autocommand may mess things up */
|
||||
if (curbuf != old_curbuf
|
||||
|| (using_b_ffname
|
||||
&& (old_b_ffname != curbuf->b_ffname))
|
||||
|| (using_b_fname
|
||||
&& (old_b_fname != curbuf->b_fname))) {
|
||||
EMSG(_(e_auchangedbuf));
|
||||
return FAIL;
|
||||
}
|
||||
}
|
||||
if (dir_of_file_exists(fname))
|
||||
filemess(curbuf, sfname, (char_u *)_("[New File]"), 0);
|
||||
else
|
||||
filemess(curbuf, sfname,
|
||||
(char_u *)_("[New DIRECTORY]"), 0);
|
||||
/* Even though this is a new file, it might have been
|
||||
* edited before and deleted. Get the old marks. */
|
||||
check_marks_read();
|
||||
/* Set forced 'fileencoding'. */
|
||||
if (eap != NULL)
|
||||
set_forced_fenc(eap);
|
||||
apply_autocmds_exarg(EVENT_BUFNEWFILE, sfname, sfname,
|
||||
FALSE, curbuf, eap);
|
||||
/* remember the current fileformat */
|
||||
save_file_ff(curbuf);
|
||||
|
||||
if (aborting()) /* autocmds may abort script processing */
|
||||
/* Create a swap file now, so that other Vims are warned
|
||||
* that we are editing this file. Don't do this for a
|
||||
* "nofile" or "nowrite" buffer type. */
|
||||
if (!bt_dontwrite(curbuf)) {
|
||||
check_need_swap(newfile);
|
||||
/* SwapExists autocommand may mess things up */
|
||||
if (curbuf != old_curbuf
|
||||
|| (using_b_ffname
|
||||
&& (old_b_ffname != curbuf->b_ffname))
|
||||
|| (using_b_fname
|
||||
&& (old_b_fname != curbuf->b_fname))) {
|
||||
EMSG(_(e_auchangedbuf));
|
||||
return FAIL;
|
||||
return OK; /* a new file is not an error */
|
||||
} else {
|
||||
filemess(curbuf, sfname, (char_u *)(
|
||||
}
|
||||
}
|
||||
if (dir_of_file_exists(fname))
|
||||
filemess(curbuf, sfname, (char_u *)_("[New File]"), 0);
|
||||
else
|
||||
filemess(curbuf, sfname,
|
||||
(char_u *)_("[New DIRECTORY]"), 0);
|
||||
/* Even though this is a new file, it might have been
|
||||
* edited before and deleted. Get the old marks. */
|
||||
check_marks_read();
|
||||
/* Set forced 'fileencoding'. */
|
||||
if (eap != NULL)
|
||||
set_forced_fenc(eap);
|
||||
apply_autocmds_exarg(EVENT_BUFNEWFILE, sfname, sfname,
|
||||
FALSE, curbuf, eap);
|
||||
/* remember the current fileformat */
|
||||
save_file_ff(curbuf);
|
||||
|
||||
if (aborting()) /* autocmds may abort script processing */
|
||||
return FAIL;
|
||||
return OK; /* a new file is not an error */
|
||||
} else {
|
||||
filemess(curbuf, sfname, (char_u *)(
|
||||
# ifdef EFBIG
|
||||
(errno == EFBIG) ? _("[File too big]") :
|
||||
(errno == EFBIG) ? _("[File too big]") :
|
||||
# endif
|
||||
# ifdef EOVERFLOW
|
||||
(errno == EOVERFLOW) ? _("[File too big]") :
|
||||
(errno == EOVERFLOW) ? _("[File too big]") :
|
||||
# endif
|
||||
_("[Permission Denied]")), 0);
|
||||
curbuf->b_p_ro = TRUE; /* must use "w!" now */
|
||||
}
|
||||
_("[Permission Denied]")), 0);
|
||||
curbuf->b_p_ro = TRUE; /* must use "w!" now */
|
||||
}
|
||||
|
||||
return FAIL;
|
||||
@ -5329,22 +5330,23 @@ static void show_autocmd(AutoPat *ap, event_T event)
|
||||
msg_outtrans(ap->pat);
|
||||
|
||||
for (ac = ap->cmds; ac != NULL; ac = ac->next) {
|
||||
if (ac->cmd != NULL) { /* skip removed commands */
|
||||
if (msg_col >= 14)
|
||||
msg_putchar('\n');
|
||||
msg_col = 14;
|
||||
if (ac->cmd == NULL) { /* skip removed commands */
|
||||
continue;
|
||||
}
|
||||
if (msg_col >= 14)
|
||||
msg_putchar('\n');
|
||||
msg_col = 14;
|
||||
if (got_int)
|
||||
return;
|
||||
msg_outtrans(ac->cmd);
|
||||
if (p_verbose > 0)
|
||||
last_set_msg(ac->scriptID);
|
||||
if (got_int)
|
||||
return;
|
||||
if (ac->next != NULL) {
|
||||
msg_putchar('\n');
|
||||
if (got_int)
|
||||
return;
|
||||
msg_outtrans(ac->cmd);
|
||||
if (p_verbose > 0)
|
||||
last_set_msg(ac->scriptID);
|
||||
if (got_int)
|
||||
return;
|
||||
if (ac->next != NULL) {
|
||||
msg_putchar('\n');
|
||||
if (got_int)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -6120,27 +6122,28 @@ void ex_doautoall(exarg_T *eap)
|
||||
* buffers or windows...
|
||||
*/
|
||||
FOR_ALL_BUFFERS(buf) {
|
||||
if (buf->b_ml.ml_mfp != NULL) {
|
||||
/* find a window for this buffer and save some values */
|
||||
aucmd_prepbuf(&aco, buf);
|
||||
|
||||
/* execute the autocommands for this buffer */
|
||||
retval = do_doautocmd(arg, FALSE);
|
||||
|
||||
if (call_do_modelines) {
|
||||
/* Execute the modeline settings, but don't set window-local
|
||||
* options if we are using the current window for another
|
||||
* buffer. */
|
||||
do_modelines(curwin == aucmd_win ? OPT_NOWIN : 0);
|
||||
}
|
||||
|
||||
/* restore the current window */
|
||||
aucmd_restbuf(&aco);
|
||||
|
||||
/* stop if there is some error or buffer was deleted */
|
||||
if (retval == FAIL || !buf_valid(buf))
|
||||
break;
|
||||
if (buf->b_ml.ml_mfp == NULL) {
|
||||
continue;
|
||||
}
|
||||
/* find a window for this buffer and save some values */
|
||||
aucmd_prepbuf(&aco, buf);
|
||||
|
||||
/* execute the autocommands for this buffer */
|
||||
retval = do_doautocmd(arg, FALSE);
|
||||
|
||||
if (call_do_modelines) {
|
||||
/* Execute the modeline settings, but don't set window-local
|
||||
* options if we are using the current window for another
|
||||
* buffer. */
|
||||
do_modelines(curwin == aucmd_win ? OPT_NOWIN : 0);
|
||||
}
|
||||
|
||||
/* restore the current window */
|
||||
aucmd_restbuf(&aco);
|
||||
|
||||
/* stop if there is some error or buffer was deleted */
|
||||
if (retval == FAIL || !buf_valid(buf))
|
||||
break;
|
||||
}
|
||||
|
||||
check_cursor(); /* just in case lines got deleted */
|
||||
|
@ -1639,39 +1639,38 @@ deleteFoldMarkers (
|
||||
*/
|
||||
static void foldDelMarker(linenr_T lnum, char_u *marker, int markerlen)
|
||||
{
|
||||
char_u *line;
|
||||
char_u *newline;
|
||||
char_u *p;
|
||||
int len;
|
||||
char_u *cms = curbuf->b_p_cms;
|
||||
char_u *cms2;
|
||||
|
||||
line = ml_get(lnum);
|
||||
for (p = line; *p != NUL; ++p)
|
||||
if (STRNCMP(p, marker, markerlen) == 0) {
|
||||
/* Found the marker, include a digit if it's there. */
|
||||
len = markerlen;
|
||||
if (VIM_ISDIGIT(p[len]))
|
||||
++len;
|
||||
if (*cms != NUL) {
|
||||
/* Also delete 'commentstring' if it matches. */
|
||||
cms2 = (char_u *)strstr((char *)cms, "%s");
|
||||
if (p - line >= cms2 - cms
|
||||
&& STRNCMP(p - (cms2 - cms), cms, cms2 - cms) == 0
|
||||
&& STRNCMP(p + len, cms2 + 2, STRLEN(cms2 + 2)) == 0) {
|
||||
p -= cms2 - cms;
|
||||
len += (int)STRLEN(cms) - 2;
|
||||
}
|
||||
}
|
||||
if (u_save(lnum - 1, lnum + 1) == OK) {
|
||||
/* Make new line: text-before-marker + text-after-marker */
|
||||
newline = xmalloc(STRLEN(line) - len + 1);
|
||||
STRNCPY(newline, line, p - line);
|
||||
STRCPY(newline + (p - line), p + len);
|
||||
ml_replace(lnum, newline, FALSE);
|
||||
}
|
||||
break;
|
||||
char_u *line = ml_get(lnum);
|
||||
for (char_u *p = line; *p != NUL; ++p) {
|
||||
if (STRNCMP(p, marker, markerlen) != 0) {
|
||||
continue;
|
||||
}
|
||||
/* Found the marker, include a digit if it's there. */
|
||||
int len = markerlen;
|
||||
if (VIM_ISDIGIT(p[len]))
|
||||
++len;
|
||||
if (*cms != NUL) {
|
||||
/* Also delete 'commentstring' if it matches. */
|
||||
cms2 = (char_u *)strstr((char *)cms, "%s");
|
||||
if (p - line >= cms2 - cms
|
||||
&& STRNCMP(p - (cms2 - cms), cms, cms2 - cms) == 0
|
||||
&& STRNCMP(p + len, cms2 + 2, STRLEN(cms2 + 2)) == 0) {
|
||||
p -= cms2 - cms;
|
||||
len += (int)STRLEN(cms) - 2;
|
||||
}
|
||||
}
|
||||
if (u_save(lnum - 1, lnum + 1) == OK) {
|
||||
/* Make new line: text-before-marker + text-after-marker */
|
||||
newline = xmalloc(STRLEN(line) - len + 1);
|
||||
STRNCPY(newline, line, p - line);
|
||||
STRCPY(newline + (p - line), p + len);
|
||||
ml_replace(lnum, newline, FALSE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* get_foldtext() {{{2 */
|
||||
|
@ -680,33 +680,34 @@ static int read_redo(int init, int old_redo)
|
||||
p = bp->b_str;
|
||||
return OK;
|
||||
}
|
||||
if ((c = *p) != NUL) {
|
||||
/* Reverse the conversion done by add_char_buff() */
|
||||
/* For a multi-byte character get all the bytes and return the
|
||||
* converted character. */
|
||||
if (has_mbyte && (c != K_SPECIAL || p[1] == KS_SPECIAL))
|
||||
n = MB_BYTE2LEN_CHECK(c);
|
||||
else
|
||||
n = 1;
|
||||
for (i = 0;; ++i) {
|
||||
if (c == K_SPECIAL) { /* special key or escaped K_SPECIAL */
|
||||
c = TO_SPECIAL(p[1], p[2]);
|
||||
p += 2;
|
||||
}
|
||||
if (*++p == NUL && bp->b_next != NULL) {
|
||||
bp = bp->b_next;
|
||||
p = bp->b_str;
|
||||
}
|
||||
buf[i] = c;
|
||||
if (i == n - 1) { /* last byte of a character */
|
||||
if (n != 1)
|
||||
c = (*mb_ptr2char)(buf);
|
||||
break;
|
||||
}
|
||||
c = *p;
|
||||
if (c == NUL) /* cannot happen? */
|
||||
break;
|
||||
if ((c = *p) == NUL) {
|
||||
return c;
|
||||
}
|
||||
/* Reverse the conversion done by add_char_buff() */
|
||||
/* For a multi-byte character get all the bytes and return the
|
||||
* converted character. */
|
||||
if (has_mbyte && (c != K_SPECIAL || p[1] == KS_SPECIAL))
|
||||
n = MB_BYTE2LEN_CHECK(c);
|
||||
else
|
||||
n = 1;
|
||||
for (i = 0;; ++i) {
|
||||
if (c == K_SPECIAL) { /* special key or escaped K_SPECIAL */
|
||||
c = TO_SPECIAL(p[1], p[2]);
|
||||
p += 2;
|
||||
}
|
||||
if (*++p == NUL && bp->b_next != NULL) {
|
||||
bp = bp->b_next;
|
||||
p = bp->b_str;
|
||||
}
|
||||
buf[i] = c;
|
||||
if (i == n - 1) { /* last byte of a character */
|
||||
if (n != 1)
|
||||
c = (*mb_ptr2char)(buf);
|
||||
break;
|
||||
}
|
||||
c = *p;
|
||||
if (c == NUL) /* cannot happen? */
|
||||
break;
|
||||
}
|
||||
|
||||
return c;
|
||||
|
@ -329,24 +329,25 @@ static void hash_may_resize(hashtab_T *ht, size_t minitems)
|
||||
size_t todo = ht->ht_used;
|
||||
|
||||
for (hashitem_T *olditem = oldarray; todo > 0; ++olditem) {
|
||||
if (!HASHITEM_EMPTY(olditem)) {
|
||||
// The algorithm to find the spot to add the item is identical to
|
||||
// the algorithm to find an item in hash_lookup(). But we only
|
||||
// need to search for a NULL key, thus it's simpler.
|
||||
hash_T newi = olditem->hi_hash & newmask;
|
||||
hashitem_T *newitem = &newarray[newi];
|
||||
if (newitem->hi_key != NULL) {
|
||||
for (hash_T perturb = olditem->hi_hash;; perturb >>= PERTURB_SHIFT) {
|
||||
newi = 5 * newi + perturb + 1;
|
||||
newitem = &newarray[newi & newmask];
|
||||
if (newitem->hi_key == NULL) {
|
||||
break;
|
||||
}
|
||||
if (HASHITEM_EMPTY(olditem)) {
|
||||
continue;
|
||||
}
|
||||
// The algorithm to find the spot to add the item is identical to
|
||||
// the algorithm to find an item in hash_lookup(). But we only
|
||||
// need to search for a NULL key, thus it's simpler.
|
||||
hash_T newi = olditem->hi_hash & newmask;
|
||||
hashitem_T *newitem = &newarray[newi];
|
||||
if (newitem->hi_key != NULL) {
|
||||
for (hash_T perturb = olditem->hi_hash;; perturb >>= PERTURB_SHIFT) {
|
||||
newi = 5 * newi + perturb + 1;
|
||||
newitem = &newarray[newi & newmask];
|
||||
if (newitem->hi_key == NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
*newitem = *olditem;
|
||||
todo--;
|
||||
}
|
||||
*newitem = *olditem;
|
||||
todo--;
|
||||
}
|
||||
|
||||
if (ht->ht_array != ht->ht_smallarray) {
|
||||
|
@ -233,9 +233,7 @@ static int cin_islabel_skip(char_u **s)
|
||||
*/
|
||||
int cin_islabel(void)
|
||||
{ /* XXX */
|
||||
char_u *s;
|
||||
|
||||
s = cin_skipcomment(get_cursor_line_ptr());
|
||||
char_u *s = cin_skipcomment(get_cursor_line_ptr());
|
||||
|
||||
/*
|
||||
* Exclude "default" from labels, since it should be indented
|
||||
@ -246,44 +244,45 @@ int cin_islabel(void)
|
||||
if (cin_isscopedecl(s))
|
||||
return FALSE;
|
||||
|
||||
if (cin_islabel_skip(&s)) {
|
||||
/*
|
||||
* Only accept a label if the previous line is terminated or is a case
|
||||
* label.
|
||||
*/
|
||||
pos_T cursor_save;
|
||||
pos_T *trypos;
|
||||
char_u *line;
|
||||
|
||||
cursor_save = curwin->w_cursor;
|
||||
while (curwin->w_cursor.lnum > 1) {
|
||||
--curwin->w_cursor.lnum;
|
||||
|
||||
/*
|
||||
* If we're in a comment now, skip to the start of the comment.
|
||||
*/
|
||||
curwin->w_cursor.col = 0;
|
||||
if ((trypos = ind_find_start_comment()) != NULL) /* XXX */
|
||||
curwin->w_cursor = *trypos;
|
||||
|
||||
line = get_cursor_line_ptr();
|
||||
if (cin_ispreproc(line)) /* ignore #defines, #if, etc. */
|
||||
continue;
|
||||
if (*(line = cin_skipcomment(line)) == NUL)
|
||||
continue;
|
||||
|
||||
curwin->w_cursor = cursor_save;
|
||||
if (cin_isterminated(line, TRUE, FALSE)
|
||||
|| cin_isscopedecl(line)
|
||||
|| cin_iscase(line, TRUE)
|
||||
|| (cin_islabel_skip(&line) && cin_nocode(line)))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
curwin->w_cursor = cursor_save;
|
||||
return TRUE; /* label at start of file??? */
|
||||
if (!cin_islabel_skip(&s)) {
|
||||
return FALSE;
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
* Only accept a label if the previous line is terminated or is a case
|
||||
* label.
|
||||
*/
|
||||
pos_T cursor_save;
|
||||
pos_T *trypos;
|
||||
char_u *line;
|
||||
|
||||
cursor_save = curwin->w_cursor;
|
||||
while (curwin->w_cursor.lnum > 1) {
|
||||
--curwin->w_cursor.lnum;
|
||||
|
||||
/*
|
||||
* If we're in a comment now, skip to the start of the comment.
|
||||
*/
|
||||
curwin->w_cursor.col = 0;
|
||||
if ((trypos = ind_find_start_comment()) != NULL) /* XXX */
|
||||
curwin->w_cursor = *trypos;
|
||||
|
||||
line = get_cursor_line_ptr();
|
||||
if (cin_ispreproc(line)) /* ignore #defines, #if, etc. */
|
||||
continue;
|
||||
if (*(line = cin_skipcomment(line)) == NUL)
|
||||
continue;
|
||||
|
||||
curwin->w_cursor = cursor_save;
|
||||
if (cin_isterminated(line, TRUE, FALSE)
|
||||
|| cin_isscopedecl(line)
|
||||
|| cin_iscase(line, TRUE)
|
||||
|| (cin_islabel_skip(&line) && cin_nocode(line)))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
curwin->w_cursor = cursor_save;
|
||||
return TRUE; /* label at start of file??? */
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3200,80 +3199,82 @@ static int find_match(int lookfor, linenr_T ourscope)
|
||||
curwin->w_cursor.col = 0;
|
||||
|
||||
look = cin_skipcomment(get_cursor_line_ptr());
|
||||
if (cin_iselse(look)
|
||||
|| cin_isif(look)
|
||||
|| cin_isdo(look) /* XXX */
|
||||
|| cin_iswhileofdo(look, curwin->w_cursor.lnum)) {
|
||||
if (!cin_iselse(look)
|
||||
&& !cin_isif(look)
|
||||
&& !cin_isdo(look) /* XXX */
|
||||
&& !cin_iswhileofdo(look, curwin->w_cursor.lnum)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* if we've gone outside the braces entirely,
|
||||
* we must be out of scope...
|
||||
*/
|
||||
theirscope = find_start_brace(); /* XXX */
|
||||
if (theirscope == NULL)
|
||||
break;
|
||||
|
||||
/*
|
||||
* and if the brace enclosing this is further
|
||||
* back than the one enclosing the else, we're
|
||||
* out of luck too.
|
||||
*/
|
||||
if (theirscope->lnum < ourscope)
|
||||
break;
|
||||
|
||||
/*
|
||||
* and if they're enclosed in a *deeper* brace,
|
||||
* then we can ignore it because it's in a
|
||||
* different scope...
|
||||
*/
|
||||
if (theirscope->lnum > ourscope)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* if it was an "else" (that's not an "else if")
|
||||
* then we need to go back to another if, so
|
||||
* increment elselevel
|
||||
*/
|
||||
look = cin_skipcomment(get_cursor_line_ptr());
|
||||
if (cin_iselse(look)) {
|
||||
mightbeif = cin_skipcomment(look + 4);
|
||||
if (!cin_isif(mightbeif))
|
||||
++elselevel;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* if it was a "while" then we need to go back to
|
||||
* another "do", so increment whilelevel. XXX
|
||||
*/
|
||||
if (cin_iswhileofdo(look, curwin->w_cursor.lnum)) {
|
||||
++whilelevel;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If it's an "if" decrement elselevel */
|
||||
look = cin_skipcomment(get_cursor_line_ptr());
|
||||
if (cin_isif(look)) {
|
||||
elselevel--;
|
||||
/*
|
||||
* if we've gone outside the braces entirely,
|
||||
* we must be out of scope...
|
||||
* When looking for an "if" ignore "while"s that
|
||||
* get in the way.
|
||||
*/
|
||||
theirscope = find_start_brace(); /* XXX */
|
||||
if (theirscope == NULL)
|
||||
break;
|
||||
if (elselevel == 0 && lookfor == LOOKFOR_IF)
|
||||
whilelevel = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* and if the brace enclosing this is further
|
||||
* back than the one enclosing the else, we're
|
||||
* out of luck too.
|
||||
*/
|
||||
if (theirscope->lnum < ourscope)
|
||||
break;
|
||||
/* If it's a "do" decrement whilelevel */
|
||||
if (cin_isdo(look))
|
||||
whilelevel--;
|
||||
|
||||
/*
|
||||
* and if they're enclosed in a *deeper* brace,
|
||||
* then we can ignore it because it's in a
|
||||
* different scope...
|
||||
*/
|
||||
if (theirscope->lnum > ourscope)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* if it was an "else" (that's not an "else if")
|
||||
* then we need to go back to another if, so
|
||||
* increment elselevel
|
||||
*/
|
||||
look = cin_skipcomment(get_cursor_line_ptr());
|
||||
if (cin_iselse(look)) {
|
||||
mightbeif = cin_skipcomment(look + 4);
|
||||
if (!cin_isif(mightbeif))
|
||||
++elselevel;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* if it was a "while" then we need to go back to
|
||||
* another "do", so increment whilelevel. XXX
|
||||
*/
|
||||
if (cin_iswhileofdo(look, curwin->w_cursor.lnum)) {
|
||||
++whilelevel;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If it's an "if" decrement elselevel */
|
||||
look = cin_skipcomment(get_cursor_line_ptr());
|
||||
if (cin_isif(look)) {
|
||||
elselevel--;
|
||||
/*
|
||||
* When looking for an "if" ignore "while"s that
|
||||
* get in the way.
|
||||
*/
|
||||
if (elselevel == 0 && lookfor == LOOKFOR_IF)
|
||||
whilelevel = 0;
|
||||
}
|
||||
|
||||
/* If it's a "do" decrement whilelevel */
|
||||
if (cin_isdo(look))
|
||||
whilelevel--;
|
||||
|
||||
/*
|
||||
* if we've used up all the elses, then
|
||||
* this must be the if that we want!
|
||||
* match the indent level of that if.
|
||||
*/
|
||||
if (elselevel <= 0 && whilelevel <= 0) {
|
||||
return OK;
|
||||
}
|
||||
/*
|
||||
* if we've used up all the elses, then
|
||||
* this must be the if that we want!
|
||||
* match the indent level of that if.
|
||||
*/
|
||||
if (elselevel <= 0 && whilelevel <= 0) {
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
return FAIL;
|
||||
|
@ -3124,40 +3124,41 @@ void check_scrollbind(linenr_T topline_diff, long leftcol_diff)
|
||||
for (curwin = firstwin; curwin; curwin = curwin->w_next) {
|
||||
curbuf = curwin->w_buffer;
|
||||
/* skip original window and windows with 'noscrollbind' */
|
||||
if (curwin != old_curwin && curwin->w_p_scb) {
|
||||
/*
|
||||
* do the vertical scroll
|
||||
*/
|
||||
if (want_ver) {
|
||||
if (old_curwin->w_p_diff && curwin->w_p_diff) {
|
||||
diff_set_topline(old_curwin, curwin);
|
||||
} else {
|
||||
curwin->w_scbind_pos += topline_diff;
|
||||
topline = curwin->w_scbind_pos;
|
||||
if (topline > curbuf->b_ml.ml_line_count)
|
||||
topline = curbuf->b_ml.ml_line_count;
|
||||
if (topline < 1)
|
||||
topline = 1;
|
||||
if (curwin == old_curwin || !curwin->w_p_scb) {
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* do the vertical scroll
|
||||
*/
|
||||
if (want_ver) {
|
||||
if (old_curwin->w_p_diff && curwin->w_p_diff) {
|
||||
diff_set_topline(old_curwin, curwin);
|
||||
} else {
|
||||
curwin->w_scbind_pos += topline_diff;
|
||||
topline = curwin->w_scbind_pos;
|
||||
if (topline > curbuf->b_ml.ml_line_count)
|
||||
topline = curbuf->b_ml.ml_line_count;
|
||||
if (topline < 1)
|
||||
topline = 1;
|
||||
|
||||
y = topline - curwin->w_topline;
|
||||
if (y > 0)
|
||||
scrollup(y, false);
|
||||
else
|
||||
scrolldown(-y, false);
|
||||
}
|
||||
|
||||
redraw_later(VALID);
|
||||
cursor_correct();
|
||||
curwin->w_redr_status = true;
|
||||
y = topline - curwin->w_topline;
|
||||
if (y > 0)
|
||||
scrollup(y, false);
|
||||
else
|
||||
scrolldown(-y, false);
|
||||
}
|
||||
|
||||
/*
|
||||
* do the horizontal scroll
|
||||
*/
|
||||
if (want_hor && curwin->w_leftcol != tgt_leftcol) {
|
||||
curwin->w_leftcol = tgt_leftcol;
|
||||
leftcol_changed();
|
||||
}
|
||||
redraw_later(VALID);
|
||||
cursor_correct();
|
||||
curwin->w_redr_status = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* do the horizontal scroll
|
||||
*/
|
||||
if (want_hor && curwin->w_leftcol != tgt_leftcol) {
|
||||
curwin->w_leftcol = tgt_leftcol;
|
||||
leftcol_changed();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2735,150 +2735,152 @@ static int peekchr(void)
|
||||
{
|
||||
static int after_slash = FALSE;
|
||||
|
||||
if (curchr == -1) {
|
||||
switch (curchr = regparse[0]) {
|
||||
case '.':
|
||||
case '[':
|
||||
case '~':
|
||||
/* magic when 'magic' is on */
|
||||
if (reg_magic >= MAGIC_ON)
|
||||
curchr = Magic(curchr);
|
||||
break;
|
||||
case '(':
|
||||
case ')':
|
||||
case '{':
|
||||
case '%':
|
||||
case '+':
|
||||
case '=':
|
||||
case '?':
|
||||
case '@':
|
||||
case '!':
|
||||
case '&':
|
||||
case '|':
|
||||
case '<':
|
||||
case '>':
|
||||
case '#': /* future ext. */
|
||||
case '"': /* future ext. */
|
||||
case '\'': /* future ext. */
|
||||
case ',': /* future ext. */
|
||||
case '-': /* future ext. */
|
||||
case ':': /* future ext. */
|
||||
case ';': /* future ext. */
|
||||
case '`': /* future ext. */
|
||||
case '/': /* Can't be used in / command */
|
||||
/* magic only after "\v" */
|
||||
if (reg_magic == MAGIC_ALL)
|
||||
curchr = Magic(curchr);
|
||||
break;
|
||||
case '*':
|
||||
/* * is not magic as the very first character, eg "?*ptr", when
|
||||
* after '^', eg "/^*ptr" and when after "\(", "\|", "\&". But
|
||||
* "\(\*" is not magic, thus must be magic if "after_slash" */
|
||||
if (reg_magic >= MAGIC_ON
|
||||
&& !at_start
|
||||
&& !(prev_at_start && prevchr == Magic('^'))
|
||||
&& (after_slash
|
||||
|| (prevchr != Magic('(')
|
||||
&& prevchr != Magic('&')
|
||||
&& prevchr != Magic('|'))))
|
||||
curchr = Magic('*');
|
||||
break;
|
||||
case '^':
|
||||
/* '^' is only magic as the very first character and if it's after
|
||||
* "\(", "\|", "\&' or "\n" */
|
||||
if (reg_magic >= MAGIC_OFF
|
||||
&& (at_start
|
||||
|| reg_magic == MAGIC_ALL
|
||||
|| prevchr == Magic('(')
|
||||
|| prevchr == Magic('|')
|
||||
|| prevchr == Magic('&')
|
||||
|| prevchr == Magic('n')
|
||||
|| (no_Magic(prevchr) == '('
|
||||
&& prevprevchr == Magic('%')))) {
|
||||
curchr = Magic('^');
|
||||
at_start = TRUE;
|
||||
prev_at_start = FALSE;
|
||||
}
|
||||
break;
|
||||
case '$':
|
||||
/* '$' is only magic as the very last char and if it's in front of
|
||||
* either "\|", "\)", "\&", or "\n" */
|
||||
if (reg_magic >= MAGIC_OFF) {
|
||||
char_u *p = regparse + 1;
|
||||
bool is_magic_all = (reg_magic == MAGIC_ALL);
|
||||
if (curchr != -1) {
|
||||
return curchr;
|
||||
}
|
||||
|
||||
// ignore \c \C \m \M \v \V and \Z after '$'
|
||||
while (p[0] == '\\' && (p[1] == 'c' || p[1] == 'C'
|
||||
|| p[1] == 'm' || p[1] == 'M'
|
||||
|| p[1] == 'v' || p[1] == 'V'
|
||||
|| p[1] == 'Z')) {
|
||||
if (p[1] == 'v') {
|
||||
is_magic_all = true;
|
||||
} else if (p[1] == 'm' || p[1] == 'M' || p[1] == 'V') {
|
||||
is_magic_all = false;
|
||||
}
|
||||
p += 2;
|
||||
}
|
||||
if (p[0] == NUL
|
||||
|| (p[0] == '\\'
|
||||
&& (p[1] == '|' || p[1] == '&' || p[1] == ')'
|
||||
|| p[1] == 'n'))
|
||||
|| (is_magic_all
|
||||
&& (p[0] == '|' || p[0] == '&' || p[0] == ')'))
|
||||
|| reg_magic == MAGIC_ALL) {
|
||||
curchr = Magic('$');
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '\\':
|
||||
{
|
||||
int c = regparse[1];
|
||||
|
||||
if (c == NUL)
|
||||
curchr = '\\'; /* trailing '\' */
|
||||
else if (
|
||||
c <= '~' && META_flags[c]
|
||||
) {
|
||||
/*
|
||||
* META contains everything that may be magic sometimes,
|
||||
* except ^ and $ ("\^" and "\$" are only magic after
|
||||
* "\v"). We now fetch the next character and toggle its
|
||||
* magicness. Therefore, \ is so meta-magic that it is
|
||||
* not in META.
|
||||
*/
|
||||
curchr = -1;
|
||||
prev_at_start = at_start;
|
||||
at_start = FALSE; /* be able to say "/\*ptr" */
|
||||
++regparse;
|
||||
++after_slash;
|
||||
peekchr();
|
||||
--regparse;
|
||||
--after_slash;
|
||||
curchr = toggle_Magic(curchr);
|
||||
} else if (vim_strchr(REGEXP_ABBR, c)) {
|
||||
/*
|
||||
* Handle abbreviations, like "\t" for TAB -- webb
|
||||
*/
|
||||
curchr = backslash_trans(c);
|
||||
} else if (reg_magic == MAGIC_NONE && (c == '$' || c == '^'))
|
||||
curchr = toggle_Magic(c);
|
||||
else {
|
||||
/*
|
||||
* Next character can never be (made) magic?
|
||||
* Then backslashing it won't do anything.
|
||||
*/
|
||||
if (has_mbyte)
|
||||
curchr = (*mb_ptr2char)(regparse + 1);
|
||||
else
|
||||
curchr = c;
|
||||
}
|
||||
break;
|
||||
switch (curchr = regparse[0]) {
|
||||
case '.':
|
||||
case '[':
|
||||
case '~':
|
||||
/* magic when 'magic' is on */
|
||||
if (reg_magic >= MAGIC_ON)
|
||||
curchr = Magic(curchr);
|
||||
break;
|
||||
case '(':
|
||||
case ')':
|
||||
case '{':
|
||||
case '%':
|
||||
case '+':
|
||||
case '=':
|
||||
case '?':
|
||||
case '@':
|
||||
case '!':
|
||||
case '&':
|
||||
case '|':
|
||||
case '<':
|
||||
case '>':
|
||||
case '#': /* future ext. */
|
||||
case '"': /* future ext. */
|
||||
case '\'': /* future ext. */
|
||||
case ',': /* future ext. */
|
||||
case '-': /* future ext. */
|
||||
case ':': /* future ext. */
|
||||
case ';': /* future ext. */
|
||||
case '`': /* future ext. */
|
||||
case '/': /* Can't be used in / command */
|
||||
/* magic only after "\v" */
|
||||
if (reg_magic == MAGIC_ALL)
|
||||
curchr = Magic(curchr);
|
||||
break;
|
||||
case '*':
|
||||
/* * is not magic as the very first character, eg "?*ptr", when
|
||||
* after '^', eg "/^*ptr" and when after "\(", "\|", "\&". But
|
||||
* "\(\*" is not magic, thus must be magic if "after_slash" */
|
||||
if (reg_magic >= MAGIC_ON
|
||||
&& !at_start
|
||||
&& !(prev_at_start && prevchr == Magic('^'))
|
||||
&& (after_slash
|
||||
|| (prevchr != Magic('(')
|
||||
&& prevchr != Magic('&')
|
||||
&& prevchr != Magic('|'))))
|
||||
curchr = Magic('*');
|
||||
break;
|
||||
case '^':
|
||||
/* '^' is only magic as the very first character and if it's after
|
||||
* "\(", "\|", "\&' or "\n" */
|
||||
if (reg_magic >= MAGIC_OFF
|
||||
&& (at_start
|
||||
|| reg_magic == MAGIC_ALL
|
||||
|| prevchr == Magic('(')
|
||||
|| prevchr == Magic('|')
|
||||
|| prevchr == Magic('&')
|
||||
|| prevchr == Magic('n')
|
||||
|| (no_Magic(prevchr) == '('
|
||||
&& prevprevchr == Magic('%')))) {
|
||||
curchr = Magic('^');
|
||||
at_start = TRUE;
|
||||
prev_at_start = FALSE;
|
||||
}
|
||||
break;
|
||||
case '$':
|
||||
/* '$' is only magic as the very last char and if it's in front of
|
||||
* either "\|", "\)", "\&", or "\n" */
|
||||
if (reg_magic >= MAGIC_OFF) {
|
||||
char_u *p = regparse + 1;
|
||||
bool is_magic_all = (reg_magic == MAGIC_ALL);
|
||||
|
||||
default:
|
||||
// ignore \c \C \m \M \v \V and \Z after '$'
|
||||
while (p[0] == '\\' && (p[1] == 'c' || p[1] == 'C'
|
||||
|| p[1] == 'm' || p[1] == 'M'
|
||||
|| p[1] == 'v' || p[1] == 'V'
|
||||
|| p[1] == 'Z')) {
|
||||
if (p[1] == 'v') {
|
||||
is_magic_all = true;
|
||||
} else if (p[1] == 'm' || p[1] == 'M' || p[1] == 'V') {
|
||||
is_magic_all = false;
|
||||
}
|
||||
p += 2;
|
||||
}
|
||||
if (p[0] == NUL
|
||||
|| (p[0] == '\\'
|
||||
&& (p[1] == '|' || p[1] == '&' || p[1] == ')'
|
||||
|| p[1] == 'n'))
|
||||
|| (is_magic_all
|
||||
&& (p[0] == '|' || p[0] == '&' || p[0] == ')'))
|
||||
|| reg_magic == MAGIC_ALL) {
|
||||
curchr = Magic('$');
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '\\':
|
||||
{
|
||||
int c = regparse[1];
|
||||
|
||||
if (c == NUL)
|
||||
curchr = '\\'; /* trailing '\' */
|
||||
else if (
|
||||
c <= '~' && META_flags[c]
|
||||
) {
|
||||
/*
|
||||
* META contains everything that may be magic sometimes,
|
||||
* except ^ and $ ("\^" and "\$" are only magic after
|
||||
* "\v"). We now fetch the next character and toggle its
|
||||
* magicness. Therefore, \ is so meta-magic that it is
|
||||
* not in META.
|
||||
*/
|
||||
curchr = -1;
|
||||
prev_at_start = at_start;
|
||||
at_start = FALSE; /* be able to say "/\*ptr" */
|
||||
++regparse;
|
||||
++after_slash;
|
||||
peekchr();
|
||||
--regparse;
|
||||
--after_slash;
|
||||
curchr = toggle_Magic(curchr);
|
||||
} else if (vim_strchr(REGEXP_ABBR, c)) {
|
||||
/*
|
||||
* Handle abbreviations, like "\t" for TAB -- webb
|
||||
*/
|
||||
curchr = backslash_trans(c);
|
||||
} else if (reg_magic == MAGIC_NONE && (c == '$' || c == '^'))
|
||||
curchr = toggle_Magic(c);
|
||||
else {
|
||||
/*
|
||||
* Next character can never be (made) magic?
|
||||
* Then backslashing it won't do anything.
|
||||
*/
|
||||
if (has_mbyte)
|
||||
curchr = (*mb_ptr2char)(regparse);
|
||||
curchr = (*mb_ptr2char)(regparse + 1);
|
||||
else
|
||||
curchr = c;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
if (has_mbyte)
|
||||
curchr = (*mb_ptr2char)(regparse);
|
||||
}
|
||||
|
||||
return curchr;
|
||||
|
@ -4283,7 +4283,7 @@ static int comp_char_differs(int off_from, int off_to)
|
||||
*/
|
||||
static int char_needs_redraw(int off_from, int off_to, int cols)
|
||||
{
|
||||
if (cols > 0
|
||||
return (cols > 0
|
||||
&& ((ScreenLines[off_from] != ScreenLines[off_to]
|
||||
|| ScreenAttrs[off_from] != ScreenAttrs[off_to])
|
||||
|
||||
@ -4299,10 +4299,7 @@ static int char_needs_redraw(int off_from, int off_to, int cols)
|
||||
&& comp_char_differs(off_from, off_to))
|
||||
|| ((*mb_off2cells)(off_from, off_from + cols) > 1
|
||||
&& ScreenLines[off_from + 1]
|
||||
!= ScreenLines[off_to + 1])))
|
||||
))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
!= ScreenLines[off_to + 1])))));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1360,54 +1360,58 @@ static int syn_stack_equal(synstate_T *sp)
|
||||
reg_extmatch_T *six, *bsx;
|
||||
|
||||
/* 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) {
|
||||
/* Need to compare all states on both stacks. */
|
||||
if (sp->sst_stacksize > SST_FIX_STATES)
|
||||
bp = SYN_STATE_P(&(sp->sst_union.sst_ga));
|
||||
else
|
||||
bp = sp->sst_union.sst_stack;
|
||||
if (sp->sst_stacksize != current_state.ga_len
|
||||
|| sp->sst_next_list != current_next_list) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int i;
|
||||
for (i = current_state.ga_len; --i >= 0; ) {
|
||||
/* If the item has another index the state is different. */
|
||||
if (bp[i].bs_idx != CUR_STATE(i).si_idx)
|
||||
break;
|
||||
if (bp[i].bs_extmatch != CUR_STATE(i).si_extmatch) {
|
||||
/* When the extmatch pointers are different, the strings in
|
||||
* them can still be the same. Check if the extmatch
|
||||
* references are equal. */
|
||||
bsx = bp[i].bs_extmatch;
|
||||
six = CUR_STATE(i).si_extmatch;
|
||||
/* If one of the extmatch pointers is NULL the states are
|
||||
* different. */
|
||||
if (bsx == NULL || six == NULL)
|
||||
/* Need to compare all states on both stacks. */
|
||||
if (sp->sst_stacksize > SST_FIX_STATES)
|
||||
bp = SYN_STATE_P(&(sp->sst_union.sst_ga));
|
||||
else
|
||||
bp = sp->sst_union.sst_stack;
|
||||
|
||||
int i;
|
||||
for (i = current_state.ga_len; --i >= 0; ) {
|
||||
/* If the item has another index the state is different. */
|
||||
if (bp[i].bs_idx != CUR_STATE(i).si_idx)
|
||||
break;
|
||||
if (bp[i].bs_extmatch == CUR_STATE(i).si_extmatch) {
|
||||
continue;
|
||||
}
|
||||
/* When the extmatch pointers are different, the strings in
|
||||
* them can still be the same. Check if the extmatch
|
||||
* references are equal. */
|
||||
bsx = bp[i].bs_extmatch;
|
||||
six = CUR_STATE(i).si_extmatch;
|
||||
/* If one of the extmatch pointers is NULL the states are
|
||||
* different. */
|
||||
if (bsx == NULL || six == NULL)
|
||||
break;
|
||||
int j;
|
||||
for (j = 0; j < NSUBEXP; ++j) {
|
||||
/* Check each referenced match string. They must all be
|
||||
* equal. */
|
||||
if (bsx->matches[j] != six->matches[j]) {
|
||||
/* If the pointer is different it can still be the
|
||||
* same text. Compare the strings, ignore case when
|
||||
* the start item has the sp_ic flag set. */
|
||||
if (bsx->matches[j] == NULL
|
||||
|| six->matches[j] == NULL)
|
||||
break;
|
||||
int j;
|
||||
for (j = 0; j < NSUBEXP; ++j) {
|
||||
/* Check each referenced match string. They must all be
|
||||
* equal. */
|
||||
if (bsx->matches[j] != six->matches[j]) {
|
||||
/* If the pointer is different it can still be the
|
||||
* same text. Compare the strings, ignore case when
|
||||
* the start item has the sp_ic flag set. */
|
||||
if (bsx->matches[j] == NULL
|
||||
|| six->matches[j] == NULL)
|
||||
break;
|
||||
if ((SYN_ITEMS(syn_block)[CUR_STATE(i).si_idx]).sp_ic
|
||||
? MB_STRICMP(bsx->matches[j],
|
||||
six->matches[j]) != 0
|
||||
: STRCMP(bsx->matches[j], six->matches[j]) != 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j != NSUBEXP)
|
||||
if ((SYN_ITEMS(syn_block)[CUR_STATE(i).si_idx]).sp_ic
|
||||
? MB_STRICMP(bsx->matches[j],
|
||||
six->matches[j]) != 0
|
||||
: STRCMP(bsx->matches[j], six->matches[j]) != 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i < 0)
|
||||
return TRUE;
|
||||
if (j != NSUBEXP)
|
||||
break;
|
||||
}
|
||||
if (i < 0)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -1509,33 +1513,31 @@ syn_finish_line (
|
||||
stateitem_T *cur_si;
|
||||
colnr_T prev_current_col;
|
||||
|
||||
if (!current_finished) {
|
||||
while (!current_finished) {
|
||||
(void)syn_current_attr(syncing, FALSE, NULL, FALSE);
|
||||
while (!current_finished) {
|
||||
(void)syn_current_attr(syncing, FALSE, NULL, FALSE);
|
||||
/*
|
||||
* When syncing, and found some item, need to check the item.
|
||||
*/
|
||||
if (syncing && current_state.ga_len) {
|
||||
/*
|
||||
* When syncing, and found some item, need to check the item.
|
||||
* Check for match with sync item.
|
||||
*/
|
||||
if (syncing && current_state.ga_len) {
|
||||
/*
|
||||
* Check for match with sync item.
|
||||
*/
|
||||
cur_si = &CUR_STATE(current_state.ga_len - 1);
|
||||
if (cur_si->si_idx >= 0
|
||||
&& (SYN_ITEMS(syn_block)[cur_si->si_idx].sp_flags
|
||||
& (HL_SYNC_HERE|HL_SYNC_THERE)))
|
||||
return TRUE;
|
||||
cur_si = &CUR_STATE(current_state.ga_len - 1);
|
||||
if (cur_si->si_idx >= 0
|
||||
&& (SYN_ITEMS(syn_block)[cur_si->si_idx].sp_flags
|
||||
& (HL_SYNC_HERE|HL_SYNC_THERE)))
|
||||
return TRUE;
|
||||
|
||||
/* syn_current_attr() will have skipped the check for an item
|
||||
* that ends here, need to do that now. Be careful not to go
|
||||
* past the NUL. */
|
||||
prev_current_col = current_col;
|
||||
if (syn_getcurline()[current_col] != NUL)
|
||||
++current_col;
|
||||
check_state_ends();
|
||||
current_col = prev_current_col;
|
||||
}
|
||||
++current_col;
|
||||
/* syn_current_attr() will have skipped the check for an item
|
||||
* that ends here, need to do that now. Be careful not to go
|
||||
* past the NUL. */
|
||||
prev_current_col = current_col;
|
||||
if (syn_getcurline()[current_col] != NUL)
|
||||
++current_col;
|
||||
check_state_ends();
|
||||
current_col = prev_current_col;
|
||||
}
|
||||
++current_col;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
@ -3625,23 +3627,24 @@ static void put_pattern(char *s, int c, synpat_T *spp, int attr)
|
||||
first = TRUE;
|
||||
for (i = 0; i < SPO_COUNT; ++i) {
|
||||
mask = (1 << i);
|
||||
if (spp->sp_off_flags & (mask + (mask << SPO_COUNT))) {
|
||||
if (!first)
|
||||
msg_putchar(','); /* separate with commas */
|
||||
msg_puts((char_u *)spo_name_tab[i]);
|
||||
n = spp->sp_offsets[i];
|
||||
if (i != SPO_LC_OFF) {
|
||||
if (spp->sp_off_flags & mask)
|
||||
msg_putchar('s');
|
||||
else
|
||||
msg_putchar('e');
|
||||
if (n > 0)
|
||||
msg_putchar('+');
|
||||
}
|
||||
if (n || i == SPO_LC_OFF)
|
||||
msg_outnum(n);
|
||||
first = FALSE;
|
||||
if (!(spp->sp_off_flags & (mask + (mask << SPO_COUNT)))) {
|
||||
continue;
|
||||
}
|
||||
if (!first)
|
||||
msg_putchar(','); /* separate with commas */
|
||||
msg_puts((char_u *)spo_name_tab[i]);
|
||||
n = spp->sp_offsets[i];
|
||||
if (i != SPO_LC_OFF) {
|
||||
if (spp->sp_off_flags & mask)
|
||||
msg_putchar('s');
|
||||
else
|
||||
msg_putchar('e');
|
||||
if (n > 0)
|
||||
msg_putchar('+');
|
||||
}
|
||||
if (n || i == SPO_LC_OFF)
|
||||
msg_outnum(n);
|
||||
first = FALSE;
|
||||
}
|
||||
msg_putchar(' ');
|
||||
}
|
||||
@ -3675,62 +3678,63 @@ syn_list_keywords (
|
||||
*/
|
||||
todo = (int)ht->ht_used;
|
||||
for (hi = ht->ht_array; todo > 0 && !got_int; ++hi) {
|
||||
if (!HASHITEM_EMPTY(hi)) {
|
||||
--todo;
|
||||
for (kp = HI2KE(hi); kp != NULL && !got_int; kp = kp->ke_next) {
|
||||
if (kp->k_syn.id == id) {
|
||||
if (prev_contained != (kp->flags & HL_CONTAINED)
|
||||
|| prev_skipnl != (kp->flags & HL_SKIPNL)
|
||||
|| prev_skipwhite != (kp->flags & HL_SKIPWHITE)
|
||||
|| prev_skipempty != (kp->flags & HL_SKIPEMPTY)
|
||||
|| prev_cont_in_list != kp->k_syn.cont_in_list
|
||||
|| prev_next_list != kp->next_list)
|
||||
outlen = 9999;
|
||||
else
|
||||
outlen = (int)STRLEN(kp->keyword);
|
||||
/* output "contained" and "nextgroup" on each line */
|
||||
if (syn_list_header(did_header, outlen, id)) {
|
||||
prev_contained = 0;
|
||||
prev_next_list = NULL;
|
||||
prev_cont_in_list = NULL;
|
||||
prev_skipnl = 0;
|
||||
prev_skipwhite = 0;
|
||||
prev_skipempty = 0;
|
||||
}
|
||||
did_header = TRUE;
|
||||
if (prev_contained != (kp->flags & HL_CONTAINED)) {
|
||||
msg_puts_attr((char_u *)"contained", attr);
|
||||
msg_putchar(' ');
|
||||
prev_contained = (kp->flags & HL_CONTAINED);
|
||||
}
|
||||
if (kp->k_syn.cont_in_list != prev_cont_in_list) {
|
||||
put_id_list((char_u *)"containedin",
|
||||
kp->k_syn.cont_in_list, attr);
|
||||
msg_putchar(' ');
|
||||
prev_cont_in_list = kp->k_syn.cont_in_list;
|
||||
}
|
||||
if (kp->next_list != prev_next_list) {
|
||||
put_id_list((char_u *)"nextgroup", kp->next_list, attr);
|
||||
msg_putchar(' ');
|
||||
prev_next_list = kp->next_list;
|
||||
if (kp->flags & HL_SKIPNL) {
|
||||
msg_puts_attr((char_u *)"skipnl", attr);
|
||||
msg_putchar(' ');
|
||||
prev_skipnl = (kp->flags & HL_SKIPNL);
|
||||
}
|
||||
if (kp->flags & HL_SKIPWHITE) {
|
||||
msg_puts_attr((char_u *)"skipwhite", attr);
|
||||
msg_putchar(' ');
|
||||
prev_skipwhite = (kp->flags & HL_SKIPWHITE);
|
||||
}
|
||||
if (kp->flags & HL_SKIPEMPTY) {
|
||||
msg_puts_attr((char_u *)"skipempty", attr);
|
||||
msg_putchar(' ');
|
||||
prev_skipempty = (kp->flags & HL_SKIPEMPTY);
|
||||
}
|
||||
}
|
||||
msg_outtrans(kp->keyword);
|
||||
if (HASHITEM_EMPTY(hi)) {
|
||||
continue;
|
||||
}
|
||||
--todo;
|
||||
for (kp = HI2KE(hi); kp != NULL && !got_int; kp = kp->ke_next) {
|
||||
if (kp->k_syn.id == id) {
|
||||
if (prev_contained != (kp->flags & HL_CONTAINED)
|
||||
|| prev_skipnl != (kp->flags & HL_SKIPNL)
|
||||
|| prev_skipwhite != (kp->flags & HL_SKIPWHITE)
|
||||
|| prev_skipempty != (kp->flags & HL_SKIPEMPTY)
|
||||
|| prev_cont_in_list != kp->k_syn.cont_in_list
|
||||
|| prev_next_list != kp->next_list)
|
||||
outlen = 9999;
|
||||
else
|
||||
outlen = (int)STRLEN(kp->keyword);
|
||||
/* output "contained" and "nextgroup" on each line */
|
||||
if (syn_list_header(did_header, outlen, id)) {
|
||||
prev_contained = 0;
|
||||
prev_next_list = NULL;
|
||||
prev_cont_in_list = NULL;
|
||||
prev_skipnl = 0;
|
||||
prev_skipwhite = 0;
|
||||
prev_skipempty = 0;
|
||||
}
|
||||
did_header = TRUE;
|
||||
if (prev_contained != (kp->flags & HL_CONTAINED)) {
|
||||
msg_puts_attr((char_u *)"contained", attr);
|
||||
msg_putchar(' ');
|
||||
prev_contained = (kp->flags & HL_CONTAINED);
|
||||
}
|
||||
if (kp->k_syn.cont_in_list != prev_cont_in_list) {
|
||||
put_id_list((char_u *)"containedin",
|
||||
kp->k_syn.cont_in_list, attr);
|
||||
msg_putchar(' ');
|
||||
prev_cont_in_list = kp->k_syn.cont_in_list;
|
||||
}
|
||||
if (kp->next_list != prev_next_list) {
|
||||
put_id_list((char_u *)"nextgroup", kp->next_list, attr);
|
||||
msg_putchar(' ');
|
||||
prev_next_list = kp->next_list;
|
||||
if (kp->flags & HL_SKIPNL) {
|
||||
msg_puts_attr((char_u *)"skipnl", attr);
|
||||
msg_putchar(' ');
|
||||
prev_skipnl = (kp->flags & HL_SKIPNL);
|
||||
}
|
||||
if (kp->flags & HL_SKIPWHITE) {
|
||||
msg_puts_attr((char_u *)"skipwhite", attr);
|
||||
msg_putchar(' ');
|
||||
prev_skipwhite = (kp->flags & HL_SKIPWHITE);
|
||||
}
|
||||
if (kp->flags & HL_SKIPEMPTY) {
|
||||
msg_puts_attr((char_u *)"skipempty", attr);
|
||||
msg_putchar(' ');
|
||||
prev_skipempty = (kp->flags & HL_SKIPEMPTY);
|
||||
}
|
||||
}
|
||||
msg_outtrans(kp->keyword);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3749,27 +3753,28 @@ static void syn_clear_keyword(int id, hashtab_T *ht)
|
||||
hash_lock(ht);
|
||||
todo = (int)ht->ht_used;
|
||||
for (hi = ht->ht_array; todo > 0; ++hi) {
|
||||
if (!HASHITEM_EMPTY(hi)) {
|
||||
--todo;
|
||||
kp_prev = NULL;
|
||||
for (kp = HI2KE(hi); kp != NULL; ) {
|
||||
if (kp->k_syn.id == id) {
|
||||
kp_next = kp->ke_next;
|
||||
if (kp_prev == NULL) {
|
||||
if (kp_next == NULL)
|
||||
hash_remove(ht, hi);
|
||||
else
|
||||
hi->hi_key = KE2HIKEY(kp_next);
|
||||
} else
|
||||
kp_prev->ke_next = kp_next;
|
||||
free(kp->next_list);
|
||||
free(kp->k_syn.cont_in_list);
|
||||
free(kp);
|
||||
kp = kp_next;
|
||||
} else {
|
||||
kp_prev = kp;
|
||||
kp = kp->ke_next;
|
||||
}
|
||||
if (HASHITEM_EMPTY(hi)) {
|
||||
continue;
|
||||
}
|
||||
--todo;
|
||||
kp_prev = NULL;
|
||||
for (kp = HI2KE(hi); kp != NULL; ) {
|
||||
if (kp->k_syn.id == id) {
|
||||
kp_next = kp->ke_next;
|
||||
if (kp_prev == NULL) {
|
||||
if (kp_next == NULL)
|
||||
hash_remove(ht, hi);
|
||||
else
|
||||
hi->hi_key = KE2HIKEY(kp_next);
|
||||
} else
|
||||
kp_prev->ke_next = kp_next;
|
||||
free(kp->next_list);
|
||||
free(kp->k_syn.cont_in_list);
|
||||
free(kp);
|
||||
kp = kp_next;
|
||||
} else {
|
||||
kp_prev = kp;
|
||||
kp = kp->ke_next;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5152,22 +5157,22 @@ get_id_list (
|
||||
regmatch.rm_ic = TRUE;
|
||||
id = 0;
|
||||
for (int i = highlight_ga.ga_len; --i >= 0; ) {
|
||||
if (vim_regexec(®match, HL_TABLE()[i].sg_name,
|
||||
(colnr_T)0)) {
|
||||
if (round == 2) {
|
||||
/* Got more items than expected; can happen
|
||||
* when adding items that match:
|
||||
* "contains=a.*b,axb".
|
||||
* Go back to first round */
|
||||
if (count >= total_count) {
|
||||
free(retval);
|
||||
round = 1;
|
||||
} else
|
||||
retval[count] = i + 1;
|
||||
}
|
||||
++count;
|
||||
id = -1; /* remember that we found one */
|
||||
if (!vim_regexec(®match, HL_TABLE()[i].sg_name, (colnr_T)0)) {
|
||||
continue;
|
||||
}
|
||||
if (round == 2) {
|
||||
/* Got more items than expected; can happen
|
||||
* when adding items that match:
|
||||
* "contains=a.*b,axb".
|
||||
* Go back to first round */
|
||||
if (count >= total_count) {
|
||||
free(retval);
|
||||
round = 1;
|
||||
} else
|
||||
retval[count] = i + 1;
|
||||
}
|
||||
++count;
|
||||
id = -1; /* remember that we found one */
|
||||
}
|
||||
vim_regfree(regmatch.regprog);
|
||||
}
|
||||
|
@ -1463,25 +1463,26 @@ win_equal_rec (
|
||||
/* If 'winfixwidth' set keep the window width if
|
||||
* possible.
|
||||
* Watch out for this window being the next_curwin. */
|
||||
if (frame_fixed_width(fr)) {
|
||||
n = frame_minwidth(fr, NOWIN);
|
||||
new_size = fr->fr_width;
|
||||
if (frame_has_win(fr, next_curwin)) {
|
||||
room += p_wiw - p_wmw;
|
||||
next_curwin_size = 0;
|
||||
if (new_size < p_wiw)
|
||||
new_size = p_wiw;
|
||||
} else
|
||||
/* These windows don't use up room. */
|
||||
totwincount -= (n + (fr->fr_next == NULL
|
||||
? extra_sep : 0)) / (p_wmw + 1);
|
||||
room -= new_size - n;
|
||||
if (room < 0) {
|
||||
new_size += room;
|
||||
room = 0;
|
||||
}
|
||||
fr->fr_newwidth = new_size;
|
||||
if (!frame_fixed_width(fr)) {
|
||||
continue;
|
||||
}
|
||||
n = frame_minwidth(fr, NOWIN);
|
||||
new_size = fr->fr_width;
|
||||
if (frame_has_win(fr, next_curwin)) {
|
||||
room += p_wiw - p_wmw;
|
||||
next_curwin_size = 0;
|
||||
if (new_size < p_wiw)
|
||||
new_size = p_wiw;
|
||||
} else
|
||||
/* These windows don't use up room. */
|
||||
totwincount -= (n + (fr->fr_next == NULL
|
||||
? extra_sep : 0)) / (p_wmw + 1);
|
||||
room -= new_size - n;
|
||||
if (room < 0) {
|
||||
new_size += room;
|
||||
room = 0;
|
||||
}
|
||||
fr->fr_newwidth = new_size;
|
||||
}
|
||||
if (next_curwin_size == -1) {
|
||||
if (!has_next_curwin)
|
||||
@ -1583,25 +1584,26 @@ win_equal_rec (
|
||||
/* If 'winfixheight' set keep the window height if
|
||||
* possible.
|
||||
* Watch out for this window being the next_curwin. */
|
||||
if (frame_fixed_height(fr)) {
|
||||
n = frame_minheight(fr, NOWIN);
|
||||
new_size = fr->fr_height;
|
||||
if (frame_has_win(fr, next_curwin)) {
|
||||
room += p_wh - p_wmh;
|
||||
next_curwin_size = 0;
|
||||
if (new_size < p_wh)
|
||||
new_size = p_wh;
|
||||
} else
|
||||
/* These windows don't use up room. */
|
||||
totwincount -= (n + (fr->fr_next == NULL
|
||||
? extra_sep : 0)) / (p_wmh + 1);
|
||||
room -= new_size - n;
|
||||
if (room < 0) {
|
||||
new_size += room;
|
||||
room = 0;
|
||||
}
|
||||
fr->fr_newheight = new_size;
|
||||
if (!frame_fixed_height(fr)) {
|
||||
continue;
|
||||
}
|
||||
n = frame_minheight(fr, NOWIN);
|
||||
new_size = fr->fr_height;
|
||||
if (frame_has_win(fr, next_curwin)) {
|
||||
room += p_wh - p_wmh;
|
||||
next_curwin_size = 0;
|
||||
if (new_size < p_wh)
|
||||
new_size = p_wh;
|
||||
} else
|
||||
/* These windows don't use up room. */
|
||||
totwincount -= (n + (fr->fr_next == NULL
|
||||
? extra_sep : 0)) / (p_wmh + 1);
|
||||
room -= new_size - n;
|
||||
if (room < 0) {
|
||||
new_size += room;
|
||||
room = 0;
|
||||
}
|
||||
fr->fr_newheight = new_size;
|
||||
}
|
||||
if (next_curwin_size == -1) {
|
||||
if (!has_next_curwin)
|
||||
@ -1759,38 +1761,38 @@ bool one_window(void)
|
||||
*/
|
||||
static int close_last_window_tabpage(win_T *win, int free_buf, tabpage_T *prev_curtab)
|
||||
{
|
||||
if (firstwin == lastwin) {
|
||||
buf_T *old_curbuf = curbuf;
|
||||
|
||||
/*
|
||||
* Closing the last window in a tab page. First go to another tab
|
||||
* page and then close the window and the tab page. This avoids that
|
||||
* curwin and curtab are invalid while we are freeing memory, they may
|
||||
* be used in GUI events.
|
||||
* Don't trigger autocommands yet, they may use wrong values, so do
|
||||
* that below.
|
||||
*/
|
||||
goto_tabpage_tp(alt_tabpage(), FALSE, TRUE);
|
||||
redraw_tabline = TRUE;
|
||||
|
||||
/* Safety check: Autocommands may have closed the window when jumping
|
||||
* to the other tab page. */
|
||||
if (valid_tabpage(prev_curtab) && prev_curtab->tp_firstwin == win) {
|
||||
int h = tabline_height();
|
||||
|
||||
win_close_othertab(win, free_buf, prev_curtab);
|
||||
if (h != tabline_height())
|
||||
shell_new_rows();
|
||||
}
|
||||
/* Since goto_tabpage_tp above did not trigger *Enter autocommands, do
|
||||
* that now. */
|
||||
apply_autocmds(EVENT_WINENTER, NULL, NULL, FALSE, curbuf);
|
||||
apply_autocmds(EVENT_TABENTER, NULL, NULL, FALSE, curbuf);
|
||||
if (old_curbuf != curbuf)
|
||||
apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf);
|
||||
return TRUE;
|
||||
if (firstwin != lastwin) {
|
||||
return FALSE;
|
||||
}
|
||||
return FALSE;
|
||||
buf_T *old_curbuf = curbuf;
|
||||
|
||||
/*
|
||||
* Closing the last window in a tab page. First go to another tab
|
||||
* page and then close the window and the tab page. This avoids that
|
||||
* curwin and curtab are invalid while we are freeing memory, they may
|
||||
* be used in GUI events.
|
||||
* Don't trigger autocommands yet, they may use wrong values, so do
|
||||
* that below.
|
||||
*/
|
||||
goto_tabpage_tp(alt_tabpage(), FALSE, TRUE);
|
||||
redraw_tabline = TRUE;
|
||||
|
||||
/* Safety check: Autocommands may have closed the window when jumping
|
||||
* to the other tab page. */
|
||||
if (valid_tabpage(prev_curtab) && prev_curtab->tp_firstwin == win) {
|
||||
int h = tabline_height();
|
||||
|
||||
win_close_othertab(win, free_buf, prev_curtab);
|
||||
if (h != tabline_height())
|
||||
shell_new_rows();
|
||||
}
|
||||
/* Since goto_tabpage_tp above did not trigger *Enter autocommands, do
|
||||
* that now. */
|
||||
apply_autocmds(EVENT_WINENTER, NULL, NULL, FALSE, curbuf);
|
||||
apply_autocmds(EVENT_TABENTER, NULL, NULL, FALSE, curbuf);
|
||||
if (old_curbuf != curbuf)
|
||||
apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2712,27 +2714,28 @@ close_others (
|
||||
/* Be very careful here: autocommands may change the window layout. */
|
||||
for (wp = firstwin; win_valid(wp); wp = nextwp) {
|
||||
nextwp = wp->w_next;
|
||||
if (wp != curwin) { /* don't close current window */
|
||||
|
||||
/* Check if it's allowed to abandon this window */
|
||||
r = can_abandon(wp->w_buffer, forceit);
|
||||
if (!win_valid(wp)) { /* autocommands messed wp up */
|
||||
nextwp = firstwin;
|
||||
continue;
|
||||
}
|
||||
if (!r) {
|
||||
if (message && (p_confirm || cmdmod.confirm) && p_write) {
|
||||
dialog_changed(wp->w_buffer, FALSE);
|
||||
if (!win_valid(wp)) { /* autocommands messed wp up */
|
||||
nextwp = firstwin;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (bufIsChanged(wp->w_buffer))
|
||||
continue;
|
||||
}
|
||||
win_close(wp, !P_HID(wp->w_buffer) && !bufIsChanged(wp->w_buffer));
|
||||
if (wp == curwin) { /* don't close current window */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check if it's allowed to abandon this window */
|
||||
r = can_abandon(wp->w_buffer, forceit);
|
||||
if (!win_valid(wp)) { /* autocommands messed wp up */
|
||||
nextwp = firstwin;
|
||||
continue;
|
||||
}
|
||||
if (!r) {
|
||||
if (message && (p_confirm || cmdmod.confirm) && p_write) {
|
||||
dialog_changed(wp->w_buffer, FALSE);
|
||||
if (!win_valid(wp)) { /* autocommands messed wp up */
|
||||
nextwp = firstwin;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (bufIsChanged(wp->w_buffer))
|
||||
continue;
|
||||
}
|
||||
win_close(wp, !P_HID(wp->w_buffer) && !bufIsChanged(wp->w_buffer));
|
||||
}
|
||||
|
||||
if (message && lastwin != firstwin)
|
||||
@ -3572,20 +3575,21 @@ win_T *buf_jump_open_tab(buf_T *buf)
|
||||
|
||||
FOR_ALL_TABS(tp) {
|
||||
// Skip the current tab since we already checked it.
|
||||
if (tp != curtab) {
|
||||
FOR_ALL_WINDOWS_IN_TAB(wp, tp) {
|
||||
if (wp->w_buffer == buf) {
|
||||
goto_tabpage_win(tp, wp);
|
||||
if (tp == curtab) {
|
||||
continue;
|
||||
}
|
||||
FOR_ALL_WINDOWS_IN_TAB(wp, tp) {
|
||||
if (wp->w_buffer == buf) {
|
||||
goto_tabpage_win(tp, wp);
|
||||
|
||||
// If we the current window didn't switch,
|
||||
// something went wrong.
|
||||
if (curwin != wp) {
|
||||
wp = NULL;
|
||||
}
|
||||
|
||||
// Return the window we switched to.
|
||||
return wp;
|
||||
// If we the current window didn't switch,
|
||||
// something went wrong.
|
||||
if (curwin != wp) {
|
||||
wp = NULL;
|
||||
}
|
||||
|
||||
// Return the window we switched to.
|
||||
return wp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user