Skip to content

Commit dff6380

Browse files
committed
Merge remote-tracking branch 'vim/master'
2 parents 4be84d7 + 66669fc commit dff6380

44 files changed

Lines changed: 1058 additions & 124 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

runtime/doc/change.txt

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1801,14 +1801,22 @@ Vim has a sorting function and a sorting command. The sorting function can be
18011801
found here: |sort()|, |uniq()|.
18021802

18031803
*:sor* *:sort*
1804-
:[range]sor[t][!] [b][f][i][n][o][r][u][x] [/{pattern}/]
1804+
:[range]sor[t][!] [b][f][i][l][n][o][r][u][x] [/{pattern}/]
18051805
Sort lines in [range]. When no range is given all
18061806
lines are sorted.
18071807

18081808
With [!] the order is reversed.
18091809

18101810
With [i] case is ignored.
18111811

1812+
With [l] sort uses the current locale. See
1813+
`language collate` to check or set the locale used
1814+
for ordering. For example, with "en_US.UTF8",
1815+
Ö will be ordered after O and before P,
1816+
whereas with the Swedish locale "sv_SE.UTF8",
1817+
it will be after Z.
1818+
Case is typically ignored by the locale.
1819+
18121820
Options [n][f][x][o][b] are mutually exclusive.
18131821

18141822
With [n] sorting is done on the first decimal number
@@ -1875,8 +1883,7 @@ found here: |sort()|, |uniq()|.
18751883
Note that using `:sort` with `:global` doesn't sort the matching lines, it's
18761884
quite useless.
18771885

1878-
The details about sorting depend on the library function used. There is no
1879-
guarantee that sorting obeys the current locale. You will have to try it out.
1886+
`:sort` does not use the current locale unless the l flag is used.
18801887
Vim does do a "stable" sort.
18811888

18821889
The sorting can be interrupted, but if you interrupt it too late in the

runtime/doc/eval.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9712,6 +9712,13 @@ sort({list} [, {func} [, {dict}]]) *sort()* *E702*
97129712
When {func} is given and it is '1' or 'i' then case is
97139713
ignored.
97149714

