comparison src/cmdexpand.c @ 27626:95d6e3c9aa1e v8.2.4339

patch 8.2.4339: CTRL-A does not work properly with the cmdline popup menu Commit: https://github.com/vim/vim/commit/560dff49c0095111fc96b4b8dd7f4d269aba9473 Author: Yegappan Lakshmanan <yegappan@yahoo.com> Date: Thu Feb 10 19:52:10 2022 +0000 patch 8.2.4339: CTRL-A does not work properly with the cmdline popup menu Problem: CTRL-A does not work properly with the cmdline popup menu. Solution: Fix issues with CTRL-A. Add more tests for the cmdline popup menu. Remove TermWait() before VeriryScreenDump(). Refactor the cmdline popup code. (Yegappan Lakshmanan, closes #9735)
author Bram Moolenaar <Bram@vim.org>
date Thu, 10 Feb 2022 21:00:04 +0100
parents a74901e95937
children 9caeb7f8b094
comparison
equal deleted inserted replaced
27625:bba604950a7e 27626:95d6e3c9aa1e
34 static int compl_match_arraysize; 34 static int compl_match_arraysize;
35 // First column in cmdline of the matched item for completion. 35 // First column in cmdline of the matched item for completion.
36 static int compl_startcol; 36 static int compl_startcol;
37 static int compl_selected; 37 static int compl_selected;
38 #endif 38 #endif
39
40 #define SHOW_FILE_TEXT(m) (showtail ? sm_gettail(files_found[m]) : files_found[m])
39 41
40 static int 42 static int
41 sort_func_compare(const void *s1, const void *s2) 43 sort_func_compare(const void *s1, const void *s2)
42 { 44 {
43 char_u *p1 = *(char_u **)s1; 45 char_u *p1 = *(char_u **)s1;
254 256
255 return OK; 257 return OK;
256 } 258 }
257 259
258 #if defined(FEAT_WILDMENU) || defined(PROTO) 260 #if defined(FEAT_WILDMENU) || defined(PROTO)
261
262 /*
263 * Create and display a cmdline completion popup menu with items from
264 * 'files_found'.
265 */
266 static int
267 cmdline_pum_create(
268 cmdline_info_T *ccline,
269 expand_T *xp,
270 char_u **files_found,
271 int num_files,
272 int showtail)
273 {
274 int i;
275 int columns;
276
277 // Add all the completion matches
278 compl_match_arraysize = num_files;
279 compl_match_array = ALLOC_MULT(pumitem_T, compl_match_arraysize);
280 for (i = 0; i < num_files; i++)
281 {
282 compl_match_array[i].pum_text = SHOW_FILE_TEXT(i);
283 compl_match_array[i].pum_info = NULL;
284 compl_match_array[i].pum_extra = NULL;
285 compl_match_array[i].pum_kind = NULL;
286 }
287
288 // Compute the popup menu starting column
289 compl_startcol = vim_strsize(ccline->cmdbuff) + 1;
290 columns = vim_strsize(xp->xp_pattern);
291 if (showtail)
292 {
293 columns += vim_strsize(sm_gettail(files_found[0]));
294 columns -= vim_strsize(files_found[0]);
295 }
296 if (columns >= compl_startcol)
297 compl_startcol = 0;
298 else
299 compl_startcol -= columns;
300
301 // no default selection
302 compl_selected = -1;
303
304 cmdline_pum_display();
305
306 return EXPAND_OK;
307 }
308
259 /* 309 /*
260 * Display the cmdline completion matches in a popup menu 310 * Display the cmdline completion matches in a popup menu
261 */ 311 */
262 void cmdline_pum_display(void) 312 void cmdline_pum_display(void)
263 { 313 {
264 pum_display(compl_match_array, compl_match_arraysize, compl_selected); 314 pum_display(compl_match_array, compl_match_arraysize, compl_selected);
265 } 315 }
266 316
317 /*
318 * Returns TRUE if the cmdline completion popup menu is being displayed.
319 */
267 int cmdline_pum_active(void) 320 int cmdline_pum_active(void)
268 { 321 {
269 return p_wmnu && pum_visible() && compl_match_array != NULL; 322 return p_wmnu && pum_visible() && compl_match_array != NULL;
270 } 323 }
271 324
272 /* 325 /*
273 * Remove the cmdline completion popup menu 326 * Remove the cmdline completion popup menu (if present), free the list of
327 * items and refresh the screen.
274 */ 328 */
275 void cmdline_pum_remove(void) 329 void cmdline_pum_remove(void)
276 { 330 {
277 pum_undisplay(); 331 pum_undisplay();
278 VIM_CLEAR(compl_match_array); 332 VIM_CLEAR(compl_match_array);
283 { 337 {
284 cmdline_pum_remove(); 338 cmdline_pum_remove();
285 wildmenu_cleanup(cclp); 339 wildmenu_cleanup(cclp);
286 } 340 }
287 341
342 /*
343 * Returns the starting column number to use for the cmdline completion popup
344 * menu.
345 */
288 int cmdline_compl_startcol(void) 346 int cmdline_compl_startcol(void)
289 { 347 {
290 return compl_startcol; 348 return compl_startcol;
291 } 349 }
292 #endif 350 #endif
579 */ 637 */
580 int 638 int
581 showmatches(expand_T *xp, int wildmenu UNUSED) 639 showmatches(expand_T *xp, int wildmenu UNUSED)
582 { 640 {
583 cmdline_info_T *ccline = get_cmdline_info(); 641 cmdline_info_T *ccline = get_cmdline_info();
584 #define L_SHOWFILE(m) (showtail ? sm_gettail(files_found[m]) : files_found[m])
585 int num_files; 642 int num_files;
586 char_u **files_found; 643 char_u **files_found;
587 int i, j, k; 644 int i, j, k;
588 int maxlen; 645 int maxlen;
589 int lines; 646 int lines;
610 showtail = cmd_showtail; 667 showtail = cmd_showtail;
611 } 668 }
612 669
613 #ifdef FEAT_WILDMENU 670 #ifdef FEAT_WILDMENU
614 if (wildmenu && vim_strchr(p_wop, WOP_PUM) != NULL) 671 if (wildmenu && vim_strchr(p_wop, WOP_PUM) != NULL)
615 { 672 // cmdline completion popup menu (with wildoptions=pum)
616 compl_match_arraysize = num_files; 673 return cmdline_pum_create(ccline, xp, files_found, num_files, showtail);
617 compl_match_array = ALLOC_MULT(pumitem_T, compl_match_arraysize);
618 for (i = 0; i < num_files; i++)
619 {
620 compl_match_array[i].pum_text = L_SHOWFILE(i);
621 compl_match_array[i].pum_info = NULL;
622 compl_match_array[i].pum_extra = NULL;
623 compl_match_array[i].pum_kind = NULL;
624 }
625 compl_startcol = vim_strsize(ccline->cmdbuff) + 1;
626 columns = vim_strsize(xp->xp_pattern);
627 if (showtail)
628 {
629 columns += vim_strsize(sm_gettail(files_found[0]));
630 columns -= vim_strsize(files_found[0]);
631 }
632 if (columns >= compl_startcol)
633 compl_startcol = 0;
634 else
635 compl_startcol -= columns;
636 compl_selected = -1;
637 cmdline_pum_display();
638 return EXPAND_OK;
639 }
640 #endif 674 #endif
641 675
642 #ifdef FEAT_WILDMENU 676 #ifdef FEAT_WILDMENU
643 if (!wildmenu) 677 if (!wildmenu)
644 { 678 {
672 { 706 {
673 home_replace(NULL, files_found[i], NameBuff, MAXPATHL, TRUE); 707 home_replace(NULL, files_found[i], NameBuff, MAXPATHL, TRUE);
674 j = vim_strsize(NameBuff); 708 j = vim_strsize(NameBuff);
675 } 709 }
676 else 710 else
677 j = vim_strsize(L_SHOWFILE(i)); 711 j = vim_strsize(SHOW_FILE_TEXT(i));
678 if (j > maxlen) 712 if (j > maxlen)
679 maxlen = j; 713 maxlen = j;
680 } 714 }
681 715
682 if (xp->xp_context == EXPAND_TAGS_LISTFILES) 716 if (xp->xp_context == EXPAND_TAGS_LISTFILES)
744 } 778 }
745 else 779 else
746 // Expansion was done here, file names are literal. 780 // Expansion was done here, file names are literal.
747 j = mch_isdir(files_found[k]); 781 j = mch_isdir(files_found[k]);
748 if (showtail) 782 if (showtail)
749 p = L_SHOWFILE(k); 783 p = SHOW_FILE_TEXT(k);
750 else 784 else
751 { 785 {
752 home_replace(NULL, files_found[k], NameBuff, MAXPATHL, 786 home_replace(NULL, files_found[k], NameBuff, MAXPATHL,
753 TRUE); 787 TRUE);
754 p = NameBuff; 788 p = NameBuff;
755 } 789 }
756 } 790 }
757 else 791 else
758 { 792 {
759 j = FALSE; 793 j = FALSE;
760 p = L_SHOWFILE(k); 794 p = SHOW_FILE_TEXT(k);
761 } 795 }
762 lastlen = msg_outtrans_attr(p, j ? attr : 0); 796 lastlen = msg_outtrans_attr(p, j ? attr : 0);
763 } 797 }
764 if (msg_col > 0) // when not wrapped around 798 if (msg_col > 0) // when not wrapped around
765 { 799 {
2724 int did_wild_list) 2758 int did_wild_list)
2725 { 2759 {
2726 int c = key; 2760 int c = key;
2727 2761
2728 #ifdef FEAT_WILDMENU 2762 #ifdef FEAT_WILDMENU
2729 if (p_wmnu && cmdline_pum_active()) 2763 if (cmdline_pum_active())
2730 { 2764 {
2731 // When the popup menu is used, Up/Down keys go to the previous and 2765 // When the popup menu is used for cmdline completion:
2732 // next items in the menu and Left/Right keys go up/down a directory. 2766 // Up : go to the previous item in the menu
2733 if (c == K_UP) 2767 // Down : go to the next item in the menu
2734 c = K_LEFT; 2768 // Left : go to the parent directory
2735 else if (c == K_DOWN) 2769 // Right: list the files in the selected directory
2736 c = K_RIGHT; 2770 switch (c)
2737 else if (c == K_LEFT) 2771 {
2738 c = K_UP; 2772 case K_UP: c = K_LEFT; break;
2739 else if (c == K_RIGHT) 2773 case K_DOWN: c = K_RIGHT; break;
2740 c = K_DOWN; 2774 case K_LEFT: c = K_UP; break;
2775 case K_RIGHT: c = K_DOWN; break;
2776 default: break;
2777 }
2741 } 2778 }
2742 #endif 2779 #endif
2743 2780
2744 if (did_wild_list && p_wmnu) 2781 if (did_wild_list && p_wmnu)
2745 { 2782 {