Compare commits

...

17 Commits

Author SHA1 Message Date
DungSaga
47810464aa patch 8.2.3552: xxd revert does not handle end of line correctly
Problem:    Xxd revert does not handle end of line correctly.
Solution:   Check for newline first. (closes #9034)
2021-10-22 12:55:42 +01:00
itchyny
94e7d345c1 patch 8.2.3551: checking first character of url twice
Problem:    Checking first character of url twice.
Solution:   Only check once. (closes #9026)
2021-10-21 18:01:13 +01:00
Shougo Matsushita
ae38a9db77 patch 8.2.3550: completion() does not work properly
Problem:    completion() does not work properly.
Solution:   Set xp_line and add WILD_HOME_REPLACE. (Shougo Matsushita,
            closes #9016)
2021-10-21 11:39:53 +01:00
zeertzjq
b811de5d49 patch 8.2.3549: mistakes in test comments
Problem:    Mistakes in test comments.
Solution:   Fix the comments. (closes #9029)
2021-10-21 10:50:44 +01:00
Bram Moolenaar
d68a004485 patch 8.2.3548: GTK GUI crashen when reading from stdin
Problem:    GTK GUI crashen when reading from stdin.
Solution:   Do not overwrite the NUL after the string. (closes #9028)
2021-10-20 23:08:11 +01:00
Bram Moolenaar
1d30fde3c9 patch 8.2.3547: opening the quickfix window triggers BufWinEnter twice
Problem:    Opening the quickfix window triggers BufWinEnter twice. (Yorick
            Peterse)
Solution:   Only trigger BufWinEnter with "quickfix". (closes #9022)
2021-10-20 21:58:42 +01:00
zeertzjq
09f7723d5a patch 8.2.3546: build failure without the +eval feature
Problem:    Build failure without the +eval feature.
Solution:   Add #ifdef. (closes #9025)
2021-10-20 17:21:24 +01:00
zeertzjq
94358a1e6e patch 8.2.3545: setcellwidths() may make 'listchars' or 'fillchars' invalid
Problem:    setcellwidths() may make 'listchars' or 'fillchars' invalid.
Solution:   Check the value and give an error. (closes #9024)
2021-10-20 11:01:15 +01:00
itchyny
051a40c8d9 patch 8.2.3544: Unix: may leak file descriptor using non-existing directory
Problem:    Unix: may leak file descriptor when using a non-existing
            directory.
Solution:   Always close the file. (closes #9023)
2021-10-20 10:00:05 +01:00
Bram Moolenaar
8b0e62c93b patch 8.2.3543: swapname has double slash when 'directory' ends in it
Problem:    Swapname has double slash when 'directory' ends in double slash.
            (Shane Smith)
Solution:   Remove the superfluous slash. (closes #8876)
2021-10-19 22:12:25 +01:00
Bram Moolenaar
c5935a859e patch 8.2.3542: too many comments are old style
Problem:    Too many comments are old style.
Solution:   Change comments to // style. (closes #9021)
2021-10-19 20:48:52 +01:00
Bram Moolenaar
731fba1081 patch 8.2.3541: compiler warning for unused variable in tiny version
Problem:    Compiler warning for unused variable in tiny version.
Solution:   Add #ifdef. (John Marriott)
2021-10-19 20:24:34 +01:00
Bram Moolenaar
f47ebf1e1a patch 8.2.3540: the mark '] is wrong after put with a count
Problem:    The mark '] is wrong after put with a count. (Naohiro Ono)
Solution:   Use the right line number. (closes #8956)
2021-10-19 20:08:45 +01:00
Bram Moolenaar
604e207e27 patch 8.2.3539: GTK3: with 'rightleft' set scrollbar may move unintentionally
Problem:    GTK3: with 'rightleft' set scrollbar may move unintentionally.
Solution:   Ignore events while moving the scrollbar thumb. (closes #8958)
2021-10-19 14:22:03 +01:00
Yegappan Lakshmanan
d43d8e28db patch 8.2.3538: else-if indenting is confusing
Problem:    Else-if indenting is confusing.
Solution:   Add curly brackets. (Yegappan Lakshmanan, closes #9017)
2021-10-19 13:44:52 +01:00
naohiro ono
75c30e96cf patch 8.2.3537: mode() does not return the right value in 'operatorfunc'
Problem:    mode() does not return the right value in 'operatorfunc'.
Solution:   Reset finish_op while calling 'operatorfunc'.
2021-10-19 11:15:41 +01:00
Yegappan Lakshmanan
ad6b90c33c patch 8.2.3536: the do_highlight() function is way too long
Problem:    The do_highlight() function is way too long.
Solution:   Split it into several functions. (Yegappan Lakshmanan,
            closes #9011)
2021-10-18 22:13:57 +01:00
28 changed files with 1300 additions and 957 deletions

View File

@@ -9648,6 +9648,9 @@ setcellwidths({list}) *setcellwidths()*
range overlaps with another.
Only characters with value 0x100 and higher can be used.
If the new value causes 'fillchars' or 'listchars' to become
invalid it is rejected and an error is given.
To clear the overrides pass an empty list: >
setcellwidths([]);
< You can use the script $VIMRUNTIME/tools/emoji_list.vim to see

View File

@@ -94,11 +94,9 @@ read_buffer(
int retval = OK;
linenr_T line_count;
/*
* Read from the buffer which the text is already filled in and append at
* the end. This makes it possible to retry when 'fileformat' or
* 'fileencoding' was guessed wrong.
*/
// Read from the buffer which the text is already filled in and append at
// the end. This makes it possible to retry when 'fileformat' or
// 'fileencoding' was guessed wrong.
line_count = curbuf->b_ml.ml_line_count;
retval = readfile(
read_stdin ? NULL : curbuf->b_ffname,
@@ -178,29 +176,23 @@ open_buffer(
#endif
int read_fifo = FALSE;
/*
* The 'readonly' flag is only set when BF_NEVERLOADED is being reset.
* When re-entering the same buffer, it should not change, because the
* user may have reset the flag by hand.
*/
// The 'readonly' flag is only set when BF_NEVERLOADED is being reset.
// When re-entering the same buffer, it should not change, because the
// user may have reset the flag by hand.
if (readonlymode && curbuf->b_ffname != NULL
&& (curbuf->b_flags & BF_NEVERLOADED))
curbuf->b_p_ro = TRUE;
if (ml_open(curbuf) == FAIL)
{
/*
* There MUST be a memfile, otherwise we can't do anything
* If we can't create one for the current buffer, take another buffer
*/
// There MUST be a memfile, otherwise we can't do anything
// If we can't create one for the current buffer, take another buffer
close_buffer(NULL, curbuf, 0, FALSE, FALSE);
FOR_ALL_BUFFERS(curbuf)
if (curbuf->b_ml.ml_mfp != NULL)
break;
/*
* If there is no memfile at all, exit.
* This is OK, since there are no changes to lose.
*/
// If there is no memfile at all, exit.
// This is OK, since there are no changes to lose.
if (curbuf == NULL)
{
emsg(_("E82: Cannot allocate any buffer, exiting..."));
@@ -281,12 +273,10 @@ open_buffer(
{
int save_bin = curbuf->b_p_bin;
/*
* First read the text in binary mode into the buffer.
* Then read from that same buffer and append at the end. This makes
* it possible to retry when 'fileformat' or 'fileencoding' was
* guessed wrong.
*/
// First read the text in binary mode into the buffer.
// Then read from that same buffer and append at the end. This makes
// it possible to retry when 'fileformat' or 'fileencoding' was
// guessed wrong.
curbuf->b_p_bin = TRUE;
retval = readfile(NULL, NULL, (linenr_T)0,
(linenr_T)0, (linenr_T)MAXLNUM, NULL,
@@ -305,11 +295,10 @@ open_buffer(
#endif
}
/*
* Set/reset the Changed flag first, autocmds may change the buffer.
* Apply the automatic commands, before processing the modelines.
* So the modelines have priority over autocommands.
*/
// Set/reset the Changed flag first, autocmds may change the buffer.
// Apply the automatic commands, before processing the modelines.
// So the modelines have priority over autocommands.
//
// When reading stdin, the buffer contents always needs writing, so set
// the changed flag. Unless in readonly mode: "ls | gview -".
// When interrupted and 'cpoptions' contains 'i' set changed flag.
@@ -360,10 +349,8 @@ open_buffer(
if (retval == OK)
{
/*
* The autocommands may have changed the current buffer. Apply the
* modelines to the correct buffer, if it still exists and is loaded.
*/
// The autocommands may have changed the current buffer. Apply the
// modelines to the correct buffer, if it still exists and is loaded.
if (bufref_valid(&old_curbuf) && old_curbuf.br_buf->b_ml.ml_mfp != NULL)
{
aco_save_T aco;
@@ -373,11 +360,12 @@ open_buffer(
do_modelines(0);
curbuf->b_flags &= ~(BF_CHECK_RO | BF_NEVERLOADED);
if ((flags & READ_NOWINENTER) == 0)
#ifdef FEAT_EVAL
apply_autocmds_retval(EVENT_BUFWINENTER, NULL, NULL, FALSE, curbuf,
&retval);
apply_autocmds_retval(EVENT_BUFWINENTER, NULL, NULL, FALSE,
curbuf, &retval);
#else
apply_autocmds(EVENT_BUFWINENTER, NULL, NULL, FALSE, curbuf);
apply_autocmds(EVENT_BUFWINENTER, NULL, NULL, FALSE, curbuf);
#endif
// restore curwin/curbuf and a few other things
@@ -521,11 +509,10 @@ close_buffer(
int del_buf = (action == DOBUF_DEL || wipe_buf);
CHECK_CURBUF;
/*
* Force unloading or deleting when 'bufhidden' says so.
* The caller must take care of NOT deleting/freeing when 'bufhidden' is
* "hide" (otherwise we could never free or delete a buffer).
*/
// Force unloading or deleting when 'bufhidden' says so.
// The caller must take care of NOT deleting/freeing when 'bufhidden' is
// "hide" (otherwise we could never free or delete a buffer).
if (buf->b_p_bh[0] == 'd') // 'bufhidden' == "delete"
{
del_buf = TRUE;
@@ -681,10 +668,9 @@ aucmd_abort:
)
end_visual_mode();
/*
* Free all things allocated for this buffer.
* Also calls the "BufDelete" autocommands when del_buf is TRUE.
*/
// Free all things allocated for this buffer.
// Also calls the "BufDelete" autocommands when del_buf is TRUE.
//
// Remember if we are closing the current buffer. Restore the number of
// windows, so that autocommands in buf_freeall() don't get confused.
is_curbuf = (buf == curbuf);
@@ -703,13 +689,11 @@ aucmd_abort:
return FALSE;
#endif
/*
* It's possible that autocommands change curbuf to the one being deleted.
* This might cause the previous curbuf to be deleted unexpectedly. But
* in some cases it's OK to delete the curbuf, because a new one is
* obtained anyway. Therefore only return if curbuf changed to the
* deleted buffer.
*/
// It's possible that autocommands change curbuf to the one being deleted.
// This might cause the previous curbuf to be deleted unexpectedly. But
// in some cases it's OK to delete the curbuf, because a new one is
// obtained anyway. Therefore only return if curbuf changed to the
// deleted buffer.
if (buf == curbuf && !is_curbuf)
return FALSE;
@@ -856,12 +840,10 @@ buf_freeall(buf_T *buf, int flags)
return;
#endif
/*
* It's possible that autocommands change curbuf to the one being deleted.
* This might cause curbuf to be deleted unexpectedly. But in some cases
* it's OK to delete the curbuf, because a new one is obtained anyway.
* Therefore only return if curbuf changed to the deleted buffer.
*/
// It's possible that autocommands change curbuf to the one being deleted.
// This might cause curbuf to be deleted unexpectedly. But in some cases
// it's OK to delete the curbuf, because a new one is obtained anyway.
// Therefore only return if curbuf changed to the deleted buffer.
if (buf == curbuf && !is_curbuf)
return;
#ifdef FEAT_DIFF
@@ -1215,11 +1197,9 @@ empty_curbuf(
retval = do_ecmd(0, NULL, NULL, NULL, ECMD_ONE,
forceit ? ECMD_FORCEIT : 0, curwin);
/*
* do_ecmd() may create a new buffer, then we have to delete
* the old one. But do_ecmd() may have done that already, check
* if the buffer still exists.
*/
// do_ecmd() may create a new buffer, then we have to delete
// the old one. But do_ecmd() may have done that already, check
// if the buffer still exists.
if (buf != curbuf && bufref_valid(&bufref) && buf->b_nwindows == 0)
close_buffer(NULL, buf, action, FALSE, FALSE);
if (!close_others)
@@ -1350,7 +1330,7 @@ do_buffer_ext(
#endif
/*
* delete buffer buf from memory and/or the list
* delete buffer "buf" from memory and/or the list
*/
if (unload)
{
@@ -1396,21 +1376,17 @@ do_buffer_ext(
if (buf == curbuf && VIsual_active)
end_visual_mode();
/*
* If deleting the last (listed) buffer, make it empty.
* The last (listed) buffer cannot be unloaded.
*/
// If deleting the last (listed) buffer, make it empty.
// The last (listed) buffer cannot be unloaded.
FOR_ALL_BUFFERS(bp)
if (bp->b_p_bl && bp != buf)
break;
if (bp == NULL && buf == curbuf)
return empty_curbuf(TRUE, (flags & DOBUF_FORCEIT), action);
/*
* If the deleted buffer is the current one, close the current window
* (unless it's the only window). Repeat this so long as we end up in
* a window with this buffer.
*/
// If the deleted buffer is the current one, close the current window
// (unless it's the only window). Repeat this so long as we end up in
// a window with this buffer.
while (buf == curbuf
&& !(curwin->w_closing || curwin->w_buffer->b_locked > 0)
&& (!ONE_WINDOW || first_tabpage->tp_next != NULL))
@@ -1419,9 +1395,7 @@ do_buffer_ext(
break;
}
/*
* If the buffer to be deleted is not the current one, delete it here.
*/
// If the buffer to be deleted is not the current one, delete it here.
if (buf != curbuf)
{
close_windows(buf, FALSE);
@@ -1535,7 +1509,7 @@ do_buffer_ext(
}
/*
* make buf current buffer
* make "buf" the current buffer
*/
if (action == DOBUF_SPLIT) // split window first
{
@@ -1555,9 +1529,7 @@ do_buffer_ext(
if (buf == curbuf)
return OK;
/*
* Check if the current buffer may be abandoned.
*/
// Check if the current buffer may be abandoned.
if (action == DOBUF_GOTO && !can_abandon(curbuf, (flags & DOBUF_FORCEIT)))
{
#if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
@@ -1650,21 +1622,17 @@ do_bufdel(
for ( ;!got_int; ui_breakcheck())
{
/*
* Delete the current buffer last, otherwise when the
* current buffer is deleted, the next buffer becomes
* the current one and will be loaded, which may then
* also be deleted, etc.
*/
// Delete the current buffer last, otherwise when the
// current buffer is deleted, the next buffer becomes
// the current one and will be loaded, which may then
// also be deleted, etc.
if (bnr == curbuf->b_fnum)
do_current = bnr;
else if (do_buffer_ext(command, DOBUF_FIRST, FORWARD, (int)bnr,
DOBUF_NOPOPUP | (forceit ? DOBUF_FORCEIT : 0)) == OK)
++deleted;
/*
* find next buffer number to delete/unload
*/
// find next buffer number to delete/unload
if (addr_count == 2)
{
if (++bnr > end_bnr)
@@ -2011,7 +1979,7 @@ buflist_new(
fname_expand(curbuf, &ffname, &sfname); // will allocate ffname
/*
* If file name already exists in the list, update the entry.
* If the file name already exists in the list, update the entry.
*/
#ifdef UNIX
// On Unix we can use inode numbers when the file exists. Works better
@@ -2152,9 +2120,7 @@ buflist_new(
}
else
{
/*
* put new buffer at the end of the buffer list
*/
// put the new buffer at the end of the buffer list
buf->b_next = NULL;
if (firstbuf == NULL) // buffer list is empty
{
@@ -2209,9 +2175,7 @@ buflist_new(
}
buf_hashtab_add(buf);
/*
* Always copy the options from the current buffer.
*/
// Always copy the options from the current buffer.
buf_copy_options(buf, BCO_ALWAYS);
}
@@ -2759,10 +2723,8 @@ ExpandBufnames(
else
patc = pat;
/*
* attempt == 0: try match with '\<', match at start of word
* attempt == 1: try match without '\<', match anywhere
*/
// attempt == 0: try match with '\<', match at start of word
// attempt == 1: try match without '\<', match anywhere
for (attempt = 0; attempt <= 1; ++attempt)
{
regmatch_T regmatch;
@@ -2777,10 +2739,8 @@ ExpandBufnames(
return FAIL;
}
/*
* round == 1: Count the matches.
* round == 2: Build the array to keep the matches.
*/
// round == 1: Count the matches.
// round == 2: Build the array to keep the matches.
for (round = 1; round <= 2; ++round)
{
count = 0;
@@ -3383,7 +3343,7 @@ setfname(
return FAIL;
/*
* if the file name is already used in another buffer:
* If the file name is already used in another buffer:
* - if the buffer is loaded, fail
* - if the buffer is not loaded, delete it from the list
*/

View File

@@ -978,6 +978,7 @@ set_one_cmd_context(
ExpandInit(xp);
xp->xp_pattern = buff;
xp->xp_line = buff;
xp->xp_context = EXPAND_COMMANDS; // Default until we get past command
ea.argt = 0;
@@ -2891,7 +2892,7 @@ f_getcompletion(typval_T *argvars, typval_T *rettv)
expand_T xpc;
int filtered = FALSE;
int options = WILD_SILENT | WILD_USE_NL | WILD_ADD_SLASH
| WILD_NO_BEEP;
| WILD_NO_BEEP | WILD_HOME_REPLACE;
if (in_vim9script()
&& (check_for_string_arg(argvars, 0) == FAIL

View File

@@ -160,6 +160,12 @@ EXTERN char e_list_value_does_not_have_enough_items[]
INIT(= N_("E711: List value does not have enough items"));
EXTERN char e_cannot_slice_dictionary[]
INIT(= N_("E719: Cannot slice a Dictionary"));
#endif
EXTERN char e_conflicts_with_value_of_listchars[]
INIT(= N_("E834: Conflicts with value of 'listchars'"));
EXTERN char e_conflicts_with_value_of_fillchars[]
INIT(= N_("E835: Conflicts with value of 'fillchars'"));
#ifdef FEAT_EVAL
EXTERN char e_assert_fails_second_arg[]
INIT(= N_("E856: \"assert_fails()\" second argument must be a string or a list with one or two strings"));
EXTERN char e_using_invalid_value_as_string_str[]

View File

@@ -2473,6 +2473,7 @@ theend:
* ECMD_FORCEIT: ! used for Ex command
* ECMD_ADDBUF: don't edit, just add to buffer list
* ECMD_ALTBUF: like ECMD_ADDBUF and also set the alternate file
* ECMD_NOWINENTER: Do not trigger BufWinEnter
* oldwin: Should be "curwin" when editing a new buffer in the current
* window, NULL when splitting the window first. When not NULL info
* of the previous buffer for "oldwin" is stored.
@@ -3030,6 +3031,8 @@ do_ecmd(
/*
* Open the buffer and read the file.
*/
if (flags & ECMD_NOWINENTER)
readfile_flags |= READ_NOWINENTER;
#if defined(FEAT_EVAL)
if (should_abort(open_buffer(FALSE, eap, readfile_flags)))
retval = FAIL;
@@ -3051,10 +3054,11 @@ do_ecmd(
// changed by the user.
do_modelines(OPT_WINONLY);
apply_autocmds_retval(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf,
&retval);
apply_autocmds_retval(EVENT_BUFWINENTER, NULL, NULL, FALSE, curbuf,
&retval);
apply_autocmds_retval(EVENT_BUFENTER, NULL, NULL, FALSE,
curbuf, &retval);
if ((flags & ECMD_NOWINENTER) == 0)
apply_autocmds_retval(EVENT_BUFWINENTER, NULL, NULL, FALSE,
curbuf, &retval);
}
check_arg_idx(curwin);

View File

@@ -1011,6 +1011,9 @@ gui_mch_set_scrollbar_thumb(scrollbar_T *sb, long val, long size, long max)
{
GtkAdjustment *adjustment;
// ignore events triggered by moving the thumb (happens in GTK 3)
++hold_gui_events;
adjustment = gtk_range_get_adjustment(GTK_RANGE(sb->id));
gtk_adjustment_set_lower(adjustment, 0.0);
@@ -1023,6 +1026,8 @@ gui_mch_set_scrollbar_thumb(scrollbar_T *sb, long val, long size, long max)
g_signal_handler_block(G_OBJECT(adjustment), (gulong)sb->handler_id);
--hold_gui_events;
#if !GTK_CHECK_VERSION(3,18,0)
gtk_adjustment_changed(adjustment);
#endif

View File

@@ -5744,12 +5744,16 @@ gui_gtk2_draw_string(int row, int col, char_u *s, int len, int flags)
}
}
// temporarily zero terminate substring, print, restore char, wrap
backup_ch = *(cs + slen);
*(cs + slen) = 0;
if (slen < len)
{
// temporarily zero terminate substring, print, restore char, wrap
backup_ch = *(cs + slen);
*(cs + slen) = NUL;
}
len_sum += gui_gtk2_draw_string_ext(row, col + len_sum,
cs, slen, flags, needs_pango);
*(cs + slen) = backup_ch;
if (slen < len)
*(cs + slen) = backup_ch;
cs += slen;
byte_sum += slen;
needs_pango = should_need_pango;

File diff suppressed because it is too large Load Diff

View File

@@ -5510,6 +5510,8 @@ f_setcellwidths(typval_T *argvars, typval_T *rettv UNUSED)
int i;
listitem_T **ptrs;
cw_interval_T *table;
cw_interval_T *cw_table_save;
size_t cw_table_size_save;
if (in_vim9script() && check_for_list_arg(argvars, 0) == FAIL)
return;
@@ -5620,9 +5622,41 @@ f_setcellwidths(typval_T *argvars, typval_T *rettv UNUSED)
}
vim_free(ptrs);
vim_free(cw_table);
cw_table_save = cw_table;
cw_table_size_save = cw_table_size;
cw_table = table;
cw_table_size = l->lv_len;
// Check that the new value does not conflict with 'fillchars' or
// 'listchars'.
if (set_chars_option(curwin, &p_fcs) != NULL)
{
emsg(_(e_conflicts_with_value_of_fillchars));
cw_table = cw_table_save;
cw_table_size = cw_table_size_save;
vim_free(table);
return;
}
else
{
tabpage_T *tp;
win_T *wp;
FOR_ALL_TAB_WINDOWS(tp, wp)
{
if (set_chars_option(wp, &wp->w_p_lcs) != NULL)
{
emsg((e_conflicts_with_value_of_listchars));
cw_table = cw_table_save;
cw_table_size = cw_table_size_save;
vim_free(table);
return;
}
}
}
vim_free(cw_table_save);
}
void

View File

@@ -2064,7 +2064,9 @@ recover_names(
/*
* Need _very_ long file names.
* Append the full path to name with path separators made into percent
* signs, to dir. An unnamed buffer is handled as "" (<currentdir>/"")
* signs, to "dir". An unnamed buffer is handled as "" (<currentdir>/"")
* The last character in "dir" must be an extra slash or backslash, it is
* removed.
*/
char_u *
make_percent_swname(char_u *dir, char_u *name)
@@ -2081,6 +2083,8 @@ make_percent_swname(char_u *dir, char_u *name)
for (d = s; *d != NUL; MB_PTR_ADV(d))
if (vim_ispathsep(*d))
*d = '%';
dir[STRLEN(dir) - 1] = NUL; // remove one trailing slash
d = concat_fnames(dir, s, TRUE);
vim_free(s);
}

View File

@@ -2643,7 +2643,7 @@ path_with_url(char_u *fname)
return 0;
// check body: alpha or dash
for (p = fname; (isalpha(*p) || (*p == '-')); ++p)
for (p = fname + 1; (isalpha(*p) || (*p == '-')); ++p)
;
// check last char is not a dash

View File

@@ -3314,6 +3314,7 @@ op_function(oparg_T *oap UNUSED)
#ifdef FEAT_EVAL
typval_T argv[2];
int save_virtual_op = virtual_op;
int save_finish_op = finish_op;
pos_T orig_start = curbuf->b_op_start;
pos_T orig_end = curbuf->b_op_end;
@@ -3341,9 +3342,13 @@ op_function(oparg_T *oap UNUSED)
// function.
virtual_op = MAYBE;
// Reset finish_op so that mode() returns the right value.
finish_op = FALSE;
(void)call_func_noret(p_opfunc, 1, argv);
virtual_op = save_virtual_op;
finish_op = save_finish_op;
if (cmdmod.cmod_flags & CMOD_LOCKMARKS)
{
curbuf->b_op_start = orig_start;

View File

@@ -871,7 +871,7 @@ did_set_string_option(
if (check_opt_strings(p_ambw, p_ambw_values, FALSE) != OK)
errmsg = e_invarg;
else if (set_chars_option(curwin, &p_fcs) != NULL)
errmsg = _("E835: Conflicts with value of 'fillchars'");
errmsg = _(e_conflicts_with_value_of_fillchars);
else
{
tabpage_T *tp;
@@ -881,7 +881,7 @@ did_set_string_option(
{
if (set_chars_option(wp, &wp->w_p_lcs) != NULL)
{
errmsg = _("E834: Conflicts with value of 'listchars'");
errmsg = _(e_conflicts_with_value_of_listchars);
goto ambw_end;
}
}

View File

@@ -2681,7 +2681,6 @@ mch_FullName(
verbose_leave();
}
l = fchdir(fd);
close(fd);
}
else
#endif
@@ -2689,6 +2688,10 @@ mch_FullName(
if (l != 0)
emsg(_(e_prev_dir));
}
#ifdef HAVE_FCHDIR
if (fd >= 0)
close(fd);
#endif
l = STRLEN(buf);
if (l >= len - 1)

View File

@@ -4199,13 +4199,14 @@ qf_open_new_cwindow(qf_info_T *qi, int height)
{
// Use the existing quickfix buffer
if (do_ecmd(qf_buf->b_fnum, NULL, NULL, NULL, ECMD_ONE,
ECMD_HIDE + ECMD_OLDBUF, oldwin) == FAIL)
ECMD_HIDE + ECMD_OLDBUF + ECMD_NOWINENTER, oldwin) == FAIL)
return FAIL;
}
else
{
// Create a new quickfix buffer
if (do_ecmd(0, NULL, NULL, NULL, ECMD_ONE, ECMD_HIDE, oldwin) == FAIL)
if (do_ecmd(0, NULL, NULL, NULL, ECMD_ONE, ECMD_HIDE + ECMD_NOWINENTER,
oldwin) == FAIL)
return FAIL;
// save the number of the new buffer

View File

@@ -2183,7 +2183,7 @@ error:
curbuf->b_op_start.lnum, nr_lines);
// put '] mark at last inserted character
curbuf->b_op_end.lnum = lnum;
curbuf->b_op_end.lnum = new_lnum;
// correct length for change in indent
col = (colnr_T)STRLEN(y_array[y_size - 1]) - lendiff;
if (col > 1)

View File

@@ -760,33 +760,33 @@ func Test_OptionSet()
call assert_equal(g:opt[0], g:opt[1])
" 19a: Setting string local-global (to buffer) option"
" 19a: Setting string global-local (to buffer) option"
let oldval = &tags
let g:options = [['tags', oldval, oldval, oldval, 'tagpath', 'global', 'set']]
set tags=tagpath
call assert_equal([], g:options)
call assert_equal(g:opt[0], g:opt[1])
" 19b: Resetting string local-global (to buffer) option"
" 19b: Resetting string global-local (to buffer) option"
let g:options = [['tags', 'tagpath', 'tagpath', 'tagpath', oldval, 'global', 'set']]
set tags&
call assert_equal([], g:options)
call assert_equal(g:opt[0], g:opt[1])
" 19c: Setting global string local-global (to buffer) option "
" 19c: Setting global string global-local (to buffer) option "
let g:options = [['tags', oldval, '', oldval, 'tagpath1', 'global', 'setglobal']]
setglobal tags=tagpath1
call assert_equal([], g:options)
call assert_equal(g:opt[0], g:opt[1])
" 19d: Setting local string local-global (to buffer) option"
" 19d: Setting local string global-local (to buffer) option"
let g:options = [['tags', 'tagpath1', 'tagpath1', '', 'tagpath2', 'local', 'setlocal']]
setlocal tags=tagpath2
call assert_equal([], g:options)
call assert_equal(g:opt[0], g:opt[1])
" 19e: Setting again string local-global (to buffer) option"
" Note: v:option_old is the old global value for local-global string options
" 19e: Setting again string global-local (to buffer) option"
" Note: v:option_old is the old global value for global-local string options
" but the old local value for all other kinds of options.
noa setglobal tags=tag_global " Reset global and local value (without triggering autocmd)
noa setlocal tags=tag_local
@@ -795,8 +795,8 @@ func Test_OptionSet()
call assert_equal([], g:options)
call assert_equal(g:opt[0], g:opt[1])
" 19f: Setting string local-global (to buffer) option to an empty string"
" Note: v:option_old is the old global value for local-global string options
" 19f: Setting string global-local (to buffer) option to an empty string"
" Note: v:option_old is the old global value for global-local string options
" but the old local value for all other kinds of options.
noa set tags=tag_global " Reset global and local value (without triggering autocmd)
noa setlocal tags= " empty string
@@ -833,7 +833,7 @@ func Test_OptionSet()
call assert_equal(g:opt[0], g:opt[1])
" 20e: Setting again string local (to buffer) option"
" Note: v:option_old is the old global value for local-global string options
" Note: v:option_old is the old global value for global-local string options
" but the old local value for all other kinds of options.
noa setglobal spelllang=spellglobal " Reset global and local value (without triggering autocmd)
noa setlocal spelllang=spelllocal
@@ -843,36 +843,36 @@ func Test_OptionSet()
call assert_equal(g:opt[0], g:opt[1])
" 21a: Setting string local-global (to window) option"
" 21a: Setting string global-local (to window) option"
let oldval = &statusline
let g:options = [['statusline', oldval, oldval, oldval, 'foo', 'global', 'set']]
set statusline=foo
call assert_equal([], g:options)
call assert_equal(g:opt[0], g:opt[1])
" 21b: Resetting string local-global (to window) option"
" Note: v:option_old is the old global value for local-global string options
" 21b: Resetting string global-local (to window) option"
" Note: v:option_old is the old global value for global-local string options
" but the old local value for all other kinds of options.
let g:options = [['statusline', 'foo', 'foo', 'foo', oldval, 'global', 'set']]
set statusline&
call assert_equal([], g:options)
call assert_equal(g:opt[0], g:opt[1])
" 21c: Setting global string local-global (to window) option"
" 21c: Setting global string global-local (to window) option"
let g:options = [['statusline', oldval, '', oldval, 'bar', 'global', 'setglobal']]
setglobal statusline=bar
call assert_equal([], g:options)
call assert_equal(g:opt[0], g:opt[1])
" 21d: Setting local string local-global (to window) option"
" 21d: Setting local string global-local (to window) option"
noa set statusline& " Reset global and local value (without triggering autocmd)
let g:options = [['statusline', oldval, oldval, '', 'baz', 'local', 'setlocal']]
setlocal statusline=baz
call assert_equal([], g:options)
call assert_equal(g:opt[0], g:opt[1])
" 21e: Setting again string local-global (to window) option"
" Note: v:option_old is the old global value for local-global string options
" 21e: Setting again string global-local (to window) option"
" Note: v:option_old is the old global value for global-local string options
" but the old local value for all other kinds of options.
noa setglobal statusline=bar " Reset global and local value (without triggering autocmd)
noa setlocal statusline=baz
@@ -917,7 +917,7 @@ func Test_OptionSet()
call assert_equal(g:opt[0], g:opt[1])
" 23a: Setting global number local option"
" 23a: Setting global number global option"
noa setglobal cmdheight=8 " Reset global and local value (without triggering autocmd)
noa setlocal cmdheight=1 " Sets the global(!) value!
let g:options = [['cmdheight', '1', '', '1', '2', 'global', 'setglobal']]
@@ -1041,7 +1041,7 @@ func Test_OptionSet()
call assert_equal([], g:options)
call assert_equal(g:opt[0], g:opt[1])
" 27d: Ssettin again global number local (to window) option"
" 27d: Setting again global number local (to window) option"
noa set foldcolumn=8 " Reset global and local value (without triggering autocmd)
let g:options = [['foldcolumn', '8', '8', '8', '2', 'global', 'set']]
set foldcolumn=2

View File

@@ -305,6 +305,11 @@ func Test_getcompletion()
let l = getcompletion('NoMatch', 'dir')
call assert_equal([], l)
if glob('~/*') !=# ''
let l = getcompletion('~/', 'dir')
call assert_true(l[0][0] ==# '~')
endif
let l = getcompletion('exe', 'expression')
call assert_true(index(l, 'executable(') >= 0)
let l = getcompletion('kill', 'expression')
@@ -418,6 +423,16 @@ func Test_getcompletion()
let l = getcompletion('call paint', 'cmdline')
call assert_equal([], l)
func T(a, c, p)
return "oneA\noneB\noneC"
endfunc
command -nargs=1 -complete=custom,T MyCmd
let l = getcompletion('MyCmd ', 'cmdline')
call assert_equal(['oneA', 'oneB', 'oneC'], l)
delcommand MyCmd
delfunc T
" For others test if the name is recognized.
let names = ['buffer', 'environment', 'file_in_path', 'mapping', 'tag', 'tag_listfiles', 'user']
if has('cmdline_hist')

View File

@@ -912,6 +912,20 @@ func Test_mode()
call assert_equal('c-ce', g:current_modes)
" How to test Ex mode?
" Test mode in operatorfunc (it used to be Operator-pending).
set operatorfunc=OperatorFunc
function OperatorFunc(_)
call Save_mode()
endfunction
execute "normal! g@l\<Esc>"
call assert_equal('n-n', g:current_modes)
execute "normal! i\<C-o>g@l\<Esc>"
call assert_equal('n-niI', g:current_modes)
execute "normal! R\<C-o>g@l\<Esc>"
call assert_equal('n-niR', g:current_modes)
execute "normal! gR\<C-o>g@l\<Esc>"
call assert_equal('n-niV', g:current_modes)
if has('terminal')
term
call feedkeys("\<C-W>N", 'xt')
@@ -924,6 +938,8 @@ func Test_mode()
iunmap <F2>
xunmap <F2>
set complete&
set operatorfunc&
delfunction OperatorFunc
endfunc
" Test for append()

View File

@@ -145,6 +145,28 @@ func Test_quoteplus()
let @+ = quoteplus_saved
endfunc
func Test_gui_read_stdin()
CheckUnix
call writefile(['some', 'lines'], 'Xstdin')
let script =<< trim END
call writefile(getline(1, '$'), 'XstdinOK')
qa!
END
call writefile(script, 'Xscript')
" Cannot use --not-a-term here, the "reading from stdin" message would not be
" displayed.
let vimcmd = substitute(GetVimCommand(), '--not-a-term', '', '')
call system('cat Xstdin | ' .. vimcmd .. ' -f -g -S Xscript -')
call assert_equal(['some', 'lines'], readfile('XstdinOK'))
call delete('Xstdin')
call delete('XstdinOK')
call delete('Xscript')
endfunc
func Test_set_background()
let background_saved = &background

View File

@@ -136,6 +136,18 @@ func Test_gp_with_count_leaves_cursor_at_end()
bwipe!
endfunc
func Test_p_with_count_leaves_mark_at_end()
new
call setline(1, '<---->')
call setreg('@', "start\nend", 'c')
normal 1G3|3p
call assert_equal([0, 1, 4, 0], getpos("."))
call assert_equal(['<--start', 'endstart', 'endstart', 'end-->'], getline(1, '$'))
call assert_equal([0, 4, 3, 0], getpos("']"))
bwipe!
endfunc
func Test_very_large_count()
" FIXME: should actually check if sizeof(int) == sizeof(long)
CheckNotMSWindows

View File

@@ -786,6 +786,23 @@ func Test_vimgreptitle()
augroup! QfBufWinEnter
endfunc
func Test_bufwinenter_once()
augroup QfBufWinEnter
au!
au BufWinEnter * let g:got_afile ..= 'got ' .. expand('<afile>')
augroup END
let g:got_afile = ''
copen
call assert_equal('got quickfix', g:got_afile)
cclose
unlet g:got_afile
augroup QfBufWinEnter
au!
augroup END
augroup! QfBufWinEnter
endfunc
func XqfTitleTests(cchar)
call s:setup_commands(a:cchar)

View File

@@ -410,7 +410,7 @@ func Test_swap_symlink()
" Check that this also works when 'directory' ends with '//'
edit Xtestlink
call assert_match('Xtestfile\.swp$', s:swapname())
call assert_match('Xswapdir[/\\]%.*testdir%Xtestfile\.swp$', s:swapname())
bwipe!
set dir&

View File

@@ -185,6 +185,16 @@ func Test_setcellwidths()
call assert_fails('call setcellwidths([[0x111, 0x122, 1], [0x122, 0x123, 2]])', 'E1113:')
call assert_fails('call setcellwidths([[0x33, 0x44, 2]])', 'E1114:')
set listchars=tab:--\\u2192
call assert_fails('call setcellwidths([[0x2192, 0x2192, 2]])', 'E834:')
set fillchars=stl:\\u2501
call assert_fails('call setcellwidths([[0x2501, 0x2501, 2]])', 'E835:')
set listchars&
set fillchars&
call setcellwidths([])
endfunc
func Test_print_overlong()

View File

@@ -213,6 +213,39 @@ func Test_xxd()
call delete('XXDfile')
endfunc
func Test_xxd_patch()
let cmd = 'silent !' .. s:xxd_cmd .. ' -r Xxxdin Xxxdfile; ' .. s:xxd_cmd .. ' -g1 Xxxdfile > Xxxdout'
call writefile(["2: 41 41", "8: 42 42"], 'Xxxdin')
call writefile(['::::::::'], 'Xxxdfile')
exe cmd
call assert_equal(['00000000: 3a 3a 41 41 3a 3a 3a 3a 42 42 ::AA::::BB'], readfile('Xxxdout'))
call writefile(["2: 43 43 ", "8: 44 44"], 'Xxxdin')
exe cmd
call assert_equal(['00000000: 3a 3a 43 43 3a 3a 3a 3a 44 44 ::CC::::DD'], readfile('Xxxdout'))
call writefile(["2: 45 45 ", "8: 46 46"], 'Xxxdin')
exe cmd
call assert_equal(['00000000: 3a 3a 45 45 3a 3a 3a 3a 46 46 ::EE::::FF'], readfile('Xxxdout'))
call writefile(["2: 41 41", "08: 42 42"], 'Xxxdin')
call writefile(['::::::::'], 'Xxxdfile')
exe cmd
call assert_equal(['00000000: 3a 3a 41 41 3a 3a 3a 3a 42 42 ::AA::::BB'], readfile('Xxxdout'))
call writefile(["2: 43 43 ", "09: 44 44"], 'Xxxdin')
exe cmd
call assert_equal(['00000000: 3a 3a 43 43 3a 3a 3a 3a 42 44 44 ::CC::::BDD'], readfile('Xxxdout'))
call writefile(["2: 45 45 ", "0a: 46 46"], 'Xxxdin')
exe cmd
call assert_equal(['00000000: 3a 3a 45 45 3a 3a 3a 3a 42 44 46 46 ::EE::::BDFF'], readfile('Xxxdout'))
call delete('Xxxdin')
call delete('Xxxdfile')
call delete('Xxxdout')
endfunc
" Various ways with wrong arguments that trigger the usage output.
func Test_xxd_usage()
for arg in ['-c', '-g', '-o', '-s', '-l', '-X', 'one two three']

View File

@@ -757,6 +757,40 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
3552,
/**/
3551,
/**/
3550,
/**/
3549,
/**/
3548,
/**/
3547,
/**/
3546,
/**/
3545,
/**/
3544,
/**/
3543,
/**/
3542,
/**/
3541,
/**/
3540,
/**/
3539,
/**/
3538,
/**/
3537,
/**/
3536,
/**/
3535,
/**/

View File

@@ -977,6 +977,7 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring);
#define READ_DUMMY 0x10 // reading into a dummy buffer
#define READ_KEEP_UNDO 0x20 // keep undo info
#define READ_FIFO 0x40 // read from fifo or socket
#define READ_NOWINENTER 0x80 // do not trigger BufWinEnter
// Values for change_indent()
#define INDENT_SET 1 // set indent
@@ -1043,6 +1044,7 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring);
#define ECMD_FORCEIT 0x08 // ! used in Ex command
#define ECMD_ADDBUF 0x10 // don't edit, just add to buffer list
#define ECMD_ALTBUF 0x20 // like ECMD_ADDBUF and set the alternate file
#define ECMD_NOWINENTER 0x40 // do not trigger BufWinEnter
// for lnum argument in do_ecmd()
#define ECMD_LASTL (linenr_T)0 // use last position in loaded file

View File

@@ -131,7 +131,7 @@ extern void perror __P((char *));
extern long int strtol();
extern long int ftell();
char version[] = "xxd 2020-02-04 by Juergen Weigert et al.";
char version[] = "xxd 2021-10-22 by Juergen Weigert et al.";
#ifdef WIN32
char osver[] = " (Win32)";
#else
@@ -318,8 +318,7 @@ huntype(
if (fflush(fpo) != 0)
die(3);
#ifdef TRY_SEEK
c = fseek(fpo, base_off + want_off - have_off, 1);
if (c >= 0)
if (fseek(fpo, base_off + want_off - have_off, 1) >= 0)
have_off = base_off + want_off;
#endif
if (base_off + want_off < have_off)
@@ -349,12 +348,16 @@ huntype(
if (n1 < 0 && n2 < 0 && n3 < 0)
{
/* already stumbled into garbage, skip line, wait and see */
if (!hextype)
want_off = 0;
while ((c = getc(fpi)) != '\n' && c != EOF)
;
while (c != '\n' && c != EOF)
c = getc(fpi);
if (c == EOF && ferror(fpi))
die(2);
}
if (c == '\n')
{
if (!hextype)
want_off = 0;
p = cols;
ign_garb = 1;
}
}