comparison src/option.c @ 27875:ae38d2e81fca v8.2.4463

patch 8.2.4463: completion only uses strict matching Commit: https://github.com/vim/vim/commit/38b85cb4d7216705058708bacbc25ab90cd61595 Author: Yegappan Lakshmanan <yegappan@yahoo.com> Date: Thu Feb 24 13:28:41 2022 +0000 patch 8.2.4463: completion only uses strict matching Problem: Completion only uses strict matching. Solution: Add the "fuzzy" item for 'wildoptions'. (Yegappan Lakshmanan, closes #9803)
author Bram Moolenaar <Bram@vim.org>
date Thu, 24 Feb 2022 14:30:05 +0100
parents 44a552776007
children f04a3ec65e2d
comparison
equal deleted inserted replaced
27874:f4a227222e7a 27875:ae38d2e81fca
6445 } 6445 }
6446 #endif 6446 #endif
6447 } 6447 }
6448 } 6448 }
6449 6449
6450 /*
6451 * Returns TRUE if 'str' either matches 'regmatch' or fuzzy matches 'pat'.
6452 *
6453 * If 'test_only' is TRUE and 'fuzzy' is FALSE and if 'str' matches the regular
6454 * expression 'regmatch', then returns TRUE. Otherwise returns FALSE.
6455 *
6456 * If 'test_only' is FALSE and 'fuzzy' is FALSE and if 'str' matches the
6457 * regular expression 'regmatch', then stores the match in matches[idx] and
6458 * returns TRUE.
6459 *
6460 * If 'test_only' is TRUE and 'fuzzy' is TRUE and if 'str' fuzzy matches
6461 * 'fuzzystr', then returns TRUE. Otherwise returns FALSE.
6462 *
6463 * If 'test_only' is FALSE and 'fuzzy' is TRUE and if 'str' fuzzy matches
6464 * 'fuzzystr', then stores the match details in fuzmatch[idx] and returns TRUE.
6465 */
6466 static int
6467 match_str(
6468 char_u *str,
6469 regmatch_T *regmatch,
6470 char_u **matches,
6471 int idx,
6472 int test_only,
6473 int fuzzy,
6474 char_u *fuzzystr,
6475 fuzmatch_str_T *fuzmatch)
6476 {
6477 if (!fuzzy)
6478 {
6479 if (vim_regexec(regmatch, str, (colnr_T)0))
6480 {
6481 if (!test_only)
6482 matches[idx] = vim_strsave(str);
6483 return TRUE;
6484 }
6485 }
6486 else
6487 {
6488 int score;
6489
6490 score = fuzzy_match_str(str, fuzzystr);
6491 if (score != 0)
6492 {
6493 if (!test_only)
6494 {
6495 fuzmatch[idx].idx = idx;
6496 fuzmatch[idx].str = vim_strsave(str);
6497 fuzmatch[idx].score = score;
6498 }
6499
6500 return TRUE;
6501 }
6502 }
6503
6504 return FALSE;
6505 }
6506
6450 int 6507 int
6451 ExpandSettings( 6508 ExpandSettings(
6452 expand_T *xp, 6509 expand_T *xp,
6453 regmatch_T *regmatch, 6510 regmatch_T *regmatch,
6454 int *num_file, 6511 char_u *fuzzystr,
6455 char_u ***file) 6512 int *numMatches,
6513 char_u ***matches)
6456 { 6514 {
6457 int num_normal = 0; // Nr of matching non-term-code settings 6515 int num_normal = 0; // Nr of matching non-term-code settings
6458 int num_term = 0; // Nr of matching terminal code settings 6516 int num_term = 0; // Nr of matching terminal code settings
6459 int opt_idx; 6517 int opt_idx;
6460 int match; 6518 int match;
6463 int loop; 6521 int loop;
6464 int is_term_opt; 6522 int is_term_opt;
6465 char_u name_buf[MAX_KEY_NAME_LEN]; 6523 char_u name_buf[MAX_KEY_NAME_LEN];
6466 static char *(names[]) = {"all", "termcap"}; 6524 static char *(names[]) = {"all", "termcap"};
6467 int ic = regmatch->rm_ic; // remember the ignore-case flag 6525 int ic = regmatch->rm_ic; // remember the ignore-case flag
6526 int fuzzy;
6527 fuzmatch_str_T *fuzmatch = NULL;
6528
6529 fuzzy = cmdline_fuzzy_complete(fuzzystr);
6468 6530
6469 // do this loop twice: 6531 // do this loop twice:
6470 // loop == 0: count the number of matching options 6532 // loop == 0: count the number of matching options
6471 // loop == 1: copy the matching options into allocated memory 6533 // loop == 1: copy the matching options into allocated memory
6472 for (loop = 0; loop <= 1; ++loop) 6534 for (loop = 0; loop <= 1; ++loop)
6473 { 6535 {
6474 regmatch->rm_ic = ic; 6536 regmatch->rm_ic = ic;
6475 if (xp->xp_context != EXPAND_BOOL_SETTINGS) 6537 if (xp->xp_context != EXPAND_BOOL_SETTINGS)
6476 { 6538 {
6477 for (match = 0; match < (int)ARRAY_LENGTH(names); ++match) 6539 for (match = 0; match < (int)ARRAY_LENGTH(names); ++match)
6478 if (vim_regexec(regmatch, (char_u *)names[match], (colnr_T)0)) 6540 {
6541 if (match_str((char_u *)names[match], regmatch, *matches,
6542 count, (loop == 0), fuzzy, fuzzystr, fuzmatch))
6479 { 6543 {
6480 if (loop == 0) 6544 if (loop == 0)
6481 num_normal++; 6545 num_normal++;
6482 else 6546 else
6483 (*file)[count++] = vim_strsave((char_u *)names[match]); 6547 count++;
6484 } 6548 }
6549 }
6485 } 6550 }
6486 for (opt_idx = 0; (str = (char_u *)options[opt_idx].fullname) != NULL; 6551 for (opt_idx = 0; (str = (char_u *)options[opt_idx].fullname) != NULL;
6487 opt_idx++) 6552 opt_idx++)
6488 { 6553 {
6489 if (options[opt_idx].var == NULL) 6554 if (options[opt_idx].var == NULL)
6492 && !(options[opt_idx].flags & P_BOOL)) 6557 && !(options[opt_idx].flags & P_BOOL))
6493 continue; 6558 continue;
6494 is_term_opt = istermoption_idx(opt_idx); 6559 is_term_opt = istermoption_idx(opt_idx);
6495 if (is_term_opt && num_normal > 0) 6560 if (is_term_opt && num_normal > 0)
6496 continue; 6561 continue;
6497 match = FALSE; 6562
6498 if (vim_regexec(regmatch, str, (colnr_T)0) 6563 if (match_str(str, regmatch, *matches, count, (loop == 0),
6499 || (options[opt_idx].shortname != NULL 6564 fuzzy, fuzzystr, fuzmatch))
6500 && vim_regexec(regmatch,
6501 (char_u *)options[opt_idx].shortname, (colnr_T)0)))
6502 match = TRUE;
6503 else if (is_term_opt)
6504 {
6505 name_buf[0] = '<';
6506 name_buf[1] = 't';
6507 name_buf[2] = '_';
6508 name_buf[3] = str[2];
6509 name_buf[4] = str[3];
6510 name_buf[5] = '>';
6511 name_buf[6] = NUL;
6512 if (vim_regexec(regmatch, name_buf, (colnr_T)0))
6513 {
6514 match = TRUE;
6515 str = name_buf;
6516 }
6517 }
6518 if (match)
6519 { 6565 {
6520 if (loop == 0) 6566 if (loop == 0)
6521 { 6567 {
6522 if (is_term_opt) 6568 if (is_term_opt)
6523 num_term++; 6569 num_term++;
6524 else 6570 else
6525 num_normal++; 6571 num_normal++;
6526 } 6572 }
6527 else 6573 else
6528 (*file)[count++] = vim_strsave(str); 6574 count++;
6529 } 6575 }
6530 } 6576 else if (!fuzzy && options[opt_idx].shortname != NULL
6577 && vim_regexec(regmatch,
6578 (char_u *)options[opt_idx].shortname, (colnr_T)0))
6579 {
6580 // Compare against the abbreviated option name (for regular
6581 // expression match). Fuzzy matching (previous if) already
6582 // matches against both the expanded and abbreviated names.
6583 if (loop == 0)
6584 {
6585 if (is_term_opt)
6586 num_term++;
6587 else
6588 num_normal++;
6589 }
6590 else
6591 (*matches)[count++] = vim_strsave(str);
6592 }
6593 else if (is_term_opt)
6594 {
6595 name_buf[0] = '<';
6596 name_buf[1] = 't';
6597 name_buf[2] = '_';
6598 name_buf[3] = str[2];
6599 name_buf[4] = str[3];
6600 name_buf[5] = '>';
6601 name_buf[6] = NUL;
6602
6603 if (match_str(name_buf, regmatch, *matches, count, (loop == 0),
6604 fuzzy, fuzzystr, fuzmatch))
6605 {
6606 if (loop == 0)
6607 num_term++;
6608 else
6609 count++;
6610 }
6611 }
6612 }
6613
6531 /* 6614 /*
6532 * Check terminal key codes, these are not in the option table 6615 * Check terminal key codes, these are not in the option table
6533 */ 6616 */
6534 if (xp->xp_context != EXPAND_BOOL_SETTINGS && num_normal == 0) 6617 if (xp->xp_context != EXPAND_BOOL_SETTINGS && num_normal == 0)
6535 { 6618 {
6542 name_buf[1] = '_'; 6625 name_buf[1] = '_';
6543 name_buf[2] = str[0]; 6626 name_buf[2] = str[0];
6544 name_buf[3] = str[1]; 6627 name_buf[3] = str[1];
6545 name_buf[4] = NUL; 6628 name_buf[4] = NUL;
6546 6629
6547 match = FALSE; 6630 if (match_str(name_buf, regmatch, *matches, count,
6548 if (vim_regexec(regmatch, name_buf, (colnr_T)0)) 6631 (loop == 0), fuzzy, fuzzystr, fuzmatch))
6549 match = TRUE; 6632 {
6633 if (loop == 0)
6634 num_term++;
6635 else
6636 count++;
6637 }
6550 else 6638 else
6551 { 6639 {
6552 name_buf[0] = '<'; 6640 name_buf[0] = '<';
6553 name_buf[1] = 't'; 6641 name_buf[1] = 't';
6554 name_buf[2] = '_'; 6642 name_buf[2] = '_';
6555 name_buf[3] = str[0]; 6643 name_buf[3] = str[0];
6556 name_buf[4] = str[1]; 6644 name_buf[4] = str[1];
6557 name_buf[5] = '>'; 6645 name_buf[5] = '>';
6558 name_buf[6] = NUL; 6646 name_buf[6] = NUL;
6559 6647
6560 if (vim_regexec(regmatch, name_buf, (colnr_T)0)) 6648 if (match_str(name_buf, regmatch, *matches, count,
6561 match = TRUE; 6649 (loop == 0), fuzzy, fuzzystr,
6562 } 6650 fuzmatch))
6563 if (match) 6651 {
6564 { 6652 if (loop == 0)
6565 if (loop == 0) 6653 num_term++;
6566 num_term++; 6654 else
6567 else 6655 count++;
6568 (*file)[count++] = vim_strsave(name_buf); 6656 }
6569 } 6657 }
6570 } 6658 }
6571 6659
6572 /* 6660 /*
6573 * Check special key names. 6661 * Check special key names.
6577 { 6665 {
6578 name_buf[0] = '<'; 6666 name_buf[0] = '<';
6579 STRCPY(name_buf + 1, str); 6667 STRCPY(name_buf + 1, str);
6580 STRCAT(name_buf, ">"); 6668 STRCAT(name_buf, ">");
6581 6669
6582 if (vim_regexec(regmatch, name_buf, (colnr_T)0)) 6670 if (match_str(name_buf, regmatch, *matches, count, (loop == 0),
6671 fuzzy, fuzzystr, fuzmatch))
6583 { 6672 {
6584 if (loop == 0) 6673 if (loop == 0)
6585 num_term++; 6674 num_term++;
6586 else 6675 else
6587 (*file)[count++] = vim_strsave(name_buf); 6676 count++;
6588 } 6677 }
6589 } 6678 }
6590 } 6679 }
6591 if (loop == 0) 6680 if (loop == 0)
6592 { 6681 {
6593 if (num_normal > 0) 6682 if (num_normal > 0)
6594 *num_file = num_normal; 6683 *numMatches = num_normal;
6595 else if (num_term > 0) 6684 else if (num_term > 0)
6596 *num_file = num_term; 6685 *numMatches = num_term;
6597 else 6686 else
6598 return OK; 6687 return OK;
6599 *file = ALLOC_MULT(char_u *, *num_file); 6688 if (!fuzzy)
6600 if (*file == NULL) 6689 {
6601 { 6690 *matches = ALLOC_MULT(char_u *, *numMatches);
6602 *file = (char_u **)""; 6691 if (*matches == NULL)
6603 return FAIL; 6692 {
6604 } 6693 *matches = (char_u **)"";
6605 } 6694 return FAIL;
6606 } 6695 }
6696 }
6697 else
6698 {
6699 fuzmatch = ALLOC_MULT(fuzmatch_str_T, *numMatches);
6700 if (fuzmatch == NULL)
6701 {
6702 *matches = (char_u **)"";
6703 return FAIL;
6704 }
6705 }
6706 }
6707 }
6708
6709 if (fuzzy &&
6710 fuzzymatches_to_strmatches(fuzmatch, matches, count, FALSE) == FAIL)
6711 return FAIL;
6712
6607 return OK; 6713 return OK;
6608 } 6714 }
6609 6715
6610 int 6716 int
6611 ExpandOldSetting(int *num_file, char_u ***file) 6717 ExpandOldSetting(int *num_file, char_u ***file)