Mercurial > vim
comparison src/insexpand.c @ 16142:570a296aa0b4 v8.1.1076
patch 8.1.1076: file for Insert mode is much too big
commit https://github.com/vim/vim/commit/7591bb39d58ece38a5fef984a08ea9012616c1f9
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Mar 30 13:53:47 2019 +0100
patch 8.1.1076: file for Insert mode is much too big
Problem: File for Insert mode is much too big.
Solution: Split off the code for Insert completion. (Yegappan Lakshmanan,
closes #4044)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sat, 30 Mar 2019 14:00:07 +0100 |
parents | |
children | cd5c83115ec6 |
comparison
equal
deleted
inserted
replaced
16141:8abbc25d5d23 | 16142:570a296aa0b4 |
---|---|
1 /* vi:set ts=8 sts=4 sw=4 noet: | |
2 * | |
3 * VIM - Vi IMproved by Bram Moolenaar | |
4 * | |
5 * Do ":help uganda" in Vim to read copying and usage conditions. | |
6 * Do ":help credits" in Vim to see a list of people who contributed. | |
7 * See README.txt for an overview of the Vim source code. | |
8 */ | |
9 | |
10 /* | |
11 * insexpand.c: functions for Insert mode completion | |
12 */ | |
13 | |
14 #include "vim.h" | |
15 | |
16 #ifdef FEAT_INS_EXPAND | |
17 /* | |
18 * Definitions used for CTRL-X submode. | |
19 * Note: If you change CTRL-X submode, you must also maintain ctrl_x_msgs[] and | |
20 * ctrl_x_mode_names[] below. | |
21 */ | |
22 # define CTRL_X_WANT_IDENT 0x100 | |
23 | |
24 # define CTRL_X_NORMAL 0 /* CTRL-N CTRL-P completion, default */ | |
25 # define CTRL_X_NOT_DEFINED_YET 1 | |
26 # define CTRL_X_SCROLL 2 | |
27 # define CTRL_X_WHOLE_LINE 3 | |
28 # define CTRL_X_FILES 4 | |
29 # define CTRL_X_TAGS (5 + CTRL_X_WANT_IDENT) | |
30 # define CTRL_X_PATH_PATTERNS (6 + CTRL_X_WANT_IDENT) | |
31 # define CTRL_X_PATH_DEFINES (7 + CTRL_X_WANT_IDENT) | |
32 # define CTRL_X_FINISHED 8 | |
33 # define CTRL_X_DICTIONARY (9 + CTRL_X_WANT_IDENT) | |
34 # define CTRL_X_THESAURUS (10 + CTRL_X_WANT_IDENT) | |
35 # define CTRL_X_CMDLINE 11 | |
36 # define CTRL_X_FUNCTION 12 | |
37 # define CTRL_X_OMNI 13 | |
38 # define CTRL_X_SPELL 14 | |
39 # define CTRL_X_LOCAL_MSG 15 /* only used in "ctrl_x_msgs" */ | |
40 # define CTRL_X_EVAL 16 /* for builtin function complete() */ | |
41 | |
42 # define CTRL_X_MSG(i) ctrl_x_msgs[(i) & ~CTRL_X_WANT_IDENT] | |
43 | |
44 // Message for CTRL-X mode, index is ctrl_x_mode. | |
45 static char *ctrl_x_msgs[] = | |
46 { | |
47 N_(" Keyword completion (^N^P)"), // CTRL_X_NORMAL, ^P/^N compl. | |
48 N_(" ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"), | |
49 NULL, // CTRL_X_SCROLL: depends on state | |
50 N_(" Whole line completion (^L^N^P)"), | |
51 N_(" File name completion (^F^N^P)"), | |
52 N_(" Tag completion (^]^N^P)"), | |
53 N_(" Path pattern completion (^N^P)"), | |
54 N_(" Definition completion (^D^N^P)"), | |
55 NULL, // CTRL_X_FINISHED | |
56 N_(" Dictionary completion (^K^N^P)"), | |
57 N_(" Thesaurus completion (^T^N^P)"), | |
58 N_(" Command-line completion (^V^N^P)"), | |
59 N_(" User defined completion (^U^N^P)"), | |
60 N_(" Omni completion (^O^N^P)"), | |
61 N_(" Spelling suggestion (s^N^P)"), | |
62 N_(" Keyword Local completion (^N^P)"), | |
63 NULL, // CTRL_X_EVAL doesn't use msg. | |
64 }; | |
65 | |
66 static char *ctrl_x_mode_names[] = { | |
67 "keyword", | |
68 "ctrl_x", | |
69 "unknown", // CTRL_X_SCROLL | |
70 "whole_line", | |
71 "files", | |
72 "tags", | |
73 "path_patterns", | |
74 "path_defines", | |
75 "unknown", // CTRL_X_FINISHED | |
76 "dictionary", | |
77 "thesaurus", | |
78 "cmdline", | |
79 "function", | |
80 "omni", | |
81 "spell", | |
82 NULL, // CTRL_X_LOCAL_MSG only used in "ctrl_x_msgs" | |
83 "eval" | |
84 }; | |
85 | |
86 /* | |
87 * Array indexes used for cp_text[]. | |
88 */ | |
89 #define CPT_ABBR 0 // "abbr" | |
90 #define CPT_MENU 1 // "menu" | |
91 #define CPT_KIND 2 // "kind" | |
92 #define CPT_INFO 3 // "info" | |
93 #define CPT_USER_DATA 4 // "user data" | |
94 #define CPT_COUNT 5 // Number of entries | |
95 | |
96 /* | |
97 * Structure used to store one match for insert completion. | |
98 */ | |
99 typedef struct compl_S compl_T; | |
100 struct compl_S | |
101 { | |
102 compl_T *cp_next; | |
103 compl_T *cp_prev; | |
104 char_u *cp_str; /* matched text */ | |
105 char cp_icase; /* TRUE or FALSE: ignore case */ | |
106 char_u *(cp_text[CPT_COUNT]); /* text for the menu */ | |
107 char_u *cp_fname; /* file containing the match, allocated when | |
108 * cp_flags has FREE_FNAME */ | |
109 int cp_flags; /* ORIGINAL_TEXT, CONT_S_IPOS or FREE_FNAME */ | |
110 int cp_number; /* sequence number */ | |
111 }; | |
112 | |
113 # define ORIGINAL_TEXT (1) /* the original text when the expansion begun */ | |
114 # define FREE_FNAME (2) | |
115 | |
116 static char e_hitend[] = N_("Hit end of paragraph"); | |
117 # ifdef FEAT_COMPL_FUNC | |
118 static char e_complwin[] = N_("E839: Completion function changed window"); | |
119 static char e_compldel[] = N_("E840: Completion function deleted text"); | |
120 # endif | |
121 | |
122 /* | |
123 * All the current matches are stored in a list. | |
124 * "compl_first_match" points to the start of the list. | |
125 * "compl_curr_match" points to the currently selected entry. | |
126 * "compl_shown_match" is different from compl_curr_match during | |
127 * ins_compl_get_exp(). | |
128 */ | |
129 static compl_T *compl_first_match = NULL; | |
130 static compl_T *compl_curr_match = NULL; | |
131 static compl_T *compl_shown_match = NULL; | |
132 static compl_T *compl_old_match = NULL; | |
133 | |
134 // After using a cursor key <Enter> selects a match in the popup menu, | |
135 // otherwise it inserts a line break. | |
136 static int compl_enter_selects = FALSE; | |
137 | |
138 // When "compl_leader" is not NULL only matches that start with this string | |
139 // are used. | |
140 static char_u *compl_leader = NULL; | |
141 | |
142 static int compl_get_longest = FALSE; // put longest common string | |
143 // in compl_leader | |
144 | |
145 static int compl_no_insert = FALSE; // FALSE: select & insert | |
146 // TRUE: noinsert | |
147 static int compl_no_select = FALSE; // FALSE: select & insert | |
148 // TRUE: noselect | |
149 | |
150 // Selected one of the matches. When FALSE the match was edited or using the | |
151 // longest common string. | |
152 static int compl_used_match; | |
153 | |
154 // didn't finish finding completions. | |
155 static int compl_was_interrupted = FALSE; | |
156 | |
157 // Set when character typed while looking for matches and it means we should | |
158 // stop looking for matches. | |
159 static int compl_interrupted = FALSE; | |
160 | |
161 static int compl_restarting = FALSE; // don't insert match | |
162 | |
163 // When the first completion is done "compl_started" is set. When it's | |
164 // FALSE the word to be completed must be located. | |
165 static int compl_started = FALSE; | |
166 | |
167 // Which Ctrl-X mode are we in? | |
168 static int ctrl_x_mode = CTRL_X_NORMAL; | |
169 | |
170 static int compl_matches = 0; | |
171 static char_u *compl_pattern = NULL; | |
172 static int compl_direction = FORWARD; | |
173 static int compl_shows_dir = FORWARD; | |
174 static int compl_pending = 0; // > 1 for postponed CTRL-N | |
175 static pos_T compl_startpos; | |
176 static colnr_T compl_col = 0; // column where the text starts | |
177 // that is being completed | |
178 static char_u *compl_orig_text = NULL; // text as it was before | |
179 // completion started | |
180 static int compl_cont_mode = 0; | |
181 static expand_T compl_xp; | |
182 | |
183 static int compl_opt_refresh_always = FALSE; | |
184 static int compl_opt_suppress_empty = FALSE; | |
185 | |
186 static int ins_compl_add(char_u *str, int len, int icase, char_u *fname, char_u **cptext, int cdir, int flags, int adup); | |
187 static void ins_compl_longest_match(compl_T *match); | |
188 static void ins_compl_del_pum(void); | |
189 static void ins_compl_files(int count, char_u **files, int thesaurus, int flags, regmatch_T *regmatch, char_u *buf, int *dir); | |
190 static char_u *find_line_end(char_u *ptr); | |
191 static void ins_compl_free(void); | |
192 static char_u *ins_compl_mode(void); | |
193 static int ins_compl_need_restart(void); | |
194 static void ins_compl_new_leader(void); | |
195 static int ins_compl_len(void); | |
196 static void ins_compl_restart(void); | |
197 static void ins_compl_set_original_text(char_u *str); | |
198 static void ins_compl_fixRedoBufForLeader(char_u *ptr_arg); | |
199 # if defined(FEAT_COMPL_FUNC) || defined(FEAT_EVAL) | |
200 static void ins_compl_add_list(list_T *list); | |
201 static void ins_compl_add_dict(dict_T *dict); | |
202 # endif | |
203 static int ins_compl_key2dir(int c); | |
204 static int ins_compl_pum_key(int c); | |
205 static int ins_compl_key2count(int c); | |
206 static void show_pum(int prev_w_wrow, int prev_w_leftcol); | |
207 static unsigned quote_meta(char_u *dest, char_u *str, int len); | |
208 #endif // FEAT_INS_EXPAND | |
209 | |
210 #ifdef FEAT_SPELL | |
211 static void spell_back_to_badword(void); | |
212 static int spell_bad_len = 0; // length of located bad word | |
213 #endif | |
214 | |
215 #if defined(FEAT_INS_EXPAND) || defined(PROTO) | |
216 /* | |
217 * CTRL-X pressed in Insert mode. | |
218 */ | |
219 void | |
220 ins_ctrl_x(void) | |
221 { | |
222 // CTRL-X after CTRL-X CTRL-V doesn't do anything, so that CTRL-X | |
223 // CTRL-V works like CTRL-N | |
224 if (ctrl_x_mode != CTRL_X_CMDLINE) | |
225 { | |
226 // if the next ^X<> won't ADD nothing, then reset | |
227 // compl_cont_status | |
228 if (compl_cont_status & CONT_N_ADDS) | |
229 compl_cont_status |= CONT_INTRPT; | |
230 else | |
231 compl_cont_status = 0; | |
232 // We're not sure which CTRL-X mode it will be yet | |
233 ctrl_x_mode = CTRL_X_NOT_DEFINED_YET; | |
234 edit_submode = (char_u *)_(CTRL_X_MSG(ctrl_x_mode)); | |
235 edit_submode_pre = NULL; | |
236 showmode(); | |
237 } | |
238 } | |
239 | |
240 /* | |
241 * Functions to check the current CTRL-X mode. | |
242 */ | |
243 int ctrl_x_mode_none(void) { return ctrl_x_mode == 0; } | |
244 int ctrl_x_mode_normal(void) { return ctrl_x_mode == CTRL_X_NORMAL; } | |
245 int ctrl_x_mode_scroll(void) { return ctrl_x_mode == CTRL_X_SCROLL; } | |
246 int ctrl_x_mode_whole_line(void) { return ctrl_x_mode == CTRL_X_WHOLE_LINE; } | |
247 int ctrl_x_mode_files(void) { return ctrl_x_mode == CTRL_X_FILES; } | |
248 int ctrl_x_mode_tags(void) { return ctrl_x_mode == CTRL_X_TAGS; } | |
249 int ctrl_x_mode_path_patterns(void) { | |
250 return ctrl_x_mode == CTRL_X_PATH_PATTERNS; } | |
251 int ctrl_x_mode_path_defines(void) { | |
252 return ctrl_x_mode == CTRL_X_PATH_DEFINES; } | |
253 int ctrl_x_mode_dictionary(void) { return ctrl_x_mode == CTRL_X_DICTIONARY; } | |
254 int ctrl_x_mode_thesaurus(void) { return ctrl_x_mode == CTRL_X_THESAURUS; } | |
255 int ctrl_x_mode_cmdline(void) { return ctrl_x_mode == CTRL_X_CMDLINE; } | |
256 int ctrl_x_mode_function(void) { return ctrl_x_mode == CTRL_X_FUNCTION; } | |
257 int ctrl_x_mode_omni(void) { return ctrl_x_mode == CTRL_X_OMNI; } | |
258 int ctrl_x_mode_spell(void) { return ctrl_x_mode == CTRL_X_SPELL; } | |
259 int ctrl_x_mode_line_or_eval(void) { | |
260 return ctrl_x_mode == CTRL_X_WHOLE_LINE || ctrl_x_mode == CTRL_X_EVAL; } | |
261 | |
262 /* | |
263 * Whether other than default completion has been selected. | |
264 */ | |
265 int | |
266 ctrl_x_mode_not_default(void) | |
267 { | |
268 return ctrl_x_mode != CTRL_X_NORMAL; | |
269 } | |
270 | |
271 /* | |
272 * Whether CTRL-X was typed without a following character. | |
273 */ | |
274 int | |
275 ctrl_x_mode_not_defined_yet(void) | |
276 { | |
277 return ctrl_x_mode == CTRL_X_NOT_DEFINED_YET; | |
278 } | |
279 | |
280 /* | |
281 * Return TRUE if the 'dict' or 'tsr' option can be used. | |
282 */ | |
283 int | |
284 has_compl_option(int dict_opt) | |
285 { | |
286 if (dict_opt ? (*curbuf->b_p_dict == NUL && *p_dict == NUL | |
287 # ifdef FEAT_SPELL | |
288 && !curwin->w_p_spell | |
289 # endif | |
290 ) | |
291 : (*curbuf->b_p_tsr == NUL && *p_tsr == NUL)) | |
292 { | |
293 ctrl_x_mode = CTRL_X_NORMAL; | |
294 edit_submode = NULL; | |
295 msg_attr(dict_opt ? _("'dictionary' option is empty") | |
296 : _("'thesaurus' option is empty"), | |
297 HL_ATTR(HLF_E)); | |
298 if (emsg_silent == 0) | |
299 { | |
300 vim_beep(BO_COMPL); | |
301 setcursor(); | |
302 out_flush(); | |
303 #ifdef FEAT_EVAL | |
304 if (!get_vim_var_nr(VV_TESTING)) | |
305 #endif | |
306 ui_delay(2000L, FALSE); | |
307 } | |
308 return FALSE; | |
309 } | |
310 return TRUE; | |
311 } | |
312 | |
313 /* | |
314 * Is the character 'c' a valid key to go to or keep us in CTRL-X mode? | |
315 * This depends on the current mode. | |
316 */ | |
317 int | |
318 vim_is_ctrl_x_key(int c) | |
319 { | |
320 // Always allow ^R - let its results then be checked | |
321 if (c == Ctrl_R) | |
322 return TRUE; | |
323 | |
324 // Accept <PageUp> and <PageDown> if the popup menu is visible. | |
325 if (ins_compl_pum_key(c)) | |
326 return TRUE; | |
327 | |
328 switch (ctrl_x_mode) | |
329 { | |
330 case 0: // Not in any CTRL-X mode | |
331 return (c == Ctrl_N || c == Ctrl_P || c == Ctrl_X); | |
332 case CTRL_X_NOT_DEFINED_YET: | |
333 return ( c == Ctrl_X || c == Ctrl_Y || c == Ctrl_E | |
334 || c == Ctrl_L || c == Ctrl_F || c == Ctrl_RSB | |
335 || c == Ctrl_I || c == Ctrl_D || c == Ctrl_P | |
336 || c == Ctrl_N || c == Ctrl_T || c == Ctrl_V | |
337 || c == Ctrl_Q || c == Ctrl_U || c == Ctrl_O | |
338 || c == Ctrl_S || c == Ctrl_K || c == 's'); | |
339 case CTRL_X_SCROLL: | |
340 return (c == Ctrl_Y || c == Ctrl_E); | |
341 case CTRL_X_WHOLE_LINE: | |
342 return (c == Ctrl_L || c == Ctrl_P || c == Ctrl_N); | |
343 case CTRL_X_FILES: | |
344 return (c == Ctrl_F || c == Ctrl_P || c == Ctrl_N); | |
345 case CTRL_X_DICTIONARY: | |
346 return (c == Ctrl_K || c == Ctrl_P || c == Ctrl_N); | |
347 case CTRL_X_THESAURUS: | |
348 return (c == Ctrl_T || c == Ctrl_P || c == Ctrl_N); | |
349 case CTRL_X_TAGS: | |
350 return (c == Ctrl_RSB || c == Ctrl_P || c == Ctrl_N); | |
351 #ifdef FEAT_FIND_ID | |
352 case CTRL_X_PATH_PATTERNS: | |
353 return (c == Ctrl_P || c == Ctrl_N); | |
354 case CTRL_X_PATH_DEFINES: | |
355 return (c == Ctrl_D || c == Ctrl_P || c == Ctrl_N); | |
356 #endif | |
357 case CTRL_X_CMDLINE: | |
358 return (c == Ctrl_V || c == Ctrl_Q || c == Ctrl_P || c == Ctrl_N | |
359 || c == Ctrl_X); | |
360 #ifdef FEAT_COMPL_FUNC | |
361 case CTRL_X_FUNCTION: | |
362 return (c == Ctrl_U || c == Ctrl_P || c == Ctrl_N); | |
363 case CTRL_X_OMNI: | |
364 return (c == Ctrl_O || c == Ctrl_P || c == Ctrl_N); | |
365 #endif | |
366 case CTRL_X_SPELL: | |
367 return (c == Ctrl_S || c == Ctrl_P || c == Ctrl_N); | |
368 case CTRL_X_EVAL: | |
369 return (c == Ctrl_P || c == Ctrl_N); | |
370 } | |
371 internal_error("vim_is_ctrl_x_key()"); | |
372 return FALSE; | |
373 } | |
374 | |
375 /* | |
376 * Return TRUE when character "c" is part of the item currently being | |
377 * completed. Used to decide whether to abandon complete mode when the menu | |
378 * is visible. | |
379 */ | |
380 int | |
381 ins_compl_accept_char(int c) | |
382 { | |
383 if (ctrl_x_mode & CTRL_X_WANT_IDENT) | |
384 // When expanding an identifier only accept identifier chars. | |
385 return vim_isIDc(c); | |
386 | |
387 switch (ctrl_x_mode) | |
388 { | |
389 case CTRL_X_FILES: | |
390 // When expanding file name only accept file name chars. But not | |
391 // path separators, so that "proto/<Tab>" expands files in | |
392 // "proto", not "proto/" as a whole | |
393 return vim_isfilec(c) && !vim_ispathsep(c); | |
394 | |
395 case CTRL_X_CMDLINE: | |
396 case CTRL_X_OMNI: | |
397 // Command line and Omni completion can work with just about any | |
398 // printable character, but do stop at white space. | |
399 return vim_isprintc(c) && !VIM_ISWHITE(c); | |
400 | |
401 case CTRL_X_WHOLE_LINE: | |
402 // For while line completion a space can be part of the line. | |
403 return vim_isprintc(c); | |
404 } | |
405 return vim_iswordc(c); | |
406 } | |
407 | |
408 /* | |
409 * This is like ins_compl_add(), but if 'ic' and 'inf' are set, then the | |
410 * case of the originally typed text is used, and the case of the completed | |
411 * text is inferred, ie this tries to work out what case you probably wanted | |
412 * the rest of the word to be in -- webb | |
413 */ | |
414 int | |
415 ins_compl_add_infercase( | |
416 char_u *str, | |
417 int len, | |
418 int icase, | |
419 char_u *fname, | |
420 int dir, | |
421 int flags) | |
422 { | |
423 char_u *p; | |
424 int i, c; | |
425 int actual_len; // Take multi-byte characters | |
426 int actual_compl_length; // into account. | |
427 int min_len; | |
428 int *wca; // Wide character array. | |
429 int has_lower = FALSE; | |
430 int was_letter = FALSE; | |
431 | |
432 if (p_ic && curbuf->b_p_inf && len > 0) | |
433 { | |
434 // Infer case of completed part. | |
435 | |
436 // Find actual length of completion. | |
437 if (has_mbyte) | |
438 { | |
439 p = str; | |
440 actual_len = 0; | |
441 while (*p != NUL) | |
442 { | |
443 MB_PTR_ADV(p); | |
444 ++actual_len; | |
445 } | |
446 } | |
447 else | |
448 actual_len = len; | |
449 | |
450 // Find actual length of original text. | |
451 if (has_mbyte) | |
452 { | |
453 p = compl_orig_text; | |
454 actual_compl_length = 0; | |
455 while (*p != NUL) | |
456 { | |
457 MB_PTR_ADV(p); | |
458 ++actual_compl_length; | |
459 } | |
460 } | |
461 else | |
462 actual_compl_length = compl_length; | |
463 | |
464 // "actual_len" may be smaller than "actual_compl_length" when using | |
465 // thesaurus, only use the minimum when comparing. | |
466 min_len = actual_len < actual_compl_length | |
467 ? actual_len : actual_compl_length; | |
468 | |
469 // Allocate wide character array for the completion and fill it. | |
470 wca = (int *)alloc((unsigned)(actual_len * sizeof(int))); | |
471 if (wca != NULL) | |
472 { | |
473 p = str; | |
474 for (i = 0; i < actual_len; ++i) | |
475 if (has_mbyte) | |
476 wca[i] = mb_ptr2char_adv(&p); | |
477 else | |
478 wca[i] = *(p++); | |
479 | |
480 // Rule 1: Were any chars converted to lower? | |
481 p = compl_orig_text; | |
482 for (i = 0; i < min_len; ++i) | |
483 { | |
484 if (has_mbyte) | |
485 c = mb_ptr2char_adv(&p); | |
486 else | |
487 c = *(p++); | |
488 if (MB_ISLOWER(c)) | |
489 { | |
490 has_lower = TRUE; | |
491 if (MB_ISUPPER(wca[i])) | |
492 { | |
493 // Rule 1 is satisfied. | |
494 for (i = actual_compl_length; i < actual_len; ++i) | |
495 wca[i] = MB_TOLOWER(wca[i]); | |
496 break; | |
497 } | |
498 } | |
499 } | |
500 | |
501 // Rule 2: No lower case, 2nd consecutive letter converted to | |
502 // upper case. | |
503 if (!has_lower) | |
504 { | |
505 p = compl_orig_text; | |
506 for (i = 0; i < min_len; ++i) | |
507 { | |
508 if (has_mbyte) | |
509 c = mb_ptr2char_adv(&p); | |
510 else | |
511 c = *(p++); | |
512 if (was_letter && MB_ISUPPER(c) && MB_ISLOWER(wca[i])) | |
513 { | |
514 // Rule 2 is satisfied. | |
515 for (i = actual_compl_length; i < actual_len; ++i) | |
516 wca[i] = MB_TOUPPER(wca[i]); | |
517 break; | |
518 } | |
519 was_letter = MB_ISLOWER(c) || MB_ISUPPER(c); | |
520 } | |
521 } | |
522 | |
523 // Copy the original case of the part we typed. | |
524 p = compl_orig_text; | |
525 for (i = 0; i < min_len; ++i) | |
526 { | |
527 if (has_mbyte) | |
528 c = mb_ptr2char_adv(&p); | |
529 else | |
530 c = *(p++); | |
531 if (MB_ISLOWER(c)) | |
532 wca[i] = MB_TOLOWER(wca[i]); | |
533 else if (MB_ISUPPER(c)) | |
534 wca[i] = MB_TOUPPER(wca[i]); | |
535 } | |
536 | |
537 // Generate encoding specific output from wide character array. | |
538 // Multi-byte characters can occupy up to five bytes more than | |
539 // ASCII characters, and we also need one byte for NUL, so stay | |
540 // six bytes away from the edge of IObuff. | |
541 p = IObuff; | |
542 i = 0; | |
543 while (i < actual_len && (p - IObuff + 6) < IOSIZE) | |
544 if (has_mbyte) | |
545 p += (*mb_char2bytes)(wca[i++], p); | |
546 else | |
547 *(p++) = wca[i++]; | |
548 *p = NUL; | |
549 | |
550 vim_free(wca); | |
551 } | |
552 | |
553 return ins_compl_add(IObuff, len, icase, fname, NULL, dir, | |
554 flags, FALSE); | |
555 } | |
556 return ins_compl_add(str, len, icase, fname, NULL, dir, flags, FALSE); | |
557 } | |
558 | |
559 /* | |
560 * Add a match to the list of matches. | |
561 * If the given string is already in the list of completions, then return | |
562 * NOTDONE, otherwise add it to the list and return OK. If there is an error, | |
563 * maybe because alloc() returns NULL, then FAIL is returned. | |
564 */ | |
565 static int | |
566 ins_compl_add( | |
567 char_u *str, | |
568 int len, | |
569 int icase, | |
570 char_u *fname, | |
571 char_u **cptext, // extra text for popup menu or NULL | |
572 int cdir, | |
573 int flags, | |
574 int adup) // accept duplicate match | |
575 { | |
576 compl_T *match; | |
577 int dir = (cdir == 0 ? compl_direction : cdir); | |
578 | |
579 ui_breakcheck(); | |
580 if (got_int) | |
581 return FAIL; | |
582 if (len < 0) | |
583 len = (int)STRLEN(str); | |
584 | |
585 // If the same match is already present, don't add it. | |
586 if (compl_first_match != NULL && !adup) | |
587 { | |
588 match = compl_first_match; | |
589 do | |
590 { | |
591 if ( !(match->cp_flags & ORIGINAL_TEXT) | |
592 && STRNCMP(match->cp_str, str, len) == 0 | |
593 && match->cp_str[len] == NUL) | |
594 return NOTDONE; | |
595 match = match->cp_next; | |
596 } while (match != NULL && match != compl_first_match); | |
597 } | |
598 | |
599 // Remove any popup menu before changing the list of matches. | |
600 ins_compl_del_pum(); | |
601 | |
602 // Allocate a new match structure. | |
603 // Copy the values to the new match structure. | |
604 match = (compl_T *)alloc_clear((unsigned)sizeof(compl_T)); | |
605 if (match == NULL) | |
606 return FAIL; | |
607 match->cp_number = -1; | |
608 if (flags & ORIGINAL_TEXT) | |
609 match->cp_number = 0; | |
610 if ((match->cp_str = vim_strnsave(str, len)) == NULL) | |
611 { | |
612 vim_free(match); | |
613 return FAIL; | |
614 } | |
615 match->cp_icase = icase; | |
616 | |
617 // match-fname is: | |
618 // - compl_curr_match->cp_fname if it is a string equal to fname. | |
619 // - a copy of fname, FREE_FNAME is set to free later THE allocated mem. | |
620 // - NULL otherwise. --Acevedo | |
621 if (fname != NULL | |
622 && compl_curr_match != NULL | |
623 && compl_curr_match->cp_fname != NULL | |
624 && STRCMP(fname, compl_curr_match->cp_fname) == 0) | |
625 match->cp_fname = compl_curr_match->cp_fname; | |
626 else if (fname != NULL) | |
627 { | |
628 match->cp_fname = vim_strsave(fname); | |
629 flags |= FREE_FNAME; | |
630 } | |
631 else | |
632 match->cp_fname = NULL; | |
633 match->cp_flags = flags; | |
634 | |
635 if (cptext != NULL) | |
636 { | |
637 int i; | |
638 | |
639 for (i = 0; i < CPT_COUNT; ++i) | |
640 if (cptext[i] != NULL && *cptext[i] != NUL) | |
641 match->cp_text[i] = vim_strsave(cptext[i]); | |
642 } | |
643 | |
644 // Link the new match structure in the list of matches. | |
645 if (compl_first_match == NULL) | |
646 match->cp_next = match->cp_prev = NULL; | |
647 else if (dir == FORWARD) | |
648 { | |
649 match->cp_next = compl_curr_match->cp_next; | |
650 match->cp_prev = compl_curr_match; | |
651 } | |
652 else // BACKWARD | |
653 { | |
654 match->cp_next = compl_curr_match; | |
655 match->cp_prev = compl_curr_match->cp_prev; | |
656 } | |
657 if (match->cp_next) | |
658 match->cp_next->cp_prev = match; | |
659 if (match->cp_prev) | |
660 match->cp_prev->cp_next = match; | |
661 else // if there's nothing before, it is the first match | |
662 compl_first_match = match; | |
663 compl_curr_match = match; | |
664 | |
665 // Find the longest common string if still doing that. | |
666 if (compl_get_longest && (flags & ORIGINAL_TEXT) == 0) | |
667 ins_compl_longest_match(match); | |
668 | |
669 return OK; | |
670 } | |
671 | |
672 /* | |
673 * Return TRUE if "str[len]" matches with match->cp_str, considering | |
674 * match->cp_icase. | |
675 */ | |
676 static int | |
677 ins_compl_equal(compl_T *match, char_u *str, int len) | |
678 { | |
679 if (match->cp_icase) | |
680 return STRNICMP(match->cp_str, str, (size_t)len) == 0; | |
681 return STRNCMP(match->cp_str, str, (size_t)len) == 0; | |
682 } | |
683 | |
684 /* | |
685 * Reduce the longest common string for match "match". | |
686 */ | |
687 static void | |
688 ins_compl_longest_match(compl_T *match) | |
689 { | |
690 char_u *p, *s; | |
691 int c1, c2; | |
692 int had_match; | |
693 | |
694 if (compl_leader == NULL) | |
695 { | |
696 // First match, use it as a whole. | |
697 compl_leader = vim_strsave(match->cp_str); | |
698 if (compl_leader != NULL) | |
699 { | |
700 had_match = (curwin->w_cursor.col > compl_col); | |
701 ins_compl_delete(); | |
702 ins_bytes(compl_leader + ins_compl_len()); | |
703 ins_redraw(FALSE); | |
704 | |
705 // When the match isn't there (to avoid matching itself) remove it | |
706 // again after redrawing. | |
707 if (!had_match) | |
708 ins_compl_delete(); | |
709 compl_used_match = FALSE; | |
710 } | |
711 } | |
712 else | |
713 { | |
714 // Reduce the text if this match differs from compl_leader. | |
715 p = compl_leader; | |
716 s = match->cp_str; | |
717 while (*p != NUL) | |
718 { | |
719 if (has_mbyte) | |
720 { | |
721 c1 = mb_ptr2char(p); | |
722 c2 = mb_ptr2char(s); | |
723 } | |
724 else | |
725 { | |
726 c1 = *p; | |
727 c2 = *s; | |
728 } | |
729 if (match->cp_icase ? (MB_TOLOWER(c1) != MB_TOLOWER(c2)) | |
730 : (c1 != c2)) | |
731 break; | |
732 if (has_mbyte) | |
733 { | |
734 MB_PTR_ADV(p); | |
735 MB_PTR_ADV(s); | |
736 } | |
737 else | |
738 { | |
739 ++p; | |
740 ++s; | |
741 } | |
742 } | |
743 | |
744 if (*p != NUL) | |
745 { | |
746 // Leader was shortened, need to change the inserted text. | |
747 *p = NUL; | |
748 had_match = (curwin->w_cursor.col > compl_col); | |
749 ins_compl_delete(); | |
750 ins_bytes(compl_leader + ins_compl_len()); | |
751 ins_redraw(FALSE); | |
752 | |
753 // When the match isn't there (to avoid matching itself) remove it | |
754 // again after redrawing. | |
755 if (!had_match) | |
756 ins_compl_delete(); | |
757 } | |
758 | |
759 compl_used_match = FALSE; | |
760 } | |
761 } | |
762 | |
763 /* | |
764 * Add an array of matches to the list of matches. | |
765 * Frees matches[]. | |
766 */ | |
767 static void | |
768 ins_compl_add_matches( | |
769 int num_matches, | |
770 char_u **matches, | |
771 int icase) | |
772 { | |
773 int i; | |
774 int add_r = OK; | |
775 int dir = compl_direction; | |
776 | |
777 for (i = 0; i < num_matches && add_r != FAIL; i++) | |
778 if ((add_r = ins_compl_add(matches[i], -1, icase, | |
779 NULL, NULL, dir, 0, FALSE)) == OK) | |
780 // if dir was BACKWARD then honor it just once | |
781 dir = FORWARD; | |
782 FreeWild(num_matches, matches); | |
783 } | |
784 | |
785 /* | |
786 * Make the completion list cyclic. | |
787 * Return the number of matches (excluding the original). | |
788 */ | |
789 static int | |
790 ins_compl_make_cyclic(void) | |
791 { | |
792 compl_T *match; | |
793 int count = 0; | |
794 | |
795 if (compl_first_match != NULL) | |
796 { | |
797 // Find the end of the list. | |
798 match = compl_first_match; | |
799 // there's always an entry for the compl_orig_text, it doesn't count. | |
800 while (match->cp_next != NULL && match->cp_next != compl_first_match) | |
801 { | |
802 match = match->cp_next; | |
803 ++count; | |
804 } | |
805 match->cp_next = compl_first_match; | |
806 compl_first_match->cp_prev = match; | |
807 } | |
808 return count; | |
809 } | |
810 | |
811 /* | |
812 * Return whether there currently is a shown match. | |
813 */ | |
814 int | |
815 ins_compl_has_shown_match(void) | |
816 { | |
817 return compl_shown_match == NULL | |
818 || compl_shown_match != compl_shown_match->cp_next; | |
819 } | |
820 | |
821 /* | |
822 * Return whether the shown match is long enough. | |
823 */ | |
824 int | |
825 ins_compl_long_shown_match(void) | |
826 { | |
827 return (int)STRLEN(compl_shown_match->cp_str) | |
828 > curwin->w_cursor.col - compl_col; | |
829 } | |
830 | |
831 /* | |
832 * Set variables that store noselect and noinsert behavior from the | |
833 * 'completeopt' value. | |
834 */ | |
835 void | |
836 completeopt_was_set(void) | |
837 { | |
838 compl_no_insert = FALSE; | |
839 compl_no_select = FALSE; | |
840 if (strstr((char *)p_cot, "noselect") != NULL) | |
841 compl_no_select = TRUE; | |
842 if (strstr((char *)p_cot, "noinsert") != NULL) | |
843 compl_no_insert = TRUE; | |
844 } | |
845 | |
846 /* | |
847 * Start completion for the complete() function. | |
848 * "startcol" is where the matched text starts (1 is first column). | |
849 * "list" is the list of matches. | |
850 */ | |
851 void | |
852 set_completion(colnr_T startcol, list_T *list) | |
853 { | |
854 int save_w_wrow = curwin->w_wrow; | |
855 int save_w_leftcol = curwin->w_leftcol; | |
856 | |
857 // If already doing completions stop it. | |
858 if (ctrl_x_mode != CTRL_X_NORMAL) | |
859 ins_compl_prep(' '); | |
860 ins_compl_clear(); | |
861 ins_compl_free(); | |
862 | |
863 compl_direction = FORWARD; | |
864 if (startcol > curwin->w_cursor.col) | |
865 startcol = curwin->w_cursor.col; | |
866 compl_col = startcol; | |
867 compl_length = (int)curwin->w_cursor.col - (int)startcol; | |
868 // compl_pattern doesn't need to be set | |
869 compl_orig_text = vim_strnsave(ml_get_curline() + compl_col, compl_length); | |
870 if (compl_orig_text == NULL || ins_compl_add(compl_orig_text, | |
871 -1, p_ic, NULL, NULL, 0, ORIGINAL_TEXT, FALSE) != OK) | |
872 return; | |
873 | |
874 ctrl_x_mode = CTRL_X_EVAL; | |
875 | |
876 ins_compl_add_list(list); | |
877 compl_matches = ins_compl_make_cyclic(); | |
878 compl_started = TRUE; | |
879 compl_used_match = TRUE; | |
880 compl_cont_status = 0; | |
881 | |
882 compl_curr_match = compl_first_match; | |
883 if (compl_no_insert || compl_no_select) | |
884 { | |
885 ins_complete(K_DOWN, FALSE); | |
886 if (compl_no_select) | |
887 // Down/Up has no real effect. | |
888 ins_complete(K_UP, FALSE); | |
889 } | |
890 else | |
891 ins_complete(Ctrl_N, FALSE); | |
892 compl_enter_selects = compl_no_insert; | |
893 | |
894 // Lazily show the popup menu, unless we got interrupted. | |
895 if (!compl_interrupted) | |
896 show_pum(save_w_wrow, save_w_leftcol); | |
897 out_flush(); | |
898 } | |
899 | |
900 | |
901 // "compl_match_array" points the currently displayed list of entries in the | |
902 // popup menu. It is NULL when there is no popup menu. | |
903 static pumitem_T *compl_match_array = NULL; | |
904 static int compl_match_arraysize; | |
905 | |
906 /* | |
907 * Update the screen and when there is any scrolling remove the popup menu. | |
908 */ | |
909 static void | |
910 ins_compl_upd_pum(void) | |
911 { | |
912 int h; | |
913 | |
914 if (compl_match_array != NULL) | |
915 { | |
916 h = curwin->w_cline_height; | |
917 // Update the screen later, before drawing the popup menu over it. | |
918 pum_call_update_screen(); | |
919 if (h != curwin->w_cline_height) | |
920 ins_compl_del_pum(); | |
921 } | |
922 } | |
923 | |
924 /* | |
925 * Remove any popup menu. | |
926 */ | |
927 static void | |
928 ins_compl_del_pum(void) | |
929 { | |
930 if (compl_match_array != NULL) | |
931 { | |
932 pum_undisplay(); | |
933 VIM_CLEAR(compl_match_array); | |
934 } | |
935 } | |
936 | |
937 /* | |
938 * Return TRUE if the popup menu should be displayed. | |
939 */ | |
940 int | |
941 pum_wanted(void) | |
942 { | |
943 // 'completeopt' must contain "menu" or "menuone" | |
944 if (vim_strchr(p_cot, 'm') == NULL) | |
945 return FALSE; | |
946 | |
947 // The display looks bad on a B&W display. | |
948 if (t_colors < 8 | |
949 #ifdef FEAT_GUI | |
950 && !gui.in_use | |
951 #endif | |
952 ) | |
953 return FALSE; | |
954 return TRUE; | |
955 } | |
956 | |
957 /* | |
958 * Return TRUE if there are two or more matches to be shown in the popup menu. | |
959 * One if 'completopt' contains "menuone". | |
960 */ | |
961 static int | |
962 pum_enough_matches(void) | |
963 { | |
964 compl_T *compl; | |
965 int i; | |
966 | |
967 // Don't display the popup menu if there are no matches or there is only | |
968 // one (ignoring the original text). | |
969 compl = compl_first_match; | |
970 i = 0; | |
971 do | |
972 { | |
973 if (compl == NULL | |
974 || ((compl->cp_flags & ORIGINAL_TEXT) == 0 && ++i == 2)) | |
975 break; | |
976 compl = compl->cp_next; | |
977 } while (compl != compl_first_match); | |
978 | |
979 if (strstr((char *)p_cot, "menuone") != NULL) | |
980 return (i >= 1); | |
981 return (i >= 2); | |
982 } | |
983 | |
984 /* | |
985 * Show the popup menu for the list of matches. | |
986 * Also adjusts "compl_shown_match" to an entry that is actually displayed. | |
987 */ | |
988 void | |
989 ins_compl_show_pum(void) | |
990 { | |
991 compl_T *compl; | |
992 compl_T *shown_compl = NULL; | |
993 int did_find_shown_match = FALSE; | |
994 int shown_match_ok = FALSE; | |
995 int i; | |
996 int cur = -1; | |
997 colnr_T col; | |
998 int lead_len = 0; | |
999 | |
1000 if (!pum_wanted() || !pum_enough_matches()) | |
1001 return; | |
1002 | |
1003 #if defined(FEAT_EVAL) | |
1004 // Dirty hard-coded hack: remove any matchparen highlighting. | |
1005 do_cmdline_cmd((char_u *)"if exists('g:loaded_matchparen')|3match none|endif"); | |
1006 #endif | |
1007 | |
1008 // Update the screen later, before drawing the popup menu over it. | |
1009 pum_call_update_screen(); | |
1010 | |
1011 if (compl_match_array == NULL) | |
1012 { | |
1013 // Need to build the popup menu list. | |
1014 compl_match_arraysize = 0; | |
1015 compl = compl_first_match; | |
1016 if (compl_leader != NULL) | |
1017 lead_len = (int)STRLEN(compl_leader); | |
1018 do | |
1019 { | |
1020 if ((compl->cp_flags & ORIGINAL_TEXT) == 0 | |
1021 && (compl_leader == NULL | |
1022 || ins_compl_equal(compl, compl_leader, lead_len))) | |
1023 ++compl_match_arraysize; | |
1024 compl = compl->cp_next; | |
1025 } while (compl != NULL && compl != compl_first_match); | |
1026 if (compl_match_arraysize == 0) | |
1027 return; | |
1028 compl_match_array = (pumitem_T *)alloc_clear( | |
1029 (unsigned)(sizeof(pumitem_T) | |
1030 * compl_match_arraysize)); | |
1031 if (compl_match_array != NULL) | |
1032 { | |
1033 // If the current match is the original text don't find the first | |
1034 // match after it, don't highlight anything. | |
1035 if (compl_shown_match->cp_flags & ORIGINAL_TEXT) | |
1036 shown_match_ok = TRUE; | |
1037 | |
1038 i = 0; | |
1039 compl = compl_first_match; | |
1040 do | |
1041 { | |
1042 if ((compl->cp_flags & ORIGINAL_TEXT) == 0 | |
1043 && (compl_leader == NULL | |
1044 || ins_compl_equal(compl, compl_leader, lead_len))) | |
1045 { | |
1046 if (!shown_match_ok) | |
1047 { | |
1048 if (compl == compl_shown_match || did_find_shown_match) | |
1049 { | |
1050 // This item is the shown match or this is the | |
1051 // first displayed item after the shown match. | |
1052 compl_shown_match = compl; | |
1053 did_find_shown_match = TRUE; | |
1054 shown_match_ok = TRUE; | |
1055 } | |
1056 else | |
1057 // Remember this displayed match for when the | |
1058 // shown match is just below it. | |
1059 shown_compl = compl; | |
1060 cur = i; | |
1061 } | |
1062 | |
1063 if (compl->cp_text[CPT_ABBR] != NULL) | |
1064 compl_match_array[i].pum_text = | |
1065 compl->cp_text[CPT_ABBR]; | |
1066 else | |
1067 compl_match_array[i].pum_text = compl->cp_str; | |
1068 compl_match_array[i].pum_kind = compl->cp_text[CPT_KIND]; | |
1069 compl_match_array[i].pum_info = compl->cp_text[CPT_INFO]; | |
1070 if (compl->cp_text[CPT_MENU] != NULL) | |
1071 compl_match_array[i++].pum_extra = | |
1072 compl->cp_text[CPT_MENU]; | |
1073 else | |
1074 compl_match_array[i++].pum_extra = compl->cp_fname; | |
1075 } | |
1076 | |
1077 if (compl == compl_shown_match) | |
1078 { | |
1079 did_find_shown_match = TRUE; | |
1080 | |
1081 // When the original text is the shown match don't set | |
1082 // compl_shown_match. | |
1083 if (compl->cp_flags & ORIGINAL_TEXT) | |
1084 shown_match_ok = TRUE; | |
1085 | |
1086 if (!shown_match_ok && shown_compl != NULL) | |
1087 { | |
1088 // The shown match isn't displayed, set it to the | |
1089 // previously displayed match. | |
1090 compl_shown_match = shown_compl; | |
1091 shown_match_ok = TRUE; | |
1092 } | |
1093 } | |
1094 compl = compl->cp_next; | |
1095 } while (compl != NULL && compl != compl_first_match); | |
1096 | |
1097 if (!shown_match_ok) // no displayed match at all | |
1098 cur = -1; | |
1099 } | |
1100 } | |
1101 else | |
1102 { | |
1103 // popup menu already exists, only need to find the current item. | |
1104 for (i = 0; i < compl_match_arraysize; ++i) | |
1105 if (compl_match_array[i].pum_text == compl_shown_match->cp_str | |
1106 || compl_match_array[i].pum_text | |
1107 == compl_shown_match->cp_text[CPT_ABBR]) | |
1108 { | |
1109 cur = i; | |
1110 break; | |
1111 } | |
1112 } | |
1113 | |
1114 if (compl_match_array != NULL) | |
1115 { | |
1116 // In Replace mode when a $ is displayed at the end of the line only | |
1117 // part of the screen would be updated. We do need to redraw here. | |
1118 dollar_vcol = -1; | |
1119 | |
1120 // Compute the screen column of the start of the completed text. | |
1121 // Use the cursor to get all wrapping and other settings right. | |
1122 col = curwin->w_cursor.col; | |
1123 curwin->w_cursor.col = compl_col; | |
1124 pum_display(compl_match_array, compl_match_arraysize, cur); | |
1125 curwin->w_cursor.col = col; | |
1126 } | |
1127 } | |
1128 | |
1129 #define DICT_FIRST (1) // use just first element in "dict" | |
1130 #define DICT_EXACT (2) // "dict" is the exact name of a file | |
1131 | |
1132 /* | |
1133 * Add any identifiers that match the given pattern in the list of dictionary | |
1134 * files "dict_start" to the list of completions. | |
1135 */ | |
1136 static void | |
1137 ins_compl_dictionaries( | |
1138 char_u *dict_start, | |
1139 char_u *pat, | |
1140 int flags, // DICT_FIRST and/or DICT_EXACT | |
1141 int thesaurus) // Thesaurus completion | |
1142 { | |
1143 char_u *dict = dict_start; | |
1144 char_u *ptr; | |
1145 char_u *buf; | |
1146 regmatch_T regmatch; | |
1147 char_u **files; | |
1148 int count; | |
1149 int save_p_scs; | |
1150 int dir = compl_direction; | |
1151 | |
1152 if (*dict == NUL) | |
1153 { | |
1154 #ifdef FEAT_SPELL | |
1155 // When 'dictionary' is empty and spell checking is enabled use | |
1156 // "spell". | |
1157 if (!thesaurus && curwin->w_p_spell) | |
1158 dict = (char_u *)"spell"; | |
1159 else | |
1160 #endif | |
1161 return; | |
1162 } | |
1163 | |
1164 buf = alloc(LSIZE); | |
1165 if (buf == NULL) | |
1166 return; | |
1167 regmatch.regprog = NULL; // so that we can goto theend | |
1168 | |
1169 // If 'infercase' is set, don't use 'smartcase' here | |
1170 save_p_scs = p_scs; | |
1171 if (curbuf->b_p_inf) | |
1172 p_scs = FALSE; | |
1173 | |
1174 // When invoked to match whole lines for CTRL-X CTRL-L adjust the pattern | |
1175 // to only match at the start of a line. Otherwise just match the | |
1176 // pattern. Also need to double backslashes. | |
1177 if (ctrl_x_mode_line_or_eval()) | |
1178 { | |
1179 char_u *pat_esc = vim_strsave_escaped(pat, (char_u *)"\\"); | |
1180 size_t len; | |
1181 | |
1182 if (pat_esc == NULL) | |
1183 goto theend; | |
1184 len = STRLEN(pat_esc) + 10; | |
1185 ptr = alloc((unsigned)len); | |
1186 if (ptr == NULL) | |
1187 { | |
1188 vim_free(pat_esc); | |
1189 goto theend; | |
1190 } | |
1191 vim_snprintf((char *)ptr, len, "^\\s*\\zs\\V%s", pat_esc); | |
1192 regmatch.regprog = vim_regcomp(ptr, RE_MAGIC); | |
1193 vim_free(pat_esc); | |
1194 vim_free(ptr); | |
1195 } | |
1196 else | |
1197 { | |
1198 regmatch.regprog = vim_regcomp(pat, p_magic ? RE_MAGIC : 0); | |
1199 if (regmatch.regprog == NULL) | |
1200 goto theend; | |
1201 } | |
1202 | |
1203 // ignore case depends on 'ignorecase', 'smartcase' and "pat" | |
1204 regmatch.rm_ic = ignorecase(pat); | |
1205 while (*dict != NUL && !got_int && !compl_interrupted) | |
1206 { | |
1207 // copy one dictionary file name into buf | |
1208 if (flags == DICT_EXACT) | |
1209 { | |
1210 count = 1; | |
1211 files = &dict; | |
1212 } | |
1213 else | |
1214 { | |
1215 // Expand wildcards in the dictionary name, but do not allow | |
1216 // backticks (for security, the 'dict' option may have been set in | |
1217 // a modeline). | |
1218 copy_option_part(&dict, buf, LSIZE, ","); | |
1219 # ifdef FEAT_SPELL | |
1220 if (!thesaurus && STRCMP(buf, "spell") == 0) | |
1221 count = -1; | |
1222 else | |
1223 # endif | |
1224 if (vim_strchr(buf, '`') != NULL | |
1225 || expand_wildcards(1, &buf, &count, &files, | |
1226 EW_FILE|EW_SILENT) != OK) | |
1227 count = 0; | |
1228 } | |
1229 | |
1230 # ifdef FEAT_SPELL | |
1231 if (count == -1) | |
1232 { | |
1233 // Complete from active spelling. Skip "\<" in the pattern, we | |
1234 // don't use it as a RE. | |
1235 if (pat[0] == '\\' && pat[1] == '<') | |
1236 ptr = pat + 2; | |
1237 else | |
1238 ptr = pat; | |
1239 spell_dump_compl(ptr, regmatch.rm_ic, &dir, 0); | |
1240 } | |
1241 else | |
1242 # endif | |
1243 if (count > 0) // avoid warning for using "files" uninit | |
1244 { | |
1245 ins_compl_files(count, files, thesaurus, flags, | |
1246 ®match, buf, &dir); | |
1247 if (flags != DICT_EXACT) | |
1248 FreeWild(count, files); | |
1249 } | |
1250 if (flags != 0) | |
1251 break; | |
1252 } | |
1253 | |
1254 theend: | |
1255 p_scs = save_p_scs; | |
1256 vim_regfree(regmatch.regprog); | |
1257 vim_free(buf); | |
1258 } | |
1259 | |
1260 static void | |
1261 ins_compl_files( | |
1262 int count, | |
1263 char_u **files, | |
1264 int thesaurus, | |
1265 int flags, | |
1266 regmatch_T *regmatch, | |
1267 char_u *buf, | |
1268 int *dir) | |
1269 { | |
1270 char_u *ptr; | |
1271 int i; | |
1272 FILE *fp; | |
1273 int add_r; | |
1274 | |
1275 for (i = 0; i < count && !got_int && !compl_interrupted; i++) | |
1276 { | |
1277 fp = mch_fopen((char *)files[i], "r"); // open dictionary file | |
1278 if (flags != DICT_EXACT) | |
1279 { | |
1280 vim_snprintf((char *)IObuff, IOSIZE, | |
1281 _("Scanning dictionary: %s"), (char *)files[i]); | |
1282 (void)msg_trunc_attr((char *)IObuff, TRUE, HL_ATTR(HLF_R)); | |
1283 } | |
1284 | |
1285 if (fp != NULL) | |
1286 { | |
1287 // Read dictionary file line by line. | |
1288 // Check each line for a match. | |
1289 while (!got_int && !compl_interrupted | |
1290 && !vim_fgets(buf, LSIZE, fp)) | |
1291 { | |
1292 ptr = buf; | |
1293 while (vim_regexec(regmatch, buf, (colnr_T)(ptr - buf))) | |
1294 { | |
1295 ptr = regmatch->startp[0]; | |
1296 if (ctrl_x_mode_line_or_eval()) | |
1297 ptr = find_line_end(ptr); | |
1298 else | |
1299 ptr = find_word_end(ptr); | |
1300 add_r = ins_compl_add_infercase(regmatch->startp[0], | |
1301 (int)(ptr - regmatch->startp[0]), | |
1302 p_ic, files[i], *dir, 0); | |
1303 if (thesaurus) | |
1304 { | |
1305 char_u *wstart; | |
1306 | |
1307 // Add the other matches on the line | |
1308 ptr = buf; | |
1309 while (!got_int) | |
1310 { | |
1311 // Find start of the next word. Skip white | |
1312 // space and punctuation. | |
1313 ptr = find_word_start(ptr); | |
1314 if (*ptr == NUL || *ptr == NL) | |
1315 break; | |
1316 wstart = ptr; | |
1317 | |
1318 // Find end of the word. | |
1319 if (has_mbyte) | |
1320 // Japanese words may have characters in | |
1321 // different classes, only separate words | |
1322 // with single-byte non-word characters. | |
1323 while (*ptr != NUL) | |
1324 { | |
1325 int l = (*mb_ptr2len)(ptr); | |
1326 | |
1327 if (l < 2 && !vim_iswordc(*ptr)) | |
1328 break; | |
1329 ptr += l; | |
1330 } | |
1331 else | |
1332 ptr = find_word_end(ptr); | |
1333 | |
1334 // Add the word. Skip the regexp match. | |
1335 if (wstart != regmatch->startp[0]) | |
1336 add_r = ins_compl_add_infercase(wstart, | |
1337 (int)(ptr - wstart), | |
1338 p_ic, files[i], *dir, 0); | |
1339 } | |
1340 } | |
1341 if (add_r == OK) | |
1342 // if dir was BACKWARD then honor it just once | |
1343 *dir = FORWARD; | |
1344 else if (add_r == FAIL) | |
1345 break; | |
1346 // avoid expensive call to vim_regexec() when at end | |
1347 // of line | |
1348 if (*ptr == '\n' || got_int) | |
1349 break; | |
1350 } | |
1351 line_breakcheck(); | |
1352 ins_compl_check_keys(50, FALSE); | |
1353 } | |
1354 fclose(fp); | |
1355 } | |
1356 } | |
1357 } | |
1358 | |
1359 /* | |
1360 * Find the start of the next word. | |
1361 * Returns a pointer to the first char of the word. Also stops at a NUL. | |
1362 */ | |
1363 char_u * | |
1364 find_word_start(char_u *ptr) | |
1365 { | |
1366 if (has_mbyte) | |
1367 while (*ptr != NUL && *ptr != '\n' && mb_get_class(ptr) <= 1) | |
1368 ptr += (*mb_ptr2len)(ptr); | |
1369 else | |
1370 while (*ptr != NUL && *ptr != '\n' && !vim_iswordc(*ptr)) | |
1371 ++ptr; | |
1372 return ptr; | |
1373 } | |
1374 | |
1375 /* | |
1376 * Find the end of the word. Assumes it starts inside a word. | |
1377 * Returns a pointer to just after the word. | |
1378 */ | |
1379 char_u * | |
1380 find_word_end(char_u *ptr) | |
1381 { | |
1382 int start_class; | |
1383 | |
1384 if (has_mbyte) | |
1385 { | |
1386 start_class = mb_get_class(ptr); | |
1387 if (start_class > 1) | |
1388 while (*ptr != NUL) | |
1389 { | |
1390 ptr += (*mb_ptr2len)(ptr); | |
1391 if (mb_get_class(ptr) != start_class) | |
1392 break; | |
1393 } | |
1394 } | |
1395 else | |
1396 while (vim_iswordc(*ptr)) | |
1397 ++ptr; | |
1398 return ptr; | |
1399 } | |
1400 | |
1401 /* | |
1402 * Find the end of the line, omitting CR and NL at the end. | |
1403 * Returns a pointer to just after the line. | |
1404 */ | |
1405 static char_u * | |
1406 find_line_end(char_u *ptr) | |
1407 { | |
1408 char_u *s; | |
1409 | |
1410 s = ptr + STRLEN(ptr); | |
1411 while (s > ptr && (s[-1] == CAR || s[-1] == NL)) | |
1412 --s; | |
1413 return s; | |
1414 } | |
1415 | |
1416 /* | |
1417 * Free the list of completions | |
1418 */ | |
1419 static void | |
1420 ins_compl_free(void) | |
1421 { | |
1422 compl_T *match; | |
1423 int i; | |
1424 | |
1425 VIM_CLEAR(compl_pattern); | |
1426 VIM_CLEAR(compl_leader); | |
1427 | |
1428 if (compl_first_match == NULL) | |
1429 return; | |
1430 | |
1431 ins_compl_del_pum(); | |
1432 pum_clear(); | |
1433 | |
1434 compl_curr_match = compl_first_match; | |
1435 do | |
1436 { | |
1437 match = compl_curr_match; | |
1438 compl_curr_match = compl_curr_match->cp_next; | |
1439 vim_free(match->cp_str); | |
1440 // several entries may use the same fname, free it just once. | |
1441 if (match->cp_flags & FREE_FNAME) | |
1442 vim_free(match->cp_fname); | |
1443 for (i = 0; i < CPT_COUNT; ++i) | |
1444 vim_free(match->cp_text[i]); | |
1445 vim_free(match); | |
1446 } while (compl_curr_match != NULL && compl_curr_match != compl_first_match); | |
1447 compl_first_match = compl_curr_match = NULL; | |
1448 compl_shown_match = NULL; | |
1449 compl_old_match = NULL; | |
1450 } | |
1451 | |
1452 void | |
1453 ins_compl_clear(void) | |
1454 { | |
1455 compl_cont_status = 0; | |
1456 compl_started = FALSE; | |
1457 compl_matches = 0; | |
1458 VIM_CLEAR(compl_pattern); | |
1459 VIM_CLEAR(compl_leader); | |
1460 edit_submode_extra = NULL; | |
1461 VIM_CLEAR(compl_orig_text); | |
1462 compl_enter_selects = FALSE; | |
1463 // clear v:completed_item | |
1464 set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc_lock(VAR_FIXED)); | |
1465 } | |
1466 | |
1467 /* | |
1468 * Return TRUE when Insert completion is active. | |
1469 */ | |
1470 int | |
1471 ins_compl_active(void) | |
1472 { | |
1473 return compl_started; | |
1474 } | |
1475 | |
1476 /* | |
1477 * Get complete information | |
1478 */ | |
1479 void | |
1480 get_complete_info(list_T *what_list, dict_T *retdict) | |
1481 { | |
1482 int ret = OK; | |
1483 listitem_T *item; | |
1484 #define CI_WHAT_MODE 0x01 | |
1485 #define CI_WHAT_PUM_VISIBLE 0x02 | |
1486 #define CI_WHAT_ITEMS 0x04 | |
1487 #define CI_WHAT_SELECTED 0x08 | |
1488 #define CI_WHAT_INSERTED 0x10 | |
1489 #define CI_WHAT_ALL 0xff | |
1490 int what_flag; | |
1491 | |
1492 if (what_list == NULL) | |
1493 what_flag = CI_WHAT_ALL; | |
1494 else | |
1495 { | |
1496 what_flag = 0; | |
1497 for (item = what_list->lv_first; item != NULL; item = item->li_next) | |
1498 { | |
1499 char_u *what = tv_get_string(&item->li_tv); | |
1500 | |
1501 if (STRCMP(what, "mode") == 0) | |
1502 what_flag |= CI_WHAT_MODE; | |
1503 else if (STRCMP(what, "pum_visible") == 0) | |
1504 what_flag |= CI_WHAT_PUM_VISIBLE; | |
1505 else if (STRCMP(what, "items") == 0) | |
1506 what_flag |= CI_WHAT_ITEMS; | |
1507 else if (STRCMP(what, "selected") == 0) | |
1508 what_flag |= CI_WHAT_SELECTED; | |
1509 else if (STRCMP(what, "inserted") == 0) | |
1510 what_flag |= CI_WHAT_INSERTED; | |
1511 } | |
1512 } | |
1513 | |
1514 if (ret == OK && (what_flag & CI_WHAT_MODE)) | |
1515 ret = dict_add_string(retdict, "mode", ins_compl_mode()); | |
1516 | |
1517 if (ret == OK && (what_flag & CI_WHAT_PUM_VISIBLE)) | |
1518 ret = dict_add_number(retdict, "pum_visible", pum_visible()); | |
1519 | |
1520 if (ret == OK && (what_flag & CI_WHAT_ITEMS)) | |
1521 { | |
1522 list_T *li; | |
1523 dict_T *di; | |
1524 compl_T *match; | |
1525 | |
1526 li = list_alloc(); | |
1527 if (li == NULL) | |
1528 return; | |
1529 ret = dict_add_list(retdict, "items", li); | |
1530 if (ret == OK && compl_first_match != NULL) | |
1531 { | |
1532 match = compl_first_match; | |
1533 do | |
1534 { | |
1535 if (!(match->cp_flags & ORIGINAL_TEXT)) | |
1536 { | |
1537 di = dict_alloc(); | |
1538 if (di == NULL) | |
1539 return; | |
1540 ret = list_append_dict(li, di); | |
1541 if (ret != OK) | |
1542 return; | |
1543 dict_add_string(di, "word", match->cp_str); | |
1544 dict_add_string(di, "abbr", match->cp_text[CPT_ABBR]); | |
1545 dict_add_string(di, "menu", match->cp_text[CPT_MENU]); | |
1546 dict_add_string(di, "kind", match->cp_text[CPT_KIND]); | |
1547 dict_add_string(di, "info", match->cp_text[CPT_INFO]); | |
1548 dict_add_string(di, "user_data", | |
1549 match->cp_text[CPT_USER_DATA]); | |
1550 } | |
1551 match = match->cp_next; | |
1552 } | |
1553 while (match != NULL && match != compl_first_match); | |
1554 } | |
1555 } | |
1556 | |
1557 if (ret == OK && (what_flag & CI_WHAT_SELECTED)) | |
1558 ret = dict_add_number(retdict, "selected", (compl_curr_match != NULL) ? | |
1559 compl_curr_match->cp_number - 1 : -1); | |
1560 | |
1561 // TODO | |
1562 // if (ret == OK && (what_flag & CI_WHAT_INSERTED)) | |
1563 } | |
1564 | |
1565 /* | |
1566 * Return Insert completion mode name string | |
1567 */ | |
1568 static char_u * | |
1569 ins_compl_mode(void) | |
1570 { | |
1571 if (ctrl_x_mode == CTRL_X_NOT_DEFINED_YET || compl_started) | |
1572 return (char_u *)ctrl_x_mode_names[ctrl_x_mode & ~CTRL_X_WANT_IDENT]; | |
1573 | |
1574 return (char_u *)""; | |
1575 } | |
1576 | |
1577 /* | |
1578 * Selected one of the matches. When FALSE the match was edited or using the | |
1579 * longest common string. | |
1580 */ | |
1581 int | |
1582 ins_compl_used_match(void) | |
1583 { | |
1584 return compl_used_match; | |
1585 } | |
1586 | |
1587 /* | |
1588 * Initialize get longest common string. | |
1589 */ | |
1590 void | |
1591 ins_compl_init_get_longest(void) | |
1592 { | |
1593 compl_get_longest = FALSE; | |
1594 } | |
1595 | |
1596 /* | |
1597 * Returns TRUE when insert completion is interrupted. | |
1598 */ | |
1599 int | |
1600 ins_compl_interrupted(void) | |
1601 { | |
1602 return compl_interrupted; | |
1603 } | |
1604 | |
1605 /* | |
1606 * Returns TRUE if the <Enter> key selects a match in the completion popup | |
1607 * menu. | |
1608 */ | |
1609 int | |
1610 ins_compl_enter_selects(void) | |
1611 { | |
1612 return compl_enter_selects; | |
1613 } | |
1614 | |
1615 /* | |
1616 * Return the column where the text starts that is being completed | |
1617 */ | |
1618 colnr_T | |
1619 ins_compl_col(void) | |
1620 { | |
1621 return compl_col; | |
1622 } | |
1623 | |
1624 /* | |
1625 * Delete one character before the cursor and show the subset of the matches | |
1626 * that match the word that is now before the cursor. | |
1627 * Returns the character to be used, NUL if the work is done and another char | |
1628 * to be got from the user. | |
1629 */ | |
1630 int | |
1631 ins_compl_bs(void) | |
1632 { | |
1633 char_u *line; | |
1634 char_u *p; | |
1635 | |
1636 line = ml_get_curline(); | |
1637 p = line + curwin->w_cursor.col; | |
1638 MB_PTR_BACK(line, p); | |
1639 | |
1640 // Stop completion when the whole word was deleted. For Omni completion | |
1641 // allow the word to be deleted, we won't match everything. | |
1642 // Respect the 'backspace' option. | |
1643 if ((int)(p - line) - (int)compl_col < 0 | |
1644 || ((int)(p - line) - (int)compl_col == 0 | |
1645 && ctrl_x_mode != CTRL_X_OMNI) || ctrl_x_mode == CTRL_X_EVAL | |
1646 || (!can_bs(BS_START) && (int)(p - line) - (int)compl_col | |
1647 - compl_length < 0)) | |
1648 return K_BS; | |
1649 | |
1650 // Deleted more than what was used to find matches or didn't finish | |
1651 // finding all matches: need to look for matches all over again. | |
1652 if (curwin->w_cursor.col <= compl_col + compl_length | |
1653 || ins_compl_need_restart()) | |
1654 ins_compl_restart(); | |
1655 | |
1656 vim_free(compl_leader); | |
1657 compl_leader = vim_strnsave(line + compl_col, (int)(p - line) - compl_col); | |
1658 if (compl_leader != NULL) | |
1659 { | |
1660 ins_compl_new_leader(); | |
1661 if (compl_shown_match != NULL) | |
1662 // Make sure current match is not a hidden item. | |
1663 compl_curr_match = compl_shown_match; | |
1664 return NUL; | |
1665 } | |
1666 return K_BS; | |
1667 } | |
1668 | |
1669 /* | |
1670 * Return TRUE when we need to find matches again, ins_compl_restart() is to | |
1671 * be called. | |
1672 */ | |
1673 static int | |
1674 ins_compl_need_restart(void) | |
1675 { | |
1676 // Return TRUE if we didn't complete finding matches or when the | |
1677 // 'completefunc' returned "always" in the "refresh" dictionary item. | |
1678 return compl_was_interrupted | |
1679 || ((ctrl_x_mode == CTRL_X_FUNCTION || ctrl_x_mode == CTRL_X_OMNI) | |
1680 && compl_opt_refresh_always); | |
1681 } | |
1682 | |
1683 /* | |
1684 * Called after changing "compl_leader". | |
1685 * Show the popup menu with a different set of matches. | |
1686 * May also search for matches again if the previous search was interrupted. | |
1687 */ | |
1688 static void | |
1689 ins_compl_new_leader(void) | |
1690 { | |
1691 ins_compl_del_pum(); | |
1692 ins_compl_delete(); | |
1693 ins_bytes(compl_leader + ins_compl_len()); | |
1694 compl_used_match = FALSE; | |
1695 | |
1696 if (compl_started) | |
1697 ins_compl_set_original_text(compl_leader); | |
1698 else | |
1699 { | |
1700 #ifdef FEAT_SPELL | |
1701 spell_bad_len = 0; // need to redetect bad word | |
1702 #endif | |
1703 // Matches were cleared, need to search for them now. Befor drawing | |
1704 // the popup menu display the changed text before the cursor. Set | |
1705 // "compl_restarting" to avoid that the first match is inserted. | |
1706 pum_call_update_screen(); | |
1707 #ifdef FEAT_GUI | |
1708 if (gui.in_use) | |
1709 { | |
1710 // Show the cursor after the match, not after the redrawn text. | |
1711 setcursor(); | |
1712 out_flush_cursor(FALSE, FALSE); | |
1713 } | |
1714 #endif | |
1715 compl_restarting = TRUE; | |
1716 if (ins_complete(Ctrl_N, TRUE) == FAIL) | |
1717 compl_cont_status = 0; | |
1718 compl_restarting = FALSE; | |
1719 } | |
1720 | |
1721 compl_enter_selects = !compl_used_match; | |
1722 | |
1723 // Show the popup menu with a different set of matches. | |
1724 ins_compl_show_pum(); | |
1725 | |
1726 // Don't let Enter select the original text when there is no popup menu. | |
1727 if (compl_match_array == NULL) | |
1728 compl_enter_selects = FALSE; | |
1729 } | |
1730 | |
1731 /* | |
1732 * Return the length of the completion, from the completion start column to | |
1733 * the cursor column. Making sure it never goes below zero. | |
1734 */ | |
1735 static int | |
1736 ins_compl_len(void) | |
1737 { | |
1738 int off = (int)curwin->w_cursor.col - (int)compl_col; | |
1739 | |
1740 if (off < 0) | |
1741 return 0; | |
1742 return off; | |
1743 } | |
1744 | |
1745 /* | |
1746 * Append one character to the match leader. May reduce the number of | |
1747 * matches. | |
1748 */ | |
1749 void | |
1750 ins_compl_addleader(int c) | |
1751 { | |
1752 int cc; | |
1753 | |
1754 if (stop_arrow() == FAIL) | |
1755 return; | |
1756 if (has_mbyte && (cc = (*mb_char2len)(c)) > 1) | |
1757 { | |
1758 char_u buf[MB_MAXBYTES + 1]; | |
1759 | |
1760 (*mb_char2bytes)(c, buf); | |
1761 buf[cc] = NUL; | |
1762 ins_char_bytes(buf, cc); | |
1763 if (compl_opt_refresh_always) | |
1764 AppendToRedobuff(buf); | |
1765 } | |
1766 else | |
1767 { | |
1768 ins_char(c); | |
1769 if (compl_opt_refresh_always) | |
1770 AppendCharToRedobuff(c); | |
1771 } | |
1772 | |
1773 // If we didn't complete finding matches we must search again. | |
1774 if (ins_compl_need_restart()) | |
1775 ins_compl_restart(); | |
1776 | |
1777 // When 'always' is set, don't reset compl_leader. While completing, | |
1778 // cursor doesn't point original position, changing compl_leader would | |
1779 // break redo. | |
1780 if (!compl_opt_refresh_always) | |
1781 { | |
1782 vim_free(compl_leader); | |
1783 compl_leader = vim_strnsave(ml_get_curline() + compl_col, | |
1784 (int)(curwin->w_cursor.col - compl_col)); | |
1785 if (compl_leader != NULL) | |
1786 ins_compl_new_leader(); | |
1787 } | |
1788 } | |
1789 | |
1790 /* | |
1791 * Setup for finding completions again without leaving CTRL-X mode. Used when | |
1792 * BS or a key was typed while still searching for matches. | |
1793 */ | |
1794 static void | |
1795 ins_compl_restart(void) | |
1796 { | |
1797 ins_compl_free(); | |
1798 compl_started = FALSE; | |
1799 compl_matches = 0; | |
1800 compl_cont_status = 0; | |
1801 compl_cont_mode = 0; | |
1802 } | |
1803 | |
1804 /* | |
1805 * Set the first match, the original text. | |
1806 */ | |
1807 static void | |
1808 ins_compl_set_original_text(char_u *str) | |
1809 { | |
1810 char_u *p; | |
1811 | |
1812 // Replace the original text entry. | |
1813 // The ORIGINAL_TEXT flag is either at the first item or might possibly be | |
1814 // at the last item for backward completion | |
1815 if (compl_first_match->cp_flags & ORIGINAL_TEXT) // safety check | |
1816 { | |
1817 p = vim_strsave(str); | |
1818 if (p != NULL) | |
1819 { | |
1820 vim_free(compl_first_match->cp_str); | |
1821 compl_first_match->cp_str = p; | |
1822 } | |
1823 } | |
1824 else if (compl_first_match->cp_prev != NULL | |
1825 && (compl_first_match->cp_prev->cp_flags & ORIGINAL_TEXT)) | |
1826 { | |
1827 p = vim_strsave(str); | |
1828 if (p != NULL) | |
1829 { | |
1830 vim_free(compl_first_match->cp_prev->cp_str); | |
1831 compl_first_match->cp_prev->cp_str = p; | |
1832 } | |
1833 } | |
1834 } | |
1835 | |
1836 /* | |
1837 * Append one character to the match leader. May reduce the number of | |
1838 * matches. | |
1839 */ | |
1840 void | |
1841 ins_compl_addfrommatch(void) | |
1842 { | |
1843 char_u *p; | |
1844 int len = (int)curwin->w_cursor.col - (int)compl_col; | |
1845 int c; | |
1846 compl_T *cp; | |
1847 | |
1848 p = compl_shown_match->cp_str; | |
1849 if ((int)STRLEN(p) <= len) // the match is too short | |
1850 { | |
1851 // When still at the original match use the first entry that matches | |
1852 // the leader. | |
1853 if (compl_shown_match->cp_flags & ORIGINAL_TEXT) | |
1854 { | |
1855 p = NULL; | |
1856 for (cp = compl_shown_match->cp_next; cp != NULL | |
1857 && cp != compl_first_match; cp = cp->cp_next) | |
1858 { | |
1859 if (compl_leader == NULL | |
1860 || ins_compl_equal(cp, compl_leader, | |
1861 (int)STRLEN(compl_leader))) | |
1862 { | |
1863 p = cp->cp_str; | |
1864 break; | |
1865 } | |
1866 } | |
1867 if (p == NULL || (int)STRLEN(p) <= len) | |
1868 return; | |
1869 } | |
1870 else | |
1871 return; | |
1872 } | |
1873 p += len; | |
1874 c = PTR2CHAR(p); | |
1875 ins_compl_addleader(c); | |
1876 } | |
1877 | |
1878 /* | |
1879 * Prepare for Insert mode completion, or stop it. | |
1880 * Called just after typing a character in Insert mode. | |
1881 * Returns TRUE when the character is not to be inserted; | |
1882 */ | |
1883 int | |
1884 ins_compl_prep(int c) | |
1885 { | |
1886 char_u *ptr; | |
1887 int want_cindent; | |
1888 int retval = FALSE; | |
1889 | |
1890 // Forget any previous 'special' messages if this is actually | |
1891 // a ^X mode key - bar ^R, in which case we wait to see what it gives us. | |
1892 if (c != Ctrl_R && vim_is_ctrl_x_key(c)) | |
1893 edit_submode_extra = NULL; | |
1894 | |
1895 // Ignore end of Select mode mapping and mouse scroll buttons. | |
1896 if (c == K_SELECT || c == K_MOUSEDOWN || c == K_MOUSEUP | |
1897 || c == K_MOUSELEFT || c == K_MOUSERIGHT) | |
1898 return retval; | |
1899 | |
1900 // Set "compl_get_longest" when finding the first matches. | |
1901 if (ctrl_x_mode == CTRL_X_NOT_DEFINED_YET | |
1902 || (ctrl_x_mode == CTRL_X_NORMAL && !compl_started)) | |
1903 { | |
1904 compl_get_longest = (strstr((char *)p_cot, "longest") != NULL); | |
1905 compl_used_match = TRUE; | |
1906 | |
1907 } | |
1908 | |
1909 if (ctrl_x_mode == CTRL_X_NOT_DEFINED_YET) | |
1910 { | |
1911 // We have just typed CTRL-X and aren't quite sure which CTRL-X mode | |
1912 // it will be yet. Now we decide. | |
1913 switch (c) | |
1914 { | |
1915 case Ctrl_E: | |
1916 case Ctrl_Y: | |
1917 ctrl_x_mode = CTRL_X_SCROLL; | |
1918 if (!(State & REPLACE_FLAG)) | |
1919 edit_submode = (char_u *)_(" (insert) Scroll (^E/^Y)"); | |
1920 else | |
1921 edit_submode = (char_u *)_(" (replace) Scroll (^E/^Y)"); | |
1922 edit_submode_pre = NULL; | |
1923 showmode(); | |
1924 break; | |
1925 case Ctrl_L: | |
1926 ctrl_x_mode = CTRL_X_WHOLE_LINE; | |
1927 break; | |
1928 case Ctrl_F: | |
1929 ctrl_x_mode = CTRL_X_FILES; | |
1930 break; | |
1931 case Ctrl_K: | |
1932 ctrl_x_mode = CTRL_X_DICTIONARY; | |
1933 break; | |
1934 case Ctrl_R: | |
1935 // Simply allow ^R to happen without affecting ^X mode | |
1936 break; | |
1937 case Ctrl_T: | |
1938 ctrl_x_mode = CTRL_X_THESAURUS; | |
1939 break; | |
1940 #ifdef FEAT_COMPL_FUNC | |
1941 case Ctrl_U: | |
1942 ctrl_x_mode = CTRL_X_FUNCTION; | |
1943 break; | |
1944 case Ctrl_O: | |
1945 ctrl_x_mode = CTRL_X_OMNI; | |
1946 break; | |
1947 #endif | |
1948 case 's': | |
1949 case Ctrl_S: | |
1950 ctrl_x_mode = CTRL_X_SPELL; | |
1951 #ifdef FEAT_SPELL | |
1952 ++emsg_off; // Avoid getting the E756 error twice. | |
1953 spell_back_to_badword(); | |
1954 --emsg_off; | |
1955 #endif | |
1956 break; | |
1957 case Ctrl_RSB: | |
1958 ctrl_x_mode = CTRL_X_TAGS; | |
1959 break; | |
1960 #ifdef FEAT_FIND_ID | |
1961 case Ctrl_I: | |
1962 case K_S_TAB: | |
1963 ctrl_x_mode = CTRL_X_PATH_PATTERNS; | |
1964 break; | |
1965 case Ctrl_D: | |
1966 ctrl_x_mode = CTRL_X_PATH_DEFINES; | |
1967 break; | |
1968 #endif | |
1969 case Ctrl_V: | |
1970 case Ctrl_Q: | |
1971 ctrl_x_mode = CTRL_X_CMDLINE; | |
1972 break; | |
1973 case Ctrl_P: | |
1974 case Ctrl_N: | |
1975 // ^X^P means LOCAL expansion if nothing interrupted (eg we | |
1976 // just started ^X mode, or there were enough ^X's to cancel | |
1977 // the previous mode, say ^X^F^X^X^P or ^P^X^X^X^P, see below) | |
1978 // do normal expansion when interrupting a different mode (say | |
1979 // ^X^F^X^P or ^P^X^X^P, see below) | |
1980 // nothing changes if interrupting mode 0, (eg, the flag | |
1981 // doesn't change when going to ADDING mode -- Acevedo | |
1982 if (!(compl_cont_status & CONT_INTRPT)) | |
1983 compl_cont_status |= CONT_LOCAL; | |
1984 else if (compl_cont_mode != 0) | |
1985 compl_cont_status &= ~CONT_LOCAL; | |
1986 // FALLTHROUGH | |
1987 default: | |
1988 // If we have typed at least 2 ^X's... for modes != 0, we set | |
1989 // compl_cont_status = 0 (eg, as if we had just started ^X | |
1990 // mode). | |
1991 // For mode 0, we set "compl_cont_mode" to an impossible | |
1992 // value, in both cases ^X^X can be used to restart the same | |
1993 // mode (avoiding ADDING mode). | |
1994 // Undocumented feature: In a mode != 0 ^X^P and ^X^X^P start | |
1995 // 'complete' and local ^P expansions respectively. | |
1996 // In mode 0 an extra ^X is needed since ^X^P goes to ADDING | |
1997 // mode -- Acevedo | |
1998 if (c == Ctrl_X) | |
1999 { | |
2000 if (compl_cont_mode != 0) | |
2001 compl_cont_status = 0; | |
2002 else | |
2003 compl_cont_mode = CTRL_X_NOT_DEFINED_YET; | |
2004 } | |
2005 ctrl_x_mode = CTRL_X_NORMAL; | |
2006 edit_submode = NULL; | |
2007 showmode(); | |
2008 break; | |
2009 } | |
2010 } | |
2011 else if (ctrl_x_mode != CTRL_X_NORMAL) | |
2012 { | |
2013 // We're already in CTRL-X mode, do we stay in it? | |
2014 if (!vim_is_ctrl_x_key(c)) | |
2015 { | |
2016 if (ctrl_x_mode == CTRL_X_SCROLL) | |
2017 ctrl_x_mode = CTRL_X_NORMAL; | |
2018 else | |
2019 ctrl_x_mode = CTRL_X_FINISHED; | |
2020 edit_submode = NULL; | |
2021 } | |
2022 showmode(); | |
2023 } | |
2024 | |
2025 if (compl_started || ctrl_x_mode == CTRL_X_FINISHED) | |
2026 { | |
2027 // Show error message from attempted keyword completion (probably | |
2028 // 'Pattern not found') until another key is hit, then go back to | |
2029 // showing what mode we are in. | |
2030 showmode(); | |
2031 if ((ctrl_x_mode == CTRL_X_NORMAL && c != Ctrl_N && c != Ctrl_P | |
2032 && c != Ctrl_R && !ins_compl_pum_key(c)) | |
2033 || ctrl_x_mode == CTRL_X_FINISHED) | |
2034 { | |
2035 // Get here when we have finished typing a sequence of ^N and | |
2036 // ^P or other completion characters in CTRL-X mode. Free up | |
2037 // memory that was used, and make sure we can redo the insert. | |
2038 if (compl_curr_match != NULL || compl_leader != NULL || c == Ctrl_E) | |
2039 { | |
2040 // If any of the original typed text has been changed, eg when | |
2041 // ignorecase is set, we must add back-spaces to the redo | |
2042 // buffer. We add as few as necessary to delete just the part | |
2043 // of the original text that has changed. | |
2044 // When using the longest match, edited the match or used | |
2045 // CTRL-E then don't use the current match. | |
2046 if (compl_curr_match != NULL && compl_used_match && c != Ctrl_E) | |
2047 ptr = compl_curr_match->cp_str; | |
2048 else | |
2049 ptr = NULL; | |
2050 ins_compl_fixRedoBufForLeader(ptr); | |
2051 } | |
2052 | |
2053 #ifdef FEAT_CINDENT | |
2054 want_cindent = (can_cindent_get() && cindent_on()); | |
2055 #endif | |
2056 // When completing whole lines: fix indent for 'cindent'. | |
2057 // Otherwise, break line if it's too long. | |
2058 if (compl_cont_mode == CTRL_X_WHOLE_LINE) | |
2059 { | |
2060 #ifdef FEAT_CINDENT | |
2061 // re-indent the current line | |
2062 if (want_cindent) | |
2063 { | |
2064 do_c_expr_indent(); | |
2065 want_cindent = FALSE; // don't do it again | |
2066 } | |
2067 #endif | |
2068 } | |
2069 else | |
2070 { | |
2071 int prev_col = curwin->w_cursor.col; | |
2072 | |
2073 // put the cursor on the last char, for 'tw' formatting | |
2074 if (prev_col > 0) | |
2075 dec_cursor(); | |
2076 // only format when something was inserted | |
2077 if (!arrow_used && !ins_need_undo_get() && c != Ctrl_E) | |
2078 insertchar(NUL, 0, -1); | |
2079 if (prev_col > 0 | |
2080 && ml_get_curline()[curwin->w_cursor.col] != NUL) | |
2081 inc_cursor(); | |
2082 } | |
2083 | |
2084 // If the popup menu is displayed pressing CTRL-Y means accepting | |
2085 // the selection without inserting anything. When | |
2086 // compl_enter_selects is set the Enter key does the same. | |
2087 if ((c == Ctrl_Y || (compl_enter_selects | |
2088 && (c == CAR || c == K_KENTER || c == NL))) | |
2089 && pum_visible()) | |
2090 retval = TRUE; | |
2091 | |
2092 // CTRL-E means completion is Ended, go back to the typed text. | |
2093 // but only do this, if the Popup is still visible | |
2094 if (c == Ctrl_E) | |
2095 { | |
2096 ins_compl_delete(); | |
2097 if (compl_leader != NULL) | |
2098 ins_bytes(compl_leader + ins_compl_len()); | |
2099 else if (compl_first_match != NULL) | |
2100 ins_bytes(compl_orig_text + ins_compl_len()); | |
2101 retval = TRUE; | |
2102 } | |
2103 | |
2104 auto_format(FALSE, TRUE); | |
2105 | |
2106 ins_compl_free(); | |
2107 compl_started = FALSE; | |
2108 compl_matches = 0; | |
2109 if (!shortmess(SHM_COMPLETIONMENU)) | |
2110 msg_clr_cmdline(); // necessary for "noshowmode" | |
2111 ctrl_x_mode = CTRL_X_NORMAL; | |
2112 compl_enter_selects = FALSE; | |
2113 if (edit_submode != NULL) | |
2114 { | |
2115 edit_submode = NULL; | |
2116 showmode(); | |
2117 } | |
2118 | |
2119 #ifdef FEAT_CMDWIN | |
2120 if (c == Ctrl_C && cmdwin_type != 0) | |
2121 // Avoid the popup menu remains displayed when leaving the | |
2122 // command line window. | |
2123 update_screen(0); | |
2124 #endif | |
2125 #ifdef FEAT_CINDENT | |
2126 // Indent now if a key was typed that is in 'cinkeys'. | |
2127 if (want_cindent && in_cinkeys(KEY_COMPLETE, ' ', inindent(0))) | |
2128 do_c_expr_indent(); | |
2129 #endif | |
2130 // Trigger the CompleteDone event to give scripts a chance to act | |
2131 // upon the completion. | |
2132 ins_apply_autocmds(EVENT_COMPLETEDONE); | |
2133 } | |
2134 } | |
2135 else if (ctrl_x_mode == CTRL_X_LOCAL_MSG) | |
2136 // Trigger the CompleteDone event to give scripts a chance to act | |
2137 // upon the (possibly failed) completion. | |
2138 ins_apply_autocmds(EVENT_COMPLETEDONE); | |
2139 | |
2140 // reset continue_* if we left expansion-mode, if we stay they'll be | |
2141 // (re)set properly in ins_complete() | |
2142 if (!vim_is_ctrl_x_key(c)) | |
2143 { | |
2144 compl_cont_status = 0; | |
2145 compl_cont_mode = 0; | |
2146 } | |
2147 | |
2148 return retval; | |
2149 } | |
2150 | |
2151 /* | |
2152 * Fix the redo buffer for the completion leader replacing some of the typed | |
2153 * text. This inserts backspaces and appends the changed text. | |
2154 * "ptr" is the known leader text or NUL. | |
2155 */ | |
2156 static void | |
2157 ins_compl_fixRedoBufForLeader(char_u *ptr_arg) | |
2158 { | |
2159 int len; | |
2160 char_u *p; | |
2161 char_u *ptr = ptr_arg; | |
2162 | |
2163 if (ptr == NULL) | |
2164 { | |
2165 if (compl_leader != NULL) | |
2166 ptr = compl_leader; | |
2167 else | |
2168 return; // nothing to do | |
2169 } | |
2170 if (compl_orig_text != NULL) | |
2171 { | |
2172 p = compl_orig_text; | |
2173 for (len = 0; p[len] != NUL && p[len] == ptr[len]; ++len) | |
2174 ; | |
2175 if (len > 0) | |
2176 len -= (*mb_head_off)(p, p + len); | |
2177 for (p += len; *p != NUL; MB_PTR_ADV(p)) | |
2178 AppendCharToRedobuff(K_BS); | |
2179 } | |
2180 else | |
2181 len = 0; | |
2182 if (ptr != NULL) | |
2183 AppendToRedobuffLit(ptr + len, -1); | |
2184 } | |
2185 | |
2186 /* | |
2187 * Loops through the list of windows, loaded-buffers or non-loaded-buffers | |
2188 * (depending on flag) starting from buf and looking for a non-scanned | |
2189 * buffer (other than curbuf). curbuf is special, if it is called with | |
2190 * buf=curbuf then it has to be the first call for a given flag/expansion. | |
2191 * | |
2192 * Returns the buffer to scan, if any, otherwise returns curbuf -- Acevedo | |
2193 */ | |
2194 static buf_T * | |
2195 ins_compl_next_buf(buf_T *buf, int flag) | |
2196 { | |
2197 static win_T *wp = NULL; | |
2198 | |
2199 if (flag == 'w') // just windows | |
2200 { | |
2201 if (buf == curbuf || wp == NULL) // first call for this flag/expansion | |
2202 wp = curwin; | |
2203 while ((wp = (wp->w_next != NULL ? wp->w_next : firstwin)) != curwin | |
2204 && wp->w_buffer->b_scanned) | |
2205 ; | |
2206 buf = wp->w_buffer; | |
2207 } | |
2208 else | |
2209 // 'b' (just loaded buffers), 'u' (just non-loaded buffers) or 'U' | |
2210 // (unlisted buffers) | |
2211 // When completing whole lines skip unloaded buffers. | |
2212 while ((buf = (buf->b_next != NULL ? buf->b_next : firstbuf)) != curbuf | |
2213 && ((flag == 'U' | |
2214 ? buf->b_p_bl | |
2215 : (!buf->b_p_bl | |
2216 || (buf->b_ml.ml_mfp == NULL) != (flag == 'u'))) | |
2217 || buf->b_scanned)) | |
2218 ; | |
2219 return buf; | |
2220 } | |
2221 | |
2222 #ifdef FEAT_COMPL_FUNC | |
2223 /* | |
2224 * Execute user defined complete function 'completefunc' or 'omnifunc', and | |
2225 * get matches in "matches". | |
2226 */ | |
2227 static void | |
2228 expand_by_function( | |
2229 int type, // CTRL_X_OMNI or CTRL_X_FUNCTION | |
2230 char_u *base) | |
2231 { | |
2232 list_T *matchlist = NULL; | |
2233 dict_T *matchdict = NULL; | |
2234 typval_T args[3]; | |
2235 char_u *funcname; | |
2236 pos_T pos; | |
2237 win_T *curwin_save; | |
2238 buf_T *curbuf_save; | |
2239 typval_T rettv; | |
2240 int save_State = State; | |
2241 | |
2242 funcname = (type == CTRL_X_FUNCTION) ? curbuf->b_p_cfu : curbuf->b_p_ofu; | |
2243 if (*funcname == NUL) | |
2244 return; | |
2245 | |
2246 // Call 'completefunc' to obtain the list of matches. | |
2247 args[0].v_type = VAR_NUMBER; | |
2248 args[0].vval.v_number = 0; | |
2249 args[1].v_type = VAR_STRING; | |
2250 args[1].vval.v_string = base != NULL ? base : (char_u *)""; | |
2251 args[2].v_type = VAR_UNKNOWN; | |
2252 | |
2253 pos = curwin->w_cursor; | |
2254 curwin_save = curwin; | |
2255 curbuf_save = curbuf; | |
2256 | |
2257 // Call a function, which returns a list or dict. | |
2258 if (call_vim_function(funcname, 2, args, &rettv) == OK) | |
2259 { | |
2260 switch (rettv.v_type) | |
2261 { | |
2262 case VAR_LIST: | |
2263 matchlist = rettv.vval.v_list; | |
2264 break; | |
2265 case VAR_DICT: | |
2266 matchdict = rettv.vval.v_dict; | |
2267 break; | |
2268 case VAR_SPECIAL: | |
2269 if (rettv.vval.v_number == VVAL_NONE) | |
2270 compl_opt_suppress_empty = TRUE; | |
2271 // FALLTHROUGH | |
2272 default: | |
2273 // TODO: Give error message? | |
2274 clear_tv(&rettv); | |
2275 break; | |
2276 } | |
2277 } | |
2278 | |
2279 if (curwin_save != curwin || curbuf_save != curbuf) | |
2280 { | |
2281 emsg(_(e_complwin)); | |
2282 goto theend; | |
2283 } | |
2284 curwin->w_cursor = pos; // restore the cursor position | |
2285 validate_cursor(); | |
2286 if (!EQUAL_POS(curwin->w_cursor, pos)) | |
2287 { | |
2288 emsg(_(e_compldel)); | |
2289 goto theend; | |
2290 } | |
2291 | |
2292 if (matchlist != NULL) | |
2293 ins_compl_add_list(matchlist); | |
2294 else if (matchdict != NULL) | |
2295 ins_compl_add_dict(matchdict); | |
2296 | |
2297 theend: | |
2298 // Restore State, it might have been changed. | |
2299 State = save_State; | |
2300 | |
2301 if (matchdict != NULL) | |
2302 dict_unref(matchdict); | |
2303 if (matchlist != NULL) | |
2304 list_unref(matchlist); | |
2305 } | |
2306 #endif // FEAT_COMPL_FUNC | |
2307 | |
2308 #if defined(FEAT_COMPL_FUNC) || defined(FEAT_EVAL) || defined(PROTO) | |
2309 /* | |
2310 * Add completions from a list. | |
2311 */ | |
2312 static void | |
2313 ins_compl_add_list(list_T *list) | |
2314 { | |
2315 listitem_T *li; | |
2316 int dir = compl_direction; | |
2317 | |
2318 // Go through the List with matches and add each of them. | |
2319 for (li = list->lv_first; li != NULL; li = li->li_next) | |
2320 { | |
2321 if (ins_compl_add_tv(&li->li_tv, dir) == OK) | |
2322 // if dir was BACKWARD then honor it just once | |
2323 dir = FORWARD; | |
2324 else if (did_emsg) | |
2325 break; | |
2326 } | |
2327 } | |
2328 | |
2329 /* | |
2330 * Add completions from a dict. | |
2331 */ | |
2332 static void | |
2333 ins_compl_add_dict(dict_T *dict) | |
2334 { | |
2335 dictitem_T *di_refresh; | |
2336 dictitem_T *di_words; | |
2337 | |
2338 // Check for optional "refresh" item. | |
2339 compl_opt_refresh_always = FALSE; | |
2340 di_refresh = dict_find(dict, (char_u *)"refresh", 7); | |
2341 if (di_refresh != NULL && di_refresh->di_tv.v_type == VAR_STRING) | |
2342 { | |
2343 char_u *v = di_refresh->di_tv.vval.v_string; | |
2344 | |
2345 if (v != NULL && STRCMP(v, (char_u *)"always") == 0) | |
2346 compl_opt_refresh_always = TRUE; | |
2347 } | |
2348 | |
2349 // Add completions from a "words" list. | |
2350 di_words = dict_find(dict, (char_u *)"words", 5); | |
2351 if (di_words != NULL && di_words->di_tv.v_type == VAR_LIST) | |
2352 ins_compl_add_list(di_words->di_tv.vval.v_list); | |
2353 } | |
2354 | |
2355 /* | |
2356 * Add a match to the list of matches from a typeval_T. | |
2357 * If the given string is already in the list of completions, then return | |
2358 * NOTDONE, otherwise add it to the list and return OK. If there is an error, | |
2359 * maybe because alloc() returns NULL, then FAIL is returned. | |
2360 */ | |
2361 int | |
2362 ins_compl_add_tv(typval_T *tv, int dir) | |
2363 { | |
2364 char_u *word; | |
2365 int icase = FALSE; | |
2366 int adup = FALSE; | |
2367 int aempty = FALSE; | |
2368 char_u *(cptext[CPT_COUNT]); | |
2369 | |
2370 if (tv->v_type == VAR_DICT && tv->vval.v_dict != NULL) | |
2371 { | |
2372 word = dict_get_string(tv->vval.v_dict, (char_u *)"word", FALSE); | |
2373 cptext[CPT_ABBR] = dict_get_string(tv->vval.v_dict, | |
2374 (char_u *)"abbr", FALSE); | |
2375 cptext[CPT_MENU] = dict_get_string(tv->vval.v_dict, | |
2376 (char_u *)"menu", FALSE); | |
2377 cptext[CPT_KIND] = dict_get_string(tv->vval.v_dict, | |
2378 (char_u *)"kind", FALSE); | |
2379 cptext[CPT_INFO] = dict_get_string(tv->vval.v_dict, | |
2380 (char_u *)"info", FALSE); | |
2381 cptext[CPT_USER_DATA] = dict_get_string(tv->vval.v_dict, | |
2382 (char_u *)"user_data", FALSE); | |
2383 if (dict_get_string(tv->vval.v_dict, (char_u *)"icase", FALSE) != NULL) | |
2384 icase = dict_get_number(tv->vval.v_dict, (char_u *)"icase"); | |
2385 if (dict_get_string(tv->vval.v_dict, (char_u *)"dup", FALSE) != NULL) | |
2386 adup = dict_get_number(tv->vval.v_dict, (char_u *)"dup"); | |
2387 if (dict_get_string(tv->vval.v_dict, (char_u *)"empty", FALSE) != NULL) | |
2388 aempty = dict_get_number(tv->vval.v_dict, (char_u *)"empty"); | |
2389 } | |
2390 else | |
2391 { | |
2392 word = tv_get_string_chk(tv); | |
2393 vim_memset(cptext, 0, sizeof(cptext)); | |
2394 } | |
2395 if (word == NULL || (!aempty && *word == NUL)) | |
2396 return FAIL; | |
2397 return ins_compl_add(word, -1, icase, NULL, cptext, dir, 0, adup); | |
2398 } | |
2399 #endif | |
2400 | |
2401 /* | |
2402 * Get the next expansion(s), using "compl_pattern". | |
2403 * The search starts at position "ini" in curbuf and in the direction | |
2404 * compl_direction. | |
2405 * When "compl_started" is FALSE start at that position, otherwise continue | |
2406 * where we stopped searching before. | |
2407 * This may return before finding all the matches. | |
2408 * Return the total number of matches or -1 if still unknown -- Acevedo | |
2409 */ | |
2410 static int | |
2411 ins_compl_get_exp(pos_T *ini) | |
2412 { | |
2413 static pos_T first_match_pos; | |
2414 static pos_T last_match_pos; | |
2415 static char_u *e_cpt = (char_u *)""; // curr. entry in 'complete' | |
2416 static int found_all = FALSE; // Found all matches of a | |
2417 // certain type. | |
2418 static buf_T *ins_buf = NULL; // buffer being scanned | |
2419 | |
2420 pos_T *pos; | |
2421 char_u **matches; | |
2422 int save_p_scs; | |
2423 int save_p_ws; | |
2424 int save_p_ic; | |
2425 int i; | |
2426 int num_matches; | |
2427 int len; | |
2428 int found_new_match; | |
2429 int type = ctrl_x_mode; | |
2430 char_u *ptr; | |
2431 char_u *dict = NULL; | |
2432 int dict_f = 0; | |
2433 int set_match_pos; | |
2434 | |
2435 if (!compl_started) | |
2436 { | |
2437 FOR_ALL_BUFFERS(ins_buf) | |
2438 ins_buf->b_scanned = 0; | |
2439 found_all = FALSE; | |
2440 ins_buf = curbuf; | |
2441 e_cpt = (compl_cont_status & CONT_LOCAL) | |
2442 ? (char_u *)"." : curbuf->b_p_cpt; | |
2443 last_match_pos = first_match_pos = *ini; | |
2444 } | |
2445 else if (ins_buf != curbuf && !buf_valid(ins_buf)) | |
2446 ins_buf = curbuf; // In case the buffer was wiped out. | |
2447 | |
2448 compl_old_match = compl_curr_match; // remember the last current match | |
2449 pos = (compl_direction == FORWARD) ? &last_match_pos : &first_match_pos; | |
2450 | |
2451 // For ^N/^P loop over all the flags/windows/buffers in 'complete'. | |
2452 for (;;) | |
2453 { | |
2454 found_new_match = FAIL; | |
2455 set_match_pos = FALSE; | |
2456 | |
2457 // For ^N/^P pick a new entry from e_cpt if compl_started is off, | |
2458 // or if found_all says this entry is done. For ^X^L only use the | |
2459 // entries from 'complete' that look in loaded buffers. | |
2460 if ((ctrl_x_mode == CTRL_X_NORMAL | |
2461 || ctrl_x_mode_line_or_eval()) | |
2462 && (!compl_started || found_all)) | |
2463 { | |
2464 found_all = FALSE; | |
2465 while (*e_cpt == ',' || *e_cpt == ' ') | |
2466 e_cpt++; | |
2467 if (*e_cpt == '.' && !curbuf->b_scanned) | |
2468 { | |
2469 ins_buf = curbuf; | |
2470 first_match_pos = *ini; | |
2471 // Move the cursor back one character so that ^N can match the | |
2472 // word immediately after the cursor. | |
2473 if (ctrl_x_mode == CTRL_X_NORMAL && dec(&first_match_pos) < 0) | |
2474 { | |
2475 // Move the cursor to after the last character in the | |
2476 // buffer, so that word at start of buffer is found | |
2477 // correctly. | |
2478 first_match_pos.lnum = ins_buf->b_ml.ml_line_count; | |
2479 first_match_pos.col = | |
2480 (colnr_T)STRLEN(ml_get(first_match_pos.lnum)); | |
2481 } | |
2482 last_match_pos = first_match_pos; | |
2483 type = 0; | |
2484 | |
2485 // Remember the first match so that the loop stops when we | |
2486 // wrap and come back there a second time. | |
2487 set_match_pos = TRUE; | |
2488 } | |
2489 else if (vim_strchr((char_u *)"buwU", *e_cpt) != NULL | |
2490 && (ins_buf = ins_compl_next_buf(ins_buf, *e_cpt)) != curbuf) | |
2491 { | |
2492 // Scan a buffer, but not the current one. | |
2493 if (ins_buf->b_ml.ml_mfp != NULL) // loaded buffer | |
2494 { | |
2495 compl_started = TRUE; | |
2496 first_match_pos.col = last_match_pos.col = 0; | |
2497 first_match_pos.lnum = ins_buf->b_ml.ml_line_count + 1; | |
2498 last_match_pos.lnum = 0; | |
2499 type = 0; | |
2500 } | |
2501 else // unloaded buffer, scan like dictionary | |
2502 { | |
2503 found_all = TRUE; | |
2504 if (ins_buf->b_fname == NULL) | |
2505 continue; | |
2506 type = CTRL_X_DICTIONARY; | |
2507 dict = ins_buf->b_fname; | |
2508 dict_f = DICT_EXACT; | |
2509 } | |
2510 vim_snprintf((char *)IObuff, IOSIZE, _("Scanning: %s"), | |
2511 ins_buf->b_fname == NULL | |
2512 ? buf_spname(ins_buf) | |
2513 : ins_buf->b_sfname == NULL | |
2514 ? ins_buf->b_fname | |
2515 : ins_buf->b_sfname); | |
2516 (void)msg_trunc_attr((char *)IObuff, TRUE, HL_ATTR(HLF_R)); | |
2517 } | |
2518 else if (*e_cpt == NUL) | |
2519 break; | |
2520 else | |
2521 { | |
2522 if (ctrl_x_mode_line_or_eval()) | |
2523 type = -1; | |
2524 else if (*e_cpt == 'k' || *e_cpt == 's') | |
2525 { | |
2526 if (*e_cpt == 'k') | |
2527 type = CTRL_X_DICTIONARY; | |
2528 else | |
2529 type = CTRL_X_THESAURUS; | |
2530 if (*++e_cpt != ',' && *e_cpt != NUL) | |
2531 { | |
2532 dict = e_cpt; | |
2533 dict_f = DICT_FIRST; | |
2534 } | |
2535 } | |
2536 #ifdef FEAT_FIND_ID | |
2537 else if (*e_cpt == 'i') | |
2538 type = CTRL_X_PATH_PATTERNS; | |
2539 else if (*e_cpt == 'd') | |
2540 type = CTRL_X_PATH_DEFINES; | |
2541 #endif | |
2542 else if (*e_cpt == ']' || *e_cpt == 't') | |
2543 { | |
2544 type = CTRL_X_TAGS; | |
2545 vim_snprintf((char *)IObuff, IOSIZE, _("Scanning tags.")); | |
2546 (void)msg_trunc_attr((char *)IObuff, TRUE, HL_ATTR(HLF_R)); | |
2547 } | |
2548 else | |
2549 type = -1; | |
2550 | |
2551 // in any case e_cpt is advanced to the next entry | |
2552 (void)copy_option_part(&e_cpt, IObuff, IOSIZE, ","); | |
2553 | |
2554 found_all = TRUE; | |
2555 if (type == -1) | |
2556 continue; | |
2557 } | |
2558 } | |
2559 | |
2560 // If complete() was called then compl_pattern has been reset. The | |
2561 // following won't work then, bail out. | |
2562 if (compl_pattern == NULL) | |
2563 break; | |
2564 | |
2565 switch (type) | |
2566 { | |
2567 case -1: | |
2568 break; | |
2569 #ifdef FEAT_FIND_ID | |
2570 case CTRL_X_PATH_PATTERNS: | |
2571 case CTRL_X_PATH_DEFINES: | |
2572 find_pattern_in_path(compl_pattern, compl_direction, | |
2573 (int)STRLEN(compl_pattern), FALSE, FALSE, | |
2574 (type == CTRL_X_PATH_DEFINES | |
2575 && !(compl_cont_status & CONT_SOL)) | |
2576 ? FIND_DEFINE : FIND_ANY, 1L, ACTION_EXPAND, | |
2577 (linenr_T)1, (linenr_T)MAXLNUM); | |
2578 break; | |
2579 #endif | |
2580 | |
2581 case CTRL_X_DICTIONARY: | |
2582 case CTRL_X_THESAURUS: | |
2583 ins_compl_dictionaries( | |
2584 dict != NULL ? dict | |
2585 : (type == CTRL_X_THESAURUS | |
2586 ? (*curbuf->b_p_tsr == NUL | |
2587 ? p_tsr | |
2588 : curbuf->b_p_tsr) | |
2589 : (*curbuf->b_p_dict == NUL | |
2590 ? p_dict | |
2591 : curbuf->b_p_dict)), | |
2592 compl_pattern, | |
2593 dict != NULL ? dict_f | |
2594 : 0, type == CTRL_X_THESAURUS); | |
2595 dict = NULL; | |
2596 break; | |
2597 | |
2598 case CTRL_X_TAGS: | |
2599 // set p_ic according to p_ic, p_scs and pat for find_tags(). | |
2600 save_p_ic = p_ic; | |
2601 p_ic = ignorecase(compl_pattern); | |
2602 | |
2603 // Find up to TAG_MANY matches. Avoids that an enormous number | |
2604 // of matches is found when compl_pattern is empty | |
2605 if (find_tags(compl_pattern, &num_matches, &matches, | |
2606 TAG_REGEXP | TAG_NAMES | TAG_NOIC | TAG_INS_COMP | |
2607 | (ctrl_x_mode != CTRL_X_NORMAL ? TAG_VERBOSE : 0), | |
2608 TAG_MANY, curbuf->b_ffname) == OK && num_matches > 0) | |
2609 { | |
2610 ins_compl_add_matches(num_matches, matches, p_ic); | |
2611 } | |
2612 p_ic = save_p_ic; | |
2613 break; | |
2614 | |
2615 case CTRL_X_FILES: | |
2616 if (expand_wildcards(1, &compl_pattern, &num_matches, &matches, | |
2617 EW_FILE|EW_DIR|EW_ADDSLASH|EW_SILENT) == OK) | |
2618 { | |
2619 | |
2620 // May change home directory back to "~". | |
2621 tilde_replace(compl_pattern, num_matches, matches); | |
2622 ins_compl_add_matches(num_matches, matches, p_fic || p_wic); | |
2623 } | |
2624 break; | |
2625 | |
2626 case CTRL_X_CMDLINE: | |
2627 if (expand_cmdline(&compl_xp, compl_pattern, | |
2628 (int)STRLEN(compl_pattern), | |
2629 &num_matches, &matches) == EXPAND_OK) | |
2630 ins_compl_add_matches(num_matches, matches, FALSE); | |
2631 break; | |
2632 | |
2633 #ifdef FEAT_COMPL_FUNC | |
2634 case CTRL_X_FUNCTION: | |
2635 case CTRL_X_OMNI: | |
2636 expand_by_function(type, compl_pattern); | |
2637 break; | |
2638 #endif | |
2639 | |
2640 case CTRL_X_SPELL: | |
2641 #ifdef FEAT_SPELL | |
2642 num_matches = expand_spelling(first_match_pos.lnum, | |
2643 compl_pattern, &matches); | |
2644 if (num_matches > 0) | |
2645 ins_compl_add_matches(num_matches, matches, p_ic); | |
2646 #endif | |
2647 break; | |
2648 | |
2649 default: // normal ^P/^N and ^X^L | |
2650 // If 'infercase' is set, don't use 'smartcase' here | |
2651 save_p_scs = p_scs; | |
2652 if (ins_buf->b_p_inf) | |
2653 p_scs = FALSE; | |
2654 | |
2655 // Buffers other than curbuf are scanned from the beginning or the | |
2656 // end but never from the middle, thus setting nowrapscan in this | |
2657 // buffers is a good idea, on the other hand, we always set | |
2658 // wrapscan for curbuf to avoid missing matches -- Acevedo,Webb | |
2659 save_p_ws = p_ws; | |
2660 if (ins_buf != curbuf) | |
2661 p_ws = FALSE; | |
2662 else if (*e_cpt == '.') | |
2663 p_ws = TRUE; | |
2664 for (;;) | |
2665 { | |
2666 int flags = 0; | |
2667 | |
2668 ++msg_silent; // Don't want messages for wrapscan. | |
2669 | |
2670 // ctrl_x_mode_line_or_eval() || word-wise search that | |
2671 // has added a word that was at the beginning of the line | |
2672 if (ctrl_x_mode_line_or_eval() | |
2673 || (compl_cont_status & CONT_SOL)) | |
2674 found_new_match = search_for_exact_line(ins_buf, pos, | |
2675 compl_direction, compl_pattern); | |
2676 else | |
2677 found_new_match = searchit(NULL, ins_buf, pos, NULL, | |
2678 compl_direction, | |
2679 compl_pattern, 1L, SEARCH_KEEP + SEARCH_NFMSG, | |
2680 RE_LAST, (linenr_T)0, NULL, NULL); | |
2681 --msg_silent; | |
2682 if (!compl_started || set_match_pos) | |
2683 { | |
2684 // set "compl_started" even on fail | |
2685 compl_started = TRUE; | |
2686 first_match_pos = *pos; | |
2687 last_match_pos = *pos; | |
2688 set_match_pos = FALSE; | |
2689 } | |
2690 else if (first_match_pos.lnum == last_match_pos.lnum | |
2691 && first_match_pos.col == last_match_pos.col) | |
2692 found_new_match = FAIL; | |
2693 if (found_new_match == FAIL) | |
2694 { | |
2695 if (ins_buf == curbuf) | |
2696 found_all = TRUE; | |
2697 break; | |
2698 } | |
2699 | |
2700 // when ADDING, the text before the cursor matches, skip it | |
2701 if ( (compl_cont_status & CONT_ADDING) && ins_buf == curbuf | |
2702 && ini->lnum == pos->lnum | |
2703 && ini->col == pos->col) | |
2704 continue; | |
2705 ptr = ml_get_buf(ins_buf, pos->lnum, FALSE) + pos->col; | |
2706 if (ctrl_x_mode_line_or_eval()) | |
2707 { | |
2708 if (compl_cont_status & CONT_ADDING) | |
2709 { | |
2710 if (pos->lnum >= ins_buf->b_ml.ml_line_count) | |
2711 continue; | |
2712 ptr = ml_get_buf(ins_buf, pos->lnum + 1, FALSE); | |
2713 if (!p_paste) | |
2714 ptr = skipwhite(ptr); | |
2715 } | |
2716 len = (int)STRLEN(ptr); | |
2717 } | |
2718 else | |
2719 { | |
2720 char_u *tmp_ptr = ptr; | |
2721 | |
2722 if (compl_cont_status & CONT_ADDING) | |
2723 { | |
2724 tmp_ptr += compl_length; | |
2725 // Skip if already inside a word. | |
2726 if (vim_iswordp(tmp_ptr)) | |
2727 continue; | |
2728 // Find start of next word. | |
2729 tmp_ptr = find_word_start(tmp_ptr); | |
2730 } | |
2731 // Find end of this word. | |
2732 tmp_ptr = find_word_end(tmp_ptr); | |
2733 len = (int)(tmp_ptr - ptr); | |
2734 | |
2735 if ((compl_cont_status & CONT_ADDING) | |
2736 && len == compl_length) | |
2737 { | |
2738 if (pos->lnum < ins_buf->b_ml.ml_line_count) | |
2739 { | |
2740 // Try next line, if any. the new word will be | |
2741 // "join" as if the normal command "J" was used. | |
2742 // IOSIZE is always greater than | |
2743 // compl_length, so the next STRNCPY always | |
2744 // works -- Acevedo | |
2745 STRNCPY(IObuff, ptr, len); | |
2746 ptr = ml_get_buf(ins_buf, pos->lnum + 1, FALSE); | |
2747 tmp_ptr = ptr = skipwhite(ptr); | |
2748 // Find start of next word. | |
2749 tmp_ptr = find_word_start(tmp_ptr); | |
2750 // Find end of next word. | |
2751 tmp_ptr = find_word_end(tmp_ptr); | |
2752 if (tmp_ptr > ptr) | |
2753 { | |
2754 if (*ptr != ')' && IObuff[len - 1] != TAB) | |
2755 { | |
2756 if (IObuff[len - 1] != ' ') | |
2757 IObuff[len++] = ' '; | |
2758 // IObuf =~ "\k.* ", thus len >= 2 | |
2759 if (p_js | |
2760 && (IObuff[len - 2] == '.' | |
2761 || (vim_strchr(p_cpo, CPO_JOINSP) | |
2762 == NULL | |
2763 && (IObuff[len - 2] == '?' | |
2764 || IObuff[len - 2] == '!')))) | |
2765 IObuff[len++] = ' '; | |
2766 } | |
2767 // copy as much as possible of the new word | |
2768 if (tmp_ptr - ptr >= IOSIZE - len) | |
2769 tmp_ptr = ptr + IOSIZE - len - 1; | |
2770 STRNCPY(IObuff + len, ptr, tmp_ptr - ptr); | |
2771 len += (int)(tmp_ptr - ptr); | |
2772 flags |= CONT_S_IPOS; | |
2773 } | |
2774 IObuff[len] = NUL; | |
2775 ptr = IObuff; | |
2776 } | |
2777 if (len == compl_length) | |
2778 continue; | |
2779 } | |
2780 } | |
2781 if (ins_compl_add_infercase(ptr, len, p_ic, | |
2782 ins_buf == curbuf ? NULL : ins_buf->b_sfname, | |
2783 0, flags) != NOTDONE) | |
2784 { | |
2785 found_new_match = OK; | |
2786 break; | |
2787 } | |
2788 } | |
2789 p_scs = save_p_scs; | |
2790 p_ws = save_p_ws; | |
2791 } | |
2792 | |
2793 // check if compl_curr_match has changed, (e.g. other type of | |
2794 // expansion added something) | |
2795 if (type != 0 && compl_curr_match != compl_old_match) | |
2796 found_new_match = OK; | |
2797 | |
2798 // break the loop for specialized modes (use 'complete' just for the | |
2799 // generic ctrl_x_mode == CTRL_X_NORMAL) or when we've found a new | |
2800 // match | |
2801 if ((ctrl_x_mode != CTRL_X_NORMAL | |
2802 && !ctrl_x_mode_line_or_eval()) || found_new_match != FAIL) | |
2803 { | |
2804 if (got_int) | |
2805 break; | |
2806 // Fill the popup menu as soon as possible. | |
2807 if (type != -1) | |
2808 ins_compl_check_keys(0, FALSE); | |
2809 | |
2810 if ((ctrl_x_mode != CTRL_X_NORMAL | |
2811 && !ctrl_x_mode_line_or_eval()) || compl_interrupted) | |
2812 break; | |
2813 compl_started = TRUE; | |
2814 } | |
2815 else | |
2816 { | |
2817 // Mark a buffer scanned when it has been scanned completely | |
2818 if (type == 0 || type == CTRL_X_PATH_PATTERNS) | |
2819 ins_buf->b_scanned = TRUE; | |
2820 | |
2821 compl_started = FALSE; | |
2822 } | |
2823 } | |
2824 compl_started = TRUE; | |
2825 | |
2826 if ((ctrl_x_mode == CTRL_X_NORMAL || ctrl_x_mode_line_or_eval()) | |
2827 && *e_cpt == NUL) // Got to end of 'complete' | |
2828 found_new_match = FAIL; | |
2829 | |
2830 i = -1; // total of matches, unknown | |
2831 if (found_new_match == FAIL || (ctrl_x_mode != CTRL_X_NORMAL | |
2832 && !ctrl_x_mode_line_or_eval())) | |
2833 i = ins_compl_make_cyclic(); | |
2834 | |
2835 if (compl_old_match != NULL) | |
2836 { | |
2837 // If several matches were added (FORWARD) or the search failed and has | |
2838 // just been made cyclic then we have to move compl_curr_match to the | |
2839 // next or previous entry (if any) -- Acevedo | |
2840 compl_curr_match = compl_direction == FORWARD ? compl_old_match->cp_next | |
2841 : compl_old_match->cp_prev; | |
2842 if (compl_curr_match == NULL) | |
2843 compl_curr_match = compl_old_match; | |
2844 } | |
2845 return i; | |
2846 } | |
2847 | |
2848 /* | |
2849 * Delete the old text being completed. | |
2850 */ | |
2851 void | |
2852 ins_compl_delete(void) | |
2853 { | |
2854 int col; | |
2855 | |
2856 // In insert mode: Delete the typed part. | |
2857 // In replace mode: Put the old characters back, if any. | |
2858 col = compl_col + (compl_cont_status & CONT_ADDING ? compl_length : 0); | |
2859 if ((int)curwin->w_cursor.col > col) | |
2860 { | |
2861 if (stop_arrow() == FAIL) | |
2862 return; | |
2863 backspace_until_column(col); | |
2864 } | |
2865 | |
2866 // TODO: is this sufficient for redrawing? Redrawing everything causes | |
2867 // flicker, thus we can't do that. | |
2868 changed_cline_bef_curs(); | |
2869 // clear v:completed_item | |
2870 set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc_lock(VAR_FIXED)); | |
2871 } | |
2872 | |
2873 /* | |
2874 * Insert the new text being completed. | |
2875 * "in_compl_func" is TRUE when called from complete_check(). | |
2876 */ | |
2877 void | |
2878 ins_compl_insert(int in_compl_func) | |
2879 { | |
2880 dict_T *dict; | |
2881 | |
2882 ins_bytes(compl_shown_match->cp_str + ins_compl_len()); | |
2883 if (compl_shown_match->cp_flags & ORIGINAL_TEXT) | |
2884 compl_used_match = FALSE; | |
2885 else | |
2886 compl_used_match = TRUE; | |
2887 | |
2888 // Set completed item. | |
2889 // { word, abbr, menu, kind, info } | |
2890 dict = dict_alloc_lock(VAR_FIXED); | |
2891 if (dict != NULL) | |
2892 { | |
2893 dict_add_string(dict, "word", compl_shown_match->cp_str); | |
2894 dict_add_string(dict, "abbr", compl_shown_match->cp_text[CPT_ABBR]); | |
2895 dict_add_string(dict, "menu", compl_shown_match->cp_text[CPT_MENU]); | |
2896 dict_add_string(dict, "kind", compl_shown_match->cp_text[CPT_KIND]); | |
2897 dict_add_string(dict, "info", compl_shown_match->cp_text[CPT_INFO]); | |
2898 dict_add_string(dict, "user_data", | |
2899 compl_shown_match->cp_text[CPT_USER_DATA]); | |
2900 } | |
2901 set_vim_var_dict(VV_COMPLETED_ITEM, dict); | |
2902 if (!in_compl_func) | |
2903 compl_curr_match = compl_shown_match; | |
2904 } | |
2905 | |
2906 /* | |
2907 * Fill in the next completion in the current direction. | |
2908 * If "allow_get_expansion" is TRUE, then we may call ins_compl_get_exp() to | |
2909 * get more completions. If it is FALSE, then we just do nothing when there | |
2910 * are no more completions in a given direction. The latter case is used when | |
2911 * we are still in the middle of finding completions, to allow browsing | |
2912 * through the ones found so far. | |
2913 * Return the total number of matches, or -1 if still unknown -- webb. | |
2914 * | |
2915 * compl_curr_match is currently being used by ins_compl_get_exp(), so we use | |
2916 * compl_shown_match here. | |
2917 * | |
2918 * Note that this function may be called recursively once only. First with | |
2919 * "allow_get_expansion" TRUE, which calls ins_compl_get_exp(), which in turn | |
2920 * calls this function with "allow_get_expansion" FALSE. | |
2921 */ | |
2922 static int | |
2923 ins_compl_next( | |
2924 int allow_get_expansion, | |
2925 int count, // repeat completion this many times; should | |
2926 // be at least 1 | |
2927 int insert_match, // Insert the newly selected match | |
2928 int in_compl_func) // called from complete_check() | |
2929 { | |
2930 int num_matches = -1; | |
2931 int todo = count; | |
2932 compl_T *found_compl = NULL; | |
2933 int found_end = FALSE; | |
2934 int advance; | |
2935 int started = compl_started; | |
2936 | |
2937 // When user complete function return -1 for findstart which is next | |
2938 // time of 'always', compl_shown_match become NULL. | |
2939 if (compl_shown_match == NULL) | |
2940 return -1; | |
2941 | |
2942 if (compl_leader != NULL | |
2943 && (compl_shown_match->cp_flags & ORIGINAL_TEXT) == 0) | |
2944 { | |
2945 // Set "compl_shown_match" to the actually shown match, it may differ | |
2946 // when "compl_leader" is used to omit some of the matches. | |
2947 while (!ins_compl_equal(compl_shown_match, | |
2948 compl_leader, (int)STRLEN(compl_leader)) | |
2949 && compl_shown_match->cp_next != NULL | |
2950 && compl_shown_match->cp_next != compl_first_match) | |
2951 compl_shown_match = compl_shown_match->cp_next; | |
2952 | |
2953 // If we didn't find it searching forward, and compl_shows_dir is | |
2954 // backward, find the last match. | |
2955 if (compl_shows_dir == BACKWARD | |
2956 && !ins_compl_equal(compl_shown_match, | |
2957 compl_leader, (int)STRLEN(compl_leader)) | |
2958 && (compl_shown_match->cp_next == NULL | |
2959 || compl_shown_match->cp_next == compl_first_match)) | |
2960 { | |
2961 while (!ins_compl_equal(compl_shown_match, | |
2962 compl_leader, (int)STRLEN(compl_leader)) | |
2963 && compl_shown_match->cp_prev != NULL | |
2964 && compl_shown_match->cp_prev != compl_first_match) | |
2965 compl_shown_match = compl_shown_match->cp_prev; | |
2966 } | |
2967 } | |
2968 | |
2969 if (allow_get_expansion && insert_match | |
2970 && (!(compl_get_longest || compl_restarting) || compl_used_match)) | |
2971 // Delete old text to be replaced | |
2972 ins_compl_delete(); | |
2973 | |
2974 // When finding the longest common text we stick at the original text, | |
2975 // don't let CTRL-N or CTRL-P move to the first match. | |
2976 advance = count != 1 || !allow_get_expansion || !compl_get_longest; | |
2977 | |
2978 // When restarting the search don't insert the first match either. | |
2979 if (compl_restarting) | |
2980 { | |
2981 advance = FALSE; | |
2982 compl_restarting = FALSE; | |
2983 } | |
2984 | |
2985 // Repeat this for when <PageUp> or <PageDown> is typed. But don't wrap | |
2986 // around. | |
2987 while (--todo >= 0) | |
2988 { | |
2989 if (compl_shows_dir == FORWARD && compl_shown_match->cp_next != NULL) | |
2990 { | |
2991 compl_shown_match = compl_shown_match->cp_next; | |
2992 found_end = (compl_first_match != NULL | |
2993 && (compl_shown_match->cp_next == compl_first_match | |
2994 || compl_shown_match == compl_first_match)); | |
2995 } | |
2996 else if (compl_shows_dir == BACKWARD | |
2997 && compl_shown_match->cp_prev != NULL) | |
2998 { | |
2999 found_end = (compl_shown_match == compl_first_match); | |
3000 compl_shown_match = compl_shown_match->cp_prev; | |
3001 found_end |= (compl_shown_match == compl_first_match); | |
3002 } | |
3003 else | |
3004 { | |
3005 if (!allow_get_expansion) | |
3006 { | |
3007 if (advance) | |
3008 { | |
3009 if (compl_shows_dir == BACKWARD) | |
3010 compl_pending -= todo + 1; | |
3011 else | |
3012 compl_pending += todo + 1; | |
3013 } | |
3014 return -1; | |
3015 } | |
3016 | |
3017 if (!compl_no_select && advance) | |
3018 { | |
3019 if (compl_shows_dir == BACKWARD) | |
3020 --compl_pending; | |
3021 else | |
3022 ++compl_pending; | |
3023 } | |
3024 | |
3025 // Find matches. | |
3026 num_matches = ins_compl_get_exp(&compl_startpos); | |
3027 | |
3028 // handle any pending completions | |
3029 while (compl_pending != 0 && compl_direction == compl_shows_dir | |
3030 && advance) | |
3031 { | |
3032 if (compl_pending > 0 && compl_shown_match->cp_next != NULL) | |
3033 { | |
3034 compl_shown_match = compl_shown_match->cp_next; | |
3035 --compl_pending; | |
3036 } | |
3037 if (compl_pending < 0 && compl_shown_match->cp_prev != NULL) | |
3038 { | |
3039 compl_shown_match = compl_shown_match->cp_prev; | |
3040 ++compl_pending; | |
3041 } | |
3042 else | |
3043 break; | |
3044 } | |
3045 found_end = FALSE; | |
3046 } | |
3047 if ((compl_shown_match->cp_flags & ORIGINAL_TEXT) == 0 | |
3048 && compl_leader != NULL | |
3049 && !ins_compl_equal(compl_shown_match, | |
3050 compl_leader, (int)STRLEN(compl_leader))) | |
3051 ++todo; | |
3052 else | |
3053 // Remember a matching item. | |
3054 found_compl = compl_shown_match; | |
3055 | |
3056 // Stop at the end of the list when we found a usable match. | |
3057 if (found_end) | |
3058 { | |
3059 if (found_compl != NULL) | |
3060 { | |
3061 compl_shown_match = found_compl; | |
3062 break; | |
3063 } | |
3064 todo = 1; // use first usable match after wrapping around | |
3065 } | |
3066 } | |
3067 | |
3068 // Insert the text of the new completion, or the compl_leader. | |
3069 if (compl_no_insert && !started) | |
3070 { | |
3071 ins_bytes(compl_orig_text + ins_compl_len()); | |
3072 compl_used_match = FALSE; | |
3073 } | |
3074 else if (insert_match) | |
3075 { | |
3076 if (!compl_get_longest || compl_used_match) | |
3077 ins_compl_insert(in_compl_func); | |
3078 else | |
3079 ins_bytes(compl_leader + ins_compl_len()); | |
3080 } | |
3081 else | |
3082 compl_used_match = FALSE; | |
3083 | |
3084 if (!allow_get_expansion) | |
3085 { | |
3086 // may undisplay the popup menu first | |
3087 ins_compl_upd_pum(); | |
3088 | |
3089 if (pum_enough_matches()) | |
3090 // Will display the popup menu, don't redraw yet to avoid flicker. | |
3091 pum_call_update_screen(); | |
3092 else | |
3093 // Not showing the popup menu yet, redraw to show the user what was | |
3094 // inserted. | |
3095 update_screen(0); | |
3096 | |
3097 // display the updated popup menu | |
3098 ins_compl_show_pum(); | |
3099 #ifdef FEAT_GUI | |
3100 if (gui.in_use) | |
3101 { | |
3102 // Show the cursor after the match, not after the redrawn text. | |
3103 setcursor(); | |
3104 out_flush_cursor(FALSE, FALSE); | |
3105 } | |
3106 #endif | |
3107 | |
3108 // Delete old text to be replaced, since we're still searching and | |
3109 // don't want to match ourselves! | |
3110 ins_compl_delete(); | |
3111 } | |
3112 | |
3113 // Enter will select a match when the match wasn't inserted and the popup | |
3114 // menu is visible. | |
3115 if (compl_no_insert && !started) | |
3116 compl_enter_selects = TRUE; | |
3117 else | |
3118 compl_enter_selects = !insert_match && compl_match_array != NULL; | |
3119 | |
3120 // Show the file name for the match (if any) | |
3121 // Truncate the file name to avoid a wait for return. | |
3122 if (compl_shown_match->cp_fname != NULL) | |
3123 { | |
3124 char *lead = _("match in file"); | |
3125 int space = sc_col - vim_strsize((char_u *)lead) - 2; | |
3126 char_u *s; | |
3127 char_u *e; | |
3128 | |
3129 if (space > 0) | |
3130 { | |
3131 // We need the tail that fits. With double-byte encoding going | |
3132 // back from the end is very slow, thus go from the start and keep | |
3133 // the text that fits in "space" between "s" and "e". | |
3134 for (s = e = compl_shown_match->cp_fname; *e != NUL; MB_PTR_ADV(e)) | |
3135 { | |
3136 space -= ptr2cells(e); | |
3137 while (space < 0) | |
3138 { | |
3139 space += ptr2cells(s); | |
3140 MB_PTR_ADV(s); | |
3141 } | |
3142 } | |
3143 vim_snprintf((char *)IObuff, IOSIZE, "%s %s%s", lead, | |
3144 s > compl_shown_match->cp_fname ? "<" : "", s); | |
3145 msg((char *)IObuff); | |
3146 redraw_cmdline = FALSE; // don't overwrite! | |
3147 } | |
3148 } | |
3149 | |
3150 return num_matches; | |
3151 } | |
3152 | |
3153 /* | |
3154 * Call this while finding completions, to check whether the user has hit a key | |
3155 * that should change the currently displayed completion, or exit completion | |
3156 * mode. Also, when compl_pending is not zero, show a completion as soon as | |
3157 * possible. -- webb | |
3158 * "frequency" specifies out of how many calls we actually check. | |
3159 * "in_compl_func" is TRUE when called from complete_check(), don't set | |
3160 * compl_curr_match. | |
3161 */ | |
3162 void | |
3163 ins_compl_check_keys(int frequency, int in_compl_func) | |
3164 { | |
3165 static int count = 0; | |
3166 int c; | |
3167 | |
3168 // Don't check when reading keys from a script, :normal or feedkeys(). | |
3169 // That would break the test scripts. But do check for keys when called | |
3170 // from complete_check(). | |
3171 if (!in_compl_func && (using_script() || ex_normal_busy)) | |
3172 return; | |
3173 | |
3174 // Only do this at regular intervals | |
3175 if (++count < frequency) | |
3176 return; | |
3177 count = 0; | |
3178 | |
3179 // Check for a typed key. Do use mappings, otherwise vim_is_ctrl_x_key() | |
3180 // can't do its work correctly. | |
3181 c = vpeekc_any(); | |
3182 if (c != NUL) | |
3183 { | |
3184 if (vim_is_ctrl_x_key(c) && c != Ctrl_X && c != Ctrl_R) | |
3185 { | |
3186 c = safe_vgetc(); // Eat the character | |
3187 compl_shows_dir = ins_compl_key2dir(c); | |
3188 (void)ins_compl_next(FALSE, ins_compl_key2count(c), | |
3189 c != K_UP && c != K_DOWN, in_compl_func); | |
3190 } | |
3191 else | |
3192 { | |
3193 // Need to get the character to have KeyTyped set. We'll put it | |
3194 // back with vungetc() below. But skip K_IGNORE. | |
3195 c = safe_vgetc(); | |
3196 if (c != K_IGNORE) | |
3197 { | |
3198 // Don't interrupt completion when the character wasn't typed, | |
3199 // e.g., when doing @q to replay keys. | |
3200 if (c != Ctrl_R && KeyTyped) | |
3201 compl_interrupted = TRUE; | |
3202 | |
3203 vungetc(c); | |
3204 } | |
3205 } | |
3206 } | |
3207 if (compl_pending != 0 && !got_int && !compl_no_insert) | |
3208 { | |
3209 int todo = compl_pending > 0 ? compl_pending : -compl_pending; | |
3210 | |
3211 compl_pending = 0; | |
3212 (void)ins_compl_next(FALSE, todo, TRUE, in_compl_func); | |
3213 } | |
3214 } | |
3215 | |
3216 /* | |
3217 * Decide the direction of Insert mode complete from the key typed. | |
3218 * Returns BACKWARD or FORWARD. | |
3219 */ | |
3220 static int | |
3221 ins_compl_key2dir(int c) | |
3222 { | |
3223 if (c == Ctrl_P || c == Ctrl_L | |
3224 || c == K_PAGEUP || c == K_KPAGEUP || c == K_S_UP || c == K_UP) | |
3225 return BACKWARD; | |
3226 return FORWARD; | |
3227 } | |
3228 | |
3229 /* | |
3230 * Return TRUE for keys that are used for completion only when the popup menu | |
3231 * is visible. | |
3232 */ | |
3233 static int | |
3234 ins_compl_pum_key(int c) | |
3235 { | |
3236 return pum_visible() && (c == K_PAGEUP || c == K_KPAGEUP || c == K_S_UP | |
3237 || c == K_PAGEDOWN || c == K_KPAGEDOWN || c == K_S_DOWN | |
3238 || c == K_UP || c == K_DOWN); | |
3239 } | |
3240 | |
3241 /* | |
3242 * Decide the number of completions to move forward. | |
3243 * Returns 1 for most keys, height of the popup menu for page-up/down keys. | |
3244 */ | |
3245 static int | |
3246 ins_compl_key2count(int c) | |
3247 { | |
3248 int h; | |
3249 | |
3250 if (ins_compl_pum_key(c) && c != K_UP && c != K_DOWN) | |
3251 { | |
3252 h = pum_get_height(); | |
3253 if (h > 3) | |
3254 h -= 2; // keep some context | |
3255 return h; | |
3256 } | |
3257 return 1; | |
3258 } | |
3259 | |
3260 /* | |
3261 * Return TRUE if completion with "c" should insert the match, FALSE if only | |
3262 * to change the currently selected completion. | |
3263 */ | |
3264 static int | |
3265 ins_compl_use_match(int c) | |
3266 { | |
3267 switch (c) | |
3268 { | |
3269 case K_UP: | |
3270 case K_DOWN: | |
3271 case K_PAGEDOWN: | |
3272 case K_KPAGEDOWN: | |
3273 case K_S_DOWN: | |
3274 case K_PAGEUP: | |
3275 case K_KPAGEUP: | |
3276 case K_S_UP: | |
3277 return FALSE; | |
3278 } | |
3279 return TRUE; | |
3280 } | |
3281 | |
3282 /* | |
3283 * Do Insert mode completion. | |
3284 * Called when character "c" was typed, which has a meaning for completion. | |
3285 * Returns OK if completion was done, FAIL if something failed (out of mem). | |
3286 */ | |
3287 int | |
3288 ins_complete(int c, int enable_pum) | |
3289 { | |
3290 char_u *line; | |
3291 int startcol = 0; // column where searched text starts | |
3292 colnr_T curs_col; // cursor column | |
3293 int n; | |
3294 int save_w_wrow; | |
3295 int save_w_leftcol; | |
3296 int insert_match; | |
3297 int save_did_ai = did_ai; | |
3298 | |
3299 compl_direction = ins_compl_key2dir(c); | |
3300 insert_match = ins_compl_use_match(c); | |
3301 | |
3302 if (!compl_started) | |
3303 { | |
3304 // First time we hit ^N or ^P (in a row, I mean) | |
3305 | |
3306 did_ai = FALSE; | |
3307 #ifdef FEAT_SMARTINDENT | |
3308 did_si = FALSE; | |
3309 can_si = FALSE; | |
3310 can_si_back = FALSE; | |
3311 #endif | |
3312 if (stop_arrow() == FAIL) | |
3313 return FAIL; | |
3314 | |
3315 line = ml_get(curwin->w_cursor.lnum); | |
3316 curs_col = curwin->w_cursor.col; | |
3317 compl_pending = 0; | |
3318 | |
3319 // If this same ctrl_x_mode has been interrupted use the text from | |
3320 // "compl_startpos" to the cursor as a pattern to add a new word | |
3321 // instead of expand the one before the cursor, in word-wise if | |
3322 // "compl_startpos" is not in the same line as the cursor then fix it | |
3323 // (the line has been split because it was longer than 'tw'). if SOL | |
3324 // is set then skip the previous pattern, a word at the beginning of | |
3325 // the line has been inserted, we'll look for that -- Acevedo. | |
3326 if ((compl_cont_status & CONT_INTRPT) == CONT_INTRPT | |
3327 && compl_cont_mode == ctrl_x_mode) | |
3328 { | |
3329 // it is a continued search | |
3330 compl_cont_status &= ~CONT_INTRPT; // remove INTRPT | |
3331 if (ctrl_x_mode == CTRL_X_NORMAL | |
3332 || ctrl_x_mode == CTRL_X_PATH_PATTERNS | |
3333 || ctrl_x_mode == CTRL_X_PATH_DEFINES) | |
3334 { | |
3335 if (compl_startpos.lnum != curwin->w_cursor.lnum) | |
3336 { | |
3337 // line (probably) wrapped, set compl_startpos to the | |
3338 // first non_blank in the line, if it is not a wordchar | |
3339 // include it to get a better pattern, but then we don't | |
3340 // want the "\\<" prefix, check it bellow | |
3341 compl_col = (colnr_T)getwhitecols(line); | |
3342 compl_startpos.col = compl_col; | |
3343 compl_startpos.lnum = curwin->w_cursor.lnum; | |
3344 compl_cont_status &= ~CONT_SOL; // clear SOL if present | |
3345 } | |
3346 else | |
3347 { | |
3348 // S_IPOS was set when we inserted a word that was at the | |
3349 // beginning of the line, which means that we'll go to SOL | |
3350 // mode but first we need to redefine compl_startpos | |
3351 if (compl_cont_status & CONT_S_IPOS) | |
3352 { | |
3353 compl_cont_status |= CONT_SOL; | |
3354 compl_startpos.col = (colnr_T)(skipwhite( | |
3355 line + compl_length | |
3356 + compl_startpos.col) - line); | |
3357 } | |
3358 compl_col = compl_startpos.col; | |
3359 } | |
3360 compl_length = curwin->w_cursor.col - (int)compl_col; | |
3361 // IObuff is used to add a "word from the next line" would we | |
3362 // have enough space? just being paranoid | |
3363 #define MIN_SPACE 75 | |
3364 if (compl_length > (IOSIZE - MIN_SPACE)) | |
3365 { | |
3366 compl_cont_status &= ~CONT_SOL; | |
3367 compl_length = (IOSIZE - MIN_SPACE); | |
3368 compl_col = curwin->w_cursor.col - compl_length; | |
3369 } | |
3370 compl_cont_status |= CONT_ADDING | CONT_N_ADDS; | |
3371 if (compl_length < 1) | |
3372 compl_cont_status &= CONT_LOCAL; | |
3373 } | |
3374 else if (ctrl_x_mode_line_or_eval()) | |
3375 compl_cont_status = CONT_ADDING | CONT_N_ADDS; | |
3376 else | |
3377 compl_cont_status = 0; | |
3378 } | |
3379 else | |
3380 compl_cont_status &= CONT_LOCAL; | |
3381 | |
3382 if (!(compl_cont_status & CONT_ADDING)) // normal expansion | |
3383 { | |
3384 compl_cont_mode = ctrl_x_mode; | |
3385 if (ctrl_x_mode != CTRL_X_NORMAL) | |
3386 // Remove LOCAL if ctrl_x_mode != CTRL_X_NORMAL | |
3387 compl_cont_status = 0; | |
3388 compl_cont_status |= CONT_N_ADDS; | |
3389 compl_startpos = curwin->w_cursor; | |
3390 startcol = (int)curs_col; | |
3391 compl_col = 0; | |
3392 } | |
3393 | |
3394 // Work out completion pattern and original text -- webb | |
3395 if (ctrl_x_mode == CTRL_X_NORMAL || (ctrl_x_mode & CTRL_X_WANT_IDENT)) | |
3396 { | |
3397 if ((compl_cont_status & CONT_SOL) | |
3398 || ctrl_x_mode == CTRL_X_PATH_DEFINES) | |
3399 { | |
3400 if (!(compl_cont_status & CONT_ADDING)) | |
3401 { | |
3402 while (--startcol >= 0 && vim_isIDc(line[startcol])) | |
3403 ; | |
3404 compl_col += ++startcol; | |
3405 compl_length = curs_col - startcol; | |
3406 } | |
3407 if (p_ic) | |
3408 compl_pattern = str_foldcase(line + compl_col, | |
3409 compl_length, NULL, 0); | |
3410 else | |
3411 compl_pattern = vim_strnsave(line + compl_col, | |
3412 compl_length); | |
3413 if (compl_pattern == NULL) | |
3414 return FAIL; | |
3415 } | |
3416 else if (compl_cont_status & CONT_ADDING) | |
3417 { | |
3418 char_u *prefix = (char_u *)"\\<"; | |
3419 | |
3420 // we need up to 2 extra chars for the prefix | |
3421 compl_pattern = alloc(quote_meta(NULL, line + compl_col, | |
3422 compl_length) + 2); | |
3423 if (compl_pattern == NULL) | |
3424 return FAIL; | |
3425 if (!vim_iswordp(line + compl_col) | |
3426 || (compl_col > 0 | |
3427 && (vim_iswordp(mb_prevptr(line, line + compl_col))))) | |
3428 prefix = (char_u *)""; | |
3429 STRCPY((char *)compl_pattern, prefix); | |
3430 (void)quote_meta(compl_pattern + STRLEN(prefix), | |
3431 line + compl_col, compl_length); | |
3432 } | |
3433 else if (--startcol < 0 | |
3434 || !vim_iswordp(mb_prevptr(line, line + startcol + 1))) | |
3435 { | |
3436 // Match any word of at least two chars | |
3437 compl_pattern = vim_strsave((char_u *)"\\<\\k\\k"); | |
3438 if (compl_pattern == NULL) | |
3439 return FAIL; | |
3440 compl_col += curs_col; | |
3441 compl_length = 0; | |
3442 } | |
3443 else | |
3444 { | |
3445 // Search the point of change class of multibyte character | |
3446 // or not a word single byte character backward. | |
3447 if (has_mbyte) | |
3448 { | |
3449 int base_class; | |
3450 int head_off; | |
3451 | |
3452 startcol -= (*mb_head_off)(line, line + startcol); | |
3453 base_class = mb_get_class(line + startcol); | |
3454 while (--startcol >= 0) | |
3455 { | |
3456 head_off = (*mb_head_off)(line, line + startcol); | |
3457 if (base_class != mb_get_class(line + startcol | |
3458 - head_off)) | |
3459 break; | |
3460 startcol -= head_off; | |
3461 } | |
3462 } | |
3463 else | |
3464 while (--startcol >= 0 && vim_iswordc(line[startcol])) | |
3465 ; | |
3466 compl_col += ++startcol; | |
3467 compl_length = (int)curs_col - startcol; | |
3468 if (compl_length == 1) | |
3469 { | |
3470 // Only match word with at least two chars -- webb | |
3471 // there's no need to call quote_meta, | |
3472 // alloc(7) is enough -- Acevedo | |
3473 compl_pattern = alloc(7); | |
3474 if (compl_pattern == NULL) | |
3475 return FAIL; | |
3476 STRCPY((char *)compl_pattern, "\\<"); | |
3477 (void)quote_meta(compl_pattern + 2, line + compl_col, 1); | |
3478 STRCAT((char *)compl_pattern, "\\k"); | |
3479 } | |
3480 else | |
3481 { | |
3482 compl_pattern = alloc(quote_meta(NULL, line + compl_col, | |
3483 compl_length) + 2); | |
3484 if (compl_pattern == NULL) | |
3485 return FAIL; | |
3486 STRCPY((char *)compl_pattern, "\\<"); | |
3487 (void)quote_meta(compl_pattern + 2, line + compl_col, | |
3488 compl_length); | |
3489 } | |
3490 } | |
3491 } | |
3492 else if (ctrl_x_mode_line_or_eval()) | |
3493 { | |
3494 compl_col = (colnr_T)getwhitecols(line); | |
3495 compl_length = (int)curs_col - (int)compl_col; | |
3496 if (compl_length < 0) // cursor in indent: empty pattern | |
3497 compl_length = 0; | |
3498 if (p_ic) | |
3499 compl_pattern = str_foldcase(line + compl_col, compl_length, | |
3500 NULL, 0); | |
3501 else | |
3502 compl_pattern = vim_strnsave(line + compl_col, compl_length); | |
3503 if (compl_pattern == NULL) | |
3504 return FAIL; | |
3505 } | |
3506 else if (ctrl_x_mode == CTRL_X_FILES) | |
3507 { | |
3508 // Go back to just before the first filename character. | |
3509 if (startcol > 0) | |
3510 { | |
3511 char_u *p = line + startcol; | |
3512 | |
3513 MB_PTR_BACK(line, p); | |
3514 while (p > line && vim_isfilec(PTR2CHAR(p))) | |
3515 MB_PTR_BACK(line, p); | |
3516 if (p == line && vim_isfilec(PTR2CHAR(p))) | |
3517 startcol = 0; | |
3518 else | |
3519 startcol = (int)(p - line) + 1; | |
3520 } | |
3521 | |
3522 compl_col += startcol; | |
3523 compl_length = (int)curs_col - startcol; | |
3524 compl_pattern = addstar(line + compl_col, compl_length, | |
3525 EXPAND_FILES); | |
3526 if (compl_pattern == NULL) | |
3527 return FAIL; | |
3528 } | |
3529 else if (ctrl_x_mode == CTRL_X_CMDLINE) | |
3530 { | |
3531 compl_pattern = vim_strnsave(line, curs_col); | |
3532 if (compl_pattern == NULL) | |
3533 return FAIL; | |
3534 set_cmd_context(&compl_xp, compl_pattern, | |
3535 (int)STRLEN(compl_pattern), curs_col, FALSE); | |
3536 if (compl_xp.xp_context == EXPAND_UNSUCCESSFUL | |
3537 || compl_xp.xp_context == EXPAND_NOTHING) | |
3538 // No completion possible, use an empty pattern to get a | |
3539 // "pattern not found" message. | |
3540 compl_col = curs_col; | |
3541 else | |
3542 compl_col = (int)(compl_xp.xp_pattern - compl_pattern); | |
3543 compl_length = curs_col - compl_col; | |
3544 } | |
3545 else if (ctrl_x_mode == CTRL_X_FUNCTION || ctrl_x_mode == CTRL_X_OMNI) | |
3546 { | |
3547 #ifdef FEAT_COMPL_FUNC | |
3548 // Call user defined function 'completefunc' with "a:findstart" | |
3549 // set to 1 to obtain the length of text to use for completion. | |
3550 typval_T args[3]; | |
3551 int col; | |
3552 char_u *funcname; | |
3553 pos_T pos; | |
3554 win_T *curwin_save; | |
3555 buf_T *curbuf_save; | |
3556 int save_State = State; | |
3557 | |
3558 // Call 'completefunc' or 'omnifunc' and get pattern length as a | |
3559 // string | |
3560 funcname = ctrl_x_mode == CTRL_X_FUNCTION | |
3561 ? curbuf->b_p_cfu : curbuf->b_p_ofu; | |
3562 if (*funcname == NUL) | |
3563 { | |
3564 semsg(_(e_notset), ctrl_x_mode == CTRL_X_FUNCTION | |
3565 ? "completefunc" : "omnifunc"); | |
3566 // restore did_ai, so that adding comment leader works | |
3567 did_ai = save_did_ai; | |
3568 return FAIL; | |
3569 } | |
3570 | |
3571 args[0].v_type = VAR_NUMBER; | |
3572 args[0].vval.v_number = 1; | |
3573 args[1].v_type = VAR_STRING; | |
3574 args[1].vval.v_string = (char_u *)""; | |
3575 args[2].v_type = VAR_UNKNOWN; | |
3576 pos = curwin->w_cursor; | |
3577 curwin_save = curwin; | |
3578 curbuf_save = curbuf; | |
3579 col = call_func_retnr(funcname, 2, args); | |
3580 | |
3581 State = save_State; | |
3582 if (curwin_save != curwin || curbuf_save != curbuf) | |
3583 { | |
3584 emsg(_(e_complwin)); | |
3585 return FAIL; | |
3586 } | |
3587 curwin->w_cursor = pos; // restore the cursor position | |
3588 validate_cursor(); | |
3589 if (!EQUAL_POS(curwin->w_cursor, pos)) | |
3590 { | |
3591 emsg(_(e_compldel)); | |
3592 return FAIL; | |
3593 } | |
3594 | |
3595 // Return value -2 means the user complete function wants to | |
3596 // cancel the complete without an error. | |
3597 // Return value -3 does the same as -2 and leaves CTRL-X mode. | |
3598 if (col == -2) | |
3599 return FAIL; | |
3600 if (col == -3) | |
3601 { | |
3602 ctrl_x_mode = CTRL_X_NORMAL; | |
3603 edit_submode = NULL; | |
3604 if (!shortmess(SHM_COMPLETIONMENU)) | |
3605 msg_clr_cmdline(); | |
3606 return FAIL; | |
3607 } | |
3608 | |
3609 // Reset extended parameters of completion, when start new | |
3610 // completion. | |
3611 compl_opt_refresh_always = FALSE; | |
3612 compl_opt_suppress_empty = FALSE; | |
3613 | |
3614 if (col < 0) | |
3615 col = curs_col; | |
3616 compl_col = col; | |
3617 if (compl_col > curs_col) | |
3618 compl_col = curs_col; | |
3619 | |
3620 // Setup variables for completion. Need to obtain "line" again, | |
3621 // it may have become invalid. | |
3622 line = ml_get(curwin->w_cursor.lnum); | |
3623 compl_length = curs_col - compl_col; | |
3624 compl_pattern = vim_strnsave(line + compl_col, compl_length); | |
3625 if (compl_pattern == NULL) | |
3626 #endif | |
3627 return FAIL; | |
3628 } | |
3629 else if (ctrl_x_mode == CTRL_X_SPELL) | |
3630 { | |
3631 #ifdef FEAT_SPELL | |
3632 if (spell_bad_len > 0) | |
3633 compl_col = curs_col - spell_bad_len; | |
3634 else | |
3635 compl_col = spell_word_start(startcol); | |
3636 if (compl_col >= (colnr_T)startcol) | |
3637 { | |
3638 compl_length = 0; | |
3639 compl_col = curs_col; | |
3640 } | |
3641 else | |
3642 { | |
3643 spell_expand_check_cap(compl_col); | |
3644 compl_length = (int)curs_col - compl_col; | |
3645 } | |
3646 // Need to obtain "line" again, it may have become invalid. | |
3647 line = ml_get(curwin->w_cursor.lnum); | |
3648 compl_pattern = vim_strnsave(line + compl_col, compl_length); | |
3649 if (compl_pattern == NULL) | |
3650 #endif | |
3651 return FAIL; | |
3652 } | |
3653 else | |
3654 { | |
3655 internal_error("ins_complete()"); | |
3656 return FAIL; | |
3657 } | |
3658 | |
3659 if (compl_cont_status & CONT_ADDING) | |
3660 { | |
3661 edit_submode_pre = (char_u *)_(" Adding"); | |
3662 if (ctrl_x_mode_line_or_eval()) | |
3663 { | |
3664 // Insert a new line, keep indentation but ignore 'comments' | |
3665 #ifdef FEAT_COMMENTS | |
3666 char_u *old = curbuf->b_p_com; | |
3667 | |
3668 curbuf->b_p_com = (char_u *)""; | |
3669 #endif | |
3670 compl_startpos.lnum = curwin->w_cursor.lnum; | |
3671 compl_startpos.col = compl_col; | |
3672 ins_eol('\r'); | |
3673 #ifdef FEAT_COMMENTS | |
3674 curbuf->b_p_com = old; | |
3675 #endif | |
3676 compl_length = 0; | |
3677 compl_col = curwin->w_cursor.col; | |
3678 } | |
3679 } | |
3680 else | |
3681 { | |
3682 edit_submode_pre = NULL; | |
3683 compl_startpos.col = compl_col; | |
3684 } | |
3685 | |
3686 if (compl_cont_status & CONT_LOCAL) | |
3687 edit_submode = (char_u *)_(ctrl_x_msgs[CTRL_X_LOCAL_MSG]); | |
3688 else | |
3689 edit_submode = (char_u *)_(CTRL_X_MSG(ctrl_x_mode)); | |
3690 | |
3691 // If any of the original typed text has been changed we need to fix | |
3692 // the redo buffer. | |
3693 ins_compl_fixRedoBufForLeader(NULL); | |
3694 | |
3695 // Always add completion for the original text. | |
3696 vim_free(compl_orig_text); | |
3697 compl_orig_text = vim_strnsave(line + compl_col, compl_length); | |
3698 if (compl_orig_text == NULL || ins_compl_add(compl_orig_text, | |
3699 -1, p_ic, NULL, NULL, 0, ORIGINAL_TEXT, FALSE) != OK) | |
3700 { | |
3701 VIM_CLEAR(compl_pattern); | |
3702 VIM_CLEAR(compl_orig_text); | |
3703 return FAIL; | |
3704 } | |
3705 | |
3706 // showmode might reset the internal line pointers, so it must | |
3707 // be called before line = ml_get(), or when this address is no | |
3708 // longer needed. -- Acevedo. | |
3709 edit_submode_extra = (char_u *)_("-- Searching..."); | |
3710 edit_submode_highl = HLF_COUNT; | |
3711 showmode(); | |
3712 edit_submode_extra = NULL; | |
3713 out_flush(); | |
3714 } | |
3715 else if (insert_match && stop_arrow() == FAIL) | |
3716 return FAIL; | |
3717 | |
3718 compl_shown_match = compl_curr_match; | |
3719 compl_shows_dir = compl_direction; | |
3720 | |
3721 // Find next match (and following matches). | |
3722 save_w_wrow = curwin->w_wrow; | |
3723 save_w_leftcol = curwin->w_leftcol; | |
3724 n = ins_compl_next(TRUE, ins_compl_key2count(c), insert_match, FALSE); | |
3725 | |
3726 // may undisplay the popup menu | |
3727 ins_compl_upd_pum(); | |
3728 | |
3729 if (n > 1) // all matches have been found | |
3730 compl_matches = n; | |
3731 compl_curr_match = compl_shown_match; | |
3732 compl_direction = compl_shows_dir; | |
3733 | |
3734 // Eat the ESC that vgetc() returns after a CTRL-C to avoid leaving Insert | |
3735 // mode. | |
3736 if (got_int && !global_busy) | |
3737 { | |
3738 (void)vgetc(); | |
3739 got_int = FALSE; | |
3740 } | |
3741 | |
3742 // we found no match if the list has only the "compl_orig_text"-entry | |
3743 if (compl_first_match == compl_first_match->cp_next) | |
3744 { | |
3745 edit_submode_extra = (compl_cont_status & CONT_ADDING) | |
3746 && compl_length > 1 | |
3747 ? (char_u *)_(e_hitend) : (char_u *)_(e_patnotf); | |
3748 edit_submode_highl = HLF_E; | |
3749 // remove N_ADDS flag, so next ^X<> won't try to go to ADDING mode, | |
3750 // because we couldn't expand anything at first place, but if we used | |
3751 // ^P, ^N, ^X^I or ^X^D we might want to add-expand a single-char-word | |
3752 // (such as M in M'exico) if not tried already. -- Acevedo | |
3753 if ( compl_length > 1 | |
3754 || (compl_cont_status & CONT_ADDING) | |
3755 || (ctrl_x_mode != CTRL_X_NORMAL | |
3756 && ctrl_x_mode != CTRL_X_PATH_PATTERNS | |
3757 && ctrl_x_mode != CTRL_X_PATH_DEFINES)) | |
3758 compl_cont_status &= ~CONT_N_ADDS; | |
3759 } | |
3760 | |
3761 if (compl_curr_match->cp_flags & CONT_S_IPOS) | |
3762 compl_cont_status |= CONT_S_IPOS; | |
3763 else | |
3764 compl_cont_status &= ~CONT_S_IPOS; | |
3765 | |
3766 if (edit_submode_extra == NULL) | |
3767 { | |
3768 if (compl_curr_match->cp_flags & ORIGINAL_TEXT) | |
3769 { | |
3770 edit_submode_extra = (char_u *)_("Back at original"); | |
3771 edit_submode_highl = HLF_W; | |
3772 } | |
3773 else if (compl_cont_status & CONT_S_IPOS) | |
3774 { | |
3775 edit_submode_extra = (char_u *)_("Word from other line"); | |
3776 edit_submode_highl = HLF_COUNT; | |
3777 } | |
3778 else if (compl_curr_match->cp_next == compl_curr_match->cp_prev) | |
3779 { | |
3780 edit_submode_extra = (char_u *)_("The only match"); | |
3781 edit_submode_highl = HLF_COUNT; | |
3782 } | |
3783 else | |
3784 { | |
3785 // Update completion sequence number when needed. | |
3786 if (compl_curr_match->cp_number == -1) | |
3787 { | |
3788 int number = 0; | |
3789 compl_T *match; | |
3790 | |
3791 if (compl_direction == FORWARD) | |
3792 { | |
3793 // search backwards for the first valid (!= -1) number. | |
3794 // This should normally succeed already at the first loop | |
3795 // cycle, so it's fast! | |
3796 for (match = compl_curr_match->cp_prev; match != NULL | |
3797 && match != compl_first_match; | |
3798 match = match->cp_prev) | |
3799 if (match->cp_number != -1) | |
3800 { | |
3801 number = match->cp_number; | |
3802 break; | |
3803 } | |
3804 if (match != NULL) | |
3805 // go up and assign all numbers which are not assigned | |
3806 // yet | |
3807 for (match = match->cp_next; | |
3808 match != NULL && match->cp_number == -1; | |
3809 match = match->cp_next) | |
3810 match->cp_number = ++number; | |
3811 } | |
3812 else // BACKWARD | |
3813 { | |
3814 // search forwards (upwards) for the first valid (!= -1) | |
3815 // number. This should normally succeed already at the | |
3816 // first loop cycle, so it's fast! | |
3817 for (match = compl_curr_match->cp_next; match != NULL | |
3818 && match != compl_first_match; | |
3819 match = match->cp_next) | |
3820 if (match->cp_number != -1) | |
3821 { | |
3822 number = match->cp_number; | |
3823 break; | |
3824 } | |
3825 if (match != NULL) | |
3826 // go down and assign all numbers which are not | |
3827 // assigned yet | |
3828 for (match = match->cp_prev; match | |
3829 && match->cp_number == -1; | |
3830 match = match->cp_prev) | |
3831 match->cp_number = ++number; | |
3832 } | |
3833 } | |
3834 | |
3835 // The match should always have a sequence number now, this is | |
3836 // just a safety check. | |
3837 if (compl_curr_match->cp_number != -1) | |
3838 { | |
3839 // Space for 10 text chars. + 2x10-digit no.s = 31. | |
3840 // Translations may need more than twice that. | |
3841 static char_u match_ref[81]; | |
3842 | |
3843 if (compl_matches > 0) | |
3844 vim_snprintf((char *)match_ref, sizeof(match_ref), | |
3845 _("match %d of %d"), | |
3846 compl_curr_match->cp_number, compl_matches); | |
3847 else | |
3848 vim_snprintf((char *)match_ref, sizeof(match_ref), | |
3849 _("match %d"), | |
3850 compl_curr_match->cp_number); | |
3851 edit_submode_extra = match_ref; | |
3852 edit_submode_highl = HLF_R; | |
3853 if (dollar_vcol >= 0) | |
3854 curs_columns(FALSE); | |
3855 } | |
3856 } | |
3857 } | |
3858 | |
3859 // Show a message about what (completion) mode we're in. | |
3860 if (!compl_opt_suppress_empty) | |
3861 { | |
3862 showmode(); | |
3863 if (!shortmess(SHM_COMPLETIONMENU)) | |
3864 { | |
3865 if (edit_submode_extra != NULL) | |
3866 { | |
3867 if (!p_smd) | |
3868 msg_attr((char *)edit_submode_extra, | |
3869 edit_submode_highl < HLF_COUNT | |
3870 ? HL_ATTR(edit_submode_highl) : 0); | |
3871 } | |
3872 else | |
3873 msg_clr_cmdline(); // necessary for "noshowmode" | |
3874 } | |
3875 } | |
3876 | |
3877 // Show the popup menu, unless we got interrupted. | |
3878 if (enable_pum && !compl_interrupted) | |
3879 show_pum(save_w_wrow, save_w_leftcol); | |
3880 | |
3881 compl_was_interrupted = compl_interrupted; | |
3882 compl_interrupted = FALSE; | |
3883 | |
3884 return OK; | |
3885 } | |
3886 | |
3887 static void | |
3888 show_pum(int prev_w_wrow, int prev_w_leftcol) | |
3889 { | |
3890 // RedrawingDisabled may be set when invoked through complete(). | |
3891 int n = RedrawingDisabled; | |
3892 | |
3893 RedrawingDisabled = 0; | |
3894 | |
3895 // If the cursor moved or the display scrolled we need to remove the pum | |
3896 // first. | |
3897 setcursor(); | |
3898 if (prev_w_wrow != curwin->w_wrow || prev_w_leftcol != curwin->w_leftcol) | |
3899 ins_compl_del_pum(); | |
3900 | |
3901 ins_compl_show_pum(); | |
3902 setcursor(); | |
3903 RedrawingDisabled = n; | |
3904 } | |
3905 | |
3906 /* | |
3907 * Looks in the first "len" chars. of "src" for search-metachars. | |
3908 * If dest is not NULL the chars. are copied there quoting (with | |
3909 * a backslash) the metachars, and dest would be NUL terminated. | |
3910 * Returns the length (needed) of dest | |
3911 */ | |
3912 static unsigned | |
3913 quote_meta(char_u *dest, char_u *src, int len) | |
3914 { | |
3915 unsigned m = (unsigned)len + 1; // one extra for the NUL | |
3916 | |
3917 for ( ; --len >= 0; src++) | |
3918 { | |
3919 switch (*src) | |
3920 { | |
3921 case '.': | |
3922 case '*': | |
3923 case '[': | |
3924 if (ctrl_x_mode == CTRL_X_DICTIONARY | |
3925 || ctrl_x_mode == CTRL_X_THESAURUS) | |
3926 break; | |
3927 // FALLTHROUGH | |
3928 case '~': | |
3929 if (!p_magic) // quote these only if magic is set | |
3930 break; | |
3931 // FALLTHROUGH | |
3932 case '\\': | |
3933 if (ctrl_x_mode == CTRL_X_DICTIONARY | |
3934 || ctrl_x_mode == CTRL_X_THESAURUS) | |
3935 break; | |
3936 // FALLTHROUGH | |
3937 case '^': // currently it's not needed. | |
3938 case '$': | |
3939 m++; | |
3940 if (dest != NULL) | |
3941 *dest++ = '\\'; | |
3942 break; | |
3943 } | |
3944 if (dest != NULL) | |
3945 *dest++ = *src; | |
3946 // Copy remaining bytes of a multibyte character. | |
3947 if (has_mbyte) | |
3948 { | |
3949 int i, mb_len; | |
3950 | |
3951 mb_len = (*mb_ptr2len)(src) - 1; | |
3952 if (mb_len > 0 && len >= mb_len) | |
3953 for (i = 0; i < mb_len; ++i) | |
3954 { | |
3955 --len; | |
3956 ++src; | |
3957 if (dest != NULL) | |
3958 *dest++ = *src; | |
3959 } | |
3960 } | |
3961 } | |
3962 if (dest != NULL) | |
3963 *dest = NUL; | |
3964 | |
3965 return m; | |
3966 } | |
3967 | |
3968 # if defined(EXITFREE) || defined(PROTO) | |
3969 void | |
3970 free_insexpand_stuff(void) | |
3971 { | |
3972 VIM_CLEAR(compl_orig_text); | |
3973 } | |
3974 # endif | |
3975 | |
3976 # ifdef FEAT_SPELL | |
3977 /* | |
3978 * Called when starting CTRL_X_SPELL mode: Move backwards to a previous badly | |
3979 * spelled word, if there is one. | |
3980 */ | |
3981 static void | |
3982 spell_back_to_badword(void) | |
3983 { | |
3984 pos_T tpos = curwin->w_cursor; | |
3985 | |
3986 spell_bad_len = spell_move_to(curwin, BACKWARD, TRUE, TRUE, NULL); | |
3987 if (curwin->w_cursor.col != tpos.col) | |
3988 start_arrow(&tpos); | |
3989 } | |
3990 # endif | |
3991 | |
3992 #endif // FEAT_INS_EXPAND |