diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/api/vim.c | 10 | ||||
-rw-r--r-- | src/nvim/eval.c | 2 | ||||
-rw-r--r-- | src/nvim/ex_cmds.c | 6 | ||||
-rw-r--r-- | src/nvim/if_cscope.c | 22 | ||||
-rw-r--r-- | src/nvim/message.c | 16 | ||||
-rw-r--r-- | src/nvim/ops.c | 26 | ||||
-rw-r--r-- | src/nvim/syntax.c | 46 | ||||
-rw-r--r-- | src/nvim/testdir/test_cmdline.vim | 52 | ||||
-rw-r--r-- | src/nvim/testdir/test_put.vim | 13 | ||||
-rw-r--r-- | src/nvim/testdir/test_syntax.vim | 3 | ||||
-rw-r--r-- | src/nvim/ui.c | 16 | ||||
-rw-r--r-- | src/nvim/version.c | 260 |
12 files changed, 346 insertions, 126 deletions
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 0e7cc428d4..dad67c5e4b 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -35,6 +35,7 @@ #include "nvim/os/input.h" #include "nvim/viml/parser/expressions.h" #include "nvim/viml/parser/parser.h" +#include "nvim/ui.h" #define LINE_BUFFER_SIZE 4096 @@ -1468,3 +1469,12 @@ Float nvim__id_float(Float flt) { return flt; } + +/// Gets a list of dictionaries representing attached UIs. +/// +/// @return Array of UI dictionaries +Array nvim_list_uis(void) + FUNC_API_SINCE(4) +{ + return ui_array(); +} diff --git a/src/nvim/eval.c b/src/nvim/eval.c index d69acf4eef..4140eebdf6 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -16224,7 +16224,7 @@ static void f_synIDattr(typval_T *argvars, typval_T *rettv, FunPtr fptr) break; } case 'n': { // name - p = get_highlight_name(NULL, id - 1); + p = get_highlight_name_ext(NULL, id - 1, false); break; } case 'r': { // reverse diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 48d1d42e2e..5e5d3cedfc 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -5828,7 +5828,8 @@ static void sign_list_defined(sign_T *sp) } if (sp->sn_line_hl > 0) { msg_puts(" linehl="); - const char *const p = get_highlight_name(NULL, sp->sn_line_hl - 1); + const char *const p = get_highlight_name_ext(NULL, + sp->sn_line_hl - 1, false); if (p == NULL) { msg_puts("NONE"); } else { @@ -5837,7 +5838,8 @@ static void sign_list_defined(sign_T *sp) } if (sp->sn_text_hl > 0) { msg_puts(" texthl="); - const char *const p = get_highlight_name(NULL, sp->sn_text_hl - 1); + const char *const p = get_highlight_name_ext(NULL, + sp->sn_text_hl - 1, false); if (p == NULL) { msg_puts("NONE"); } else { diff --git a/src/nvim/if_cscope.c b/src/nvim/if_cscope.c index 793142f153..b78b56562c 100644 --- a/src/nvim/if_cscope.c +++ b/src/nvim/if_cscope.c @@ -549,7 +549,7 @@ static void cs_reading_emsg( static int cs_cnt_matches(size_t idx) { char *stok; - int nlines; + int nlines = 0; char *buf = xmalloc(CSREAD_BUFSIZE); for (;; ) { @@ -569,16 +569,20 @@ static int cs_cnt_matches(size_t idx) return CSCOPE_FAILURE; } - /* - * If the database is out of date, or there's some other problem, - * cscope will output error messages before the number-of-lines output. - * Display/discard any output that doesn't match what we want. - * Accept "\S*cscope: X lines", also matches "mlcscope". - */ - if ((stok = strtok(buf, (const char *)" ")) == NULL) + // If the database is out of date, or there's some other problem, + // cscope will output error messages before the number-of-lines output. + // Display/discard any output that doesn't match what we want. + // Accept "\S*cscope: X lines", also matches "mlcscope". + // Bail out for the "Unable to search" error. + if (strstr((const char *)buf, "Unable to search database") != NULL) { + break; + } + if ((stok = strtok(buf, (const char *)" ")) == NULL) { continue; - if (strstr((const char *)stok, "cscope:") == NULL) + } + if (strstr((const char *)stok, "cscope:") == NULL) { continue; + } if ((stok = strtok(NULL, (const char *)" ")) == NULL) continue; diff --git a/src/nvim/message.c b/src/nvim/message.c index 1d9a4de9c0..e522670a65 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -1825,17 +1825,13 @@ static void msg_puts_display(const char_u *str, int maxlen, int attr, } while (msg_col & 7); } else if (*s == BELL) { // beep (from ":sh") vim_beep(BO_SH); - } else { - if (has_mbyte) { - cw = (*mb_ptr2cells)(s); - if (enc_utf8 && maxlen >= 0) - /* avoid including composing chars after the end */ - l = utfc_ptr2len_len(s, (int)((str + maxlen) - s)); - else - l = (*mb_ptr2len)(s); + } else if (*s >= 0x20) { // printable char + cw = mb_ptr2cells(s); + if (maxlen >= 0) { + // avoid including composing chars after the end + l = utfc_ptr2len_len(s, (int)((str + maxlen) - s)); } else { - cw = 1; - l = 1; + l = utfc_ptr2len(s); } // When drawing from right to left or when a double-wide character // doesn't fit, draw a single character here. Otherwise collect diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 4d974f5760..b421d81b7e 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -3078,15 +3078,26 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) --lnum; new_cursor = curwin->w_cursor; - /* - * simple case: insert into current line - */ + // simple case: insert into current line if (y_type == kMTCharWise && y_size == 1) { + linenr_T end_lnum = 0; // init for gcc + + if (VIsual_active) { + end_lnum = curbuf->b_visual.vi_end.lnum; + if (end_lnum < curbuf->b_visual.vi_start.lnum) { + end_lnum = curbuf->b_visual.vi_start.lnum; + } + } + do { totlen = (size_t)(count * yanklen); if (totlen > 0) { oldp = ml_get(lnum); - newp = (char_u *) xmalloc((size_t)(STRLEN(oldp) + totlen + 1)); + if (VIsual_active && col > (int)STRLEN(oldp)) { + lnum++; + continue; + } + newp = (char_u *)xmalloc((size_t)(STRLEN(oldp) + totlen + 1)); memmove(newp, oldp, (size_t)col); ptr = newp + col; for (i = 0; i < (size_t)count; i++) { @@ -3102,11 +3113,10 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) curwin->w_cursor.col += (colnr_T)(totlen - 1); } } - if (VIsual_active) + if (VIsual_active) { lnum++; - } while (VIsual_active - && (lnum <= curbuf->b_visual.vi_end.lnum - || lnum <= curbuf->b_visual.vi_start.lnum)); + } + } while (VIsual_active && lnum <= end_lnum); if (VIsual_active) { /* reset lnum to the last visual line */ lnum--; diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index c3bc009f6a..e2476f9b0b 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -2133,9 +2133,11 @@ syn_current_attr ( /* nextgroup ends at end of line, unless "skipnl" or "skipempty" present */ if (current_next_list != NULL - && syn_getcurline()[current_col + 1] == NUL - && !(current_next_flags & (HL_SKIPNL | HL_SKIPEMPTY))) + && (line = syn_getcurline())[current_col] != NUL + && line[current_col + 1] == NUL + && !(current_next_flags & (HL_SKIPNL | HL_SKIPEMPTY))) { current_next_list = NULL; + } if (!GA_EMPTY(&zero_width_next_ga)) ga_clear(&zero_width_next_ga); @@ -7756,14 +7758,28 @@ static void highlight_list_two(int cnt, int attr) } -/* - * Function given to ExpandGeneric() to obtain the list of group names. - * Also used for synIDattr() function. - */ -const char *get_highlight_name(expand_T *const xp, const int idx) +/// Function given to ExpandGeneric() to obtain the list of group names. +const char *get_highlight_name(expand_T *const xp, int idx) + FUNC_ATTR_WARN_UNUSED_RESULT +{ + return get_highlight_name_ext(xp, idx, true); +} + + +/// Obtain a highlight group name. +/// When "skip_cleared" is TRUE don't return a cleared entry. +const char *get_highlight_name_ext(expand_T *xp, int idx, int skip_cleared) FUNC_ATTR_WARN_UNUSED_RESULT { - // TODO(justinmk): 'xp' is unused + if (idx < 0) { + return NULL; + } + + // Items are never removed from the table, skip the ones that were cleared. + if (skip_cleared && idx < highlight_ga.ga_len && HL_TABLE()[idx].sg_cleared) { + return ""; + } + if (idx == highlight_ga.ga_len && include_none != 0) { return "none"; } else if (idx == highlight_ga.ga_len + include_none @@ -7775,20 +7791,10 @@ const char *get_highlight_name(expand_T *const xp, const int idx) } else if (idx == highlight_ga.ga_len + include_none + include_default + 1 && include_link != 0) { return "clear"; - } else if (idx < 0) { - return NULL; - } - - // Items are never removed from the table, skip the ones that were cleared. - int current_idx = idx; - while (current_idx < highlight_ga.ga_len - && HL_TABLE()[current_idx].sg_cleared) { - current_idx++; - } - if (current_idx >= highlight_ga.ga_len) { + } else if (idx >= highlight_ga.ga_len) { return NULL; } - return (const char *)HL_TABLE()[current_idx].sg_name; + return (const char *)HL_TABLE()[idx].sg_name; } color_name_table_T color_name_table[] = { diff --git a/src/nvim/testdir/test_cmdline.vim b/src/nvim/testdir/test_cmdline.vim index 1bf5930eb9..673246e1fb 100644 --- a/src/nvim/testdir/test_cmdline.vim +++ b/src/nvim/testdir/test_cmdline.vim @@ -46,8 +46,42 @@ func Test_map_completion() call assert_equal('"map <silent> <special>', getreg(':')) endfunc +func Test_match_completion() + if !has('cmdline_compl') + return + endif + hi Aardig ctermfg=green + call feedkeys(":match \<Tab>\<Home>\"\<CR>", 'xt') + call assert_equal('"match Aardig', getreg(':')) + call feedkeys(":match \<S-Tab>\<Home>\"\<CR>", 'xt') + call assert_equal('"match none', getreg(':')) +endfunc + +func Test_highlight_completion() + if !has('cmdline_compl') + return + endif + hi Aardig ctermfg=green + call feedkeys(":hi \<Tab>\<Home>\"\<CR>", 'xt') + call assert_equal('"hi Aardig', getreg(':')) + call feedkeys(":hi li\<S-Tab>\<Home>\"\<CR>", 'xt') + call assert_equal('"hi link', getreg(':')) + call feedkeys(":hi d\<S-Tab>\<Home>\"\<CR>", 'xt') + call assert_equal('"hi default', getreg(':')) + call feedkeys(":hi c\<S-Tab>\<Home>\"\<CR>", 'xt') + call assert_equal('"hi clear', getreg(':')) + + " A cleared group does not show up in completions. + hi Anders ctermfg=green + call assert_equal(['Aardig', 'Anders'], getcompletion('A', 'highlight')) + hi clear Aardig + call assert_equal(['Anders'], getcompletion('A', 'highlight')) + hi clear Anders + call assert_equal([], getcompletion('A', 'highlight')) +endfunc + func Test_expr_completion() - if !(has('cmdline_compl') && has('eval')) + if !has('cmdline_compl') return endif for cmd in [ @@ -286,17 +320,17 @@ func Test_paste_in_cmdline() endfunc func Test_remove_char_in_cmdline() - call feedkeys(":abc def\<S-Left>\<Del>\<C-B>\"\<CR>", 'tx') - call assert_equal('"abc ef', @:) + call feedkeys(":abc def\<S-Left>\<Del>\<C-B>\"\<CR>", 'tx') + call assert_equal('"abc ef', @:) - call feedkeys(":abc def\<S-Left>\<BS>\<C-B>\"\<CR>", 'tx') - call assert_equal('"abcdef', @:) + call feedkeys(":abc def\<S-Left>\<BS>\<C-B>\"\<CR>", 'tx') + call assert_equal('"abcdef', @:) - call feedkeys(":abc def ghi\<S-Left>\<C-W>\<C-B>\"\<CR>", 'tx') - call assert_equal('"abc ghi', @:) + call feedkeys(":abc def ghi\<S-Left>\<C-W>\<C-B>\"\<CR>", 'tx') + call assert_equal('"abc ghi', @:) - call feedkeys(":abc def\<S-Left>\<C-U>\<C-B>\"\<CR>", 'tx') - call assert_equal('"def', @:) + call feedkeys(":abc def\<S-Left>\<C-U>\<C-B>\"\<CR>", 'tx') + call assert_equal('"def', @:) endfunc func Test_illegal_address1() diff --git a/src/nvim/testdir/test_put.vim b/src/nvim/testdir/test_put.vim index 0154de1ec0..38c812bc9c 100644 --- a/src/nvim/testdir/test_put.vim +++ b/src/nvim/testdir/test_put.vim @@ -21,3 +21,16 @@ func Test_put_char_block() call assert_equal(['Xfile_put 1', 'Xfile_put 2'], getline(1,2)) bw! endfunc + +func Test_put_char_block2() + new + let a = [ getreg('a'), getregtype('a') ] + call setreg('a', ' one ', 'v') + call setline(1, ['Line 1', '', 'Line 3', '']) + " visually select the first 3 lines and put register a over it + exe "norm! ggl\<c-v>2j2l\"ap" + call assert_equal(['L one 1', '', 'L one 3', ''], getline(1,4)) + " clean up + bw! + call setreg('a', a[0], a[1]) +endfunc diff --git a/src/nvim/testdir/test_syntax.vim b/src/nvim/testdir/test_syntax.vim index b662279c6d..8465fe7d45 100644 --- a/src/nvim/testdir/test_syntax.vim +++ b/src/nvim/testdir/test_syntax.vim @@ -322,13 +322,16 @@ func Test_syn_clear() syntax keyword Bar tar call assert_match('Foo', execute('syntax')) call assert_match('Bar', execute('syntax')) + call assert_equal('Foo', synIDattr(hlID("Foo"), "name")) syn clear Foo call assert_notmatch('Foo', execute('syntax')) call assert_match('Bar', execute('syntax')) + call assert_equal('Foo', synIDattr(hlID("Foo"), "name")) syn clear Foo Bar call assert_notmatch('Foo', execute('syntax')) call assert_notmatch('Bar', execute('syntax')) hi clear Foo + call assert_equal('Foo', synIDattr(hlID("Foo"), "name")) hi clear Bar endfunc diff --git a/src/nvim/ui.c b/src/nvim/ui.c index f4d3cd987d..c70a02d960 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -526,3 +526,19 @@ bool ui_is_external(UIExtension widget) { return ui_ext[widget]; } + +Array ui_array(void) +{ + Array all_uis = ARRAY_DICT_INIT; + for (size_t i = 0; i < ui_count; i++) { + Dictionary dic = ARRAY_DICT_INIT; + PUT(dic, "width", INTEGER_OBJ(uis[i]->width)); + PUT(dic, "height", INTEGER_OBJ(uis[i]->height)); + PUT(dic, "rgb", BOOLEAN_OBJ(uis[i]->rgb)); + for (UIExtension j = 0; j < kUIExtCount; j++) { + PUT(dic, ui_ext_names[j], BOOLEAN_OBJ(uis[i]->ui_ext[j])); + } + ADD(all_uis, DICTIONARY_OBJ(dic)); + } + return all_uis; +} diff --git a/src/nvim/version.c b/src/nvim/version.c index 5fd94fcee8..77ae849d2e 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -78,6 +78,132 @@ NULL // clang-format off static const int included_patches[] = { + 1561, + // 1560, + // 1559, + // 1558, + // 1557, + // 1556, + // 1555, + // 1554, + // 1553, + // 1552, + // 1551, + // 1550, + // 1549, + // 1548, + // 1547, + // 1546, + // 1545, + // 1544, + // 1543, + // 1542, + // 1541, + // 1540, + // 1539, + // 1538, + // 1537, + // 1536, + // 1535, + // 1534, + // 1533, + // 1532, + // 1531, + // 1530, + // 1529, + // 1528, + // 1527, + // 1526, + // 1525, + // 1524, + // 1523, + // 1522, + // 1521, + // 1520, + // 1519, + // 1518, + // 1517, + // 1516, + // 1515, + // 1514, + // 1513, + // 1512, + // 1511, + // 1510, + // 1509, + // 1508, + // 1507, + // 1506, + // 1505, + // 1504, + // 1503, + // 1502, + // 1501, + // 1500, + // 1499, + // 1498, + // 1497, + // 1496, + // 1495, + // 1494, + 1493, + // 1492, + // 1491, + // 1490, + // 1489, + // 1488, + // 1487, + // 1486, + // 1485, + // 1484, + 1483, + // 1482, + // 1481, + // 1480, + // 1479, + // 1478, + // 1477, + // 1476, + 1475, + // 1474, + // 1473, + // 1472, + // 1471, + // 1470, + // 1469, + // 1468, + // 1467, + // 1466, + // 1465, + // 1464, + // 1463, + // 1462, + // 1461, + // 1460, + // 1459, + // 1458, + // 1457, + // 1456, + // 1455, + // 1454, + // 1453, + // 1452, + // 1451, + // 1450, + // 1449, + // 1448, + // 1447, + // 1446, + // 1445, + // 1444, + // 1443, + 1442, + // 1441, + // 1440, + 1439, + // 1438, + // 1437, + // 1436, 1435, // 1434, // 1433, @@ -110,8 +236,8 @@ static const int included_patches[] = { // 1406, // 1405, // 1404, - // 1403, - // 1402, + 1403, + 1402, // 1401, // 1400, // 1399, @@ -143,12 +269,12 @@ static const int included_patches[] = { // 1373, // 1372, // 1371, - // 1370, + 1370, // 1369, // 1368, // 1367, // 1366, - // 1365, + 1365, // 1364, // 1363, // 1362, @@ -180,11 +306,11 @@ static const int included_patches[] = { // 1336, // 1335, // 1334, - // 1333, + 1333, // 1332, // 1331, // 1330, - // 1329, + 1329, // 1328, // 1327, // 1326, @@ -211,7 +337,7 @@ static const int included_patches[] = { // 1305, 1304, // 1303, - // 1302, + 1302, // 1301, // 1300, // 1299, @@ -242,7 +368,7 @@ static const int included_patches[] = { // 1274, // 1273, // 1272, - // 1271, + 1271, // 1270, // 1269, // 1268, @@ -251,7 +377,7 @@ static const int included_patches[] = { // 1265, // 1264, // 1263, - // 1262, + 1262, // 1261, // 1260, // 1259, @@ -287,14 +413,14 @@ static const int included_patches[] = { 1229, // 1228, // 1227, - // 1226, + 1226, 1225, - // 1224, - // 1223, - // 1222, - // 1221, + 1224, + 1223, + 1222, + 1221, // 1220, - // 1219, + 1219, // 1218, // 1217, // 1216, @@ -303,17 +429,17 @@ static const int included_patches[] = { // 1213, // 1212, // 1211, - // 1210, + 1210, // 1209, // 1208, 1207, 1206, - // 1205, - // 1204, + 1205, + 1204, // 1203, // 1202, // 1201, - // 1200, + 1200, // 1199, // 1198, // 1197, @@ -325,9 +451,9 @@ static const int included_patches[] = { // 1191, // 1190, 1189, - // 1188, + 1188, // 1187, - // 1186, + 1186, // 1185, // 1184, // 1183, @@ -355,7 +481,7 @@ static const int included_patches[] = { // 1161, // 1160, // 1159, - // 1158, + 1158, // 1157, // 1156, // 1155, @@ -506,7 +632,7 @@ static const int included_patches[] = { // 1010, // 1009, // 1008, - // 1007, + 1007, // 1006, // 1005, // 1004, @@ -538,8 +664,8 @@ static const int included_patches[] = { // 978, // 977, // 976, - // 975, - // 974, + 975, + 974, // 973, // 972, // 971, @@ -607,7 +733,7 @@ static const int included_patches[] = { // 909, // 908, // 907, - // 906, + 906, // 905, // 904, // 903, @@ -618,8 +744,8 @@ static const int included_patches[] = { // 898, // 897, // 896, - // 895, - // 894, + 895, + 894, // 893, // 892, // 891, @@ -651,11 +777,11 @@ static const int included_patches[] = { // 865, // 864, // 863, - // 862, - // 861, + 862, + 861, // 860, // 859, - // 858, + 858, // 857, // 856, // 855, @@ -666,7 +792,7 @@ static const int included_patches[] = { // 850, // 849, // 848, - // 847, + 847, // 846, // 845, // 844, @@ -777,7 +903,7 @@ static const int included_patches[] = { // 739, // 738, // 737, - // 736, + 736, // 735, // 734, // 733, @@ -790,9 +916,9 @@ static const int included_patches[] = { // 726, // 725, // 724, - // 723, + 723, // 722, - // 721, + 721, // 720, // 719, // 718, @@ -810,26 +936,26 @@ static const int included_patches[] = { // 706, // 705, // 704, - // 703, + 703, // 702, // 701, - // 700, - // 699, + 700, + 699, // 698, // 697, // 696, // 695, // 694, // 693, - // 692, + 692, // 691, // 690, - // 689, + 689, // 688, // 687, // 686, // 685, - // 684, + 684, // 683, // 682, // 681, @@ -837,7 +963,7 @@ static const int included_patches[] = { 679, 678, // 677, - // 676, + 676, // 675, 674, 673, @@ -863,7 +989,7 @@ static const int included_patches[] = { // 653, 652, // 651, - // 650, + 650, // 649, // 648, // 647, @@ -891,7 +1017,7 @@ static const int included_patches[] = { // 625, // 624, // 623, - // 622, + 622, // 621, // 620, // 619, @@ -900,7 +1026,7 @@ static const int included_patches[] = { // 616, // 615, 614, - // 613, + 613, 612, // 611, // 610, @@ -913,7 +1039,7 @@ static const int included_patches[] = { // 603, // 602, 601, - // 600, + 600, 599, // 598, 597, @@ -1023,7 +1149,7 @@ static const int included_patches[] = { // 493, // 492, // 491, - // 490, + 490, // 489, // 488, 487, @@ -1033,17 +1159,17 @@ static const int included_patches[] = { 483, 482, // 481, - // 480, - // 479, + 480, + 479, 478, 477, // 476, // 475, // 474, - // 473, - // 472, - // 471, - // 470, + 473, + 472, + 471, + 470, // 469, // 468, // 467, @@ -1067,14 +1193,14 @@ static const int included_patches[] = { // 449, 448, // 447, - // 446, + 446, // 445, 444, 443, 442, // 441, - // 440, - // 439, + 440, + 439, // 438, 437, // 436, @@ -1175,8 +1301,8 @@ static const int included_patches[] = { 341, // 340, 339, - // 338, - // 337, + 338, + 337, 336, 335, 334, @@ -1190,7 +1316,7 @@ static const int included_patches[] = { 326, 325, 324, - // 323, + 323, 322, // 321, 320, @@ -1220,7 +1346,7 @@ static const int included_patches[] = { // 296, 295, 294, - // 293, + 293, 292, 291, 290, @@ -1277,9 +1403,9 @@ static const int included_patches[] = { 239, // 238, 237, - // 236, + 236, 235, - // 234, + 234, // 233, 232, // 231, @@ -1288,20 +1414,20 @@ static const int included_patches[] = { // 228, 227, 226, - // 225, + 225, 224, 223, - // 222, + 222, 221, - // 220, + 220, 219, 218, 217, // 216, 215, - // 214, + 214, 213, - // 212, + 212, 211, // 210, 209, |