diff options
author | zeertzjq <zeertzjq@outlook.com> | 2024-06-13 14:08:50 +0800 |
---|---|---|
committer | zeertzjq <zeertzjq@outlook.com> | 2024-06-15 04:47:23 +0800 |
commit | dc4037f612c6f3bbc76890adfa638d48ec238eee (patch) | |
tree | 97e79ba5672c7e6190a8379a2f7d1869f48cbf7e /src/nvim/search.c | |
parent | fd950d4998a497cb4258d35af72408105900296a (diff) | |
download | rneovim-dc4037f612c6f3bbc76890adfa638d48ec238eee.tar.gz rneovim-dc4037f612c6f3bbc76890adfa638d48ec238eee.tar.bz2 rneovim-dc4037f612c6f3bbc76890adfa638d48ec238eee.zip |
vim-patch:9.1.0476: Cannot see matched text in popup menu
Problem: Cannot see matched text in popup menu
Solution: Introduce 2 new highlighting groups: PmenuMatch and
PmenuMatchSel (glepnir)
closes: vim/vim#14694
https://github.com/vim/vim/commit/40c1c3317d92f8c2adadf744fab72e4458e2a9fa
Co-authored-by: glepnir <glephunter@gmail.com>
Diffstat (limited to 'src/nvim/search.c')
-rw-r--r-- | src/nvim/search.c | 82 |
1 files changed, 81 insertions, 1 deletions
diff --git a/src/nvim/search.c b/src/nvim/search.c index bee124e305..fef27dba48 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -21,12 +21,14 @@ #include "nvim/errors.h" #include "nvim/eval.h" #include "nvim/eval/typval.h" +#include "nvim/eval/typval_defs.h" #include "nvim/ex_cmds.h" #include "nvim/ex_cmds_defs.h" #include "nvim/ex_docmd.h" #include "nvim/ex_getln.h" #include "nvim/fileio.h" #include "nvim/fold.h" +#include "nvim/garray.h" #include "nvim/getchar.h" #include "nvim/gettext_defs.h" #include "nvim/globals.h" @@ -3254,7 +3256,7 @@ static void fuzzy_match_in_list(list_T *const l, char *const str, const bool mat const char *const key, Callback *const item_cb, const bool retmatchpos, list_T *const fmatchlist, const int max_matches) - FUNC_ATTR_NONNULL_ARG(2, 5, 7) + FUNC_ATTR_NONNULL_ARG(2, 7) { int len = tv_list_len(l); if (len == 0) { @@ -3542,6 +3544,84 @@ int fuzzy_match_str(char *const str, const char *const pat) return score; } +/// Fuzzy match the position of string "pat" in string "str". +/// @returns a dynamic array of matching positions. If there is no match, returns NULL. +garray_T *fuzzy_match_str_with_pos(const char *const str, char *const pat) +{ + garray_T *match_positions = xmalloc(sizeof(garray_T)); + + ga_init(match_positions, sizeof(int), 10); + if (str == NULL || pat == NULL) { + ga_clear(match_positions); + return NULL; + } + list_T *l = tv_list_alloc(1); + + typval_T tv_str = { + .v_type = VAR_STRING, + .vval.v_string = xstrdup(str), + }; + tv_list_append_tv(l, &tv_str); + + list_T *retlist = tv_list_alloc(3); + list_T *match_str_list = tv_list_alloc(1); + list_T *match_pos_list = tv_list_alloc(1); + list_T *match_score_list = tv_list_alloc(1); + + tv_list_append_list(retlist, match_str_list); + tv_list_append_list(retlist, match_pos_list); + tv_list_append_list(retlist, match_score_list); + + fuzzy_match_in_list(l, pat, false, NULL, NULL, true, retlist, 1); + + varnumber_T score = 0; + listitem_T *score_item = tv_list_find(retlist, 2); + if (score_item != NULL && TV_LIST_ITEM_TV(score_item)->v_type == VAR_LIST) { + list_T *score_list = TV_LIST_ITEM_TV(score_item)->vval.v_list; + if (tv_list_len(score_list) > 0) { + listitem_T *first_score_item = tv_list_first(score_list); + if (first_score_item != NULL && TV_LIST_ITEM_TV(first_score_item)->v_type == VAR_NUMBER) { + score = TV_LIST_ITEM_TV(first_score_item)->vval.v_number; + } + } + } + if (score == 0) { + goto cleanup; + } + + listitem_T *positions_item = tv_list_find(retlist, 1); + if (positions_item != NULL && TV_LIST_ITEM_TV(positions_item)->v_type == VAR_LIST) { + list_T *positions_outer_list = TV_LIST_ITEM_TV(positions_item)->vval.v_list; + if (tv_list_len(positions_outer_list) > 0) { + listitem_T *outer_li = tv_list_first(positions_outer_list); + if (outer_li != NULL && TV_LIST_ITEM_TV(outer_li)->v_type == VAR_LIST) { + list_T *positions_inner_list = TV_LIST_ITEM_TV(outer_li)->vval.v_list; + TV_LIST_ITER_CONST(positions_inner_list, li, { + if (TV_LIST_ITEM_TV(li)->v_type == VAR_NUMBER) { + varnumber_T pos = TV_LIST_ITEM_TV(li)->vval.v_number; + GA_APPEND(int, match_positions, (int)pos); + } + }); + } + } + } + + xfree(tv_str.vval.v_string); + tv_list_free(retlist); + tv_list_free(l); + return match_positions; + +cleanup: + xfree(tv_str.vval.v_string); + tv_list_free(match_str_list); + tv_list_free(match_pos_list); + tv_list_free(match_score_list); + tv_list_free(retlist); + tv_list_free(l); + ga_clear(match_positions); + return NULL; +} + /// Copy a list of fuzzy matches into a string list after sorting the matches by /// the fuzzy score. Frees the memory allocated for "fuzmatch". void fuzzymatches_to_strmatches(fuzmatch_str_T *const fuzmatch, char ***const matches, |