Mercurial > vim
comparison src/edit.c @ 659:d6a69271cb9a v7.0194
updated for version 7.0194
author | vimboss |
---|---|
date | Wed, 08 Feb 2006 09:20:24 +0000 |
parents | b112ec5c73f0 |
children | e93a99ef31d0 |
comparison
equal
deleted
inserted
replaced
658:903088c7a7c6 | 659:d6a69271cb9a |
---|---|
66 struct Completion | 66 struct Completion |
67 { | 67 { |
68 compl_T *cp_next; | 68 compl_T *cp_next; |
69 compl_T *cp_prev; | 69 compl_T *cp_prev; |
70 char_u *cp_str; /* matched text */ | 70 char_u *cp_str; /* matched text */ |
71 char_u *cp_fname; /* file containing the match */ | 71 char_u *cp_extra; /* extra menu text (allocated, can be NULL) */ |
72 char_u *cp_info; /* verbose info (can be NULL) */ | |
73 char_u cp_kind; /* kind of match, single letter, or NUL */ | |
74 char_u *cp_fname; /* file containing the match, allocated when | |
75 * cp_flags has FREE_FNAME */ | |
72 int cp_flags; /* ORIGINAL_TEXT, CONT_S_IPOS or FREE_FNAME */ | 76 int cp_flags; /* ORIGINAL_TEXT, CONT_S_IPOS or FREE_FNAME */ |
73 int cp_number; /* sequence number */ | 77 int cp_number; /* sequence number */ |
74 }; | 78 }; |
75 | 79 |
76 #define ORIGINAL_TEXT (1) /* the original text when the expansion begun */ | 80 #define ORIGINAL_TEXT (1) /* the original text when the expansion begun */ |
113 static int compl_cont_mode = 0; | 117 static int compl_cont_mode = 0; |
114 static expand_T compl_xp; | 118 static expand_T compl_xp; |
115 | 119 |
116 static void ins_ctrl_x __ARGS((void)); | 120 static void ins_ctrl_x __ARGS((void)); |
117 static int has_compl_option __ARGS((int dict_opt)); | 121 static int has_compl_option __ARGS((int dict_opt)); |
118 static void ins_compl_add_matches __ARGS((int num_matches, char_u **matches, int dir)); | 122 static void ins_compl_add_matches __ARGS((int num_matches, char_u **matches)); |
119 static int ins_compl_make_cyclic __ARGS((void)); | 123 static int ins_compl_make_cyclic __ARGS((void)); |
120 static void ins_compl_upd_pum __ARGS((void)); | 124 static void ins_compl_upd_pum __ARGS((void)); |
121 static void ins_compl_del_pum __ARGS((void)); | 125 static void ins_compl_del_pum __ARGS((void)); |
122 static int pum_wanted __ARGS((void)); | 126 static int pum_wanted __ARGS((void)); |
123 static int pum_two_or_more __ARGS((void)); | 127 static int pum_two_or_more __ARGS((void)); |
124 static void ins_compl_dictionaries __ARGS((char_u *dict, char_u *pat, int dir, int flags, int thesaurus)); | 128 static void ins_compl_dictionaries __ARGS((char_u *dict, char_u *pat, int flags, int thesaurus)); |
125 static void ins_compl_free __ARGS((void)); | 129 static void ins_compl_free __ARGS((void)); |
126 static void ins_compl_clear __ARGS((void)); | 130 static void ins_compl_clear __ARGS((void)); |
127 static int ins_compl_bs __ARGS((void)); | 131 static int ins_compl_bs __ARGS((void)); |
128 static void ins_compl_addleader __ARGS((int c)); | 132 static void ins_compl_addleader __ARGS((int c)); |
133 static void ins_compl_addfrommatch __ARGS((void)); | |
129 static int ins_compl_prep __ARGS((int c)); | 134 static int ins_compl_prep __ARGS((int c)); |
130 static buf_T *ins_compl_next_buf __ARGS((buf_T *buf, int flag)); | 135 static buf_T *ins_compl_next_buf __ARGS((buf_T *buf, int flag)); |
131 static int ins_compl_get_exp __ARGS((pos_T *ini, int dir)); | 136 static int ins_compl_get_exp __ARGS((pos_T *ini)); |
132 static void ins_compl_delete __ARGS((void)); | 137 static void ins_compl_delete __ARGS((void)); |
133 static void ins_compl_insert __ARGS((void)); | 138 static void ins_compl_insert __ARGS((void)); |
134 static int ins_compl_next __ARGS((int allow_get_expansion, int count)); | 139 static int ins_compl_next __ARGS((int allow_get_expansion, int count)); |
135 static int ins_compl_key2dir __ARGS((int c)); | 140 static int ins_compl_key2dir __ARGS((int c)); |
136 static int ins_compl_pum_key __ARGS((int c)); | 141 static int ins_compl_pum_key __ARGS((int c)); |
682 if (c == K_UP && pum_visible()) | 687 if (c == K_UP && pum_visible()) |
683 c = Ctrl_P; | 688 c = Ctrl_P; |
684 if (c == K_DOWN && pum_visible()) | 689 if (c == K_DOWN && pum_visible()) |
685 c = Ctrl_N; | 690 c = Ctrl_N; |
686 | 691 |
687 /* When using BS while the popup menu is wanted and still after the | 692 /* |
688 * character where completion started: Change the subset of matches to | 693 * Special handling of keys while the popup menu is visible or wanted |
689 * what matches "compl_leader". */ | 694 * and the cursor is still in the completed word. |
690 if (compl_started && pum_wanted() && curwin->w_cursor.col > compl_col) | 695 */ |
691 { | 696 if (compl_started && pum_wanted() && curwin->w_cursor.col >= compl_col) |
692 if ((c == K_BS || c == Ctrl_H) && ins_compl_bs()) | 697 { |
698 /* BS: Delete one character from "compl_leader". */ | |
699 if ((c == K_BS || c == Ctrl_H) | |
700 && curwin->w_cursor.col > compl_col && ins_compl_bs()) | |
693 continue; | 701 continue; |
694 | 702 |
695 /* Editing the word. */ | 703 /* When no match was selected or it was edited. */ |
696 if (!compl_used_match && vim_isprintc(c)) | 704 if (!compl_used_match) |
697 { | 705 { |
698 ins_compl_addleader(c); | 706 /* CTRL-L: Add one character from the current match to |
699 continue; | 707 * "compl_leader". */ |
708 if (c == Ctrl_L) | |
709 { | |
710 ins_compl_addfrommatch(); | |
711 continue; | |
712 } | |
713 | |
714 /* A printable character: Add it to "compl_leader". */ | |
715 if (vim_isprintc(c)) | |
716 { | |
717 ins_compl_addleader(c); | |
718 continue; | |
719 } | |
700 } | 720 } |
701 } | 721 } |
702 | 722 |
703 /* Prepare for or stop CTRL-X mode. This doesn't do completion, but | 723 /* Prepare for or stop CTRL-X mode. This doesn't do completion, but |
704 * it does fix up the text when finishing completion. */ | 724 * it does fix up the text when finishing completion. */ |
1920 EMSG(_(e_internal)); | 1940 EMSG(_(e_internal)); |
1921 return FALSE; | 1941 return FALSE; |
1922 } | 1942 } |
1923 | 1943 |
1924 /* | 1944 /* |
1925 * This is like ins_compl_add(), but if ic and inf are set, then the | 1945 * This is like ins_compl_add(), but if 'ic' and 'inf' are set, then the |
1926 * case of the originally typed text is used, and the case of the completed | 1946 * case of the originally typed text is used, and the case of the completed |
1927 * text is infered, ie this tries to work out what case you probably wanted | 1947 * text is infered, ie this tries to work out what case you probably wanted |
1928 * the rest of the word to be in -- webb | 1948 * the rest of the word to be in -- webb |
1929 * TODO: make this work for multi-byte characters. | 1949 * TODO: make this work for multi-byte characters. |
1930 */ | 1950 */ |
1983 } | 2003 } |
1984 | 2004 |
1985 /* Copy the original case of the part we typed */ | 2005 /* Copy the original case of the part we typed */ |
1986 STRNCPY(IObuff, compl_orig_text, compl_length); | 2006 STRNCPY(IObuff, compl_orig_text, compl_length); |
1987 | 2007 |
1988 return ins_compl_add(IObuff, len, fname, dir, flags); | 2008 return ins_compl_add(IObuff, len, fname, NULL, dir, flags); |
1989 } | 2009 } |
1990 return ins_compl_add(str, len, fname, dir, flags); | 2010 return ins_compl_add(str, len, fname, NULL, dir, flags); |
1991 } | 2011 } |
1992 | 2012 |
1993 /* | 2013 /* |
1994 * Add a match to the list of matches. | 2014 * Add a match to the list of matches. |
1995 * If the given string is already in the list of completions, then return | 2015 * If the given string is already in the list of completions, then return |
2000 * If the given string is already in the list of completions, then return | 2020 * If the given string is already in the list of completions, then return |
2001 * NOTDONE, otherwise add it to the list and return OK. If there is an error, | 2021 * NOTDONE, otherwise add it to the list and return OK. If there is an error, |
2002 * maybe because alloc() returns NULL, then FAIL is returned -- webb. | 2022 * maybe because alloc() returns NULL, then FAIL is returned -- webb. |
2003 */ | 2023 */ |
2004 int | 2024 int |
2005 ins_compl_add(str, len, fname, dir, flags) | 2025 ins_compl_add(str, len, fname, extra, cdir, flags) |
2006 char_u *str; | 2026 char_u *str; |
2007 int len; | 2027 int len; |
2008 char_u *fname; | 2028 char_u *fname; |
2009 int dir; | 2029 char_u *extra; /* extra text for popup menu or NULL */ |
2030 int cdir; | |
2010 int flags; | 2031 int flags; |
2011 { | 2032 { |
2012 compl_T *match; | 2033 compl_T *match; |
2034 int dir = (cdir == 0 ? compl_direction : cdir); | |
2013 | 2035 |
2014 ui_breakcheck(); | 2036 ui_breakcheck(); |
2015 if (got_int) | 2037 if (got_int) |
2016 return FAIL; | 2038 return FAIL; |
2017 if (len < 0) | 2039 if (len < 0) |
2038 | 2060 |
2039 /* | 2061 /* |
2040 * Allocate a new match structure. | 2062 * Allocate a new match structure. |
2041 * Copy the values to the new match structure. | 2063 * Copy the values to the new match structure. |
2042 */ | 2064 */ |
2043 match = (compl_T *)alloc((unsigned)sizeof(compl_T)); | 2065 match = (compl_T *)alloc_clear((unsigned)sizeof(compl_T)); |
2044 if (match == NULL) | 2066 if (match == NULL) |
2045 return FAIL; | 2067 return FAIL; |
2046 match->cp_number = -1; | 2068 match->cp_number = -1; |
2047 if (flags & ORIGINAL_TEXT) | 2069 if (flags & ORIGINAL_TEXT) |
2048 { | 2070 { |
2052 else if ((match->cp_str = vim_strnsave(str, len)) == NULL) | 2074 else if ((match->cp_str = vim_strnsave(str, len)) == NULL) |
2053 { | 2075 { |
2054 vim_free(match); | 2076 vim_free(match); |
2055 return FAIL; | 2077 return FAIL; |
2056 } | 2078 } |
2079 | |
2057 /* match-fname is: | 2080 /* match-fname is: |
2058 * - compl_curr_match->cp_fname if it is a string equal to fname. | 2081 * - compl_curr_match->cp_fname if it is a string equal to fname. |
2059 * - a copy of fname, FREE_FNAME is set to free later THE allocated mem. | 2082 * - a copy of fname, FREE_FNAME is set to free later THE allocated mem. |
2060 * - NULL otherwise. --Acevedo */ | 2083 * - NULL otherwise. --Acevedo */ |
2061 if (fname && compl_curr_match && compl_curr_match->cp_fname | 2084 if (fname != NULL |
2062 && STRCMP(fname, compl_curr_match->cp_fname) == 0) | 2085 && compl_curr_match |
2086 && compl_curr_match->cp_fname != NULL | |
2087 && STRCMP(fname, compl_curr_match->cp_fname) == 0) | |
2063 match->cp_fname = compl_curr_match->cp_fname; | 2088 match->cp_fname = compl_curr_match->cp_fname; |
2064 else if (fname && (match->cp_fname = vim_strsave(fname)) != NULL) | 2089 else if (fname != NULL) |
2090 { | |
2091 match->cp_fname = vim_strsave(fname); | |
2065 flags |= FREE_FNAME; | 2092 flags |= FREE_FNAME; |
2093 } | |
2066 else | 2094 else |
2067 match->cp_fname = NULL; | 2095 match->cp_fname = NULL; |
2068 match->cp_flags = flags; | 2096 match->cp_flags = flags; |
2097 if (extra != NULL) | |
2098 match->cp_extra = vim_strsave(extra); | |
2069 | 2099 |
2070 /* | 2100 /* |
2071 * Link the new match structure in the list of matches. | 2101 * Link the new match structure in the list of matches. |
2072 */ | 2102 */ |
2073 if (compl_first_match == NULL) | 2103 if (compl_first_match == NULL) |
2096 /* | 2126 /* |
2097 * Add an array of matches to the list of matches. | 2127 * Add an array of matches to the list of matches. |
2098 * Frees matches[]. | 2128 * Frees matches[]. |
2099 */ | 2129 */ |
2100 static void | 2130 static void |
2101 ins_compl_add_matches(num_matches, matches, dir) | 2131 ins_compl_add_matches(num_matches, matches) |
2102 int num_matches; | 2132 int num_matches; |
2103 char_u **matches; | 2133 char_u **matches; |
2104 int dir; | |
2105 { | 2134 { |
2106 int i; | 2135 int i; |
2107 int add_r = OK; | 2136 int add_r = OK; |
2108 int ldir = dir; | 2137 int dir = compl_direction; |
2109 | 2138 |
2110 for (i = 0; i < num_matches && add_r != FAIL; i++) | 2139 for (i = 0; i < num_matches && add_r != FAIL; i++) |
2111 if ((add_r = ins_compl_add(matches[i], -1, NULL, ldir, 0)) == OK) | 2140 if ((add_r = ins_compl_add(matches[i], -1, NULL, NULL, dir, 0)) == OK) |
2112 /* if dir was BACKWARD then honor it just once */ | 2141 /* if dir was BACKWARD then honor it just once */ |
2113 ldir = FORWARD; | 2142 dir = FORWARD; |
2114 FreeWild(num_matches, matches); | 2143 FreeWild(num_matches, matches); |
2115 } | 2144 } |
2116 | 2145 |
2117 /* Make the completion list cyclic. | 2146 /* Make the completion list cyclic. |
2118 * Return the number of matches (excluding the original). | 2147 * Return the number of matches (excluding the original). |
2141 return count; | 2170 return count; |
2142 } | 2171 } |
2143 | 2172 |
2144 /* "compl_match_array" points the currently displayed list of entries in the | 2173 /* "compl_match_array" points the currently displayed list of entries in the |
2145 * popup menu. It is NULL when there is no popup menu. */ | 2174 * popup menu. It is NULL when there is no popup menu. */ |
2146 static char_u **compl_match_array = NULL; | 2175 static pumitem_T *compl_match_array = NULL; |
2147 static int compl_match_arraysize; | 2176 static int compl_match_arraysize; |
2148 | 2177 |
2149 /* | 2178 /* |
2150 * Update the screen and when there is any scrolling remove the popup menu. | 2179 * Update the screen and when there is any scrolling remove the popup menu. |
2151 */ | 2180 */ |
2221 return (i >= 2); | 2250 return (i >= 2); |
2222 } | 2251 } |
2223 | 2252 |
2224 /* | 2253 /* |
2225 * Show the popup menu for the list of matches. | 2254 * Show the popup menu for the list of matches. |
2255 * Also adjusts "compl_shown_match" to an entry that is actually displayed. | |
2226 */ | 2256 */ |
2227 void | 2257 void |
2228 ins_compl_show_pum() | 2258 ins_compl_show_pum() |
2229 { | 2259 { |
2230 compl_T *compl; | 2260 compl_T *compl; |
2261 compl_T *shown_compl = NULL; | |
2262 int did_find_shown_match = FALSE; | |
2263 int shown_match_ok = FALSE; | |
2231 int i; | 2264 int i; |
2232 int cur = -1; | 2265 int cur = -1; |
2233 colnr_T col; | 2266 colnr_T col; |
2234 int lead_len = 0; | 2267 int lead_len = 0; |
2235 | 2268 |
2254 ++compl_match_arraysize; | 2287 ++compl_match_arraysize; |
2255 compl = compl->cp_next; | 2288 compl = compl->cp_next; |
2256 } while (compl != NULL && compl != compl_first_match); | 2289 } while (compl != NULL && compl != compl_first_match); |
2257 if (compl_match_arraysize == 0) | 2290 if (compl_match_arraysize == 0) |
2258 return; | 2291 return; |
2259 compl_match_array = (char_u **)alloc((unsigned)(sizeof(char_u **) | 2292 compl_match_array = (pumitem_T *)alloc_clear( |
2293 (unsigned)(sizeof(pumitem_T) | |
2260 * compl_match_arraysize)); | 2294 * compl_match_arraysize)); |
2261 if (compl_match_array != NULL) | 2295 if (compl_match_array != NULL) |
2262 { | 2296 { |
2263 i = 0; | 2297 i = 0; |
2264 compl = compl_first_match; | 2298 compl = compl_first_match; |
2267 if ((compl->cp_flags & ORIGINAL_TEXT) == 0 | 2301 if ((compl->cp_flags & ORIGINAL_TEXT) == 0 |
2268 && (compl_leader == NULL | 2302 && (compl_leader == NULL |
2269 || STRNCMP(compl->cp_str, compl_leader, | 2303 || STRNCMP(compl->cp_str, compl_leader, |
2270 lead_len) == 0)) | 2304 lead_len) == 0)) |
2271 { | 2305 { |
2272 if (compl == compl_shown_match) | 2306 if (!shown_match_ok) |
2307 { | |
2308 if (compl == compl_shown_match || did_find_shown_match) | |
2309 { | |
2310 /* This item is the shown match or this is the | |
2311 * first displayed item after the shown match. */ | |
2312 compl_shown_match = compl; | |
2313 did_find_shown_match = TRUE; | |
2314 shown_match_ok = TRUE; | |
2315 } | |
2316 else | |
2317 /* Remember this displayed match for when the | |
2318 * shown match is just below it. */ | |
2319 shown_compl = compl; | |
2273 cur = i; | 2320 cur = i; |
2274 compl_match_array[i++] = compl->cp_str; | 2321 } |
2322 compl_match_array[i].pum_text = compl->cp_str; | |
2323 if (compl->cp_extra != NULL) | |
2324 compl_match_array[i++].pum_extra = compl->cp_extra; | |
2325 else | |
2326 compl_match_array[i++].pum_extra = compl->cp_fname; | |
2327 } | |
2328 | |
2329 if (compl == compl_shown_match) | |
2330 { | |
2331 did_find_shown_match = TRUE; | |
2332 if (!shown_match_ok && shown_compl != NULL) | |
2333 { | |
2334 /* The shown match isn't displayed, set it to the | |
2335 * previously displayed match. */ | |
2336 compl_shown_match = shown_compl; | |
2337 shown_match_ok = TRUE; | |
2338 } | |
2275 } | 2339 } |
2276 compl = compl->cp_next; | 2340 compl = compl->cp_next; |
2277 } while (compl != NULL && compl != compl_first_match); | 2341 } while (compl != NULL && compl != compl_first_match); |
2342 | |
2343 if (!shown_match_ok) /* no displayed match at all */ | |
2344 cur = -1; | |
2278 } | 2345 } |
2279 } | 2346 } |
2280 else | 2347 else |
2281 { | 2348 { |
2282 /* popup menu already exists, only need to find the current item.*/ | 2349 /* popup menu already exists, only need to find the current item.*/ |
2283 for (i = 0; i < compl_match_arraysize; ++i) | 2350 for (i = 0; i < compl_match_arraysize; ++i) |
2284 if (compl_match_array[i] == compl_shown_match->cp_str) | 2351 if (compl_match_array[i].pum_text == compl_shown_match->cp_str) |
2285 break; | 2352 break; |
2286 cur = i; | 2353 cur = i; |
2287 } | 2354 } |
2288 | 2355 |
2289 if (compl_match_array != NULL) | 2356 if (compl_match_array != NULL) |
2307 /* | 2374 /* |
2308 * Add any identifiers that match the given pattern to the list of | 2375 * Add any identifiers that match the given pattern to the list of |
2309 * completions. | 2376 * completions. |
2310 */ | 2377 */ |
2311 static void | 2378 static void |
2312 ins_compl_dictionaries(dict, pat, dir, flags, thesaurus) | 2379 ins_compl_dictionaries(dict, pat, flags, thesaurus) |
2313 char_u *dict; | 2380 char_u *dict; |
2314 char_u *pat; | 2381 char_u *pat; |
2315 int dir; | |
2316 int flags; | 2382 int flags; |
2317 int thesaurus; | 2383 int thesaurus; |
2318 { | 2384 { |
2319 char_u *ptr; | 2385 char_u *ptr; |
2320 char_u *buf; | 2386 char_u *buf; |
2323 int add_r; | 2389 int add_r; |
2324 char_u **files; | 2390 char_u **files; |
2325 int count; | 2391 int count; |
2326 int i; | 2392 int i; |
2327 int save_p_scs; | 2393 int save_p_scs; |
2394 int dir = compl_direction; | |
2328 | 2395 |
2329 buf = alloc(LSIZE); | 2396 buf = alloc(LSIZE); |
2330 /* If 'infercase' is set, don't use 'smartcase' here */ | 2397 /* If 'infercase' is set, don't use 'smartcase' here */ |
2331 save_p_scs = p_scs; | 2398 save_p_scs = p_scs; |
2332 if (curbuf->b_p_inf) | 2399 if (curbuf->b_p_inf) |
2519 compl_curr_match = compl_curr_match->cp_next; | 2586 compl_curr_match = compl_curr_match->cp_next; |
2520 vim_free(match->cp_str); | 2587 vim_free(match->cp_str); |
2521 /* several entries may use the same fname, free it just once. */ | 2588 /* several entries may use the same fname, free it just once. */ |
2522 if (match->cp_flags & FREE_FNAME) | 2589 if (match->cp_flags & FREE_FNAME) |
2523 vim_free(match->cp_fname); | 2590 vim_free(match->cp_fname); |
2591 vim_free(match->cp_extra); | |
2524 vim_free(match); | 2592 vim_free(match); |
2525 } while (compl_curr_match != NULL && compl_curr_match != compl_first_match); | 2593 } while (compl_curr_match != NULL && compl_curr_match != compl_first_match); |
2526 compl_first_match = compl_curr_match = NULL; | 2594 compl_first_match = compl_curr_match = NULL; |
2527 } | 2595 } |
2528 | 2596 |
2539 save_sm = -1; | 2607 save_sm = -1; |
2540 edit_submode_extra = NULL; | 2608 edit_submode_extra = NULL; |
2541 } | 2609 } |
2542 | 2610 |
2543 /* | 2611 /* |
2544 * Delete one character before the cursor and make a subset of the matches | 2612 * Delete one character before the cursor and show the subset of the matches |
2545 * that match now. | 2613 * that match the word that is now before the cursor. |
2546 * Returns TRUE if the work is done and another char to be got from the user. | 2614 * Returns TRUE if the work is done and another char to be got from the user. |
2547 */ | 2615 */ |
2548 static int | 2616 static int |
2549 ins_compl_bs() | 2617 ins_compl_bs() |
2550 { | 2618 { |
2625 /* Show the popup menu with a different set of matches. */ | 2693 /* Show the popup menu with a different set of matches. */ |
2626 ins_compl_del_pum(); | 2694 ins_compl_del_pum(); |
2627 ins_compl_show_pum(); | 2695 ins_compl_show_pum(); |
2628 compl_used_match = FALSE; | 2696 compl_used_match = FALSE; |
2629 } | 2697 } |
2698 } | |
2699 | |
2700 /* | |
2701 * Append one character to the match leader. May reduce the number of | |
2702 * matches. | |
2703 */ | |
2704 static void | |
2705 ins_compl_addfrommatch() | |
2706 { | |
2707 char_u *p; | |
2708 int len = curwin->w_cursor.col - compl_col; | |
2709 int c; | |
2710 | |
2711 p = compl_shown_match->cp_str; | |
2712 if (STRLEN(p) <= len) /* the match is too short */ | |
2713 return; | |
2714 p += len; | |
2715 #ifdef FEAT_MBYTE | |
2716 c = mb_ptr2char(p); | |
2717 #else | |
2718 c = *p; | |
2719 #endif | |
2720 ins_compl_addleader(c); | |
2630 } | 2721 } |
2631 | 2722 |
2632 /* | 2723 /* |
2633 * Prepare for Insert mode completion, or stop it. | 2724 * Prepare for Insert mode completion, or stop it. |
2634 * Called just after typing a character in Insert mode. | 2725 * Called just after typing a character in Insert mode. |
2917 ; | 3008 ; |
2918 return buf; | 3009 return buf; |
2919 } | 3010 } |
2920 | 3011 |
2921 #ifdef FEAT_COMPL_FUNC | 3012 #ifdef FEAT_COMPL_FUNC |
2922 static int expand_by_function __ARGS((int type, char_u *base, char_u ***matches)); | 3013 static void expand_by_function __ARGS((int type, char_u *base)); |
2923 | 3014 |
2924 /* | 3015 /* |
2925 * Execute user defined complete function 'completefunc' or 'omnifunc', and | 3016 * Execute user defined complete function 'completefunc' or 'omnifunc', and |
2926 * get matches in "matches". | 3017 * get matches in "matches". |
2927 * Return value is number of matches. | 3018 * Return value is number of matches. |
2928 */ | 3019 */ |
2929 static int | 3020 static void |
2930 expand_by_function(type, base, matches) | 3021 expand_by_function(type, base) |
2931 int type; /* CTRL_X_OMNI or CTRL_X_FUNCTION */ | 3022 int type; /* CTRL_X_OMNI or CTRL_X_FUNCTION */ |
2932 char_u *base; | 3023 char_u *base; |
2933 char_u ***matches; | |
2934 { | 3024 { |
2935 list_T *matchlist; | 3025 list_T *matchlist; |
2936 char_u *args[2]; | 3026 char_u *args[2]; |
2937 listitem_T *li; | 3027 listitem_T *li; |
2938 garray_T ga; | |
2939 char_u *p; | 3028 char_u *p; |
2940 char_u *funcname; | 3029 char_u *funcname; |
2941 pos_T pos; | 3030 pos_T pos; |
3031 int dir = compl_direction; | |
3032 char_u *x; | |
2942 | 3033 |
2943 funcname = (type == CTRL_X_FUNCTION) ? curbuf->b_p_cfu : curbuf->b_p_ofu; | 3034 funcname = (type == CTRL_X_FUNCTION) ? curbuf->b_p_cfu : curbuf->b_p_ofu; |
2944 if (*funcname == NUL) | 3035 if (*funcname == NUL) |
2945 return 0; | 3036 return; |
2946 | 3037 |
2947 /* Call 'completefunc' to obtain the list of matches. */ | 3038 /* Call 'completefunc' to obtain the list of matches. */ |
2948 args[0] = (char_u *)"0"; | 3039 args[0] = (char_u *)"0"; |
2949 args[1] = base; | 3040 args[1] = base; |
2950 | 3041 |
2951 pos = curwin->w_cursor; | 3042 pos = curwin->w_cursor; |
2952 matchlist = call_func_retlist(funcname, 2, args, FALSE); | 3043 matchlist = call_func_retlist(funcname, 2, args, FALSE); |
2953 curwin->w_cursor = pos; /* restore the cursor position */ | 3044 curwin->w_cursor = pos; /* restore the cursor position */ |
2954 if (matchlist == NULL) | 3045 if (matchlist == NULL) |
2955 return 0; | 3046 return; |
2956 | 3047 |
2957 /* Go through the List with matches and put them in an array. */ | 3048 /* Go through the List with matches and add each of them. */ |
2958 ga_init2(&ga, (int)sizeof(char_u *), 8); | |
2959 for (li = matchlist->lv_first; li != NULL; li = li->li_next) | 3049 for (li = matchlist->lv_first; li != NULL; li = li->li_next) |
2960 { | 3050 { |
2961 p = get_tv_string_chk(&li->li_tv); | 3051 if (li->li_tv.v_type == VAR_DICT && li->li_tv.vval.v_dict != NULL) |
3052 { | |
3053 p = get_dict_string(li->li_tv.vval.v_dict, (char_u *)"word", FALSE); | |
3054 x = get_dict_string(li->li_tv.vval.v_dict, (char_u *)"menu", FALSE); | |
3055 } | |
3056 else | |
3057 { | |
3058 p = get_tv_string_chk(&li->li_tv); | |
3059 x = NULL; | |
3060 } | |
2962 if (p != NULL && *p != NUL) | 3061 if (p != NULL && *p != NUL) |
2963 { | 3062 { |
2964 if (ga_grow(&ga, 1) == FAIL) | 3063 if (ins_compl_add(p, -1, NULL, x, dir, 0) == OK) |
2965 break; | 3064 /* if dir was BACKWARD then honor it just once */ |
2966 ((char_u **)ga.ga_data)[ga.ga_len] = vim_strsave(p); | 3065 dir = FORWARD; |
2967 ++ga.ga_len; | |
2968 } | 3066 } |
2969 else if (did_emsg) | 3067 else if (did_emsg) |
2970 break; | 3068 break; |
2971 } | 3069 } |
2972 | 3070 |
2973 list_unref(matchlist); | 3071 list_unref(matchlist); |
2974 *matches = (char_u **)ga.ga_data; | |
2975 return ga.ga_len; | |
2976 } | 3072 } |
2977 #endif /* FEAT_COMPL_FUNC */ | 3073 #endif /* FEAT_COMPL_FUNC */ |
2978 | 3074 |
2979 /* | 3075 /* |
2980 * Get the next expansion(s), using "compl_pattern". | 3076 * Get the next expansion(s), using "compl_pattern". |
2981 * The search starts at position "ini" in curbuf and in the direction dir. | 3077 * The search starts at position "ini" in curbuf and in the direction |
3078 * compl_direction. | |
2982 * When "compl_started" is FALSE start at that position, otherwise | 3079 * When "compl_started" is FALSE start at that position, otherwise |
2983 * continue where we stopped searching before. | 3080 * continue where we stopped searching before. |
2984 * This may return before finding all the matches. | 3081 * This may return before finding all the matches. |
2985 * Return the total number of matches or -1 if still unknown -- Acevedo | 3082 * Return the total number of matches or -1 if still unknown -- Acevedo |
2986 */ | 3083 */ |
2987 static int | 3084 static int |
2988 ins_compl_get_exp(ini, dir) | 3085 ins_compl_get_exp(ini) |
2989 pos_T *ini; | 3086 pos_T *ini; |
2990 int dir; | |
2991 { | 3087 { |
2992 static pos_T first_match_pos; | 3088 static pos_T first_match_pos; |
2993 static pos_T last_match_pos; | 3089 static pos_T last_match_pos; |
2994 static char_u *e_cpt = (char_u *)""; /* curr. entry in 'complete' */ | 3090 static char_u *e_cpt = (char_u *)""; /* curr. entry in 'complete' */ |
2995 static int found_all = FALSE; /* Found all matches of a | 3091 static int found_all = FALSE; /* Found all matches of a |
3021 ? (char_u *)"." : curbuf->b_p_cpt; | 3117 ? (char_u *)"." : curbuf->b_p_cpt; |
3022 last_match_pos = first_match_pos = *ini; | 3118 last_match_pos = first_match_pos = *ini; |
3023 } | 3119 } |
3024 | 3120 |
3025 old_match = compl_curr_match; /* remember the last current match */ | 3121 old_match = compl_curr_match; /* remember the last current match */ |
3026 pos = (dir == FORWARD) ? &last_match_pos : &first_match_pos; | 3122 pos = (compl_direction == FORWARD) ? &last_match_pos : &first_match_pos; |
3027 /* For ^N/^P loop over all the flags/windows/buffers in 'complete' */ | 3123 /* For ^N/^P loop over all the flags/windows/buffers in 'complete' */ |
3028 for (;;) | 3124 for (;;) |
3029 { | 3125 { |
3030 found_new_match = FAIL; | 3126 found_new_match = FAIL; |
3031 | 3127 |
3124 case -1: | 3220 case -1: |
3125 break; | 3221 break; |
3126 #ifdef FEAT_FIND_ID | 3222 #ifdef FEAT_FIND_ID |
3127 case CTRL_X_PATH_PATTERNS: | 3223 case CTRL_X_PATH_PATTERNS: |
3128 case CTRL_X_PATH_DEFINES: | 3224 case CTRL_X_PATH_DEFINES: |
3129 find_pattern_in_path(compl_pattern, dir, | 3225 find_pattern_in_path(compl_pattern, compl_direction, |
3130 (int)STRLEN(compl_pattern), FALSE, FALSE, | 3226 (int)STRLEN(compl_pattern), FALSE, FALSE, |
3131 (type == CTRL_X_PATH_DEFINES | 3227 (type == CTRL_X_PATH_DEFINES |
3132 && !(compl_cont_status & CONT_SOL)) | 3228 && !(compl_cont_status & CONT_SOL)) |
3133 ? FIND_DEFINE : FIND_ANY, 1L, ACTION_EXPAND, | 3229 ? FIND_DEFINE : FIND_ANY, 1L, ACTION_EXPAND, |
3134 (linenr_T)1, (linenr_T)MAXLNUM); | 3230 (linenr_T)1, (linenr_T)MAXLNUM); |
3144 ? p_tsr | 3240 ? p_tsr |
3145 : curbuf->b_p_tsr) | 3241 : curbuf->b_p_tsr) |
3146 : (*curbuf->b_p_dict == NUL | 3242 : (*curbuf->b_p_dict == NUL |
3147 ? p_dict | 3243 ? p_dict |
3148 : curbuf->b_p_dict)), | 3244 : curbuf->b_p_dict)), |
3149 compl_pattern, dir, | 3245 compl_pattern, |
3150 dict ? dict_f : 0, type == CTRL_X_THESAURUS); | 3246 dict ? dict_f : 0, type == CTRL_X_THESAURUS); |
3151 dict = NULL; | 3247 dict = NULL; |
3152 break; | 3248 break; |
3153 | 3249 |
3154 case CTRL_X_TAGS: | 3250 case CTRL_X_TAGS: |
3161 if (find_tags(compl_pattern, &num_matches, &matches, | 3257 if (find_tags(compl_pattern, &num_matches, &matches, |
3162 TAG_REGEXP | TAG_NAMES | TAG_NOIC | | 3258 TAG_REGEXP | TAG_NAMES | TAG_NOIC | |
3163 TAG_INS_COMP | (ctrl_x_mode ? TAG_VERBOSE : 0), | 3259 TAG_INS_COMP | (ctrl_x_mode ? TAG_VERBOSE : 0), |
3164 TAG_MANY, curbuf->b_ffname) == OK && num_matches > 0) | 3260 TAG_MANY, curbuf->b_ffname) == OK && num_matches > 0) |
3165 { | 3261 { |
3166 ins_compl_add_matches(num_matches, matches, dir); | 3262 ins_compl_add_matches(num_matches, matches); |
3167 } | 3263 } |
3168 p_ic = save_p_ic; | 3264 p_ic = save_p_ic; |
3169 break; | 3265 break; |
3170 | 3266 |
3171 case CTRL_X_FILES: | 3267 case CTRL_X_FILES: |
3173 EW_FILE|EW_DIR|EW_ADDSLASH|EW_SILENT) == OK) | 3269 EW_FILE|EW_DIR|EW_ADDSLASH|EW_SILENT) == OK) |
3174 { | 3270 { |
3175 | 3271 |
3176 /* May change home directory back to "~". */ | 3272 /* May change home directory back to "~". */ |
3177 tilde_replace(compl_pattern, num_matches, matches); | 3273 tilde_replace(compl_pattern, num_matches, matches); |
3178 ins_compl_add_matches(num_matches, matches, dir); | 3274 ins_compl_add_matches(num_matches, matches); |
3179 } | 3275 } |
3180 break; | 3276 break; |
3181 | 3277 |
3182 case CTRL_X_CMDLINE: | 3278 case CTRL_X_CMDLINE: |
3183 if (expand_cmdline(&compl_xp, compl_pattern, | 3279 if (expand_cmdline(&compl_xp, compl_pattern, |
3184 (int)STRLEN(compl_pattern), | 3280 (int)STRLEN(compl_pattern), |
3185 &num_matches, &matches) == EXPAND_OK) | 3281 &num_matches, &matches) == EXPAND_OK) |
3186 ins_compl_add_matches(num_matches, matches, dir); | 3282 ins_compl_add_matches(num_matches, matches); |
3187 break; | 3283 break; |
3188 | 3284 |
3189 #ifdef FEAT_COMPL_FUNC | 3285 #ifdef FEAT_COMPL_FUNC |
3190 case CTRL_X_FUNCTION: | 3286 case CTRL_X_FUNCTION: |
3191 case CTRL_X_OMNI: | 3287 case CTRL_X_OMNI: |
3192 num_matches = expand_by_function(type, compl_pattern, &matches); | 3288 expand_by_function(type, compl_pattern); |
3193 if (num_matches > 0) | |
3194 ins_compl_add_matches(num_matches, matches, dir); | |
3195 break; | 3289 break; |
3196 #endif | 3290 #endif |
3197 | 3291 |
3198 case CTRL_X_SPELL: | 3292 case CTRL_X_SPELL: |
3199 #ifdef FEAT_SYN_HL | 3293 #ifdef FEAT_SYN_HL |
3200 num_matches = expand_spelling(first_match_pos.lnum, | 3294 num_matches = expand_spelling(first_match_pos.lnum, |
3201 first_match_pos.col, compl_pattern, &matches); | 3295 first_match_pos.col, compl_pattern, &matches); |
3202 if (num_matches > 0) | 3296 if (num_matches > 0) |
3203 ins_compl_add_matches(num_matches, matches, dir); | 3297 ins_compl_add_matches(num_matches, matches); |
3204 #endif | 3298 #endif |
3205 break; | 3299 break; |
3206 | 3300 |
3207 default: /* normal ^P/^N and ^X^L */ | 3301 default: /* normal ^P/^N and ^X^L */ |
3208 /* | 3302 /* |
3228 /* ctrl_x_mode == CTRL_X_WHOLE_LINE || word-wise search that | 3322 /* ctrl_x_mode == CTRL_X_WHOLE_LINE || word-wise search that |
3229 * has added a word that was at the beginning of the line */ | 3323 * has added a word that was at the beginning of the line */ |
3230 if ( ctrl_x_mode == CTRL_X_WHOLE_LINE | 3324 if ( ctrl_x_mode == CTRL_X_WHOLE_LINE |
3231 || (compl_cont_status & CONT_SOL)) | 3325 || (compl_cont_status & CONT_SOL)) |
3232 found_new_match = search_for_exact_line(ins_buf, pos, | 3326 found_new_match = search_for_exact_line(ins_buf, pos, |
3233 dir, compl_pattern); | 3327 compl_direction, compl_pattern); |
3234 else | 3328 else |
3235 found_new_match = searchit(NULL, ins_buf, pos, dir, | 3329 found_new_match = searchit(NULL, ins_buf, pos, |
3330 compl_direction, | |
3236 compl_pattern, 1L, SEARCH_KEEP + SEARCH_NFMSG, | 3331 compl_pattern, 1L, SEARCH_KEEP + SEARCH_NFMSG, |
3237 RE_LAST); | 3332 RE_LAST); |
3238 if (!compl_started) | 3333 if (!compl_started) |
3239 { | 3334 { |
3240 /* set compl_started even on fail */ | 3335 /* set compl_started even on fail */ |
3333 continue; | 3428 continue; |
3334 } | 3429 } |
3335 } | 3430 } |
3336 if (ins_compl_add_infercase(ptr, len, | 3431 if (ins_compl_add_infercase(ptr, len, |
3337 ins_buf == curbuf ? NULL : ins_buf->b_sfname, | 3432 ins_buf == curbuf ? NULL : ins_buf->b_sfname, |
3338 dir, flags) != NOTDONE) | 3433 0, flags) != NOTDONE) |
3339 { | 3434 { |
3340 found_new_match = OK; | 3435 found_new_match = OK; |
3341 break; | 3436 break; |
3342 } | 3437 } |
3343 } | 3438 } |
3386 i = ins_compl_make_cyclic(); | 3481 i = ins_compl_make_cyclic(); |
3387 | 3482 |
3388 /* If several matches were added (FORWARD) or the search failed and has | 3483 /* If several matches were added (FORWARD) or the search failed and has |
3389 * just been made cyclic then we have to move compl_curr_match to the next | 3484 * just been made cyclic then we have to move compl_curr_match to the next |
3390 * or previous entry (if any) -- Acevedo */ | 3485 * or previous entry (if any) -- Acevedo */ |
3391 compl_curr_match = dir == FORWARD ? old_match->cp_next : old_match->cp_prev; | 3486 compl_curr_match = compl_direction == FORWARD ? old_match->cp_next : old_match->cp_prev; |
3392 if (compl_curr_match == NULL) | 3487 if (compl_curr_match == NULL) |
3393 compl_curr_match = old_match; | 3488 compl_curr_match = old_match; |
3394 return i; | 3489 return i; |
3395 } | 3490 } |
3396 | 3491 |
3474 { | 3569 { |
3475 compl_pending = TRUE; | 3570 compl_pending = TRUE; |
3476 if (!allow_get_expansion) | 3571 if (!allow_get_expansion) |
3477 return -1; | 3572 return -1; |
3478 | 3573 |
3479 num_matches = ins_compl_get_exp(&compl_startpos, compl_direction); | 3574 num_matches = ins_compl_get_exp(&compl_startpos); |
3480 if (compl_pending && compl_direction == compl_shows_dir) | 3575 if (compl_pending && compl_direction == compl_shows_dir) |
3481 compl_shown_match = compl_curr_match; | 3576 compl_shown_match = compl_curr_match; |
3482 found_end = FALSE; | 3577 found_end = FALSE; |
3483 } | 3578 } |
3484 if ((compl_shown_match->cp_flags & ORIGINAL_TEXT) == 0 | 3579 if ((compl_shown_match->cp_flags & ORIGINAL_TEXT) == 0 |
3990 /* Always add completion for the original text. Note that | 4085 /* Always add completion for the original text. Note that |
3991 * "compl_orig_text" itself (not a copy) is added, it will be freed | 4086 * "compl_orig_text" itself (not a copy) is added, it will be freed |
3992 * when the list of matches is freed. */ | 4087 * when the list of matches is freed. */ |
3993 compl_orig_text = vim_strnsave(line + compl_col, compl_length); | 4088 compl_orig_text = vim_strnsave(line + compl_col, compl_length); |
3994 if (compl_orig_text == NULL || ins_compl_add(compl_orig_text, | 4089 if (compl_orig_text == NULL || ins_compl_add(compl_orig_text, |
3995 -1, NULL, 0, ORIGINAL_TEXT) != OK) | 4090 -1, NULL, NULL, 0, ORIGINAL_TEXT) != OK) |
3996 { | 4091 { |
3997 vim_free(compl_pattern); | 4092 vim_free(compl_pattern); |
3998 compl_pattern = NULL; | 4093 compl_pattern = NULL; |
3999 vim_free(compl_orig_text); | 4094 vim_free(compl_orig_text); |
4000 compl_orig_text = NULL; | 4095 compl_orig_text = NULL; |