From 73e1942abe7a96d63ce3749af4187f2cdff87e69 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 16 Jan 2024 08:00:08 +0800 Subject: vim-patch:9.1.0009: Cannot easily get the list of matches (#27028) Problem: Cannot easily get the list of matches Solution: Add the matchstrlist() and matchbufline() Vim script functions (Yegappan Lakshmanan) closes: vim/vim#13766 Omit CHECK_LIST_MATERIALIZE(): it populates a List with numbers only, and there is a check for strings below. https://github.com/vim/vim/commit/f93b1c881a99fa847a1bafa71877d7e16f18e6ef vim-patch:eb3475df0d92 runtime(doc): Replace non-breaking space with normal space (vim/vim#13868) https://github.com/vim/vim/commit/eb3475df0d927a178789cf8e7fc4983932e1cdbe Co-authored-by: Yegappan Lakshmanan <4298407+yegappan@users.noreply.github.com> --- runtime/doc/builtin.txt | 73 ++++++++++++++++++++++++++++++++++- runtime/doc/usr_41.txt | 3 ++ runtime/lua/vim/_meta/vimfn.lua | 85 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 159 insertions(+), 2 deletions(-) (limited to 'runtime') diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt index d85735a008..416a10460a 100644 --- a/runtime/doc/builtin.txt +++ b/runtime/doc/builtin.txt @@ -4480,6 +4480,47 @@ matcharg({nr}) *matcharg()* Highlighting matches using the |:match| commands are limited to three matches. |matchadd()| does not have this limitation. +matchbufline({buf}, {pat}, {lnum}, {end}, [, {dict}]) *matchbufline()* + Returns the |List| of matches in lines from {lnum} to {end} in + buffer {buf} where {pat} matches. + + {lnum} and {end} can either be a line number or the string "$" + to refer to the last line in {buf}. + + The {dict} argument supports following items: + submatches include submatch information (|/\(|) + + For each match, a |Dict| with the following items is returned: + byteidx starting byte index of the match + lnum line number where there is a match + text matched string + Note that there can be multiple matches in a single line. + + This function works only for loaded buffers. First call + |bufload()| if needed. + + When {buf} is not a valid buffer, the buffer is not loaded or + {lnum} or {end} is not valid then an error is given and an + empty |List| is returned. + + Examples: >vim + " Assuming line 3 in buffer 5 contains "a" + :echo matchbufline(5, '\<\k\+\>', 3, 3) + [{'lnum': 3, 'byteidx': 0, 'text': 'a'}] + " Assuming line 4 in buffer 10 contains "tik tok" + :echo matchbufline(10, '\<\k\+\>', 1, 4) + [{'lnum': 4, 'byteidx': 0, 'text': 'tik'}, {'lnum': 4, 'byteidx': 4, 'text': 'tok'}] +< + If {submatch} is present and is v:true, then submatches like + "\1", "\2", etc. are also returned. Example: >vim + " Assuming line 2 in buffer 2 contains "acd" + :echo matchbufline(2, '\(a\)\?\(b\)\?\(c\)\?\(.*\)', 2, 2 + \ {'submatches': v:true}) + [{'lnum': 2, 'byteidx': 0, 'text': 'acd', 'submatches': ['a', '', 'c', 'd', '', '', '', '', '']}] +< The "submatches" List always contains 9 items. If a submatch + is not found, then an empty string is returned for that + submatch. + matchdelete({id} [, {win}]) *matchdelete()* *E802* *E803* Deletes a match with ID {id} previously defined by |matchadd()| or one of the |:match| commands. Returns 0 if successful, @@ -4617,6 +4658,36 @@ matchstr({expr}, {pat} [, {start} [, {count}]]) *matchstr()* When {expr} is a |List| then the matching item is returned. The type isn't changed, it's not necessarily a String. +matchstrlist({list}, {pat} [, {dict}]) *matchstrlist()* + Returns the |List| of matches in {list} where {pat} matches. + {list} is a |List| of strings. {pat} is matched against each + string in {list}. + + The {dict} argument supports following items: + submatches include submatch information (|/\(|) + + For each match, a |Dict| with the following items is returned: + byteidx starting byte index of the match. + idx index in {list} of the match. + text matched string + submatches a List of submatches. Present only if + "submatches" is set to v:true in {dict}. + + Example: >vim + :echo matchstrlist(['tik tok'], '\<\k\+\>') + [{'idx': 0, 'byteidx': 0, 'text': 'tik'}, {'idx': 0, 'byteidx': 4, 'text': 'tok'}] + :echo matchstrlist(['a', 'b'], '\<\k\+\>') + [{'idx': 0, 'byteidx': 0, 'text': 'a'}, {'idx': 1, 'byteidx': 0, 'text': 'b'}] +< + If "submatches" is present and is v:true, then submatches like + "\1", "\2", etc. are also returned. Example: >vim + :echo matchstrlist(['acd'], '\(a\)\?\(b\)\?\(c\)\?\(.*\)', + \ #{submatches: v:true}) + [{'idx': 0, 'byteidx': 0, 'text': 'acd', 'submatches': ['a', '', 'c', 'd', '', '', '', '', '']}] +< The "submatches" List always contains 9 items. If a submatch + is not found, then an empty string is returned for that + submatch. + matchstrpos({expr}, {pat} [, {start} [, {count}]]) *matchstrpos()* Same as |matchstr()|, but return the matched string, the start position and the end position of the match. Example: >vim @@ -4643,7 +4714,7 @@ max({expr}) *max()* it returns the maximum of all values in the Dictionary. If {expr} is neither a List nor a Dictionary, or one of the items in {expr} cannot be used as a Number this results in - an error. An empty |List| or |Dictionary| results in zero. + an error. An empty |List| or |Dictionary| results in zero. menu_get({path} [, {modes}]) *menu_get()* Returns a |List| of |Dictionaries| describing |menus| (defined diff --git a/runtime/doc/usr_41.txt b/runtime/doc/usr_41.txt index e206a804f4..acb957d0c1 100644 --- a/runtime/doc/usr_41.txt +++ b/runtime/doc/usr_41.txt @@ -610,10 +610,13 @@ String manipulation: *string-functions* toupper() turn a string to uppercase charclass() class of a character match() position where a pattern matches in a string + matchbufline() all the matches of a pattern in a buffer matchend() position where a pattern match ends in a string matchfuzzy() fuzzy matches a string in a list of strings matchfuzzypos() fuzzy matches a string in a list of strings matchstr() match of a pattern in a string + matchstrlist() all the matches of a pattern in a List of + strings matchstrpos() match and positions of a pattern in a string matchlist() like matchstr() and also return submatches stridx() first index of a short string in a long string diff --git a/runtime/lua/vim/_meta/vimfn.lua b/runtime/lua/vim/_meta/vimfn.lua index fd9b68a6f3..01b4ef920b 100644 --- a/runtime/lua/vim/_meta/vimfn.lua +++ b/runtime/lua/vim/_meta/vimfn.lua @@ -5412,6 +5412,54 @@ function vim.fn.matchaddpos(group, pos, priority, id, dict) end --- @return any function vim.fn.matcharg(nr) end +--- Returns the |List| of matches in lines from {lnum} to {end} in +--- buffer {buf} where {pat} matches. +--- +--- {lnum} and {end} can either be a line number or the string "$" +--- to refer to the last line in {buf}. +--- +--- The {dict} argument supports following items: +--- submatches include submatch information (|/\(|) +--- +--- For each match, a |Dict| with the following items is returned: +--- byteidx starting byte index of the match +--- lnum line number where there is a match +--- text matched string +--- Note that there can be multiple matches in a single line. +--- +--- This function works only for loaded buffers. First call +--- |bufload()| if needed. +--- +--- When {buf} is not a valid buffer, the buffer is not loaded or +--- {lnum} or {end} is not valid then an error is given and an +--- empty |List| is returned. +--- +--- Examples: >vim +--- " Assuming line 3 in buffer 5 contains "a" +--- :echo matchbufline(5, '\<\k\+\>', 3, 3) +--- [{'lnum': 3, 'byteidx': 0, 'text': 'a'}] +--- " Assuming line 4 in buffer 10 contains "tik tok" +--- :echo matchbufline(10, '\<\k\+\>', 1, 4) +--- [{'lnum': 4, 'byteidx': 0, 'text': 'tik'}, {'lnum': 4, 'byteidx': 4, 'text': 'tok'}] +--- < +--- If {submatch} is present and is v:true, then submatches like +--- "\1", "\2", etc. are also returned. Example: >vim +--- " Assuming line 2 in buffer 2 contains "acd" +--- :echo matchbufline(2, '\(a\)\?\(b\)\?\(c\)\?\(.*\)', 2, 2 +--- \ {'submatches': v:true}) +--- [{'lnum': 2, 'byteidx': 0, 'text': 'acd', 'submatches': ['a', '', 'c', 'd', '', '', '', '', '']}] +--- vim +--- :echo matchstrlist(['tik tok'], '\<\k\+\>') +--- [{'idx': 0, 'byteidx': 0, 'text': 'tik'}, {'idx': 0, 'byteidx': 4, 'text': 'tok'}] +--- :echo matchstrlist(['a', 'b'], '\<\k\+\>') +--- [{'idx': 0, 'byteidx': 0, 'text': 'a'}, {'idx': 1, 'byteidx': 0, 'text': 'b'}] +--- < +--- If "submatches" is present and is v:true, then submatches like +--- "\1", "\2", etc. are also returned. Example: >vim +--- :echo matchstrlist(['acd'], '\(a\)\?\(b\)\?\(c\)\?\(.*\)', +--- \ #{submatches: v:true}) +--- [{'idx': 0, 'byteidx': 0, 'text': 'acd', 'submatches': ['a', '', 'c', 'd', '', '', '', '', '']}] +--- vim --- echo matchstrpos("testing", "ing") @@ -5612,7 +5695,7 @@ function vim.fn.matchstrpos(expr, pat, start, count) end --- it returns the maximum of all values in the Dictionary. --- If {expr} is neither a List nor a Dictionary, or one of the --- items in {expr} cannot be used as a Number this results in ---- an error. An empty |List| or |Dictionary| results in zero. +--- an error. An empty |List| or |Dictionary| results in zero. --- --- @param expr any --- @return any -- cgit