From 4f73b8e9cc83f647b34002554a8bdf9abec0a82f Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Tue, 22 Sep 2020 20:33:50 +0200 Subject: patch 8.2.1726: fuzzy matching only works on strings Problem: Fuzzy matching only works on strings. Solution: Support passing a dict. Add matchfuzzypos() to also get the match positions. (Yegappan Lakshmanan, closes #6947) --- runtime/doc/eval.txt | 55 +++++++++++++++++++++++++++++++++++++++++++------- runtime/doc/usr_41.txt | 1 + 2 files changed, 49 insertions(+), 7 deletions(-) (limited to 'runtime') diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 82b81fbb32..f0271c01dc 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -2641,7 +2641,10 @@ matcharg({nr}) List arguments of |:match| matchdelete({id} [, {win}]) Number delete match identified by {id} matchend({expr}, {pat} [, {start} [, {count}]]) Number position where {pat} ends in {expr} -matchfuzzy({list}, {str}) List fuzzy match {str} in {list} +matchfuzzy({list}, {str} [, {dict}]) + List fuzzy match {str} in {list} +matchfuzzypos({list}, {str} [, {dict}]) + List fuzzy match {str} in {list} matchlist({expr}, {pat} [, {start} [, {count}]]) List match and submatches of {pat} in {expr} matchstr({expr}, {pat} [, {start} [, {count}]]) @@ -7311,12 +7314,25 @@ matchend({expr}, {pat} [, {start} [, {count}]]) *matchend()* GetText()->matchend('word') -matchfuzzy({list}, {str}) *matchfuzzy()* - Returns a list with all the strings in {list} that fuzzy - match {str}. The strings in the returned list are sorted - based on the matching score. {str} is treated as a literal - string and regular expression matching is NOT supported. - The maximum supported {str} length is 256. +matchfuzzy({list}, {str} [, {dict}]) *matchfuzzy()* + If {list} is a list of strings, then returns a list with all + the strings in {list} that fuzzy match {str}. The strings in + the returned list are sorted based on the matching score. + + If {list} is a list of dictionaries, then the optional {dict} + argument supports the following items: + key key of the item which is fuzzy matched against + {str}. The value of this item should be a + string. + text_cb |Funcref| that will be called for every item + in {list} to get the text for fuzzy matching. + This should accept a dictionary item as the + argument and return the text for that item to + use for fuzzy matching. + + {str} is treated as a literal string and regular expression + matching is NOT supported. The maximum supported {str} length + is 256. If there are no matching strings or there is an error, then an empty list is returned. If length of {str} is greater than @@ -7327,11 +7343,36 @@ matchfuzzy({list}, {str}) *matchfuzzy()* < results in ["clay"]. > :echo getbufinfo()->map({_, v -> v.name})->matchfuzzy("ndl") < results in a list of buffer names fuzzy matching "ndl". > + :echo getbufinfo()->matchfuzzy("ndl", {'key' : 'name'}) +< results in a list of buffer information dicts with buffer + names fuzzy matching "ndl". > + :echo getbufinfo()->matchfuzzy("spl", + \ {'text_cb' : {v -> v.name}}) +< results in a list of buffer information dicts with buffer + names fuzzy matching "spl". > :echo v:oldfiles->matchfuzzy("test") < results in a list of file names fuzzy matching "test". > :let l = readfile("buffer.c")->matchfuzzy("str") < results in a list of lines in "buffer.c" fuzzy matching "str". +matchfuzzypos({list}, {str} [, {dict}]) *matchfuzzypos()* + Same as |matchfuzzy()|, but returns the list of matched + strings and the list of character positions where characters + in {str} matches. + + If {str} matches multiple times in a string, then only the + positions for the best match is returned. + + If there are no matching strings or there is an error, then a + list with two empty list items is returned. + + Example: > + :echo matchfuzzypos(['testing'], 'tsg') +< results in [['testing'], [[0, 2, 6]]] > + :echo matchfuzzypos(['clay', 'lacy'], 'la') +< results in [['lacy', 'clay'], [[0, 1], [1, 2]]] > + :echo [{'text': 'hello', 'id' : 10}]->matchfuzzypos('ll', {'key' : 'text'}) +< results in [{'id': 10, 'text': 'hello'}] [[2, 3]] matchlist({expr}, {pat} [, {start} [, {count}]]) *matchlist()* Same as |match()|, but return a |List|. The first item in the diff --git a/runtime/doc/usr_41.txt b/runtime/doc/usr_41.txt index 1e5915f41b..387232b52e 100644 --- a/runtime/doc/usr_41.txt +++ b/runtime/doc/usr_41.txt @@ -604,6 +604,7 @@ String manipulation: *string-functions* match() position where a pattern matches in a string 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 matchstrpos() match and positions of a pattern in a string matchlist() like matchstr() and also return submatches -- cgit v1.2.3