9715+
When {func} is given and it is 'l' then the current locale
9716+
is used for ordering. See `language collate` to check or set
9717+
the locale used for ordering. For example, with "en_US.UTF8",
9718+
Ö will be ordered after O and before P, whereas with the
9719+
Swedish locale "sv_SE.UTF8", it will be after Z.
9720+
Case is typically ignored by the locale.
9721+
97159722
When {func} is given and it is 'n' then all items will be
97169723
sorted numerical (Implementation detail: This uses the
97179724
strtod() function to parse numbers, Strings, Lists, Dicts and

runtime/doc/netbeans.txt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -562,9 +562,10 @@ setModtime time
562562
saved directly by the Vim Controller.
563563
New in version 2.3.
564564

565-
setReadOnly
566-
Set a file as readonly
567-
Implemented in version 2.3.
565+
setReadOnly readonly
566+
When the boolean argument "readonly" is "T" for True, mark the
567+
buffer as readonly, when it is "F" for False, mark it as not
568+
readonly. Implemented in version 2.3.
568569

569570
setStyle Not implemented.
570571

src/errors.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,4 +286,10 @@ EXTERN char e_cannot_add_to_null_list[]
286286
INIT(= N_("E1130: Cannot add to null list"));
287287
EXTERN char e_cannot_add_to_null_blob[]
288288
INIT(= N_("E1131: Cannot add to null blob"));
289+
EXTERN char e_missing_function_argument[]
290+
INIT(= N_("E1132: Missing function argument"));
291+
EXTERN char e_cannot_extend_null_dict[]
292+
INIT(= N_("E1133: Cannot extend a null dict"));
293+
EXTERN char e_cannot_extend_null_list[]
294+
INIT(= N_("E1134: Cannot extend a null list"));
289295
#endif

src/evalfunc.c

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,9 @@ typedef struct {
276276
// E.g. if "arg_idx" is 1, then (type - 1) is the first argument type.
277277
typedef int (*argcheck_T)(type_T *, argcontext_T *);
278278

279+
/*
280+
* Check "type" is a float or a number.
281+
*/
279282
static int
280283
arg_float_or_nr(type_T *type, argcontext_T *context)
281284
{
@@ -286,12 +289,27 @@ arg_float_or_nr(type_T *type, argcontext_T *context)
286289
return FAIL;
287290
}
288291

292+
/*
293+
* Check "type" is a number.
294+
*/
289295
static int
290296
arg_number(type_T *type, argcontext_T *context)
291297
{
292298
return check_type(&t_number, type, TRUE, context->arg_idx + 1);
293299
}
294300

301+
/*
302+
* Check "type" is a string.
303+
*/
304+
static int
305+
arg_string(type_T *type, argcontext_T *context)
306+
{
307+
return check_type(&t_string, type, TRUE, context->arg_idx + 1);
308+
}
309+
310+
/*
311+
* Check "type" is a list or a blob.
312+
*/
295313
static int
296314
arg_list_or_blob(type_T *type, argcontext_T *context)
297315
{
@@ -303,7 +321,32 @@ arg_list_or_blob(type_T *type, argcontext_T *context)
303321
}
304322

305323
/*
306-
* Check the type is an item of the list or blob of the previous arg.
324+
* Check "type" is a list or a dict.
325+
*/
326+
static int
327+
arg_list_or_dict(type_T *type, argcontext_T *context)
328+
{
329+
if (type->tt_type == VAR_ANY
330+
|| type->tt_type == VAR_LIST || type->tt_type == VAR_DICT)
331+
return OK;
332+
arg_type_mismatch(&t_list_any, type, context->arg_idx + 1);
333+
return FAIL;
334+
}
335+
336+
/*
337+
* Check "type" is the same type as the previous argument
338+
* Must not be used for the first argcheck_T entry.
339+
*/
340+
static int
341+
arg_same_as_prev(type_T *type, argcontext_T *context)
342+
{
343+
type_T *prev_type = context->arg_types[context->arg_idx - 1];
344+
345+
return check_type(prev_type, type, TRUE, context->arg_idx + 1);
346+
}
347+
348+
/*
349+
* Check "type" is an item of the list or blob of the previous arg.
307350
* Must not be used for the first argcheck_T entry.
308351
*/
309352
static int
@@ -323,10 +366,28 @@ arg_item_of_prev(type_T *type, argcontext_T *context)
323366
return check_type(expected, type, TRUE, context->arg_idx + 1);
324367
}
325368

369+
/*
370+
* Check "type" which is the third argument of extend().
371+
*/
372+
static int
373+
arg_extend3(type_T *type, argcontext_T *context)
374+
{
375+
type_T *first_type = context->arg_types[context->arg_idx - 2];
376+
377+
if (first_type->tt_type == VAR_LIST)
378+
return arg_number(type, context);
379+
if (first_type->tt_type == VAR_DICT)
380+
return arg_string(type, context);
381+
return OK;
382+
}
383+
384+
326385
/*
327386
* Lists of functions that check the argument types of a builtin function.
328387
*/
329388
argcheck_T arg1_float_or_nr[] = {arg_float_or_nr};
389+
argcheck_T arg2_listblob_item[] = {arg_list_or_blob, arg_item_of_prev};
390+
argcheck_T arg23_extend[] = {arg_list_or_dict, arg_same_as_prev, arg_extend3};
330391
argcheck_T arg3_insert[] = {arg_list_or_blob, arg_item_of_prev, arg_number};
331392

332393
/*
@@ -567,7 +628,7 @@ static funcentry_T global_functions[] =
567628
ret_any, FLOAT_FUNC(f_abs)},
568629
{"acos", 1, 1, FEARG_1, NULL,
569630
ret_float, FLOAT_FUNC(f_acos)},
570-
{"add", 2, 2, FEARG_1, NULL,
631+
{"add", 2, 2, FEARG_1, NULL /* arg2_listblob_item */,
571632
ret_first_arg, f_add},
572633
{"and", 2, 2, FEARG_1, NULL,
573634
ret_number, f_and},
@@ -793,7 +854,7 @@ static funcentry_T global_functions[] =
793854
ret_any, f_expand},
794855
{"expandcmd", 1, 1, FEARG_1, NULL,
795856
ret_string, f_expandcmd},
796-
{"extend", 2, 3, FEARG_1, NULL,
857+
{"extend", 2, 3, FEARG_1, arg23_extend,
797858
ret_first_arg, f_extend},
798859
{"feedkeys", 1, 2, FEARG_1, NULL,
799860
ret_void, f_feedkeys},

src/evalvars.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2555,7 +2555,22 @@ eval_variable(
25552555
ret = FAIL;
25562556
}
25572557
else if (rettv != NULL)
2558+
{
2559+
// If a list or dict variable wasn't initialized, do it now.
2560+
if (tv->v_type == VAR_DICT && tv->vval.v_dict == NULL)
2561+
{
2562+
tv->vval.v_dict = dict_alloc();
2563+
if (tv->vval.v_dict != NULL)
2564+
++tv->vval.v_dict->dv_refcount;
2565+
}
2566+
else if (tv->v_type == VAR_LIST && tv->vval.v_list == NULL)
2567+
{
2568+
tv->vval.v_list = list_alloc();
2569+
if (tv->vval.v_list != NULL)
2570+
++tv->vval.v_list->lv_refcount;
2571+
}
25582572
copy_tv(tv, rettv);
2573+
}
25592574
}
25602575

