Merge remote-tracking branch 'vim/master'

This commit is contained in:
Yee Cheng Chin
2018-12-26 19:04:45 +08:00
44 changed files with 933 additions and 453 deletions
+1
View File
@@ -80,6 +80,7 @@ src/testdir/dostmp/*
src/testdir/messages
src/testdir/viminfo
src/testdir/opt_test.vim
runtime/indent/testdir/*.out
src/memfile_test
src/json_test
src/message_test
-1
View File
@@ -475,7 +475,6 @@ SRC_DOS = \
src/xxd/Make_mvc.mak \
nsis/gvim.nsi \
nsis/gvim_version.nsh \
nsis/vimrc.ini \
nsis/README.txt \
nsis/lang/*.nsi \
uninstal.txt \
-68
View File
@@ -1,68 +0,0 @@
[Settings]
NumFields=7
[Field 1]
Type=GroupBox
Left=0
Right=-1
Top=0
Bottom=53
Text=" Key remapping "
[Field 2]
Type=radiobutton
Text=Do not remap keys for Windows behavior (Default)
Left=10
Right=-10
Top=17
Bottom=25
State=1
Flags=GROUP
[Field 3]
Type=radiobutton
Text=Remap a few keys for Windows behavior (<C-V>, <C-C>, <C-A>, <C-S>, <C-F>, etc)
Left=10
Right=-10
Top=30
Bottom=47
State=0
Flags=NOTABSTOP
[Field 4]
Type=GroupBox
Left=0
Right=-1
Top=55
Bottom=-5
Text=" Mouse behavior "
[Field 5]
Type=radiobutton
Text=Right button extends selection, left button starts visual mode (Unix)
Left=10
Right=-5
Top=72
Bottom=80
State=0
Flags=GROUP
[Field 6]
Type=radiobutton
Text=Right button has a popup menu, left button starts select mode (Windows)
Left=10
Right=-5
Top=85
Bottom=93
State=0
Flags=NOTABSTOP
[Field 7]
Type=radiobutton
Text=Right button has a popup menu, left button starts visual mode (Default)
Left=10
Right=-5
Top=98
Bottom=106
State=1
Flags=NOTABSTOP
+12 -7
View File
@@ -1,4 +1,4 @@
*eval.txt* For Vim version 8.1. Last change: 2018 Dec 18
*eval.txt* For Vim version 8.1. Last change: 2018 Dec 24
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -2318,7 +2318,7 @@ prompt_setcallback({buf}, {expr}) none set prompt callback function
prompt_setinterrupt({buf}, {text}) none set prompt interrupt function
prompt_setprompt({buf}, {text}) none set prompt text
prop_add({lnum}, {col}, {props}) none add a text property
prop_clear({lnum} [, {lnum-end} [, {bufnr}]])
prop_clear({lnum} [, {lnum-end} [, {props}]])
none remove all text properties
prop_find({props} [, {direction}])
Dict search for a text property
@@ -6695,7 +6695,7 @@ prop_add({lnum}, {col}, {props})
used for a property that does not
continue in another line
"end_lnum" - line number for end of text
"end_col" - column for end of text; not used when
"end_col" - last column of the text; not used when
"length" is present
"bufnr" - buffer to add the property to; when
omitted the current buffer is used
@@ -6710,6 +6710,10 @@ prop_add({lnum}, {col}, {props})
property that spans more than one line.
When neither "length" nor "end_col" are passed the property
will apply to one character.
The property can end exactly at the last character of the
text, or just after it. In the last case, if text is appended
to the line, the text property size will increase, also when
the property type does not have "end_incl" set.
"type" will first be looked up in the buffer the property is
added to. When not found, the global property types are used.
@@ -9233,7 +9237,8 @@ test_ignore_error({expr}) *test_ignore_error()*
error with try/catch cannot be used (because it skips over
following code).
{expr} is used literally, not as a pattern.
There is currently no way to revert this.
When the {expr} is the string "RESET" then the list of ignored
errors is made empty.
test_null_channel() *test_null_channel()*
Return a Channel that is null. Only useful for testing.
@@ -11004,8 +11009,8 @@ This does NOT work: >
The parsing works slightly different from |:echo|,
more like |:execute|. All the expressions are first
evaluated and concatenated before echoing anything.
The expressions must evaluate to a Number or String, a
Dictionary or List causes an error.
If expressions does not evaluate to a Number or
String, string() is used to turn it into a string.
Uses the highlighting set by the |:echohl| command.
Example: >
:echomsg "It's a Zizzer Zazzer Zuzz, as you can plainly see."
@@ -11016,7 +11021,7 @@ This does NOT work: >
message in the |message-history|. When used in a
script or function the line number will be added.
Spaces are placed between the arguments as with the
:echo command. When used inside a try conditional,
|:echomsg| command. When used inside a try conditional,
the message is raised as an error exception instead
(see |try-echoerr|).
Example: >
+17 -5
View File
@@ -142,6 +142,13 @@ func s:StartDebug_internal(dict)
endif
endfunc
" Use when debugger didn't start or ended.
func s:CloseBuffers()
exe 'bwipe! ' . s:ptybuf
exe 'bwipe! ' . s:commbuf
unlet! s:gdbwin
endfunc
func s:StartDebug_term(dict)
" Open a terminal window without a job, to run the debugged program in.
let s:ptybuf = term_start('NONE', {
@@ -181,13 +188,11 @@ func s:StartDebug_term(dict)
let cmd = [g:termdebugger, '-quiet', '-tty', pty] + gdb_args
call ch_log('executing "' . join(cmd) . '"')
let s:gdbbuf = term_start(cmd, {
\ 'exit_cb': function('s:EndTermDebug'),
\ 'term_finish': 'close',
\ })
if s:gdbbuf == 0
echoerr 'Failed to open the gdb terminal window'
exe 'bwipe! ' . s:ptybuf
exe 'bwipe! ' . s:commbuf
call s:CloseBuffers()
return
endif
let s:gdbwin = win_getid(winnr())
@@ -204,6 +209,13 @@ func s:StartDebug_term(dict)
" why the debugger doesn't work.
let try_count = 0
while 1
let gdbproc = term_getjob(s:gdbbuf)
if gdbproc == v:null || job_status(gdbproc) !=# 'run'
echoerr string(g:termdebugger) . ' exited unexpectedly'
call s:CloseBuffers()
return
endif
let response = ''
for lnum in range(1,200)
if term_getline(s:gdbbuf, lnum) =~ 'new-ui mi '
@@ -211,8 +223,7 @@ func s:StartDebug_term(dict)
let response = term_getline(s:gdbbuf, lnum) . term_getline(s:gdbbuf, lnum + 1)
if response =~ 'Undefined command'
echoerr 'Sorry, your gdb is too old, gdb 7.12 is required'
exe 'bwipe! ' . s:ptybuf
exe 'bwipe! ' . s:commbuf
call s:CloseBuffers()
return
endif
if response =~ 'New UI allocated'
@@ -243,6 +254,7 @@ func s:StartDebug_term(dict)
" "Type <return> to continue" prompt.
call s:SendCommand('set pagination off')
call job_setoptions(gdbproc, {'exit_cb': function('s:EndTermDebug')})
call s:StartDebugCommon(a:dict)
endfunc
+4 -3
View File
@@ -323,10 +323,9 @@ CClink = $(CC)
#CONF_ARGS3 = --with-global-runtime=/etc/vim,/usr/share/vim
#CONF_ARGS4 = --with-local-dir=/usr/share
#CONF_ARGS5 = --without-local-dir
CONF_ARGS = $(CONF_ARGS1) $(CONF_ARGS2) $(CONF_ARGS3) $(CONF_ARGS4) $(CONF_ARGS5)
# Use this one if you distribute a modified version of Vim.
#CONF_ARGS = --with-modified-by="John Doe"
#CONF_ARGS6 = --with-modified-by="John Doe"
# GUI - For creating Vim with GUI (gvim) (B)
# Uncomment this line when you don't want to get the GUI version, although you
@@ -1950,7 +1949,9 @@ config auto/config.mk: auto/configure config.mk.in config.h.in
$(CONF_OPT_FEAT) $(CONF_TERM_LIB) \
$(CONF_OPT_COMPBY) $(CONF_OPT_ACL) $(CONF_OPT_NETBEANS) \
$(CONF_OPT_CHANNEL) $(CONF_OPT_TERMINAL) \
$(CONF_ARGS) $(CONF_OPT_MZSCHEME) $(CONF_OPT_PLTHOME) \
$(CONF_ARGS) $(CONF_ARGS1) $(CONF_ARGS2) $(CONF_ARGS3) \
$(CONF_ARGS4) $(CONF_ARGS5) $(CONF_ARGS6) \
$(CONF_OPT_MZSCHEME) $(CONF_OPT_PLTHOME) \
$(CONF_OPT_LUA) $(CONF_OPT_LUA_PREFIX) \
$(CONF_OPT_SYSMOUSE); \
fi
+90 -11
View File
@@ -5875,6 +5875,73 @@ win_found:
#endif
#if defined(FEAT_SIGNS) || defined(PROTO)
static hashtab_T sg_table; // sign group (signgroup_T) hashtable
/*
* A new sign in group 'groupname' is added. If the group is not present,
* create it. Otherwise reference the group.
*/
static signgroup_T *
sign_group_ref(char_u *groupname)
{
static int initialized = FALSE;
hash_T hash;
hashitem_T *hi;
signgroup_T *group;
if (!initialized)
{
initialized = TRUE;
hash_init(&sg_table);
}
hash = hash_hash(groupname);
hi = hash_lookup(&sg_table, groupname, hash);
if (HASHITEM_EMPTY(hi))
{
// new group
group = (signgroup_T *)alloc(
(unsigned)(sizeof(signgroup_T) + STRLEN(groupname)));
if (group == NULL)
return NULL;
STRCPY(group->sg_name, groupname);
group->refcount = 1;
hash_add_item(&sg_table, hi, group->sg_name, hash);
}
else
{
// existing group
group = HI2SG(hi);
group->refcount++;
}
return group;
}
/*
* A sign in group 'groupname' is removed. If all the signs in this group are
* removed, then remove the group.
*/
static void
sign_group_unref(char_u *groupname)
{
hashitem_T *hi;
signgroup_T *group;
hi = hash_find(&sg_table, groupname);
if (!HASHITEM_EMPTY(hi))
{
group = HI2SG(hi);
group->refcount--;
if (group->refcount == 0)
{
// All the signs in this group are removed
hash_remove(&sg_table, hi);
vim_free(group);
}
}
}
/*
* Insert a new sign into the signlist for buffer 'buf' between the 'prev' and
* 'next' signs.
@@ -5900,7 +5967,14 @@ insert_sign(
newsign->lnum = lnum;
newsign->typenr = typenr;
if (group != NULL)
newsign->group = vim_strsave(group);
{
newsign->group = sign_group_ref(group);
if (newsign->group == NULL)
{
vim_free(newsign);
return;
}
}
else
newsign->group = NULL;
newsign->priority = prio;
@@ -5969,7 +6043,7 @@ sign_in_group(signlist_T *sign, char_u *group)
return ((group != NULL && STRCMP(group, "*") == 0) ||
(group == NULL && sign->group == NULL) ||
(group != NULL && sign->group != NULL &&
STRCMP(group, sign->group) == 0));
STRCMP(group, sign->group->sg_name) == 0));
}
/*
@@ -5984,7 +6058,7 @@ sign_get_info(signlist_T *sign)
return NULL;
dict_add_number(d, "id", sign->id);
dict_add_string(d, "group", (sign->group == NULL) ?
(char_u *)"" : sign->group);
(char_u *)"" : sign->group->sg_name);
dict_add_number(d, "lnum", sign->lnum);
dict_add_string(d, "name", sign_typenr2name(sign->typenr));
dict_add_number(d, "priority", sign->priority);
@@ -5999,7 +6073,7 @@ sign_get_info(signlist_T *sign)
buf_addsign(
buf_T *buf, // buffer to store sign in
int id, // sign ID
char_u *group, // sign group
char_u *groupname, // sign group
int prio, // sign priority
linenr_T lnum, // line number which gets the mark
int typenr) // typenr of sign we are adding
@@ -6011,7 +6085,7 @@ buf_addsign(
FOR_ALL_SIGNS_IN_BUF(buf)
{
if (lnum == sign->lnum && id == sign->id &&
sign_in_group(sign, group))
sign_in_group(sign, groupname))
{
// Update an existing sign
sign->typenr = typenr;
@@ -6019,14 +6093,14 @@ buf_addsign(
}
else if (lnum < sign->lnum)
{
insert_sign_by_lnum_prio(buf, prev, id, group, prio, lnum, typenr);
insert_sign_by_lnum_prio(buf, prev, id, groupname, prio,
lnum, typenr);
return;
}
prev = sign;
}
insert_sign_by_lnum_prio(buf, prev, id, group, prio, lnum, typenr);
insert_sign_by_lnum_prio(buf, prev, id, groupname, prio, lnum, typenr);
return;
}
@@ -6116,7 +6190,8 @@ buf_delsign(
if (next != NULL)
next->prev = sign->prev;
lnum = sign->lnum;
vim_free(sign->group);
if (sign->group != NULL)
sign_group_unref(sign->group->sg_name);
vim_free(sign);
// Check whether only one sign needs to be deleted
if (group == NULL || (*group != '*' && id != 0))
@@ -6279,7 +6354,8 @@ buf_delete_signs(buf_T *buf, char_u *group)
*lastp = next;
if (next != NULL)
next->prev = sign->prev;
vim_free(sign->group);
if (sign->group != NULL)
sign_group_unref(sign->group->sg_name);
vim_free(sign);
}
else
@@ -6327,10 +6403,13 @@ sign_list_placed(buf_T *rbuf, char_u *sign_group)
}
FOR_ALL_SIGNS_IN_BUF(buf)
{
if (got_int)
break;
if (!sign_in_group(sign, sign_group))
continue;
if (sign->group != NULL)
vim_snprintf(group, BUFSIZ, " group=%s", sign->group);
vim_snprintf(group, BUFSIZ, " group=%s",
sign->group->sg_name);
else
group[0] = '\0';
vim_snprintf(lbuf, BUFSIZ, _(" line=%ld id=%d%s name=%s "
+1 -1
View File
@@ -4668,7 +4668,7 @@ ins_compl_get_exp(pos_T *ini)
found_new_match = search_for_exact_line(ins_buf, pos,
compl_direction, compl_pattern);
else
found_new_match = searchit(NULL, ins_buf, pos,
found_new_match = searchit(NULL, ins_buf, pos, NULL,
compl_direction,
compl_pattern, 1L, SEARCH_KEEP + SEARCH_NFMSG,
RE_LAST, (linenr_T)0, NULL, NULL);
+30 -1
View File
@@ -7162,6 +7162,30 @@ tv_get_string_buf_chk(typval_T *varp, char_u *buf)
return NULL;
}
/*
* Turn a typeval into a string. Similar to tv_get_string_buf() but uses
* string() on Dict, List, etc.
*/
char_u *
tv_stringify(typval_T *varp, char_u *buf)
{
if (varp->v_type == VAR_LIST
|| varp->v_type == VAR_DICT
|| varp->v_type == VAR_FUNC
|| varp->v_type == VAR_PARTIAL
|| varp->v_type == VAR_FLOAT)
{
typval_T tmp;
f_string(varp, &tmp);
tv_get_string_buf(&tmp, buf);
clear_tv(varp);
*varp = tmp;
return tmp.vval.v_string;
}
return tv_get_string_buf(varp, buf);
}
/*
* Find variable "name" in the list of variables.
* Return a pointer to it if found, NULL if not found.
@@ -8142,7 +8166,12 @@ ex_execute(exarg_T *eap)
if (!eap->skip)
{
p = tv_get_string(&rettv);
char_u buf[NUMBUFLEN];
if (eap->cmdidx == CMD_execute)
p = tv_get_string_buf(&rettv, buf);
else
p = tv_stringify(&rettv, buf);
len = (int)STRLEN(p);
if (ga_grow(&ga, len + 2) == FAIL)
{
+4 -5
View File
@@ -396,7 +396,6 @@ static void f_strftime(typval_T *argvars, typval_T *rettv);
#endif
static void f_strgetchar(typval_T *argvars, typval_T *rettv);
static void f_stridx(typval_T *argvars, typval_T *rettv);
static void f_string(typval_T *argvars, typval_T *rettv);
static void f_strlen(typval_T *argvars, typval_T *rettv);
static void f_strcharpart(typval_T *argvars, typval_T *rettv);
static void f_strpart(typval_T *argvars, typval_T *rettv);
@@ -10088,7 +10087,7 @@ search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
}
pos = save_cursor = curwin->w_cursor;
subpatnum = searchit(curwin, curbuf, &pos, dir, pat, 1L,
subpatnum = searchit(curwin, curbuf, &pos, NULL, dir, pat, 1L,
options, RE_SEARCH, (linenr_T)lnum_stop, &tm, NULL);
if (subpatnum != FAIL)
{
@@ -10446,7 +10445,7 @@ do_searchpair(
pat = pat3;
for (;;)
{
n = searchit(curwin, curbuf, &pos, dir, pat, 1L,
n = searchit(curwin, curbuf, &pos, NULL, dir, pat, 1L,
options, RE_SEARCH, lnum_stop, &tm, NULL);
if (n == FAIL || (firstpos.lnum != 0 && EQUAL_POS(pos, firstpos)))
/* didn't find it or found the first match again: FAIL */
@@ -12506,7 +12505,7 @@ f_stridx(typval_T *argvars, typval_T *rettv)
/*
* "string()" function
*/
static void
void
f_string(typval_T *argvars, typval_T *rettv)
{
char_u *tofree;
@@ -13618,7 +13617,7 @@ f_test_override(typval_T *argvars, typval_T *rettv UNUSED)
EMSG(_(e_invarg));
else
{
name = tv_get_string_chk(&argvars[0]);
name = tv_get_string(&argvars[0]);
val = (int)tv_get_number(&argvars[1]);
if (STRCMP(name, (char_u *)"redraw") == 0)
+1 -1
View File
@@ -8180,7 +8180,7 @@ ex_sign(exarg_T *eap)
{
EMSG2(_("E158: Invalid buffer name: %s"), arg);
}
else if (id <= 0 && !(idx == SIGNCMD_UNPLACE && id == -2))
else if (id <= 0 && idx == SIGNCMD_PLACE)
{
if ((group == NULL) && (lnum >= 0 || sign_name != NULL))
EMSG(_(e_invarg));
+3 -3
View File
@@ -4685,7 +4685,7 @@ get_address(
#ifdef FEAT_VIRTUALEDIT
pos.coladd = 0;
#endif
if (searchit(curwin, curbuf, &pos,
if (searchit(curwin, curbuf, &pos, NULL,
*cmd == '?' ? BACKWARD : FORWARD,
(char_u *)"", 1L, SEARCH_MSG,
i, (linenr_T)0, NULL, NULL) != FAIL)
@@ -11722,7 +11722,7 @@ ses_skipframe(frame_T *fr)
{
frame_T *frc;
for (frc = fr; frc != NULL; frc = frc->fr_next)
FOR_ALL_FRAMES(frc, fr)
if (ses_do_frame(frc))
break;
return frc;
@@ -11739,7 +11739,7 @@ ses_do_frame(frame_T *fr)
if (fr->fr_layout == FR_LEAF)
return ses_do_win(fr->fr_win);
for (frc = fr->fr_child; frc != NULL; frc = frc->fr_next)
FOR_ALL_FRAMES(frc, fr->fr_child)
if (ses_do_frame(frc))
return TRUE;
return FALSE;
+1 -1
View File
@@ -675,7 +675,7 @@ may_adjust_incsearch_highlighting(
++emsg_off;
save = pat[patlen];
pat[patlen] = NUL;
i = searchit(curwin, curbuf, &t,
i = searchit(curwin, curbuf, &t, NULL,
c == Ctrl_G ? FORWARD : BACKWARD,
pat, count, search_flags,
RE_SEARCH, 0, NULL, NULL);
+5
View File
@@ -9055,6 +9055,7 @@ aucmd_prepbuf(
aco->save_curwin = curwin;
aco->save_curbuf = curbuf;
aco->save_prevwin = prevwin;
if (win != NULL)
{
/* There is a window for "buf" in the current tab page, make it the
@@ -9165,6 +9166,8 @@ win_found:
else
/* Hmm, original window disappeared. Just use the first one. */
curwin = firstwin;
if (win_valid(aco->save_prevwin))
prevwin = aco->save_prevwin;
#ifdef FEAT_EVAL
vars_clear(&aucmd_win->w_vars->dv_hashtab); /* free all w: variables */
hash_init(&aucmd_win->w_vars->dv_hashtab); /* re-use the hashtab */
@@ -9215,6 +9218,8 @@ win_found:
curwin = aco->save_curwin;
curbuf = curwin->w_buffer;
if (win_valid(aco->save_prevwin))
prevwin = aco->save_prevwin;
/* In case the autocommand move the cursor to a position that that
* not exist in curbuf. */
check_cursor();
+2
View File
@@ -564,6 +564,8 @@ EXTERN win_T *prevwin INIT(= NULL); /* previous window */
# define ONE_WINDOW (firstwin == lastwin)
# define W_NEXT(wp) ((wp)->w_next)
# define FOR_ALL_WINDOWS(wp) for (wp = firstwin; wp != NULL; wp = wp->w_next)
# define FOR_ALL_FRAMES(frp, first_frame) \
for (frp = first_frame; frp != NULL; frp = frp->fr_next)
# define FOR_ALL_TABPAGES(tp) for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
# define FOR_ALL_WINDOWS_IN_TAB(tp, wp) \
for ((wp) = ((tp) == NULL || (tp) == curtab) \
+4 -3
View File
@@ -687,9 +687,10 @@ gui_init(void)
gui.shell_created = TRUE;
#ifndef FEAT_GUI_GTK
/* Set the shell size, adjusted for the screen size. For GTK this only
* works after the shell has been opened, thus it is further down. */
gui_set_shellsize(TRUE, TRUE, RESIZE_BOTH);
// Set the shell size, adjusted for the screen size. For GTK this only
// works after the shell has been opened, thus it is further down.
// For MS-Windows pass FALSE for "mustset" to make --windowid work.
gui_set_shellsize(FALSE, TRUE, RESIZE_BOTH);
#endif
#if defined(FEAT_GUI_MOTIF) && defined(FEAT_MENU)
/* Need to set the size of the menubar after all the menus have been
+25 -5
View File
@@ -2922,8 +2922,7 @@ FunctionNew(PyTypeObject *subtype, char_u *name, int argc, typval_T *argv,
{
FunctionObject *self;
self = (FunctionObject *) subtype->tp_alloc(subtype, 0);
self = (FunctionObject *)subtype->tp_alloc(subtype, 0);
if (self == NULL)
return NULL;
@@ -2938,15 +2937,36 @@ FunctionNew(PyTypeObject *subtype, char_u *name, int argc, typval_T *argv,
self->name = vim_strsave(name);
}
else
if ((self->name = get_expanded_name(name,
vim_strchr(name, AUTOLOAD_CHAR) == NULL))
== NULL)
{
char_u *p;
if ((p = get_expanded_name(name,
vim_strchr(name, AUTOLOAD_CHAR) == NULL)) == NULL)
{
PyErr_FORMAT(PyExc_ValueError,
N_("function %s does not exist"), name);
return NULL;
}
if (p[0] == K_SPECIAL && p[1] == KS_EXTRA && p[2] == (int)KE_SNR)
{
char_u *np;
size_t len = STRLEN(p) + 1;
if ((np = alloc((int)len + 2)) == NULL)
{
vim_free(p);
return NULL;
}
mch_memmove(np, "<SNR>", 5);
mch_memmove(np + 5, p + 3, len - 3);
vim_free(p);
self->name = np;
}
else
self->name = p;
}
func_ref(self->name);
self->argc = argc;
self->argv = argv;
+8
View File
@@ -53,6 +53,8 @@ static VTermState *vterm_state_new(VTerm *vt)
{
VTermState *state = vterm_allocator_malloc(vt, sizeof(VTermState));
if (state == NULL)
return NULL;
state->vt = vt;
state->rows = vt->rows;
@@ -1693,6 +1695,10 @@ static const VTermParserCallbacks parser_callbacks = {
on_resize /* resize */
};
/*
* Return the existing state or create a new one.
* Returns NULL when out of memory.
*/
VTermState *vterm_obtain_state(VTerm *vt)
{
VTermState *state;
@@ -1700,6 +1706,8 @@ VTermState *vterm_obtain_state(VTerm *vt)
return vt->state;
state = vterm_state_new(vt);
if (state == NULL)
return NULL;
vt->state = state;
state->combine_chars_size = 16;
+16 -12
View File
@@ -1,5 +1,6 @@
#include "vterm_internal.h"
/* vim: set sw=2 : */
#include <stdio.h>
#include <string.h>
@@ -95,8 +96,7 @@ static ScreenCell *realloc_buffer(VTermScreen *screen, ScreenCell *buffer, int n
}
}
if(buffer)
vterm_allocator_free(screen->vt, buffer);
vterm_allocator_free(screen->vt, buffer);
return new_buffer;
}
@@ -518,8 +518,7 @@ static int resize(int new_rows, int new_cols, VTermPos *delta, void *user)
screen->rows = new_rows;
screen->cols = new_cols;
if(screen->sb_buffer)
vterm_allocator_free(screen->vt, screen->sb_buffer);
vterm_allocator_free(screen->vt, screen->sb_buffer);
screen->sb_buffer = vterm_allocator_malloc(screen->vt, sizeof(VTermScreenCell) * new_cols);
@@ -619,16 +618,21 @@ static VTermStateCallbacks state_cbs = {
&setlineinfo /* setlineinfo */
};
/*
* Allocate a new screen and return it.
* Return NULL when out of memory.
*/
static VTermScreen *screen_new(VTerm *vt)
{
VTermState *state = vterm_obtain_state(vt);
VTermScreen *screen;
int rows, cols;
if(!state)
if (state == NULL)
return NULL;
screen = vterm_allocator_malloc(vt, sizeof(VTermScreen));
if (screen == NULL)
return NULL;
vterm_get_size(vt, &rows, &cols);
@@ -646,10 +650,13 @@ static VTermScreen *screen_new(VTerm *vt)
screen->cbdata = NULL;
screen->buffers[0] = realloc_buffer(screen, NULL, rows, cols);
screen->buffer = screen->buffers[0];
screen->sb_buffer = vterm_allocator_malloc(screen->vt, sizeof(VTermScreenCell) * cols);
if (screen->buffer == NULL || screen->sb_buffer == NULL)
{
vterm_screen_free(screen);
return NULL;
}
vterm_state_set_callbacks(screen->state, &state_cbs, screen);
@@ -659,11 +666,8 @@ static VTermScreen *screen_new(VTerm *vt)
INTERNAL void vterm_screen_free(VTermScreen *screen)
{
vterm_allocator_free(screen->vt, screen->buffers[0]);
if(screen->buffers[1])
vterm_allocator_free(screen->vt, screen->buffers[1]);
vterm_allocator_free(screen->vt, screen->buffers[1]);
vterm_allocator_free(screen->vt, screen->sb_buffer);
vterm_allocator_free(screen->vt, screen);
}
+19 -1
View File
@@ -1,5 +1,6 @@
#define DEFINE_INLINES
/* vim: set sw=2 : */
#include "vterm_internal.h"
#include <stdio.h>
@@ -41,6 +42,8 @@ VTerm *vterm_new_with_allocator(int rows, int cols, VTermAllocatorFunctions *fun
/* Need to bootstrap using the allocator function directly */
VTerm *vt = (*funcs->malloc)(sizeof(VTerm), allocdata);
if (vt == NULL)
return NULL;
vt->allocator = funcs;
vt->allocdata = allocdata;
@@ -55,10 +58,21 @@ VTerm *vterm_new_with_allocator(int rows, int cols, VTermAllocatorFunctions *fun
vt->parser.strbuffer_len = 500; /* should be able to hold an OSC string */
vt->parser.strbuffer_cur = 0;
vt->parser.strbuffer = vterm_allocator_malloc(vt, vt->parser.strbuffer_len);
if (vt->parser.strbuffer == NULL)
{
vterm_allocator_free(vt, vt);
return NULL;
}
vt->outbuffer_len = 200;
vt->outbuffer_cur = 0;
vt->outbuffer = vterm_allocator_malloc(vt, vt->outbuffer_len);
if (vt->outbuffer == NULL)
{
vterm_allocator_free(vt, vt->parser.strbuffer);
vterm_allocator_free(vt, vt);
return NULL;
}
return vt;
}
@@ -82,9 +96,13 @@ INTERNAL void *vterm_allocator_malloc(VTerm *vt, size_t size)
return (*vt->allocator->malloc)(size, vt->allocdata);
}
/*
* Free "ptr" unless it is NULL.
*/
INTERNAL void vterm_allocator_free(VTerm *vt, void *ptr)
{
(*vt->allocator->free)(ptr, vt->allocdata);
if (ptr)
(*vt->allocator->free)(ptr, vt->allocdata);
}
void vterm_get_size(const VTerm *vt, int *rowsp, int *colsp)
+41 -11
View File
@@ -3179,14 +3179,14 @@ ml_replace_len(linenr_T lnum, char_u *line_arg, colnr_T len_arg, int copy)
curbuf->b_ml.ml_flags &= ~ML_LINE_DIRTY;
#ifdef FEAT_TEXT_PROP
if (has_any_text_properties(curbuf))
if (curbuf->b_has_textprop)
// Need to fetch the old line to copy over any text properties.
ml_get_buf(curbuf, lnum, TRUE);
#endif
}
#ifdef FEAT_TEXT_PROP
if (has_any_text_properties(curbuf))
if (curbuf->b_has_textprop)
{
size_t oldtextlen = STRLEN(curbuf->b_ml.ml_line_ptr) + 1;
@@ -5131,6 +5131,7 @@ ml_updatechunk(
{
int count; /* number of entries in block */
int idx;
int end_idx;
int text_end;
int linecnt;
@@ -5154,23 +5155,39 @@ ml_updatechunk(
(long)(buf->b_ml.ml_locked_low) + 1;
idx = curline - buf->b_ml.ml_locked_low;
curline = buf->b_ml.ml_locked_high + 1;
if (idx == 0)/* first line in block, text at the end */
text_end = dp->db_txt_end;
else
text_end = ((dp->db_index[idx - 1]) & DB_INDEX_MASK);
/* Compute index of last line to use in this MEMLINE */
// compute index of last line to use in this MEMLINE
rest = count - idx;
if (linecnt + rest > MLCS_MINL)
{
idx += MLCS_MINL - linecnt - 1;
end_idx = idx + MLCS_MINL - linecnt - 1;
linecnt = MLCS_MINL;
}
else
{
idx = count - 1;
end_idx = count - 1;
linecnt += rest;
}
size += text_end - ((dp->db_index[idx]) & DB_INDEX_MASK);
#ifdef FEAT_TEXT_PROP
if (buf->b_has_textprop)
{
int i;
// We cannot use the text pointers to get the text length,
// the text prop info would also be counted. Go over the
// lines.
for (i = end_idx; i < idx; ++i)
size += STRLEN((char_u *)dp + (dp->db_index[i] & DB_INDEX_MASK)) + 1;
}
else
#endif
{
if (idx == 0)/* first line in block, text at the end */
text_end = dp->db_txt_end;
else
text_end = ((dp->db_index[idx - 1]) & DB_INDEX_MASK);
size += text_end - ((dp->db_index[end_idx]) & DB_INDEX_MASK);
}
}
buf->b_ml.ml_chunksize[curix].mlcs_numlines = linecnt;
buf->b_ml.ml_chunksize[curix + 1].mlcs_numlines -= linecnt;
@@ -5360,7 +5377,20 @@ ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp)
idx++;
}
}
len = text_end - ((dp->db_index[idx]) & DB_INDEX_MASK);
#ifdef FEAT_TEXT_PROP
if (buf->b_has_textprop)
{
int i;
// cannot use the db_index pointer, need to get the actual text
// lengths.
len = 0;
for (i = start_idx; i <= idx; ++i)
len += STRLEN((char_u *)dp + ((dp->db_index[idx]) & DB_INDEX_MASK)) + 1;
}
else
#endif
len = text_end - ((dp->db_index[idx]) & DB_INDEX_MASK);
size += len;
if (offset != 0 && size >= offset)
{
+4 -1
View File
@@ -553,7 +553,10 @@ ignore_error_for_testing(char_u *error)
if (ignore_error_list.ga_itemsize == 0)
ga_init2(&ignore_error_list, sizeof(char_u *), 1);
ga_add_string(&ignore_error_list, error);
if (STRCMP("RESET", error) == 0)
ga_clear_strings(&ignore_error_list);
else
ga_add_string(&ignore_error_list, error);
}
static int
+1 -1
View File
@@ -4342,7 +4342,7 @@ find_decl(
for (;;)
{
valid = FALSE;
t = searchit(curwin, curbuf, &curwin->w_cursor, FORWARD,
t = searchit(curwin, curbuf, &curwin->w_cursor, NULL, FORWARD,
pat, 1L, searchflags, RE_LAST, (linenr_T)0, NULL, NULL);
if (curwin->w_cursor.lnum >= old_pos.lnum)
t = FAIL; /* match after start is failure too */
+1
View File
@@ -89,6 +89,7 @@ char_u *tv_get_string(typval_T *varp);
char_u *tv_get_string_buf(typval_T *varp, char_u *buf);
char_u *tv_get_string_chk(typval_T *varp);
char_u *tv_get_string_buf_chk(typval_T *varp, char_u *buf);
char_u *tv_stringify(typval_T *varp, char_u *buf);
dictitem_T *find_var(char_u *name, hashtab_T **htp, int no_autoload);
dictitem_T *find_var_in_ht(hashtab_T *ht, int htname, char_u *varname, int no_autoload);
hashtab_T *find_var_ht(char_u *name, char_u **varname);
+1
View File
@@ -9,6 +9,7 @@ void execute_redir_str(char_u *value, int value_len);
void mzscheme_call_vim(char_u *name, typval_T *args, typval_T *rettv);
float_T vim_round(float_T f);
long do_searchpair(char_u *spat, char_u *mpat, char_u *epat, int dir, typval_T *skip, int flags, pos_T *match_pos, linenr_T lnum_stop, long time_limit);
void f_string(typval_T *argvars, typval_T *rettv);
char_u *get_callback(typval_T *arg, partial_T **pp);
void free_callback(char_u *callback, partial_T *partial);
/* vim: set ft=c : */
+1 -1
View File
@@ -22,7 +22,7 @@ char_u *last_search_pat(void);
void reset_search_dir(void);
void set_last_search_pat(char_u *s, int idx, int magic, int setlast);
void last_pat_prog(regmmatch_T *regmatch);
int searchit(win_T *win, buf_T *buf, pos_T *pos, int dir, char_u *pat, long count, int options, int pat_use, linenr_T stop_lnum, proftime_T *tm, int *timed_out);
int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, int dir, char_u *pat, long count, int options, int pat_use, linenr_T stop_lnum, proftime_T *tm, int *timed_out);
void set_search_direction(int cdir);
int do_search(oparg_T *oap, int dirc, char_u *pat, long count, int options, proftime_T *tm, int *timed_out);
int search_for_exact_line(buf_T *buf, pos_T *pos, int dir, char_u *pat);
-1
View File
@@ -1,6 +1,5 @@
/* textprop.c */
void f_prop_add(typval_T *argvars, typval_T *rettv);
int has_any_text_properties(buf_T *buf);
int get_text_props(buf_T *buf, linenr_T lnum, char_u **props, int will_change);
proptype_T *text_prop_type_by_id(buf_T *buf, int id);
void f_prop_clear(typval_T *argvars, typval_T *rettv);
+21 -10
View File
@@ -6241,14 +6241,16 @@ qf_get_properties(win_T *wp, dict_T *what, dict_T *retdict)
/*
* Add a new quickfix entry to list at 'qf_idx' in the stack 'qi' from the
* items in the dict 'd'.
* items in the dict 'd'. If it is a valid error entry, then set 'valid_entry'
* to TRUE.
*/
static int
qf_add_entry_from_dict(
qf_info_T *qi,
int qf_idx,
dict_T *d,
int first_entry)
int first_entry,
int *valid_entry)
{
static int did_bufnr_emsg;
char_u *filename, *module, *pattern, *text, *type;
@@ -6313,6 +6315,9 @@ qf_add_entry_from_dict(
vim_free(text);
vim_free(type);
if (valid)
*valid_entry = TRUE;
return status;
}
@@ -6333,6 +6338,7 @@ qf_add_entries(
dict_T *d;
qfline_T *old_last = NULL;
int retval = OK;
int valid_entry = FALSE;
if (action == ' ' || qf_idx == qi->qf_listcount)
{
@@ -6359,22 +6365,27 @@ qf_add_entries(
if (d == NULL)
continue;
retval = qf_add_entry_from_dict(qi, qf_idx, d, li == list->lv_first);
retval = qf_add_entry_from_dict(qi, qf_idx, d, li == list->lv_first,
&valid_entry);
if (retval == FAIL)
break;
}
if (qfl->qf_index == 0)
// Check if any valid error entries are added to the list.
if (valid_entry)
qfl->qf_nonevalid = FALSE;
else if (qfl->qf_index == 0)
// no valid entry
qfl->qf_nonevalid = TRUE;
else
qfl->qf_nonevalid = FALSE;
// If not appending to the list, set the current error to the first entry
if (action != 'a')
{
qfl->qf_ptr = qfl->qf_start;
if (!qf_list_empty(qi, qf_idx))
qfl->qf_index = 1;
}
// Update the current error index if not appending to the list or if the
// list was empty before and it is not empty now.
if ((action != 'a' || qfl->qf_index == 0) && !qf_list_empty(qi, qf_idx))
qfl->qf_index = 1;
// Don't update the cursor in quickfix window when appending entries
qf_update_buffer(qi, old_last);
+73 -67
View File
@@ -4298,6 +4298,66 @@ win_line(
}
#endif
#ifdef FEAT_TEXT_PROP
if (text_props != NULL)
{
int pi;
// Check if any active property ends.
for (pi = 0; pi < text_props_active; ++pi)
{
int tpi = text_prop_idxs[pi];
if (col >= text_props[tpi].tp_col - 1
+ text_props[tpi].tp_len)
{
if (pi + 1 < text_props_active)
mch_memmove(text_prop_idxs + pi,
text_prop_idxs + pi + 1,
sizeof(int)
* (text_props_active - (pi + 1)));
--text_props_active;
--pi;
}
}
// Add any text property that starts in this column.
while (text_prop_next < text_prop_count
&& col >= text_props[text_prop_next].tp_col - 1)
text_prop_idxs[text_props_active++] = text_prop_next++;
text_prop_type = NULL;
if (text_props_active > 0)
{
int max_priority = INT_MIN;
int max_col = 0;
// Get the property type with the highest priority
// and/or starting last.
for (pi = 0; pi < text_props_active; ++pi)
{
int tpi = text_prop_idxs[pi];
proptype_T *pt;
pt = text_prop_type_by_id(
curwin->w_buffer, text_props[tpi].tp_type);
if (pt != NULL
&& (pt->pt_priority > max_priority
|| (pt->pt_priority == max_priority
&& text_props[tpi].tp_col >= max_col)))
{
text_prop_type = pt;
max_priority = pt->pt_priority;
max_col = text_props[tpi].tp_col;
}
}
if (text_prop_type != NULL)
text_prop_attr =
syn_id2attr(text_prop_type->pt_hl_id);
}
}
#endif
/* Decide which of the highlight attributes to use. */
attr_pri = TRUE;
#ifdef LINE_ATTR
@@ -4657,8 +4717,8 @@ win_line(
#endif
#ifdef FEAT_SYN_HL
/* Get syntax attribute, unless still at the start of the line
* (double-wide char that doesn't fit). */
// Get syntax attribute, unless still at the start of the line
// (double-wide char that doesn't fit).
v = (long)(ptr - line);
if (has_syntax && v > 0)
{
@@ -4690,10 +4750,16 @@ win_line(
line = ml_get_buf(wp->w_buffer, lnum, FALSE);
ptr = line + v;
if (!attr_pri)
char_attr = syntax_attr;
else
char_attr = hl_combine_attr(syntax_attr, char_attr);
# ifdef FEAT_TEXT_PROP
// Text properties overrule syntax highlighting.
if (text_prop_attr == 0)
#endif
{
if (!attr_pri)
char_attr = syntax_attr;
else
char_attr = hl_combine_attr(syntax_attr, char_attr);
}
# ifdef FEAT_CONCEAL
/* no concealing past the end of the line, it interferes
* with line highlighting */
@@ -4705,66 +4771,6 @@ win_line(
}
#endif
#ifdef FEAT_TEXT_PROP
if (text_props != NULL)
{
int pi;
// Check if any active property ends.
for (pi = 0; pi < text_props_active; ++pi)
{
int tpi = text_prop_idxs[pi];
if (col >= text_props[tpi].tp_col - 1
+ text_props[tpi].tp_len)
{
if (pi + 1 < text_props_active)
mch_memmove(text_prop_idxs + pi,
text_prop_idxs + pi + 1,
sizeof(int)
* (text_props_active - (pi + 1)));
--text_props_active;
--pi;
}
}
// Add any text property that starts in this column.
while (text_prop_next < text_prop_count
&& col >= text_props[text_prop_next].tp_col - 1)
text_prop_idxs[text_props_active++] = text_prop_next++;
text_prop_type = NULL;
if (text_props_active > 0)
{
int max_priority = INT_MIN;
int max_col = 0;
// Get the property type with the highest priority
// and/or starting last.
for (pi = 0; pi < text_props_active; ++pi)
{
int tpi = text_prop_idxs[pi];
proptype_T *pt;
pt = text_prop_type_by_id(
curwin->w_buffer, text_props[tpi].tp_type);
if (pt != NULL
&& (pt->pt_priority > max_priority
|| (pt->pt_priority == max_priority
&& text_props[tpi].tp_col >= max_col)))
{
text_prop_type = pt;
max_priority = pt->pt_priority;
max_col = text_props[tpi].tp_col;
}
}
if (text_prop_type != NULL)
text_prop_attr =
syn_id2attr(text_prop_type->pt_hl_id);
}
}
#endif
#ifdef FEAT_SPELL
/* Check spelling (unless at the end of the line).
* Only do this when there is no syntax highlighting, the
@@ -6701,7 +6707,7 @@ win_redraw_last_status(frame_T *frp)
frp->fr_win->w_redr_status = TRUE;
else if (frp->fr_layout == FR_ROW)
{
for (frp = frp->fr_child; frp != NULL; frp = frp->fr_next)
FOR_ALL_FRAMES(frp, frp->fr_child)
win_redraw_last_status(frp);
}
else /* frp->fr_layout == FR_COL */
+32 -47
View File
@@ -619,8 +619,8 @@ last_pat_prog(regmmatch_T *regmatch)
/*
* Lowest level search function.
* Search for 'count'th occurrence of pattern 'pat' in direction 'dir'.
* Start at position 'pos' and return the found position in 'pos'.
* Search for 'count'th occurrence of pattern "pat" in direction "dir".
* Start at position "pos" and return the found position in "pos".
*
* if (options & SEARCH_MSG) == 0 don't give any messages
* if (options & SEARCH_MSG) == SEARCH_NFMSG don't give 'notfound' messages
@@ -643,6 +643,7 @@ searchit(
buffer without a window! */
buf_T *buf,
pos_T *pos,
pos_T *end_pos, // set to end of the match, unless NULL
int dir,
char_u *pat,
long count,
@@ -1044,14 +1045,26 @@ searchit(
}
#endif
}
if (end_pos != NULL)
{
end_pos->lnum = lnum + matchpos.lnum;
end_pos->col = matchpos.col;
}
}
else
{
pos->lnum = lnum + matchpos.lnum;
pos->col = matchpos.col;
if (end_pos != NULL)
{
end_pos->lnum = lnum + endpos.lnum;
end_pos->col = endpos.col;
}
}
#ifdef FEAT_VIRTUALEDIT
pos->coladd = 0;
if (end_pos != NULL)
end_pos->coladd = 0;
#endif
found = 1;
first_match = FALSE;
@@ -1505,7 +1518,7 @@ do_search(
lrFswap(searchstr,0);
#endif
c = searchit(curwin, curbuf, &pos, dirc == '/' ? FORWARD : BACKWARD,
c = searchit(curwin, curbuf, &pos, NULL, dirc == '/' ? FORWARD : BACKWARD,
searchstr, count, spats[0].off.end + (options &
(SEARCH_KEEP + SEARCH_PEEK + SEARCH_HIS
+ SEARCH_MSG + SEARCH_START
@@ -4674,20 +4687,19 @@ static int is_one_char(char_u *pattern, int move, pos_T *cur, int direction);
int
current_search(
long count,
int forward) /* move forward or backwards */
int forward) // TRUE for forward, FALSE for backward
{
pos_T start_pos; /* position before the pattern */
pos_T orig_pos; /* position of the cursor at beginning */
pos_T first_match; /* position of first match */
pos_T pos; /* position after the pattern */
pos_T start_pos; // start position of the pattern match
pos_T end_pos; // end position of the pattern match
pos_T orig_pos; // position of the cursor at beginning
pos_T pos; // position after the pattern
int i;
int dir;
int result; /* result of various function calls */
int result; // result of various function calls
char_u old_p_ws = p_ws;
int flags = 0;
pos_T save_VIsual = VIsual;
int one_char;
int direction = forward ? FORWARD : BACKWARD;
/* wrapping should not occur */
p_ws = FALSE;
@@ -4739,8 +4751,10 @@ current_search(
flags = 0;
if (!dir && !one_char)
flags = SEARCH_END;
end_pos = pos;
result = searchit(curwin, curbuf, &pos, (dir ? FORWARD : BACKWARD),
result = searchit(curwin, curbuf, &pos, &end_pos,
(dir ? FORWARD : BACKWARD),
spats[last_idx].pat, (long) (i ? count : 1),
SEARCH_KEEP | flags, RE_SEARCH, 0, NULL, NULL);
@@ -4748,7 +4762,7 @@ current_search(
* beginning of the file (cursor might be on the search match)
* except when Visual mode is active, so that extending the visual
* selection works. */
if (!result && i) /* not found, abort */
if (i == 1 && !result) /* not found, abort */
{
curwin->w_cursor = orig_pos;
if (VIsual_active)
@@ -4756,7 +4770,7 @@ current_search(
p_ws = old_p_ws;
return FAIL;
}
else if (!i && !result)
else if (i == 0 && !result)
{
if (forward)
{
@@ -4772,48 +4786,19 @@ current_search(
ml_get(curwin->w_buffer->b_ml.ml_line_count));
}
}
if (i == 0)
first_match = pos;
p_ws = old_p_ws;
}
start_pos = pos;
flags = forward ? SEARCH_END : SEARCH_START;
/* Check again from the current cursor position,
* since the next match might actually by only one char wide */
one_char = is_one_char(spats[last_idx].pat, FALSE, &pos, direction);
if (one_char < 0)
/* search failed, abort */
return FAIL;
/* move to match, except for zero-width matches, in which case, we are
* already on the next match */
if (!one_char)
{
p_ws = FALSE;
for (i = 0; i < 2; i++)
{
result = searchit(curwin, curbuf, &pos, direction,
spats[last_idx].pat, 0L, flags | SEARCH_KEEP, RE_SEARCH, 0,
NULL, NULL);
/* Search successfull, break out from the loop */
if (result)
break;
/* search failed, try again from the last search position match */
pos = first_match;
}
}
p_ws = old_p_ws;
/* not found */
if (!result)
return FAIL;
if (!VIsual_active)
VIsual = start_pos;
curwin->w_cursor = pos;
// put cursor on last character of match
curwin->w_cursor = end_pos;
if (LT_POS(VIsual, end_pos))
dec_cursor();
VIsual_active = TRUE;
VIsual_mode = 'v';
@@ -4889,7 +4874,7 @@ is_one_char(char_u *pattern, int move, pos_T *cur, int direction)
flag = SEARCH_START;
}
if (searchit(curwin, curbuf, &pos, direction, pattern, 1,
if (searchit(curwin, curbuf, &pos, NULL, direction, pattern, 1,
SEARCH_KEEP + flag, RE_SEARCH, 0, NULL, NULL) != FAIL)
{
/* Zero-width pattern should match somewhere, then we can check if
+16 -3
View File
@@ -705,7 +705,7 @@ typedef struct memline
*/
typedef struct textprop_S
{
colnr_T tp_col; // start column
colnr_T tp_col; // start column (one based)
colnr_T tp_len; // length in bytes
int tp_id; // identifier
int tp_type; // property type
@@ -733,6 +733,17 @@ typedef struct proptype_S
#if defined(FEAT_SIGNS) || defined(PROTO)
// Sign group
typedef struct signgroup_S
{
short_u refcount; // number of signs in this group
char_u sg_name[1]; // sign group name
} signgroup_T;
// Macros to get the sign group structure from the group name
#define SGN_KEY_OFF offsetof(signgroup_T, sg_name)
#define HI2SG(hi) ((signgroup_T *)((hi)->hi_key - SGN_KEY_OFF))
typedef struct signlist signlist_T;
struct signlist
@@ -740,7 +751,7 @@ struct signlist
int id; /* unique identifier for each placed sign */
linenr_T lnum; /* line number which has this sign */
int typenr; /* typenr of sign */
char_u *group; /* sign group */
signgroup_T *group; /* sign group */
int priority; /* priority for highlighting */
signlist_T *next; /* next signlist entry */
signlist_T *prev; /* previous entry -- for easy reordering */
@@ -2406,7 +2417,8 @@ struct file_buffer
dict_T *b_vars; /* internal variables, local to buffer */
#endif
#ifdef FEAT_TEXT_PROP
hashtab_T *b_proptypes; /* text property types local to buffer */
int b_has_textprop; // TRUE when text props were added
hashtab_T *b_proptypes; // text property types local to buffer
#endif
#if defined(FEAT_BEVAL) && defined(FEAT_EVAL)
@@ -3271,6 +3283,7 @@ typedef struct
int use_aucmd_win; /* using aucmd_win */
win_T *save_curwin; /* saved curwin */
win_T *new_curwin; /* new curwin */
win_T *save_prevwin; /* saved prevwin */
bufref_T new_curbuf; /* new curbuf */
char_u *globaldir; /* saved value of globaldir */
} aco_save_T;
+25 -7
View File
@@ -3435,6 +3435,7 @@ set_vterm_palette(VTerm *vterm, long_u *rgb)
{
int index = 0;
VTermState *state = vterm_obtain_state(vterm);
for (; index < 16; index++)
{
VTermColor color;
@@ -3708,8 +3709,9 @@ static VTermAllocatorFunctions vterm_allocator = {
/*
* Create a new vterm and initialize it.
* Return FAIL when out of memory.
*/
static void
static int
create_vterm(term_T *term, int rows, int cols)
{
VTerm *vterm;
@@ -3719,7 +3721,18 @@ create_vterm(term_T *term, int rows, int cols)
vterm = vterm_new_with_allocator(rows, cols, &vterm_allocator, NULL);
term->tl_vterm = vterm;
if (vterm == NULL)
return FAIL;
// Allocate screen and state here, so we can bail out if that fails.
state = vterm_obtain_state(vterm);
screen = vterm_obtain_screen(vterm);
if (state == NULL || screen == NULL)
{
vterm_free(vterm);
return FAIL;
}
vterm_screen_set_callbacks(screen, &screen_callbacks, term);
/* TODO: depends on 'encoding'. */
vterm_set_utf8(vterm, 1);
@@ -3727,7 +3740,7 @@ create_vterm(term_T *term, int rows, int cols)
init_default_colors(term);
vterm_state_set_default_colors(
vterm_obtain_state(vterm),
state,
&term->tl_default_color.fg,
&term->tl_default_color.bg);
@@ -3751,9 +3764,10 @@ create_vterm(term_T *term, int rows, int cols)
#else
value.boolean = 0;
#endif
state = vterm_obtain_state(vterm);
vterm_state_set_termprop(state, VTERM_PROP_CURSORBLINK, &value);
vterm_state_set_unrecognised_fallbacks(state, &parser_fallbacks, term);
return OK;
}
/*
@@ -5634,7 +5648,8 @@ term_and_job_init(
vim_free(cwd_wchar);
vim_free(env_wchar);
create_vterm(term, term->tl_rows, term->tl_cols);
if (create_vterm(term, term->tl_rows, term->tl_cols) == FAIL)
goto failed;
#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
if (opt->jo_set2 & JO2_ANSI_COLORS)
@@ -5715,7 +5730,8 @@ create_pty_only(term_T *term, jobopt_T *options)
char in_name[80], out_name[80];
channel_T *channel = NULL;
create_vterm(term, term->tl_rows, term->tl_cols);
if (create_vterm(term, term->tl_rows, term->tl_cols) == FAIL)
return FAIL;
vim_snprintf(in_name, sizeof(in_name), "\\\\.\\pipe\\vim-%d-in-%d",
GetCurrentProcessId(),
@@ -5827,7 +5843,8 @@ term_and_job_init(
jobopt_T *opt,
jobopt_T *orig_opt UNUSED)
{
create_vterm(term, term->tl_rows, term->tl_cols);
if (create_vterm(term, term->tl_rows, term->tl_cols) == FAIL)
return FAIL;
#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
if (opt->jo_set2 & JO2_ANSI_COLORS)
@@ -5849,7 +5866,8 @@ term_and_job_init(
static int
create_pty_only(term_T *term, jobopt_T *opt)
{
create_vterm(term, term->tl_rows, term->tl_cols);
if (create_vterm(term, term->tl_rows, term->tl_cols) == FAIL)
return FAIL;
term->tl_job = job_alloc();
if (term->tl_job == NULL)
+19
View File
@@ -131,4 +131,23 @@ func Test_gn_command()
set wrapscan&vim
endfu
func Test_gn_multi_line()
new
call setline(1, [
\ 'func Tm1()',
\ ' echo "one"',
\ 'endfunc',
\ 'func Tm2()',
\ ' echo "two"',
\ 'endfunc',
\ 'func Tm3()',
\ ' echo "three"',
\ 'endfunc',
\])
/\v^func Tm\d\(\)\n.*\zs".*"\ze$
normal jgnrx
call assert_equal(' echo xxxxx', getline(5))
bwipe!
endfunc
" vim: shiftwidth=2 sts=2 expandtab
+29 -1
View File
@@ -1,4 +1,4 @@
" Tests for :messages
" Tests for :messages, :echomsg, :echoerr
function Test_messages()
let oldmore = &more
@@ -64,3 +64,31 @@ func Test_message_completion()
call feedkeys(":message \<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"message clear', @:)
endfunc
func Test_echomsg()
call assert_equal("\nhello", execute(':echomsg "hello"'))
call assert_equal("\n", execute(':echomsg ""'))
call assert_equal("\n12345", execute(':echomsg 12345'))
call assert_equal("\n[]", execute(':echomsg []'))
call assert_equal("\n[1, 2, 3]", execute(':echomsg [1, 2, 3]'))
call assert_equal("\n{}", execute(':echomsg {}'))
call assert_equal("\n{'a': 1, 'b': 2}", execute(':echomsg {"a": 1, "b": 2}'))
if has('float')
call assert_equal("\n1.23", execute(':echomsg 1.23'))
endif
call assert_match("function('<lambda>\\d*')", execute(':echomsg {-> 1234}'))
endfunc
func Test_echoerr()
call test_ignore_error('IgNoRe')
call assert_equal("\nIgNoRe hello", execute(':echoerr "IgNoRe hello"'))
call assert_equal("\n12345 IgNoRe", execute(':echoerr 12345 "IgNoRe"'))
call assert_equal("\n[1, 2, 'IgNoRe']", execute(':echoerr [1, 2, "IgNoRe"]'))
call assert_equal("\n{'IgNoRe': 2, 'a': 1}", execute(':echoerr {"a": 1, "IgNoRe": 2}'))
if has('float')
call assert_equal("\n1.23 IgNoRe", execute(':echoerr 1.23 "IgNoRe"'))
endif
call test_ignore_error('<lambda>')
call assert_match("function('<lambda>\\d*')", execute(':echoerr {-> 1234}'))
call test_ignore_error('RESET')
endfunc
+27
View File
@@ -36,3 +36,30 @@ func Test_set_cursor()
normal j
call assert_equal([2, 6], [line('.'), col('.')])
endfunc
func Test_vim_function()
" Check creating vim.Function object
py import vim
func s:foo()
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+_foo$')
endfunc
let name = '<SNR>' . s:foo()
try
py f = vim.bindeval('function("s:foo")')
call assert_equal(name, pyeval('f.name'))
catch
call assert_false(v:exception)
endtry
try
py f = vim.Function('\x80\xfdR' + vim.eval('s:foo()'))
call assert_equal(name, pyeval('f.name'))
catch
call assert_false(v:exception)
endtry
py del f
delfunc s:foo
endfunc
+27
View File
@@ -36,3 +36,30 @@ func Test_set_cursor()
normal j
call assert_equal([2, 6], [line('.'), col('.')])
endfunc
func Test_vim_function()
" Check creating vim.Function object
py3 import vim
func s:foo()
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+_foo$')
endfunc
let name = '<SNR>' . s:foo()
try
py3 f = vim.bindeval('function("s:foo")')
call assert_equal(name, py3eval('f.name'))
catch
call assert_false(v:exception)
endtry
try
py3 f = vim.Function(b'\x80\xfdR' + vim.eval('s:foo()').encode())
call assert_equal(name, py3eval('f.name'))
catch
call assert_false(v:exception)
endtry
py3 del f
delfunc s:foo
endfunc
+22
View File
@@ -1299,6 +1299,28 @@ func SetXlistTests(cchar, bnum)
let l = g:Xgetlist()
call g:Xsetlist(l)
call assert_equal(0, g:Xgetlist()[0].valid)
" Adding a non-valid entry should not mark the list as having valid entries
call g:Xsetlist([{'bufnr':a:bnum, 'lnum':5, 'valid':0}], 'a')
Xwindow
call assert_equal(1, winnr('$'))
" :cnext/:cprev should still work even with invalid entries in the list
let l = [{'bufnr' : a:bnum, 'lnum' : 1, 'text' : '1', 'valid' : 0},
\ {'bufnr' : a:bnum, 'lnum' : 2, 'text' : '2', 'valid' : 0}]
call g:Xsetlist(l)
Xnext
call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
Xprev
call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
" :cnext/:cprev should still work after appending invalid entries to an
" empty list
call g:Xsetlist([])
call g:Xsetlist(l, 'a')
Xnext
call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
Xprev
call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
call g:Xsetlist([{'text':'Text1', 'valid':1}])
Xwindow
call assert_equal(2, winnr('$'))
+65 -59
View File
@@ -59,7 +59,7 @@ func Test_sign()
redraw
" Check that we can't change sign.
call assert_fails("exe 'sign place 40 name=Sign1 buffer=' . bufnr('%')", 'E885:')
call assert_fails("sign place 40 name=Sign1 buffer=" . bufnr('%'), 'E885:')
" Check placed signs
let a=execute('sign place')
@@ -68,7 +68,7 @@ func Test_sign()
" Unplace the sign and try jumping to it again should fail.
sign unplace 41
1
call assert_fails("exe 'sign jump 41 buffer=' . bufnr('%')", 'E157:')
call assert_fails("sign jump 41 buffer=" . bufnr('%'), 'E157:')
call assert_equal('a', getline('.'))
" Unplace sign on current line.
@@ -132,17 +132,22 @@ func Test_sign()
sign undefine Sign4
" Error cases
call assert_fails("exe 'sign place abc line=3 name=Sign1 buffer=' . bufnr('%')", 'E474:')
call assert_fails("exe 'sign unplace abc name=Sign1 buffer=' . bufnr('%')", 'E474:')
call assert_fails("exe 'sign place 1abc line=3 name=Sign1 buffer=' . bufnr('%')", 'E474:')
call assert_fails("exe 'sign unplace 2abc name=Sign1 buffer=' . bufnr('%')", 'E474:')
call assert_fails("sign place abc line=3 name=Sign1 buffer=" .
\ bufnr('%'), 'E474:')
call assert_fails("sign unplace abc name=Sign1 buffer=" .
\ bufnr('%'), 'E474:')
call assert_fails("sign place 1abc line=3 name=Sign1 buffer=" .
\ bufnr('%'), 'E474:')
call assert_fails("sign unplace 2abc name=Sign1 buffer=" .
\ bufnr('%'), 'E474:')
call assert_fails("sign unplace 2 *", 'E474:')
call assert_fails("exe 'sign place 1 line=3 name=Sign1 buffer=' . bufnr('%') a", 'E488:')
call assert_fails("exe 'sign place name=Sign1 buffer=' . bufnr('%')", 'E474:')
call assert_fails("exe 'sign place line=10 buffer=' . bufnr('%')", 'E474:')
call assert_fails("exe 'sign unplace 2 line=10 buffer=' . bufnr('%')", 'E474:')
call assert_fails("exe 'sign unplace 2 name=Sign1 buffer=' . bufnr('%')", 'E474:')
call assert_fails("exe 'sign place 2 line=3 buffer=' . bufnr('%')", 'E474:')
call assert_fails("sign place 1 line=3 name=Sign1 buffer=" .
\ bufnr('%') . " a", 'E488:')
call assert_fails("sign place name=Sign1 buffer=" . bufnr('%'), 'E474:')
call assert_fails("sign place line=10 buffer=" . bufnr('%'), 'E474:')
call assert_fails("sign unplace 2 line=10 buffer=" . bufnr('%'), 'E474:')
call assert_fails("sign unplace 2 name=Sign1 buffer=" . bufnr('%'), 'E474:')
call assert_fails("sign place 2 line=3 buffer=" . bufnr('%'), 'E474:')
call assert_fails("sign place 2", 'E474:')
call assert_fails("sign place abc", 'E474:')
call assert_fails("sign place 5 line=3", 'E474:')
@@ -157,7 +162,8 @@ func Test_sign()
sign undefine Sign1
sign undefine Sign2
sign undefine Sign3
call assert_fails("exe 'sign place 41 line=3 name=Sign1 buffer=' . bufnr('%')", 'E155:')
call assert_fails("sign place 41 line=3 name=Sign1 buffer=" .
\ bufnr('%'), 'E155:')
endfunc
" Undefining placed sign is not recommended.
@@ -236,33 +242,33 @@ func Test_sign_invalid_commands()
call assert_fails('sign place 1 buffer=999', 'E158:')
call assert_fails('sign define Sign2 text=', 'E239:')
" Non-numeric identifier for :sign place
call assert_fails("exe 'sign place abc line=3 name=Sign1 buffer=' . bufnr('%')", 'E474:')
call assert_fails("sign place abc line=3 name=Sign1 buffer=" . bufnr('%'), 'E474:')
" Non-numeric identifier for :sign unplace
call assert_fails("exe 'sign unplace abc name=Sign1 buffer=' . bufnr('%')", 'E474:')
call assert_fails("sign unplace abc name=Sign1 buffer=" . bufnr('%'), 'E474:')
" Number followed by an alphabet as sign identifier for :sign place
call assert_fails("exe 'sign place 1abc line=3 name=Sign1 buffer=' . bufnr('%')", 'E474:')
call assert_fails("sign place 1abc line=3 name=Sign1 buffer=" . bufnr('%'), 'E474:')
" Number followed by an alphabet as sign identifier for :sign unplace
call assert_fails("exe 'sign unplace 2abc name=Sign1 buffer=' . bufnr('%')", 'E474:')
call assert_fails("sign unplace 2abc name=Sign1 buffer=" . bufnr('%'), 'E474:')
" Sign identifier and '*' for :sign unplace
call assert_fails("sign unplace 2 *", 'E474:')
" Trailing characters after buffer number for :sign place
call assert_fails("exe 'sign place 1 line=3 name=Sign1 buffer=' . bufnr('%') . 'xxx'", 'E488:')
call assert_fails("sign place 1 line=3 name=Sign1 buffer=" . bufnr('%') . 'xxx', 'E488:')
" Trailing characters after buffer number for :sign unplace
call assert_fails("exe 'sign unplace 1 buffer=' . bufnr('%') . 'xxx'", 'E488:')
call assert_fails("exe 'sign unplace * buffer=' . bufnr('%') . 'xxx'", 'E488:')
call assert_fails("sign unplace 1 buffer=" . bufnr('%') . 'xxx', 'E488:')
call assert_fails("sign unplace * buffer=" . bufnr('%') . 'xxx', 'E488:')
call assert_fails("sign unplace 1 xxx", 'E474:')
call assert_fails("sign unplace * xxx", 'E474:')
call assert_fails("sign unplace xxx", 'E474:')
" Placing a sign without line number
call assert_fails("exe 'sign place name=Sign1 buffer=' . bufnr('%')", 'E474:')
call assert_fails("sign place name=Sign1 buffer=" . bufnr('%'), 'E474:')
" Placing a sign without sign name
call assert_fails("exe 'sign place line=10 buffer=' . bufnr('%')", 'E474:')
call assert_fails("sign place line=10 buffer=" . bufnr('%'), 'E474:')
" Unplacing a sign with line number
call assert_fails("exe 'sign unplace 2 line=10 buffer=' . bufnr('%')", 'E474:')
call assert_fails("sign unplace 2 line=10 buffer=" . bufnr('%'), 'E474:')
" Unplacing a sign with sign name
call assert_fails("exe 'sign unplace 2 name=Sign1 buffer=' . bufnr('%')", 'E474:')
call assert_fails("sign unplace 2 name=Sign1 buffer=" . bufnr('%'), 'E474:')
" Placing a sign without sign name
call assert_fails("exe 'sign place 2 line=3 buffer=' . bufnr('%')", 'E474:')
call assert_fails("sign place 2 line=3 buffer=" . bufnr('%'), 'E474:')
" Placing a sign with only sign identifier
call assert_fails("sign place 2", 'E474:')
" Placing a sign with only a name
@@ -574,24 +580,24 @@ func Test_sign_group()
call sign_unplace('*')
" Test for :sign command and groups
exe 'sign place 5 line=10 name=sign1 file=' . fname
exe 'sign place 5 group=g1 line=10 name=sign1 file=' . fname
exe 'sign place 5 group=g2 line=10 name=sign1 file=' . fname
sign place 5 line=10 name=sign1 file=Xsign
sign place 5 group=g1 line=10 name=sign1 file=Xsign
sign place 5 group=g2 line=10 name=sign1 file=Xsign
" Test for :sign place group={group} file={fname}
let a = execute('sign place file=' . fname)
let a = execute('sign place file=Xsign')
call assert_equal("\n--- Signs ---\nSigns for Xsign:\n line=10 id=5 name=sign1 priority=10\n", a)
let a = execute('sign place group=g2 file=' . fname)
let a = execute('sign place group=g2 file=Xsign')
call assert_equal("\n--- Signs ---\nSigns for Xsign:\n line=10 id=5 group=g2 name=sign1 priority=10\n", a)
let a = execute('sign place group=* file=' . fname)
let a = execute('sign place group=* file=Xsign')
call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
\ " line=10 id=5 group=g2 name=sign1 priority=10\n" .
\ " line=10 id=5 group=g1 name=sign1 priority=10\n" .
\ " line=10 id=5 name=sign1 priority=10\n", a)
let a = execute('sign place group=xyz file=' . fname)
let a = execute('sign place group=xyz file=Xsign')
call assert_equal("\n--- Signs ---\nSigns for Xsign:\n", a)
call sign_unplace('*')
@@ -624,22 +630,22 @@ func Test_sign_group()
\ " line=12 id=5 group=g2 name=sign1 priority=10\n", a)
" Test for :sign unplace
exe 'sign unplace 5 group=g2 file=' . fname
sign unplace 5 group=g2 file=Xsign
call assert_equal([], sign_getplaced(bnum, {'group' : 'g2'})[0].signs)
exe 'sign unplace 5 group=g1 buffer=' . bnum
call assert_equal([], sign_getplaced(bnum, {'group' : 'g1'})[0].signs)
exe 'sign unplace 5 group=xy file=' . fname
sign unplace 5 group=xy file=Xsign
call assert_equal(1, len(sign_getplaced(bnum, {'group' : '*'})[0].signs))
" Test for removing all the signs. Place the signs again for this test
exe 'sign place 5 group=g1 line=11 name=sign1 file=' . fname
exe 'sign place 5 group=g2 line=12 name=sign1 file=' . fname
exe 'sign place 6 line=20 name=sign1 file=' . fname
exe 'sign place 6 group=g1 line=21 name=sign1 file=' . fname
exe 'sign place 6 group=g2 line=22 name=sign1 file=' . fname
exe 'sign unplace 5 group=* file=' . fname
sign place 5 group=g1 line=11 name=sign1 file=Xsign
sign place 5 group=g2 line=12 name=sign1 file=Xsign
sign place 6 line=20 name=sign1 file=Xsign
sign place 6 group=g1 line=21 name=sign1 file=Xsign
sign place 6 group=g2 line=22 name=sign1 file=Xsign
sign unplace 5 group=* file=Xsign
let a = execute('sign place group=*')
call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
\ " line=20 id=6 name=sign1 priority=10\n" .
@@ -647,17 +653,17 @@ func Test_sign_group()
\ " line=22 id=6 group=g2 name=sign1 priority=10\n", a)
" Remove all the signs from the global group
exe 'sign unplace * file=' . fname
sign unplace * file=Xsign
let a = execute('sign place group=*')
call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
\ " line=21 id=6 group=g1 name=sign1 priority=10\n" .
\ " line=22 id=6 group=g2 name=sign1 priority=10\n", a)
" Remove all the signs from a particular group
exe 'sign place 5 line=10 name=sign1 file=' . fname
exe 'sign place 5 group=g1 line=11 name=sign1 file=' . fname
exe 'sign place 5 group=g2 line=12 name=sign1 file=' . fname
exe 'sign unplace * group=g1 file=' . fname
sign place 5 line=10 name=sign1 file=Xsign
sign place 5 group=g1 line=11 name=sign1 file=Xsign
sign place 5 group=g2 line=12 name=sign1 file=Xsign
sign unplace * group=g1 file=Xsign
let a = execute('sign place group=*')
call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
\ " line=10 id=5 name=sign1 priority=10\n" .
@@ -665,26 +671,26 @@ func Test_sign_group()
\ " line=22 id=6 group=g2 name=sign1 priority=10\n", a)
" Remove all the signs from all the groups in a file
exe 'sign place 5 group=g1 line=11 name=sign1 file=' . fname
exe 'sign place 6 line=20 name=sign1 file=' . fname
exe 'sign place 6 group=g1 line=21 name=sign1 file=' . fname
exe 'sign unplace * group=* file=' . fname
sign place 5 group=g1 line=11 name=sign1 file=Xsign
sign place 6 line=20 name=sign1 file=Xsign
sign place 6 group=g1 line=21 name=sign1 file=Xsign
sign unplace * group=* file=Xsign
let a = execute('sign place group=*')
call assert_equal("\n--- Signs ---\n", a)
" Remove a particular sign id in a group from all the files
exe 'sign place 5 group=g1 line=11 name=sign1 file=' . fname
sign place 5 group=g1 line=11 name=sign1 file=Xsign
sign unplace 5 group=g1
let a = execute('sign place group=*')
call assert_equal("\n--- Signs ---\n", a)
" Remove a particular sign id in all the groups from all the files
exe 'sign place 5 line=10 name=sign1 file=' . fname
exe 'sign place 5 group=g1 line=11 name=sign1 file=' . fname
exe 'sign place 5 group=g2 line=12 name=sign1 file=' . fname
exe 'sign place 6 line=20 name=sign1 file=' . fname
exe 'sign place 6 group=g1 line=21 name=sign1 file=' . fname
exe 'sign place 6 group=g2 line=22 name=sign1 file=' . fname
sign place 5 line=10 name=sign1 file=Xsign
sign place 5 group=g1 line=11 name=sign1 file=Xsign
sign place 5 group=g2 line=12 name=sign1 file=Xsign
sign place 6 line=20 name=sign1 file=Xsign
sign place 6 group=g1 line=21 name=sign1 file=Xsign
sign place 6 group=g2 line=22 name=sign1 file=Xsign
sign unplace 5 group=*
let a = execute('sign place group=*')
call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
@@ -693,14 +699,14 @@ func Test_sign_group()
\ " line=22 id=6 group=g2 name=sign1 priority=10\n", a)
" Remove all the signs from all the groups in all the files
exe 'sign place 5 line=10 name=sign1 file=' . fname
exe 'sign place 5 group=g1 line=11 name=sign1 file=' . fname
sign place 5 line=10 name=sign1 file=Xsign
sign place 5 group=g1 line=11 name=sign1 file=Xsign
sign unplace * group=*
let a = execute('sign place group=*')
call assert_equal("\n--- Signs ---\n", a)
" Error cases
call assert_fails("exe 'sign place 3 group= name=sign1 buffer=' . bnum", 'E474:')
call assert_fails("sign place 3 group= name=sign1 buffer=" . bnum, 'E474:')
call delete("Xsign")
call sign_unplace('*')
+13 -5
View File
@@ -159,10 +159,16 @@ func Check_123(buf)
call assert_equal('2', l[1].chars)
call assert_equal('3', l[2].chars)
call assert_equal('#00e000', l[0].fg)
if &background == 'light'
call assert_equal('#ffffff', l[0].bg)
if has('win32')
" On Windows 'background' always defaults to dark, even though the terminal
" may use a light background. Therefore accept both white and black.
call assert_match('#ffffff\|#000000', l[0].bg)
else
call assert_equal('#000000', l[0].bg)
if &background == 'light'
call assert_equal('#ffffff', l[0].bg)
else
call assert_equal('#000000', l[0].bg)
endif
endif
let l = term_getline(a:buf, -1)
@@ -1709,11 +1715,13 @@ func Test_stop_in_terminal()
call WaitForAssert({-> assert_match('ready', Get_terminal_text(bufnr, lastrow))})
call term_sendkeys(bufnr, ":stop\r")
" Not sure where "Stopped" shows up, assume in the first three lines.
" Not sure where "Stopped" shows up, need five lines for Arch.
call WaitForAssert({-> assert_match('Stopped',
\ Get_terminal_text(bufnr, 1) .
\ Get_terminal_text(bufnr, 2) .
\ Get_terminal_text(bufnr, 3))})
\ Get_terminal_text(bufnr, 3) .
\ Get_terminal_text(bufnr, 4) .
\ Get_terminal_text(bufnr, 5))})
call term_sendkeys(bufnr, "fg\r")
call term_sendkeys(bufnr, ":echo 'back again'\r")
+43
View File
@@ -197,4 +197,47 @@ func Test_prop_clear_buf()
bwipe!
endfunc
func Test_prop_multiline()
call prop_type_add('comment', {'highlight': 'Directory'})
new
call setline(1, ['xxxxxxx', 'yyyyyyyyy', 'zzzzzzzz'])
" start halfway line 1, end halfway line 3
call prop_add(1, 3, {'end_lnum': 3, 'end_col': 5, 'type': 'comment'})
let expect1 = {'col': 3, 'length': 6, 'type': 'comment', 'start': 1, 'end': 0, 'id': 0}
call assert_equal([expect1], prop_list(1))
let expect2 = {'col': 1, 'length': 10, 'type': 'comment', 'start': 0, 'end': 0, 'id': 0}
call assert_equal([expect2], prop_list(2))
let expect3 = {'col': 1, 'length': 5, 'type': 'comment', 'start': 0, 'end': 1, 'id': 0}
call assert_equal([expect3], prop_list(3))
call prop_clear(1, 3)
" include all three lines
call prop_add(1, 1, {'end_lnum': 3, 'end_col': 999, 'type': 'comment'})
let expect1.col = 1
let expect1.length = 8
call assert_equal([expect1], prop_list(1))
call assert_equal([expect2], prop_list(2))
let expect3.length = 9
call assert_equal([expect3], prop_list(3))
call prop_clear(1, 3)
bwipe!
call prop_type_delete('comment')
endfunc
func Test_prop_byteoff()
call prop_type_add('comment', {'highlight': 'Directory'})
new
call setline(1, ['line1', 'line2', ''])
set ff=unix
call assert_equal(13, line2byte(3))
call prop_add(1, 1, {'end_col': 3, 'type': 'comment'})
call assert_equal(13, line2byte(3))
bwipe!
call prop_type_delete('comment')
endfunc
" TODO: screenshot test with highlighting
+37
View File
@@ -578,4 +578,41 @@ func Test_winrestcmd()
only
endfunc
function! Fun_RenewFile()
sleep 2
silent execute '!echo "1" > tmp.txt'
sp
wincmd p
edit! tmp.txt
endfunction
func Test_window_prevwin()
" Can we make this work on MS-Windows?
if !has('unix')
return
endif
set hidden autoread
call writefile(['2'], 'tmp.txt')
new tmp.txt
q
" Need to wait a bit for the timestamp to be older.
call Fun_RenewFile()
call assert_equal(2, winnr())
wincmd p
call assert_equal(1, winnr())
wincmd p
q
call Fun_RenewFile()
call assert_equal(2, winnr())
wincmd p
call assert_equal(1, winnr())
wincmd p
" reset
q
call delete('tmp.txt')
set hidden&vim autoread&vim
delfunc Fun_RenewFile
endfunc
" vim: shiftwidth=2 sts=2 expandtab
+119 -75
View File
@@ -17,10 +17,16 @@
* Text properties have a type, which can be used to specify highlighting.
*
* TODO:
* - mismatch in column 1 being the first column
* - Let props overrule syntax HL.
* - When deleting a line where a prop ended, adjust flag of previous line.
* - When deleting a line where a prop started, adjust flag of next line.
* - When inserting a line add props that continue from previous line.
* - Adjust property column and length when text is inserted/deleted
* - Add an arrray for global_proptypes, to quickly lookup a proptype by ID
* - Add an arrray for b_proptypes, to quickly lookup a proptype by ID
* - adjust property column when text is inserted/deleted
* - support properties that continue over a line break
* - Also test line2byte() with many lines, so that ml_updatechunk() is taken
* into account.
* - add mechanism to keep track of changed lines.
*/
@@ -47,6 +53,7 @@ static int proptype_id = 0;
static char_u e_type_not_exist[] = N_("E971: Property type %s does not exist");
static char_u e_invalid_col[] = N_("E964: Invalid column number: %ld");
static char_u e_invalid_lnum[] = N_("E966: Invalid line number: %ld");
/*
* Find a property type by name, return the hashitem.
@@ -139,9 +146,11 @@ get_bufnr_from_arg(typval_T *arg, buf_T **buf)
f_prop_add(typval_T *argvars, typval_T *rettv UNUSED)
{
linenr_T lnum;
colnr_T col;
linenr_T start_lnum;
linenr_T end_lnum;
colnr_T start_col;
colnr_T end_col;
dict_T *dict;
colnr_T length = 1;
char_u *type_name;
proptype_T *type;
buf_T *buf = curbuf;
@@ -154,11 +163,11 @@ f_prop_add(typval_T *argvars, typval_T *rettv UNUSED)
textprop_T tmp_prop;
int i;
lnum = tv_get_number(&argvars[0]);
col = tv_get_number(&argvars[1]);
if (col < 1)
start_lnum = tv_get_number(&argvars[0]);
start_col = tv_get_number(&argvars[1]);
if (start_col < 1)
{
EMSGN(_(e_invalid_col), (long)col);
EMSGN(_(e_invalid_col), (long)start_col);
return;
}
if (argvars[2].v_type != VAR_DICT)
@@ -177,22 +186,40 @@ f_prop_add(typval_T *argvars, typval_T *rettv UNUSED)
if (dict_find(dict, (char_u *)"end_lnum", -1) != NULL)
{
// TODO: handle end_lnum
EMSG("Sorry, end_lnum not supported yet");
return;
end_lnum = dict_get_number(dict, (char_u *)"end_lnum");
if (end_lnum < start_lnum)
{
EMSG2(_(e_invargval), "end_lnum");
return;
}
}
else
end_lnum = start_lnum;
if (dict_find(dict, (char_u *)"length", -1) != NULL)
length = dict_get_number(dict, (char_u *)"length");
{
long length = dict_get_number(dict, (char_u *)"length");
if (length < 1 || end_lnum > start_lnum)
{
EMSG2(_(e_invargval), "length");
return;
}
end_col = start_col + length - 1;
}
else if (dict_find(dict, (char_u *)"end_col", -1) != NULL)
{
length = dict_get_number(dict, (char_u *)"end_col") - col;
if (length <= 0)
end_col = dict_get_number(dict, (char_u *)"end_col");
if (end_col <= 0)
{
EMSG2(_(e_invargval), "end_col");
return;
}
}
else if (start_lnum == end_lnum)
end_col = start_col;
else
end_col = 1;
if (dict_find(dict, (char_u *)"id", -1) != NULL)
id = dict_get_number(dict, (char_u *)"id");
@@ -204,75 +231,91 @@ f_prop_add(typval_T *argvars, typval_T *rettv UNUSED)
if (type == NULL)
return;
if (lnum < 1 || lnum > buf->b_ml.ml_line_count)
if (start_lnum < 1 || start_lnum > buf->b_ml.ml_line_count)
{
EMSGN(_("E966: Invalid line number: %ld"), (long)lnum);
EMSGN(_(e_invalid_lnum), (long)start_lnum);
return;
}
if (end_lnum < start_lnum || end_lnum > buf->b_ml.ml_line_count)
{
EMSGN(_(e_invalid_lnum), (long)end_lnum);
return;
}
// Fetch the line to get the ml_line_len field updated.
proplen = get_text_props(buf, lnum, &props, TRUE);
textlen = buf->b_ml.ml_line_len - proplen * sizeof(textprop_T);
if (col >= (colnr_T)textlen - 1)
for (lnum = start_lnum; lnum <= end_lnum; ++lnum)
{
EMSGN(_(e_invalid_col), (long)col);
return;
colnr_T col; // start column
long length; // in bytes
// Fetch the line to get the ml_line_len field updated.
proplen = get_text_props(buf, lnum, &props, TRUE);
textlen = buf->b_ml.ml_line_len - proplen * sizeof(textprop_T);
if (lnum == start_lnum)
col = start_col;
else
col = 1;
if (col - 1 > (colnr_T)textlen)
{
EMSGN(_(e_invalid_col), (long)start_col);
return;
}
if (lnum == end_lnum)
length = end_col - col + 1;
else
length = textlen - col + 1;
if (length > (long)textlen)
length = textlen; // can include the end-of-line
if (length < 1)
length = 1;
// Allocate the new line with space for the new proprety.
newtext = alloc(buf->b_ml.ml_line_len + sizeof(textprop_T));
if (newtext == NULL)
return;
// Copy the text, including terminating NUL.
mch_memmove(newtext, buf->b_ml.ml_line_ptr, textlen);
// Find the index where to insert the new property.
// Since the text properties are not aligned properly when stored with the
// text, we need to copy them as bytes before using it as a struct.
for (i = 0; i < proplen; ++i)
{
mch_memmove(&tmp_prop, props + i * sizeof(textprop_T),
sizeof(textprop_T));
if (tmp_prop.tp_col >= col)
break;
}
newprops = newtext + textlen;
if (i > 0)
mch_memmove(newprops, props, sizeof(textprop_T) * i);
tmp_prop.tp_col = col;
tmp_prop.tp_len = length;
tmp_prop.tp_id = id;
tmp_prop.tp_type = type->pt_id;
tmp_prop.tp_flags = (lnum > start_lnum ? TP_FLAG_CONT_PREV : 0)
| (lnum < end_lnum ? TP_FLAG_CONT_NEXT : 0);
mch_memmove(newprops + i * sizeof(textprop_T), &tmp_prop,
sizeof(textprop_T));
if (i < proplen)
mch_memmove(newprops + (i + 1) * sizeof(textprop_T),
props + i * sizeof(textprop_T),
sizeof(textprop_T) * (proplen - i));
if (buf->b_ml.ml_flags & ML_LINE_DIRTY)
vim_free(buf->b_ml.ml_line_ptr);
buf->b_ml.ml_line_ptr = newtext;
buf->b_ml.ml_line_len += sizeof(textprop_T);
buf->b_ml.ml_flags |= ML_LINE_DIRTY;
}
// Allocate the new line with space for the new proprety.
newtext = alloc(buf->b_ml.ml_line_len + sizeof(textprop_T));
if (newtext == NULL)
return;
// Copy the text, including terminating NUL.
mch_memmove(newtext, buf->b_ml.ml_line_ptr, textlen);
// Find the index where to insert the new property.
// Since the text properties are not aligned properly when stored with the
// text, we need to copy them as bytes before using it as a struct.
for (i = 0; i < proplen; ++i)
{
mch_memmove(&tmp_prop, props + i * sizeof(textprop_T),
sizeof(textprop_T));
if (tmp_prop.tp_col >= col)
break;
}
newprops = newtext + textlen;
if (i > 0)
mch_memmove(newprops, props, sizeof(textprop_T) * i);
tmp_prop.tp_col = col;
tmp_prop.tp_len = length;
tmp_prop.tp_id = id;
tmp_prop.tp_type = type->pt_id;
tmp_prop.tp_flags = 0;
mch_memmove(newprops + i * sizeof(textprop_T), &tmp_prop,
sizeof(textprop_T));
if (i < proplen)
mch_memmove(newprops + (i + 1) * sizeof(textprop_T),
props + i * sizeof(textprop_T),
sizeof(textprop_T) * (proplen - i));
if (buf->b_ml.ml_flags & ML_LINE_DIRTY)
vim_free(buf->b_ml.ml_line_ptr);
buf->b_ml.ml_line_ptr = newtext;
buf->b_ml.ml_line_len += sizeof(textprop_T);
buf->b_ml.ml_flags |= ML_LINE_DIRTY;
buf->b_has_textprop = TRUE; // this is never reset
redraw_buf_later(buf, NOT_VALID);
}
/*
* Return TRUE if any text properties are defined globally or for buffer
* "buf".
*/
int
has_any_text_properties(buf_T *buf)
{
return buf->b_proptypes != NULL || global_proptypes != NULL;
}
/*
* Fetch the text properties for line "lnum" in buffer "buf".
* Returns the number of text properties and, when non-zero, a pointer to the
@@ -286,8 +329,9 @@ get_text_props(buf_T *buf, linenr_T lnum, char_u **props, int will_change)
size_t textlen;
size_t proplen;
// Be quick when no text property types are defined.
if (!has_any_text_properties(buf))
// Be quick when no text property types have been defined or the buffer,
// unless we are adding one.
if (!buf->b_has_textprop && !will_change)
return 0;
// Fetch the line to get the ml_line_len field updated.
+42
View File
@@ -814,6 +814,48 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
639,
/**/
638,
/**/
637,
/**/
636,
/**/
635,
/**/
634,
/**/
633,
/**/
632,
/**/
631,
/**/
630,
/**/
629,
/**/
628,
/**/
627,
/**/
626,
/**/
625,
/**/
624,
/**/
623,
/**/
622,
/**/
621,
/**/
620,
/**/
619,
/**/
618,
/**/
+31 -36
View File
@@ -836,8 +836,7 @@ win_split_ins(
frp = frp->fr_parent)
{
if (frp->fr_layout == FR_ROW)
for (frp2 = frp->fr_child; frp2 != NULL;
frp2 = frp2->fr_next)
FOR_ALL_FRAMES(frp2, frp->fr_child)
if (frp2 != prevfrp)
minwidth += frame_minwidth(frp2, NOWIN);
prevfrp = frp;
@@ -920,8 +919,7 @@ win_split_ins(
frp = frp->fr_parent)
{
if (frp->fr_layout == FR_COL)
for (frp2 = frp->fr_child; frp2 != NULL;
frp2 = frp2->fr_next)
FOR_ALL_FRAMES(frp2, frp->fr_child)
if (frp2 != prevfrp)
minheight += frame_minheight(frp2, NOWIN);
prevfrp = frp;
@@ -1078,7 +1076,7 @@ win_split_ins(
if (frp->fr_win != NULL)
oldwin->w_frame = frp;
else
for (frp = frp->fr_child; frp != NULL; frp = frp->fr_next)
FOR_ALL_FRAMES(frp, frp->fr_child)
frp->fr_parent = curfrp;
}
@@ -1610,8 +1608,7 @@ win_rotate(int upwards, int count)
#endif
/* Check if all frames in this row/col have one window. */
for (frp = curwin->w_frame->fr_parent->fr_child; frp != NULL;
frp = frp->fr_next)
FOR_ALL_FRAMES(frp, curwin->w_frame->fr_parent->fr_child)
if (frp->fr_win == NULL)
{
EMSG(_("E443: Cannot rotate when another window is split"));
@@ -1861,7 +1858,7 @@ win_equal_rec(
else
{
next_curwin_size = -1;
for (fr = topfr->fr_child; fr != NULL; fr = fr->fr_next)
FOR_ALL_FRAMES(fr, topfr->fr_child)
{
/* If 'winfixwidth' set keep the window width if
* possible.
@@ -1914,7 +1911,7 @@ win_equal_rec(
--totwincount; /* don't count curwin */
}
for (fr = topfr->fr_child; fr != NULL; fr = fr->fr_next)
FOR_ALL_FRAMES(fr, topfr->fr_child)
{
wincount = 1;
if (fr->fr_next == NULL)
@@ -2002,7 +1999,7 @@ win_equal_rec(
else
{
next_curwin_size = -1;
for (fr = topfr->fr_child; fr != NULL; fr = fr->fr_next)
FOR_ALL_FRAMES(fr, topfr->fr_child)
{
/* If 'winfixheight' set keep the window height if
* possible.
@@ -2055,7 +2052,7 @@ win_equal_rec(
--totwincount; /* don't count curwin */
}
for (fr = topfr->fr_child; fr != NULL; fr = fr->fr_next)
FOR_ALL_FRAMES(fr, topfr->fr_child)
{
wincount = 1;
if (fr->fr_next == NULL)
@@ -2756,7 +2753,7 @@ winframe_remove(
* and remove it. */
frp2->fr_parent->fr_layout = frp2->fr_layout;
frp2->fr_parent->fr_child = frp2->fr_child;
for (frp = frp2->fr_child; frp != NULL; frp = frp->fr_next)
FOR_ALL_FRAMES(frp, frp2->fr_child)
frp->fr_parent = frp2->fr_parent;
frp2->fr_parent->fr_win = frp2->fr_win;
if (frp2->fr_win != NULL)
@@ -2888,7 +2885,7 @@ frame_has_win(frame_T *frp, win_T *wp)
if (frp->fr_layout == FR_LEAF)
return frp->fr_win == wp;
for (p = frp->fr_child; p != NULL; p = p->fr_next)
FOR_ALL_FRAMES(p, frp->fr_child)
if (frame_has_win(p, wp))
return TRUE;
return FALSE;
@@ -2922,7 +2919,7 @@ frame_new_height(
do
{
/* All frames in this row get the same new height. */
for (frp = topfrp->fr_child; frp != NULL; frp = frp->fr_next)
FOR_ALL_FRAMES(frp, topfrp->fr_child)
{
frame_new_height(frp, height, topfirst, wfh);
if (frp->fr_height > height)
@@ -3019,7 +3016,7 @@ frame_fixed_height(frame_T *frp)
{
/* The frame is fixed height if one of the frames in the row is fixed
* height. */
for (frp = frp->fr_child; frp != NULL; frp = frp->fr_next)
FOR_ALL_FRAMES(frp, frp->fr_child)
if (frame_fixed_height(frp))
return TRUE;
return FALSE;
@@ -3027,7 +3024,7 @@ frame_fixed_height(frame_T *frp)
/* frp->fr_layout == FR_COL: The frame is fixed height if all of the
* frames in the row are fixed height. */
for (frp = frp->fr_child; frp != NULL; frp = frp->fr_next)
FOR_ALL_FRAMES(frp, frp->fr_child)
if (!frame_fixed_height(frp))
return FALSE;
return TRUE;
@@ -3048,7 +3045,7 @@ frame_fixed_width(frame_T *frp)
{
/* The frame is fixed width if one of the frames in the row is fixed
* width. */
for (frp = frp->fr_child; frp != NULL; frp = frp->fr_next)
FOR_ALL_FRAMES(frp, frp->fr_child)
if (frame_fixed_width(frp))
return TRUE;
return FALSE;
@@ -3056,7 +3053,7 @@ frame_fixed_width(frame_T *frp)
/* frp->fr_layout == FR_ROW: The frame is fixed width if all of the
* frames in the row are fixed width. */
for (frp = frp->fr_child; frp != NULL; frp = frp->fr_next)
FOR_ALL_FRAMES(frp, frp->fr_child)
if (!frame_fixed_width(frp))
return FALSE;
return TRUE;
@@ -3084,7 +3081,7 @@ frame_add_statusline(frame_T *frp)
else if (frp->fr_layout == FR_ROW)
{
/* Handle all the frames in the row. */
for (frp = frp->fr_child; frp != NULL; frp = frp->fr_next)
FOR_ALL_FRAMES(frp, frp->fr_child)
frame_add_statusline(frp);
}
else /* frp->fr_layout == FR_COL */
@@ -3130,7 +3127,7 @@ frame_new_width(
do
{
/* All frames in this column get the same new width. */
for (frp = topfrp->fr_child; frp != NULL; frp = frp->fr_next)
FOR_ALL_FRAMES(frp, topfrp->fr_child)
{
frame_new_width(frp, width, leftfirst, wfw);
if (frp->fr_width > width)
@@ -3233,7 +3230,7 @@ frame_add_vsep(frame_T *frp)
else if (frp->fr_layout == FR_COL)
{
/* Handle all the frames in the column. */
for (frp = frp->fr_child; frp != NULL; frp = frp->fr_next)
FOR_ALL_FRAMES(frp, frp->fr_child)
frame_add_vsep(frp);
}
else /* frp->fr_layout == FR_ROW */
@@ -3300,7 +3297,7 @@ frame_minheight(frame_T *topfrp, win_T *next_curwin)
{
/* get the minimal height from each frame in this row */
m = 0;
for (frp = topfrp->fr_child; frp != NULL; frp = frp->fr_next)
FOR_ALL_FRAMES(frp, topfrp->fr_child)
{
n = frame_minheight(frp, next_curwin);
if (n > m)
@@ -3311,7 +3308,7 @@ frame_minheight(frame_T *topfrp, win_T *next_curwin)
{
/* Add up the minimal heights for all frames in this column. */
m = 0;
for (frp = topfrp->fr_child; frp != NULL; frp = frp->fr_next)
FOR_ALL_FRAMES(frp, topfrp->fr_child)
m += frame_minheight(frp, next_curwin);
}
@@ -3349,7 +3346,7 @@ frame_minwidth(
{
/* get the minimal width from each frame in this column */
m = 0;
for (frp = topfrp->fr_child; frp != NULL; frp = frp->fr_next)
FOR_ALL_FRAMES(frp, topfrp->fr_child)
{
n = frame_minwidth(frp, next_curwin);
if (n > m)
@@ -3360,7 +3357,7 @@ frame_minwidth(
{
/* Add up the minimal widths for all frames in this row. */
m = 0;
for (frp = topfrp->fr_child; frp != NULL; frp = frp->fr_next)
FOR_ALL_FRAMES(frp, topfrp->fr_child)
m += frame_minwidth(frp, next_curwin);
}
@@ -5028,7 +5025,7 @@ frame_comp_pos(frame_T *topfrp, int *row, int *col)
{
startrow = *row;
startcol = *col;
for (frp = topfrp->fr_child; frp != NULL; frp = frp->fr_next)
FOR_ALL_FRAMES(frp, topfrp->fr_child)
{
if (topfrp->fr_layout == FR_ROW)
*row = startrow; /* all frames are at the same row */
@@ -5148,8 +5145,7 @@ frame_setheight(frame_T *curfrp, int height)
{
room = 0;
room_reserved = 0;
for (frp = curfrp->fr_parent->fr_child; frp != NULL;
frp = frp->fr_next)
FOR_ALL_FRAMES(frp, curfrp->fr_parent->fr_child)
{
if (frp != curfrp
&& frp->fr_win != NULL
@@ -5342,8 +5338,7 @@ frame_setwidth(frame_T *curfrp, int width)
{
room = 0;
room_reserved = 0;
for (frp = curfrp->fr_parent->fr_child; frp != NULL;
frp = frp->fr_next)
FOR_ALL_FRAMES(frp, curfrp->fr_parent->fr_child)
{
if (frp != curfrp
&& frp->fr_win != NULL
@@ -5567,7 +5562,7 @@ win_drag_status_line(win_T *dragwin, int offset)
if (room < 0)
room = 0;
/* sum up the room of frames below of the current one */
for (fr = curfr->fr_next; fr != NULL; fr = fr->fr_next)
FOR_ALL_FRAMES(fr, curfr->fr_next)
room += fr->fr_height - frame_minheight(fr, NULL);
fr = curfr; /* put fr at window that grows */
}
@@ -5681,7 +5676,7 @@ win_drag_vsep_line(win_T *dragwin, int offset)
left = FALSE;
/* sum up the room of frames right of the current one */
room = 0;
for (fr = curfr->fr_next; fr != NULL; fr = fr->fr_next)
FOR_ALL_FRAMES(fr, curfr->fr_next)
room += fr->fr_width - frame_minwidth(fr, NULL);
fr = curfr; /* put fr at window that grows */
}
@@ -6086,7 +6081,7 @@ last_status_rec(frame_T *fr, int statusline)
else if (fr->fr_layout == FR_ROW)
{
/* vertically split windows, set status line for each one */
for (fp = fr->fr_child; fp != NULL; fp = fp->fr_next)
FOR_ALL_FRAMES(fp, fr->fr_child)
last_status_rec(fp, statusline);
}
else
@@ -6764,7 +6759,7 @@ win_hasvertsplit(void)
return TRUE;
if (topframe->fr_layout == FR_COL)
for (fr = topframe->fr_child; fr != NULL; fr = fr->fr_next)
FOR_ALL_FRAMES(fr, topframe->fr_child)
if (fr->fr_layout == FR_ROW)
return TRUE;
@@ -7110,7 +7105,7 @@ frame_check_height(frame_T *topfrp, int height)
return FALSE;
if (topfrp->fr_layout == FR_ROW)
for (frp = topfrp->fr_child; frp != NULL; frp = frp->fr_next)
FOR_ALL_FRAMES(frp, topfrp->fr_child)
if (frp->fr_height != height)
return FALSE;
@@ -7129,7 +7124,7 @@ frame_check_width(frame_T *topfrp, int width)
return FALSE;
if (topfrp->fr_layout == FR_COL)
for (frp = topfrp->fr_child; frp != NULL; frp = frp->fr_next)
FOR_ALL_FRAMES(frp, topfrp->fr_child)
if (frp->fr_width != width)
return FALSE;