mirror of
https://github.com/neovim/neovim.git
synced 2025-09-13 14:58:18 +00:00
vim-patch:9.1.0479: fuzzy_match_str_with_pos() does unnecessary list operations
Problem: fuzzy_match_str_with_pos() does unnecessary list operations.
Solution: Use fuzzy_match() directly (zeertzjq).
closes: vim/vim#14987
2f95ca9fce
N/A patch:
vim-patch:9.1.0478: potential deref of NULL pointer in fuzzy_match_str_with_pos
This commit is contained in:
@@ -5080,7 +5080,6 @@ PmenuThumb Popup menu: Thumb of the scrollbar.
|
|||||||
PmenuMatch Popup menu: Matched text in normal item
|
PmenuMatch Popup menu: Matched text in normal item
|
||||||
*hl-PmenuMatchSel*
|
*hl-PmenuMatchSel*
|
||||||
PmenuMatchSel Popup menu: Matched text in selected item
|
PmenuMatchSel Popup menu: Matched text in selected item
|
||||||
|
|
||||||
*hl-Question*
|
*hl-Question*
|
||||||
Question |hit-enter| prompt and yes/no questions.
|
Question |hit-enter| prompt and yes/no questions.
|
||||||
*hl-QuickFixLine*
|
*hl-QuickFixLine*
|
||||||
|
@@ -438,7 +438,7 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, i
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Displays text on the popup menu with specific attributes.
|
/// Displays text on the popup menu with specific attributes.
|
||||||
static void pum_puts_with_attr(int col, const char *text, int attr)
|
static void pum_puts_with_attr(int col, char *text, int attr)
|
||||||
{
|
{
|
||||||
char *leader = ins_compl_leader();
|
char *leader = ins_compl_leader();
|
||||||
|
|
||||||
@@ -472,8 +472,8 @@ static void pum_puts_with_attr(int col, const char *text, int attr)
|
|||||||
if (ga != NULL) {
|
if (ga != NULL) {
|
||||||
// Handle fuzzy matching
|
// Handle fuzzy matching
|
||||||
for (int i = 0; i < ga->ga_len; i++) {
|
for (int i = 0; i < ga->ga_len; i++) {
|
||||||
int *match_pos = ((int *)ga->ga_data) + i;
|
uint32_t *match_pos = ((uint32_t *)ga->ga_data) + i;
|
||||||
int actual_char_pos = 0;
|
uint32_t actual_char_pos = 0;
|
||||||
const char *temp_ptr = text;
|
const char *temp_ptr = text;
|
||||||
while (temp_ptr < ptr) {
|
while (temp_ptr < ptr) {
|
||||||
temp_ptr += utfc_ptr2len(temp_ptr);
|
temp_ptr += utfc_ptr2len(temp_ptr);
|
||||||
|
@@ -3256,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 char *const key, Callback *const item_cb,
|
||||||
const bool retmatchpos, list_T *const fmatchlist,
|
const bool retmatchpos, list_T *const fmatchlist,
|
||||||
const int max_matches)
|
const int max_matches)
|
||||||
FUNC_ATTR_NONNULL_ARG(2, 7)
|
FUNC_ATTR_NONNULL_ARG(2, 5, 7)
|
||||||
{
|
{
|
||||||
int len = tv_list_len(l);
|
int len = tv_list_len(l);
|
||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
@@ -3546,80 +3546,33 @@ int fuzzy_match_str(char *const str, const char *const pat)
|
|||||||
|
|
||||||
/// Fuzzy match the position of string "pat" in string "str".
|
/// Fuzzy match the position of string "pat" in string "str".
|
||||||
/// @returns a dynamic array of matching positions. If there is no match, returns NULL.
|
/// @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 *fuzzy_match_str_with_pos(char *const str, const char *const pat)
|
||||||
{
|
{
|
||||||
garray_T *match_positions = xmalloc(sizeof(garray_T));
|
|
||||||
|
|
||||||
ga_init(match_positions, sizeof(int), 10);
|
|
||||||
if (str == NULL || pat == NULL) {
|
if (str == NULL || pat == NULL) {
|
||||||
ga_clear(match_positions);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
list_T *l = tv_list_alloc(1);
|
|
||||||
|
|
||||||
typval_T tv_str = {
|
garray_T *match_positions = xmalloc(sizeof(garray_T));
|
||||||
.v_type = VAR_STRING,
|
ga_init(match_positions, sizeof(uint32_t), 10);
|
||||||
.vval.v_string = xstrdup(str),
|
|
||||||
};
|
|
||||||
tv_list_append_tv(l, &tv_str);
|
|
||||||
|
|
||||||
list_T *retlist = tv_list_alloc(3);
|
unsigned matches[MAX_FUZZY_MATCHES];
|
||||||
list_T *match_str_list = tv_list_alloc(1);
|
int score = 0;
|
||||||
list_T *match_pos_list = tv_list_alloc(1);
|
if (!fuzzy_match(str, pat, false, &score, matches, MAX_FUZZY_MATCHES)
|
||||||
list_T *match_score_list = tv_list_alloc(1);
|
|| score == 0) {
|
||||||
|
ga_clear(match_positions);
|
||||||
tv_list_append_list(retlist, match_str_list);
|
xfree(match_positions);
|
||||||
tv_list_append_list(retlist, match_pos_list);
|
return NULL;
|
||||||
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);
|
int j = 0;
|
||||||
if (positions_item != NULL && TV_LIST_ITEM_TV(positions_item)->v_type == VAR_LIST) {
|
for (const char *p = pat; *p != NUL; MB_PTR_ADV(p)) {
|
||||||
list_T *positions_outer_list = TV_LIST_ITEM_TV(positions_item)->vval.v_list;
|
if (!ascii_iswhite(utf_ptr2char(p))) {
|
||||||
if (tv_list_len(positions_outer_list) > 0) {
|
GA_APPEND(uint32_t, match_positions, matches[j]);
|
||||||
listitem_T *outer_li = tv_list_first(positions_outer_list);
|
j++;
|
||||||
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;
|
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
|
/// Copy a list of fuzzy matches into a string list after sorting the matches by
|
||||||
|
Reference in New Issue
Block a user