To: vim_dev@googlegroups.com Subject: Patch 9.0.0622 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 9.0.0622 Problem: matchaddpos() can get slow when adding many matches. Solution: Update the next available match ID when manually picking an ID and remove check if the available ID can be used. (idea by Rick Howe) Files: runtime/doc/builtin.txt, src/window.c, src/match.c, src/testdir/test_match.vim *** ../vim-9.0.0621/runtime/doc/builtin.txt 2022-09-29 12:49:52.257601397 +0100 --- runtime/doc/builtin.txt 2022-09-29 13:33:48.939266514 +0100 *************** *** 5854,5860 **** respectively. 3 is reserved for use by the |matchparen| plugin. If the {id} argument is not specified or -1, |matchadd()| ! automatically chooses a free ID. The optional {dict} argument allows for further custom values. Currently this is used to specify a match specific --- 5864,5870 ---- respectively. 3 is reserved for use by the |matchparen| plugin. If the {id} argument is not specified or -1, |matchadd()| ! automatically chooses a free ID, which is at least 1000. The optional {dict} argument allows for further custom values. Currently this is used to specify a match specific *** ../vim-9.0.0621/src/window.c 2022-09-27 12:30:53.222180148 +0100 --- src/window.c 2022-09-29 13:34:37.267689826 +0100 *************** *** 5143,5150 **** #endif unblock_autocmds(); #ifdef FEAT_SEARCH_EXTRA ! new_wp->w_match_head = NULL; ! new_wp->w_next_match_id = 4; #endif return new_wp; } --- 5143,5149 ---- #endif unblock_autocmds(); #ifdef FEAT_SEARCH_EXTRA ! new_wp->w_next_match_id = 1000; // up to 1000 can be picked by the user #endif return new_wp; } *** ../vim-9.0.0621/src/match.c 2022-09-29 12:49:52.261601394 +0100 --- src/match.c 2022-09-29 13:41:58.590146155 +0100 *************** *** 50,68 **** semsg(_(e_invalid_id_nr_must_be_greater_than_or_equal_to_one_1), id); return -1; } ! if (id != -1) { ! cur = wp->w_match_head; ! while (cur != NULL) ! { if (cur->mit_id == id) { semsg(_(e_id_already_taken_nr), id); return -1; } ! cur = cur->mit_next; ! } } if ((hlg_id = syn_namen2id(grp, (int)STRLEN(grp))) == 0) { semsg(_(e_no_such_highlight_group_name_str), grp); --- 50,77 ---- semsg(_(e_invalid_id_nr_must_be_greater_than_or_equal_to_one_1), id); return -1; } ! if (id == -1) { ! // use the next available match ID ! id = wp->w_next_match_id++; ! } ! else ! { ! // check the given ID is not already in use ! for (cur = wp->w_match_head; cur != NULL; cur = cur->mit_next) if (cur->mit_id == id) { semsg(_(e_id_already_taken_nr), id); return -1; } ! ! // Make sure the next match ID is always higher than the highest ! // manually selected ID. Add some extra in case a few more IDs are ! // added soon. ! if (wp->w_next_match_id < id + 100) ! wp->w_next_match_id = id + 100; } + if ((hlg_id = syn_namen2id(grp, (int)STRLEN(grp))) == 0) { semsg(_(e_no_such_highlight_group_name_str), grp); *************** *** 74,90 **** return -1; } - // Find available match ID. - while (id == -1) - { - cur = wp->w_match_head; - while (cur != NULL && cur->mit_id != wp->w_next_match_id) - cur = cur->mit_next; - if (cur == NULL) - id = wp->w_next_match_id; - wp->w_next_match_id++; - } - // Build new match. m = ALLOC_CLEAR_ONE(matchitem_T); if (m == NULL) --- 83,88 ---- *** ../vim-9.0.0621/src/testdir/test_match.vim 2022-09-29 12:49:52.261601394 +0100 --- src/testdir/test_match.vim 2022-09-29 13:47:31.478989310 +0100 *************** *** 36,43 **** let m1 = matchadd("MyGroup1", "TODO") let m2 = matchadd("MyGroup2", "FIXME", 42) let m3 = matchadd("MyGroup3", "XXX", 60, 17) ! let ans = [{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 4}, ! \ {'group': 'MyGroup2', 'pattern': 'FIXME', 'priority': 42, 'id': 5}, \ {'group': 'MyGroup3', 'pattern': 'XXX', 'priority': 60, 'id': 17}] call assert_equal(ans, getmatches()) --- 36,43 ---- let m1 = matchadd("MyGroup1", "TODO") let m2 = matchadd("MyGroup2", "FIXME", 42) let m3 = matchadd("MyGroup3", "XXX", 60, 17) ! let ans = [{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 1000}, ! \ {'group': 'MyGroup2', 'pattern': 'FIXME', 'priority': 42, 'id': 1001}, \ {'group': 'MyGroup3', 'pattern': 'XXX', 'priority': 60, 'id': 17}] call assert_equal(ans, getmatches()) *************** *** 119,125 **** call clearmatches() call setline(1, 'abcdΣabcdef') ! eval "MyGroup1"->matchaddpos([[1, 4, 2], [1, 9, 2]]) 1 redraw! let v1 = screenattr(1, 1) --- 119,125 ---- call clearmatches() call setline(1, 'abcdΣabcdef') ! eval "MyGroup1"->matchaddpos([[1, 4, 2], [1, 9, 2]], 10, 42) 1 redraw! let v1 = screenattr(1, 1) *************** *** 130,136 **** let v8 = screenattr(1, 8) let v9 = screenattr(1, 9) let v10 = screenattr(1, 10) ! call assert_equal([{'group': 'MyGroup1', 'id': 11, 'priority': 10, 'pos1': [1, 4, 2], 'pos2': [1, 9, 2]}], getmatches()) call assert_notequal(v1, v4) call assert_equal(v5, v4) call assert_equal(v6, v1) --- 130,136 ---- let v8 = screenattr(1, 8) let v9 = screenattr(1, 9) let v10 = screenattr(1, 10) ! call assert_equal([{'group': 'MyGroup1', 'id': 42, 'priority': 10, 'pos1': [1, 4, 2], 'pos2': [1, 9, 2]}], getmatches()) call assert_notequal(v1, v4) call assert_equal(v5, v4) call assert_equal(v6, v1) *************** *** 144,150 **** let m=getmatches() call clearmatches() call setmatches(m) ! call assert_equal([{'group': 'MyGroup1', 'id': 11, 'priority': 10, 'pos1': [1, 4, 2], 'pos2': [1,9, 2]}, {'group': 'MyGroup1', 'pattern': '\%2lmatchadd', 'priority': 10, 'id': 12}], getmatches()) highlight MyGroup1 NONE highlight MyGroup2 NONE --- 144,150 ---- let m=getmatches() call clearmatches() call setmatches(m) ! call assert_equal([{'group': 'MyGroup1', 'id': 42, 'priority': 10, 'pos1': [1, 4, 2], 'pos2': [1,9, 2]}, {'group': 'MyGroup1', 'pattern': '\%2lmatchadd', 'priority': 10, 'id': 1106}], getmatches()) highlight MyGroup1 NONE highlight MyGroup2 NONE *************** *** 252,259 **** let savematches = getmatches(winid) let expect = [ ! \ {'group': 'Search', 'pattern': '4', 'priority': 10, 'id': 4}, ! \ {'group': 'Error', 'id': 5, 'priority': 10, 'pos1': [1, 2, 1], 'pos2': [2, 2, 1]}, \] call assert_equal(expect, savematches) --- 252,259 ---- let savematches = getmatches(winid) let expect = [ ! \ {'group': 'Search', 'pattern': '4', 'priority': 10, 'id': 1000}, ! \ {'group': 'Error', 'id': 1001, 'priority': 10, 'pos1': [1, 2, 1], 'pos2': [2, 2, 1]}, \] call assert_equal(expect, savematches) *** ../vim-9.0.0621/src/version.c 2022-09-29 13:07:14.262964414 +0100 --- src/version.c 2022-09-29 13:40:37.937841975 +0100 *************** *** 701,702 **** --- 701,704 ---- { /* Add new patch number below this line */ + /**/ + 622, /**/ -- hundred-and-one symptoms of being an internet addict: 218. Your spouse hands you a gift wrapped magnet with your PC's name on it and you accuse him or her of genocide. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///