Compare commits

...

8 Commits

Author SHA1 Message Date
Bram Moolenaar
c8970b9464 patch 8.2.1908: Lua is initialized even when not used
Problem:    Lua is initialized even when not used.
Solution:   Put lua_init() after check for "eap->skip". (Christian Brabandt,
            closes #7191).  Avoid compiler warnings.
2020-10-26 20:18:08 +01:00
Bram Moolenaar
f9d51354de patch 8.2.1907: complete_info().selected may be wrong
Problem:    Complete_info().selected may be wrong.
Solution:   Update cp_number if it was never set. (issue #6945)
2020-10-26 19:22:42 +01:00
Bram Moolenaar
a360dbe3b6 patch 8.2.1906: warning for signed/unsigned
Problem:    Warning for signed/unsigned.
Solution:   Use size_t instead of int. (Mike Williams)
2020-10-26 18:46:53 +01:00
Bram Moolenaar
4882d98339 patch 8.2.1905: the wininfo list may contain stale entries
Problem:    The wininfo list may contain stale entries.
Solution:   When closing a window remove any other entry where the window
            pointer is NULL.
2020-10-25 17:55:09 +01:00
Bram Moolenaar
89b693e562 patch 8.2.1904: still using default option values after using ":badd +1"
Problem:    Still using default option values after using ":badd +1".
Solution:   Find a window where options were set.  Don't set the window when
            using ":badd".
2020-10-25 17:09:50 +01:00
Bram Moolenaar
37e4e03c67 patch 8.2.1903: buffer test fails with normal features
Problem:    Buffer test fails with normal features.
Solution:   Use 'numberwidth' instead of 'conceallevel' in the test.
2020-10-25 16:18:26 +01:00
Bram Moolenaar
e974fa7b2b patch 8.2.1902: default option values changed with :badd for existing buffer
Problem:    Default option values are changed when using :badd for an existing
            buffer.
Solution:   When calling buflist_new() pass a zero line number. (closes #7195)
2020-10-25 15:02:51 +01:00
Bram Moolenaar
4ff2f2fb6b patch 8.2.1901: variable completion does not work in command line window
Problem:    Variable completion does not work in command line window.
Solution:   Use the "prevwin". (closes #7198)
2020-10-25 13:22:42 +01:00
15 changed files with 210 additions and 83 deletions

View File

@@ -1005,6 +1005,22 @@ free_buffer_stuff(
VIM_CLEAR(buf->b_start_fenc);
}
/*
* Free one wininfo_T.
*/
void
free_wininfo(wininfo_T *wip)
{
if (wip->wi_optset)
{
clear_winopt(&wip->wi_opt);
#ifdef FEAT_FOLDING
deleteFoldRecurse(&wip->wi_folds);
#endif
}
vim_free(wip);
}
/*
* Free the b_wininfo list for buffer "buf".
*/
@@ -1017,14 +1033,7 @@ clear_wininfo(buf_T *buf)
{
wip = buf->b_wininfo;
buf->b_wininfo = wip->wi_next;
if (wip->wi_optset)
{
clear_winopt(&wip->wi_opt);
#ifdef FEAT_FOLDING
deleteFoldRecurse(&wip->wi_folds);
#endif
}
vim_free(wip);
free_wininfo(wip);
}
}
@@ -1974,7 +1983,8 @@ buflist_new(
{
vim_free(ffname);
if (lnum != 0)
buflist_setfpos(buf, curwin, lnum, (colnr_T)0, FALSE);
buflist_setfpos(buf, (flags & BLN_NOCURWIN) ? NULL : curwin,
lnum, (colnr_T)0, FALSE);
if ((flags & BLN_NOOPT) == 0)
// copy the options now, if 'cpo' doesn't have 's' and not done
@@ -2908,7 +2918,7 @@ buflist_nr2name(
void
buflist_setfpos(
buf_T *buf,
win_T *win,
win_T *win, // may be NULL when using :badd
linenr_T lnum,
colnr_T col,
int copy_options)
@@ -2950,7 +2960,7 @@ buflist_setfpos(
wip->wi_fpos.lnum = lnum;
wip->wi_fpos.col = col;
}
if (copy_options)
if (copy_options && win != NULL)
{
// Save the window-specific option values.
copy_winopt(&win->w_onebuf_opt, &wip->wi_opt);
@@ -2997,6 +3007,7 @@ wininfo_other_tab_diff(wininfo_T *wip)
/*
* Find info for the current window in buffer "buf".
* If not found, return the info for the most recently used window.
* When "need_options" is TRUE skip entries where wi_optset is FALSE.
* When "skip_diff_buffer" is TRUE avoid windows with 'diff' set that is in
* another tab page.
* Returns NULL when there isn't any info.
@@ -3004,6 +3015,7 @@ wininfo_other_tab_diff(wininfo_T *wip)
static wininfo_T *
find_wininfo(
buf_T *buf,
int need_options,
int skip_diff_buffer UNUSED)
{
wininfo_T *wip;
@@ -3013,18 +3025,25 @@ find_wininfo(
#ifdef FEAT_DIFF
&& (!skip_diff_buffer || !wininfo_other_tab_diff(wip))
#endif
)
&& (!need_options || wip->wi_optset))
break;
// If no wininfo for curwin, use the first in the list (that doesn't have
// 'diff' set and is in another tab page).
// If "need_options" is TRUE skip entries that don't have options set,
// unless the window is editing "buf", so we can copy from the window
// itself.
if (wip == NULL)
{
#ifdef FEAT_DIFF
if (skip_diff_buffer)
{
FOR_ALL_BUF_WININFO(buf, wip)
if (!wininfo_other_tab_diff(wip))
if (!wininfo_other_tab_diff(wip)
&& (!need_options || wip->wi_optset
|| (wip->wi_win != NULL
&& wip->wi_win->w_buffer == buf)))
break;
}
else
@@ -3050,7 +3069,7 @@ get_winopts(buf_T *buf)
clearFolding(curwin);
#endif
wip = find_wininfo(buf, TRUE);
wip = find_wininfo(buf, TRUE, TRUE);
if (wip != NULL && wip->wi_win != NULL
&& wip->wi_win != curwin && wip->wi_win->w_buffer == buf)
{
@@ -3097,7 +3116,7 @@ buflist_findfpos(buf_T *buf)
wininfo_T *wip;
static pos_T no_position = {1, 0, 0};
wip = find_wininfo(buf, FALSE);
wip = find_wininfo(buf, FALSE, FALSE);
if (wip != NULL)
return &(wip->wi_fpos);
else

View File

@@ -1981,7 +1981,13 @@ get_user_var_name(expand_T *xp, int idx)
}
// b: variables
ht = &curbuf->b_vars->dv_hashtab;
ht =
#ifdef FEAT_CMDWIN
// In cmdwin, the alternative buffer should be used.
(cmdwin_type != 0 && get_cmdline_type() == NUL) ?
&prevwin->w_buffer->b_vars->dv_hashtab :
#endif
&curbuf->b_vars->dv_hashtab;
if (bdone < ht->ht_used)
{
if (bdone++ == 0)
@@ -1994,7 +2000,13 @@ get_user_var_name(expand_T *xp, int idx)
}
// w: variables
ht = &curwin->w_vars->dv_hashtab;
ht =
#ifdef FEAT_CMDWIN
// In cmdwin, the alternative window should be used.
(cmdwin_type != 0 && get_cmdline_type() == NUL) ?
&prevwin->w_vars->dv_hashtab :
#endif
&curwin->w_vars->dv_hashtab;
if (wdone < ht->ht_used)
{
if (wdone++ == 0)

View File

@@ -2630,7 +2630,9 @@ do_ecmd(
{
if (flags & ECMD_ADDBUF)
{
linenr_T tlnum = 1L;
// Default the line number to zero to avoid that a wininfo item
// is added for the current window.
linenr_T tlnum = 0;
if (command != NULL)
{
@@ -2638,7 +2640,10 @@ do_ecmd(
if (tlnum <= 0)
tlnum = 1L;
}
(void)buflist_new(ffname, sfname, tlnum, BLN_LISTED);
// Add BLN_NOCURWIN to avoid a new wininfo items is assocated
// with the current window.
(void)buflist_new(ffname, sfname, tlnum,
BLN_LISTED | BLN_NOCURWIN);
goto theend;
}
buf = buflist_new(ffname, sfname, 0L,

View File

@@ -33,7 +33,7 @@ typedef struct {
char_u *name; // funcref
dict_T *self; // selfdict
} luaV_Funcref;
typedef void (*msgfunc_T)(char_u *);
typedef int (*msgfunc_T)(char *);
typedef struct {
int lua_funcref; // ref to a lua func
@@ -788,11 +788,11 @@ luaV_msgfunc(lua_State *L, msgfunc_T mf)
{
if (*p++ == '\0') // break?
{
mf((char_u *) s);
mf((char *)s);
s = p;
}
}
mf((char_u *) s);
mf((char *)s);
lua_pop(L, 2); // original and modified strings
}
@@ -2372,18 +2372,19 @@ lua_end(void)
void
ex_lua(exarg_T *eap)
{
char *script;
if (lua_init() == FAIL) return;
script = (char *) script_get(eap, eap->arg);
if (!eap->skip)
char *script = (char *)script_get(eap, eap->arg);
if (!eap->skip && lua_init() == OK)
{
char *s = (script) ? script : (char *) eap->arg;
char *s = script != NULL ? script : (char *)eap->arg;
luaV_setrange(L, eap->line1, eap->line2);
if (luaL_loadbuffer(L, s, strlen(s), LUAVIM_CHUNKNAME)
|| lua_pcall(L, 0, 0, 0))
luaV_emsg(L);
}
if (script != NULL) vim_free(script);
if (script != NULL)
vim_free(script);
}
void

View File

@@ -2498,6 +2498,56 @@ ins_compl_mode(void)
return (char_u *)"";
}
static void
ins_compl_update_sequence_numbers()
{
int number = 0;
compl_T *match;
if (compl_direction == FORWARD)
{
// search backwards for the first valid (!= -1) number.
// This should normally succeed already at the first loop
// cycle, so it's fast!
for (match = compl_curr_match->cp_prev; match != NULL
&& match != compl_first_match;
match = match->cp_prev)
if (match->cp_number != -1)
{
number = match->cp_number;
break;
}
if (match != NULL)
// go up and assign all numbers which are not assigned
// yet
for (match = match->cp_next;
match != NULL && match->cp_number == -1;
match = match->cp_next)
match->cp_number = ++number;
}
else // BACKWARD
{
// search forwards (upwards) for the first valid (!= -1)
// number. This should normally succeed already at the
// first loop cycle, so it's fast!
for (match = compl_curr_match->cp_next; match != NULL
&& match != compl_first_match;
match = match->cp_next)
if (match->cp_number != -1)
{
number = match->cp_number;
break;
}
if (match != NULL)
// go down and assign all numbers which are not
// assigned yet
for (match = match->cp_prev; match
&& match->cp_number == -1;
match = match->cp_prev)
match->cp_number = ++number;
}
}
/*
* Get complete information
*/
@@ -2584,8 +2634,12 @@ get_complete_info(list_T *what_list, dict_T *retdict)
}
if (ret == OK && (what_flag & CI_WHAT_SELECTED))
ret = dict_add_number(retdict, "selected", (compl_curr_match != NULL) ?
compl_curr_match->cp_number - 1 : -1);
{
if (compl_curr_match != NULL && compl_curr_match->cp_number == -1)
ins_compl_update_sequence_numbers();
ret = dict_add_number(retdict, "selected", compl_curr_match != NULL
? compl_curr_match->cp_number - 1 : -1);
}
// TODO
// if (ret == OK && (what_flag & CI_WHAT_INSERTED))
@@ -4009,59 +4063,13 @@ ins_complete(int c, int enable_pum)
{
edit_submode_extra = (char_u *)_("The only match");
edit_submode_highl = HLF_COUNT;
compl_curr_match->cp_number = 0;
compl_curr_match->cp_number = 1;
}
else
{
// Update completion sequence number when needed.
if (compl_curr_match->cp_number == -1)
{
int number = 0;
compl_T *match;
if (compl_direction == FORWARD)
{
// search backwards for the first valid (!= -1) number.
// This should normally succeed already at the first loop
// cycle, so it's fast!
for (match = compl_curr_match->cp_prev; match != NULL
&& match != compl_first_match;
match = match->cp_prev)
if (match->cp_number != -1)
{
number = match->cp_number;
break;
}
if (match != NULL)
// go up and assign all numbers which are not assigned
// yet
for (match = match->cp_next;
match != NULL && match->cp_number == -1;
match = match->cp_next)
match->cp_number = ++number;
}
else // BACKWARD
{
// search forwards (upwards) for the first valid (!= -1)
// number. This should normally succeed already at the
// first loop cycle, so it's fast!
for (match = compl_curr_match->cp_next; match != NULL
&& match != compl_first_match;
match = match->cp_next)
if (match->cp_number != -1)
{
number = match->cp_number;
break;
}
if (match != NULL)
// go down and assign all numbers which are not
// assigned yet
for (match = match->cp_prev; match
&& match->cp_number == -1;
match = match->cp_prev)
match->cp_number = ++number;
}
}
ins_compl_update_sequence_numbers();
// The match should always have a sequence number now, this is
// just a safety check.

View File

@@ -8,6 +8,7 @@ int buf_valid(buf_T *buf);
void close_buffer(win_T *win, buf_T *buf, int action, int abort_if_last, int ignore_abort);
void buf_clear_file(buf_T *buf);
void buf_freeall(buf_T *buf, int flags);
void free_wininfo(wininfo_T *wip);
void goto_buffer(exarg_T *eap, int start, int dir, int count);
void handle_swap_exists(bufref_T *old_curbuf);
char *do_bufdel(int command, char_u *arg, int addr_count, int start_bnr, int end_bnr, int forceit);

View File

@@ -15,6 +15,6 @@ void ex_comclear(exarg_T *eap);
void uc_clear(garray_T *gap);
void ex_delcommand(exarg_T *eap);
size_t add_win_cmd_modifers(char_u *buf, cmdmod_T *cmod, int *multi_mods);
int produce_cmdmods(char_u *buf, cmdmod_T *cmod, int quote);
size_t produce_cmdmods(char_u *buf, cmdmod_T *cmod, int quote);
void do_ucmd(exarg_T *eap);
/* vim: set ft=c : */

View File

@@ -362,4 +362,16 @@ func Test_sball_with_count()
%bw!
endfunc
func Test_badd_options()
new SomeNewBuffer
setlocal numberwidth=3
wincmd p
badd +1 SomeNewBuffer
new SomeNewBuffer
call assert_equal(3, &numberwidth)
close
close
bwipe! SomeNewBuffer
endfunc
" vim: shiftwidth=2 sts=2 expandtab

View File

@@ -325,7 +325,7 @@ func Test_completefunc_info()
set completeopt=menuone
set completefunc=CompleteTest
call feedkeys("i\<C-X>\<C-U>\<C-R>\<C-R>=string(complete_info())\<CR>\<ESC>", "tx")
call assert_equal("matched{'pum_visible': 1, 'mode': 'function', 'selected': -1, 'items': [{'word': 'matched', 'menu': '', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}]}", getline(1))
call assert_equal("matched{'pum_visible': 1, 'mode': 'function', 'selected': 0, 'items': [{'word': 'matched', 'menu': '', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}]}", getline(1))
bwipe!
set completeopt&
set completefunc&
@@ -346,7 +346,10 @@ func Test_compl_in_cmdwin()
set wildmenu wildchar=<Tab>
com! -nargs=1 -complete=command GetInput let input = <q-args>
com! -buffer TestCommand echo 'TestCommand'
let w:test_winvar = 'winvar'
let b:test_bufvar = 'bufvar'
" User-defined commands
let input = ''
call feedkeys("q:iGetInput T\<C-x>\<C-v>\<CR>", 'tx!')
call assert_equal('TestCommand', input)
@@ -355,8 +358,30 @@ func Test_compl_in_cmdwin()
call feedkeys("q::GetInput T\<Tab>\<CR>:q\<CR>", 'tx!')
call assert_equal('T', input)
com! -nargs=1 -complete=var GetInput let input = <q-args>
" Window-local variables
let input = ''
call feedkeys("q:iGetInput w:test_\<C-x>\<C-v>\<CR>", 'tx!')
call assert_equal('w:test_winvar', input)
let input = ''
call feedkeys("q::GetInput w:test_\<Tab>\<CR>:q\<CR>", 'tx!')
call assert_equal('w:test_', input)
" Buffer-local variables
let input = ''
call feedkeys("q:iGetInput b:test_\<C-x>\<C-v>\<CR>", 'tx!')
call assert_equal('b:test_bufvar', input)
let input = ''
call feedkeys("q::GetInput b:test_\<Tab>\<CR>:q\<CR>", 'tx!')
call assert_equal('b:test_', input)
delcom TestCommand
delcom GetInput
unlet w:test_winvar
unlet b:test_bufvar
set wildmenu& wildchar&
endfunc

View File

@@ -1,6 +1,14 @@
" Tests for Lua.
source check.vim
" This test also works without the lua feature.
func Test_skip_lua()
if 0
lua print("Not executed")
endif
endfunc
CheckFeature lua
CheckFeature float

View File

@@ -1269,10 +1269,10 @@ add_win_cmd_modifers(char_u *buf, cmdmod_T *cmod, int *multi_mods)
* Generate text for the "cmod" command modifiers.
* If "buf" is NULL just return the length.
*/
int
size_t
produce_cmdmods(char_u *buf, cmdmod_T *cmod, int quote)
{
int result = 0;
size_t result = 0;
int multi_mods = 0;
int i;
typedef struct {

View File

@@ -750,6 +750,22 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1908,
/**/
1907,
/**/
1906,
/**/
1905,
/**/
1904,
/**/
1903,
/**/
1902,
/**/
1901,
/**/
1900,
/**/

View File

@@ -931,6 +931,7 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring);
#define BLN_NOOPT 16 // don't copy options to existing buffer
#define BLN_DUMMY_OK 32 // also find an existing dummy buffer
#define BLN_REUSE 64 // may re-use number from buf_reuse
#define BLN_NOCURWIN 128 // buffer is not associated with curwin
// Values for in_cinkeys()
#define KEY_OPEN_FORW 0x101

View File

@@ -3530,7 +3530,7 @@ ex_disassemble(exarg_T *eap)
case ISN_CMDMOD:
{
char_u *buf;
int len = produce_cmdmods(
size_t len = produce_cmdmods(
NULL, iptr->isn_arg.cmdmod.cf_cmdmod, FALSE);
buf = alloc(len + 1);

View File

@@ -5015,7 +5015,26 @@ win_free(
FOR_ALL_BUFFERS(buf)
FOR_ALL_BUF_WININFO(buf, wip)
if (wip->wi_win == wp)
{
wininfo_T *wip2;
// If there already is an entry with "wi_win" set to NULL it
// must be removed, it would never be used.
for (wip2 = buf->b_wininfo; wip2 != NULL; wip2 = wip2->wi_next)
if (wip2->wi_win == NULL)
{
if (wip2->wi_next != NULL)
wip2->wi_next->wi_prev = wip2->wi_prev;
if (wip2->wi_prev == NULL)
buf->b_wininfo = wip2->wi_next;
else
wip2->wi_prev->wi_next = wip2->wi_next;
free_wininfo(wip2);
break;
}
wip->wi_win = NULL;
}
#ifdef FEAT_SEARCH_EXTRA
clear_matches(wp);