25612576
name[len] = cc;

src/ex_cmds.c

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ linelen(int *has_tab)
277277
static char_u *sortbuf1;
278278
static char_u *sortbuf2;
279279

280+
static int sort_lc; // sort using locale
280281
static int sort_ic; // ignore case
281282
static int sort_nr; // sort on number
282283
static int sort_rx; // sort on regex instead of skipping it
@@ -307,7 +308,13 @@ typedef struct
307308
} st_u;
308309
} sorti_T;
309310

310-
static int sort_compare(const void *s1, const void *s2);
311+
static int
312+
string_compare(const void *s1, const void *s2)
313+
{
314+
if (sort_lc)
315+
return strcoll((char *)s1, (char *)s2);
316+
return sort_ic ? STRICMP(s1, s2) : STRCMP(s1, s2);
317+
}
311318

312319
static int
313320
sort_compare(const void *s1, const void *s2)
@@ -350,8 +357,7 @@ sort_compare(const void *s1, const void *s2)
350357
l2.st_u.line.end_col_nr - l2.st_u.line.start_col_nr + 1);
351358
sortbuf2[l2.st_u.line.end_col_nr - l2.st_u.line.start_col_nr] = 0;
352359

353-
result = sort_ic ? STRICMP(sortbuf1, sortbuf2)
354-
: STRCMP(sortbuf1, sortbuf2);
360+
result = string_compare(sortbuf1, sortbuf2);
355361
}
356362

357363
// If two lines have the same value, preserve the original line order.
@@ -398,7 +404,7 @@ ex_sort(exarg_T *eap)
398404
if (nrs == NULL)
399405
goto sortend;
400406

401-
sort_abort = sort_ic = sort_rx = sort_nr = 0;
407+
sort_abort = sort_ic = sort_lc = sort_rx = sort_nr = 0;
402408
#ifdef FEAT_FLOAT
403409
sort_flt = 0;
404410
#endif
@@ -409,6 +415,8 @@ ex_sort(exarg_T *eap)
409415
;
410416
else if (*p == 'i')
411417
sort_ic = TRUE;
418+
else if (*p == 'l')
419+
sort_lc = TRUE;
412420
else if (*p == 'r')
413421
sort_rx = TRUE;
414422
else if (*p == 'n')
@@ -614,8 +622,7 @@ ex_sort(exarg_T *eap)
614622
change_occurred = TRUE;
615623

616624
s = ml_get(get_lnum);
617-
if (!unique || i == 0
618-
|| (sort_ic ? STRICMP(s, sortbuf1) : STRCMP(s, sortbuf1)) != 0)
625+
if (!unique || i == 0 || string_compare(s, sortbuf1) != 0)
619626
{
620627
// Copy the line into a buffer, it may become invalid in
621628
// ml_append(). And it's needed for "unique".
@@ -1247,6 +1254,16 @@ do_filter(
12471254
if (read_linecount >= linecount)
12481255
// move all marks from old lines to new lines
12491256
mark_adjust(line1, line2, linecount, 0L);
1257+
else if (save_cmod_flags & CMOD_LOCKMARKS)
1258+
{
1259+
// Move marks from the lines below the new lines down by
1260+
// the number of lines lost.
1261+
// Move marks from the lines that will be deleted to the
1262+
// new lines and below.
1263+
mark_adjust(line2 + 1, (linenr_T)MAXLNUM,
1264+
linecount - read_linecount, 0L);
1265+
mark_adjust(line1, line2, linecount, 0L);
1266+
}
12501267
else
12511268
{
12521269
// move marks from old lines to new lines, delete marks

src/ex_docmd.c

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1788,24 +1788,44 @@ do_one_cmd(
17881788
*/
17891789
cmd = ea.cmd;
17901790
#ifdef FEAT_EVAL
1791-
// In Vim9 script a colon is required before the range.
1792-
may_have_range = !vim9script || starts_with_colon;
1791+
// In Vim9 script a colon is required before the range. This may also be
1792+
// after command modifiers.
1793+
if (vim9script)
1794+
{
1795+
may_have_range = FALSE;
1796+
for (p = ea.cmd; p >= *cmdlinep; --p)
1797+
{
1798+
if (*p == ':')
1799+
may_have_range = TRUE;
1800+
if (p < ea.cmd && !VIM_ISWHITE(*p))
1801+
break;
1802+
}
1803+
}
1804+
else
1805+
may_have_range = TRUE;
17931806
if (may_have_range)
17941807
#endif
17951808
ea.cmd = skip_range(ea.cmd, TRUE, NULL);
17961809

17971810
#ifdef FEAT_EVAL
1798-
if (vim9script && !starts_with_colon)
1811+
if (vim9script && !may_have_range)
17991812
{
18001813
if (ea.cmd == cmd + 1 && *cmd == '$')
18011814
// should be "$VAR = val"
18021815
--ea.cmd;
1803-
else if (ea.cmd > cmd)
1816+
p = find_ex_command(&ea, NULL, lookup_scriptvar, NULL);
1817+
if (ea.cmdidx == CMD_SIZE)
18041818
{
1805-
emsg(_(e_colon_required_before_a_range));
1806-
goto doend;
1819+
char_u *ar = skip_range(ea.cmd, TRUE, NULL);
1820+
1821+
// If a ':' before the range is missing, give a clearer error
1822+
// message.
1823+
if (ar > ea.cmd)
1824+
{
1825+
emsg(_(e_colon_required_before_a_range));
1826+
goto doend;
1827+
}
18071828
}
1808-
p = find_ex_command(&ea, NULL, lookup_scriptvar, NULL);
18091829
}
18101830
else
18111831
#endif

src/fold.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -902,6 +902,8 @@ foldMoveTo(
902902
// that moves the cursor is used.
903903
lnum_off = 0;
904904
gap = &curwin->w_folds;
905+
if (gap->ga_len == 0)
906+
break;
905907
use_level = FALSE;
906908
maybe_small = FALSE;
907909
lnum_found = curwin->w_cursor.lnum;

src/getchar.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2163,7 +2163,8 @@ parse_queued_messages(void)
21632163

21642164
// Do not handle messages while redrawing, because it may cause buffers to
21652165
// change or be wiped while they are being redrawn.
2166-
if (updating_screen)
2166+
// Also bail out when parsing messages was explicitly disabled.
2167+
if (updating_screen || dont_parse_messages)
21672168
return;
21682169

21692170
// If memory allocation fails during startup we'll exit but curbuf or

0 commit comments

Comments
 (0)