Mercurial > vim
annotate src/edit.c @ 15629:dd2e0b83a660
patch 8.1.0822: peeking and flushing output slows down execution
commit https://github.com/vim/vim/commit/cb574f415486adff645ce384979bfecf27f5be8c
Author: Bram Moolenaar <Bram@vim.org>
Date: Fri Jan 25 22:29:57 2019 +0100
patch 8.1.0822: peeking and flushing output slows down execution
Problem: Peeking and flushing output slows down execution.
Solution: Do not update the mode message when global_busy is set. Do not
flush when only peeking for a character. (Ken Takata)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Fri, 25 Jan 2019 22:30:13 +0100 |
parents | 1ec942f1b648 |
children | 6f1c7e9a6393 |
rev | line source |
---|---|
10042
4aead6a9b7a9
commit https://github.com/vim/vim/commit/edf3f97ae2af024708ebb4ac614227327033ca47
Christian Brabandt <cb@256bit.org>
parents:
9852
diff
changeset
|
1 /* vi:set ts=8 sts=4 sw=4 noet: |
7 | 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 * edit.c: functions for Insert mode | |
12 */ | |
13 | |
14 #include "vim.h" | |
15 | |
16 #ifdef FEAT_INS_EXPAND | |
17 /* | |
18 * definitions used for CTRL-X submode | |
19 */ | |
13210
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
20 # define CTRL_X_WANT_IDENT 0x100 |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
21 |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
22 # define CTRL_X_NORMAL 0 /* CTRL-N CTRL-P completion, default */ |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
23 # define CTRL_X_NOT_DEFINED_YET 1 |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
24 # define CTRL_X_SCROLL 2 |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
25 # define CTRL_X_WHOLE_LINE 3 |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
26 # define CTRL_X_FILES 4 |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
27 # define CTRL_X_TAGS (5 + CTRL_X_WANT_IDENT) |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
28 # define CTRL_X_PATH_PATTERNS (6 + CTRL_X_WANT_IDENT) |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
29 # define CTRL_X_PATH_DEFINES (7 + CTRL_X_WANT_IDENT) |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
30 # define CTRL_X_FINISHED 8 |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
31 # define CTRL_X_DICTIONARY (9 + CTRL_X_WANT_IDENT) |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
32 # define CTRL_X_THESAURUS (10 + CTRL_X_WANT_IDENT) |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
33 # define CTRL_X_CMDLINE 11 |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
34 # define CTRL_X_FUNCTION 12 |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
35 # define CTRL_X_OMNI 13 |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
36 # define CTRL_X_SPELL 14 |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
37 # define CTRL_X_LOCAL_MSG 15 /* only used in "ctrl_x_msgs" */ |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
38 # define CTRL_X_EVAL 16 /* for builtin function complete() */ |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
39 |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
40 # define CTRL_X_MSG(i) ctrl_x_msgs[(i) & ~CTRL_X_WANT_IDENT] |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
41 # define CTRL_X_MODE_LINE_OR_EVAL(m) ((m) == CTRL_X_WHOLE_LINE || (m) == CTRL_X_EVAL) |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
42 |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
43 /* Message for CTRL-X mode, index is ctrl_x_mode. */ |
7 | 44 static char *ctrl_x_msgs[] = |
45 { | |
13210
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
46 N_(" Keyword completion (^N^P)"), /* CTRL_X_NORMAL, ^P/^N compl. */ |
819 | 47 N_(" ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"), |
13210
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
48 NULL, /* CTRL_X_SCROLL: depends on state */ |
7 | 49 N_(" Whole line completion (^L^N^P)"), |
50 N_(" File name completion (^F^N^P)"), | |
51 N_(" Tag completion (^]^N^P)"), | |
52 N_(" Path pattern completion (^N^P)"), | |
53 N_(" Definition completion (^D^N^P)"), | |
13210
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
54 NULL, /* CTRL_X_FINISHED */ |
7 | 55 N_(" Dictionary completion (^K^N^P)"), |
56 N_(" Thesaurus completion (^T^N^P)"), | |
12 | 57 N_(" Command-line completion (^V^N^P)"), |
58 N_(" User defined completion (^U^N^P)"), | |
523 | 59 N_(" Omni completion (^O^N^P)"), |
819 | 60 N_(" Spelling suggestion (s^N^P)"), |
449 | 61 N_(" Keyword Local completion (^N^P)"), |
6657 | 62 NULL, /* CTRL_X_EVAL doesn't use msg. */ |
7 | 63 }; |
64 | |
1869 | 65 static char e_hitend[] = N_("Hit end of paragraph"); |
13210
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
66 # ifdef FEAT_COMPL_FUNC |
2631 | 67 static char e_complwin[] = N_("E839: Completion function changed window"); |
68 static char e_compldel[] = N_("E840: Completion function deleted text"); | |
13210
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
69 # endif |
7 | 70 |
71 /* | |
72 * Structure used to store one match for insert completion. | |
73 */ | |
681 | 74 typedef struct compl_S compl_T; |
75 struct compl_S | |
7 | 76 { |
464 | 77 compl_T *cp_next; |
78 compl_T *cp_prev; | |
79 char_u *cp_str; /* matched text */ | |
681 | 80 char cp_icase; /* TRUE or FALSE: ignore case */ |
786 | 81 char_u *(cp_text[CPT_COUNT]); /* text for the menu */ |
659 | 82 char_u *cp_fname; /* file containing the match, allocated when |
83 * cp_flags has FREE_FNAME */ | |
464 | 84 int cp_flags; /* ORIGINAL_TEXT, CONT_S_IPOS or FREE_FNAME */ |
85 int cp_number; /* sequence number */ | |
7 | 86 }; |
87 | |
13210
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
88 # define ORIGINAL_TEXT (1) /* the original text when the expansion begun */ |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
89 # define FREE_FNAME (2) |
7 | 90 |
91 /* | |
92 * All the current matches are stored in a list. | |
449 | 93 * "compl_first_match" points to the start of the list. |
94 * "compl_curr_match" points to the currently selected entry. | |
95 * "compl_shown_match" is different from compl_curr_match during | |
96 * ins_compl_get_exp(). | |
7 | 97 */ |
464 | 98 static compl_T *compl_first_match = NULL; |
99 static compl_T *compl_curr_match = NULL; | |
100 static compl_T *compl_shown_match = NULL; | |
11424
328a9ee98fb2
patch 8.0.0596: crash when complete() called after complete_add()
Christian Brabandt <cb@256bit.org>
parents:
11317
diff
changeset
|
101 static compl_T *compl_old_match = NULL; |
449 | 102 |
825 | 103 /* After using a cursor key <Enter> selects a match in the popup menu, |
104 * otherwise it inserts a line break. */ | |
105 static int compl_enter_selects = FALSE; | |
106 | |
657 | 107 /* When "compl_leader" is not NULL only matches that start with this string |
108 * are used. */ | |
109 static char_u *compl_leader = NULL; | |
110 | |
665 | 111 static int compl_get_longest = FALSE; /* put longest common string |
112 in compl_leader */ | |
113 | |
6911 | 114 static int compl_no_insert = FALSE; /* FALSE: select & insert |
115 TRUE: noinsert */ | |
116 static int compl_no_select = FALSE; /* FALSE: select & insert | |
117 TRUE: noselect */ | |
118 | |
657 | 119 static int compl_used_match; /* Selected one of the matches. When |
120 FALSE the match was edited or using | |
121 the longest common string. */ | |
122 | |
874 | 123 static int compl_was_interrupted = FALSE; /* didn't finish finding |
124 completions. */ | |
125 | |
126 static int compl_restarting = FALSE; /* don't insert match */ | |
127 | |
449 | 128 /* When the first completion is done "compl_started" is set. When it's |
129 * FALSE the word to be completed must be located. */ | |
644 | 130 static int compl_started = FALSE; |
449 | 131 |
13210
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
132 /* Which Ctrl-X mode are we in? */ |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
133 static int ctrl_x_mode = CTRL_X_NORMAL; |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
134 |
1927 | 135 /* Set when doing something for completion that may call edit() recursively, |
136 * which is not allowed. */ | |
137 static int compl_busy = FALSE; | |
138 | |
464 | 139 static int compl_matches = 0; |
140 static char_u *compl_pattern = NULL; | |
141 static int compl_direction = FORWARD; | |
142 static int compl_shows_dir = FORWARD; | |
716 | 143 static int compl_pending = 0; /* > 1 for postponed CTRL-N */ |
464 | 144 static pos_T compl_startpos; |
145 static colnr_T compl_col = 0; /* column where the text starts | |
146 * that is being completed */ | |
147 static char_u *compl_orig_text = NULL; /* text as it was before | |
148 * completion started */ | |
149 static int compl_cont_mode = 0; | |
150 static expand_T compl_xp; | |
449 | 151 |
3078 | 152 static int compl_opt_refresh_always = FALSE; |
15416
5f8ddd2a7b92
patch 8.1.0716: get warning message when 'completefunc' returns nothing
Bram Moolenaar <Bram@vim.org>
parents:
15400
diff
changeset
|
153 static int compl_opt_suppress_empty = FALSE; |
3078 | 154 |
7799
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
155 static void ins_ctrl_x(void); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
156 static int has_compl_option(int dict_opt); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
157 static int ins_compl_accept_char(int c); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
158 static int ins_compl_add(char_u *str, int len, int icase, char_u *fname, char_u **cptext, int cdir, int flags, int adup); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
159 static void ins_compl_longest_match(compl_T *match); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
160 static void ins_compl_del_pum(void); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
161 static int pum_wanted(void); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
162 static void ins_compl_files(int count, char_u **files, int thesaurus, int flags, regmatch_T *regmatch, char_u *buf, int *dir); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
163 static char_u *find_line_end(char_u *ptr); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
164 static void ins_compl_free(void); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
165 static void ins_compl_clear(void); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
166 static int ins_compl_bs(void); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
167 static int ins_compl_need_restart(void); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
168 static void ins_compl_new_leader(void); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
169 static void ins_compl_addleader(int c); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
170 static int ins_compl_len(void); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
171 static void ins_compl_restart(void); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
172 static void ins_compl_set_original_text(char_u *str); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
173 static void ins_compl_addfrommatch(void); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
174 static int ins_compl_prep(int c); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
175 static void ins_compl_fixRedoBufForLeader(char_u *ptr_arg); |
13210
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
176 # if defined(FEAT_COMPL_FUNC) || defined(FEAT_EVAL) |
7799
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
177 static void ins_compl_add_list(list_T *list); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
178 static void ins_compl_add_dict(dict_T *dict); |
13210
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
179 # endif |
7799
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
180 static void ins_compl_delete(void); |
10277
154d5a2e7395
commit https://github.com/vim/vim/commit/472e85970ee3a80abd824bef510df12e9cfe9e96
Christian Brabandt <cb@256bit.org>
parents:
10120
diff
changeset
|
181 static void ins_compl_insert(int in_compl_func); |
7799
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
182 static int ins_compl_key2dir(int c); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
183 static int ins_compl_pum_key(int c); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
184 static int ins_compl_key2count(int c); |
8224
2baf64fead5e
commit https://github.com/vim/vim/commit/8aefbe0ad5d05ee7225b20024b0f3023286ebd0f
Christian Brabandt <cb@256bit.org>
parents:
8090
diff
changeset
|
185 static int ins_complete(int c, int enable_pum); |
11002
35d4975a5bb5
patch 8.0.0390: when the window scrolls the popup menu may be garbled
Christian Brabandt <cb@256bit.org>
parents:
10980
diff
changeset
|
186 static void show_pum(int prev_w_wrow, int prev_w_leftcol); |
7799
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
187 static unsigned quote_meta(char_u *dest, char_u *str, int len); |
7 | 188 #endif /* FEAT_INS_EXPAND */ |
189 | |
190 #define BACKSPACE_CHAR 1 | |
191 #define BACKSPACE_WORD 2 | |
192 #define BACKSPACE_WORD_NOT_SPACE 3 | |
193 #define BACKSPACE_LINE 4 | |
194 | |
7799
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
195 static void ins_redraw(int ready); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
196 static void ins_ctrl_v(void); |
14019
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
197 #ifdef FEAT_JOB_CHANNEL |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
198 static void init_prompt(int cmdchar_todo); |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
199 #endif |
7799
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
200 static void undisplay_dollar(void); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
201 static void insert_special(int, int, int); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
202 static void internal_format(int textwidth, int second_indent, int flags, int format_only, int c); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
203 static void check_auto_format(int); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
204 static void redo_literal(int c); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
205 static void start_arrow(pos_T *end_insert_pos); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
206 static void start_arrow_common(pos_T *end_insert_pos, int change); |
744 | 207 #ifdef FEAT_SPELL |
7799
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
208 static void check_spell_redraw(void); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
209 static void spell_back_to_badword(void); |
497 | 210 static int spell_bad_len = 0; /* length of located bad word */ |
221 | 211 #endif |
7799
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
212 static void stop_insert(pos_T *end_insert_pos, int esc, int nomove); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
213 static int echeck_abbr(int); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
214 static void replace_join(int off); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
215 static void mb_replace_pop_ins(int cc); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
216 static void replace_flush(void); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
217 static void replace_do_bs(int limit_col); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
218 static int del_char_after_col(int limit_col); |
7 | 219 #ifdef FEAT_CINDENT |
7799
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
220 static int cindent_on(void); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
221 #endif |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
222 static void ins_reg(void); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
223 static void ins_ctrl_g(void); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
224 static void ins_ctrl_hat(void); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
225 static int ins_esc(long *count, int cmdchar, int nomove); |
7 | 226 #ifdef FEAT_RIGHTLEFT |
7799
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
227 static void ins_ctrl_(void); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
228 #endif |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
229 static int ins_start_select(int c); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
230 static void ins_insert(int replaceState); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
231 static void ins_ctrl_o(void); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
232 static void ins_shift(int c, int lastc); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
233 static void ins_del(void); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
234 static int ins_bs(int c, int mode, int *inserted_space_p); |
7 | 235 #ifdef FEAT_MOUSE |
7799
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
236 static void ins_mouse(int c); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
237 static void ins_mousescroll(int dir); |
7 | 238 #endif |
692 | 239 #if defined(FEAT_GUI_TABLINE) || defined(PROTO) |
7799
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
240 static void ins_tabline(int c); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
241 #endif |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
242 static void ins_left(int end_change); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
243 static void ins_home(int c); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
244 static void ins_end(int c); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
245 static void ins_s_left(void); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
246 static void ins_right(int end_change); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
247 static void ins_s_right(void); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
248 static void ins_up(int startcol); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
249 static void ins_pageup(void); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
250 static void ins_down(int startcol); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
251 static void ins_pagedown(void); |
7 | 252 #ifdef FEAT_DND |
7799
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
253 static void ins_drop(void); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
254 #endif |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
255 static int ins_tab(void); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
256 static int ins_eol(int c); |
7 | 257 #ifdef FEAT_DIGRAPHS |
7799
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
258 static int ins_digraph(void); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
259 #endif |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
260 static int ins_ctrl_ey(int tc); |
7 | 261 #ifdef FEAT_SMARTINDENT |
7799
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
262 static void ins_try_si(int c); |
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
263 #endif |
13380
69517d67421f
patch 8.0.1564: too many #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
13244
diff
changeset
|
264 #if defined(FEAT_EVAL) |
7799
af3c41a3c53f
commit https://github.com/vim/vim/commit/f28dbcea371b3a35727d91afc90fb90e0527d78a
Christian Brabandt <cb@256bit.org>
parents:
7141
diff
changeset
|
265 static char_u *do_insert_char_pre(int c); |
3390 | 266 #endif |
14485
c71d65c3672f
patch 8.1.0256: using setline() in TextChangedI splits undo
Christian Brabandt <cb@256bit.org>
parents:
14465
diff
changeset
|
267 static int ins_apply_autocmds(event_T event); |
7 | 268 |
269 static colnr_T Insstart_textlen; /* length of line when insert started */ | |
270 static colnr_T Insstart_blank_vcol; /* vcol for first inserted blank */ | |
5680 | 271 static int update_Insstart_orig = TRUE; /* set Insstart_orig to Insstart */ |
7 | 272 |
273 static char_u *last_insert = NULL; /* the text of the previous insert, | |
274 K_SPECIAL and CSI are escaped */ | |
275 static int last_insert_skip; /* nr of chars in front of previous insert */ | |
276 static int new_insert_skip; /* nr of chars in front of current insert */ | |
603 | 277 static int did_restart_edit; /* "restart_edit" when calling edit() */ |
7 | 278 |
279 #ifdef FEAT_CINDENT | |
280 static int can_cindent; /* may do cindenting on this line */ | |
281 #endif | |
282 | |
283 static int old_indent = 0; /* for ^^D command in insert mode */ | |
284 | |
285 #ifdef FEAT_RIGHTLEFT | |
298 | 286 static int revins_on; /* reverse insert mode on */ |
287 static int revins_chars; /* how much to skip after edit */ | |
288 static int revins_legal; /* was the last char 'legal'? */ | |
289 static int revins_scol; /* start column of revins session */ | |
7 | 290 #endif |
291 | |
292 static int ins_need_undo; /* call u_save() before inserting a | |
293 char. Set when edit() is called. | |
294 after that arrow_used is used. */ | |
295 | |
296 static int did_add_space = FALSE; /* auto_format() added an extra space | |
297 under the cursor */ | |
7074
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
298 static int dont_sync_undo = FALSE; /* CTRL-G U prevents syncing undo for |
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
299 the next left/right cursor */ |
7 | 300 |
301 /* | |
302 * edit(): Start inserting text. | |
303 * | |
304 * "cmdchar" can be: | |
305 * 'i' normal insert command | |
306 * 'a' normal append command | |
10640
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
307 * K_PS bracketed paste |
7 | 308 * 'R' replace command |
309 * 'r' "r<CR>" command: insert one <CR>. Note: count can be > 1, for redo, | |
310 * but still only one <CR> is inserted. The <Esc> is not used for redo. | |
311 * 'g' "gI" command. | |
312 * 'V' "gR" command for Virtual Replace mode. | |
313 * 'v' "gr" command for single character Virtual Replace mode. | |
314 * | |
315 * This function is not called recursively. For CTRL-O commands, it returns | |
316 * and lets the caller handle the Normal-mode command. | |
317 * | |
318 * Return TRUE if a CTRL-O command caused the return (insert mode pending). | |
319 */ | |
320 int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
321 edit( |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
322 int cmdchar, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
323 int startln, /* if set, insert at start of line */ |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
324 long count) |
7 | 325 { |
326 int c = 0; | |
327 char_u *ptr; | |
8090
54cfe888c627
commit https://github.com/vim/vim/commit/418f81b5fa400ed59793384f2f3d9df45390f080
Christian Brabandt <cb@256bit.org>
parents:
8003
diff
changeset
|
328 int lastc = 0; |
1869 | 329 int mincol; |
7 | 330 static linenr_T o_lnum = 0; |
331 int i; | |
332 int did_backspace = TRUE; /* previous char was backspace */ | |
333 #ifdef FEAT_CINDENT | |
334 int line_is_white = FALSE; /* line is empty before insert */ | |
335 #endif | |
336 linenr_T old_topline = 0; /* topline before insertion */ | |
337 #ifdef FEAT_DIFF | |
338 int old_topfill = -1; | |
339 #endif | |
340 int inserted_space = FALSE; /* just inserted a space */ | |
341 int replaceState = REPLACE; | |
477 | 342 int nomove = FALSE; /* don't move cursor on return */ |
14019
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
343 #ifdef FEAT_JOB_CHANNEL |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
344 int cmdchar_todo = cmdchar; |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
345 #endif |
7 | 346 |
603 | 347 /* Remember whether editing was restarted after CTRL-O. */ |
348 did_restart_edit = restart_edit; | |
349 | |
7 | 350 /* sleep before redrawing, needed for "CTRL-O :" that results in an |
351 * error message */ | |
352 check_for_delay(TRUE); | |
353 | |
5680 | 354 /* set Insstart_orig to Insstart */ |
355 update_Insstart_orig = TRUE; | |
356 | |
7 | 357 #ifdef HAVE_SANDBOX |
358 /* Don't allow inserting in the sandbox. */ | |
359 if (sandbox != 0) | |
360 { | |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
15440
diff
changeset
|
361 emsg(_(e_sandbox)); |
7 | 362 return FALSE; |
363 } | |
364 #endif | |
632 | 365 /* Don't allow changes in the buffer while editing the cmdline. The |
366 * caller of getcmdline() may get confused. */ | |
634 | 367 if (textlock != 0) |
632 | 368 { |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
15440
diff
changeset
|
369 emsg(_(e_secure)); |
632 | 370 return FALSE; |
371 } | |
7 | 372 |
373 #ifdef FEAT_INS_EXPAND | |
844 | 374 /* Don't allow recursive insert mode when busy with completion. */ |
1927 | 375 if (compl_started || compl_busy || pum_visible()) |
844 | 376 { |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
15440
diff
changeset
|
377 emsg(_(e_secure)); |
844 | 378 return FALSE; |
379 } | |
7 | 380 ins_compl_clear(); /* clear stuff for CTRL-X mode */ |
381 #endif | |
382 | |
11 | 383 /* |
384 * Trigger InsertEnter autocommands. Do not do this for "r<CR>" or "grx". | |
385 */ | |
386 if (cmdchar != 'r' && cmdchar != 'v') | |
387 { | |
4027 | 388 pos_T save_cursor = curwin->w_cursor; |
389 | |
13380
69517d67421f
patch 8.0.1564: too many #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
13244
diff
changeset
|
390 #ifdef FEAT_EVAL |
11 | 391 if (cmdchar == 'R') |
392 ptr = (char_u *)"r"; | |
393 else if (cmdchar == 'V') | |
394 ptr = (char_u *)"v"; | |
395 else | |
396 ptr = (char_u *)"i"; | |
397 set_vim_var_string(VV_INSERTMODE, ptr, 1); | |
4448 | 398 set_vim_var_string(VV_CHAR, NULL, -1); /* clear v:char */ |
13380
69517d67421f
patch 8.0.1564: too many #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
13244
diff
changeset
|
399 #endif |
14485
c71d65c3672f
patch 8.1.0256: using setline() in TextChangedI splits undo
Christian Brabandt <cb@256bit.org>
parents:
14465
diff
changeset
|
400 ins_apply_autocmds(EVENT_INSERTENTER); |
4027 | 401 |
4448 | 402 /* Make sure the cursor didn't move. Do call check_cursor_col() in |
403 * case the text was modified. Since Insert mode was not started yet | |
404 * a call to check_cursor_col() may move the cursor, especially with | |
405 * the "A" command, thus set State to avoid that. Also check that the | |
406 * line number is still valid (lines may have been deleted). | |
407 * Do not restore if v:char was set to a non-empty string. */ | |
11121
778c10516955
patch 8.0.0448: some macros are in lower case
Christian Brabandt <cb@256bit.org>
parents:
11105
diff
changeset
|
408 if (!EQUAL_POS(curwin->w_cursor, save_cursor) |
13380
69517d67421f
patch 8.0.1564: too many #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
13244
diff
changeset
|
409 #ifdef FEAT_EVAL |
4448 | 410 && *get_vim_var_str(VV_CHAR) == NUL |
13380
69517d67421f
patch 8.0.1564: too many #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
13244
diff
changeset
|
411 #endif |
4448 | 412 && save_cursor.lnum <= curbuf->b_ml.ml_line_count) |
4027 | 413 { |
414 int save_state = State; | |
415 | |
416 curwin->w_cursor = save_cursor; | |
417 State = INSERT; | |
418 check_cursor_col(); | |
419 State = save_state; | |
420 } | |
11 | 421 } |
422 | |
2378
85b7dc8da5eb
Add the 'concealcursor' option to decide when the cursor line is to be
Bram Moolenaar <bram@vim.org>
parents:
2348
diff
changeset
|
423 #ifdef FEAT_CONCEAL |
85b7dc8da5eb
Add the 'concealcursor' option to decide when the cursor line is to be
Bram Moolenaar <bram@vim.org>
parents:
2348
diff
changeset
|
424 /* Check if the cursor line needs redrawing before changing State. If |
85b7dc8da5eb
Add the 'concealcursor' option to decide when the cursor line is to be
Bram Moolenaar <bram@vim.org>
parents:
2348
diff
changeset
|
425 * 'concealcursor' is "n" it needs to be redrawn without concealing. */ |
13876
156ebdcb8ef5
patch 8.0.1809: various typos
Christian Brabandt <cb@256bit.org>
parents:
13870
diff
changeset
|
426 conceal_check_cursor_line(); |
2378
85b7dc8da5eb
Add the 'concealcursor' option to decide when the cursor line is to be
Bram Moolenaar <bram@vim.org>
parents:
2348
diff
changeset
|
427 #endif |
85b7dc8da5eb
Add the 'concealcursor' option to decide when the cursor line is to be
Bram Moolenaar <bram@vim.org>
parents:
2348
diff
changeset
|
428 |
7 | 429 #ifdef FEAT_MOUSE |
430 /* | |
431 * When doing a paste with the middle mouse button, Insstart is set to | |
432 * where the paste started. | |
433 */ | |
434 if (where_paste_started.lnum != 0) | |
435 Insstart = where_paste_started; | |
436 else | |
437 #endif | |
438 { | |
439 Insstart = curwin->w_cursor; | |
440 if (startln) | |
441 Insstart.col = 0; | |
442 } | |
1869 | 443 Insstart_textlen = (colnr_T)linetabsize(ml_get_curline()); |
7 | 444 Insstart_blank_vcol = MAXCOL; |
445 if (!did_ai) | |
446 ai_col = 0; | |
447 | |
448 if (cmdchar != NUL && restart_edit == 0) | |
449 { | |
450 ResetRedobuff(); | |
451 AppendNumberToRedobuff(count); | |
452 if (cmdchar == 'V' || cmdchar == 'v') | |
453 { | |
454 /* "gR" or "gr" command */ | |
455 AppendCharToRedobuff('g'); | |
456 AppendCharToRedobuff((cmdchar == 'v') ? 'r' : 'R'); | |
457 } | |
458 else | |
459 { | |
10682
d564e73ff9ee
patch 8.0.0231: bracketed paste mode is not tested
Christian Brabandt <cb@256bit.org>
parents:
10680
diff
changeset
|
460 if (cmdchar == K_PS) |
d564e73ff9ee
patch 8.0.0231: bracketed paste mode is not tested
Christian Brabandt <cb@256bit.org>
parents:
10680
diff
changeset
|
461 AppendCharToRedobuff('a'); |
d564e73ff9ee
patch 8.0.0231: bracketed paste mode is not tested
Christian Brabandt <cb@256bit.org>
parents:
10680
diff
changeset
|
462 else |
d564e73ff9ee
patch 8.0.0231: bracketed paste mode is not tested
Christian Brabandt <cb@256bit.org>
parents:
10680
diff
changeset
|
463 AppendCharToRedobuff(cmdchar); |
7 | 464 if (cmdchar == 'g') /* "gI" command */ |
465 AppendCharToRedobuff('I'); | |
466 else if (cmdchar == 'r') /* "r<CR>" command */ | |
467 count = 1; /* insert only one <CR> */ | |
468 } | |
469 } | |
470 | |
471 if (cmdchar == 'R') | |
472 { | |
473 #ifdef FEAT_FKMAP | |
474 if (p_fkmap && p_ri) | |
475 { | |
476 beep_flush(); | |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
15440
diff
changeset
|
477 emsg(farsi_text_3); /* encoded in Farsi */ |
7 | 478 State = INSERT; |
479 } | |
480 else | |
481 #endif | |
482 State = REPLACE; | |
483 } | |
484 else if (cmdchar == 'V' || cmdchar == 'v') | |
485 { | |
486 State = VREPLACE; | |
487 replaceState = VREPLACE; | |
488 orig_line_count = curbuf->b_ml.ml_line_count; | |
489 vr_lines_changed = 1; | |
490 } | |
491 else | |
492 State = INSERT; | |
493 | |
494 stop_insert_mode = FALSE; | |
495 | |
496 /* | |
497 * Need to recompute the cursor position, it might move when the cursor is | |
498 * on a TAB or special character. | |
499 */ | |
500 curs_columns(TRUE); | |
501 | |
502 /* | |
503 * Enable langmap or IME, indicated by 'iminsert'. | |
504 * Note that IME may enabled/disabled without us noticing here, thus the | |
505 * 'iminsert' value may not reflect what is actually used. It is updated | |
506 * when hitting <Esc>. | |
507 */ | |
508 if (curbuf->b_p_iminsert == B_IMODE_LMAP) | |
509 State |= LANGMAP; | |
13380
69517d67421f
patch 8.0.1564: too many #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
13244
diff
changeset
|
510 #ifdef HAVE_INPUT_METHOD |
7 | 511 im_set_active(curbuf->b_p_iminsert == B_IMODE_IM); |
512 #endif | |
513 | |
514 #ifdef FEAT_MOUSE | |
515 setmouse(); | |
516 #endif | |
517 #ifdef FEAT_CMDL_INFO | |
518 clear_showcmd(); | |
519 #endif | |
520 #ifdef FEAT_RIGHTLEFT | |
521 /* there is no reverse replace mode */ | |
522 revins_on = (State == INSERT && p_ri); | |
523 if (revins_on) | |
524 undisplay_dollar(); | |
525 revins_chars = 0; | |
526 revins_legal = 0; | |
527 revins_scol = -1; | |
528 #endif | |
10684
83a36d655a74
patch 8.0.0232: paste does not work when 'esckeys' is off
Christian Brabandt <cb@256bit.org>
parents:
10682
diff
changeset
|
529 if (!p_ek) |
83a36d655a74
patch 8.0.0232: paste does not work when 'esckeys' is off
Christian Brabandt <cb@256bit.org>
parents:
10682
diff
changeset
|
530 /* Disable bracketed paste mode, we won't recognize the escape |
83a36d655a74
patch 8.0.0232: paste does not work when 'esckeys' is off
Christian Brabandt <cb@256bit.org>
parents:
10682
diff
changeset
|
531 * sequences. */ |
83a36d655a74
patch 8.0.0232: paste does not work when 'esckeys' is off
Christian Brabandt <cb@256bit.org>
parents:
10682
diff
changeset
|
532 out_str(T_BD); |
7 | 533 |
534 /* | |
535 * Handle restarting Insert mode. | |
11073
d2178a6cc9f3
patch 8.0.0425: build errors when building without folding
Christian Brabandt <cb@256bit.org>
parents:
11002
diff
changeset
|
536 * Don't do this for "CTRL-O ." (repeat an insert): In that case we get |
d2178a6cc9f3
patch 8.0.0425: build errors when building without folding
Christian Brabandt <cb@256bit.org>
parents:
11002
diff
changeset
|
537 * here with something in the stuff buffer. |
7 | 538 */ |
539 if (restart_edit != 0 && stuff_empty()) | |
540 { | |
541 #ifdef FEAT_MOUSE | |
542 /* | |
543 * After a paste we consider text typed to be part of the insert for | |
544 * the pasted text. You can backspace over the pasted text too. | |
545 */ | |
546 if (where_paste_started.lnum) | |
547 arrow_used = FALSE; | |
548 else | |
549 #endif | |
550 arrow_used = TRUE; | |
551 restart_edit = 0; | |
552 | |
553 /* | |
554 * If the cursor was after the end-of-line before the CTRL-O and it is | |
555 * now at the end-of-line, put it after the end-of-line (this is not | |
556 * correct in very rare cases). | |
557 * Also do this if curswant is greater than the current virtual | |
558 * column. Eg after "^O$" or "^O80|". | |
559 */ | |
560 validate_virtcol(); | |
561 update_curswant(); | |
230 | 562 if (((ins_at_eol && curwin->w_cursor.lnum == o_lnum) |
7 | 563 || curwin->w_curswant > curwin->w_virtcol) |
564 && *(ptr = ml_get_curline() + curwin->w_cursor.col) != NUL) | |
565 { | |
566 if (ptr[1] == NUL) | |
567 ++curwin->w_cursor.col; | |
568 else if (has_mbyte) | |
569 { | |
474 | 570 i = (*mb_ptr2len)(ptr); |
7 | 571 if (ptr[i] == NUL) |
572 curwin->w_cursor.col += i; | |
573 } | |
574 } | |
230 | 575 ins_at_eol = FALSE; |
7 | 576 } |
577 else | |
578 arrow_used = FALSE; | |
579 | |
580 /* we are in insert mode now, don't need to start it anymore */ | |
581 need_start_insertmode = FALSE; | |
582 | |
583 /* Need to save the line for undo before inserting the first char. */ | |
584 ins_need_undo = TRUE; | |
585 | |
586 #ifdef FEAT_MOUSE | |
587 where_paste_started.lnum = 0; | |
588 #endif | |
589 #ifdef FEAT_CINDENT | |
590 can_cindent = TRUE; | |
591 #endif | |
592 #ifdef FEAT_FOLDING | |
593 /* The cursor line is not in a closed fold, unless 'insertmode' is set or | |
594 * restarting. */ | |
595 if (!p_im && did_restart_edit == 0) | |
596 foldOpenCursor(); | |
597 #endif | |
598 | |
599 /* | |
600 * If 'showmode' is set, show the current (insert/replace/..) mode. | |
601 * A warning message for changing a readonly file is given here, before | |
602 * actually changing anything. It's put after the mode, if any. | |
603 */ | |
604 i = 0; | |
644 | 605 if (p_smd && msg_silent == 0) |
7 | 606 i = showmode(); |
607 | |
608 if (!p_im && did_restart_edit == 0) | |
1473 | 609 change_warning(i == 0 ? 0 : i + 1); |
7 | 610 |
611 #ifdef CURSOR_SHAPE | |
612 ui_cursor_shape(); /* may show different cursor shape */ | |
613 #endif | |
614 #ifdef FEAT_DIGRAPHS | |
615 do_digraph(-1); /* clear digraphs */ | |
616 #endif | |
617 | |
603 | 618 /* |
619 * Get the current length of the redo buffer, those characters have to be | |
620 * skipped if we want to get to the inserted characters. | |
621 */ | |
7 | 622 ptr = get_inserted(); |
623 if (ptr == NULL) | |
624 new_insert_skip = 0; | |
625 else | |
626 { | |
627 new_insert_skip = (int)STRLEN(ptr); | |
628 vim_free(ptr); | |
629 } | |
630 | |
631 old_indent = 0; | |
632 | |
633 /* | |
634 * Main loop in Insert mode: repeat until Insert mode is left. | |
635 */ | |
636 for (;;) | |
637 { | |
638 #ifdef FEAT_RIGHTLEFT | |
639 if (!revins_legal) | |
640 revins_scol = -1; /* reset on illegal motions */ | |
641 else | |
642 revins_legal = 0; | |
643 #endif | |
644 if (arrow_used) /* don't repeat insert when arrow key used */ | |
645 count = 0; | |
646 | |
5680 | 647 if (update_Insstart_orig) |
648 Insstart_orig = Insstart; | |
649 | |
9359
35b173e37dc6
commit https://github.com/vim/vim/commit/00672e1d3f59dbff91a18d418b2984be96f89ee5
Christian Brabandt <cb@256bit.org>
parents:
9282
diff
changeset
|
650 if (stop_insert_mode |
35b173e37dc6
commit https://github.com/vim/vim/commit/00672e1d3f59dbff91a18d418b2984be96f89ee5
Christian Brabandt <cb@256bit.org>
parents:
9282
diff
changeset
|
651 #ifdef FEAT_INS_EXPAND |
35b173e37dc6
commit https://github.com/vim/vim/commit/00672e1d3f59dbff91a18d418b2984be96f89ee5
Christian Brabandt <cb@256bit.org>
parents:
9282
diff
changeset
|
652 && !pum_visible() |
35b173e37dc6
commit https://github.com/vim/vim/commit/00672e1d3f59dbff91a18d418b2984be96f89ee5
Christian Brabandt <cb@256bit.org>
parents:
9282
diff
changeset
|
653 #endif |
35b173e37dc6
commit https://github.com/vim/vim/commit/00672e1d3f59dbff91a18d418b2984be96f89ee5
Christian Brabandt <cb@256bit.org>
parents:
9282
diff
changeset
|
654 ) |
7 | 655 { |
656 /* ":stopinsert" used or 'insertmode' reset */ | |
657 count = 0; | |
658 goto doESCkey; | |
659 } | |
660 | |
661 /* set curwin->w_curswant for next K_DOWN or K_UP */ | |
662 if (!arrow_used) | |
663 curwin->w_set_curswant = TRUE; | |
664 | |
665 /* If there is no typeahead may check for timestamps (e.g., for when a | |
666 * menu invoked a shell command). */ | |
667 if (stuff_empty()) | |
668 { | |
669 did_check_timestamps = FALSE; | |
670 if (need_check_timestamps) | |
671 check_timestamps(FALSE); | |
672 } | |
673 | |
674 /* | |
675 * When emsg() was called msg_scroll will have been set. | |
676 */ | |
677 msg_scroll = FALSE; | |
678 | |
679 #ifdef FEAT_GUI | |
680 /* When 'mousefocus' is set a mouse movement may have taken us to | |
681 * another window. "need_mouse_correct" may then be set because of an | |
682 * autocommand. */ | |
683 if (need_mouse_correct) | |
684 gui_mouse_correct(); | |
685 #endif | |
686 | |
687 #ifdef FEAT_FOLDING | |
688 /* Open fold at the cursor line, according to 'foldopen'. */ | |
689 if (fdo_flags & FDO_INSERT) | |
690 foldOpenCursor(); | |
691 /* Close folds where the cursor isn't, according to 'foldclose' */ | |
692 if (!char_avail()) | |
693 foldCheckClose(); | |
694 #endif | |
695 | |
14019
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
696 #ifdef FEAT_JOB_CHANNEL |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
697 if (bt_prompt(curbuf)) |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
698 { |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
699 init_prompt(cmdchar_todo); |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
700 cmdchar_todo = NUL; |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
701 } |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
702 #endif |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
703 |
7 | 704 /* |
705 * If we inserted a character at the last position of the last line in | |
706 * the window, scroll the window one line up. This avoids an extra | |
707 * redraw. | |
708 * This is detected when the cursor column is smaller after inserting | |
709 * something. | |
710 * Don't do this when the topline changed already, it has | |
711 * already been adjusted (by insertchar() calling open_line())). | |
712 */ | |
713 if (curbuf->b_mod_set | |
714 && curwin->w_p_wrap | |
715 && !did_backspace | |
716 && curwin->w_topline == old_topline | |
717 #ifdef FEAT_DIFF | |
718 && curwin->w_topfill == old_topfill | |
719 #endif | |
720 ) | |
721 { | |
722 mincol = curwin->w_wcol; | |
723 validate_cursor_col(); | |
724 | |
14175
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
725 if ( |
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
726 #ifdef FEAT_VARTABS |
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
727 (int)curwin->w_wcol < mincol - tabstop_at( |
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
728 get_nolist_virtcol(), curbuf->b_p_ts, |
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
729 curbuf->b_p_vts_array) |
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
730 #else |
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
731 (int)curwin->w_wcol < mincol - curbuf->b_p_ts |
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
732 #endif |
7 | 733 && curwin->w_wrow == W_WINROW(curwin) |
734 + curwin->w_height - 1 - p_so | |
735 && (curwin->w_cursor.lnum != curwin->w_topline | |
736 #ifdef FEAT_DIFF | |
737 || curwin->w_topfill > 0 | |
738 #endif | |
739 )) | |
740 { | |
741 #ifdef FEAT_DIFF | |
742 if (curwin->w_topfill > 0) | |
743 --curwin->w_topfill; | |
744 else | |
745 #endif | |
746 #ifdef FEAT_FOLDING | |
747 if (hasFolding(curwin->w_topline, NULL, &old_topline)) | |
748 set_topline(curwin, old_topline + 1); | |
749 else | |
750 #endif | |
751 set_topline(curwin, curwin->w_topline + 1); | |
752 } | |
753 } | |
754 | |
755 /* May need to adjust w_topline to show the cursor. */ | |
756 update_topline(); | |
757 | |
758 did_backspace = FALSE; | |
759 | |
760 validate_cursor(); /* may set must_redraw */ | |
761 | |
762 /* | |
763 * Redraw the display when no characters are waiting. | |
764 * Also shows mode, ruler and positions cursor. | |
765 */ | |
661 | 766 ins_redraw(TRUE); |
7 | 767 |
768 if (curwin->w_p_scb) | |
769 do_check_scrollbind(TRUE); | |
13384
6740c499de13
patch 8.0.1566: too many #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
13380
diff
changeset
|
770 |
2250
1bac28a53fae
Add the conceal patch from Vince Negri.
Bram Moolenaar <bram@vim.org>
parents:
2227
diff
changeset
|
771 if (curwin->w_p_crb) |
1bac28a53fae
Add the conceal patch from Vince Negri.
Bram Moolenaar <bram@vim.org>
parents:
2227
diff
changeset
|
772 do_check_cursorbind(); |
7 | 773 update_curswant(); |
774 old_topline = curwin->w_topline; | |
775 #ifdef FEAT_DIFF | |
776 old_topfill = curwin->w_topfill; | |
777 #endif | |
778 | |
779 #ifdef USE_ON_FLY_SCROLL | |
780 dont_scroll = FALSE; /* allow scrolling here */ | |
781 #endif | |
782 | |
783 /* | |
12960
004bc78c88e6
patch 8.0.1356: using simalt in a GUIEnter autocommand inserts characters
Christian Brabandt <cb@256bit.org>
parents:
12924
diff
changeset
|
784 * Get a character for Insert mode. Ignore K_IGNORE and K_NOP. |
7 | 785 */ |
6673 | 786 if (c != K_CURSORHOLD) |
787 lastc = c; /* remember the previous char for CTRL-D */ | |
7074
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
788 |
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
789 /* After using CTRL-G U the next cursor key will not break undo. */ |
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
790 if (dont_sync_undo == MAYBE) |
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
791 dont_sync_undo = TRUE; |
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
792 else |
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
793 dont_sync_undo = FALSE; |
10640
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
794 if (cmdchar == K_PS) |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
795 /* Got here from normal mode when bracketed paste started. */ |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
796 c = K_PS; |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
797 else |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
798 do |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
799 { |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
800 c = safe_vgetc(); |
14035
bccd66fa00c1
patch 8.1.0035: not easy to switch between prompt buffer and other windows
Christian Brabandt <cb@256bit.org>
parents:
14019
diff
changeset
|
801 |
bccd66fa00c1
patch 8.1.0035: not easy to switch between prompt buffer and other windows
Christian Brabandt <cb@256bit.org>
parents:
14019
diff
changeset
|
802 if (stop_insert_mode) |
bccd66fa00c1
patch 8.1.0035: not easy to switch between prompt buffer and other windows
Christian Brabandt <cb@256bit.org>
parents:
14019
diff
changeset
|
803 { |
bccd66fa00c1
patch 8.1.0035: not easy to switch between prompt buffer and other windows
Christian Brabandt <cb@256bit.org>
parents:
14019
diff
changeset
|
804 // Insert mode ended, possibly from a callback. |
bccd66fa00c1
patch 8.1.0035: not easy to switch between prompt buffer and other windows
Christian Brabandt <cb@256bit.org>
parents:
14019
diff
changeset
|
805 count = 0; |
bccd66fa00c1
patch 8.1.0035: not easy to switch between prompt buffer and other windows
Christian Brabandt <cb@256bit.org>
parents:
14019
diff
changeset
|
806 nomove = TRUE; |
bccd66fa00c1
patch 8.1.0035: not easy to switch between prompt buffer and other windows
Christian Brabandt <cb@256bit.org>
parents:
14019
diff
changeset
|
807 goto doESCkey; |
bccd66fa00c1
patch 8.1.0035: not easy to switch between prompt buffer and other windows
Christian Brabandt <cb@256bit.org>
parents:
14019
diff
changeset
|
808 } |
12960
004bc78c88e6
patch 8.0.1356: using simalt in a GUIEnter autocommand inserts characters
Christian Brabandt <cb@256bit.org>
parents:
12924
diff
changeset
|
809 } while (c == K_IGNORE || c == K_NOP); |
7 | 810 |
978 | 811 /* Don't want K_CURSORHOLD for the second key, e.g., after CTRL-V. */ |
812 did_cursorhold = TRUE; | |
813 | |
7 | 814 #ifdef FEAT_RIGHTLEFT |
815 if (p_hkmap && KeyTyped) | |
816 c = hkmap(c); /* Hebrew mode mapping */ | |
817 #endif | |
818 #ifdef FEAT_FKMAP | |
819 if (p_fkmap && KeyTyped) | |
820 c = fkmap(c); /* Farsi mode mapping */ | |
821 #endif | |
822 | |
823 #ifdef FEAT_INS_EXPAND | |
659 | 824 /* |
825 * Special handling of keys while the popup menu is visible or wanted | |
897 | 826 * and the cursor is still in the completed word. Only when there is |
827 * a match, skip this when no matches were found. | |
659 | 828 */ |
897 | 829 if (compl_started |
830 && pum_wanted() | |
831 && curwin->w_cursor.col >= compl_col | |
832 && (compl_shown_match == NULL | |
833 || compl_shown_match != compl_shown_match->cp_next)) | |
659 | 834 { |
835 /* BS: Delete one character from "compl_leader". */ | |
836 if ((c == K_BS || c == Ctrl_H) | |
836 | 837 && curwin->w_cursor.col > compl_col |
838 && (c = ins_compl_bs()) == NUL) | |
657 | 839 continue; |
840 | |
659 | 841 /* When no match was selected or it was edited. */ |
842 if (!compl_used_match) | |
657 | 843 { |
659 | 844 /* CTRL-L: Add one character from the current match to |
836 | 845 * "compl_leader". Except when at the original match and |
846 * there is nothing to add, CTRL-L works like CTRL-P then. */ | |
847 if (c == Ctrl_L | |
6657 | 848 && (!CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode) |
1872 | 849 || (int)STRLEN(compl_shown_match->cp_str) |
836 | 850 > curwin->w_cursor.col - compl_col)) |
659 | 851 { |
852 ins_compl_addfrommatch(); | |
853 continue; | |
854 } | |
855 | |
1430 | 856 /* A non-white character that fits in with the current |
857 * completion: Add to "compl_leader". */ | |
858 if (ins_compl_accept_char(c)) | |
659 | 859 { |
13380
69517d67421f
patch 8.0.1564: too many #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
13244
diff
changeset
|
860 #if defined(FEAT_EVAL) |
3390 | 861 /* Trigger InsertCharPre. */ |
862 char_u *str = do_insert_char_pre(c); | |
863 char_u *p; | |
864 | |
865 if (str != NULL) | |
866 { | |
11127
506f5d8b7d8b
patch 8.0.0451: some macros are in lower case
Christian Brabandt <cb@256bit.org>
parents:
11121
diff
changeset
|
867 for (p = str; *p != NUL; MB_PTR_ADV(p)) |
3390 | 868 ins_compl_addleader(PTR2CHAR(p)); |
869 vim_free(str); | |
870 } | |
871 else | |
872 #endif | |
873 ins_compl_addleader(c); | |
659 | 874 continue; |
875 } | |
665 | 876 |
887 | 877 /* Pressing CTRL-Y selects the current match. When |
825 | 878 * compl_enter_selects is set the Enter key does the same. */ |
10291
d9bd03a0d70f
commit https://github.com/vim/vim/commit/cbd3bd6cbed5baf418b037b17ad46e339ff59174
Christian Brabandt <cb@256bit.org>
parents:
10289
diff
changeset
|
879 if ((c == Ctrl_Y || (compl_enter_selects |
d9bd03a0d70f
commit https://github.com/vim/vim/commit/cbd3bd6cbed5baf418b037b17ad46e339ff59174
Christian Brabandt <cb@256bit.org>
parents:
10289
diff
changeset
|
880 && (c == CAR || c == K_KENTER || c == NL))) |
d9bd03a0d70f
commit https://github.com/vim/vim/commit/cbd3bd6cbed5baf418b037b17ad46e339ff59174
Christian Brabandt <cb@256bit.org>
parents:
10289
diff
changeset
|
881 && stop_arrow() == OK) |
665 | 882 { |
883 ins_compl_delete(); | |
10277
154d5a2e7395
commit https://github.com/vim/vim/commit/472e85970ee3a80abd824bef510df12e9cfe9e96
Christian Brabandt <cb@256bit.org>
parents:
10120
diff
changeset
|
884 ins_compl_insert(FALSE); |
665 | 885 } |
657 | 886 } |
887 } | |
888 | |
7 | 889 /* Prepare for or stop CTRL-X mode. This doesn't do completion, but |
890 * it does fix up the text when finishing completion. */ | |
665 | 891 compl_get_longest = FALSE; |
1526 | 892 if (ins_compl_prep(c)) |
657 | 893 continue; |
7 | 894 #endif |
895 | |
477 | 896 /* CTRL-\ CTRL-N goes to Normal mode, |
897 * CTRL-\ CTRL-G goes to mode selected with 'insertmode', | |
898 * CTRL-\ CTRL-O is like CTRL-O but without moving the cursor. */ | |
7 | 899 if (c == Ctrl_BSL) |
900 { | |
901 /* may need to redraw when no more chars available now */ | |
661 | 902 ins_redraw(FALSE); |
7 | 903 ++no_mapping; |
904 ++allow_keys; | |
1389 | 905 c = plain_vgetc(); |
7 | 906 --no_mapping; |
907 --allow_keys; | |
477 | 908 if (c != Ctrl_N && c != Ctrl_G && c != Ctrl_O) |
7 | 909 { |
477 | 910 /* it's something else */ |
7 | 911 vungetc(c); |
912 c = Ctrl_BSL; | |
913 } | |
914 else if (c == Ctrl_G && p_im) | |
915 continue; | |
916 else | |
917 { | |
477 | 918 if (c == Ctrl_O) |
919 { | |
920 ins_ctrl_o(); | |
921 ins_at_eol = FALSE; /* cursor keeps its column */ | |
922 nomove = TRUE; | |
923 } | |
7 | 924 count = 0; |
925 goto doESCkey; | |
926 } | |
927 } | |
928 | |
929 #ifdef FEAT_DIGRAPHS | |
930 c = do_digraph(c); | |
931 #endif | |
932 | |
933 #ifdef FEAT_INS_EXPAND | |
934 if ((c == Ctrl_V || c == Ctrl_Q) && ctrl_x_mode == CTRL_X_CMDLINE) | |
935 goto docomplete; | |
936 #endif | |
937 if (c == Ctrl_V || c == Ctrl_Q) | |
938 { | |
939 ins_ctrl_v(); | |
940 c = Ctrl_V; /* pretend CTRL-V is last typed character */ | |
941 continue; | |
942 } | |
943 | |
944 #ifdef FEAT_CINDENT | |
945 if (cindent_on() | |
946 # ifdef FEAT_INS_EXPAND | |
947 && ctrl_x_mode == 0 | |
948 # endif | |
949 ) | |
950 { | |
951 /* A key name preceded by a bang means this key is not to be | |
952 * inserted. Skip ahead to the re-indenting below. | |
953 * A key name preceded by a star means that indenting has to be | |
954 * done before inserting the key. */ | |
955 line_is_white = inindent(0); | |
956 if (in_cinkeys(c, '!', line_is_white)) | |
957 goto force_cindent; | |
958 if (can_cindent && in_cinkeys(c, '*', line_is_white) | |
959 && stop_arrow() == OK) | |
960 do_c_expr_indent(); | |
961 } | |
962 #endif | |
963 | |
964 #ifdef FEAT_RIGHTLEFT | |
965 if (curwin->w_p_rl) | |
966 switch (c) | |
967 { | |
968 case K_LEFT: c = K_RIGHT; break; | |
969 case K_S_LEFT: c = K_S_RIGHT; break; | |
970 case K_C_LEFT: c = K_C_RIGHT; break; | |
971 case K_RIGHT: c = K_LEFT; break; | |
972 case K_S_RIGHT: c = K_S_LEFT; break; | |
973 case K_C_RIGHT: c = K_C_LEFT; break; | |
974 } | |
975 #endif | |
976 | |
977 /* | |
978 * If 'keymodel' contains "startsel", may start selection. If it | |
979 * does, a CTRL-O and c will be stuffed, we need to get these | |
980 * characters. | |
981 */ | |
982 if (ins_start_select(c)) | |
983 continue; | |
984 | |
985 /* | |
986 * The big switch to handle a character in insert mode. | |
987 */ | |
988 switch (c) | |
989 { | |
449 | 990 case ESC: /* End input mode */ |
7 | 991 if (echeck_abbr(ESC + ABBR_OFF)) |
992 break; | |
12674
e769c912fcd9
patch 8.0.1215: newer gcc warns for implicit fallthrough
Christian Brabandt <cb@256bit.org>
parents:
12551
diff
changeset
|
993 /* FALLTHROUGH */ |
7 | 994 |
449 | 995 case Ctrl_C: /* End input mode */ |
7 | 996 #ifdef FEAT_CMDWIN |
997 if (c == Ctrl_C && cmdwin_type != 0) | |
998 { | |
999 /* Close the cmdline window. */ | |
1000 cmdwin_result = K_IGNORE; | |
1001 got_int = FALSE; /* don't stop executing autocommands et al. */ | |
929 | 1002 nomove = TRUE; |
7 | 1003 goto doESCkey; |
1004 } | |
1005 #endif | |
14103
d053ec57d886
patch 8.1.0069: cannot handle pressing CTRL-C in a prompt buffer
Christian Brabandt <cb@256bit.org>
parents:
14093
diff
changeset
|
1006 #ifdef FEAT_JOB_CHANNEL |
d053ec57d886
patch 8.1.0069: cannot handle pressing CTRL-C in a prompt buffer
Christian Brabandt <cb@256bit.org>
parents:
14093
diff
changeset
|
1007 if (c == Ctrl_C && bt_prompt(curbuf)) |
d053ec57d886
patch 8.1.0069: cannot handle pressing CTRL-C in a prompt buffer
Christian Brabandt <cb@256bit.org>
parents:
14093
diff
changeset
|
1008 { |
d053ec57d886
patch 8.1.0069: cannot handle pressing CTRL-C in a prompt buffer
Christian Brabandt <cb@256bit.org>
parents:
14093
diff
changeset
|
1009 if (invoke_prompt_interrupt()) |
d053ec57d886
patch 8.1.0069: cannot handle pressing CTRL-C in a prompt buffer
Christian Brabandt <cb@256bit.org>
parents:
14093
diff
changeset
|
1010 { |
d053ec57d886
patch 8.1.0069: cannot handle pressing CTRL-C in a prompt buffer
Christian Brabandt <cb@256bit.org>
parents:
14093
diff
changeset
|
1011 if (!bt_prompt(curbuf)) |
d053ec57d886
patch 8.1.0069: cannot handle pressing CTRL-C in a prompt buffer
Christian Brabandt <cb@256bit.org>
parents:
14093
diff
changeset
|
1012 // buffer changed to a non-prompt buffer, get out of |
d053ec57d886
patch 8.1.0069: cannot handle pressing CTRL-C in a prompt buffer
Christian Brabandt <cb@256bit.org>
parents:
14093
diff
changeset
|
1013 // Insert mode |
d053ec57d886
patch 8.1.0069: cannot handle pressing CTRL-C in a prompt buffer
Christian Brabandt <cb@256bit.org>
parents:
14093
diff
changeset
|
1014 goto doESCkey; |
d053ec57d886
patch 8.1.0069: cannot handle pressing CTRL-C in a prompt buffer
Christian Brabandt <cb@256bit.org>
parents:
14093
diff
changeset
|
1015 break; |
d053ec57d886
patch 8.1.0069: cannot handle pressing CTRL-C in a prompt buffer
Christian Brabandt <cb@256bit.org>
parents:
14093
diff
changeset
|
1016 } |
d053ec57d886
patch 8.1.0069: cannot handle pressing CTRL-C in a prompt buffer
Christian Brabandt <cb@256bit.org>
parents:
14093
diff
changeset
|
1017 } |
d053ec57d886
patch 8.1.0069: cannot handle pressing CTRL-C in a prompt buffer
Christian Brabandt <cb@256bit.org>
parents:
14093
diff
changeset
|
1018 #endif |
7 | 1019 |
1020 #ifdef UNIX | |
1021 do_intr: | |
1022 #endif | |
1023 /* when 'insertmode' set, and not halfway a mapping, don't leave | |
1024 * Insert mode */ | |
1025 if (goto_im()) | |
1026 { | |
1027 if (got_int) | |
1028 { | |
1029 (void)vgetc(); /* flush all buffers */ | |
1030 got_int = FALSE; | |
1031 } | |
1032 else | |
6949 | 1033 vim_beep(BO_IM); |
7 | 1034 break; |
1035 } | |
1036 doESCkey: | |
1037 /* | |
1038 * This is the ONLY return from edit()! | |
1039 */ | |
1040 /* Always update o_lnum, so that a "CTRL-O ." that adds a line | |
1041 * still puts the cursor back after the inserted text. */ | |
230 | 1042 if (ins_at_eol && gchar_cursor() == NUL) |
7 | 1043 o_lnum = curwin->w_cursor.lnum; |
1044 | |
477 | 1045 if (ins_esc(&count, cmdchar, nomove)) |
11 | 1046 { |
14985
4ebda55537a5
patch 8.1.0504: when CTRL-C is mapped it triggers InsertLeave
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
1047 // When CTRL-C was typed got_int will be set, with the result |
4ebda55537a5
patch 8.1.0504: when CTRL-C is mapped it triggers InsertLeave
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
1048 // that the autocommands won't be executed. When mapped got_int |
4ebda55537a5
patch 8.1.0504: when CTRL-C is mapped it triggers InsertLeave
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
1049 // is not set, but let's keep the behavior the same. |
4ebda55537a5
patch 8.1.0504: when CTRL-C is mapped it triggers InsertLeave
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
1050 if (cmdchar != 'r' && cmdchar != 'v' && c != Ctrl_C) |
14485
c71d65c3672f
patch 8.1.0256: using setline() in TextChangedI splits undo
Christian Brabandt <cb@256bit.org>
parents:
14465
diff
changeset
|
1051 ins_apply_autocmds(EVENT_INSERTLEAVE); |
993 | 1052 did_cursorhold = FALSE; |
7 | 1053 return (c == Ctrl_O); |
11 | 1054 } |
7 | 1055 continue; |
1056 | |
449 | 1057 case Ctrl_Z: /* suspend when 'insertmode' set */ |
1058 if (!p_im) | |
1059 goto normalchar; /* insert CTRL-Z as normal char */ | |
10636
3db97def0f35
patch 8.0.0208: internally used commands end up in history
Christian Brabandt <cb@256bit.org>
parents:
10468
diff
changeset
|
1060 do_cmdline_cmd((char_u *)"stop"); |
10980
5362b4b6042c
patch 8.0.0379: CTRL-Z and mouse click use CTRL-O unnecessary
Christian Brabandt <cb@256bit.org>
parents:
10952
diff
changeset
|
1061 #ifdef CURSOR_SHAPE |
5362b4b6042c
patch 8.0.0379: CTRL-Z and mouse click use CTRL-O unnecessary
Christian Brabandt <cb@256bit.org>
parents:
10952
diff
changeset
|
1062 ui_cursor_shape(); /* may need to update cursor shape */ |
5362b4b6042c
patch 8.0.0379: CTRL-Z and mouse click use CTRL-O unnecessary
Christian Brabandt <cb@256bit.org>
parents:
10952
diff
changeset
|
1063 #endif |
5362b4b6042c
patch 8.0.0379: CTRL-Z and mouse click use CTRL-O unnecessary
Christian Brabandt <cb@256bit.org>
parents:
10952
diff
changeset
|
1064 continue; |
449 | 1065 |
1066 case Ctrl_O: /* execute one command */ | |
502 | 1067 #ifdef FEAT_COMPL_FUNC |
523 | 1068 if (ctrl_x_mode == CTRL_X_OMNI) |
449 | 1069 goto docomplete; |
1070 #endif | |
1071 if (echeck_abbr(Ctrl_O + ABBR_OFF)) | |
1072 break; | |
1073 ins_ctrl_o(); | |
853 | 1074 |
1075 #ifdef FEAT_VIRTUALEDIT | |
1076 /* don't move the cursor left when 'virtualedit' has "onemore". */ | |
1077 if (ve_flags & VE_ONEMORE) | |
1078 { | |
1079 ins_at_eol = FALSE; | |
1080 nomove = TRUE; | |
1081 } | |
1082 #endif | |
449 | 1083 count = 0; |
1084 goto doESCkey; | |
1085 | |
464 | 1086 case K_INS: /* toggle insert/replace mode */ |
1087 case K_KINS: | |
1088 ins_insert(replaceState); | |
1089 break; | |
1090 | |
1091 case K_SELECT: /* end of Select mode mapping - ignore */ | |
1092 break; | |
1093 | |
449 | 1094 case K_HELP: /* Help key works like <ESC> <Help> */ |
1095 case K_F1: | |
1096 case K_XF1: | |
1097 stuffcharReadbuff(K_HELP); | |
1098 if (p_im) | |
1099 need_start_insertmode = TRUE; | |
1100 goto doESCkey; | |
1101 | |
1102 #ifdef FEAT_NETBEANS_INTG | |
1103 case K_F21: /* NetBeans command */ | |
1104 ++no_mapping; /* don't map the next key hits */ | |
1389 | 1105 i = plain_vgetc(); |
449 | 1106 --no_mapping; |
1107 netbeans_keycommand(i); | |
1108 break; | |
1109 #endif | |
1110 | |
1111 case K_ZERO: /* Insert the previously inserted text. */ | |
7 | 1112 case NUL: |
1113 case Ctrl_A: | |
449 | 1114 /* For ^@ the trailing ESC will end the insert, unless there is an |
1115 * error. */ | |
7 | 1116 if (stuff_inserted(NUL, 1L, (c == Ctrl_A)) == FAIL |
1117 && c != Ctrl_A && !p_im) | |
1118 goto doESCkey; /* quit insert mode */ | |
1119 inserted_space = FALSE; | |
1120 break; | |
1121 | |
449 | 1122 case Ctrl_R: /* insert the contents of a register */ |
7 | 1123 ins_reg(); |
1124 auto_format(FALSE, TRUE); | |
1125 inserted_space = FALSE; | |
1126 break; | |
1127 | |
449 | 1128 case Ctrl_G: /* commands starting with CTRL-G */ |
7 | 1129 ins_ctrl_g(); |
1130 break; | |
1131 | |
449 | 1132 case Ctrl_HAT: /* switch input mode and/or langmap */ |
1133 ins_ctrl_hat(); | |
7 | 1134 break; |
1135 | |
1136 #ifdef FEAT_RIGHTLEFT | |
449 | 1137 case Ctrl__: /* switch between languages */ |
7 | 1138 if (!p_ari) |
1139 goto normalchar; | |
1140 ins_ctrl_(); | |
1141 break; | |
1142 #endif | |
1143 | |
449 | 1144 case Ctrl_D: /* Make indent one shiftwidth smaller. */ |
7 | 1145 #if defined(FEAT_INS_EXPAND) && defined(FEAT_FIND_ID) |
1146 if (ctrl_x_mode == CTRL_X_PATH_DEFINES) | |
1147 goto docomplete; | |
1148 #endif | |
1149 /* FALLTHROUGH */ | |
1150 | |
449 | 1151 case Ctrl_T: /* Make indent one shiftwidth greater. */ |
7 | 1152 # ifdef FEAT_INS_EXPAND |
1153 if (c == Ctrl_T && ctrl_x_mode == CTRL_X_THESAURUS) | |
1154 { | |
449 | 1155 if (has_compl_option(FALSE)) |
1156 goto docomplete; | |
1157 break; | |
7 | 1158 } |
1159 # endif | |
1160 ins_shift(c, lastc); | |
1161 auto_format(FALSE, TRUE); | |
1162 inserted_space = FALSE; | |
1163 break; | |
1164 | |
449 | 1165 case K_DEL: /* delete character under the cursor */ |
7 | 1166 case K_KDEL: |
1167 ins_del(); | |
1168 auto_format(FALSE, TRUE); | |
1169 break; | |
1170 | |
449 | 1171 case K_BS: /* delete character before the cursor */ |
7 | 1172 case Ctrl_H: |
1173 did_backspace = ins_bs(c, BACKSPACE_CHAR, &inserted_space); | |
1174 auto_format(FALSE, TRUE); | |
1175 break; | |
1176 | |
449 | 1177 case Ctrl_W: /* delete word before the cursor */ |
14035
bccd66fa00c1
patch 8.1.0035: not easy to switch between prompt buffer and other windows
Christian Brabandt <cb@256bit.org>
parents:
14019
diff
changeset
|
1178 #ifdef FEAT_JOB_CHANNEL |
bccd66fa00c1
patch 8.1.0035: not easy to switch between prompt buffer and other windows
Christian Brabandt <cb@256bit.org>
parents:
14019
diff
changeset
|
1179 if (bt_prompt(curbuf) && (mod_mask & MOD_MASK_SHIFT) == 0) |
bccd66fa00c1
patch 8.1.0035: not easy to switch between prompt buffer and other windows
Christian Brabandt <cb@256bit.org>
parents:
14019
diff
changeset
|
1180 { |
bccd66fa00c1
patch 8.1.0035: not easy to switch between prompt buffer and other windows
Christian Brabandt <cb@256bit.org>
parents:
14019
diff
changeset
|
1181 // In a prompt window CTRL-W is used for window commands. |
bccd66fa00c1
patch 8.1.0035: not easy to switch between prompt buffer and other windows
Christian Brabandt <cb@256bit.org>
parents:
14019
diff
changeset
|
1182 // Use Shift-CTRL-W to delete a word. |
bccd66fa00c1
patch 8.1.0035: not easy to switch between prompt buffer and other windows
Christian Brabandt <cb@256bit.org>
parents:
14019
diff
changeset
|
1183 stuffcharReadbuff(Ctrl_W); |
14093
a9d94f10ecef
patch 8.1.0064: typing CTRL-W in a prompt buffer shows mode "-- --"
Christian Brabandt <cb@256bit.org>
parents:
14079
diff
changeset
|
1184 restart_edit = 'A'; |
14035
bccd66fa00c1
patch 8.1.0035: not easy to switch between prompt buffer and other windows
Christian Brabandt <cb@256bit.org>
parents:
14019
diff
changeset
|
1185 nomove = TRUE; |
bccd66fa00c1
patch 8.1.0035: not easy to switch between prompt buffer and other windows
Christian Brabandt <cb@256bit.org>
parents:
14019
diff
changeset
|
1186 count = 0; |
bccd66fa00c1
patch 8.1.0035: not easy to switch between prompt buffer and other windows
Christian Brabandt <cb@256bit.org>
parents:
14019
diff
changeset
|
1187 goto doESCkey; |
bccd66fa00c1
patch 8.1.0035: not easy to switch between prompt buffer and other windows
Christian Brabandt <cb@256bit.org>
parents:
14019
diff
changeset
|
1188 } |
bccd66fa00c1
patch 8.1.0035: not easy to switch between prompt buffer and other windows
Christian Brabandt <cb@256bit.org>
parents:
14019
diff
changeset
|
1189 #endif |
7 | 1190 did_backspace = ins_bs(c, BACKSPACE_WORD, &inserted_space); |
1191 auto_format(FALSE, TRUE); | |
1192 break; | |
1193 | |
449 | 1194 case Ctrl_U: /* delete all inserted text in current line */ |
12 | 1195 # ifdef FEAT_COMPL_FUNC |
1196 /* CTRL-X CTRL-U completes with 'completefunc'. */ | |
449 | 1197 if (ctrl_x_mode == CTRL_X_FUNCTION) |
12 | 1198 goto docomplete; |
1199 # endif | |
7 | 1200 did_backspace = ins_bs(c, BACKSPACE_LINE, &inserted_space); |
1201 auto_format(FALSE, TRUE); | |
1202 inserted_space = FALSE; | |
1203 break; | |
1204 | |
1205 #ifdef FEAT_MOUSE | |
449 | 1206 case K_LEFTMOUSE: /* mouse keys */ |
7 | 1207 case K_LEFTMOUSE_NM: |
1208 case K_LEFTDRAG: | |
1209 case K_LEFTRELEASE: | |
1210 case K_LEFTRELEASE_NM: | |
12865
ebb4f6c93598
patch 8.0.1309: cannot use 'balloonexpr' in a terminal
Christian Brabandt <cb@256bit.org>
parents:
12716
diff
changeset
|
1211 case K_MOUSEMOVE: |
7 | 1212 case K_MIDDLEMOUSE: |
1213 case K_MIDDLEDRAG: | |
1214 case K_MIDDLERELEASE: | |
1215 case K_RIGHTMOUSE: | |
1216 case K_RIGHTDRAG: | |
1217 case K_RIGHTRELEASE: | |
1218 case K_X1MOUSE: | |
1219 case K_X1DRAG: | |
1220 case K_X1RELEASE: | |
1221 case K_X2MOUSE: | |
1222 case K_X2DRAG: | |
1223 case K_X2RELEASE: | |
1224 ins_mouse(c); | |
1225 break; | |
1226 | |
449 | 1227 case K_MOUSEDOWN: /* Default action for scroll wheel up: scroll up */ |
2409
0ca06a92adfb
Add support for horizontal scroll wheel. (Bjorn Winckler)
Bram Moolenaar <bram@vim.org>
parents:
2378
diff
changeset
|
1228 ins_mousescroll(MSCR_DOWN); |
7 | 1229 break; |
1230 | |
449 | 1231 case K_MOUSEUP: /* Default action for scroll wheel down: scroll down */ |
2409
0ca06a92adfb
Add support for horizontal scroll wheel. (Bjorn Winckler)
Bram Moolenaar <bram@vim.org>
parents:
2378
diff
changeset
|
1232 ins_mousescroll(MSCR_UP); |
0ca06a92adfb
Add support for horizontal scroll wheel. (Bjorn Winckler)
Bram Moolenaar <bram@vim.org>
parents:
2378
diff
changeset
|
1233 break; |
0ca06a92adfb
Add support for horizontal scroll wheel. (Bjorn Winckler)
Bram Moolenaar <bram@vim.org>
parents:
2378
diff
changeset
|
1234 |
0ca06a92adfb
Add support for horizontal scroll wheel. (Bjorn Winckler)
Bram Moolenaar <bram@vim.org>
parents:
2378
diff
changeset
|
1235 case K_MOUSELEFT: /* Scroll wheel left */ |
0ca06a92adfb
Add support for horizontal scroll wheel. (Bjorn Winckler)
Bram Moolenaar <bram@vim.org>
parents:
2378
diff
changeset
|
1236 ins_mousescroll(MSCR_LEFT); |
0ca06a92adfb
Add support for horizontal scroll wheel. (Bjorn Winckler)
Bram Moolenaar <bram@vim.org>
parents:
2378
diff
changeset
|
1237 break; |
0ca06a92adfb
Add support for horizontal scroll wheel. (Bjorn Winckler)
Bram Moolenaar <bram@vim.org>
parents:
2378
diff
changeset
|
1238 |
0ca06a92adfb
Add support for horizontal scroll wheel. (Bjorn Winckler)
Bram Moolenaar <bram@vim.org>
parents:
2378
diff
changeset
|
1239 case K_MOUSERIGHT: /* Scroll wheel right */ |
0ca06a92adfb
Add support for horizontal scroll wheel. (Bjorn Winckler)
Bram Moolenaar <bram@vim.org>
parents:
2378
diff
changeset
|
1240 ins_mousescroll(MSCR_RIGHT); |
7 | 1241 break; |
1242 #endif | |
10640
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
1243 case K_PS: |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
1244 bracketed_paste(PASTE_INSERT, FALSE, NULL); |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
1245 if (cmdchar == K_PS) |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
1246 /* invoked from normal mode, bail out */ |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
1247 goto doESCkey; |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
1248 break; |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
1249 case K_PE: |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
1250 /* Got K_PE without K_PS, ignore. */ |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
1251 break; |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
1252 |
692 | 1253 #ifdef FEAT_GUI_TABLINE |
1254 case K_TABLINE: | |
1255 case K_TABMENU: | |
1256 ins_tabline(c); | |
1257 break; | |
1258 #endif | |
7 | 1259 |
449 | 1260 case K_IGNORE: /* Something mapped to nothing */ |
7 | 1261 break; |
1262 | |
661 | 1263 case K_CURSORHOLD: /* Didn't type something for a while. */ |
14485
c71d65c3672f
patch 8.1.0256: using setline() in TextChangedI splits undo
Christian Brabandt <cb@256bit.org>
parents:
14465
diff
changeset
|
1264 ins_apply_autocmds(EVENT_CURSORHOLDI); |
661 | 1265 did_cursorhold = TRUE; |
1266 break; | |
1267 | |
625 | 1268 #ifdef FEAT_GUI_W32 |
1269 /* On Win32 ignore <M-F4>, we get it when closing the window was | |
1270 * cancelled. */ | |
1271 case K_F4: | |
1272 if (mod_mask != MOD_MASK_ALT) | |
1273 goto normalchar; | |
1274 break; | |
1275 #endif | |
1276 | |
7 | 1277 #ifdef FEAT_GUI |
1278 case K_VER_SCROLLBAR: | |
1279 ins_scroll(); | |
1280 break; | |
1281 | |
1282 case K_HOR_SCROLLBAR: | |
1283 ins_horscroll(); | |
1284 break; | |
1285 #endif | |
1286 | |
449 | 1287 case K_HOME: /* <Home> */ |
7 | 1288 case K_KHOME: |
1289 case K_S_HOME: | |
1290 case K_C_HOME: | |
1291 ins_home(c); | |
1292 break; | |
1293 | |
449 | 1294 case K_END: /* <End> */ |
7 | 1295 case K_KEND: |
1296 case K_S_END: | |
1297 case K_C_END: | |
1298 ins_end(c); | |
1299 break; | |
1300 | |
449 | 1301 case K_LEFT: /* <Left> */ |
180 | 1302 if (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_CTRL)) |
1303 ins_s_left(); | |
1304 else | |
7074
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
1305 ins_left(dont_sync_undo == FALSE); |
7 | 1306 break; |
1307 | |
449 | 1308 case K_S_LEFT: /* <S-Left> */ |
7 | 1309 case K_C_LEFT: |
1310 ins_s_left(); | |
1311 break; | |
1312 | |
449 | 1313 case K_RIGHT: /* <Right> */ |
180 | 1314 if (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_CTRL)) |
1315 ins_s_right(); | |
1316 else | |
7074
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
1317 ins_right(dont_sync_undo == FALSE); |
7 | 1318 break; |
1319 | |
449 | 1320 case K_S_RIGHT: /* <S-Right> */ |
7 | 1321 case K_C_RIGHT: |
1322 ins_s_right(); | |
1323 break; | |
1324 | |
449 | 1325 case K_UP: /* <Up> */ |
665 | 1326 #ifdef FEAT_INS_EXPAND |
1327 if (pum_visible()) | |
1328 goto docomplete; | |
1329 #endif | |
180 | 1330 if (mod_mask & MOD_MASK_SHIFT) |
1331 ins_pageup(); | |
1332 else | |
1333 ins_up(FALSE); | |
7 | 1334 break; |
1335 | |
449 | 1336 case K_S_UP: /* <S-Up> */ |
7 | 1337 case K_PAGEUP: |
1338 case K_KPAGEUP: | |
613 | 1339 #ifdef FEAT_INS_EXPAND |
610 | 1340 if (pum_visible()) |
1341 goto docomplete; | |
613 | 1342 #endif |
7 | 1343 ins_pageup(); |
1344 break; | |
1345 | |
449 | 1346 case K_DOWN: /* <Down> */ |
665 | 1347 #ifdef FEAT_INS_EXPAND |
1348 if (pum_visible()) | |
1349 goto docomplete; | |
1350 #endif | |
180 | 1351 if (mod_mask & MOD_MASK_SHIFT) |
1352 ins_pagedown(); | |
1353 else | |
1354 ins_down(FALSE); | |
7 | 1355 break; |
1356 | |
449 | 1357 case K_S_DOWN: /* <S-Down> */ |
7 | 1358 case K_PAGEDOWN: |
1359 case K_KPAGEDOWN: | |
613 | 1360 #ifdef FEAT_INS_EXPAND |
610 | 1361 if (pum_visible()) |
1362 goto docomplete; | |
613 | 1363 #endif |
7 | 1364 ins_pagedown(); |
1365 break; | |
1366 | |
1367 #ifdef FEAT_DND | |
449 | 1368 case K_DROP: /* drag-n-drop event */ |
7 | 1369 ins_drop(); |
1370 break; | |
1371 #endif | |
1372 | |
449 | 1373 case K_S_TAB: /* When not mapped, use like a normal TAB */ |
7 | 1374 c = TAB; |
1375 /* FALLTHROUGH */ | |
1376 | |
449 | 1377 case TAB: /* TAB or Complete patterns along path */ |
7 | 1378 #if defined(FEAT_INS_EXPAND) && defined(FEAT_FIND_ID) |
1379 if (ctrl_x_mode == CTRL_X_PATH_PATTERNS) | |
1380 goto docomplete; | |
1381 #endif | |
1382 inserted_space = FALSE; | |
1383 if (ins_tab()) | |
1384 goto normalchar; /* insert TAB as a normal char */ | |
1385 auto_format(FALSE, TRUE); | |
1386 break; | |
1387 | |
449 | 1388 case K_KENTER: /* <Enter> */ |
7 | 1389 c = CAR; |
1390 /* FALLTHROUGH */ | |
1391 case CAR: | |
1392 case NL: | |
12477
68d7bc045dbe
patch 8.0.1118: FEAT_WINDOWS adds a lot of #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
12323
diff
changeset
|
1393 #if defined(FEAT_QUICKFIX) |
7 | 1394 /* In a quickfix window a <CR> jumps to the error under the |
1395 * cursor. */ | |
1396 if (bt_quickfix(curbuf) && c == CAR) | |
1397 { | |
644 | 1398 if (curwin->w_llist_ref == NULL) /* quickfix window */ |
1399 do_cmdline_cmd((char_u *)".cc"); | |
1400 else /* location list window */ | |
1401 do_cmdline_cmd((char_u *)".ll"); | |
7 | 1402 break; |
1403 } | |
1404 #endif | |
1405 #ifdef FEAT_CMDWIN | |
1406 if (cmdwin_type != 0) | |
1407 { | |
1408 /* Execute the command in the cmdline window. */ | |
1409 cmdwin_result = CAR; | |
1410 goto doESCkey; | |
1411 } | |
1412 #endif | |
14019
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1413 #ifdef FEAT_JOB_CHANNEL |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1414 if (bt_prompt(curbuf)) |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1415 { |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1416 invoke_prompt_callback(); |
14037
afce2005fdc8
patch 8.1.0036: not restoring Insert mode if leaving prompt buffer with mouse
Christian Brabandt <cb@256bit.org>
parents:
14035
diff
changeset
|
1417 if (!bt_prompt(curbuf)) |
afce2005fdc8
patch 8.1.0036: not restoring Insert mode if leaving prompt buffer with mouse
Christian Brabandt <cb@256bit.org>
parents:
14035
diff
changeset
|
1418 // buffer changed to a non-prompt buffer, get out of |
afce2005fdc8
patch 8.1.0036: not restoring Insert mode if leaving prompt buffer with mouse
Christian Brabandt <cb@256bit.org>
parents:
14035
diff
changeset
|
1419 // Insert mode |
14019
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1420 goto doESCkey; |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1421 break; |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1422 } |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1423 #endif |
13772
cc21507ee4b1
patch 8.0.1758: open_line() returns TRUE/FALSE for success/failure
Christian Brabandt <cb@256bit.org>
parents:
13718
diff
changeset
|
1424 if (ins_eol(c) == FAIL && !p_im) |
7 | 1425 goto doESCkey; /* out of memory */ |
1426 auto_format(FALSE, FALSE); | |
1427 inserted_space = FALSE; | |
1428 break; | |
1429 | |
2250
1bac28a53fae
Add the conceal patch from Vince Negri.
Bram Moolenaar <bram@vim.org>
parents:
2227
diff
changeset
|
1430 #if defined(FEAT_DIGRAPHS) || defined(FEAT_INS_EXPAND) |
449 | 1431 case Ctrl_K: /* digraph or keyword completion */ |
7 | 1432 # ifdef FEAT_INS_EXPAND |
1433 if (ctrl_x_mode == CTRL_X_DICTIONARY) | |
1434 { | |
449 | 1435 if (has_compl_option(TRUE)) |
1436 goto docomplete; | |
1437 break; | |
7 | 1438 } |
1439 # endif | |
1440 # ifdef FEAT_DIGRAPHS | |
1441 c = ins_digraph(); | |
1442 if (c == NUL) | |
1443 break; | |
1444 # endif | |
1445 goto normalchar; | |
449 | 1446 #endif |
7 | 1447 |
1448 #ifdef FEAT_INS_EXPAND | |
464 | 1449 case Ctrl_X: /* Enter CTRL-X mode */ |
1450 ins_ctrl_x(); | |
1451 break; | |
1452 | |
449 | 1453 case Ctrl_RSB: /* Tag name completion after ^X */ |
7 | 1454 if (ctrl_x_mode != CTRL_X_TAGS) |
1455 goto normalchar; | |
1456 goto docomplete; | |
1457 | |
449 | 1458 case Ctrl_F: /* File name completion after ^X */ |
7 | 1459 if (ctrl_x_mode != CTRL_X_FILES) |
1460 goto normalchar; | |
1461 goto docomplete; | |
477 | 1462 |
1463 case 's': /* Spelling completion after ^X */ | |
1464 case Ctrl_S: | |
1465 if (ctrl_x_mode != CTRL_X_SPELL) | |
1466 goto normalchar; | |
1467 goto docomplete; | |
7 | 1468 #endif |
1469 | |
449 | 1470 case Ctrl_L: /* Whole line completion after ^X */ |
7 | 1471 #ifdef FEAT_INS_EXPAND |
1472 if (ctrl_x_mode != CTRL_X_WHOLE_LINE) | |
1473 #endif | |
1474 { | |
1475 /* CTRL-L with 'insertmode' set: Leave Insert mode */ | |
1476 if (p_im) | |
1477 { | |
1478 if (echeck_abbr(Ctrl_L + ABBR_OFF)) | |
1479 break; | |
1480 goto doESCkey; | |
1481 } | |
1482 goto normalchar; | |
1483 } | |
1484 #ifdef FEAT_INS_EXPAND | |
1485 /* FALLTHROUGH */ | |
1486 | |
449 | 1487 case Ctrl_P: /* Do previous/next pattern completion */ |
7 | 1488 case Ctrl_N: |
1489 /* if 'complete' is empty then plain ^P is no longer special, | |
1490 * but it is under other ^X modes */ | |
1491 if (*curbuf->b_p_cpt == NUL | |
13215
ae5f855a64be
patch 8.0.1482: using feedkeys() does not work to test completion
Christian Brabandt <cb@256bit.org>
parents:
13214
diff
changeset
|
1492 && (ctrl_x_mode == CTRL_X_NORMAL |
ae5f855a64be
patch 8.0.1482: using feedkeys() does not work to test completion
Christian Brabandt <cb@256bit.org>
parents:
13214
diff
changeset
|
1493 || ctrl_x_mode == CTRL_X_WHOLE_LINE) |
449 | 1494 && !(compl_cont_status & CONT_LOCAL)) |
7 | 1495 goto normalchar; |
1496 | |
1497 docomplete: | |
1927 | 1498 compl_busy = TRUE; |
11073
d2178a6cc9f3
patch 8.0.0425: build errors when building without folding
Christian Brabandt <cb@256bit.org>
parents:
11002
diff
changeset
|
1499 #ifdef FEAT_FOLDING |
8891
d7ba3f9b9ba6
commit https://github.com/vim/vim/commit/429fcfbf9a9275367fe9441a50a3dcd773497d84
Christian Brabandt <cb@256bit.org>
parents:
8362
diff
changeset
|
1500 disable_fold_update++; /* don't redraw folds here */ |
11073
d2178a6cc9f3
patch 8.0.0425: build errors when building without folding
Christian Brabandt <cb@256bit.org>
parents:
11002
diff
changeset
|
1501 #endif |
8224
2baf64fead5e
commit https://github.com/vim/vim/commit/8aefbe0ad5d05ee7225b20024b0f3023286ebd0f
Christian Brabandt <cb@256bit.org>
parents:
8090
diff
changeset
|
1502 if (ins_complete(c, TRUE) == FAIL) |
449 | 1503 compl_cont_status = 0; |
11073
d2178a6cc9f3
patch 8.0.0425: build errors when building without folding
Christian Brabandt <cb@256bit.org>
parents:
11002
diff
changeset
|
1504 #ifdef FEAT_FOLDING |
8891
d7ba3f9b9ba6
commit https://github.com/vim/vim/commit/429fcfbf9a9275367fe9441a50a3dcd773497d84
Christian Brabandt <cb@256bit.org>
parents:
8362
diff
changeset
|
1505 disable_fold_update--; |
11073
d2178a6cc9f3
patch 8.0.0425: build errors when building without folding
Christian Brabandt <cb@256bit.org>
parents:
11002
diff
changeset
|
1506 #endif |
1927 | 1507 compl_busy = FALSE; |
7 | 1508 break; |
1509 #endif /* FEAT_INS_EXPAND */ | |
1510 | |
449 | 1511 case Ctrl_Y: /* copy from previous line or scroll down */ |
1512 case Ctrl_E: /* copy from next line or scroll up */ | |
1513 c = ins_ctrl_ey(c); | |
7 | 1514 break; |
1515 | |
1516 default: | |
1517 #ifdef UNIX | |
1518 if (c == intr_char) /* special interrupt char */ | |
1519 goto do_intr; | |
1520 #endif | |
1521 | |
2845 | 1522 normalchar: |
7 | 1523 /* |
4352 | 1524 * Insert a normal character. |
7 | 1525 */ |
13380
69517d67421f
patch 8.0.1564: too many #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
13244
diff
changeset
|
1526 #if defined(FEAT_EVAL) |
2845 | 1527 if (!p_paste) |
1528 { | |
3390 | 1529 /* Trigger InsertCharPre. */ |
1530 char_u *str = do_insert_char_pre(c); | |
1531 char_u *p; | |
1532 | |
1533 if (str != NULL) | |
2845 | 1534 { |
3390 | 1535 if (*str != NUL && stop_arrow() != FAIL) |
2845 | 1536 { |
3390 | 1537 /* Insert the new value of v:char literally. */ |
11127
506f5d8b7d8b
patch 8.0.0451: some macros are in lower case
Christian Brabandt <cb@256bit.org>
parents:
11121
diff
changeset
|
1538 for (p = str; *p != NUL; MB_PTR_ADV(p)) |
2845 | 1539 { |
3390 | 1540 c = PTR2CHAR(p); |
1541 if (c == CAR || c == K_KENTER || c == NL) | |
1542 ins_eol(c); | |
1543 else | |
1544 ins_char(c); | |
2845 | 1545 } |
3390 | 1546 AppendToRedobuffLit(str, -1); |
2845 | 1547 } |
3390 | 1548 vim_free(str); |
1549 c = NUL; | |
2845 | 1550 } |
1551 | |
3390 | 1552 /* If the new value is already inserted or an empty string |
1553 * then don't insert any character. */ | |
2845 | 1554 if (c == NUL) |
1555 break; | |
1556 } | |
1557 #endif | |
7 | 1558 #ifdef FEAT_SMARTINDENT |
1559 /* Try to perform smart-indenting. */ | |
1560 ins_try_si(c); | |
1561 #endif | |
1562 | |
1563 if (c == ' ') | |
1564 { | |
1565 inserted_space = TRUE; | |
1566 #ifdef FEAT_CINDENT | |
1567 if (inindent(0)) | |
1568 can_cindent = FALSE; | |
1569 #endif | |
1570 if (Insstart_blank_vcol == MAXCOL | |
1571 && curwin->w_cursor.lnum == Insstart.lnum) | |
1572 Insstart_blank_vcol = get_nolist_virtcol(); | |
1573 } | |
1574 | |
3448 | 1575 /* Insert a normal character and check for abbreviations on a |
1576 * special character. Let CTRL-] expand abbreviations without | |
1577 * inserting it. */ | |
1578 if (vim_iswordc(c) || (!echeck_abbr( | |
15595
1ec942f1b648
patch 8.1.0805: too many #ifdefs
Bram Moolenaar <Bram@vim.org>
parents:
15569
diff
changeset
|
1579 // Add ABBR_OFF for characters above 0x100, this is |
1ec942f1b648
patch 8.1.0805: too many #ifdefs
Bram Moolenaar <Bram@vim.org>
parents:
15569
diff
changeset
|
1580 // what check_abbr() expects. |
1ec942f1b648
patch 8.1.0805: too many #ifdefs
Bram Moolenaar <Bram@vim.org>
parents:
15569
diff
changeset
|
1581 (has_mbyte && c >= 0x100) ? (c + ABBR_OFF) : c) |
1ec942f1b648
patch 8.1.0805: too many #ifdefs
Bram Moolenaar <Bram@vim.org>
parents:
15569
diff
changeset
|
1582 && c != Ctrl_RSB)) |
7 | 1583 { |
1584 insert_special(c, FALSE, FALSE); | |
1585 #ifdef FEAT_RIGHTLEFT | |
1586 revins_legal++; | |
1587 revins_chars++; | |
1588 #endif | |
1589 } | |
1590 | |
1591 auto_format(FALSE, TRUE); | |
1592 | |
1593 #ifdef FEAT_FOLDING | |
1594 /* When inserting a character the cursor line must never be in a | |
1595 * closed fold. */ | |
1596 foldOpenCursor(); | |
1597 #endif | |
1598 break; | |
1599 } /* end of switch (c) */ | |
1600 | |
978 | 1601 /* If typed something may trigger CursorHoldI again. */ |
8945
a3060addc328
commit https://github.com/vim/vim/commit/245c41070c7f37d52be43cce0cb140bd3ade6c7e
Christian Brabandt <cb@256bit.org>
parents:
8943
diff
changeset
|
1602 if (c != K_CURSORHOLD |
13380
69517d67421f
patch 8.0.1564: too many #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
13244
diff
changeset
|
1603 #ifdef FEAT_COMPL_FUNC |
13215
ae5f855a64be
patch 8.0.1482: using feedkeys() does not work to test completion
Christian Brabandt <cb@256bit.org>
parents:
13214
diff
changeset
|
1604 /* but not in CTRL-X mode, a script can't restore the state */ |
ae5f855a64be
patch 8.0.1482: using feedkeys() does not work to test completion
Christian Brabandt <cb@256bit.org>
parents:
13214
diff
changeset
|
1605 && ctrl_x_mode == CTRL_X_NORMAL |
13380
69517d67421f
patch 8.0.1564: too many #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
13244
diff
changeset
|
1606 #endif |
8945
a3060addc328
commit https://github.com/vim/vim/commit/245c41070c7f37d52be43cce0cb140bd3ade6c7e
Christian Brabandt <cb@256bit.org>
parents:
8943
diff
changeset
|
1607 ) |
978 | 1608 did_cursorhold = FALSE; |
1609 | |
7 | 1610 /* If the cursor was moved we didn't just insert a space */ |
1611 if (arrow_used) | |
1612 inserted_space = FALSE; | |
1613 | |
1614 #ifdef FEAT_CINDENT | |
1615 if (can_cindent && cindent_on() | |
1616 # ifdef FEAT_INS_EXPAND | |
13215
ae5f855a64be
patch 8.0.1482: using feedkeys() does not work to test completion
Christian Brabandt <cb@256bit.org>
parents:
13214
diff
changeset
|
1617 && ctrl_x_mode == CTRL_X_NORMAL |
7 | 1618 # endif |
1619 ) | |
1620 { | |
1621 force_cindent: | |
1622 /* | |
1623 * Indent now if a key was typed that is in 'cinkeys'. | |
1624 */ | |
1625 if (in_cinkeys(c, ' ', line_is_white)) | |
1626 { | |
1627 if (stop_arrow() == OK) | |
1628 /* re-indent the current line */ | |
1629 do_c_expr_indent(); | |
1630 } | |
1631 } | |
1632 #endif /* FEAT_CINDENT */ | |
1633 | |
1634 } /* for (;;) */ | |
1635 /* NOTREACHED */ | |
1636 } | |
1637 | |
1638 /* | |
1639 * Redraw for Insert mode. | |
1640 * This is postponed until getting the next character to make '$' in the 'cpo' | |
1641 * option work correctly. | |
1642 * Only redraw when there are no characters available. This speeds up | |
1643 * inserting sequences of characters (e.g., for CTRL-R). | |
1644 */ | |
1645 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
1646 ins_redraw( |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
1647 int ready UNUSED) /* not busy with something */ |
7 | 1648 { |
2282
a888ed7ba375
Make updating text for conceal mode simpler. A few compiler warning fixes.
Bram Moolenaar <bram@vim.org>
parents:
2250
diff
changeset
|
1649 #ifdef FEAT_CONCEAL |
a888ed7ba375
Make updating text for conceal mode simpler. A few compiler warning fixes.
Bram Moolenaar <bram@vim.org>
parents:
2250
diff
changeset
|
1650 linenr_T conceal_old_cursor_line = 0; |
a888ed7ba375
Make updating text for conceal mode simpler. A few compiler warning fixes.
Bram Moolenaar <bram@vim.org>
parents:
2250
diff
changeset
|
1651 linenr_T conceal_new_cursor_line = 0; |
a888ed7ba375
Make updating text for conceal mode simpler. A few compiler warning fixes.
Bram Moolenaar <bram@vim.org>
parents:
2250
diff
changeset
|
1652 int conceal_update_lines = FALSE; |
a888ed7ba375
Make updating text for conceal mode simpler. A few compiler warning fixes.
Bram Moolenaar <bram@vim.org>
parents:
2250
diff
changeset
|
1653 #endif |
a888ed7ba375
Make updating text for conceal mode simpler. A few compiler warning fixes.
Bram Moolenaar <bram@vim.org>
parents:
2250
diff
changeset
|
1654 |
5592 | 1655 if (char_avail()) |
1656 return; | |
1657 | |
13380
69517d67421f
patch 8.0.1564: too many #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
13244
diff
changeset
|
1658 #if defined(FEAT_CONCEAL) |
5592 | 1659 /* Trigger CursorMoved if the cursor moved. Not when the popup menu is |
1660 * visible, the command might delete it. */ | |
13380
69517d67421f
patch 8.0.1564: too many #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
13244
diff
changeset
|
1661 if (ready && (has_cursormovedI() |
69517d67421f
patch 8.0.1564: too many #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
13244
diff
changeset
|
1662 # if defined(FEAT_CONCEAL) |
69517d67421f
patch 8.0.1564: too many #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
13244
diff
changeset
|
1663 || curwin->w_p_cole > 0 |
5592 | 1664 # endif |
1665 ) | |
13380
69517d67421f
patch 8.0.1564: too many #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
13244
diff
changeset
|
1666 && !EQUAL_POS(last_cursormoved, curwin->w_cursor) |
5592 | 1667 # ifdef FEAT_INS_EXPAND |
13380
69517d67421f
patch 8.0.1564: too many #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
13244
diff
changeset
|
1668 && !pum_visible() |
5592 | 1669 # endif |
1670 ) | |
1671 { | |
1672 # ifdef FEAT_SYN_HL | |
1673 /* Need to update the screen first, to make sure syntax | |
1674 * highlighting is correct after making a change (e.g., inserting | |
1675 * a "(". The autocommand may also require a redraw, so it's done | |
1676 * again below, unfortunately. */ | |
1677 if (syntax_present(curwin) && must_redraw) | |
1678 update_screen(0); | |
2282
a888ed7ba375
Make updating text for conceal mode simpler. A few compiler warning fixes.
Bram Moolenaar <bram@vim.org>
parents:
2250
diff
changeset
|
1679 # endif |
5592 | 1680 if (has_cursormovedI()) |
8003
94798af62c56
commit https://github.com/vim/vim/commit/f068dcafcfe0c8018e5a559c50769ca1364bd9a5
Christian Brabandt <cb@256bit.org>
parents:
7817
diff
changeset
|
1681 { |
94798af62c56
commit https://github.com/vim/vim/commit/f068dcafcfe0c8018e5a559c50769ca1364bd9a5
Christian Brabandt <cb@256bit.org>
parents:
7817
diff
changeset
|
1682 /* Make sure curswant is correct, an autocommand may call |
94798af62c56
commit https://github.com/vim/vim/commit/f068dcafcfe0c8018e5a559c50769ca1364bd9a5
Christian Brabandt <cb@256bit.org>
parents:
7817
diff
changeset
|
1683 * getcurpos(). */ |
94798af62c56
commit https://github.com/vim/vim/commit/f068dcafcfe0c8018e5a559c50769ca1364bd9a5
Christian Brabandt <cb@256bit.org>
parents:
7817
diff
changeset
|
1684 update_curswant(); |
14485
c71d65c3672f
patch 8.1.0256: using setline() in TextChangedI splits undo
Christian Brabandt <cb@256bit.org>
parents:
14465
diff
changeset
|
1685 ins_apply_autocmds(EVENT_CURSORMOVEDI); |
8003
94798af62c56
commit https://github.com/vim/vim/commit/f068dcafcfe0c8018e5a559c50769ca1364bd9a5
Christian Brabandt <cb@256bit.org>
parents:
7817
diff
changeset
|
1686 } |
5592 | 1687 # ifdef FEAT_CONCEAL |
1688 if (curwin->w_p_cole > 0) | |
1689 { | |
1690 conceal_old_cursor_line = last_cursormoved.lnum; | |
1691 conceal_new_cursor_line = curwin->w_cursor.lnum; | |
1692 conceal_update_lines = TRUE; | |
1693 } | |
1694 # endif | |
1695 last_cursormoved = curwin->w_cursor; | |
13380
69517d67421f
patch 8.0.1564: too many #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
13244
diff
changeset
|
1696 } |
69517d67421f
patch 8.0.1564: too many #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
13244
diff
changeset
|
1697 #endif |
69517d67421f
patch 8.0.1564: too many #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
13244
diff
changeset
|
1698 |
5592 | 1699 /* Trigger TextChangedI if b_changedtick differs. */ |
1700 if (ready && has_textchangedI() | |
13240
5ed6e4a25925
patch 8.0.1494: no autocmd triggered in Insert mode with visible popup menu
Christian Brabandt <cb@256bit.org>
parents:
13238
diff
changeset
|
1701 && curbuf->b_last_changedtick != CHANGEDTICK(curbuf) |
13380
69517d67421f
patch 8.0.1564: too many #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
13244
diff
changeset
|
1702 #ifdef FEAT_INS_EXPAND |
2282
a888ed7ba375
Make updating text for conceal mode simpler. A few compiler warning fixes.
Bram Moolenaar <bram@vim.org>
parents:
2250
diff
changeset
|
1703 && !pum_visible() |
13380
69517d67421f
patch 8.0.1564: too many #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
13244
diff
changeset
|
1704 #endif |
5592 | 1705 ) |
1706 { | |
14079
b5e43a048878
patch 8.1.0057: popup menu displayed wrong when using autocmd
Christian Brabandt <cb@256bit.org>
parents:
14071
diff
changeset
|
1707 aco_save_T aco; |
14485
c71d65c3672f
patch 8.1.0256: using setline() in TextChangedI splits undo
Christian Brabandt <cb@256bit.org>
parents:
14465
diff
changeset
|
1708 varnumber_T tick = CHANGEDTICK(curbuf); |
14463
3b87daa5c37a
patch 8.1.0245: calling setline() in TextChangedI autocmd breaks undo
Christian Brabandt <cb@256bit.org>
parents:
14457
diff
changeset
|
1709 |
14079
b5e43a048878
patch 8.1.0057: popup menu displayed wrong when using autocmd
Christian Brabandt <cb@256bit.org>
parents:
14071
diff
changeset
|
1710 // save and restore curwin and curbuf, in case the autocmd changes them |
b5e43a048878
patch 8.1.0057: popup menu displayed wrong when using autocmd
Christian Brabandt <cb@256bit.org>
parents:
14071
diff
changeset
|
1711 aucmd_prepbuf(&aco, curbuf); |
13240
5ed6e4a25925
patch 8.0.1494: no autocmd triggered in Insert mode with visible popup menu
Christian Brabandt <cb@256bit.org>
parents:
13238
diff
changeset
|
1712 apply_autocmds(EVENT_TEXTCHANGEDI, NULL, NULL, FALSE, curbuf); |
14079
b5e43a048878
patch 8.1.0057: popup menu displayed wrong when using autocmd
Christian Brabandt <cb@256bit.org>
parents:
14071
diff
changeset
|
1713 aucmd_restbuf(&aco); |
13240
5ed6e4a25925
patch 8.0.1494: no autocmd triggered in Insert mode with visible popup menu
Christian Brabandt <cb@256bit.org>
parents:
13238
diff
changeset
|
1714 curbuf->b_last_changedtick = CHANGEDTICK(curbuf); |
14485
c71d65c3672f
patch 8.1.0256: using setline() in TextChangedI splits undo
Christian Brabandt <cb@256bit.org>
parents:
14465
diff
changeset
|
1715 if (tick != CHANGEDTICK(curbuf)) // see ins_apply_autocmds() |
c71d65c3672f
patch 8.1.0256: using setline() in TextChangedI splits undo
Christian Brabandt <cb@256bit.org>
parents:
14465
diff
changeset
|
1716 u_save(curwin->w_cursor.lnum, |
c71d65c3672f
patch 8.1.0256: using setline() in TextChangedI splits undo
Christian Brabandt <cb@256bit.org>
parents:
14465
diff
changeset
|
1717 (linenr_T)(curwin->w_cursor.lnum + 1)); |
13240
5ed6e4a25925
patch 8.0.1494: no autocmd triggered in Insert mode with visible popup menu
Christian Brabandt <cb@256bit.org>
parents:
13238
diff
changeset
|
1718 } |
5ed6e4a25925
patch 8.0.1494: no autocmd triggered in Insert mode with visible popup menu
Christian Brabandt <cb@256bit.org>
parents:
13238
diff
changeset
|
1719 |
13380
69517d67421f
patch 8.0.1564: too many #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
13244
diff
changeset
|
1720 #ifdef FEAT_INS_EXPAND |
13240
5ed6e4a25925
patch 8.0.1494: no autocmd triggered in Insert mode with visible popup menu
Christian Brabandt <cb@256bit.org>
parents:
13238
diff
changeset
|
1721 /* Trigger TextChangedP if b_changedtick differs. When the popupmenu closes |
5ed6e4a25925
patch 8.0.1494: no autocmd triggered in Insert mode with visible popup menu
Christian Brabandt <cb@256bit.org>
parents:
13238
diff
changeset
|
1722 * TextChangedI will need to trigger for backwards compatibility, thus use |
5ed6e4a25925
patch 8.0.1494: no autocmd triggered in Insert mode with visible popup menu
Christian Brabandt <cb@256bit.org>
parents:
13238
diff
changeset
|
1723 * different b_last_changedtick* variables. */ |
5ed6e4a25925
patch 8.0.1494: no autocmd triggered in Insert mode with visible popup menu
Christian Brabandt <cb@256bit.org>
parents:
13238
diff
changeset
|
1724 if (ready && has_textchangedP() |
5ed6e4a25925
patch 8.0.1494: no autocmd triggered in Insert mode with visible popup menu
Christian Brabandt <cb@256bit.org>
parents:
13238
diff
changeset
|
1725 && curbuf->b_last_changedtick_pum != CHANGEDTICK(curbuf) |
5ed6e4a25925
patch 8.0.1494: no autocmd triggered in Insert mode with visible popup menu
Christian Brabandt <cb@256bit.org>
parents:
13238
diff
changeset
|
1726 && pum_visible()) |
5ed6e4a25925
patch 8.0.1494: no autocmd triggered in Insert mode with visible popup menu
Christian Brabandt <cb@256bit.org>
parents:
13238
diff
changeset
|
1727 { |
14079
b5e43a048878
patch 8.1.0057: popup menu displayed wrong when using autocmd
Christian Brabandt <cb@256bit.org>
parents:
14071
diff
changeset
|
1728 aco_save_T aco; |
14485
c71d65c3672f
patch 8.1.0256: using setline() in TextChangedI splits undo
Christian Brabandt <cb@256bit.org>
parents:
14465
diff
changeset
|
1729 varnumber_T tick = CHANGEDTICK(curbuf); |
14079
b5e43a048878
patch 8.1.0057: popup menu displayed wrong when using autocmd
Christian Brabandt <cb@256bit.org>
parents:
14071
diff
changeset
|
1730 |
b5e43a048878
patch 8.1.0057: popup menu displayed wrong when using autocmd
Christian Brabandt <cb@256bit.org>
parents:
14071
diff
changeset
|
1731 // save and restore curwin and curbuf, in case the autocmd changes them |
b5e43a048878
patch 8.1.0057: popup menu displayed wrong when using autocmd
Christian Brabandt <cb@256bit.org>
parents:
14071
diff
changeset
|
1732 aucmd_prepbuf(&aco, curbuf); |
13240
5ed6e4a25925
patch 8.0.1494: no autocmd triggered in Insert mode with visible popup menu
Christian Brabandt <cb@256bit.org>
parents:
13238
diff
changeset
|
1733 apply_autocmds(EVENT_TEXTCHANGEDP, NULL, NULL, FALSE, curbuf); |
14079
b5e43a048878
patch 8.1.0057: popup menu displayed wrong when using autocmd
Christian Brabandt <cb@256bit.org>
parents:
14071
diff
changeset
|
1734 aucmd_restbuf(&aco); |
13240
5ed6e4a25925
patch 8.0.1494: no autocmd triggered in Insert mode with visible popup menu
Christian Brabandt <cb@256bit.org>
parents:
13238
diff
changeset
|
1735 curbuf->b_last_changedtick_pum = CHANGEDTICK(curbuf); |
14485
c71d65c3672f
patch 8.1.0256: using setline() in TextChangedI splits undo
Christian Brabandt <cb@256bit.org>
parents:
14465
diff
changeset
|
1736 if (tick != CHANGEDTICK(curbuf)) // see ins_apply_autocmds() |
c71d65c3672f
patch 8.1.0256: using setline() in TextChangedI splits undo
Christian Brabandt <cb@256bit.org>
parents:
14465
diff
changeset
|
1737 u_save(curwin->w_cursor.lnum, |
c71d65c3672f
patch 8.1.0256: using setline() in TextChangedI splits undo
Christian Brabandt <cb@256bit.org>
parents:
14465
diff
changeset
|
1738 (linenr_T)(curwin->w_cursor.lnum + 1)); |
13240
5ed6e4a25925
patch 8.0.1494: no autocmd triggered in Insert mode with visible popup menu
Christian Brabandt <cb@256bit.org>
parents:
13238
diff
changeset
|
1739 } |
5592 | 1740 #endif |
1741 | |
15436
29f3d59bb6f0
patch 8.1.0726: redrawing specifically for conceal feature
Bram Moolenaar <Bram@vim.org>
parents:
15416
diff
changeset
|
1742 #if defined(FEAT_CONCEAL) |
5592 | 1743 if ((conceal_update_lines |
1744 && (conceal_old_cursor_line != conceal_new_cursor_line | |
1745 || conceal_cursor_line(curwin))) | |
1746 || need_cursor_line_redraw) | |
1747 { | |
1748 if (conceal_old_cursor_line != conceal_new_cursor_line) | |
15436
29f3d59bb6f0
patch 8.1.0726: redrawing specifically for conceal feature
Bram Moolenaar <Bram@vim.org>
parents:
15416
diff
changeset
|
1749 redrawWinline(curwin, conceal_old_cursor_line); |
29f3d59bb6f0
patch 8.1.0726: redrawing specifically for conceal feature
Bram Moolenaar <Bram@vim.org>
parents:
15416
diff
changeset
|
1750 redrawWinline(curwin, conceal_new_cursor_line == 0 |
29f3d59bb6f0
patch 8.1.0726: redrawing specifically for conceal feature
Bram Moolenaar <Bram@vim.org>
parents:
15416
diff
changeset
|
1751 ? curwin->w_cursor.lnum : conceal_new_cursor_line); |
5592 | 1752 curwin->w_valid &= ~VALID_CROW; |
15436
29f3d59bb6f0
patch 8.1.0726: redrawing specifically for conceal feature
Bram Moolenaar <Bram@vim.org>
parents:
15416
diff
changeset
|
1753 need_cursor_line_redraw = FALSE; |
29f3d59bb6f0
patch 8.1.0726: redrawing specifically for conceal feature
Bram Moolenaar <Bram@vim.org>
parents:
15416
diff
changeset
|
1754 } |
29f3d59bb6f0
patch 8.1.0726: redrawing specifically for conceal feature
Bram Moolenaar <Bram@vim.org>
parents:
15416
diff
changeset
|
1755 #endif |
29f3d59bb6f0
patch 8.1.0726: redrawing specifically for conceal feature
Bram Moolenaar <Bram@vim.org>
parents:
15416
diff
changeset
|
1756 if (must_redraw) |
29f3d59bb6f0
patch 8.1.0726: redrawing specifically for conceal feature
Bram Moolenaar <Bram@vim.org>
parents:
15416
diff
changeset
|
1757 update_screen(0); |
29f3d59bb6f0
patch 8.1.0726: redrawing specifically for conceal feature
Bram Moolenaar <Bram@vim.org>
parents:
15416
diff
changeset
|
1758 else if (clear_cmdline || redraw_cmdline) |
29f3d59bb6f0
patch 8.1.0726: redrawing specifically for conceal feature
Bram Moolenaar <Bram@vim.org>
parents:
15416
diff
changeset
|
1759 showmode(); /* clear cmdline and show mode */ |
5592 | 1760 showruler(FALSE); |
1761 setcursor(); | |
1762 emsg_on_display = FALSE; /* may remove error message now */ | |
7 | 1763 } |
1764 | |
1765 /* | |
1766 * Handle a CTRL-V or CTRL-Q typed in Insert mode. | |
1767 */ | |
1768 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
1769 ins_ctrl_v(void) |
7 | 1770 { |
1771 int c; | |
2811 | 1772 int did_putchar = FALSE; |
7 | 1773 |
1774 /* may need to redraw when no more chars available now */ | |
661 | 1775 ins_redraw(FALSE); |
7 | 1776 |
1777 if (redrawing() && !char_avail()) | |
2811 | 1778 { |
7 | 1779 edit_putchar('^', TRUE); |
2811 | 1780 did_putchar = TRUE; |
1781 } | |
7 | 1782 AppendToRedobuff((char_u *)CTRL_V_STR); /* CTRL-V */ |
1783 | |
1784 #ifdef FEAT_CMDL_INFO | |
1785 add_to_showcmd_c(Ctrl_V); | |
1786 #endif | |
1787 | |
1788 c = get_literal(); | |
2811 | 1789 if (did_putchar) |
1790 /* when the line fits in 'columns' the '^' is at the start of the next | |
1791 * line and will not removed by the redraw */ | |
1792 edit_unputchar(); | |
7 | 1793 #ifdef FEAT_CMDL_INFO |
1794 clear_showcmd(); | |
1795 #endif | |
1796 insert_special(c, FALSE, TRUE); | |
1797 #ifdef FEAT_RIGHTLEFT | |
1798 revins_chars++; | |
1799 revins_legal++; | |
1800 #endif | |
1801 } | |
1802 | |
1803 /* | |
1804 * Put a character directly onto the screen. It's not stored in a buffer. | |
1805 * Used while handling CTRL-K, CTRL-V, etc. in Insert mode. | |
1806 */ | |
1807 static int pc_status; | |
1808 #define PC_STATUS_UNSET 0 /* pc_bytes was not set */ | |
1809 #define PC_STATUS_RIGHT 1 /* right halve of double-wide char */ | |
1810 #define PC_STATUS_LEFT 2 /* left halve of double-wide char */ | |
1811 #define PC_STATUS_SET 3 /* pc_bytes was filled */ | |
1812 static char_u pc_bytes[MB_MAXBYTES + 1]; /* saved bytes */ | |
1813 static int pc_attr; | |
1814 static int pc_row; | |
1815 static int pc_col; | |
1816 | |
1817 void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
1818 edit_putchar(int c, int highlight) |
7 | 1819 { |
1820 int attr; | |
1821 | |
1822 if (ScreenLines != NULL) | |
1823 { | |
1824 update_topline(); /* just in case w_topline isn't valid */ | |
1825 validate_cursor(); | |
1826 if (highlight) | |
11158
501f46f7644c
patch 8.0.0466: still macros that should be all-caps
Christian Brabandt <cb@256bit.org>
parents:
11129
diff
changeset
|
1827 attr = HL_ATTR(HLF_8); |
7 | 1828 else |
1829 attr = 0; | |
1830 pc_row = W_WINROW(curwin) + curwin->w_wrow; | |
12513
3ca08bf99396
patch 8.0.1135: W_WINCOL() is always the same
Christian Brabandt <cb@256bit.org>
parents:
12477
diff
changeset
|
1831 pc_col = curwin->w_wincol; |
7 | 1832 pc_status = PC_STATUS_UNSET; |
1833 #ifdef FEAT_RIGHTLEFT | |
1834 if (curwin->w_p_rl) | |
1835 { | |
12515
972ea22c946f
patch 8.0.1136: W_WIDTH() is always the same
Christian Brabandt <cb@256bit.org>
parents:
12513
diff
changeset
|
1836 pc_col += curwin->w_width - 1 - curwin->w_wcol; |
7 | 1837 if (has_mbyte) |
1838 { | |
1839 int fix_col = mb_fix_col(pc_col, pc_row); | |
1840 | |
1841 if (fix_col != pc_col) | |
1842 { | |
1843 screen_putchar(' ', pc_row, fix_col, attr); | |
1844 --curwin->w_wcol; | |
1845 pc_status = PC_STATUS_RIGHT; | |
1846 } | |
1847 } | |
1848 } | |
1849 else | |
1850 #endif | |
1851 { | |
1852 pc_col += curwin->w_wcol; | |
1853 if (mb_lefthalve(pc_row, pc_col)) | |
1854 pc_status = PC_STATUS_LEFT; | |
1855 } | |
1856 | |
1857 /* save the character to be able to put it back */ | |
1858 if (pc_status == PC_STATUS_UNSET) | |
1859 { | |
1860 screen_getbytes(pc_row, pc_col, pc_bytes, &pc_attr); | |
1861 pc_status = PC_STATUS_SET; | |
1862 } | |
1863 screen_putchar(c, pc_row, pc_col, attr); | |
1864 } | |
1865 } | |
1866 | |
14019
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1867 #if defined(FEAT_JOB_CHANNEL) || defined(PROTO) |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1868 /* |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1869 * Return the effective prompt for the current buffer. |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1870 */ |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1871 char_u * |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1872 prompt_text(void) |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1873 { |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1874 if (curbuf->b_prompt_text == NULL) |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1875 return (char_u *)"% "; |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1876 return curbuf->b_prompt_text; |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1877 } |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1878 |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1879 /* |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1880 * Prepare for prompt mode: Make sure the last line has the prompt text. |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1881 * Move the cursor to this line. |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1882 */ |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1883 static void |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1884 init_prompt(int cmdchar_todo) |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1885 { |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1886 char_u *prompt = prompt_text(); |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1887 char_u *text; |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1888 |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1889 curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count; |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1890 text = ml_get_curline(); |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1891 if (STRNCMP(text, prompt, STRLEN(prompt)) != 0) |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1892 { |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1893 // prompt is missing, insert it or append a line with it |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1894 if (*text == NUL) |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1895 ml_replace(curbuf->b_ml.ml_line_count, prompt, TRUE); |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1896 else |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1897 ml_append(curbuf->b_ml.ml_line_count, prompt, 0, FALSE); |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1898 curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count; |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1899 coladvance((colnr_T)MAXCOL); |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1900 changed_bytes(curbuf->b_ml.ml_line_count, 0); |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1901 } |
14035
bccd66fa00c1
patch 8.1.0035: not easy to switch between prompt buffer and other windows
Christian Brabandt <cb@256bit.org>
parents:
14019
diff
changeset
|
1902 |
bccd66fa00c1
patch 8.1.0035: not easy to switch between prompt buffer and other windows
Christian Brabandt <cb@256bit.org>
parents:
14019
diff
changeset
|
1903 // Insert always starts after the prompt, allow editing text after it. |
bccd66fa00c1
patch 8.1.0035: not easy to switch between prompt buffer and other windows
Christian Brabandt <cb@256bit.org>
parents:
14019
diff
changeset
|
1904 if (Insstart_orig.lnum != curwin->w_cursor.lnum |
bccd66fa00c1
patch 8.1.0035: not easy to switch between prompt buffer and other windows
Christian Brabandt <cb@256bit.org>
parents:
14019
diff
changeset
|
1905 || Insstart_orig.col != (int)STRLEN(prompt)) |
bccd66fa00c1
patch 8.1.0035: not easy to switch between prompt buffer and other windows
Christian Brabandt <cb@256bit.org>
parents:
14019
diff
changeset
|
1906 { |
bccd66fa00c1
patch 8.1.0035: not easy to switch between prompt buffer and other windows
Christian Brabandt <cb@256bit.org>
parents:
14019
diff
changeset
|
1907 Insstart.lnum = curwin->w_cursor.lnum; |
14045
e182079c3374
patch 8.1.0040: warnings from 64-bit compiler
Christian Brabandt <cb@256bit.org>
parents:
14037
diff
changeset
|
1908 Insstart.col = (int)STRLEN(prompt); |
14035
bccd66fa00c1
patch 8.1.0035: not easy to switch between prompt buffer and other windows
Christian Brabandt <cb@256bit.org>
parents:
14019
diff
changeset
|
1909 Insstart_orig = Insstart; |
bccd66fa00c1
patch 8.1.0035: not easy to switch between prompt buffer and other windows
Christian Brabandt <cb@256bit.org>
parents:
14019
diff
changeset
|
1910 Insstart_textlen = Insstart.col; |
bccd66fa00c1
patch 8.1.0035: not easy to switch between prompt buffer and other windows
Christian Brabandt <cb@256bit.org>
parents:
14019
diff
changeset
|
1911 Insstart_blank_vcol = MAXCOL; |
bccd66fa00c1
patch 8.1.0035: not easy to switch between prompt buffer and other windows
Christian Brabandt <cb@256bit.org>
parents:
14019
diff
changeset
|
1912 arrow_used = FALSE; |
bccd66fa00c1
patch 8.1.0035: not easy to switch between prompt buffer and other windows
Christian Brabandt <cb@256bit.org>
parents:
14019
diff
changeset
|
1913 } |
bccd66fa00c1
patch 8.1.0035: not easy to switch between prompt buffer and other windows
Christian Brabandt <cb@256bit.org>
parents:
14019
diff
changeset
|
1914 |
14019
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1915 if (cmdchar_todo == 'A') |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1916 coladvance((colnr_T)MAXCOL); |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1917 if (cmdchar_todo == 'I' || curwin->w_cursor.col <= (int)STRLEN(prompt)) |
14045
e182079c3374
patch 8.1.0040: warnings from 64-bit compiler
Christian Brabandt <cb@256bit.org>
parents:
14037
diff
changeset
|
1918 curwin->w_cursor.col = (int)STRLEN(prompt); |
14037
afce2005fdc8
patch 8.1.0036: not restoring Insert mode if leaving prompt buffer with mouse
Christian Brabandt <cb@256bit.org>
parents:
14035
diff
changeset
|
1919 /* Make sure the cursor is in a valid position. */ |
afce2005fdc8
patch 8.1.0036: not restoring Insert mode if leaving prompt buffer with mouse
Christian Brabandt <cb@256bit.org>
parents:
14035
diff
changeset
|
1920 check_cursor(); |
14019
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1921 } |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1922 |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1923 /* |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1924 * Return TRUE if the cursor is in the editable position of the prompt line. |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1925 */ |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1926 int |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1927 prompt_curpos_editable() |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1928 { |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1929 return curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1930 && curwin->w_cursor.col >= (int)STRLEN(prompt_text()); |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1931 } |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1932 #endif |
dc67449d648c
patch 8.1.0027: difficult to make a plugin that feeds a line to a job
Christian Brabandt <cb@256bit.org>
parents:
14004
diff
changeset
|
1933 |
7 | 1934 /* |
1935 * Undo the previous edit_putchar(). | |
1936 */ | |
1937 void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
1938 edit_unputchar(void) |
7 | 1939 { |
1940 if (pc_status != PC_STATUS_UNSET && pc_row >= msg_scrolled) | |
1941 { | |
1942 if (pc_status == PC_STATUS_RIGHT) | |
1943 ++curwin->w_wcol; | |
1944 if (pc_status == PC_STATUS_RIGHT || pc_status == PC_STATUS_LEFT) | |
15400
ac5542aadd9c
patch 8.1.0708: third argument for redrawWinline() is always FALSE
Bram Moolenaar <Bram@vim.org>
parents:
15382
diff
changeset
|
1945 redrawWinline(curwin, curwin->w_cursor.lnum); |
7 | 1946 else |
1947 screen_puts(pc_bytes, pc_row - msg_scrolled, pc_col, pc_attr); | |
1948 } | |
1949 } | |
1950 | |
1951 /* | |
1952 * Called when p_dollar is set: display a '$' at the end of the changed text | |
1953 * Only works when cursor is in the line that changes. | |
1954 */ | |
1955 void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
1956 display_dollar(colnr_T col) |
7 | 1957 { |
1958 colnr_T save_col; | |
1959 | |
1960 if (!redrawing()) | |
1961 return; | |
1962 | |
1963 cursor_off(); | |
1964 save_col = curwin->w_cursor.col; | |
1965 curwin->w_cursor.col = col; | |
1966 if (has_mbyte) | |
1967 { | |
1968 char_u *p; | |
1969 | |
1970 /* If on the last byte of a multi-byte move to the first byte. */ | |
1971 p = ml_get_curline(); | |
1972 curwin->w_cursor.col -= (*mb_head_off)(p, p + col); | |
1973 } | |
1974 curs_columns(FALSE); /* recompute w_wrow and w_wcol */ | |
12515
972ea22c946f
patch 8.0.1136: W_WIDTH() is always the same
Christian Brabandt <cb@256bit.org>
parents:
12513
diff
changeset
|
1975 if (curwin->w_wcol < curwin->w_width) |
7 | 1976 { |
1977 edit_putchar('$', FALSE); | |
1978 dollar_vcol = curwin->w_virtcol; | |
1979 } | |
1980 curwin->w_cursor.col = save_col; | |
1981 } | |
1982 | |
1983 /* | |
1984 * Call this function before moving the cursor from the normal insert position | |
1985 * in insert mode. | |
1986 */ | |
1987 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
1988 undisplay_dollar(void) |
7 | 1989 { |
3318 | 1990 if (dollar_vcol >= 0) |
1991 { | |
1992 dollar_vcol = -1; | |
15400
ac5542aadd9c
patch 8.1.0708: third argument for redrawWinline() is always FALSE
Bram Moolenaar <Bram@vim.org>
parents:
15382
diff
changeset
|
1993 redrawWinline(curwin, curwin->w_cursor.lnum); |
7 | 1994 } |
1995 } | |
1996 | |
1997 /* | |
1998 * Insert an indent (for <Tab> or CTRL-T) or delete an indent (for CTRL-D). | |
1999 * Keep the cursor on the same character. | |
2000 * type == INDENT_INC increase indent (for CTRL-T or <Tab>) | |
2001 * type == INDENT_DEC decrease indent (for CTRL-D) | |
2002 * type == INDENT_SET set indent to "amount" | |
2003 * if round is TRUE, round the indent to 'shiftwidth' (only with _INC and _Dec). | |
2004 */ | |
2005 void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
2006 change_indent( |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
2007 int type, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
2008 int amount, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
2009 int round, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
2010 int replaced, /* replaced character, put on replace stack */ |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
2011 int call_changed_bytes) /* call changed_bytes() */ |
7 | 2012 { |
2013 int vcol; | |
2014 int last_vcol; | |
2015 int insstart_less; /* reduction for Insstart.col */ | |
2016 int new_cursor_col; | |
2017 int i; | |
2018 char_u *ptr; | |
2019 int save_p_list; | |
2020 int start_col; | |
2021 colnr_T vc; | |
2022 colnr_T orig_col = 0; /* init for GCC */ | |
2023 char_u *new_line, *orig_line = NULL; /* init for GCC */ | |
2024 | |
2025 /* VREPLACE mode needs to know what the line was like before changing */ | |
2026 if (State & VREPLACE_FLAG) | |
2027 { | |
2028 orig_line = vim_strsave(ml_get_curline()); /* Deal with NULL below */ | |
2029 orig_col = curwin->w_cursor.col; | |
2030 } | |
2031 | |
2032 /* for the following tricks we don't want list mode */ | |
2033 save_p_list = curwin->w_p_list; | |
2034 curwin->w_p_list = FALSE; | |
2035 vc = getvcol_nolist(&curwin->w_cursor); | |
2036 vcol = vc; | |
2037 | |
2038 /* | |
2039 * For Replace mode we need to fix the replace stack later, which is only | |
2040 * possible when the cursor is in the indent. Remember the number of | |
2041 * characters before the cursor if it's possible. | |
2042 */ | |
2043 start_col = curwin->w_cursor.col; | |
2044 | |
2045 /* determine offset from first non-blank */ | |
2046 new_cursor_col = curwin->w_cursor.col; | |
2047 beginline(BL_WHITE); | |
2048 new_cursor_col -= curwin->w_cursor.col; | |
2049 | |
2050 insstart_less = curwin->w_cursor.col; | |
2051 | |
2052 /* | |
2053 * If the cursor is in the indent, compute how many screen columns the | |
2054 * cursor is to the left of the first non-blank. | |
2055 */ | |
2056 if (new_cursor_col < 0) | |
2057 vcol = get_indent() - vcol; | |
2058 | |
2059 if (new_cursor_col > 0) /* can't fix replace stack */ | |
2060 start_col = -1; | |
2061 | |
2062 /* | |
2063 * Set the new indent. The cursor will be put on the first non-blank. | |
2064 */ | |
2065 if (type == INDENT_SET) | |
1516 | 2066 (void)set_indent(amount, call_changed_bytes ? SIN_CHANGED : 0); |
7 | 2067 else |
2068 { | |
2069 int save_State = State; | |
2070 | |
2071 /* Avoid being called recursively. */ | |
2072 if (State & VREPLACE_FLAG) | |
2073 State = INSERT; | |
1516 | 2074 shift_line(type == INDENT_DEC, round, 1, call_changed_bytes); |
7 | 2075 State = save_State; |
2076 } | |
2077 insstart_less -= curwin->w_cursor.col; | |
2078 | |
2079 /* | |
2080 * Try to put cursor on same character. | |
2081 * If the cursor is at or after the first non-blank in the line, | |
2082 * compute the cursor column relative to the column of the first | |
2083 * non-blank character. | |
2084 * If we are not in insert mode, leave the cursor on the first non-blank. | |
2085 * If the cursor is before the first non-blank, position it relative | |
2086 * to the first non-blank, counted in screen columns. | |
2087 */ | |
2088 if (new_cursor_col >= 0) | |
2089 { | |
2090 /* | |
2091 * When changing the indent while the cursor is touching it, reset | |
2092 * Insstart_col to 0. | |
2093 */ | |
2094 if (new_cursor_col == 0) | |
2095 insstart_less = MAXCOL; | |
2096 new_cursor_col += curwin->w_cursor.col; | |
2097 } | |
2098 else if (!(State & INSERT)) | |
2099 new_cursor_col = curwin->w_cursor.col; | |
2100 else | |
2101 { | |
2102 /* | |
2103 * Compute the screen column where the cursor should be. | |
2104 */ | |
2105 vcol = get_indent() - vcol; | |
1869 | 2106 curwin->w_virtcol = (colnr_T)((vcol < 0) ? 0 : vcol); |
7 | 2107 |
2108 /* | |
2109 * Advance the cursor until we reach the right screen column. | |
2110 */ | |
2111 vcol = last_vcol = 0; | |
2112 new_cursor_col = -1; | |
2113 ptr = ml_get_curline(); | |
2114 while (vcol <= (int)curwin->w_virtcol) | |
2115 { | |
2116 last_vcol = vcol; | |
2117 if (has_mbyte && new_cursor_col >= 0) | |
474 | 2118 new_cursor_col += (*mb_ptr2len)(ptr + new_cursor_col); |
7 | 2119 else |
2120 ++new_cursor_col; | |
5995 | 2121 vcol += lbr_chartabsize(ptr, ptr + new_cursor_col, (colnr_T)vcol); |
7 | 2122 } |
2123 vcol = last_vcol; | |
2124 | |
2125 /* | |
2126 * May need to insert spaces to be able to position the cursor on | |
2127 * the right screen column. | |
2128 */ | |
2129 if (vcol != (int)curwin->w_virtcol) | |
2130 { | |
1869 | 2131 curwin->w_cursor.col = (colnr_T)new_cursor_col; |
7 | 2132 i = (int)curwin->w_virtcol - vcol; |
1869 | 2133 ptr = alloc((unsigned)(i + 1)); |
7 | 2134 if (ptr != NULL) |
2135 { | |
2136 new_cursor_col += i; | |
2137 ptr[i] = NUL; | |
2138 while (--i >= 0) | |
2139 ptr[i] = ' '; | |
2140 ins_str(ptr); | |
2141 vim_free(ptr); | |
2142 } | |
2143 } | |
2144 | |
2145 /* | |
2146 * When changing the indent while the cursor is in it, reset | |
2147 * Insstart_col to 0. | |
2148 */ | |
2149 insstart_less = MAXCOL; | |
2150 } | |
2151 | |
2152 curwin->w_p_list = save_p_list; | |
2153 | |
2154 if (new_cursor_col <= 0) | |
2155 curwin->w_cursor.col = 0; | |
2156 else | |
1869 | 2157 curwin->w_cursor.col = (colnr_T)new_cursor_col; |
7 | 2158 curwin->w_set_curswant = TRUE; |
2159 changed_cline_bef_curs(); | |
2160 | |
2161 /* | |
2162 * May have to adjust the start of the insert. | |
2163 */ | |
2164 if (State & INSERT) | |
2165 { | |
2166 if (curwin->w_cursor.lnum == Insstart.lnum && Insstart.col != 0) | |
2167 { | |
2168 if ((int)Insstart.col <= insstart_less) | |
2169 Insstart.col = 0; | |
2170 else | |
2171 Insstart.col -= insstart_less; | |
2172 } | |
2173 if ((int)ai_col <= insstart_less) | |
2174 ai_col = 0; | |
2175 else | |
2176 ai_col -= insstart_less; | |
2177 } | |
2178 | |
2179 /* | |
2180 * For REPLACE mode, may have to fix the replace stack, if it's possible. | |
2181 * If the number of characters before the cursor decreased, need to pop a | |
2182 * few characters from the replace stack. | |
2183 * If the number of characters before the cursor increased, need to push a | |
2184 * few NULs onto the replace stack. | |
2185 */ | |
2186 if (REPLACE_NORMAL(State) && start_col >= 0) | |
2187 { | |
2188 while (start_col > (int)curwin->w_cursor.col) | |
2189 { | |
2190 replace_join(0); /* remove a NUL from the replace stack */ | |
2191 --start_col; | |
2192 } | |
2193 while (start_col < (int)curwin->w_cursor.col || replaced) | |
2194 { | |
2195 replace_push(NUL); | |
2196 if (replaced) | |
2197 { | |
2198 replace_push(replaced); | |
2199 replaced = NUL; | |
2200 } | |
2201 ++start_col; | |
2202 } | |
2203 } | |
2204 | |
2205 /* | |
2206 * For VREPLACE mode, we also have to fix the replace stack. In this case | |
2207 * it is always possible because we backspace over the whole line and then | |
2208 * put it back again the way we wanted it. | |
2209 */ | |
2210 if (State & VREPLACE_FLAG) | |
2211 { | |
2212 /* If orig_line didn't allocate, just return. At least we did the job, | |
2213 * even if you can't backspace. */ | |
2214 if (orig_line == NULL) | |
2215 return; | |
2216 | |
2217 /* Save new line */ | |
2218 new_line = vim_strsave(ml_get_curline()); | |
2219 if (new_line == NULL) | |
2220 return; | |
2221 | |
2222 /* We only put back the new line up to the cursor */ | |
2223 new_line[curwin->w_cursor.col] = NUL; | |
2224 | |
2225 /* Put back original line */ | |
2226 ml_replace(curwin->w_cursor.lnum, orig_line, FALSE); | |
2227 curwin->w_cursor.col = orig_col; | |
2228 | |
2229 /* Backspace from cursor to start of line */ | |
2230 backspace_until_column(0); | |
2231 | |
2232 /* Insert new stuff into line again */ | |
2233 ins_bytes(new_line); | |
2234 | |
2235 vim_free(new_line); | |
2236 } | |
2237 } | |
2238 | |
2239 /* | |
2240 * Truncate the space at the end of a line. This is to be used only in an | |
2241 * insert mode. It handles fixing the replace stack for REPLACE and VREPLACE | |
2242 * modes. | |
2243 */ | |
2244 void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
2245 truncate_spaces(char_u *line) |
7 | 2246 { |
2247 int i; | |
2248 | |
2249 /* find start of trailing white space */ | |
11129
f4ea50924c6d
patch 8.0.0452: some macros are in lower case
Christian Brabandt <cb@256bit.org>
parents:
11127
diff
changeset
|
2250 for (i = (int)STRLEN(line) - 1; i >= 0 && VIM_ISWHITE(line[i]); i--) |
7 | 2251 { |
2252 if (State & REPLACE_FLAG) | |
2253 replace_join(0); /* remove a NUL from the replace stack */ | |
2254 } | |
2255 line[i + 1] = NUL; | |
2256 } | |
2257 | |
2258 /* | |
2259 * Backspace the cursor until the given column. Handles REPLACE and VREPLACE | |
2260 * modes correctly. May also be used when not in insert mode at all. | |
1782 | 2261 * Will attempt not to go before "col" even when there is a composing |
2262 * character. | |
7 | 2263 */ |
2264 void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
2265 backspace_until_column(int col) |
7 | 2266 { |
2267 while ((int)curwin->w_cursor.col > col) | |
2268 { | |
2269 curwin->w_cursor.col--; | |
2270 if (State & REPLACE_FLAG) | |
1782 | 2271 replace_do_bs(col); |
2272 else if (!del_char_after_col(col)) | |
2273 break; | |
2274 } | |
2275 } | |
2276 | |
2277 /* | |
2278 * Like del_char(), but make sure not to go before column "limit_col". | |
2279 * Only matters when there are composing characters. | |
2280 * Return TRUE when something was deleted. | |
2281 */ | |
2282 static int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
2283 del_char_after_col(int limit_col UNUSED) |
1782 | 2284 { |
2285 if (enc_utf8 && limit_col >= 0) | |
2286 { | |
1869 | 2287 colnr_T ecol = curwin->w_cursor.col + 1; |
1782 | 2288 |
2289 /* Make sure the cursor is at the start of a character, but | |
2290 * skip forward again when going too far back because of a | |
2291 * composing character. */ | |
2292 mb_adjust_cursor(); | |
1796 | 2293 while (curwin->w_cursor.col < (colnr_T)limit_col) |
1782 | 2294 { |
2295 int l = utf_ptr2len(ml_get_cursor()); | |
2296 | |
2297 if (l == 0) /* end of line */ | |
2298 break; | |
2299 curwin->w_cursor.col += l; | |
2300 } | |
2301 if (*ml_get_cursor() == NUL || curwin->w_cursor.col == ecol) | |
2302 return FALSE; | |
1869 | 2303 del_bytes((long)((int)ecol - curwin->w_cursor.col), FALSE, TRUE); |
1782 | 2304 } |
2305 else | |
2306 (void)del_char(FALSE); | |
2307 return TRUE; | |
2308 } | |
7 | 2309 |
2310 #if defined(FEAT_INS_EXPAND) || defined(PROTO) | |
2311 /* | |
449 | 2312 * CTRL-X pressed in Insert mode. |
2313 */ | |
2314 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
2315 ins_ctrl_x(void) |
449 | 2316 { |
2317 /* CTRL-X after CTRL-X CTRL-V doesn't do anything, so that CTRL-X | |
2318 * CTRL-V works like CTRL-N */ | |
2319 if (ctrl_x_mode != CTRL_X_CMDLINE) | |
2320 { | |
2321 /* if the next ^X<> won't ADD nothing, then reset | |
2322 * compl_cont_status */ | |
2323 if (compl_cont_status & CONT_N_ADDS) | |
665 | 2324 compl_cont_status |= CONT_INTRPT; |
449 | 2325 else |
2326 compl_cont_status = 0; | |
2327 /* We're not sure which CTRL-X mode it will be yet */ | |
2328 ctrl_x_mode = CTRL_X_NOT_DEFINED_YET; | |
2329 edit_submode = (char_u *)_(CTRL_X_MSG(ctrl_x_mode)); | |
2330 edit_submode_pre = NULL; | |
2331 showmode(); | |
2332 } | |
2333 } | |
2334 | |
2335 /* | |
13210
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
2336 * Whether other than default completion has been selected. |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
2337 */ |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
2338 int |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
2339 ctrl_x_mode_not_default(void) |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
2340 { |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
2341 return ctrl_x_mode != CTRL_X_NORMAL; |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
2342 } |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
2343 |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
2344 /* |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
2345 * Whether CTRL-X was typed without a following character. |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
2346 */ |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
2347 int |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
2348 ctrl_x_mode_not_defined_yet(void) |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
2349 { |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
2350 return ctrl_x_mode == CTRL_X_NOT_DEFINED_YET; |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
2351 } |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
2352 |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
2353 /* |
449 | 2354 * Return TRUE if the 'dict' or 'tsr' option can be used. |
2355 */ | |
2356 static int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
2357 has_compl_option(int dict_opt) |
449 | 2358 { |
703 | 2359 if (dict_opt ? (*curbuf->b_p_dict == NUL && *p_dict == NUL |
744 | 2360 # ifdef FEAT_SPELL |
2361 && !curwin->w_p_spell | |
2362 # endif | |
2363 ) | |
449 | 2364 : (*curbuf->b_p_tsr == NUL && *p_tsr == NUL)) |
2365 { | |
13210
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
2366 ctrl_x_mode = CTRL_X_NORMAL; |
449 | 2367 edit_submode = NULL; |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15521
diff
changeset
|
2368 msg_attr(dict_opt ? _("'dictionary' option is empty") |
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15521
diff
changeset
|
2369 : _("'thesaurus' option is empty"), |
11158
501f46f7644c
patch 8.0.0466: still macros that should be all-caps
Christian Brabandt <cb@256bit.org>
parents:
11129
diff
changeset
|
2370 HL_ATTR(HLF_E)); |
449 | 2371 if (emsg_silent == 0) |
2372 { | |
6949 | 2373 vim_beep(BO_COMPL); |
449 | 2374 setcursor(); |
2375 out_flush(); | |
11105
7c7e496e625d
patch 8.0.0440: not enough test coverage in Insert mode
Christian Brabandt <cb@256bit.org>
parents:
11073
diff
changeset
|
2376 #ifdef FEAT_EVAL |
7c7e496e625d
patch 8.0.0440: not enough test coverage in Insert mode
Christian Brabandt <cb@256bit.org>
parents:
11073
diff
changeset
|
2377 if (!get_vim_var_nr(VV_TESTING)) |
7c7e496e625d
patch 8.0.0440: not enough test coverage in Insert mode
Christian Brabandt <cb@256bit.org>
parents:
11073
diff
changeset
|
2378 #endif |
7c7e496e625d
patch 8.0.0440: not enough test coverage in Insert mode
Christian Brabandt <cb@256bit.org>
parents:
11073
diff
changeset
|
2379 ui_delay(2000L, FALSE); |
449 | 2380 } |
2381 return FALSE; | |
2382 } | |
2383 return TRUE; | |
2384 } | |
2385 | |
2386 /* | |
7 | 2387 * Is the character 'c' a valid key to go to or keep us in CTRL-X mode? |
2388 * This depends on the current mode. | |
2389 */ | |
2390 int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
2391 vim_is_ctrl_x_key(int c) |
7 | 2392 { |
14985
4ebda55537a5
patch 8.1.0504: when CTRL-C is mapped it triggers InsertLeave
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
2393 // Always allow ^R - let its results then be checked |
7 | 2394 if (c == Ctrl_R) |
2395 return TRUE; | |
2396 | |
610 | 2397 /* Accept <PageUp> and <PageDown> if the popup menu is visible. */ |
644 | 2398 if (ins_compl_pum_key(c)) |
610 | 2399 return TRUE; |
2400 | |
7 | 2401 switch (ctrl_x_mode) |
2402 { | |
2403 case 0: /* Not in any CTRL-X mode */ | |
2404 return (c == Ctrl_N || c == Ctrl_P || c == Ctrl_X); | |
2405 case CTRL_X_NOT_DEFINED_YET: | |
449 | 2406 return ( c == Ctrl_X || c == Ctrl_Y || c == Ctrl_E |
7 | 2407 || c == Ctrl_L || c == Ctrl_F || c == Ctrl_RSB |
2408 || c == Ctrl_I || c == Ctrl_D || c == Ctrl_P | |
2409 || c == Ctrl_N || c == Ctrl_T || c == Ctrl_V | |
477 | 2410 || c == Ctrl_Q || c == Ctrl_U || c == Ctrl_O |
3229 | 2411 || c == Ctrl_S || c == Ctrl_K || c == 's'); |
7 | 2412 case CTRL_X_SCROLL: |
2413 return (c == Ctrl_Y || c == Ctrl_E); | |
2414 case CTRL_X_WHOLE_LINE: | |
2415 return (c == Ctrl_L || c == Ctrl_P || c == Ctrl_N); | |
2416 case CTRL_X_FILES: | |
2417 return (c == Ctrl_F || c == Ctrl_P || c == Ctrl_N); | |
2418 case CTRL_X_DICTIONARY: | |
2419 return (c == Ctrl_K || c == Ctrl_P || c == Ctrl_N); | |
2420 case CTRL_X_THESAURUS: | |
2421 return (c == Ctrl_T || c == Ctrl_P || c == Ctrl_N); | |
2422 case CTRL_X_TAGS: | |
2423 return (c == Ctrl_RSB || c == Ctrl_P || c == Ctrl_N); | |
2424 #ifdef FEAT_FIND_ID | |
2425 case CTRL_X_PATH_PATTERNS: | |
2426 return (c == Ctrl_P || c == Ctrl_N); | |
2427 case CTRL_X_PATH_DEFINES: | |
2428 return (c == Ctrl_D || c == Ctrl_P || c == Ctrl_N); | |
2429 #endif | |
2430 case CTRL_X_CMDLINE: | |
2431 return (c == Ctrl_V || c == Ctrl_Q || c == Ctrl_P || c == Ctrl_N | |
2432 || c == Ctrl_X); | |
12 | 2433 #ifdef FEAT_COMPL_FUNC |
2434 case CTRL_X_FUNCTION: | |
449 | 2435 return (c == Ctrl_U || c == Ctrl_P || c == Ctrl_N); |
523 | 2436 case CTRL_X_OMNI: |
449 | 2437 return (c == Ctrl_O || c == Ctrl_P || c == Ctrl_N); |
502 | 2438 #endif |
477 | 2439 case CTRL_X_SPELL: |
2440 return (c == Ctrl_S || c == Ctrl_P || c == Ctrl_N); | |
6657 | 2441 case CTRL_X_EVAL: |
2442 return (c == Ctrl_P || c == Ctrl_N); | |
7 | 2443 } |
10359
66f1b5bf3fa6
commit https://github.com/vim/vim/commit/95f096030ed1a8afea028f2ea295d6f6a70f466f
Christian Brabandt <cb@256bit.org>
parents:
10293
diff
changeset
|
2444 internal_error("vim_is_ctrl_x_key()"); |
7 | 2445 return FALSE; |
2446 } | |
2447 | |
2448 /* | |
1430 | 2449 * Return TRUE when character "c" is part of the item currently being |
2450 * completed. Used to decide whether to abandon complete mode when the menu | |
2451 * is visible. | |
2452 */ | |
2453 static int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
2454 ins_compl_accept_char(int c) |
1430 | 2455 { |
2456 if (ctrl_x_mode & CTRL_X_WANT_IDENT) | |
2457 /* When expanding an identifier only accept identifier chars. */ | |
2458 return vim_isIDc(c); | |
2459 | |
2460 switch (ctrl_x_mode) | |
2461 { | |
2462 case CTRL_X_FILES: | |
2463 /* When expanding file name only accept file name chars. But not | |
2464 * path separators, so that "proto/<Tab>" expands files in | |
2465 * "proto", not "proto/" as a whole */ | |
2466 return vim_isfilec(c) && !vim_ispathsep(c); | |
2467 | |
2468 case CTRL_X_CMDLINE: | |
2469 case CTRL_X_OMNI: | |
2470 /* Command line and Omni completion can work with just about any | |
2471 * printable character, but do stop at white space. */ | |
11129
f4ea50924c6d
patch 8.0.0452: some macros are in lower case
Christian Brabandt <cb@256bit.org>
parents:
11127
diff
changeset
|
2472 return vim_isprintc(c) && !VIM_ISWHITE(c); |
1430 | 2473 |
2474 case CTRL_X_WHOLE_LINE: | |
2475 /* For while line completion a space can be part of the line. */ | |
2476 return vim_isprintc(c); | |
2477 } | |
2478 return vim_iswordc(c); | |
2479 } | |
2480 | |
2481 /* | |
659 | 2482 * This is like ins_compl_add(), but if 'ic' and 'inf' are set, then the |
7 | 2483 * case of the originally typed text is used, and the case of the completed |
1219 | 2484 * text is inferred, ie this tries to work out what case you probably wanted |
7 | 2485 * the rest of the word to be in -- webb |
2486 */ | |
2487 int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
2488 ins_compl_add_infercase( |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
2489 char_u *str, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
2490 int len, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
2491 int icase, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
2492 char_u *fname, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
2493 int dir, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
2494 int flags) |
7 | 2495 { |
1353 | 2496 char_u *p; |
2497 int i, c; | |
2498 int actual_len; /* Take multi-byte characters */ | |
2499 int actual_compl_length; /* into account. */ | |
2177 | 2500 int min_len; |
2004 | 2501 int *wca; /* Wide character array. */ |
7 | 2502 int has_lower = FALSE; |
2503 int was_letter = FALSE; | |
1353 | 2504 |
1436 | 2505 if (p_ic && curbuf->b_p_inf && len > 0) |
1353 | 2506 { |
2507 /* Infer case of completed part. */ | |
2508 | |
2509 /* Find actual length of completion. */ | |
2510 if (has_mbyte) | |
2511 { | |
2512 p = str; | |
2513 actual_len = 0; | |
2514 while (*p != NUL) | |
2515 { | |
11127
506f5d8b7d8b
patch 8.0.0451: some macros are in lower case
Christian Brabandt <cb@256bit.org>
parents:
11121
diff
changeset
|
2516 MB_PTR_ADV(p); |
1353 | 2517 ++actual_len; |
2518 } | |
2519 } | |
2520 else | |
2521 actual_len = len; | |
2522 | |
2523 /* Find actual length of original text. */ | |
2524 if (has_mbyte) | |
2525 { | |
2526 p = compl_orig_text; | |
2527 actual_compl_length = 0; | |
2528 while (*p != NUL) | |
7 | 2529 { |
11127
506f5d8b7d8b
patch 8.0.0451: some macros are in lower case
Christian Brabandt <cb@256bit.org>
parents:
11121
diff
changeset
|
2530 MB_PTR_ADV(p); |
1353 | 2531 ++actual_compl_length; |
2532 } | |
2533 } | |
2534 else | |
2535 actual_compl_length = compl_length; | |
2536 | |
2177 | 2537 /* "actual_len" may be smaller than "actual_compl_length" when using |
2538 * thesaurus, only use the minimum when comparing. */ | |
2539 min_len = actual_len < actual_compl_length | |
2540 ? actual_len : actual_compl_length; | |
2541 | |
1353 | 2542 /* Allocate wide character array for the completion and fill it. */ |
1869 | 2543 wca = (int *)alloc((unsigned)(actual_len * sizeof(int))); |
1353 | 2544 if (wca != NULL) |
2545 { | |
2546 p = str; | |
2547 for (i = 0; i < actual_len; ++i) | |
2548 if (has_mbyte) | |
2549 wca[i] = mb_ptr2char_adv(&p); | |
2550 else | |
2551 wca[i] = *(p++); | |
2552 | |
2553 /* Rule 1: Were any chars converted to lower? */ | |
2554 p = compl_orig_text; | |
2177 | 2555 for (i = 0; i < min_len; ++i) |
1353 | 2556 { |
2557 if (has_mbyte) | |
2558 c = mb_ptr2char_adv(&p); | |
2559 else | |
2560 c = *(p++); | |
2561 if (MB_ISLOWER(c)) | |
7 | 2562 { |
1353 | 2563 has_lower = TRUE; |
2564 if (MB_ISUPPER(wca[i])) | |
2565 { | |
2566 /* Rule 1 is satisfied. */ | |
2567 for (i = actual_compl_length; i < actual_len; ++i) | |
2568 wca[i] = MB_TOLOWER(wca[i]); | |
2569 break; | |
2570 } | |
7 | 2571 } |
2572 } | |
1353 | 2573 |
2574 /* | |
2575 * Rule 2: No lower case, 2nd consecutive letter converted to | |
2576 * upper case. | |
2577 */ | |
2578 if (!has_lower) | |
2579 { | |
2580 p = compl_orig_text; | |
2177 | 2581 for (i = 0; i < min_len; ++i) |
1353 | 2582 { |
2583 if (has_mbyte) | |
2584 c = mb_ptr2char_adv(&p); | |
2585 else | |
2586 c = *(p++); | |
2587 if (was_letter && MB_ISUPPER(c) && MB_ISLOWER(wca[i])) | |
2588 { | |
2589 /* Rule 2 is satisfied. */ | |
2590 for (i = actual_compl_length; i < actual_len; ++i) | |
2591 wca[i] = MB_TOUPPER(wca[i]); | |
2592 break; | |
2593 } | |
2594 was_letter = MB_ISLOWER(c) || MB_ISUPPER(c); | |
2595 } | |
2596 } | |
2597 | |
2598 /* Copy the original case of the part we typed. */ | |
2599 p = compl_orig_text; | |
2177 | 2600 for (i = 0; i < min_len; ++i) |
7 | 2601 { |
1353 | 2602 if (has_mbyte) |
2603 c = mb_ptr2char_adv(&p); | |
2604 else | |
2605 c = *(p++); | |
2606 if (MB_ISLOWER(c)) | |
2607 wca[i] = MB_TOLOWER(wca[i]); | |
2608 else if (MB_ISUPPER(c)) | |
2609 wca[i] = MB_TOUPPER(wca[i]); | |
7 | 2610 } |
1353 | 2611 |
1436 | 2612 /* |
1353 | 2613 * Generate encoding specific output from wide character array. |
2614 * Multi-byte characters can occupy up to five bytes more than | |
2615 * ASCII characters, and we also need one byte for NUL, so stay | |
2616 * six bytes away from the edge of IObuff. | |
2617 */ | |
2618 p = IObuff; | |
2619 i = 0; | |
2620 while (i < actual_len && (p - IObuff + 6) < IOSIZE) | |
2621 if (has_mbyte) | |
1446 | 2622 p += (*mb_char2bytes)(wca[i++], p); |
1353 | 2623 else |
2624 *(p++) = wca[i++]; | |
2625 *p = NUL; | |
2626 | |
2627 vim_free(wca); | |
2628 } | |
7 | 2629 |
841 | 2630 return ins_compl_add(IObuff, len, icase, fname, NULL, dir, |
2631 flags, FALSE); | |
2632 } | |
2633 return ins_compl_add(str, len, icase, fname, NULL, dir, flags, FALSE); | |
7 | 2634 } |
2635 | |
2636 /* | |
2637 * Add a match to the list of matches. | |
2638 * If the given string is already in the list of completions, then return | |
464 | 2639 * NOTDONE, otherwise add it to the list and return OK. If there is an error, |
681 | 2640 * maybe because alloc() returns NULL, then FAIL is returned. |
7 | 2641 */ |
841 | 2642 static int |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
2643 ins_compl_add( |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
2644 char_u *str, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
2645 int len, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
2646 int icase, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
2647 char_u *fname, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
2648 char_u **cptext, /* extra text for popup menu or NULL */ |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
2649 int cdir, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
2650 int flags, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
2651 int adup) /* accept duplicate match */ |
7 | 2652 { |
464 | 2653 compl_T *match; |
659 | 2654 int dir = (cdir == 0 ? compl_direction : cdir); |
7 | 2655 |
2656 ui_breakcheck(); | |
2657 if (got_int) | |
464 | 2658 return FAIL; |
7 | 2659 if (len < 0) |
2660 len = (int)STRLEN(str); | |
2661 | |
2662 /* | |
2663 * If the same match is already present, don't add it. | |
2664 */ | |
944 | 2665 if (compl_first_match != NULL && !adup) |
449 | 2666 { |
2667 match = compl_first_match; | |
7 | 2668 do |
2669 { | |
464 | 2670 if ( !(match->cp_flags & ORIGINAL_TEXT) |
989 | 2671 && STRNCMP(match->cp_str, str, len) == 0 |
464 | 2672 && match->cp_str[len] == NUL) |
2673 return NOTDONE; | |
2674 match = match->cp_next; | |
449 | 2675 } while (match != NULL && match != compl_first_match); |
7 | 2676 } |
2677 | |
540 | 2678 /* Remove any popup menu before changing the list of matches. */ |
2679 ins_compl_del_pum(); | |
2680 | |
7 | 2681 /* |
2682 * Allocate a new match structure. | |
2683 * Copy the values to the new match structure. | |
2684 */ | |
659 | 2685 match = (compl_T *)alloc_clear((unsigned)sizeof(compl_T)); |
7 | 2686 if (match == NULL) |
464 | 2687 return FAIL; |
2688 match->cp_number = -1; | |
2689 if (flags & ORIGINAL_TEXT) | |
2690 match->cp_number = 0; | |
694 | 2691 if ((match->cp_str = vim_strnsave(str, len)) == NULL) |
7 | 2692 { |
2693 vim_free(match); | |
464 | 2694 return FAIL; |
7 | 2695 } |
681 | 2696 match->cp_icase = icase; |
659 | 2697 |
7 | 2698 /* match-fname is: |
464 | 2699 * - compl_curr_match->cp_fname if it is a string equal to fname. |
7 | 2700 * - a copy of fname, FREE_FNAME is set to free later THE allocated mem. |
2701 * - NULL otherwise. --Acevedo */ | |
659 | 2702 if (fname != NULL |
829 | 2703 && compl_curr_match != NULL |
659 | 2704 && compl_curr_match->cp_fname != NULL |
2705 && STRCMP(fname, compl_curr_match->cp_fname) == 0) | |
464 | 2706 match->cp_fname = compl_curr_match->cp_fname; |
659 | 2707 else if (fname != NULL) |
2708 { | |
2709 match->cp_fname = vim_strsave(fname); | |
464 | 2710 flags |= FREE_FNAME; |
659 | 2711 } |
7 | 2712 else |
464 | 2713 match->cp_fname = NULL; |
2714 match->cp_flags = flags; | |
786 | 2715 |
2716 if (cptext != NULL) | |
2717 { | |
2718 int i; | |
2719 | |
2720 for (i = 0; i < CPT_COUNT; ++i) | |
2721 if (cptext[i] != NULL && *cptext[i] != NUL) | |
2722 match->cp_text[i] = vim_strsave(cptext[i]); | |
2723 } | |
7 | 2724 |
2725 /* | |
2726 * Link the new match structure in the list of matches. | |
2727 */ | |
449 | 2728 if (compl_first_match == NULL) |
464 | 2729 match->cp_next = match->cp_prev = NULL; |
7 | 2730 else if (dir == FORWARD) |
2731 { | |
464 | 2732 match->cp_next = compl_curr_match->cp_next; |
2733 match->cp_prev = compl_curr_match; | |
7 | 2734 } |
2735 else /* BACKWARD */ | |
2736 { | |
464 | 2737 match->cp_next = compl_curr_match; |
2738 match->cp_prev = compl_curr_match->cp_prev; | |
2739 } | |
2740 if (match->cp_next) | |
2741 match->cp_next->cp_prev = match; | |
2742 if (match->cp_prev) | |
2743 match->cp_prev->cp_next = match; | |
7 | 2744 else /* if there's nothing before, it is the first match */ |
449 | 2745 compl_first_match = match; |
2746 compl_curr_match = match; | |
7 | 2747 |
665 | 2748 /* |
2749 * Find the longest common string if still doing that. | |
2750 */ | |
2751 if (compl_get_longest && (flags & ORIGINAL_TEXT) == 0) | |
2752 ins_compl_longest_match(match); | |
2753 | |
7 | 2754 return OK; |
2755 } | |
2756 | |
2757 /* | |
681 | 2758 * Return TRUE if "str[len]" matches with match->cp_str, considering |
2759 * match->cp_icase. | |
2760 */ | |
2761 static int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
2762 ins_compl_equal(compl_T *match, char_u *str, int len) |
681 | 2763 { |
2764 if (match->cp_icase) | |
2765 return STRNICMP(match->cp_str, str, (size_t)len) == 0; | |
2766 return STRNCMP(match->cp_str, str, (size_t)len) == 0; | |
2767 } | |
2768 | |
2769 /* | |
665 | 2770 * Reduce the longest common string for match "match". |
2771 */ | |
2772 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
2773 ins_compl_longest_match(compl_T *match) |
665 | 2774 { |
2775 char_u *p, *s; | |
681 | 2776 int c1, c2; |
665 | 2777 int had_match; |
2778 | |
2779 if (compl_leader == NULL) | |
842 | 2780 { |
665 | 2781 /* First match, use it as a whole. */ |
2782 compl_leader = vim_strsave(match->cp_str); | |
842 | 2783 if (compl_leader != NULL) |
2784 { | |
2785 had_match = (curwin->w_cursor.col > compl_col); | |
2786 ins_compl_delete(); | |
1782 | 2787 ins_bytes(compl_leader + ins_compl_len()); |
842 | 2788 ins_redraw(FALSE); |
2789 | |
2790 /* When the match isn't there (to avoid matching itself) remove it | |
2791 * again after redrawing. */ | |
2792 if (!had_match) | |
2793 ins_compl_delete(); | |
2794 compl_used_match = FALSE; | |
2795 } | |
2796 } | |
665 | 2797 else |
2798 { | |
2799 /* Reduce the text if this match differs from compl_leader. */ | |
681 | 2800 p = compl_leader; |
2801 s = match->cp_str; | |
2802 while (*p != NUL) | |
665 | 2803 { |
2804 if (has_mbyte) | |
2805 { | |
681 | 2806 c1 = mb_ptr2char(p); |
2807 c2 = mb_ptr2char(s); | |
665 | 2808 } |
2809 else | |
2810 { | |
681 | 2811 c1 = *p; |
2812 c2 = *s; | |
2813 } | |
2814 if (match->cp_icase ? (MB_TOLOWER(c1) != MB_TOLOWER(c2)) | |
2815 : (c1 != c2)) | |
2816 break; | |
2817 if (has_mbyte) | |
2818 { | |
11127
506f5d8b7d8b
patch 8.0.0451: some macros are in lower case
Christian Brabandt <cb@256bit.org>
parents:
11121
diff
changeset
|
2819 MB_PTR_ADV(p); |
506f5d8b7d8b
patch 8.0.0451: some macros are in lower case
Christian Brabandt <cb@256bit.org>
parents:
11121
diff
changeset
|
2820 MB_PTR_ADV(s); |
681 | 2821 } |
2822 else | |
2823 { | |
2824 ++p; | |
2825 ++s; | |
665 | 2826 } |
2827 } | |
2828 | |
2829 if (*p != NUL) | |
2830 { | |
2831 /* Leader was shortened, need to change the inserted text. */ | |
2832 *p = NUL; | |
2833 had_match = (curwin->w_cursor.col > compl_col); | |
2834 ins_compl_delete(); | |
1782 | 2835 ins_bytes(compl_leader + ins_compl_len()); |
665 | 2836 ins_redraw(FALSE); |
2837 | |
2838 /* When the match isn't there (to avoid matching itself) remove it | |
2839 * again after redrawing. */ | |
2840 if (!had_match) | |
2841 ins_compl_delete(); | |
2842 } | |
2843 | |
2844 compl_used_match = FALSE; | |
2845 } | |
2846 } | |
2847 | |
2848 /* | |
7 | 2849 * Add an array of matches to the list of matches. |
2850 * Frees matches[]. | |
2851 */ | |
2852 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
2853 ins_compl_add_matches( |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
2854 int num_matches, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
2855 char_u **matches, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
2856 int icase) |
7 | 2857 { |
2858 int i; | |
2859 int add_r = OK; | |
659 | 2860 int dir = compl_direction; |
7 | 2861 |
464 | 2862 for (i = 0; i < num_matches && add_r != FAIL; i++) |
681 | 2863 if ((add_r = ins_compl_add(matches[i], -1, icase, |
841 | 2864 NULL, NULL, dir, 0, FALSE)) == OK) |
7 | 2865 /* if dir was BACKWARD then honor it just once */ |
659 | 2866 dir = FORWARD; |
7 | 2867 FreeWild(num_matches, matches); |
2868 } | |
2869 | |
2870 /* Make the completion list cyclic. | |
2871 * Return the number of matches (excluding the original). | |
2872 */ | |
2873 static int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
2874 ins_compl_make_cyclic(void) |
7 | 2875 { |
464 | 2876 compl_T *match; |
7 | 2877 int count = 0; |
2878 | |
449 | 2879 if (compl_first_match != NULL) |
7 | 2880 { |
2881 /* | |
2882 * Find the end of the list. | |
2883 */ | |
449 | 2884 match = compl_first_match; |
2885 /* there's always an entry for the compl_orig_text, it doesn't count. */ | |
464 | 2886 while (match->cp_next != NULL && match->cp_next != compl_first_match) |
2887 { | |
2888 match = match->cp_next; | |
7 | 2889 ++count; |
2890 } | |
464 | 2891 match->cp_next = compl_first_match; |
2892 compl_first_match->cp_prev = match; | |
7 | 2893 } |
2894 return count; | |
2895 } | |
2896 | |
724 | 2897 /* |
8935
219d80fee92f
commit https://github.com/vim/vim/commit/c020042083b9c0a4e932b562c3bef97c76328e18
Christian Brabandt <cb@256bit.org>
parents:
8891
diff
changeset
|
2898 * Set variables that store noselect and noinsert behavior from the |
219d80fee92f
commit https://github.com/vim/vim/commit/c020042083b9c0a4e932b562c3bef97c76328e18
Christian Brabandt <cb@256bit.org>
parents:
8891
diff
changeset
|
2899 * 'completeopt' value. |
219d80fee92f
commit https://github.com/vim/vim/commit/c020042083b9c0a4e932b562c3bef97c76328e18
Christian Brabandt <cb@256bit.org>
parents:
8891
diff
changeset
|
2900 */ |
219d80fee92f
commit https://github.com/vim/vim/commit/c020042083b9c0a4e932b562c3bef97c76328e18
Christian Brabandt <cb@256bit.org>
parents:
8891
diff
changeset
|
2901 void |
9282
9f97a6290c63
commit https://github.com/vim/vim/commit/cf089463492fab53b2a5d81517829d22f882f82e
Christian Brabandt <cb@256bit.org>
parents:
8945
diff
changeset
|
2902 completeopt_was_set(void) |
8935
219d80fee92f
commit https://github.com/vim/vim/commit/c020042083b9c0a4e932b562c3bef97c76328e18
Christian Brabandt <cb@256bit.org>
parents:
8891
diff
changeset
|
2903 { |
219d80fee92f
commit https://github.com/vim/vim/commit/c020042083b9c0a4e932b562c3bef97c76328e18
Christian Brabandt <cb@256bit.org>
parents:
8891
diff
changeset
|
2904 compl_no_insert = FALSE; |
219d80fee92f
commit https://github.com/vim/vim/commit/c020042083b9c0a4e932b562c3bef97c76328e18
Christian Brabandt <cb@256bit.org>
parents:
8891
diff
changeset
|
2905 compl_no_select = FALSE; |
219d80fee92f
commit https://github.com/vim/vim/commit/c020042083b9c0a4e932b562c3bef97c76328e18
Christian Brabandt <cb@256bit.org>
parents:
8891
diff
changeset
|
2906 if (strstr((char *)p_cot, "noselect") != NULL) |
219d80fee92f
commit https://github.com/vim/vim/commit/c020042083b9c0a4e932b562c3bef97c76328e18
Christian Brabandt <cb@256bit.org>
parents:
8891
diff
changeset
|
2907 compl_no_select = TRUE; |
219d80fee92f
commit https://github.com/vim/vim/commit/c020042083b9c0a4e932b562c3bef97c76328e18
Christian Brabandt <cb@256bit.org>
parents:
8891
diff
changeset
|
2908 if (strstr((char *)p_cot, "noinsert") != NULL) |
219d80fee92f
commit https://github.com/vim/vim/commit/c020042083b9c0a4e932b562c3bef97c76328e18
Christian Brabandt <cb@256bit.org>
parents:
8891
diff
changeset
|
2909 compl_no_insert = TRUE; |
219d80fee92f
commit https://github.com/vim/vim/commit/c020042083b9c0a4e932b562c3bef97c76328e18
Christian Brabandt <cb@256bit.org>
parents:
8891
diff
changeset
|
2910 } |
219d80fee92f
commit https://github.com/vim/vim/commit/c020042083b9c0a4e932b562c3bef97c76328e18
Christian Brabandt <cb@256bit.org>
parents:
8891
diff
changeset
|
2911 |
219d80fee92f
commit https://github.com/vim/vim/commit/c020042083b9c0a4e932b562c3bef97c76328e18
Christian Brabandt <cb@256bit.org>
parents:
8891
diff
changeset
|
2912 /* |
724 | 2913 * Start completion for the complete() function. |
2914 * "startcol" is where the matched text starts (1 is first column). | |
2915 * "list" is the list of matches. | |
2916 */ | |
2917 void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
2918 set_completion(colnr_T startcol, list_T *list) |
724 | 2919 { |
8224
2baf64fead5e
commit https://github.com/vim/vim/commit/8aefbe0ad5d05ee7225b20024b0f3023286ebd0f
Christian Brabandt <cb@256bit.org>
parents:
8090
diff
changeset
|
2920 int save_w_wrow = curwin->w_wrow; |
11002
35d4975a5bb5
patch 8.0.0390: when the window scrolls the popup menu may be garbled
Christian Brabandt <cb@256bit.org>
parents:
10980
diff
changeset
|
2921 int save_w_leftcol = curwin->w_leftcol; |
8224
2baf64fead5e
commit https://github.com/vim/vim/commit/8aefbe0ad5d05ee7225b20024b0f3023286ebd0f
Christian Brabandt <cb@256bit.org>
parents:
8090
diff
changeset
|
2922 |
724 | 2923 /* If already doing completions stop it. */ |
13210
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
2924 if (ctrl_x_mode != CTRL_X_NORMAL) |
724 | 2925 ins_compl_prep(' '); |
2926 ins_compl_clear(); | |
10714
319bafc99ee8
patch 8.0.0247: need to type Ctrl-N twice to select a completion
Christian Brabandt <cb@256bit.org>
parents:
10696
diff
changeset
|
2927 ins_compl_free(); |
724 | 2928 |
2632 | 2929 compl_direction = FORWARD; |
1869 | 2930 if (startcol > curwin->w_cursor.col) |
724 | 2931 startcol = curwin->w_cursor.col; |
2932 compl_col = startcol; | |
1869 | 2933 compl_length = (int)curwin->w_cursor.col - (int)startcol; |
724 | 2934 /* compl_pattern doesn't need to be set */ |
2935 compl_orig_text = vim_strnsave(ml_get_curline() + compl_col, compl_length); | |
2936 if (compl_orig_text == NULL || ins_compl_add(compl_orig_text, | |
942 | 2937 -1, p_ic, NULL, NULL, 0, ORIGINAL_TEXT, FALSE) != OK) |
724 | 2938 return; |
2939 | |
6657 | 2940 ctrl_x_mode = CTRL_X_EVAL; |
724 | 2941 |
2942 ins_compl_add_list(list); | |
2943 compl_matches = ins_compl_make_cyclic(); | |
2944 compl_started = TRUE; | |
2945 compl_used_match = TRUE; | |
929 | 2946 compl_cont_status = 0; |
724 | 2947 |
2948 compl_curr_match = compl_first_match; | |
8943
47036dcd83a4
commit https://github.com/vim/vim/commit/8e42ae5069d4985869e46eaa56900ed19e30f504
Christian Brabandt <cb@256bit.org>
parents:
8935
diff
changeset
|
2949 if (compl_no_insert || compl_no_select) |
47036dcd83a4
commit https://github.com/vim/vim/commit/8e42ae5069d4985869e46eaa56900ed19e30f504
Christian Brabandt <cb@256bit.org>
parents:
8935
diff
changeset
|
2950 { |
8224
2baf64fead5e
commit https://github.com/vim/vim/commit/8aefbe0ad5d05ee7225b20024b0f3023286ebd0f
Christian Brabandt <cb@256bit.org>
parents:
8090
diff
changeset
|
2951 ins_complete(K_DOWN, FALSE); |
8943
47036dcd83a4
commit https://github.com/vim/vim/commit/8e42ae5069d4985869e46eaa56900ed19e30f504
Christian Brabandt <cb@256bit.org>
parents:
8935
diff
changeset
|
2952 if (compl_no_select) |
47036dcd83a4
commit https://github.com/vim/vim/commit/8e42ae5069d4985869e46eaa56900ed19e30f504
Christian Brabandt <cb@256bit.org>
parents:
8935
diff
changeset
|
2953 /* Down/Up has no real effect. */ |
47036dcd83a4
commit https://github.com/vim/vim/commit/8e42ae5069d4985869e46eaa56900ed19e30f504
Christian Brabandt <cb@256bit.org>
parents:
8935
diff
changeset
|
2954 ins_complete(K_UP, FALSE); |
47036dcd83a4
commit https://github.com/vim/vim/commit/8e42ae5069d4985869e46eaa56900ed19e30f504
Christian Brabandt <cb@256bit.org>
parents:
8935
diff
changeset
|
2955 } |
6911 | 2956 else |
8224
2baf64fead5e
commit https://github.com/vim/vim/commit/8aefbe0ad5d05ee7225b20024b0f3023286ebd0f
Christian Brabandt <cb@256bit.org>
parents:
8090
diff
changeset
|
2957 ins_complete(Ctrl_N, FALSE); |
9467
5fb484647e12
commit https://github.com/vim/vim/commit/32b808a4bdf35b0dea63c735702a591e5869fecd
Christian Brabandt <cb@256bit.org>
parents:
9465
diff
changeset
|
2958 compl_enter_selects = compl_no_insert; |
8224
2baf64fead5e
commit https://github.com/vim/vim/commit/8aefbe0ad5d05ee7225b20024b0f3023286ebd0f
Christian Brabandt <cb@256bit.org>
parents:
8090
diff
changeset
|
2959 |
2baf64fead5e
commit https://github.com/vim/vim/commit/8aefbe0ad5d05ee7225b20024b0f3023286ebd0f
Christian Brabandt <cb@256bit.org>
parents:
8090
diff
changeset
|
2960 /* Lazily show the popup menu, unless we got interrupted. */ |
2baf64fead5e
commit https://github.com/vim/vim/commit/8aefbe0ad5d05ee7225b20024b0f3023286ebd0f
Christian Brabandt <cb@256bit.org>
parents:
8090
diff
changeset
|
2961 if (!compl_interrupted) |
11002
35d4975a5bb5
patch 8.0.0390: when the window scrolls the popup menu may be garbled
Christian Brabandt <cb@256bit.org>
parents:
10980
diff
changeset
|
2962 show_pum(save_w_wrow, save_w_leftcol); |
724 | 2963 out_flush(); |
2964 } | |
2965 | |
2966 | |
574 | 2967 /* "compl_match_array" points the currently displayed list of entries in the |
2968 * popup menu. It is NULL when there is no popup menu. */ | |
659 | 2969 static pumitem_T *compl_match_array = NULL; |
540 | 2970 static int compl_match_arraysize; |
2971 | |
2972 /* | |
2973 * Update the screen and when there is any scrolling remove the popup menu. | |
2974 */ | |
2975 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
2976 ins_compl_upd_pum(void) |
540 | 2977 { |
2978 int h; | |
2979 | |
2980 if (compl_match_array != NULL) | |
2981 { | |
2982 h = curwin->w_cline_height; | |
15521
6d949e552e99
patch 8.1.0768: updating completions may cause the popup menu to flicker
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
2983 // Update the screen later, before drawing the popup menu over it. |
6d949e552e99
patch 8.1.0768: updating completions may cause the popup menu to flicker
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
2984 pum_call_update_screen(); |
540 | 2985 if (h != curwin->w_cline_height) |
2986 ins_compl_del_pum(); | |
2987 } | |
2988 } | |
2989 | |
2990 /* | |
2991 * Remove any popup menu. | |
2992 */ | |
2993 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
2994 ins_compl_del_pum(void) |
540 | 2995 { |
2996 if (compl_match_array != NULL) | |
2997 { | |
2998 pum_undisplay(); | |
13244
ac42c4b11dbc
patch 8.0.1496: clearing a pointer takes two lines
Christian Brabandt <cb@256bit.org>
parents:
13240
diff
changeset
|
2999 VIM_CLEAR(compl_match_array); |
540 | 3000 } |
3001 } | |
3002 | |
3003 /* | |
3004 * Return TRUE if the popup menu should be displayed. | |
3005 */ | |
3006 static int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
3007 pum_wanted(void) |
540 | 3008 { |
707 | 3009 /* 'completeopt' must contain "menu" or "menuone" */ |
665 | 3010 if (vim_strchr(p_cot, 'm') == NULL) |
540 | 3011 return FALSE; |
3012 | |
3013 /* The display looks bad on a B&W display. */ | |
3014 if (t_colors < 8 | |
3015 #ifdef FEAT_GUI | |
3016 && !gui.in_use | |
3017 #endif | |
3018 ) | |
3019 return FALSE; | |
657 | 3020 return TRUE; |
3021 } | |
3022 | |
3023 /* | |
3024 * Return TRUE if there are two or more matches to be shown in the popup menu. | |
707 | 3025 * One if 'completopt' contains "menuone". |
657 | 3026 */ |
3027 static int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
3028 pum_enough_matches(void) |
657 | 3029 { |
3030 compl_T *compl; | |
3031 int i; | |
540 | 3032 |
3033 /* Don't display the popup menu if there are no matches or there is only | |
3034 * one (ignoring the original text). */ | |
3035 compl = compl_first_match; | |
3036 i = 0; | |
3037 do | |
3038 { | |
3039 if (compl == NULL | |
3040 || ((compl->cp_flags & ORIGINAL_TEXT) == 0 && ++i == 2)) | |
3041 break; | |
3042 compl = compl->cp_next; | |
3043 } while (compl != compl_first_match); | |
3044 | |
707 | 3045 if (strstr((char *)p_cot, "menuone") != NULL) |
3046 return (i >= 1); | |
540 | 3047 return (i >= 2); |
3048 } | |
3049 | |
3050 /* | |
3051 * Show the popup menu for the list of matches. | |
659 | 3052 * Also adjusts "compl_shown_match" to an entry that is actually displayed. |
540 | 3053 */ |
648 | 3054 void |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
3055 ins_compl_show_pum(void) |
540 | 3056 { |
3057 compl_T *compl; | |
659 | 3058 compl_T *shown_compl = NULL; |
3059 int did_find_shown_match = FALSE; | |
3060 int shown_match_ok = FALSE; | |
540 | 3061 int i; |
3062 int cur = -1; | |
3063 colnr_T col; | |
657 | 3064 int lead_len = 0; |
3065 | |
707 | 3066 if (!pum_wanted() || !pum_enough_matches()) |
540 | 3067 return; |
3068 | |
794 | 3069 #if defined(FEAT_EVAL) |
3070 /* Dirty hard-coded hack: remove any matchparen highlighting. */ | |
3071 do_cmdline_cmd((char_u *)"if exists('g:loaded_matchparen')|3match none|endif"); | |
3072 #endif | |
3073 | |
15521
6d949e552e99
patch 8.1.0768: updating completions may cause the popup menu to flicker
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
3074 // Update the screen later, before drawing the popup menu over it. |
6d949e552e99
patch 8.1.0768: updating completions may cause the popup menu to flicker
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
3075 pum_call_update_screen(); |
540 | 3076 |
3077 if (compl_match_array == NULL) | |
3078 { | |
3079 /* Need to build the popup menu list. */ | |
3080 compl_match_arraysize = 0; | |
3081 compl = compl_first_match; | |
657 | 3082 if (compl_leader != NULL) |
835 | 3083 lead_len = (int)STRLEN(compl_leader); |
540 | 3084 do |
3085 { | |
657 | 3086 if ((compl->cp_flags & ORIGINAL_TEXT) == 0 |
3087 && (compl_leader == NULL | |
681 | 3088 || ins_compl_equal(compl, compl_leader, lead_len))) |
540 | 3089 ++compl_match_arraysize; |
3090 compl = compl->cp_next; | |
3091 } while (compl != NULL && compl != compl_first_match); | |
657 | 3092 if (compl_match_arraysize == 0) |
3093 return; | |
659 | 3094 compl_match_array = (pumitem_T *)alloc_clear( |
3095 (unsigned)(sizeof(pumitem_T) | |
540 | 3096 * compl_match_arraysize)); |
3097 if (compl_match_array != NULL) | |
3098 { | |
829 | 3099 /* If the current match is the original text don't find the first |
3100 * match after it, don't highlight anything. */ | |
3101 if (compl_shown_match->cp_flags & ORIGINAL_TEXT) | |
3102 shown_match_ok = TRUE; | |
3103 | |
540 | 3104 i = 0; |
3105 compl = compl_first_match; | |
3106 do | |
3107 { | |
657 | 3108 if ((compl->cp_flags & ORIGINAL_TEXT) == 0 |
3109 && (compl_leader == NULL | |
681 | 3110 || ins_compl_equal(compl, compl_leader, lead_len))) |
540 | 3111 { |
659 | 3112 if (!shown_match_ok) |
3113 { | |
3114 if (compl == compl_shown_match || did_find_shown_match) | |
3115 { | |
3116 /* This item is the shown match or this is the | |
3117 * first displayed item after the shown match. */ | |
3118 compl_shown_match = compl; | |
3119 did_find_shown_match = TRUE; | |
3120 shown_match_ok = TRUE; | |
3121 } | |
3122 else | |
3123 /* Remember this displayed match for when the | |
3124 * shown match is just below it. */ | |
3125 shown_compl = compl; | |
540 | 3126 cur = i; |
659 | 3127 } |
786 | 3128 |
3129 if (compl->cp_text[CPT_ABBR] != NULL) | |
3130 compl_match_array[i].pum_text = | |
3131 compl->cp_text[CPT_ABBR]; | |
3132 else | |
3133 compl_match_array[i].pum_text = compl->cp_str; | |
3134 compl_match_array[i].pum_kind = compl->cp_text[CPT_KIND]; | |
3135 compl_match_array[i].pum_info = compl->cp_text[CPT_INFO]; | |
3136 if (compl->cp_text[CPT_MENU] != NULL) | |
3137 compl_match_array[i++].pum_extra = | |
3138 compl->cp_text[CPT_MENU]; | |
659 | 3139 else |
3140 compl_match_array[i++].pum_extra = compl->cp_fname; | |
3141 } | |
3142 | |
3143 if (compl == compl_shown_match) | |
3144 { | |
3145 did_find_shown_match = TRUE; | |
716 | 3146 |
3147 /* When the original text is the shown match don't set | |
3148 * compl_shown_match. */ | |
3149 if (compl->cp_flags & ORIGINAL_TEXT) | |
3150 shown_match_ok = TRUE; | |
3151 | |
659 | 3152 if (!shown_match_ok && shown_compl != NULL) |
3153 { | |
3154 /* The shown match isn't displayed, set it to the | |
3155 * previously displayed match. */ | |
3156 compl_shown_match = shown_compl; | |
3157 shown_match_ok = TRUE; | |
3158 } | |
540 | 3159 } |
3160 compl = compl->cp_next; | |
3161 } while (compl != NULL && compl != compl_first_match); | |
659 | 3162 |
3163 if (!shown_match_ok) /* no displayed match at all */ | |
3164 cur = -1; | |
540 | 3165 } |
3166 } | |
3167 else | |
3168 { | |
3169 /* popup menu already exists, only need to find the current item.*/ | |
657 | 3170 for (i = 0; i < compl_match_arraysize; ++i) |
786 | 3171 if (compl_match_array[i].pum_text == compl_shown_match->cp_str |
3172 || compl_match_array[i].pum_text | |
3173 == compl_shown_match->cp_text[CPT_ABBR]) | |
829 | 3174 { |
3175 cur = i; | |
657 | 3176 break; |
829 | 3177 } |
540 | 3178 } |
3179 | |
3180 if (compl_match_array != NULL) | |
3181 { | |
6729 | 3182 /* In Replace mode when a $ is displayed at the end of the line only |
3183 * part of the screen would be updated. We do need to redraw here. */ | |
3184 dollar_vcol = -1; | |
3185 | |
540 | 3186 /* Compute the screen column of the start of the completed text. |
3187 * Use the cursor to get all wrapping and other settings right. */ | |
3188 col = curwin->w_cursor.col; | |
3189 curwin->w_cursor.col = compl_col; | |
732 | 3190 pum_display(compl_match_array, compl_match_arraysize, cur); |
540 | 3191 curwin->w_cursor.col = col; |
3192 } | |
3193 } | |
3194 | |
7 | 3195 #define DICT_FIRST (1) /* use just first element in "dict" */ |
3196 #define DICT_EXACT (2) /* "dict" is the exact name of a file */ | |
648 | 3197 |
7 | 3198 /* |
703 | 3199 * Add any identifiers that match the given pattern in the list of dictionary |
3200 * files "dict_start" to the list of completions. | |
7 | 3201 */ |
3202 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
3203 ins_compl_dictionaries( |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
3204 char_u *dict_start, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
3205 char_u *pat, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
3206 int flags, /* DICT_FIRST and/or DICT_EXACT */ |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
3207 int thesaurus) /* Thesaurus completion */ |
703 | 3208 { |
3209 char_u *dict = dict_start; | |
7 | 3210 char_u *ptr; |
3211 char_u *buf; | |
3212 regmatch_T regmatch; | |
3213 char_u **files; | |
3214 int count; | |
3215 int save_p_scs; | |
659 | 3216 int dir = compl_direction; |
7 | 3217 |
703 | 3218 if (*dict == NUL) |
3219 { | |
744 | 3220 #ifdef FEAT_SPELL |
703 | 3221 /* When 'dictionary' is empty and spell checking is enabled use |
3222 * "spell". */ | |
3223 if (!thesaurus && curwin->w_p_spell) | |
3224 dict = (char_u *)"spell"; | |
3225 else | |
3226 #endif | |
3227 return; | |
3228 } | |
3229 | |
7 | 3230 buf = alloc(LSIZE); |
703 | 3231 if (buf == NULL) |
3232 return; | |
1074 | 3233 regmatch.regprog = NULL; /* so that we can goto theend */ |
703 | 3234 |
7 | 3235 /* If 'infercase' is set, don't use 'smartcase' here */ |
3236 save_p_scs = p_scs; | |
3237 if (curbuf->b_p_inf) | |
3238 p_scs = FALSE; | |
667 | 3239 |
3240 /* When invoked to match whole lines for CTRL-X CTRL-L adjust the pattern | |
3241 * to only match at the start of a line. Otherwise just match the | |
842 | 3242 * pattern. Also need to double backslashes. */ |
6657 | 3243 if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)) |
667 | 3244 { |
842 | 3245 char_u *pat_esc = vim_strsave_escaped(pat, (char_u *)"\\"); |
1869 | 3246 size_t len; |
842 | 3247 |
3248 if (pat_esc == NULL) | |
1159 | 3249 goto theend; |
1869 | 3250 len = STRLEN(pat_esc) + 10; |
3251 ptr = alloc((unsigned)len); | |
667 | 3252 if (ptr == NULL) |
842 | 3253 { |
3254 vim_free(pat_esc); | |
1074 | 3255 goto theend; |
842 | 3256 } |
1869 | 3257 vim_snprintf((char *)ptr, len, "^\\s*\\zs\\V%s", pat_esc); |
842 | 3258 regmatch.regprog = vim_regcomp(ptr, RE_MAGIC); |
3259 vim_free(pat_esc); | |
667 | 3260 vim_free(ptr); |
3261 } | |
3262 else | |
703 | 3263 { |
667 | 3264 regmatch.regprog = vim_regcomp(pat, p_magic ? RE_MAGIC : 0); |
703 | 3265 if (regmatch.regprog == NULL) |
3266 goto theend; | |
3267 } | |
667 | 3268 |
7 | 3269 /* ignore case depends on 'ignorecase', 'smartcase' and "pat" */ |
3270 regmatch.rm_ic = ignorecase(pat); | |
703 | 3271 while (*dict != NUL && !got_int && !compl_interrupted) |
7 | 3272 { |
3273 /* copy one dictionary file name into buf */ | |
3274 if (flags == DICT_EXACT) | |
3275 { | |
3276 count = 1; | |
3277 files = &dict; | |
3278 } | |
3279 else | |
3280 { | |
3281 /* Expand wildcards in the dictionary name, but do not allow | |
3282 * backticks (for security, the 'dict' option may have been set in | |
3283 * a modeline). */ | |
3284 copy_option_part(&dict, buf, LSIZE, ","); | |
744 | 3285 # ifdef FEAT_SPELL |
703 | 3286 if (!thesaurus && STRCMP(buf, "spell") == 0) |
3287 count = -1; | |
744 | 3288 else |
3289 # endif | |
3290 if (vim_strchr(buf, '`') != NULL | |
7 | 3291 || expand_wildcards(1, &buf, &count, &files, |
3292 EW_FILE|EW_SILENT) != OK) | |
3293 count = 0; | |
3294 } | |
3295 | |
744 | 3296 # ifdef FEAT_SPELL |
703 | 3297 if (count == -1) |
3298 { | |
712 | 3299 /* Complete from active spelling. Skip "\<" in the pattern, we |
3300 * don't use it as a RE. */ | |
703 | 3301 if (pat[0] == '\\' && pat[1] == '<') |
3302 ptr = pat + 2; | |
3303 else | |
3304 ptr = pat; | |
2250
1bac28a53fae
Add the conceal patch from Vince Negri.
Bram Moolenaar <bram@vim.org>
parents:
2227
diff
changeset
|
3305 spell_dump_compl(ptr, regmatch.rm_ic, &dir, 0); |
703 | 3306 } |
3307 else | |
744 | 3308 # endif |
938 | 3309 if (count > 0) /* avoid warning for using "files" uninit */ |
703 | 3310 { |
3311 ins_compl_files(count, files, thesaurus, flags, | |
3312 ®match, buf, &dir); | |
7 | 3313 if (flags != DICT_EXACT) |
703 | 3314 FreeWild(count, files); |
3315 } | |
3316 if (flags != 0) | |
7 | 3317 break; |
3318 } | |
703 | 3319 |
3320 theend: | |
7 | 3321 p_scs = save_p_scs; |
4805
66803af09906
updated for version 7.3.1149
Bram Moolenaar <bram@vim.org>
parents:
4448
diff
changeset
|
3322 vim_regfree(regmatch.regprog); |
7 | 3323 vim_free(buf); |
3324 } | |
3325 | |
703 | 3326 static void |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
3327 ins_compl_files( |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
3328 int count, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
3329 char_u **files, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
3330 int thesaurus, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
3331 int flags, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
3332 regmatch_T *regmatch, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
3333 char_u *buf, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
3334 int *dir) |
703 | 3335 { |
3336 char_u *ptr; | |
3337 int i; | |
3338 FILE *fp; | |
3339 int add_r; | |
3340 | |
3341 for (i = 0; i < count && !got_int && !compl_interrupted; i++) | |
3342 { | |
3343 fp = mch_fopen((char *)files[i], "r"); /* open dictionary file */ | |
3344 if (flags != DICT_EXACT) | |
3345 { | |
3346 vim_snprintf((char *)IObuff, IOSIZE, | |
3347 _("Scanning dictionary: %s"), (char *)files[i]); | |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15521
diff
changeset
|
3348 (void)msg_trunc_attr((char *)IObuff, TRUE, HL_ATTR(HLF_R)); |
703 | 3349 } |
3350 | |
3351 if (fp != NULL) | |
3352 { | |
3353 /* | |
3354 * Read dictionary file line by line. | |
3355 * Check each line for a match. | |
3356 */ | |
3357 while (!got_int && !compl_interrupted | |
3358 && !vim_fgets(buf, LSIZE, fp)) | |
3359 { | |
3360 ptr = buf; | |
3361 while (vim_regexec(regmatch, buf, (colnr_T)(ptr - buf))) | |
3362 { | |
3363 ptr = regmatch->startp[0]; | |
6657 | 3364 if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)) |
703 | 3365 ptr = find_line_end(ptr); |
3366 else | |
3367 ptr = find_word_end(ptr); | |
3368 add_r = ins_compl_add_infercase(regmatch->startp[0], | |
3369 (int)(ptr - regmatch->startp[0]), | |
942 | 3370 p_ic, files[i], *dir, 0); |
703 | 3371 if (thesaurus) |
3372 { | |
3373 char_u *wstart; | |
3374 | |
3375 /* | |
3376 * Add the other matches on the line | |
3377 */ | |
1353 | 3378 ptr = buf; |
703 | 3379 while (!got_int) |
3380 { | |
3381 /* Find start of the next word. Skip white | |
3382 * space and punctuation. */ | |
3383 ptr = find_word_start(ptr); | |
3384 if (*ptr == NUL || *ptr == NL) | |
3385 break; | |
3386 wstart = ptr; | |
3387 | |
1353 | 3388 /* Find end of the word. */ |
703 | 3389 if (has_mbyte) |
3390 /* Japanese words may have characters in | |
3391 * different classes, only separate words | |
3392 * with single-byte non-word characters. */ | |
3393 while (*ptr != NUL) | |
3394 { | |
3395 int l = (*mb_ptr2len)(ptr); | |
3396 | |
3397 if (l < 2 && !vim_iswordc(*ptr)) | |
3398 break; | |
3399 ptr += l; | |
3400 } | |
3401 else | |
3402 ptr = find_word_end(ptr); | |
1353 | 3403 |
3404 /* Add the word. Skip the regexp match. */ | |
3405 if (wstart != regmatch->startp[0]) | |
3406 add_r = ins_compl_add_infercase(wstart, | |
3407 (int)(ptr - wstart), | |
3408 p_ic, files[i], *dir, 0); | |
703 | 3409 } |
3410 } | |
3411 if (add_r == OK) | |
3412 /* if dir was BACKWARD then honor it just once */ | |
3413 *dir = FORWARD; | |
3414 else if (add_r == FAIL) | |
3415 break; | |
3416 /* avoid expensive call to vim_regexec() when at end | |
3417 * of line */ | |
3418 if (*ptr == '\n' || got_int) | |
3419 break; | |
3420 } | |
3421 line_breakcheck(); | |
10277
154d5a2e7395
commit https://github.com/vim/vim/commit/472e85970ee3a80abd824bef510df12e9cfe9e96
Christian Brabandt <cb@256bit.org>
parents:
10120
diff
changeset
|
3422 ins_compl_check_keys(50, FALSE); |
703 | 3423 } |
3424 fclose(fp); | |
3425 } | |
3426 } | |
3427 } | |
3428 | |
7 | 3429 /* |
3430 * Find the start of the next word. | |
3431 * Returns a pointer to the first char of the word. Also stops at a NUL. | |
3432 */ | |
3433 char_u * | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
3434 find_word_start(char_u *ptr) |
7 | 3435 { |
3436 if (has_mbyte) | |
3437 while (*ptr != NUL && *ptr != '\n' && mb_get_class(ptr) <= 1) | |
474 | 3438 ptr += (*mb_ptr2len)(ptr); |
7 | 3439 else |
3440 while (*ptr != NUL && *ptr != '\n' && !vim_iswordc(*ptr)) | |
3441 ++ptr; | |
3442 return ptr; | |
3443 } | |
3444 | |
3445 /* | |
3446 * Find the end of the word. Assumes it starts inside a word. | |
3447 * Returns a pointer to just after the word. | |
3448 */ | |
3449 char_u * | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
3450 find_word_end(char_u *ptr) |
7 | 3451 { |
3452 int start_class; | |
3453 | |
3454 if (has_mbyte) | |
3455 { | |
3456 start_class = mb_get_class(ptr); | |
3457 if (start_class > 1) | |
3458 while (*ptr != NUL) | |
3459 { | |
474 | 3460 ptr += (*mb_ptr2len)(ptr); |
7 | 3461 if (mb_get_class(ptr) != start_class) |
3462 break; | |
3463 } | |
3464 } | |
3465 else | |
3466 while (vim_iswordc(*ptr)) | |
3467 ++ptr; | |
3468 return ptr; | |
3469 } | |
3470 | |
3471 /* | |
667 | 3472 * Find the end of the line, omitting CR and NL at the end. |
3473 * Returns a pointer to just after the line. | |
3474 */ | |
3475 static char_u * | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
3476 find_line_end(char_u *ptr) |
667 | 3477 { |
3478 char_u *s; | |
3479 | |
3480 s = ptr + STRLEN(ptr); | |
3481 while (s > ptr && (s[-1] == CAR || s[-1] == NL)) | |
3482 --s; | |
3483 return s; | |
3484 } | |
3485 | |
3486 /* | |
7 | 3487 * Free the list of completions |
3488 */ | |
3489 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
3490 ins_compl_free(void) |
7 | 3491 { |
464 | 3492 compl_T *match; |
786 | 3493 int i; |
7 | 3494 |
13244
ac42c4b11dbc
patch 8.0.1496: clearing a pointer takes two lines
Christian Brabandt <cb@256bit.org>
parents:
13240
diff
changeset
|
3495 VIM_CLEAR(compl_pattern); |
ac42c4b11dbc
patch 8.0.1496: clearing a pointer takes two lines
Christian Brabandt <cb@256bit.org>
parents:
13240
diff
changeset
|
3496 VIM_CLEAR(compl_leader); |
449 | 3497 |
3498 if (compl_first_match == NULL) | |
7 | 3499 return; |
540 | 3500 |
3501 ins_compl_del_pum(); | |
3502 pum_clear(); | |
3503 | |
449 | 3504 compl_curr_match = compl_first_match; |
7 | 3505 do |
3506 { | |
449 | 3507 match = compl_curr_match; |
464 | 3508 compl_curr_match = compl_curr_match->cp_next; |
3509 vim_free(match->cp_str); | |
7 | 3510 /* several entries may use the same fname, free it just once. */ |
464 | 3511 if (match->cp_flags & FREE_FNAME) |
3512 vim_free(match->cp_fname); | |
786 | 3513 for (i = 0; i < CPT_COUNT; ++i) |
3514 vim_free(match->cp_text[i]); | |
7 | 3515 vim_free(match); |
449 | 3516 } while (compl_curr_match != NULL && compl_curr_match != compl_first_match); |
3517 compl_first_match = compl_curr_match = NULL; | |
1927 | 3518 compl_shown_match = NULL; |
11424
328a9ee98fb2
patch 8.0.0596: crash when complete() called after complete_add()
Christian Brabandt <cb@256bit.org>
parents:
11317
diff
changeset
|
3519 compl_old_match = NULL; |
7 | 3520 } |
3521 | |
3522 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
3523 ins_compl_clear(void) |
7 | 3524 { |
449 | 3525 compl_cont_status = 0; |
3526 compl_started = FALSE; | |
3527 compl_matches = 0; | |
13244
ac42c4b11dbc
patch 8.0.1496: clearing a pointer takes two lines
Christian Brabandt <cb@256bit.org>
parents:
13240
diff
changeset
|
3528 VIM_CLEAR(compl_pattern); |
ac42c4b11dbc
patch 8.0.1496: clearing a pointer takes two lines
Christian Brabandt <cb@256bit.org>
parents:
13240
diff
changeset
|
3529 VIM_CLEAR(compl_leader); |
7 | 3530 edit_submode_extra = NULL; |
13244
ac42c4b11dbc
patch 8.0.1496: clearing a pointer takes two lines
Christian Brabandt <cb@256bit.org>
parents:
13240
diff
changeset
|
3531 VIM_CLEAR(compl_orig_text); |
825 | 3532 compl_enter_selects = FALSE; |
6909 | 3533 /* clear v:completed_item */ |
13150
808625d4b71b
patch 8.0.1449: slow redrawing with DirectX
Christian Brabandt <cb@256bit.org>
parents:
12960
diff
changeset
|
3534 set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc_lock(VAR_FIXED)); |
7 | 3535 } |
3536 | |
3537 /* | |
674 | 3538 * Return TRUE when Insert completion is active. |
3539 */ | |
3540 int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
3541 ins_compl_active(void) |
674 | 3542 { |
3543 return compl_started; | |
3544 } | |
3545 | |
3546 /* | |
659 | 3547 * Delete one character before the cursor and show the subset of the matches |
3548 * that match the word that is now before the cursor. | |
836 | 3549 * Returns the character to be used, NUL if the work is done and another char |
3550 * to be got from the user. | |
657 | 3551 */ |
3552 static int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
3553 ins_compl_bs(void) |
657 | 3554 { |
3555 char_u *line; | |
3556 char_u *p; | |
3557 | |
836 | 3558 line = ml_get_curline(); |
3559 p = line + curwin->w_cursor.col; | |
11127
506f5d8b7d8b
patch 8.0.0451: some macros are in lower case
Christian Brabandt <cb@256bit.org>
parents:
11121
diff
changeset
|
3560 MB_PTR_BACK(line, p); |
836 | 3561 |
1430 | 3562 /* Stop completion when the whole word was deleted. For Omni completion |
10859
64ccb8029e06
patch 8.0.0319: insert mode completion does not respect 'backspace'
Christian Brabandt <cb@256bit.org>
parents:
10745
diff
changeset
|
3563 * allow the word to be deleted, we won't match everything. |
64ccb8029e06
patch 8.0.0319: insert mode completion does not respect 'backspace'
Christian Brabandt <cb@256bit.org>
parents:
10745
diff
changeset
|
3564 * Respect the 'backspace' option. */ |
1430 | 3565 if ((int)(p - line) - (int)compl_col < 0 |
3566 || ((int)(p - line) - (int)compl_col == 0 | |
10859
64ccb8029e06
patch 8.0.0319: insert mode completion does not respect 'backspace'
Christian Brabandt <cb@256bit.org>
parents:
10745
diff
changeset
|
3567 && ctrl_x_mode != CTRL_X_OMNI) || ctrl_x_mode == CTRL_X_EVAL |
64ccb8029e06
patch 8.0.0319: insert mode completion does not respect 'backspace'
Christian Brabandt <cb@256bit.org>
parents:
10745
diff
changeset
|
3568 || (!can_bs(BS_START) && (int)(p - line) - (int)compl_col |
64ccb8029e06
patch 8.0.0319: insert mode completion does not respect 'backspace'
Christian Brabandt <cb@256bit.org>
parents:
10745
diff
changeset
|
3569 - compl_length < 0)) |
836 | 3570 return K_BS; |
3571 | |
874 | 3572 /* Deleted more than what was used to find matches or didn't finish |
3573 * finding all matches: need to look for matches all over again. */ | |
3574 if (curwin->w_cursor.col <= compl_col + compl_length | |
3078 | 3575 || ins_compl_need_restart()) |
874 | 3576 ins_compl_restart(); |
657 | 3577 |
3578 vim_free(compl_leader); | |
835 | 3579 compl_leader = vim_strnsave(line + compl_col, (int)(p - line) - compl_col); |
657 | 3580 if (compl_leader != NULL) |
3581 { | |
874 | 3582 ins_compl_new_leader(); |
4205 | 3583 if (compl_shown_match != NULL) |
3584 /* Make sure current match is not a hidden item. */ | |
3585 compl_curr_match = compl_shown_match; | |
874 | 3586 return NUL; |
3587 } | |
3588 return K_BS; | |
3589 } | |
3590 | |
3591 /* | |
3078 | 3592 * Return TRUE when we need to find matches again, ins_compl_restart() is to |
3593 * be called. | |
3594 */ | |
3595 static int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
3596 ins_compl_need_restart(void) |
3078 | 3597 { |
3598 /* Return TRUE if we didn't complete finding matches or when the | |
3599 * 'completefunc' returned "always" in the "refresh" dictionary item. */ | |
3600 return compl_was_interrupted | |
3601 || ((ctrl_x_mode == CTRL_X_FUNCTION || ctrl_x_mode == CTRL_X_OMNI) | |
3602 && compl_opt_refresh_always); | |
3603 } | |
3604 | |
3605 /* | |
874 | 3606 * Called after changing "compl_leader". |
3607 * Show the popup menu with a different set of matches. | |
3608 * May also search for matches again if the previous search was interrupted. | |
3609 */ | |
3610 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
3611 ins_compl_new_leader(void) |
874 | 3612 { |
3613 ins_compl_del_pum(); | |
3614 ins_compl_delete(); | |
1782 | 3615 ins_bytes(compl_leader + ins_compl_len()); |
874 | 3616 compl_used_match = FALSE; |
3617 | |
3618 if (compl_started) | |
3619 ins_compl_set_original_text(compl_leader); | |
3620 else | |
3621 { | |
826 | 3622 #ifdef FEAT_SPELL |
874 | 3623 spell_bad_len = 0; /* need to redetect bad word */ |
3624 #endif | |
3625 /* | |
15521
6d949e552e99
patch 8.1.0768: updating completions may cause the popup menu to flicker
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
3626 * Matches were cleared, need to search for them now. Befor drawing |
6d949e552e99
patch 8.1.0768: updating completions may cause the popup menu to flicker
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
3627 * the popup menu display the changed text before the cursor. Set |
6d949e552e99
patch 8.1.0768: updating completions may cause the popup menu to flicker
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
3628 * "compl_restarting" to avoid that the first match is inserted. |
874 | 3629 */ |
15521
6d949e552e99
patch 8.1.0768: updating completions may cause the popup menu to flicker
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
3630 pum_call_update_screen(); |
874 | 3631 #ifdef FEAT_GUI |
3632 if (gui.in_use) | |
3633 { | |
3634 /* Show the cursor after the match, not after the redrawn text. */ | |
3635 setcursor(); | |
13150
808625d4b71b
patch 8.0.1449: slow redrawing with DirectX
Christian Brabandt <cb@256bit.org>
parents:
12960
diff
changeset
|
3636 out_flush_cursor(FALSE, FALSE); |
874 | 3637 } |
3638 #endif | |
3639 compl_restarting = TRUE; | |
8224
2baf64fead5e
commit https://github.com/vim/vim/commit/8aefbe0ad5d05ee7225b20024b0f3023286ebd0f
Christian Brabandt <cb@256bit.org>
parents:
8090
diff
changeset
|
3640 if (ins_complete(Ctrl_N, TRUE) == FAIL) |
874 | 3641 compl_cont_status = 0; |
3642 compl_restarting = FALSE; | |
3643 } | |
3644 | |
887 | 3645 compl_enter_selects = !compl_used_match; |
874 | 3646 |
3647 /* Show the popup menu with a different set of matches. */ | |
3648 ins_compl_show_pum(); | |
947 | 3649 |
3650 /* Don't let Enter select the original text when there is no popup menu. */ | |
3651 if (compl_match_array == NULL) | |
3652 compl_enter_selects = FALSE; | |
657 | 3653 } |
3654 | |
3655 /* | |
1782 | 3656 * Return the length of the completion, from the completion start column to |
3657 * the cursor column. Making sure it never goes below zero. | |
3658 */ | |
3659 static int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
3660 ins_compl_len(void) |
1782 | 3661 { |
1869 | 3662 int off = (int)curwin->w_cursor.col - (int)compl_col; |
1782 | 3663 |
3664 if (off < 0) | |
3665 return 0; | |
3666 return off; | |
3667 } | |
3668 | |
3669 /* | |
657 | 3670 * Append one character to the match leader. May reduce the number of |
3671 * matches. | |
3672 */ | |
3673 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
3674 ins_compl_addleader(int c) |
657 | 3675 { |
3676 int cc; | |
10904
c68775848f5f
patch 8.0.0341: undo does not work properly when using completion
Christian Brabandt <cb@256bit.org>
parents:
10889
diff
changeset
|
3677 |
c68775848f5f
patch 8.0.0341: undo does not work properly when using completion
Christian Brabandt <cb@256bit.org>
parents:
10889
diff
changeset
|
3678 if (stop_arrow() == FAIL) |
c68775848f5f
patch 8.0.0341: undo does not work properly when using completion
Christian Brabandt <cb@256bit.org>
parents:
10889
diff
changeset
|
3679 return; |
657 | 3680 if (has_mbyte && (cc = (*mb_char2len)(c)) > 1) |
3681 { | |
3682 char_u buf[MB_MAXBYTES + 1]; | |
3683 | |
3684 (*mb_char2bytes)(c, buf); | |
3685 buf[cc] = NUL; | |
3686 ins_char_bytes(buf, cc); | |
3612 | 3687 if (compl_opt_refresh_always) |
3688 AppendToRedobuff(buf); | |
657 | 3689 } |
3690 else | |
3602 | 3691 { |
657 | 3692 ins_char(c); |
3612 | 3693 if (compl_opt_refresh_always) |
3694 AppendCharToRedobuff(c); | |
3602 | 3695 } |
657 | 3696 |
874 | 3697 /* If we didn't complete finding matches we must search again. */ |
3078 | 3698 if (ins_compl_need_restart()) |
874 | 3699 ins_compl_restart(); |
3700 | |
3271 | 3701 /* When 'always' is set, don't reset compl_leader. While completing, |
3612 | 3702 * cursor doesn't point original position, changing compl_leader would |
3271 | 3703 * break redo. */ |
3704 if (!compl_opt_refresh_always) | |
3705 { | |
3706 vim_free(compl_leader); | |
3707 compl_leader = vim_strnsave(ml_get_curline() + compl_col, | |
1869 | 3708 (int)(curwin->w_cursor.col - compl_col)); |
3271 | 3709 if (compl_leader != NULL) |
3710 ins_compl_new_leader(); | |
3711 } | |
874 | 3712 } |
3713 | |
3714 /* | |
3715 * Setup for finding completions again without leaving CTRL-X mode. Used when | |
3716 * BS or a key was typed while still searching for matches. | |
3717 */ | |
3718 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
3719 ins_compl_restart(void) |
874 | 3720 { |
3721 ins_compl_free(); | |
3722 compl_started = FALSE; | |
3723 compl_matches = 0; | |
3724 compl_cont_status = 0; | |
3725 compl_cont_mode = 0; | |
694 | 3726 } |
3727 | |
3728 /* | |
3729 * Set the first match, the original text. | |
3730 */ | |
3731 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
3732 ins_compl_set_original_text(char_u *str) |
694 | 3733 { |
3734 char_u *p; | |
3735 | |
13718
66b1d74be322
patch 8.0.1731: characters deleted on completion
Christian Brabandt <cb@256bit.org>
parents:
13402
diff
changeset
|
3736 /* Replace the original text entry. |
66b1d74be322
patch 8.0.1731: characters deleted on completion
Christian Brabandt <cb@256bit.org>
parents:
13402
diff
changeset
|
3737 * The ORIGINAL_TEXT flag is either at the first item or might possibly be |
66b1d74be322
patch 8.0.1731: characters deleted on completion
Christian Brabandt <cb@256bit.org>
parents:
13402
diff
changeset
|
3738 * at the last item for backward completion */ |
694 | 3739 if (compl_first_match->cp_flags & ORIGINAL_TEXT) /* safety check */ |
3740 { | |
3741 p = vim_strsave(str); | |
3742 if (p != NULL) | |
3743 { | |
3744 vim_free(compl_first_match->cp_str); | |
3745 compl_first_match->cp_str = p; | |
3746 } | |
657 | 3747 } |
13718
66b1d74be322
patch 8.0.1731: characters deleted on completion
Christian Brabandt <cb@256bit.org>
parents:
13402
diff
changeset
|
3748 else if (compl_first_match->cp_prev != NULL |
66b1d74be322
patch 8.0.1731: characters deleted on completion
Christian Brabandt <cb@256bit.org>
parents:
13402
diff
changeset
|
3749 && (compl_first_match->cp_prev->cp_flags & ORIGINAL_TEXT)) |
66b1d74be322
patch 8.0.1731: characters deleted on completion
Christian Brabandt <cb@256bit.org>
parents:
13402
diff
changeset
|
3750 { |
66b1d74be322
patch 8.0.1731: characters deleted on completion
Christian Brabandt <cb@256bit.org>
parents:
13402
diff
changeset
|
3751 p = vim_strsave(str); |
66b1d74be322
patch 8.0.1731: characters deleted on completion
Christian Brabandt <cb@256bit.org>
parents:
13402
diff
changeset
|
3752 if (p != NULL) |
66b1d74be322
patch 8.0.1731: characters deleted on completion
Christian Brabandt <cb@256bit.org>
parents:
13402
diff
changeset
|
3753 { |
66b1d74be322
patch 8.0.1731: characters deleted on completion
Christian Brabandt <cb@256bit.org>
parents:
13402
diff
changeset
|
3754 vim_free(compl_first_match->cp_prev->cp_str); |
66b1d74be322
patch 8.0.1731: characters deleted on completion
Christian Brabandt <cb@256bit.org>
parents:
13402
diff
changeset
|
3755 compl_first_match->cp_prev->cp_str = p; |
66b1d74be322
patch 8.0.1731: characters deleted on completion
Christian Brabandt <cb@256bit.org>
parents:
13402
diff
changeset
|
3756 } |
66b1d74be322
patch 8.0.1731: characters deleted on completion
Christian Brabandt <cb@256bit.org>
parents:
13402
diff
changeset
|
3757 } |
657 | 3758 } |
3759 | |
3760 /* | |
659 | 3761 * Append one character to the match leader. May reduce the number of |
3762 * matches. | |
3763 */ | |
3764 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
3765 ins_compl_addfrommatch(void) |
659 | 3766 { |
3767 char_u *p; | |
1869 | 3768 int len = (int)curwin->w_cursor.col - (int)compl_col; |
659 | 3769 int c; |
887 | 3770 compl_T *cp; |
659 | 3771 |
3772 p = compl_shown_match->cp_str; | |
677 | 3773 if ((int)STRLEN(p) <= len) /* the match is too short */ |
887 | 3774 { |
3775 /* When still at the original match use the first entry that matches | |
3776 * the leader. */ | |
3777 if (compl_shown_match->cp_flags & ORIGINAL_TEXT) | |
3778 { | |
3779 p = NULL; | |
3780 for (cp = compl_shown_match->cp_next; cp != NULL | |
3781 && cp != compl_first_match; cp = cp->cp_next) | |
3782 { | |
987 | 3783 if (compl_leader == NULL |
3784 || ins_compl_equal(cp, compl_leader, | |
887 | 3785 (int)STRLEN(compl_leader))) |
3786 { | |
3787 p = cp->cp_str; | |
3788 break; | |
3789 } | |
3790 } | |
3791 if (p == NULL || (int)STRLEN(p) <= len) | |
3792 return; | |
3793 } | |
3794 else | |
3795 return; | |
3796 } | |
659 | 3797 p += len; |
2845 | 3798 c = PTR2CHAR(p); |
659 | 3799 ins_compl_addleader(c); |
3800 } | |
3801 | |
3802 /* | |
7 | 3803 * Prepare for Insert mode completion, or stop it. |
464 | 3804 * Called just after typing a character in Insert mode. |
540 | 3805 * Returns TRUE when the character is not to be inserted; |
7 | 3806 */ |
540 | 3807 static int |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
3808 ins_compl_prep(int c) |
7 | 3809 { |
3810 char_u *ptr; | |
3811 int want_cindent; | |
540 | 3812 int retval = FALSE; |
7 | 3813 |
3814 /* Forget any previous 'special' messages if this is actually | |
3815 * a ^X mode key - bar ^R, in which case we wait to see what it gives us. | |
3816 */ | |
3817 if (c != Ctrl_R && vim_is_ctrl_x_key(c)) | |
3818 edit_submode_extra = NULL; | |
3819 | |
1434 | 3820 /* Ignore end of Select mode mapping and mouse scroll buttons. */ |
2409
0ca06a92adfb
Add support for horizontal scroll wheel. (Bjorn Winckler)
Bram Moolenaar <bram@vim.org>
parents:
2378
diff
changeset
|
3821 if (c == K_SELECT || c == K_MOUSEDOWN || c == K_MOUSEUP |
0ca06a92adfb
Add support for horizontal scroll wheel. (Bjorn Winckler)
Bram Moolenaar <bram@vim.org>
parents:
2378
diff
changeset
|
3822 || c == K_MOUSELEFT || c == K_MOUSERIGHT) |
540 | 3823 return retval; |
7 | 3824 |
665 | 3825 /* Set "compl_get_longest" when finding the first matches. */ |
3826 if (ctrl_x_mode == CTRL_X_NOT_DEFINED_YET | |
13210
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
3827 || (ctrl_x_mode == CTRL_X_NORMAL && !compl_started)) |
665 | 3828 { |
6911 | 3829 compl_get_longest = (strstr((char *)p_cot, "longest") != NULL); |
665 | 3830 compl_used_match = TRUE; |
6911 | 3831 |
3832 } | |
3833 | |
7 | 3834 if (ctrl_x_mode == CTRL_X_NOT_DEFINED_YET) |
3835 { | |
3836 /* | |
3837 * We have just typed CTRL-X and aren't quite sure which CTRL-X mode | |
3838 * it will be yet. Now we decide. | |
3839 */ | |
3840 switch (c) | |
3841 { | |
3842 case Ctrl_E: | |
3843 case Ctrl_Y: | |
3844 ctrl_x_mode = CTRL_X_SCROLL; | |
3845 if (!(State & REPLACE_FLAG)) | |
3846 edit_submode = (char_u *)_(" (insert) Scroll (^E/^Y)"); | |
3847 else | |
3848 edit_submode = (char_u *)_(" (replace) Scroll (^E/^Y)"); | |
3849 edit_submode_pre = NULL; | |
3850 showmode(); | |
3851 break; | |
3852 case Ctrl_L: | |
3853 ctrl_x_mode = CTRL_X_WHOLE_LINE; | |
3854 break; | |
3855 case Ctrl_F: | |
3856 ctrl_x_mode = CTRL_X_FILES; | |
3857 break; | |
3858 case Ctrl_K: | |
3859 ctrl_x_mode = CTRL_X_DICTIONARY; | |
3860 break; | |
3861 case Ctrl_R: | |
3862 /* Simply allow ^R to happen without affecting ^X mode */ | |
3863 break; | |
3864 case Ctrl_T: | |
3865 ctrl_x_mode = CTRL_X_THESAURUS; | |
3866 break; | |
12 | 3867 #ifdef FEAT_COMPL_FUNC |
3868 case Ctrl_U: | |
3869 ctrl_x_mode = CTRL_X_FUNCTION; | |
3870 break; | |
449 | 3871 case Ctrl_O: |
523 | 3872 ctrl_x_mode = CTRL_X_OMNI; |
449 | 3873 break; |
502 | 3874 #endif |
477 | 3875 case 's': |
3876 case Ctrl_S: | |
3877 ctrl_x_mode = CTRL_X_SPELL; | |
744 | 3878 #ifdef FEAT_SPELL |
819 | 3879 ++emsg_off; /* Avoid getting the E756 error twice. */ |
484 | 3880 spell_back_to_badword(); |
819 | 3881 --emsg_off; |
484 | 3882 #endif |
477 | 3883 break; |
7 | 3884 case Ctrl_RSB: |
3885 ctrl_x_mode = CTRL_X_TAGS; | |
3886 break; | |
3887 #ifdef FEAT_FIND_ID | |
3888 case Ctrl_I: | |
3889 case K_S_TAB: | |
3890 ctrl_x_mode = CTRL_X_PATH_PATTERNS; | |
3891 break; | |
3892 case Ctrl_D: | |
3893 ctrl_x_mode = CTRL_X_PATH_DEFINES; | |
3894 break; | |
3895 #endif | |
3896 case Ctrl_V: | |
3897 case Ctrl_Q: | |
3898 ctrl_x_mode = CTRL_X_CMDLINE; | |
3899 break; | |
3900 case Ctrl_P: | |
3901 case Ctrl_N: | |
3902 /* ^X^P means LOCAL expansion if nothing interrupted (eg we | |
3903 * just started ^X mode, or there were enough ^X's to cancel | |
3904 * the previous mode, say ^X^F^X^X^P or ^P^X^X^X^P, see below) | |
3905 * do normal expansion when interrupting a different mode (say | |
3906 * ^X^F^X^P or ^P^X^X^P, see below) | |
3907 * nothing changes if interrupting mode 0, (eg, the flag | |
3908 * doesn't change when going to ADDING mode -- Acevedo */ | |
449 | 3909 if (!(compl_cont_status & CONT_INTRPT)) |
3910 compl_cont_status |= CONT_LOCAL; | |
3911 else if (compl_cont_mode != 0) | |
3912 compl_cont_status &= ~CONT_LOCAL; | |
7 | 3913 /* FALLTHROUGH */ |
3914 default: | |
449 | 3915 /* If we have typed at least 2 ^X's... for modes != 0, we set |
3916 * compl_cont_status = 0 (eg, as if we had just started ^X | |
3917 * mode). | |
3918 * For mode 0, we set "compl_cont_mode" to an impossible | |
3919 * value, in both cases ^X^X can be used to restart the same | |
3920 * mode (avoiding ADDING mode). | |
3921 * Undocumented feature: In a mode != 0 ^X^P and ^X^X^P start | |
3922 * 'complete' and local ^P expansions respectively. | |
3923 * In mode 0 an extra ^X is needed since ^X^P goes to ADDING | |
3924 * mode -- Acevedo */ | |
7 | 3925 if (c == Ctrl_X) |
3926 { | |
449 | 3927 if (compl_cont_mode != 0) |
3928 compl_cont_status = 0; | |
7 | 3929 else |
449 | 3930 compl_cont_mode = CTRL_X_NOT_DEFINED_YET; |
7 | 3931 } |
13210
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
3932 ctrl_x_mode = CTRL_X_NORMAL; |
7 | 3933 edit_submode = NULL; |
3934 showmode(); | |
3935 break; | |
3936 } | |
3937 } | |
13210
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
3938 else if (ctrl_x_mode != CTRL_X_NORMAL) |
7 | 3939 { |
3940 /* We're already in CTRL-X mode, do we stay in it? */ | |
3941 if (!vim_is_ctrl_x_key(c)) | |
3942 { | |
3943 if (ctrl_x_mode == CTRL_X_SCROLL) | |
13210
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
3944 ctrl_x_mode = CTRL_X_NORMAL; |
7 | 3945 else |
3946 ctrl_x_mode = CTRL_X_FINISHED; | |
3947 edit_submode = NULL; | |
3948 } | |
3949 showmode(); | |
3950 } | |
3951 | |
449 | 3952 if (compl_started || ctrl_x_mode == CTRL_X_FINISHED) |
7 | 3953 { |
3954 /* Show error message from attempted keyword completion (probably | |
3955 * 'Pattern not found') until another key is hit, then go back to | |
449 | 3956 * showing what mode we are in. */ |
7 | 3957 showmode(); |
13210
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
3958 if ((ctrl_x_mode == CTRL_X_NORMAL && c != Ctrl_N && c != Ctrl_P |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
3959 && c != Ctrl_R && !ins_compl_pum_key(c)) |
7 | 3960 || ctrl_x_mode == CTRL_X_FINISHED) |
3961 { | |
3962 /* Get here when we have finished typing a sequence of ^N and | |
3963 * ^P or other completion characters in CTRL-X mode. Free up | |
449 | 3964 * memory that was used, and make sure we can redo the insert. */ |
836 | 3965 if (compl_curr_match != NULL || compl_leader != NULL || c == Ctrl_E) |
7 | 3966 { |
3967 /* | |
836 | 3968 * If any of the original typed text has been changed, eg when |
3969 * ignorecase is set, we must add back-spaces to the redo | |
3970 * buffer. We add as few as necessary to delete just the part | |
3971 * of the original text that has changed. | |
3972 * When using the longest match, edited the match or used | |
3973 * CTRL-E then don't use the current match. | |
7 | 3974 */ |
836 | 3975 if (compl_curr_match != NULL && compl_used_match && c != Ctrl_E) |
3976 ptr = compl_curr_match->cp_str; | |
3977 else | |
3095 | 3978 ptr = NULL; |
3979 ins_compl_fixRedoBufForLeader(ptr); | |
7 | 3980 } |
3981 | |
3982 #ifdef FEAT_CINDENT | |
3983 want_cindent = (can_cindent && cindent_on()); | |
3984 #endif | |
3985 /* | |
3986 * When completing whole lines: fix indent for 'cindent'. | |
3987 * Otherwise, break line if it's too long. | |
3988 */ | |
449 | 3989 if (compl_cont_mode == CTRL_X_WHOLE_LINE) |
7 | 3990 { |
3991 #ifdef FEAT_CINDENT | |
3992 /* re-indent the current line */ | |
3993 if (want_cindent) | |
3994 { | |
3995 do_c_expr_indent(); | |
3996 want_cindent = FALSE; /* don't do it again */ | |
3997 } | |
3998 #endif | |
3999 } | |
4000 else | |
4001 { | |
1073 | 4002 int prev_col = curwin->w_cursor.col; |
4003 | |
7 | 4004 /* put the cursor on the last char, for 'tw' formatting */ |
1073 | 4005 if (prev_col > 0) |
4006 dec_cursor(); | |
10289
af5b6efad23f
commit https://github.com/vim/vim/commit/869e35270ecffd9024958880cb03f6f0bb01ea93
Christian Brabandt <cb@256bit.org>
parents:
10277
diff
changeset
|
4007 /* only format when something was inserted */ |
10468
251554157361
commit https://github.com/vim/vim/commit/73fd4988866c3adc15b5d093efdf5e8cf70d093d
Christian Brabandt <cb@256bit.org>
parents:
10359
diff
changeset
|
4008 if (!arrow_used && !ins_need_undo && c != Ctrl_E) |
7 | 4009 insertchar(NUL, 0, -1); |
1073 | 4010 if (prev_col > 0 |
4011 && ml_get_curline()[curwin->w_cursor.col] != NUL) | |
4012 inc_cursor(); | |
7 | 4013 } |
4014 | |
816 | 4015 /* If the popup menu is displayed pressing CTRL-Y means accepting |
825 | 4016 * the selection without inserting anything. When |
4017 * compl_enter_selects is set the Enter key does the same. */ | |
4018 if ((c == Ctrl_Y || (compl_enter_selects | |
4019 && (c == CAR || c == K_KENTER || c == NL))) | |
4020 && pum_visible()) | |
540 | 4021 retval = TRUE; |
4022 | |
9742
0b0b9864c811
commit https://github.com/vim/vim/commit/472472898ab71ac80a86fedc37f8eb91461788dd
Christian Brabandt <cb@256bit.org>
parents:
9649
diff
changeset
|
4023 /* CTRL-E means completion is Ended, go back to the typed text. |
0b0b9864c811
commit https://github.com/vim/vim/commit/472472898ab71ac80a86fedc37f8eb91461788dd
Christian Brabandt <cb@256bit.org>
parents:
9649
diff
changeset
|
4024 * but only do this, if the Popup is still visible */ |
9826
f17ba1c9d209
commit https://github.com/vim/vim/commit/c9fb77c69244870a97384152f20845665c19fe39
Christian Brabandt <cb@256bit.org>
parents:
9742
diff
changeset
|
4025 if (c == Ctrl_E) |
816 | 4026 { |
4027 ins_compl_delete(); | |
4028 if (compl_leader != NULL) | |
1782 | 4029 ins_bytes(compl_leader + ins_compl_len()); |
816 | 4030 else if (compl_first_match != NULL) |
1782 | 4031 ins_bytes(compl_orig_text + ins_compl_len()); |
816 | 4032 retval = TRUE; |
4033 } | |
4034 | |
1698 | 4035 auto_format(FALSE, TRUE); |
4036 | |
7 | 4037 ins_compl_free(); |
449 | 4038 compl_started = FALSE; |
4039 compl_matches = 0; | |
6056 | 4040 if (!shortmess(SHM_COMPLETIONMENU)) |
4041 msg_clr_cmdline(); /* necessary for "noshowmode" */ | |
13210
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
4042 ctrl_x_mode = CTRL_X_NORMAL; |
825 | 4043 compl_enter_selects = FALSE; |
7 | 4044 if (edit_submode != NULL) |
4045 { | |
4046 edit_submode = NULL; | |
4047 showmode(); | |
4048 } | |
4049 | |
7141
4e8f07fc7ca3
commit https://github.com/vim/vim/commit/5f1fea28f5bc573e2430773c49e95ae1f9cc2a25
Christian Brabandt <cb@256bit.org>
parents:
7074
diff
changeset
|
4050 #ifdef FEAT_CMDWIN |
4e8f07fc7ca3
commit https://github.com/vim/vim/commit/5f1fea28f5bc573e2430773c49e95ae1f9cc2a25
Christian Brabandt <cb@256bit.org>
parents:
7074
diff
changeset
|
4051 if (c == Ctrl_C && cmdwin_type != 0) |
4e8f07fc7ca3
commit https://github.com/vim/vim/commit/5f1fea28f5bc573e2430773c49e95ae1f9cc2a25
Christian Brabandt <cb@256bit.org>
parents:
7074
diff
changeset
|
4052 /* Avoid the popup menu remains displayed when leaving the |
4e8f07fc7ca3
commit https://github.com/vim/vim/commit/5f1fea28f5bc573e2430773c49e95ae1f9cc2a25
Christian Brabandt <cb@256bit.org>
parents:
7074
diff
changeset
|
4053 * command line window. */ |
4e8f07fc7ca3
commit https://github.com/vim/vim/commit/5f1fea28f5bc573e2430773c49e95ae1f9cc2a25
Christian Brabandt <cb@256bit.org>
parents:
7074
diff
changeset
|
4054 update_screen(0); |
4e8f07fc7ca3
commit https://github.com/vim/vim/commit/5f1fea28f5bc573e2430773c49e95ae1f9cc2a25
Christian Brabandt <cb@256bit.org>
parents:
7074
diff
changeset
|
4055 #endif |
7 | 4056 #ifdef FEAT_CINDENT |
4057 /* | |
4058 * Indent now if a key was typed that is in 'cinkeys'. | |
4059 */ | |
4060 if (want_cindent && in_cinkeys(KEY_COMPLETE, ' ', inindent(0))) | |
4061 do_c_expr_indent(); | |
4062 #endif | |
3676 | 4063 /* Trigger the CompleteDone event to give scripts a chance to act |
4064 * upon the completion. */ | |
14485
c71d65c3672f
patch 8.1.0256: using setline() in TextChangedI splits undo
Christian Brabandt <cb@256bit.org>
parents:
14465
diff
changeset
|
4065 ins_apply_autocmds(EVENT_COMPLETEDONE); |
13380
69517d67421f
patch 8.0.1564: too many #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
13244
diff
changeset
|
4066 } |
69517d67421f
patch 8.0.1564: too many #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
13244
diff
changeset
|
4067 } |
4120 | 4068 else if (ctrl_x_mode == CTRL_X_LOCAL_MSG) |
4069 /* Trigger the CompleteDone event to give scripts a chance to act | |
4070 * upon the (possibly failed) completion. */ | |
14485
c71d65c3672f
patch 8.1.0256: using setline() in TextChangedI splits undo
Christian Brabandt <cb@256bit.org>
parents:
14465
diff
changeset
|
4071 ins_apply_autocmds(EVENT_COMPLETEDONE); |
7 | 4072 |
4073 /* reset continue_* if we left expansion-mode, if we stay they'll be | |
4074 * (re)set properly in ins_complete() */ | |
4075 if (!vim_is_ctrl_x_key(c)) | |
4076 { | |
449 | 4077 compl_cont_status = 0; |
4078 compl_cont_mode = 0; | |
7 | 4079 } |
540 | 4080 |
4081 return retval; | |
7 | 4082 } |
4083 | |
4084 /* | |
3095 | 4085 * Fix the redo buffer for the completion leader replacing some of the typed |
4086 * text. This inserts backspaces and appends the changed text. | |
4087 * "ptr" is the known leader text or NUL. | |
4088 */ | |
4089 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
4090 ins_compl_fixRedoBufForLeader(char_u *ptr_arg) |
3095 | 4091 { |
4092 int len; | |
4093 char_u *p; | |
4094 char_u *ptr = ptr_arg; | |
4095 | |
4096 if (ptr == NULL) | |
4097 { | |
4098 if (compl_leader != NULL) | |
4099 ptr = compl_leader; | |
4100 else | |
4101 return; /* nothing to do */ | |
4102 } | |
4103 if (compl_orig_text != NULL) | |
4104 { | |
4105 p = compl_orig_text; | |
4106 for (len = 0; p[len] != NUL && p[len] == ptr[len]; ++len) | |
4107 ; | |
4108 if (len > 0) | |
4109 len -= (*mb_head_off)(p, p + len); | |
11127
506f5d8b7d8b
patch 8.0.0451: some macros are in lower case
Christian Brabandt <cb@256bit.org>
parents:
11121
diff
changeset
|
4110 for (p += len; *p != NUL; MB_PTR_ADV(p)) |
3095 | 4111 AppendCharToRedobuff(K_BS); |
4112 } | |
4113 else | |
4114 len = 0; | |
4115 if (ptr != NULL) | |
4116 AppendToRedobuffLit(ptr + len, -1); | |
4117 } | |
4118 | |
4119 /* | |
7 | 4120 * Loops through the list of windows, loaded-buffers or non-loaded-buffers |
4121 * (depending on flag) starting from buf and looking for a non-scanned | |
4122 * buffer (other than curbuf). curbuf is special, if it is called with | |
4123 * buf=curbuf then it has to be the first call for a given flag/expansion. | |
4124 * | |
4125 * Returns the buffer to scan, if any, otherwise returns curbuf -- Acevedo | |
4126 */ | |
4127 static buf_T * | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
4128 ins_compl_next_buf(buf_T *buf, int flag) |
7 | 4129 { |
4130 static win_T *wp; | |
4131 | |
4132 if (flag == 'w') /* just windows */ | |
4133 { | |
4134 if (buf == curbuf) /* first call for this flag/expansion */ | |
4135 wp = curwin; | |
383 | 4136 while ((wp = (wp->w_next != NULL ? wp->w_next : firstwin)) != curwin |
7 | 4137 && wp->w_buffer->b_scanned) |
4138 ; | |
4139 buf = wp->w_buffer; | |
4140 } | |
4141 else | |
4142 /* 'b' (just loaded buffers), 'u' (just non-loaded buffers) or 'U' | |
4143 * (unlisted buffers) | |
4144 * When completing whole lines skip unloaded buffers. */ | |
383 | 4145 while ((buf = (buf->b_next != NULL ? buf->b_next : firstbuf)) != curbuf |
7 | 4146 && ((flag == 'U' |
4147 ? buf->b_p_bl | |
4148 : (!buf->b_p_bl | |
4149 || (buf->b_ml.ml_mfp == NULL) != (flag == 'u'))) | |
667 | 4150 || buf->b_scanned)) |
7 | 4151 ; |
4152 return buf; | |
4153 } | |
4154 | |
12 | 4155 #ifdef FEAT_COMPL_FUNC |
4156 /* | |
523 | 4157 * Execute user defined complete function 'completefunc' or 'omnifunc', and |
502 | 4158 * get matches in "matches". |
12 | 4159 */ |
659 | 4160 static void |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
4161 expand_by_function( |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
4162 int type, /* CTRL_X_OMNI or CTRL_X_FUNCTION */ |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
4163 char_u *base) |
12 | 4164 { |
3078 | 4165 list_T *matchlist = NULL; |
4166 dict_T *matchdict = NULL; | |
14071
c1fcfafa8d1a
patch 8.1.0053: first argument of 'completefunc' has inconsistent type
Christian Brabandt <cb@256bit.org>
parents:
14045
diff
changeset
|
4167 typval_T args[3]; |
502 | 4168 char_u *funcname; |
4169 pos_T pos; | |
2631 | 4170 win_T *curwin_save; |
4171 buf_T *curbuf_save; | |
3078 | 4172 typval_T rettv; |
15377
88b0a490816e
patch 8.1.0696: when test_edit fails 'insertmode' may not be reset
Bram Moolenaar <Bram@vim.org>
parents:
15349
diff
changeset
|
4173 int save_State = State; |
502 | 4174 |
4175 funcname = (type == CTRL_X_FUNCTION) ? curbuf->b_p_cfu : curbuf->b_p_ofu; | |
4176 if (*funcname == NUL) | |
659 | 4177 return; |
452 | 4178 |
4179 /* Call 'completefunc' to obtain the list of matches. */ | |
14071
c1fcfafa8d1a
patch 8.1.0053: first argument of 'completefunc' has inconsistent type
Christian Brabandt <cb@256bit.org>
parents:
14045
diff
changeset
|
4180 args[0].v_type = VAR_NUMBER; |
c1fcfafa8d1a
patch 8.1.0053: first argument of 'completefunc' has inconsistent type
Christian Brabandt <cb@256bit.org>
parents:
14045
diff
changeset
|
4181 args[0].vval.v_number = 0; |
c1fcfafa8d1a
patch 8.1.0053: first argument of 'completefunc' has inconsistent type
Christian Brabandt <cb@256bit.org>
parents:
14045
diff
changeset
|
4182 args[1].v_type = VAR_STRING; |
c1fcfafa8d1a
patch 8.1.0053: first argument of 'completefunc' has inconsistent type
Christian Brabandt <cb@256bit.org>
parents:
14045
diff
changeset
|
4183 args[1].vval.v_string = base != NULL ? base : (char_u *)""; |
c1fcfafa8d1a
patch 8.1.0053: first argument of 'completefunc' has inconsistent type
Christian Brabandt <cb@256bit.org>
parents:
14045
diff
changeset
|
4184 args[2].v_type = VAR_UNKNOWN; |
502 | 4185 |
4186 pos = curwin->w_cursor; | |
2631 | 4187 curwin_save = curwin; |
4188 curbuf_save = curbuf; | |
3078 | 4189 |
4190 /* Call a function, which returns a list or dict. */ | |
14439
e4c553e9132b
patch 8.1.0233: "safe" argument of call_vim_function() is always FALSE
Christian Brabandt <cb@256bit.org>
parents:
14424
diff
changeset
|
4191 if (call_vim_function(funcname, 2, args, &rettv) == OK) |
3078 | 4192 { |
4193 switch (rettv.v_type) | |
4194 { | |
4195 case VAR_LIST: | |
4196 matchlist = rettv.vval.v_list; | |
4197 break; | |
4198 case VAR_DICT: | |
4199 matchdict = rettv.vval.v_dict; | |
4200 break; | |
15416
5f8ddd2a7b92
patch 8.1.0716: get warning message when 'completefunc' returns nothing
Bram Moolenaar <Bram@vim.org>
parents:
15400
diff
changeset
|
4201 case VAR_SPECIAL: |
5f8ddd2a7b92
patch 8.1.0716: get warning message when 'completefunc' returns nothing
Bram Moolenaar <Bram@vim.org>
parents:
15400
diff
changeset
|
4202 if (rettv.vval.v_number == VVAL_NONE) |
5f8ddd2a7b92
patch 8.1.0716: get warning message when 'completefunc' returns nothing
Bram Moolenaar <Bram@vim.org>
parents:
15400
diff
changeset
|
4203 compl_opt_suppress_empty = TRUE; |
5f8ddd2a7b92
patch 8.1.0716: get warning message when 'completefunc' returns nothing
Bram Moolenaar <Bram@vim.org>
parents:
15400
diff
changeset
|
4204 // FALLTHROUGH |
3078 | 4205 default: |
15416
5f8ddd2a7b92
patch 8.1.0716: get warning message when 'completefunc' returns nothing
Bram Moolenaar <Bram@vim.org>
parents:
15400
diff
changeset
|
4206 // TODO: Give error message? |
3078 | 4207 clear_tv(&rettv); |
4208 break; | |
4209 } | |
4210 } | |
4211 | |
2631 | 4212 if (curwin_save != curwin || curbuf_save != curbuf) |
4213 { | |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
15440
diff
changeset
|
4214 emsg(_(e_complwin)); |
2631 | 4215 goto theend; |
4216 } | |
502 | 4217 curwin->w_cursor = pos; /* restore the cursor position */ |
6209 | 4218 validate_cursor(); |
11121
778c10516955
patch 8.0.0448: some macros are in lower case
Christian Brabandt <cb@256bit.org>
parents:
11105
diff
changeset
|
4219 if (!EQUAL_POS(curwin->w_cursor, pos)) |
2631 | 4220 { |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
15440
diff
changeset
|
4221 emsg(_(e_compldel)); |
2631 | 4222 goto theend; |
4223 } | |
3078 | 4224 |
2631 | 4225 if (matchlist != NULL) |
4226 ins_compl_add_list(matchlist); | |
3078 | 4227 else if (matchdict != NULL) |
4228 ins_compl_add_dict(matchdict); | |
2631 | 4229 |
4230 theend: | |
15377
88b0a490816e
patch 8.1.0696: when test_edit fails 'insertmode' may not be reset
Bram Moolenaar <Bram@vim.org>
parents:
15349
diff
changeset
|
4231 // Restore State, it might have been changed. |
88b0a490816e
patch 8.1.0696: when test_edit fails 'insertmode' may not be reset
Bram Moolenaar <Bram@vim.org>
parents:
15349
diff
changeset
|
4232 State = save_State; |
88b0a490816e
patch 8.1.0696: when test_edit fails 'insertmode' may not be reset
Bram Moolenaar <Bram@vim.org>
parents:
15349
diff
changeset
|
4233 |
3078 | 4234 if (matchdict != NULL) |
4235 dict_unref(matchdict); | |
2631 | 4236 if (matchlist != NULL) |
4237 list_unref(matchlist); | |
724 | 4238 } |
4239 #endif /* FEAT_COMPL_FUNC */ | |
4240 | |
786 | 4241 #if defined(FEAT_COMPL_FUNC) || defined(FEAT_EVAL) || defined(PROTO) |
724 | 4242 /* |
4243 * Add completions from a list. | |
4244 */ | |
4245 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
4246 ins_compl_add_list(list_T *list) |
724 | 4247 { |
4248 listitem_T *li; | |
4249 int dir = compl_direction; | |
4250 | |
659 | 4251 /* Go through the List with matches and add each of them. */ |
724 | 4252 for (li = list->lv_first; li != NULL; li = li->li_next) |
452 | 4253 { |
786 | 4254 if (ins_compl_add_tv(&li->li_tv, dir) == OK) |
4255 /* if dir was BACKWARD then honor it just once */ | |
4256 dir = FORWARD; | |
648 | 4257 else if (did_emsg) |
4258 break; | |
452 | 4259 } |
724 | 4260 } |
786 | 4261 |
4262 /* | |
3078 | 4263 * Add completions from a dict. |
4264 */ | |
4265 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
4266 ins_compl_add_dict(dict_T *dict) |
3078 | 4267 { |
3263 | 4268 dictitem_T *di_refresh; |
4269 dictitem_T *di_words; | |
3078 | 4270 |
4271 /* Check for optional "refresh" item. */ | |
4272 compl_opt_refresh_always = FALSE; | |
3263 | 4273 di_refresh = dict_find(dict, (char_u *)"refresh", 7); |
4274 if (di_refresh != NULL && di_refresh->di_tv.v_type == VAR_STRING) | |
4275 { | |
4276 char_u *v = di_refresh->di_tv.vval.v_string; | |
3078 | 4277 |
4278 if (v != NULL && STRCMP(v, (char_u *)"always") == 0) | |
4279 compl_opt_refresh_always = TRUE; | |
4280 } | |
4281 | |
4282 /* Add completions from a "words" list. */ | |
3263 | 4283 di_words = dict_find(dict, (char_u *)"words", 5); |
4284 if (di_words != NULL && di_words->di_tv.v_type == VAR_LIST) | |
4285 ins_compl_add_list(di_words->di_tv.vval.v_list); | |
3078 | 4286 } |
4287 | |
4288 /* | |
786 | 4289 * Add a match to the list of matches from a typeval_T. |
4290 * If the given string is already in the list of completions, then return | |
4291 * NOTDONE, otherwise add it to the list and return OK. If there is an error, | |
4292 * maybe because alloc() returns NULL, then FAIL is returned. | |
4293 */ | |
4294 int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
4295 ins_compl_add_tv(typval_T *tv, int dir) |
786 | 4296 { |
4297 char_u *word; | |
867 | 4298 int icase = FALSE; |
944 | 4299 int adup = FALSE; |
2632 | 4300 int aempty = FALSE; |
786 | 4301 char_u *(cptext[CPT_COUNT]); |
4302 | |
4303 if (tv->v_type == VAR_DICT && tv->vval.v_dict != NULL) | |
4304 { | |
15146
7903dce131d4
patch 8.1.0583: using illogical name for get_dict_number()/get_dict_string()
Bram Moolenaar <Bram@vim.org>
parents:
15138
diff
changeset
|
4305 word = dict_get_string(tv->vval.v_dict, (char_u *)"word", FALSE); |
7903dce131d4
patch 8.1.0583: using illogical name for get_dict_number()/get_dict_string()
Bram Moolenaar <Bram@vim.org>
parents:
15138
diff
changeset
|
4306 cptext[CPT_ABBR] = dict_get_string(tv->vval.v_dict, |
786 | 4307 (char_u *)"abbr", FALSE); |
15146
7903dce131d4
patch 8.1.0583: using illogical name for get_dict_number()/get_dict_string()
Bram Moolenaar <Bram@vim.org>
parents:
15138
diff
changeset
|
4308 cptext[CPT_MENU] = dict_get_string(tv->vval.v_dict, |
786 | 4309 (char_u *)"menu", FALSE); |
15146
7903dce131d4
patch 8.1.0583: using illogical name for get_dict_number()/get_dict_string()
Bram Moolenaar <Bram@vim.org>
parents:
15138
diff
changeset
|
4310 cptext[CPT_KIND] = dict_get_string(tv->vval.v_dict, |
786 | 4311 (char_u *)"kind", FALSE); |
15146
7903dce131d4
patch 8.1.0583: using illogical name for get_dict_number()/get_dict_string()
Bram Moolenaar <Bram@vim.org>
parents:
15138
diff
changeset
|
4312 cptext[CPT_INFO] = dict_get_string(tv->vval.v_dict, |
786 | 4313 (char_u *)"info", FALSE); |
15146
7903dce131d4
patch 8.1.0583: using illogical name for get_dict_number()/get_dict_string()
Bram Moolenaar <Bram@vim.org>
parents:
15138
diff
changeset
|
4314 cptext[CPT_USER_DATA] = dict_get_string(tv->vval.v_dict, |
13238
e0dcfd3dbb52
patch 8.0.1493: completion items cannot be annotated
Christian Brabandt <cb@256bit.org>
parents:
13215
diff
changeset
|
4315 (char_u *)"user_data", FALSE); |
15146
7903dce131d4
patch 8.1.0583: using illogical name for get_dict_number()/get_dict_string()
Bram Moolenaar <Bram@vim.org>
parents:
15138
diff
changeset
|
4316 if (dict_get_string(tv->vval.v_dict, (char_u *)"icase", FALSE) != NULL) |
7903dce131d4
patch 8.1.0583: using illogical name for get_dict_number()/get_dict_string()
Bram Moolenaar <Bram@vim.org>
parents:
15138
diff
changeset
|
4317 icase = dict_get_number(tv->vval.v_dict, (char_u *)"icase"); |
7903dce131d4
patch 8.1.0583: using illogical name for get_dict_number()/get_dict_string()
Bram Moolenaar <Bram@vim.org>
parents:
15138
diff
changeset
|
4318 if (dict_get_string(tv->vval.v_dict, (char_u *)"dup", FALSE) != NULL) |
7903dce131d4
patch 8.1.0583: using illogical name for get_dict_number()/get_dict_string()
Bram Moolenaar <Bram@vim.org>
parents:
15138
diff
changeset
|
4319 adup = dict_get_number(tv->vval.v_dict, (char_u *)"dup"); |
7903dce131d4
patch 8.1.0583: using illogical name for get_dict_number()/get_dict_string()
Bram Moolenaar <Bram@vim.org>
parents:
15138
diff
changeset
|
4320 if (dict_get_string(tv->vval.v_dict, (char_u *)"empty", FALSE) != NULL) |
7903dce131d4
patch 8.1.0583: using illogical name for get_dict_number()/get_dict_string()
Bram Moolenaar <Bram@vim.org>
parents:
15138
diff
changeset
|
4321 aempty = dict_get_number(tv->vval.v_dict, (char_u *)"empty"); |
786 | 4322 } |
4323 else | |
4324 { | |
15211
de63593896b3
patch 8.1.0615: get_tv function names are not consistent
Bram Moolenaar <Bram@vim.org>
parents:
15146
diff
changeset
|
4325 word = tv_get_string_chk(tv); |
786 | 4326 vim_memset(cptext, 0, sizeof(cptext)); |
4327 } | |
2632 | 4328 if (word == NULL || (!aempty && *word == NUL)) |
786 | 4329 return FAIL; |
944 | 4330 return ins_compl_add(word, -1, icase, NULL, cptext, dir, 0, adup); |
786 | 4331 } |
724 | 4332 #endif |
12 | 4333 |
449 | 4334 /* |
4335 * Get the next expansion(s), using "compl_pattern". | |
659 | 4336 * The search starts at position "ini" in curbuf and in the direction |
4337 * compl_direction. | |
667 | 4338 * When "compl_started" is FALSE start at that position, otherwise continue |
4339 * where we stopped searching before. | |
449 | 4340 * This may return before finding all the matches. |
4341 * Return the total number of matches or -1 if still unknown -- Acevedo | |
7 | 4342 */ |
4343 static int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
4344 ins_compl_get_exp(pos_T *ini) |
7 | 4345 { |
4346 static pos_T first_match_pos; | |
4347 static pos_T last_match_pos; | |
4348 static char_u *e_cpt = (char_u *)""; /* curr. entry in 'complete' */ | |
449 | 4349 static int found_all = FALSE; /* Found all matches of a |
4350 certain type. */ | |
4351 static buf_T *ins_buf = NULL; /* buffer being scanned */ | |
7 | 4352 |
464 | 4353 pos_T *pos; |
4354 char_u **matches; | |
4355 int save_p_scs; | |
4356 int save_p_ws; | |
4357 int save_p_ic; | |
4358 int i; | |
4359 int num_matches; | |
4360 int len; | |
4361 int found_new_match; | |
4362 int type = ctrl_x_mode; | |
4363 char_u *ptr; | |
4364 char_u *dict = NULL; | |
4365 int dict_f = 0; | |
5625 | 4366 int set_match_pos; |
7 | 4367 |
449 | 4368 if (!compl_started) |
7 | 4369 { |
9649
fd9727ae3c49
commit https://github.com/vim/vim/commit/2932359000b2f918d5fade79ea4d124d5943cd07
Christian Brabandt <cb@256bit.org>
parents:
9467
diff
changeset
|
4370 FOR_ALL_BUFFERS(ins_buf) |
7 | 4371 ins_buf->b_scanned = 0; |
4372 found_all = FALSE; | |
4373 ins_buf = curbuf; | |
449 | 4374 e_cpt = (compl_cont_status & CONT_LOCAL) |
12 | 4375 ? (char_u *)"." : curbuf->b_p_cpt; |
7 | 4376 last_match_pos = first_match_pos = *ini; |
4377 } | |
14457
893ac612569f
patch 8.1.0242: Insert mode completion may use an invalid buffer pointer
Christian Brabandt <cb@256bit.org>
parents:
14439
diff
changeset
|
4378 else if (ins_buf != curbuf && !buf_valid(ins_buf)) |
893ac612569f
patch 8.1.0242: Insert mode completion may use an invalid buffer pointer
Christian Brabandt <cb@256bit.org>
parents:
14439
diff
changeset
|
4379 ins_buf = curbuf; // In case the buffer was wiped out. |
7 | 4380 |
11424
328a9ee98fb2
patch 8.0.0596: crash when complete() called after complete_add()
Christian Brabandt <cb@256bit.org>
parents:
11317
diff
changeset
|
4381 compl_old_match = compl_curr_match; /* remember the last current match */ |
659 | 4382 pos = (compl_direction == FORWARD) ? &last_match_pos : &first_match_pos; |
14457
893ac612569f
patch 8.1.0242: Insert mode completion may use an invalid buffer pointer
Christian Brabandt <cb@256bit.org>
parents:
14439
diff
changeset
|
4383 |
893ac612569f
patch 8.1.0242: Insert mode completion may use an invalid buffer pointer
Christian Brabandt <cb@256bit.org>
parents:
14439
diff
changeset
|
4384 /* |
893ac612569f
patch 8.1.0242: Insert mode completion may use an invalid buffer pointer
Christian Brabandt <cb@256bit.org>
parents:
14439
diff
changeset
|
4385 * For ^N/^P loop over all the flags/windows/buffers in 'complete'. |
893ac612569f
patch 8.1.0242: Insert mode completion may use an invalid buffer pointer
Christian Brabandt <cb@256bit.org>
parents:
14439
diff
changeset
|
4386 */ |
7 | 4387 for (;;) |
4388 { | |
4389 found_new_match = FAIL; | |
5625 | 4390 set_match_pos = FALSE; |
7 | 4391 |
449 | 4392 /* For ^N/^P pick a new entry from e_cpt if compl_started is off, |
7 | 4393 * or if found_all says this entry is done. For ^X^L only use the |
4394 * entries from 'complete' that look in loaded buffers. */ | |
13210
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
4395 if ((ctrl_x_mode == CTRL_X_NORMAL |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
4396 || CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)) |
449 | 4397 && (!compl_started || found_all)) |
7 | 4398 { |
4399 found_all = FALSE; | |
4400 while (*e_cpt == ',' || *e_cpt == ' ') | |
4401 e_cpt++; | |
4402 if (*e_cpt == '.' && !curbuf->b_scanned) | |
4403 { | |
4404 ins_buf = curbuf; | |
4405 first_match_pos = *ini; | |
11573
c8fd52807897
patch 8.0.0669: CTRL-N at start of the buffer does not work correctly
Christian Brabandt <cb@256bit.org>
parents:
11521
diff
changeset
|
4406 /* Move the cursor back one character so that ^N can match the |
c8fd52807897
patch 8.0.0669: CTRL-N at start of the buffer does not work correctly
Christian Brabandt <cb@256bit.org>
parents:
11521
diff
changeset
|
4407 * word immediately after the cursor. */ |
13210
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
4408 if (ctrl_x_mode == CTRL_X_NORMAL && dec(&first_match_pos) < 0) |
11573
c8fd52807897
patch 8.0.0669: CTRL-N at start of the buffer does not work correctly
Christian Brabandt <cb@256bit.org>
parents:
11521
diff
changeset
|
4409 { |
c8fd52807897
patch 8.0.0669: CTRL-N at start of the buffer does not work correctly
Christian Brabandt <cb@256bit.org>
parents:
11521
diff
changeset
|
4410 /* Move the cursor to after the last character in the |
c8fd52807897
patch 8.0.0669: CTRL-N at start of the buffer does not work correctly
Christian Brabandt <cb@256bit.org>
parents:
11521
diff
changeset
|
4411 * buffer, so that word at start of buffer is found |
c8fd52807897
patch 8.0.0669: CTRL-N at start of the buffer does not work correctly
Christian Brabandt <cb@256bit.org>
parents:
11521
diff
changeset
|
4412 * correctly. */ |
c8fd52807897
patch 8.0.0669: CTRL-N at start of the buffer does not work correctly
Christian Brabandt <cb@256bit.org>
parents:
11521
diff
changeset
|
4413 first_match_pos.lnum = ins_buf->b_ml.ml_line_count; |
c8fd52807897
patch 8.0.0669: CTRL-N at start of the buffer does not work correctly
Christian Brabandt <cb@256bit.org>
parents:
11521
diff
changeset
|
4414 first_match_pos.col = |
c8fd52807897
patch 8.0.0669: CTRL-N at start of the buffer does not work correctly
Christian Brabandt <cb@256bit.org>
parents:
11521
diff
changeset
|
4415 (colnr_T)STRLEN(ml_get(first_match_pos.lnum)); |
c8fd52807897
patch 8.0.0669: CTRL-N at start of the buffer does not work correctly
Christian Brabandt <cb@256bit.org>
parents:
11521
diff
changeset
|
4416 } |
7 | 4417 last_match_pos = first_match_pos; |
4418 type = 0; | |
5625 | 4419 |
4420 /* Remember the first match so that the loop stops when we | |
4421 * wrap and come back there a second time. */ | |
4422 set_match_pos = TRUE; | |
7 | 4423 } |
4424 else if (vim_strchr((char_u *)"buwU", *e_cpt) != NULL | |
4425 && (ins_buf = ins_compl_next_buf(ins_buf, *e_cpt)) != curbuf) | |
4426 { | |
4427 /* Scan a buffer, but not the current one. */ | |
4428 if (ins_buf->b_ml.ml_mfp != NULL) /* loaded buffer */ | |
4429 { | |
449 | 4430 compl_started = TRUE; |
7 | 4431 first_match_pos.col = last_match_pos.col = 0; |
4432 first_match_pos.lnum = ins_buf->b_ml.ml_line_count + 1; | |
4433 last_match_pos.lnum = 0; | |
4434 type = 0; | |
4435 } | |
4436 else /* unloaded buffer, scan like dictionary */ | |
4437 { | |
4438 found_all = TRUE; | |
4439 if (ins_buf->b_fname == NULL) | |
4440 continue; | |
4441 type = CTRL_X_DICTIONARY; | |
4442 dict = ins_buf->b_fname; | |
4443 dict_f = DICT_EXACT; | |
4444 } | |
274 | 4445 vim_snprintf((char *)IObuff, IOSIZE, _("Scanning: %s"), |
7 | 4446 ins_buf->b_fname == NULL |
4447 ? buf_spname(ins_buf) | |
4448 : ins_buf->b_sfname == NULL | |
3850 | 4449 ? ins_buf->b_fname |
4450 : ins_buf->b_sfname); | |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15521
diff
changeset
|
4451 (void)msg_trunc_attr((char *)IObuff, TRUE, HL_ATTR(HLF_R)); |
7 | 4452 } |
4453 else if (*e_cpt == NUL) | |
4454 break; | |
4455 else | |
4456 { | |
6657 | 4457 if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)) |
7 | 4458 type = -1; |
4459 else if (*e_cpt == 'k' || *e_cpt == 's') | |
4460 { | |
4461 if (*e_cpt == 'k') | |
4462 type = CTRL_X_DICTIONARY; | |
4463 else | |
4464 type = CTRL_X_THESAURUS; | |
4465 if (*++e_cpt != ',' && *e_cpt != NUL) | |
4466 { | |
4467 dict = e_cpt; | |
4468 dict_f = DICT_FIRST; | |
4469 } | |
4470 } | |
4471 #ifdef FEAT_FIND_ID | |
4472 else if (*e_cpt == 'i') | |
4473 type = CTRL_X_PATH_PATTERNS; | |
4474 else if (*e_cpt == 'd') | |
4475 type = CTRL_X_PATH_DEFINES; | |
4476 #endif | |
4477 else if (*e_cpt == ']' || *e_cpt == 't') | |
4478 { | |
4479 type = CTRL_X_TAGS; | |
1872 | 4480 vim_snprintf((char *)IObuff, IOSIZE, _("Scanning tags.")); |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15521
diff
changeset
|
4481 (void)msg_trunc_attr((char *)IObuff, TRUE, HL_ATTR(HLF_R)); |
7 | 4482 } |
4483 else | |
4484 type = -1; | |
4485 | |
4486 /* in any case e_cpt is advanced to the next entry */ | |
4487 (void)copy_option_part(&e_cpt, IObuff, IOSIZE, ","); | |
4488 | |
4489 found_all = TRUE; | |
4490 if (type == -1) | |
4491 continue; | |
4492 } | |
4493 } | |
4494 | |
11424
328a9ee98fb2
patch 8.0.0596: crash when complete() called after complete_add()
Christian Brabandt <cb@256bit.org>
parents:
11317
diff
changeset
|
4495 /* If complete() was called then compl_pattern has been reset. The |
328a9ee98fb2
patch 8.0.0596: crash when complete() called after complete_add()
Christian Brabandt <cb@256bit.org>
parents:
11317
diff
changeset
|
4496 * following won't work then, bail out. */ |
328a9ee98fb2
patch 8.0.0596: crash when complete() called after complete_add()
Christian Brabandt <cb@256bit.org>
parents:
11317
diff
changeset
|
4497 if (compl_pattern == NULL) |
328a9ee98fb2
patch 8.0.0596: crash when complete() called after complete_add()
Christian Brabandt <cb@256bit.org>
parents:
11317
diff
changeset
|
4498 break; |
328a9ee98fb2
patch 8.0.0596: crash when complete() called after complete_add()
Christian Brabandt <cb@256bit.org>
parents:
11317
diff
changeset
|
4499 |
7 | 4500 switch (type) |
4501 { | |
4502 case -1: | |
4503 break; | |
4504 #ifdef FEAT_FIND_ID | |
4505 case CTRL_X_PATH_PATTERNS: | |
4506 case CTRL_X_PATH_DEFINES: | |
659 | 4507 find_pattern_in_path(compl_pattern, compl_direction, |
449 | 4508 (int)STRLEN(compl_pattern), FALSE, FALSE, |
7 | 4509 (type == CTRL_X_PATH_DEFINES |
449 | 4510 && !(compl_cont_status & CONT_SOL)) |
7 | 4511 ? FIND_DEFINE : FIND_ANY, 1L, ACTION_EXPAND, |
4512 (linenr_T)1, (linenr_T)MAXLNUM); | |
4513 break; | |
4514 #endif | |
4515 | |
4516 case CTRL_X_DICTIONARY: | |
4517 case CTRL_X_THESAURUS: | |
4518 ins_compl_dictionaries( | |
703 | 4519 dict != NULL ? dict |
7 | 4520 : (type == CTRL_X_THESAURUS |
4521 ? (*curbuf->b_p_tsr == NUL | |
4522 ? p_tsr | |
4523 : curbuf->b_p_tsr) | |
4524 : (*curbuf->b_p_dict == NUL | |
4525 ? p_dict | |
4526 : curbuf->b_p_dict)), | |
659 | 4527 compl_pattern, |
703 | 4528 dict != NULL ? dict_f |
4529 : 0, type == CTRL_X_THESAURUS); | |
7 | 4530 dict = NULL; |
4531 break; | |
4532 | |
4533 case CTRL_X_TAGS: | |
4534 /* set p_ic according to p_ic, p_scs and pat for find_tags(). */ | |
4535 save_p_ic = p_ic; | |
449 | 4536 p_ic = ignorecase(compl_pattern); |
7 | 4537 |
2047
85da03763130
updated for version 7.2.333
Bram Moolenaar <bram@zimbu.org>
parents:
2025
diff
changeset
|
4538 /* Find up to TAG_MANY matches. Avoids that an enormous number |
449 | 4539 * of matches is found when compl_pattern is empty */ |
4540 if (find_tags(compl_pattern, &num_matches, &matches, | |
13210
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
4541 TAG_REGEXP | TAG_NAMES | TAG_NOIC | TAG_INS_COMP |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
4542 | (ctrl_x_mode != CTRL_X_NORMAL ? TAG_VERBOSE : 0), |
7 | 4543 TAG_MANY, curbuf->b_ffname) == OK && num_matches > 0) |
4544 { | |
942 | 4545 ins_compl_add_matches(num_matches, matches, p_ic); |
7 | 4546 } |
4547 p_ic = save_p_ic; | |
4548 break; | |
4549 | |
4550 case CTRL_X_FILES: | |
449 | 4551 if (expand_wildcards(1, &compl_pattern, &num_matches, &matches, |
7 | 4552 EW_FILE|EW_DIR|EW_ADDSLASH|EW_SILENT) == OK) |
4553 { | |
4554 | |
4555 /* May change home directory back to "~". */ | |
449 | 4556 tilde_replace(compl_pattern, num_matches, matches); |
4242 | 4557 ins_compl_add_matches(num_matches, matches, p_fic || p_wic); |
7 | 4558 } |
4559 break; | |
4560 | |
4561 case CTRL_X_CMDLINE: | |
449 | 4562 if (expand_cmdline(&compl_xp, compl_pattern, |
4563 (int)STRLEN(compl_pattern), | |
7 | 4564 &num_matches, &matches) == EXPAND_OK) |
681 | 4565 ins_compl_add_matches(num_matches, matches, FALSE); |
7 | 4566 break; |
4567 | |
12 | 4568 #ifdef FEAT_COMPL_FUNC |
4569 case CTRL_X_FUNCTION: | |
523 | 4570 case CTRL_X_OMNI: |
659 | 4571 expand_by_function(type, compl_pattern); |
12 | 4572 break; |
4573 #endif | |
4574 | |
477 | 4575 case CTRL_X_SPELL: |
744 | 4576 #ifdef FEAT_SPELL |
477 | 4577 num_matches = expand_spelling(first_match_pos.lnum, |
1872 | 4578 compl_pattern, &matches); |
477 | 4579 if (num_matches > 0) |
942 | 4580 ins_compl_add_matches(num_matches, matches, p_ic); |
477 | 4581 #endif |
4582 break; | |
4583 | |
7 | 4584 default: /* normal ^P/^N and ^X^L */ |
4585 /* | |
4586 * If 'infercase' is set, don't use 'smartcase' here | |
4587 */ | |
4588 save_p_scs = p_scs; | |
4589 if (ins_buf->b_p_inf) | |
4590 p_scs = FALSE; | |
449 | 4591 |
5625 | 4592 /* Buffers other than curbuf are scanned from the beginning or the |
7 | 4593 * end but never from the middle, thus setting nowrapscan in this |
4594 * buffers is a good idea, on the other hand, we always set | |
4595 * wrapscan for curbuf to avoid missing matches -- Acevedo,Webb */ | |
4596 save_p_ws = p_ws; | |
4597 if (ins_buf != curbuf) | |
4598 p_ws = FALSE; | |
4599 else if (*e_cpt == '.') | |
4600 p_ws = TRUE; | |
4601 for (;;) | |
4602 { | |
464 | 4603 int flags = 0; |
7 | 4604 |
1007 | 4605 ++msg_silent; /* Don't want messages for wrapscan. */ |
4606 | |
6657 | 4607 /* CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode) |
4608 * || word-wise search that | |
540 | 4609 * has added a word that was at the beginning of the line */ |
6657 | 4610 if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode) |
449 | 4611 || (compl_cont_status & CONT_SOL)) |
7 | 4612 found_new_match = search_for_exact_line(ins_buf, pos, |
659 | 4613 compl_direction, compl_pattern); |
7 | 4614 else |
15239
db5d2429bda3
patch 8.1.0629: "gn" selects the wrong text with a multi-line match
Bram Moolenaar <Bram@vim.org>
parents:
15211
diff
changeset
|
4615 found_new_match = searchit(NULL, ins_buf, pos, NULL, |
659 | 4616 compl_direction, |
449 | 4617 compl_pattern, 1L, SEARCH_KEEP + SEARCH_NFMSG, |
11521
578df034735d
patch 8.0.0643: when a pattern search is slow Vim becomes unusable
Christian Brabandt <cb@256bit.org>
parents:
11424
diff
changeset
|
4618 RE_LAST, (linenr_T)0, NULL, NULL); |
1007 | 4619 --msg_silent; |
5625 | 4620 if (!compl_started || set_match_pos) |
7 | 4621 { |
667 | 4622 /* set "compl_started" even on fail */ |
449 | 4623 compl_started = TRUE; |
7 | 4624 first_match_pos = *pos; |
4625 last_match_pos = *pos; | |
5625 | 4626 set_match_pos = FALSE; |
7 | 4627 } |
4628 else if (first_match_pos.lnum == last_match_pos.lnum | |
665 | 4629 && first_match_pos.col == last_match_pos.col) |
7 | 4630 found_new_match = FAIL; |
4631 if (found_new_match == FAIL) | |
4632 { | |
4633 if (ins_buf == curbuf) | |
4634 found_all = TRUE; | |
4635 break; | |
4636 } | |
4637 | |
4638 /* when ADDING, the text before the cursor matches, skip it */ | |
449 | 4639 if ( (compl_cont_status & CONT_ADDING) && ins_buf == curbuf |
7 | 4640 && ini->lnum == pos->lnum |
4641 && ini->col == pos->col) | |
4642 continue; | |
4643 ptr = ml_get_buf(ins_buf, pos->lnum, FALSE) + pos->col; | |
6657 | 4644 if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)) |
7 | 4645 { |
449 | 4646 if (compl_cont_status & CONT_ADDING) |
7 | 4647 { |
4648 if (pos->lnum >= ins_buf->b_ml.ml_line_count) | |
4649 continue; | |
4650 ptr = ml_get_buf(ins_buf, pos->lnum + 1, FALSE); | |
4651 if (!p_paste) | |
4652 ptr = skipwhite(ptr); | |
4653 } | |
4654 len = (int)STRLEN(ptr); | |
4655 } | |
4656 else | |
4657 { | |
449 | 4658 char_u *tmp_ptr = ptr; |
4659 | |
4660 if (compl_cont_status & CONT_ADDING) | |
7 | 4661 { |
449 | 4662 tmp_ptr += compl_length; |
7 | 4663 /* Skip if already inside a word. */ |
4664 if (vim_iswordp(tmp_ptr)) | |
4665 continue; | |
4666 /* Find start of next word. */ | |
4667 tmp_ptr = find_word_start(tmp_ptr); | |
4668 } | |
4669 /* Find end of this word. */ | |
4670 tmp_ptr = find_word_end(tmp_ptr); | |
4671 len = (int)(tmp_ptr - ptr); | |
4672 | |
449 | 4673 if ((compl_cont_status & CONT_ADDING) |
4674 && len == compl_length) | |
7 | 4675 { |
4676 if (pos->lnum < ins_buf->b_ml.ml_line_count) | |
4677 { | |
4678 /* Try next line, if any. the new word will be | |
4679 * "join" as if the normal command "J" was used. | |
4680 * IOSIZE is always greater than | |
449 | 4681 * compl_length, so the next STRNCPY always |
7 | 4682 * works -- Acevedo */ |
4683 STRNCPY(IObuff, ptr, len); | |
4684 ptr = ml_get_buf(ins_buf, pos->lnum + 1, FALSE); | |
4685 tmp_ptr = ptr = skipwhite(ptr); | |
4686 /* Find start of next word. */ | |
4687 tmp_ptr = find_word_start(tmp_ptr); | |
4688 /* Find end of next word. */ | |
4689 tmp_ptr = find_word_end(tmp_ptr); | |
4690 if (tmp_ptr > ptr) | |
4691 { | |
419 | 4692 if (*ptr != ')' && IObuff[len - 1] != TAB) |
7 | 4693 { |
419 | 4694 if (IObuff[len - 1] != ' ') |
7 | 4695 IObuff[len++] = ' '; |
4696 /* IObuf =~ "\k.* ", thus len >= 2 */ | |
4697 if (p_js | |
419 | 4698 && (IObuff[len - 2] == '.' |
7 | 4699 || (vim_strchr(p_cpo, CPO_JOINSP) |
4700 == NULL | |
419 | 4701 && (IObuff[len - 2] == '?' |
4702 || IObuff[len - 2] == '!')))) | |
7 | 4703 IObuff[len++] = ' '; |
4704 } | |
2047
85da03763130
updated for version 7.2.333
Bram Moolenaar <bram@zimbu.org>
parents:
2025
diff
changeset
|
4705 /* copy as much as possible of the new word */ |
7 | 4706 if (tmp_ptr - ptr >= IOSIZE - len) |
4707 tmp_ptr = ptr + IOSIZE - len - 1; | |
4708 STRNCPY(IObuff + len, ptr, tmp_ptr - ptr); | |
4709 len += (int)(tmp_ptr - ptr); | |
464 | 4710 flags |= CONT_S_IPOS; |
7 | 4711 } |
4712 IObuff[len] = NUL; | |
4713 ptr = IObuff; | |
4714 } | |
449 | 4715 if (len == compl_length) |
7 | 4716 continue; |
4717 } | |
4718 } | |
942 | 4719 if (ins_compl_add_infercase(ptr, len, p_ic, |
540 | 4720 ins_buf == curbuf ? NULL : ins_buf->b_sfname, |
659 | 4721 0, flags) != NOTDONE) |
7 | 4722 { |
4723 found_new_match = OK; | |
4724 break; | |
4725 } | |
4726 } | |
4727 p_scs = save_p_scs; | |
4728 p_ws = save_p_ws; | |
4729 } | |
540 | 4730 |
449 | 4731 /* check if compl_curr_match has changed, (e.g. other type of |
1796 | 4732 * expansion added something) */ |
11424
328a9ee98fb2
patch 8.0.0596: crash when complete() called after complete_add()
Christian Brabandt <cb@256bit.org>
parents:
11317
diff
changeset
|
4733 if (type != 0 && compl_curr_match != compl_old_match) |
7 | 4734 found_new_match = OK; |
4735 | |
4736 /* break the loop for specialized modes (use 'complete' just for the | |
13210
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
4737 * generic ctrl_x_mode == CTRL_X_NORMAL) or when we've found a new |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
4738 * match */ |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
4739 if ((ctrl_x_mode != CTRL_X_NORMAL |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
4740 && !CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)) |
449 | 4741 || found_new_match != FAIL) |
540 | 4742 { |
4743 if (got_int) | |
4744 break; | |
665 | 4745 /* Fill the popup menu as soon as possible. */ |
989 | 4746 if (type != -1) |
10277
154d5a2e7395
commit https://github.com/vim/vim/commit/472e85970ee3a80abd824bef510df12e9cfe9e96
Christian Brabandt <cb@256bit.org>
parents:
10120
diff
changeset
|
4747 ins_compl_check_keys(0, FALSE); |
665 | 4748 |
13210
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
4749 if ((ctrl_x_mode != CTRL_X_NORMAL |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
4750 && !CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)) |
540 | 4751 || compl_interrupted) |
4752 break; | |
4753 compl_started = TRUE; | |
4754 } | |
4755 else | |
4756 { | |
4757 /* Mark a buffer scanned when it has been scanned completely */ | |
4758 if (type == 0 || type == CTRL_X_PATH_PATTERNS) | |
4759 ins_buf->b_scanned = TRUE; | |
4760 | |
4761 compl_started = FALSE; | |
4762 } | |
449 | 4763 } |
4764 compl_started = TRUE; | |
7 | 4765 |
13210
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
4766 if ((ctrl_x_mode == CTRL_X_NORMAL || CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)) |
7 | 4767 && *e_cpt == NUL) /* Got to end of 'complete' */ |
4768 found_new_match = FAIL; | |
4769 | |
4770 i = -1; /* total of matches, unknown */ | |
13210
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
4771 if (found_new_match == FAIL || (ctrl_x_mode != CTRL_X_NORMAL |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
4772 && !CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode))) |
7 | 4773 i = ins_compl_make_cyclic(); |
4774 | |
11424
328a9ee98fb2
patch 8.0.0596: crash when complete() called after complete_add()
Christian Brabandt <cb@256bit.org>
parents:
11317
diff
changeset
|
4775 if (compl_old_match != NULL) |
328a9ee98fb2
patch 8.0.0596: crash when complete() called after complete_add()
Christian Brabandt <cb@256bit.org>
parents:
11317
diff
changeset
|
4776 { |
328a9ee98fb2
patch 8.0.0596: crash when complete() called after complete_add()
Christian Brabandt <cb@256bit.org>
parents:
11317
diff
changeset
|
4777 /* If several matches were added (FORWARD) or the search failed and has |
328a9ee98fb2
patch 8.0.0596: crash when complete() called after complete_add()
Christian Brabandt <cb@256bit.org>
parents:
11317
diff
changeset
|
4778 * just been made cyclic then we have to move compl_curr_match to the |
328a9ee98fb2
patch 8.0.0596: crash when complete() called after complete_add()
Christian Brabandt <cb@256bit.org>
parents:
11317
diff
changeset
|
4779 * next or previous entry (if any) -- Acevedo */ |
328a9ee98fb2
patch 8.0.0596: crash when complete() called after complete_add()
Christian Brabandt <cb@256bit.org>
parents:
11317
diff
changeset
|
4780 compl_curr_match = compl_direction == FORWARD ? compl_old_match->cp_next |
328a9ee98fb2
patch 8.0.0596: crash when complete() called after complete_add()
Christian Brabandt <cb@256bit.org>
parents:
11317
diff
changeset
|
4781 : compl_old_match->cp_prev; |
328a9ee98fb2
patch 8.0.0596: crash when complete() called after complete_add()
Christian Brabandt <cb@256bit.org>
parents:
11317
diff
changeset
|
4782 if (compl_curr_match == NULL) |
328a9ee98fb2
patch 8.0.0596: crash when complete() called after complete_add()
Christian Brabandt <cb@256bit.org>
parents:
11317
diff
changeset
|
4783 compl_curr_match = compl_old_match; |
328a9ee98fb2
patch 8.0.0596: crash when complete() called after complete_add()
Christian Brabandt <cb@256bit.org>
parents:
11317
diff
changeset
|
4784 } |
7 | 4785 return i; |
4786 } | |
4787 | |
4788 /* Delete the old text being completed. */ | |
4789 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
4790 ins_compl_delete(void) |
7 | 4791 { |
10293
0bf1d211e441
commit https://github.com/vim/vim/commit/9ec7fa82a2c4f0283862ed704c2940959e6130ee
Christian Brabandt <cb@256bit.org>
parents:
10291
diff
changeset
|
4792 int col; |
7 | 4793 |
4794 /* | |
4795 * In insert mode: Delete the typed part. | |
4796 * In replace mode: Put the old characters back, if any. | |
4797 */ | |
10293
0bf1d211e441
commit https://github.com/vim/vim/commit/9ec7fa82a2c4f0283862ed704c2940959e6130ee
Christian Brabandt <cb@256bit.org>
parents:
10291
diff
changeset
|
4798 col = compl_col + (compl_cont_status & CONT_ADDING ? compl_length : 0); |
0bf1d211e441
commit https://github.com/vim/vim/commit/9ec7fa82a2c4f0283862ed704c2940959e6130ee
Christian Brabandt <cb@256bit.org>
parents:
10291
diff
changeset
|
4799 if ((int)curwin->w_cursor.col > col) |
0bf1d211e441
commit https://github.com/vim/vim/commit/9ec7fa82a2c4f0283862ed704c2940959e6130ee
Christian Brabandt <cb@256bit.org>
parents:
10291
diff
changeset
|
4800 { |
0bf1d211e441
commit https://github.com/vim/vim/commit/9ec7fa82a2c4f0283862ed704c2940959e6130ee
Christian Brabandt <cb@256bit.org>
parents:
10291
diff
changeset
|
4801 if (stop_arrow() == FAIL) |
0bf1d211e441
commit https://github.com/vim/vim/commit/9ec7fa82a2c4f0283862ed704c2940959e6130ee
Christian Brabandt <cb@256bit.org>
parents:
10291
diff
changeset
|
4802 return; |
0bf1d211e441
commit https://github.com/vim/vim/commit/9ec7fa82a2c4f0283862ed704c2940959e6130ee
Christian Brabandt <cb@256bit.org>
parents:
10291
diff
changeset
|
4803 backspace_until_column(col); |
0bf1d211e441
commit https://github.com/vim/vim/commit/9ec7fa82a2c4f0283862ed704c2940959e6130ee
Christian Brabandt <cb@256bit.org>
parents:
10291
diff
changeset
|
4804 } |
6056 | 4805 |
6075 | 4806 /* TODO: is this sufficient for redrawing? Redrawing everything causes |
4807 * flicker, thus we can't do that. */ | |
7 | 4808 changed_cline_bef_curs(); |
6909 | 4809 /* clear v:completed_item */ |
13150
808625d4b71b
patch 8.0.1449: slow redrawing with DirectX
Christian Brabandt <cb@256bit.org>
parents:
12960
diff
changeset
|
4810 set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc_lock(VAR_FIXED)); |
7 | 4811 } |
4812 | |
10277
154d5a2e7395
commit https://github.com/vim/vim/commit/472e85970ee3a80abd824bef510df12e9cfe9e96
Christian Brabandt <cb@256bit.org>
parents:
10120
diff
changeset
|
4813 /* |
154d5a2e7395
commit https://github.com/vim/vim/commit/472e85970ee3a80abd824bef510df12e9cfe9e96
Christian Brabandt <cb@256bit.org>
parents:
10120
diff
changeset
|
4814 * Insert the new text being completed. |
154d5a2e7395
commit https://github.com/vim/vim/commit/472e85970ee3a80abd824bef510df12e9cfe9e96
Christian Brabandt <cb@256bit.org>
parents:
10120
diff
changeset
|
4815 * "in_compl_func" is TRUE when called from complete_check(). |
154d5a2e7395
commit https://github.com/vim/vim/commit/472e85970ee3a80abd824bef510df12e9cfe9e96
Christian Brabandt <cb@256bit.org>
parents:
10120
diff
changeset
|
4816 */ |
7 | 4817 static void |
10277
154d5a2e7395
commit https://github.com/vim/vim/commit/472e85970ee3a80abd824bef510df12e9cfe9e96
Christian Brabandt <cb@256bit.org>
parents:
10120
diff
changeset
|
4818 ins_compl_insert(int in_compl_func) |
7 | 4819 { |
6909 | 4820 dict_T *dict; |
4821 | |
1782 | 4822 ins_bytes(compl_shown_match->cp_str + ins_compl_len()); |
683 | 4823 if (compl_shown_match->cp_flags & ORIGINAL_TEXT) |
4824 compl_used_match = FALSE; | |
4825 else | |
4826 compl_used_match = TRUE; | |
6909 | 4827 |
4828 /* Set completed item. */ | |
4829 /* { word, abbr, menu, kind, info } */ | |
13150
808625d4b71b
patch 8.0.1449: slow redrawing with DirectX
Christian Brabandt <cb@256bit.org>
parents:
12960
diff
changeset
|
4830 dict = dict_alloc_lock(VAR_FIXED); |
6909 | 4831 if (dict != NULL) |
4832 { | |
14301
3c80092eb211
patch 8.1.0166: using dict_add_nr_str() is clumsy
Christian Brabandt <cb@256bit.org>
parents:
14276
diff
changeset
|
4833 dict_add_string(dict, "word", compl_shown_match->cp_str); |
3c80092eb211
patch 8.1.0166: using dict_add_nr_str() is clumsy
Christian Brabandt <cb@256bit.org>
parents:
14276
diff
changeset
|
4834 dict_add_string(dict, "abbr", compl_shown_match->cp_text[CPT_ABBR]); |
3c80092eb211
patch 8.1.0166: using dict_add_nr_str() is clumsy
Christian Brabandt <cb@256bit.org>
parents:
14276
diff
changeset
|
4835 dict_add_string(dict, "menu", compl_shown_match->cp_text[CPT_MENU]); |
3c80092eb211
patch 8.1.0166: using dict_add_nr_str() is clumsy
Christian Brabandt <cb@256bit.org>
parents:
14276
diff
changeset
|
4836 dict_add_string(dict, "kind", compl_shown_match->cp_text[CPT_KIND]); |
3c80092eb211
patch 8.1.0166: using dict_add_nr_str() is clumsy
Christian Brabandt <cb@256bit.org>
parents:
14276
diff
changeset
|
4837 dict_add_string(dict, "info", compl_shown_match->cp_text[CPT_INFO]); |
3c80092eb211
patch 8.1.0166: using dict_add_nr_str() is clumsy
Christian Brabandt <cb@256bit.org>
parents:
14276
diff
changeset
|
4838 dict_add_string(dict, "user_data", |
3c80092eb211
patch 8.1.0166: using dict_add_nr_str() is clumsy
Christian Brabandt <cb@256bit.org>
parents:
14276
diff
changeset
|
4839 compl_shown_match->cp_text[CPT_USER_DATA]); |
6909 | 4840 } |
4841 set_vim_var_dict(VV_COMPLETED_ITEM, dict); | |
10277
154d5a2e7395
commit https://github.com/vim/vim/commit/472e85970ee3a80abd824bef510df12e9cfe9e96
Christian Brabandt <cb@256bit.org>
parents:
10120
diff
changeset
|
4842 if (!in_compl_func) |
154d5a2e7395
commit https://github.com/vim/vim/commit/472e85970ee3a80abd824bef510df12e9cfe9e96
Christian Brabandt <cb@256bit.org>
parents:
10120
diff
changeset
|
4843 compl_curr_match = compl_shown_match; |
7 | 4844 } |
4845 | |
4846 /* | |
4847 * Fill in the next completion in the current direction. | |
464 | 4848 * If "allow_get_expansion" is TRUE, then we may call ins_compl_get_exp() to |
4849 * get more completions. If it is FALSE, then we just do nothing when there | |
4850 * are no more completions in a given direction. The latter case is used when | |
4851 * we are still in the middle of finding completions, to allow browsing | |
4852 * through the ones found so far. | |
7 | 4853 * Return the total number of matches, or -1 if still unknown -- webb. |
4854 * | |
449 | 4855 * compl_curr_match is currently being used by ins_compl_get_exp(), so we use |
4856 * compl_shown_match here. | |
7 | 4857 * |
4858 * Note that this function may be called recursively once only. First with | |
464 | 4859 * "allow_get_expansion" TRUE, which calls ins_compl_get_exp(), which in turn |
4860 * calls this function with "allow_get_expansion" FALSE. | |
7 | 4861 */ |
4862 static int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
4863 ins_compl_next( |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
4864 int allow_get_expansion, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
4865 int count, /* repeat completion this many times; should |
610 | 4866 be at least 1 */ |
10277
154d5a2e7395
commit https://github.com/vim/vim/commit/472e85970ee3a80abd824bef510df12e9cfe9e96
Christian Brabandt <cb@256bit.org>
parents:
10120
diff
changeset
|
4867 int insert_match, /* Insert the newly selected match */ |
154d5a2e7395
commit https://github.com/vim/vim/commit/472e85970ee3a80abd824bef510df12e9cfe9e96
Christian Brabandt <cb@256bit.org>
parents:
10120
diff
changeset
|
4868 int in_compl_func) /* called from complete_check() */ |
7 | 4869 { |
4870 int num_matches = -1; | |
610 | 4871 int todo = count; |
657 | 4872 compl_T *found_compl = NULL; |
4873 int found_end = FALSE; | |
836 | 4874 int advance; |
6911 | 4875 int started = compl_started; |
7 | 4876 |
3271 | 4877 /* When user complete function return -1 for findstart which is next |
4878 * time of 'always', compl_shown_match become NULL. */ | |
4879 if (compl_shown_match == NULL) | |
4880 return -1; | |
4881 | |
665 | 4882 if (compl_leader != NULL |
4883 && (compl_shown_match->cp_flags & ORIGINAL_TEXT) == 0) | |
4884 { | |
4885 /* Set "compl_shown_match" to the actually shown match, it may differ | |
4886 * when "compl_leader" is used to omit some of the matches. */ | |
681 | 4887 while (!ins_compl_equal(compl_shown_match, |
835 | 4888 compl_leader, (int)STRLEN(compl_leader)) |
665 | 4889 && compl_shown_match->cp_next != NULL |
4890 && compl_shown_match->cp_next != compl_first_match) | |
4891 compl_shown_match = compl_shown_match->cp_next; | |
887 | 4892 |
4893 /* If we didn't find it searching forward, and compl_shows_dir is | |
4894 * backward, find the last match. */ | |
4895 if (compl_shows_dir == BACKWARD | |
4896 && !ins_compl_equal(compl_shown_match, | |
4897 compl_leader, (int)STRLEN(compl_leader)) | |
4898 && (compl_shown_match->cp_next == NULL | |
4899 || compl_shown_match->cp_next == compl_first_match)) | |
4900 { | |
4901 while (!ins_compl_equal(compl_shown_match, | |
4902 compl_leader, (int)STRLEN(compl_leader)) | |
4903 && compl_shown_match->cp_prev != NULL | |
4904 && compl_shown_match->cp_prev != compl_first_match) | |
4905 compl_shown_match = compl_shown_match->cp_prev; | |
4906 } | |
665 | 4907 } |
4908 | |
4909 if (allow_get_expansion && insert_match | |
874 | 4910 && (!(compl_get_longest || compl_restarting) || compl_used_match)) |
7 | 4911 /* Delete old text to be replaced */ |
4912 ins_compl_delete(); | |
665 | 4913 |
836 | 4914 /* When finding the longest common text we stick at the original text, |
4915 * don't let CTRL-N or CTRL-P move to the first match. */ | |
4916 advance = count != 1 || !allow_get_expansion || !compl_get_longest; | |
4917 | |
874 | 4918 /* When restarting the search don't insert the first match either. */ |
4919 if (compl_restarting) | |
4920 { | |
4921 advance = FALSE; | |
4922 compl_restarting = FALSE; | |
4923 } | |
4924 | |
610 | 4925 /* Repeat this for when <PageUp> or <PageDown> is typed. But don't wrap |
4926 * around. */ | |
4927 while (--todo >= 0) | |
4928 { | |
4929 if (compl_shows_dir == FORWARD && compl_shown_match->cp_next != NULL) | |
4930 { | |
4931 compl_shown_match = compl_shown_match->cp_next; | |
657 | 4932 found_end = (compl_first_match != NULL |
4933 && (compl_shown_match->cp_next == compl_first_match | |
4934 || compl_shown_match == compl_first_match)); | |
610 | 4935 } |
4936 else if (compl_shows_dir == BACKWARD | |
4937 && compl_shown_match->cp_prev != NULL) | |
4938 { | |
657 | 4939 found_end = (compl_shown_match == compl_first_match); |
610 | 4940 compl_shown_match = compl_shown_match->cp_prev; |
657 | 4941 found_end |= (compl_shown_match == compl_first_match); |
7 | 4942 } |
4943 else | |
610 | 4944 { |
909 | 4945 if (!allow_get_expansion) |
4946 { | |
4947 if (advance) | |
4948 { | |
4949 if (compl_shows_dir == BACKWARD) | |
4950 compl_pending -= todo + 1; | |
4951 else | |
4952 compl_pending += todo + 1; | |
4953 } | |
4954 return -1; | |
4955 } | |
4956 | |
6911 | 4957 if (!compl_no_select && advance) |
836 | 4958 { |
4959 if (compl_shows_dir == BACKWARD) | |
4960 --compl_pending; | |
4961 else | |
4962 ++compl_pending; | |
4963 } | |
657 | 4964 |
874 | 4965 /* Find matches. */ |
659 | 4966 num_matches = ins_compl_get_exp(&compl_startpos); |
909 | 4967 |
4968 /* handle any pending completions */ | |
4969 while (compl_pending != 0 && compl_direction == compl_shows_dir | |
836 | 4970 && advance) |
909 | 4971 { |
4972 if (compl_pending > 0 && compl_shown_match->cp_next != NULL) | |
4973 { | |
4974 compl_shown_match = compl_shown_match->cp_next; | |
4975 --compl_pending; | |
4976 } | |
4977 if (compl_pending < 0 && compl_shown_match->cp_prev != NULL) | |
4978 { | |
4979 compl_shown_match = compl_shown_match->cp_prev; | |
4980 ++compl_pending; | |
4981 } | |
4982 else | |
4983 break; | |
4984 } | |
657 | 4985 found_end = FALSE; |
4986 } | |
4987 if ((compl_shown_match->cp_flags & ORIGINAL_TEXT) == 0 | |
4988 && compl_leader != NULL | |
681 | 4989 && !ins_compl_equal(compl_shown_match, |
835 | 4990 compl_leader, (int)STRLEN(compl_leader))) |
657 | 4991 ++todo; |
4992 else | |
4993 /* Remember a matching item. */ | |
4994 found_compl = compl_shown_match; | |
4995 | |
4996 /* Stop at the end of the list when we found a usable match. */ | |
4997 if (found_end) | |
4998 { | |
4999 if (found_compl != NULL) | |
610 | 5000 { |
657 | 5001 compl_shown_match = found_compl; |
5002 break; | |
610 | 5003 } |
657 | 5004 todo = 1; /* use first usable match after wrapping around */ |
610 | 5005 } |
7 | 5006 } |
5007 | |
665 | 5008 /* Insert the text of the new completion, or the compl_leader. */ |
6911 | 5009 if (compl_no_insert && !started) |
5010 { | |
5011 ins_bytes(compl_orig_text + ins_compl_len()); | |
5012 compl_used_match = FALSE; | |
5013 } | |
5014 else if (insert_match) | |
665 | 5015 { |
5016 if (!compl_get_longest || compl_used_match) | |
10277
154d5a2e7395
commit https://github.com/vim/vim/commit/472e85970ee3a80abd824bef510df12e9cfe9e96
Christian Brabandt <cb@256bit.org>
parents:
10120
diff
changeset
|
5017 ins_compl_insert(in_compl_func); |
665 | 5018 else |
1782 | 5019 ins_bytes(compl_leader + ins_compl_len()); |
665 | 5020 } |
5021 else | |
5022 compl_used_match = FALSE; | |
7 | 5023 |
5024 if (!allow_get_expansion) | |
5025 { | |
540 | 5026 /* may undisplay the popup menu first */ |
5027 ins_compl_upd_pum(); | |
5028 | |
15521
6d949e552e99
patch 8.1.0768: updating completions may cause the popup menu to flicker
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
5029 // Redraw before showing the popup menu to show the user what was |
6d949e552e99
patch 8.1.0768: updating completions may cause the popup menu to flicker
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
5030 // inserted. |
6d949e552e99
patch 8.1.0768: updating completions may cause the popup menu to flicker
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
5031 pum_call_update_screen(); |
665 | 5032 |
540 | 5033 /* display the updated popup menu */ |
5034 ins_compl_show_pum(); | |
864 | 5035 #ifdef FEAT_GUI |
5036 if (gui.in_use) | |
5037 { | |
5038 /* Show the cursor after the match, not after the redrawn text. */ | |
5039 setcursor(); | |
13150
808625d4b71b
patch 8.0.1449: slow redrawing with DirectX
Christian Brabandt <cb@256bit.org>
parents:
12960
diff
changeset
|
5040 out_flush_cursor(FALSE, FALSE); |
864 | 5041 } |
5042 #endif | |
540 | 5043 |
7 | 5044 /* Delete old text to be replaced, since we're still searching and |
5045 * don't want to match ourselves! */ | |
5046 ins_compl_delete(); | |
5047 } | |
5048 | |
825 | 5049 /* Enter will select a match when the match wasn't inserted and the popup |
1219 | 5050 * menu is visible. */ |
6911 | 5051 if (compl_no_insert && !started) |
5052 compl_enter_selects = TRUE; | |
5053 else | |
5054 compl_enter_selects = !insert_match && compl_match_array != NULL; | |
825 | 5055 |
7 | 5056 /* |
5057 * Show the file name for the match (if any) | |
5058 * Truncate the file name to avoid a wait for return. | |
5059 */ | |
464 | 5060 if (compl_shown_match->cp_fname != NULL) |
7 | 5061 { |
11289
e0309111d976
patch 8.0.0530: buffer overflow when 'columns' is very big
Christian Brabandt <cb@256bit.org>
parents:
11158
diff
changeset
|
5062 char *lead = _("match in file"); |
e0309111d976
patch 8.0.0530: buffer overflow when 'columns' is very big
Christian Brabandt <cb@256bit.org>
parents:
11158
diff
changeset
|
5063 int space = sc_col - vim_strsize((char_u *)lead) - 2; |
e0309111d976
patch 8.0.0530: buffer overflow when 'columns' is very big
Christian Brabandt <cb@256bit.org>
parents:
11158
diff
changeset
|
5064 char_u *s; |
e0309111d976
patch 8.0.0530: buffer overflow when 'columns' is very big
Christian Brabandt <cb@256bit.org>
parents:
11158
diff
changeset
|
5065 char_u *e; |
e0309111d976
patch 8.0.0530: buffer overflow when 'columns' is very big
Christian Brabandt <cb@256bit.org>
parents:
11158
diff
changeset
|
5066 |
e0309111d976
patch 8.0.0530: buffer overflow when 'columns' is very big
Christian Brabandt <cb@256bit.org>
parents:
11158
diff
changeset
|
5067 if (space > 0) |
e0309111d976
patch 8.0.0530: buffer overflow when 'columns' is very big
Christian Brabandt <cb@256bit.org>
parents:
11158
diff
changeset
|
5068 { |
e0309111d976
patch 8.0.0530: buffer overflow when 'columns' is very big
Christian Brabandt <cb@256bit.org>
parents:
11158
diff
changeset
|
5069 /* We need the tail that fits. With double-byte encoding going |
e0309111d976
patch 8.0.0530: buffer overflow when 'columns' is very big
Christian Brabandt <cb@256bit.org>
parents:
11158
diff
changeset
|
5070 * back from the end is very slow, thus go from the start and keep |
e0309111d976
patch 8.0.0530: buffer overflow when 'columns' is very big
Christian Brabandt <cb@256bit.org>
parents:
11158
diff
changeset
|
5071 * the text that fits in "space" between "s" and "e". */ |
e0309111d976
patch 8.0.0530: buffer overflow when 'columns' is very big
Christian Brabandt <cb@256bit.org>
parents:
11158
diff
changeset
|
5072 for (s = e = compl_shown_match->cp_fname; *e != NUL; MB_PTR_ADV(e)) |
e0309111d976
patch 8.0.0530: buffer overflow when 'columns' is very big
Christian Brabandt <cb@256bit.org>
parents:
11158
diff
changeset
|
5073 { |
e0309111d976
patch 8.0.0530: buffer overflow when 'columns' is very big
Christian Brabandt <cb@256bit.org>
parents:
11158
diff
changeset
|
5074 space -= ptr2cells(e); |
e0309111d976
patch 8.0.0530: buffer overflow when 'columns' is very big
Christian Brabandt <cb@256bit.org>
parents:
11158
diff
changeset
|
5075 while (space < 0) |
e0309111d976
patch 8.0.0530: buffer overflow when 'columns' is very big
Christian Brabandt <cb@256bit.org>
parents:
11158
diff
changeset
|
5076 { |
e0309111d976
patch 8.0.0530: buffer overflow when 'columns' is very big
Christian Brabandt <cb@256bit.org>
parents:
11158
diff
changeset
|
5077 space += ptr2cells(s); |
e0309111d976
patch 8.0.0530: buffer overflow when 'columns' is very big
Christian Brabandt <cb@256bit.org>
parents:
11158
diff
changeset
|
5078 MB_PTR_ADV(s); |
e0309111d976
patch 8.0.0530: buffer overflow when 'columns' is very big
Christian Brabandt <cb@256bit.org>
parents:
11158
diff
changeset
|
5079 } |
e0309111d976
patch 8.0.0530: buffer overflow when 'columns' is very big
Christian Brabandt <cb@256bit.org>
parents:
11158
diff
changeset
|
5080 } |
e0309111d976
patch 8.0.0530: buffer overflow when 'columns' is very big
Christian Brabandt <cb@256bit.org>
parents:
11158
diff
changeset
|
5081 vim_snprintf((char *)IObuff, IOSIZE, "%s %s%s", lead, |
e0309111d976
patch 8.0.0530: buffer overflow when 'columns' is very big
Christian Brabandt <cb@256bit.org>
parents:
11158
diff
changeset
|
5082 s > compl_shown_match->cp_fname ? "<" : "", s); |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15521
diff
changeset
|
5083 msg((char *)IObuff); |
11289
e0309111d976
patch 8.0.0530: buffer overflow when 'columns' is very big
Christian Brabandt <cb@256bit.org>
parents:
11158
diff
changeset
|
5084 redraw_cmdline = FALSE; /* don't overwrite! */ |
e0309111d976
patch 8.0.0530: buffer overflow when 'columns' is very big
Christian Brabandt <cb@256bit.org>
parents:
11158
diff
changeset
|
5085 } |
7 | 5086 } |
5087 | |
5088 return num_matches; | |
5089 } | |
5090 | |
5091 /* | |
5092 * Call this while finding completions, to check whether the user has hit a key | |
5093 * that should change the currently displayed completion, or exit completion | |
716 | 5094 * mode. Also, when compl_pending is not zero, show a completion as soon as |
7 | 5095 * possible. -- webb |
464 | 5096 * "frequency" specifies out of how many calls we actually check. |
10277
154d5a2e7395
commit https://github.com/vim/vim/commit/472e85970ee3a80abd824bef510df12e9cfe9e96
Christian Brabandt <cb@256bit.org>
parents:
10120
diff
changeset
|
5097 * "in_compl_func" is TRUE when called from complete_check(), don't set |
154d5a2e7395
commit https://github.com/vim/vim/commit/472e85970ee3a80abd824bef510df12e9cfe9e96
Christian Brabandt <cb@256bit.org>
parents:
10120
diff
changeset
|
5098 * compl_curr_match. |
7 | 5099 */ |
5100 void | |
10277
154d5a2e7395
commit https://github.com/vim/vim/commit/472e85970ee3a80abd824bef510df12e9cfe9e96
Christian Brabandt <cb@256bit.org>
parents:
10120
diff
changeset
|
5101 ins_compl_check_keys(int frequency, int in_compl_func) |
7 | 5102 { |
5103 static int count = 0; | |
13215
ae5f855a64be
patch 8.0.1482: using feedkeys() does not work to test completion
Christian Brabandt <cb@256bit.org>
parents:
13214
diff
changeset
|
5104 int c; |
ae5f855a64be
patch 8.0.1482: using feedkeys() does not work to test completion
Christian Brabandt <cb@256bit.org>
parents:
13214
diff
changeset
|
5105 |
ae5f855a64be
patch 8.0.1482: using feedkeys() does not work to test completion
Christian Brabandt <cb@256bit.org>
parents:
13214
diff
changeset
|
5106 /* Don't check when reading keys from a script, :normal or feedkeys(). |
ae5f855a64be
patch 8.0.1482: using feedkeys() does not work to test completion
Christian Brabandt <cb@256bit.org>
parents:
13214
diff
changeset
|
5107 * That would break the test scripts. But do check for keys when called |
ae5f855a64be
patch 8.0.1482: using feedkeys() does not work to test completion
Christian Brabandt <cb@256bit.org>
parents:
13214
diff
changeset
|
5108 * from complete_check(). */ |
ae5f855a64be
patch 8.0.1482: using feedkeys() does not work to test completion
Christian Brabandt <cb@256bit.org>
parents:
13214
diff
changeset
|
5109 if (!in_compl_func && (using_script() || ex_normal_busy)) |
7 | 5110 return; |
5111 | |
5112 /* Only do this at regular intervals */ | |
464 | 5113 if (++count < frequency) |
7 | 5114 return; |
5115 count = 0; | |
5116 | |
909 | 5117 /* Check for a typed key. Do use mappings, otherwise vim_is_ctrl_x_key() |
5118 * can't do its work correctly. */ | |
7 | 5119 c = vpeekc_any(); |
5120 if (c != NUL) | |
5121 { | |
5122 if (vim_is_ctrl_x_key(c) && c != Ctrl_X && c != Ctrl_R) | |
5123 { | |
5124 c = safe_vgetc(); /* Eat the character */ | |
610 | 5125 compl_shows_dir = ins_compl_key2dir(c); |
665 | 5126 (void)ins_compl_next(FALSE, ins_compl_key2count(c), |
10277
154d5a2e7395
commit https://github.com/vim/vim/commit/472e85970ee3a80abd824bef510df12e9cfe9e96
Christian Brabandt <cb@256bit.org>
parents:
10120
diff
changeset
|
5127 c != K_UP && c != K_DOWN, in_compl_func); |
7 | 5128 } |
909 | 5129 else |
5130 { | |
5131 /* Need to get the character to have KeyTyped set. We'll put it | |
1526 | 5132 * back with vungetc() below. But skip K_IGNORE. */ |
909 | 5133 c = safe_vgetc(); |
1526 | 5134 if (c != K_IGNORE) |
5135 { | |
5136 /* Don't interrupt completion when the character wasn't typed, | |
5137 * e.g., when doing @q to replay keys. */ | |
5138 if (c != Ctrl_R && KeyTyped) | |
5139 compl_interrupted = TRUE; | |
5140 | |
5141 vungetc(c); | |
5142 } | |
909 | 5143 } |
449 | 5144 } |
6911 | 5145 if (compl_pending != 0 && !got_int && !compl_no_insert) |
909 | 5146 { |
5147 int todo = compl_pending > 0 ? compl_pending : -compl_pending; | |
5148 | |
5149 compl_pending = 0; | |
10277
154d5a2e7395
commit https://github.com/vim/vim/commit/472e85970ee3a80abd824bef510df12e9cfe9e96
Christian Brabandt <cb@256bit.org>
parents:
10120
diff
changeset
|
5150 (void)ins_compl_next(FALSE, todo, TRUE, in_compl_func); |
909 | 5151 } |
610 | 5152 } |
5153 | |
5154 /* | |
5155 * Decide the direction of Insert mode complete from the key typed. | |
5156 * Returns BACKWARD or FORWARD. | |
5157 */ | |
5158 static int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
5159 ins_compl_key2dir(int c) |
610 | 5160 { |
665 | 5161 if (c == Ctrl_P || c == Ctrl_L |
8943
47036dcd83a4
commit https://github.com/vim/vim/commit/8e42ae5069d4985869e46eaa56900ed19e30f504
Christian Brabandt <cb@256bit.org>
parents:
8935
diff
changeset
|
5162 || c == K_PAGEUP || c == K_KPAGEUP || c == K_S_UP || c == K_UP) |
610 | 5163 return BACKWARD; |
5164 return FORWARD; | |
5165 } | |
5166 | |
5167 /* | |
644 | 5168 * Return TRUE for keys that are used for completion only when the popup menu |
5169 * is visible. | |
5170 */ | |
5171 static int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
5172 ins_compl_pum_key(int c) |
644 | 5173 { |
5174 return pum_visible() && (c == K_PAGEUP || c == K_KPAGEUP || c == K_S_UP | |
665 | 5175 || c == K_PAGEDOWN || c == K_KPAGEDOWN || c == K_S_DOWN |
5176 || c == K_UP || c == K_DOWN); | |
644 | 5177 } |
5178 | |
5179 /* | |
610 | 5180 * Decide the number of completions to move forward. |
5181 * Returns 1 for most keys, height of the popup menu for page-up/down keys. | |
5182 */ | |
5183 static int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
5184 ins_compl_key2count(int c) |
610 | 5185 { |
5186 int h; | |
5187 | |
665 | 5188 if (ins_compl_pum_key(c) && c != K_UP && c != K_DOWN) |
610 | 5189 { |
5190 h = pum_get_height(); | |
5191 if (h > 3) | |
5192 h -= 2; /* keep some context */ | |
5193 return h; | |
5194 } | |
5195 return 1; | |
7 | 5196 } |
5197 | |
5198 /* | |
681 | 5199 * Return TRUE if completion with "c" should insert the match, FALSE if only |
5200 * to change the currently selected completion. | |
5201 */ | |
5202 static int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
5203 ins_compl_use_match(int c) |
681 | 5204 { |
5205 switch (c) | |
5206 { | |
5207 case K_UP: | |
5208 case K_DOWN: | |
5209 case K_PAGEDOWN: | |
5210 case K_KPAGEDOWN: | |
5211 case K_S_DOWN: | |
5212 case K_PAGEUP: | |
5213 case K_KPAGEUP: | |
5214 case K_S_UP: | |
5215 return FALSE; | |
5216 } | |
5217 return TRUE; | |
5218 } | |
5219 | |
5220 /* | |
7 | 5221 * Do Insert mode completion. |
5222 * Called when character "c" was typed, which has a meaning for completion. | |
5223 * Returns OK if completion was done, FAIL if something failed (out of mem). | |
5224 */ | |
5225 static int | |
8224
2baf64fead5e
commit https://github.com/vim/vim/commit/8aefbe0ad5d05ee7225b20024b0f3023286ebd0f
Christian Brabandt <cb@256bit.org>
parents:
8090
diff
changeset
|
5226 ins_complete(int c, int enable_pum) |
7 | 5227 { |
449 | 5228 char_u *line; |
5229 int startcol = 0; /* column where searched text starts */ | |
5230 colnr_T curs_col; /* cursor column */ | |
5231 int n; | |
2107
4a4287c09953
updated for version 7.2.390
Bram Moolenaar <bram@zimbu.org>
parents:
2047
diff
changeset
|
5232 int save_w_wrow; |
11002
35d4975a5bb5
patch 8.0.0390: when the window scrolls the popup menu may be garbled
Christian Brabandt <cb@256bit.org>
parents:
10980
diff
changeset
|
5233 int save_w_leftcol; |
10293
0bf1d211e441
commit https://github.com/vim/vim/commit/9ec7fa82a2c4f0283862ed704c2940959e6130ee
Christian Brabandt <cb@256bit.org>
parents:
10291
diff
changeset
|
5234 int insert_match; |
10916
503b28f0a974
patch 8.0.0347: when using completion comment leader wont work
Christian Brabandt <cb@256bit.org>
parents:
10904
diff
changeset
|
5235 int save_did_ai = did_ai; |
7 | 5236 |
610 | 5237 compl_direction = ins_compl_key2dir(c); |
10293
0bf1d211e441
commit https://github.com/vim/vim/commit/9ec7fa82a2c4f0283862ed704c2940959e6130ee
Christian Brabandt <cb@256bit.org>
parents:
10291
diff
changeset
|
5238 insert_match = ins_compl_use_match(c); |
0bf1d211e441
commit https://github.com/vim/vim/commit/9ec7fa82a2c4f0283862ed704c2940959e6130ee
Christian Brabandt <cb@256bit.org>
parents:
10291
diff
changeset
|
5239 |
449 | 5240 if (!compl_started) |
7 | 5241 { |
5242 /* First time we hit ^N or ^P (in a row, I mean) */ | |
5243 | |
5244 did_ai = FALSE; | |
5245 #ifdef FEAT_SMARTINDENT | |
5246 did_si = FALSE; | |
5247 can_si = FALSE; | |
5248 can_si_back = FALSE; | |
5249 #endif | |
5250 if (stop_arrow() == FAIL) | |
5251 return FAIL; | |
5252 | |
5253 line = ml_get(curwin->w_cursor.lnum); | |
449 | 5254 curs_col = curwin->w_cursor.col; |
716 | 5255 compl_pending = 0; |
7 | 5256 |
1430 | 5257 /* If this same ctrl_x_mode has been interrupted use the text from |
449 | 5258 * "compl_startpos" to the cursor as a pattern to add a new word |
5259 * instead of expand the one before the cursor, in word-wise if | |
1430 | 5260 * "compl_startpos" is not in the same line as the cursor then fix it |
5261 * (the line has been split because it was longer than 'tw'). if SOL | |
5262 * is set then skip the previous pattern, a word at the beginning of | |
5263 * the line has been inserted, we'll look for that -- Acevedo. */ | |
665 | 5264 if ((compl_cont_status & CONT_INTRPT) == CONT_INTRPT |
5265 && compl_cont_mode == ctrl_x_mode) | |
7 | 5266 { |
5267 /* | |
5268 * it is a continued search | |
5269 */ | |
449 | 5270 compl_cont_status &= ~CONT_INTRPT; /* remove INTRPT */ |
13210
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
5271 if (ctrl_x_mode == CTRL_X_NORMAL |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
5272 || ctrl_x_mode == CTRL_X_PATH_PATTERNS |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
5273 || ctrl_x_mode == CTRL_X_PATH_DEFINES) |
7 | 5274 { |
449 | 5275 if (compl_startpos.lnum != curwin->w_cursor.lnum) |
7 | 5276 { |
449 | 5277 /* line (probably) wrapped, set compl_startpos to the |
5278 * first non_blank in the line, if it is not a wordchar | |
5279 * include it to get a better pattern, but then we don't | |
5280 * want the "\\<" prefix, check it bellow */ | |
12323
4dba3e4f3b01
patch 8.0.1041: bogus characters when indenting during visual-block append
Christian Brabandt <cb@256bit.org>
parents:
12293
diff
changeset
|
5281 compl_col = (colnr_T)getwhitecols(line); |
449 | 5282 compl_startpos.col = compl_col; |
5283 compl_startpos.lnum = curwin->w_cursor.lnum; | |
5284 compl_cont_status &= ~CONT_SOL; /* clear SOL if present */ | |
7 | 5285 } |
5286 else | |
5287 { | |
5288 /* S_IPOS was set when we inserted a word that was at the | |
5289 * beginning of the line, which means that we'll go to SOL | |
449 | 5290 * mode but first we need to redefine compl_startpos */ |
5291 if (compl_cont_status & CONT_S_IPOS) | |
7 | 5292 { |
449 | 5293 compl_cont_status |= CONT_SOL; |
5294 compl_startpos.col = (colnr_T)(skipwhite( | |
5295 line + compl_length | |
5296 + compl_startpos.col) - line); | |
7 | 5297 } |
449 | 5298 compl_col = compl_startpos.col; |
7 | 5299 } |
449 | 5300 compl_length = curwin->w_cursor.col - (int)compl_col; |
502 | 5301 /* IObuff is used to add a "word from the next line" would we |
1796 | 5302 * have enough space? just being paranoid */ |
7 | 5303 #define MIN_SPACE 75 |
449 | 5304 if (compl_length > (IOSIZE - MIN_SPACE)) |
7 | 5305 { |
449 | 5306 compl_cont_status &= ~CONT_SOL; |
5307 compl_length = (IOSIZE - MIN_SPACE); | |
5308 compl_col = curwin->w_cursor.col - compl_length; | |
7 | 5309 } |
449 | 5310 compl_cont_status |= CONT_ADDING | CONT_N_ADDS; |
5311 if (compl_length < 1) | |
5312 compl_cont_status &= CONT_LOCAL; | |
7 | 5313 } |
6657 | 5314 else if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)) |
449 | 5315 compl_cont_status = CONT_ADDING | CONT_N_ADDS; |
7 | 5316 else |
449 | 5317 compl_cont_status = 0; |
7 | 5318 } |
5319 else | |
449 | 5320 compl_cont_status &= CONT_LOCAL; |
5321 | |
5322 if (!(compl_cont_status & CONT_ADDING)) /* normal expansion */ | |
5323 { | |
5324 compl_cont_mode = ctrl_x_mode; | |
13210
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
5325 if (ctrl_x_mode != CTRL_X_NORMAL) |
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
5326 /* Remove LOCAL if ctrl_x_mode != CTRL_X_NORMAL */ |
449 | 5327 compl_cont_status = 0; |
5328 compl_cont_status |= CONT_N_ADDS; | |
5329 compl_startpos = curwin->w_cursor; | |
5330 startcol = (int)curs_col; | |
5331 compl_col = 0; | |
7 | 5332 } |
5333 | |
5334 /* Work out completion pattern and original text -- webb */ | |
13210
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
5335 if (ctrl_x_mode == CTRL_X_NORMAL || (ctrl_x_mode & CTRL_X_WANT_IDENT)) |
7 | 5336 { |
449 | 5337 if ((compl_cont_status & CONT_SOL) |
7 | 5338 || ctrl_x_mode == CTRL_X_PATH_DEFINES) |
5339 { | |
449 | 5340 if (!(compl_cont_status & CONT_ADDING)) |
7 | 5341 { |
449 | 5342 while (--startcol >= 0 && vim_isIDc(line[startcol])) |
7 | 5343 ; |
449 | 5344 compl_col += ++startcol; |
5345 compl_length = curs_col - startcol; | |
7 | 5346 } |
5347 if (p_ic) | |
449 | 5348 compl_pattern = str_foldcase(line + compl_col, |
5349 compl_length, NULL, 0); | |
7 | 5350 else |
449 | 5351 compl_pattern = vim_strnsave(line + compl_col, |
5352 compl_length); | |
5353 if (compl_pattern == NULL) | |
7 | 5354 return FAIL; |
5355 } | |
449 | 5356 else if (compl_cont_status & CONT_ADDING) |
7 | 5357 { |
5358 char_u *prefix = (char_u *)"\\<"; | |
5359 | |
1872 | 5360 /* we need up to 2 extra chars for the prefix */ |
449 | 5361 compl_pattern = alloc(quote_meta(NULL, line + compl_col, |
1872 | 5362 compl_length) + 2); |
449 | 5363 if (compl_pattern == NULL) |
7 | 5364 return FAIL; |
449 | 5365 if (!vim_iswordp(line + compl_col) |
5366 || (compl_col > 0 | |
15595
1ec942f1b648
patch 8.1.0805: too many #ifdefs
Bram Moolenaar <Bram@vim.org>
parents:
15569
diff
changeset
|
5367 && (vim_iswordp(mb_prevptr(line, line + compl_col))))) |
7 | 5368 prefix = (char_u *)""; |
449 | 5369 STRCPY((char *)compl_pattern, prefix); |
5370 (void)quote_meta(compl_pattern + STRLEN(prefix), | |
5371 line + compl_col, compl_length); | |
7 | 5372 } |
15595
1ec942f1b648
patch 8.1.0805: too many #ifdefs
Bram Moolenaar <Bram@vim.org>
parents:
15569
diff
changeset
|
5373 else if (--startcol < 0 |
1ec942f1b648
patch 8.1.0805: too many #ifdefs
Bram Moolenaar <Bram@vim.org>
parents:
15569
diff
changeset
|
5374 || !vim_iswordp(mb_prevptr(line, line + startcol + 1))) |
7 | 5375 { |
5376 /* Match any word of at least two chars */ | |
449 | 5377 compl_pattern = vim_strsave((char_u *)"\\<\\k\\k"); |
5378 if (compl_pattern == NULL) | |
7 | 5379 return FAIL; |
449 | 5380 compl_col += curs_col; |
5381 compl_length = 0; | |
7 | 5382 } |
5383 else | |
5384 { | |
5385 /* Search the point of change class of multibyte character | |
5386 * or not a word single byte character backward. */ | |
5387 if (has_mbyte) | |
5388 { | |
5389 int base_class; | |
5390 int head_off; | |
5391 | |
449 | 5392 startcol -= (*mb_head_off)(line, line + startcol); |
5393 base_class = mb_get_class(line + startcol); | |
5394 while (--startcol >= 0) | |
7 | 5395 { |
449 | 5396 head_off = (*mb_head_off)(line, line + startcol); |
5397 if (base_class != mb_get_class(line + startcol | |
5398 - head_off)) | |
7 | 5399 break; |
449 | 5400 startcol -= head_off; |
7 | 5401 } |
5402 } | |
5403 else | |
449 | 5404 while (--startcol >= 0 && vim_iswordc(line[startcol])) |
7 | 5405 ; |
449 | 5406 compl_col += ++startcol; |
5407 compl_length = (int)curs_col - startcol; | |
5408 if (compl_length == 1) | |
7 | 5409 { |
5410 /* Only match word with at least two chars -- webb | |
5411 * there's no need to call quote_meta, | |
5412 * alloc(7) is enough -- Acevedo | |
5413 */ | |
449 | 5414 compl_pattern = alloc(7); |
5415 if (compl_pattern == NULL) | |
7 | 5416 return FAIL; |
449 | 5417 STRCPY((char *)compl_pattern, "\\<"); |
5418 (void)quote_meta(compl_pattern + 2, line + compl_col, 1); | |
5419 STRCAT((char *)compl_pattern, "\\k"); | |
7 | 5420 } |
5421 else | |
5422 { | |
449 | 5423 compl_pattern = alloc(quote_meta(NULL, line + compl_col, |
1872 | 5424 compl_length) + 2); |
449 | 5425 if (compl_pattern == NULL) |
7 | 5426 return FAIL; |
449 | 5427 STRCPY((char *)compl_pattern, "\\<"); |
5428 (void)quote_meta(compl_pattern + 2, line + compl_col, | |
5429 compl_length); | |
7 | 5430 } |
5431 } | |
5432 } | |
6657 | 5433 else if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)) |
7 | 5434 { |
12323
4dba3e4f3b01
patch 8.0.1041: bogus characters when indenting during visual-block append
Christian Brabandt <cb@256bit.org>
parents:
12293
diff
changeset
|
5435 compl_col = (colnr_T)getwhitecols(line); |
449 | 5436 compl_length = (int)curs_col - (int)compl_col; |
5437 if (compl_length < 0) /* cursor in indent: empty pattern */ | |
5438 compl_length = 0; | |
7 | 5439 if (p_ic) |
449 | 5440 compl_pattern = str_foldcase(line + compl_col, compl_length, |
5441 NULL, 0); | |
7 | 5442 else |
449 | 5443 compl_pattern = vim_strnsave(line + compl_col, compl_length); |
5444 if (compl_pattern == NULL) | |
7 | 5445 return FAIL; |
5446 } | |
5447 else if (ctrl_x_mode == CTRL_X_FILES) | |
5448 { | |
5332 | 5449 /* Go back to just before the first filename character. */ |
5349 | 5450 if (startcol > 0) |
5451 { | |
5452 char_u *p = line + startcol; | |
5453 | |
11127
506f5d8b7d8b
patch 8.0.0451: some macros are in lower case
Christian Brabandt <cb@256bit.org>
parents:
11121
diff
changeset
|
5454 MB_PTR_BACK(line, p); |
5349 | 5455 while (p > line && vim_isfilec(PTR2CHAR(p))) |
11127
506f5d8b7d8b
patch 8.0.0451: some macros are in lower case
Christian Brabandt <cb@256bit.org>
parents:
11121
diff
changeset
|
5456 MB_PTR_BACK(line, p); |
5349 | 5457 if (p == line && vim_isfilec(PTR2CHAR(p))) |
5458 startcol = 0; | |
5459 else | |
5460 startcol = (int)(p - line) + 1; | |
5461 } | |
5345 | 5462 |
5463 compl_col += startcol; | |
449 | 5464 compl_length = (int)curs_col - startcol; |
5465 compl_pattern = addstar(line + compl_col, compl_length, | |
5466 EXPAND_FILES); | |
5467 if (compl_pattern == NULL) | |
7 | 5468 return FAIL; |
5469 } | |
5470 else if (ctrl_x_mode == CTRL_X_CMDLINE) | |
5471 { | |
449 | 5472 compl_pattern = vim_strnsave(line, curs_col); |
5473 if (compl_pattern == NULL) | |
7 | 5474 return FAIL; |
449 | 5475 set_cmd_context(&compl_xp, compl_pattern, |
10120
fb040c9d8ce9
commit https://github.com/vim/vim/commit/33a80eeb859a78ba93432da6fa585786cfd77249
Christian Brabandt <cb@256bit.org>
parents:
10042
diff
changeset
|
5476 (int)STRLEN(compl_pattern), curs_col, FALSE); |
449 | 5477 if (compl_xp.xp_context == EXPAND_UNSUCCESSFUL |
5478 || compl_xp.xp_context == EXPAND_NOTHING) | |
935 | 5479 /* No completion possible, use an empty pattern to get a |
5480 * "pattern not found" message. */ | |
897 | 5481 compl_col = curs_col; |
5482 else | |
935 | 5483 compl_col = (int)(compl_xp.xp_pattern - compl_pattern); |
5484 compl_length = curs_col - compl_col; | |
7 | 5485 } |
523 | 5486 else if (ctrl_x_mode == CTRL_X_FUNCTION || ctrl_x_mode == CTRL_X_OMNI) |
502 | 5487 { |
12 | 5488 #ifdef FEAT_COMPL_FUNC |
5489 /* | |
502 | 5490 * Call user defined function 'completefunc' with "a:findstart" |
5491 * set to 1 to obtain the length of text to use for completion. | |
12 | 5492 */ |
14071
c1fcfafa8d1a
patch 8.1.0053: first argument of 'completefunc' has inconsistent type
Christian Brabandt <cb@256bit.org>
parents:
14045
diff
changeset
|
5493 typval_T args[3]; |
452 | 5494 int col; |
502 | 5495 char_u *funcname; |
5496 pos_T pos; | |
2631 | 5497 win_T *curwin_save; |
5498 buf_T *curbuf_save; | |
15377
88b0a490816e
patch 8.1.0696: when test_edit fails 'insertmode' may not be reset
Bram Moolenaar <Bram@vim.org>
parents:
15349
diff
changeset
|
5499 int save_State = State; |
502 | 5500 |
523 | 5501 /* Call 'completefunc' or 'omnifunc' and get pattern length as a |
502 | 5502 * string */ |
5503 funcname = ctrl_x_mode == CTRL_X_FUNCTION | |
5504 ? curbuf->b_p_cfu : curbuf->b_p_ofu; | |
5505 if (*funcname == NUL) | |
523 | 5506 { |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
15440
diff
changeset
|
5507 semsg(_(e_notset), ctrl_x_mode == CTRL_X_FUNCTION |
523 | 5508 ? "completefunc" : "omnifunc"); |
10916
503b28f0a974
patch 8.0.0347: when using completion comment leader wont work
Christian Brabandt <cb@256bit.org>
parents:
10904
diff
changeset
|
5509 /* restore did_ai, so that adding comment leader works */ |
503b28f0a974
patch 8.0.0347: when using completion comment leader wont work
Christian Brabandt <cb@256bit.org>
parents:
10904
diff
changeset
|
5510 did_ai = save_did_ai; |
12 | 5511 return FAIL; |
523 | 5512 } |
452 | 5513 |
14071
c1fcfafa8d1a
patch 8.1.0053: first argument of 'completefunc' has inconsistent type
Christian Brabandt <cb@256bit.org>
parents:
14045
diff
changeset
|
5514 args[0].v_type = VAR_NUMBER; |
c1fcfafa8d1a
patch 8.1.0053: first argument of 'completefunc' has inconsistent type
Christian Brabandt <cb@256bit.org>
parents:
14045
diff
changeset
|
5515 args[0].vval.v_number = 1; |
c1fcfafa8d1a
patch 8.1.0053: first argument of 'completefunc' has inconsistent type
Christian Brabandt <cb@256bit.org>
parents:
14045
diff
changeset
|
5516 args[1].v_type = VAR_STRING; |
c1fcfafa8d1a
patch 8.1.0053: first argument of 'completefunc' has inconsistent type
Christian Brabandt <cb@256bit.org>
parents:
14045
diff
changeset
|
5517 args[1].vval.v_string = (char_u *)""; |
c1fcfafa8d1a
patch 8.1.0053: first argument of 'completefunc' has inconsistent type
Christian Brabandt <cb@256bit.org>
parents:
14045
diff
changeset
|
5518 args[2].v_type = VAR_UNKNOWN; |
502 | 5519 pos = curwin->w_cursor; |
2631 | 5520 curwin_save = curwin; |
5521 curbuf_save = curbuf; | |
14439
e4c553e9132b
patch 8.1.0233: "safe" argument of call_vim_function() is always FALSE
Christian Brabandt <cb@256bit.org>
parents:
14424
diff
changeset
|
5522 col = call_func_retnr(funcname, 2, args); |
15377
88b0a490816e
patch 8.1.0696: when test_edit fails 'insertmode' may not be reset
Bram Moolenaar <Bram@vim.org>
parents:
15349
diff
changeset
|
5523 |
88b0a490816e
patch 8.1.0696: when test_edit fails 'insertmode' may not be reset
Bram Moolenaar <Bram@vim.org>
parents:
15349
diff
changeset
|
5524 State = save_State; |
2631 | 5525 if (curwin_save != curwin || curbuf_save != curbuf) |
5526 { | |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
15440
diff
changeset
|
5527 emsg(_(e_complwin)); |
2631 | 5528 return FAIL; |
5529 } | |
502 | 5530 curwin->w_cursor = pos; /* restore the cursor position */ |
6209 | 5531 validate_cursor(); |
11121
778c10516955
patch 8.0.0448: some macros are in lower case
Christian Brabandt <cb@256bit.org>
parents:
11105
diff
changeset
|
5532 if (!EQUAL_POS(curwin->w_cursor, pos)) |
2631 | 5533 { |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
15440
diff
changeset
|
5534 emsg(_(e_compldel)); |
2631 | 5535 return FAIL; |
5536 } | |
502 | 5537 |
3302 | 5538 /* Return value -2 means the user complete function wants to |
3516 | 5539 * cancel the complete without an error. |
5540 * Return value -3 does the same as -2 and leaves CTRL-X mode.*/ | |
3302 | 5541 if (col == -2) |
5542 return FAIL; | |
3516 | 5543 if (col == -3) |
5544 { | |
13210
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
5545 ctrl_x_mode = CTRL_X_NORMAL; |
3516 | 5546 edit_submode = NULL; |
5946 | 5547 if (!shortmess(SHM_COMPLETIONMENU)) |
5548 msg_clr_cmdline(); | |
3516 | 5549 return FAIL; |
5550 } | |
3302 | 5551 |
3078 | 5552 /* |
5553 * Reset extended parameters of completion, when start new | |
5554 * completion. | |
5555 */ | |
5556 compl_opt_refresh_always = FALSE; | |
15416
5f8ddd2a7b92
patch 8.1.0716: get warning message when 'completefunc' returns nothing
Bram Moolenaar <Bram@vim.org>
parents:
15400
diff
changeset
|
5557 compl_opt_suppress_empty = FALSE; |
3078 | 5558 |
452 | 5559 if (col < 0) |
523 | 5560 col = curs_col; |
452 | 5561 compl_col = col; |
1872 | 5562 if (compl_col > curs_col) |
452 | 5563 compl_col = curs_col; |
449 | 5564 |
5565 /* Setup variables for completion. Need to obtain "line" again, | |
5566 * it may have become invalid. */ | |
5567 line = ml_get(curwin->w_cursor.lnum); | |
452 | 5568 compl_length = curs_col - compl_col; |
449 | 5569 compl_pattern = vim_strnsave(line + compl_col, compl_length); |
5570 if (compl_pattern == NULL) | |
502 | 5571 #endif |
449 | 5572 return FAIL; |
5573 } | |
477 | 5574 else if (ctrl_x_mode == CTRL_X_SPELL) |
5575 { | |
744 | 5576 #ifdef FEAT_SPELL |
497 | 5577 if (spell_bad_len > 0) |
5578 compl_col = curs_col - spell_bad_len; | |
5579 else | |
5580 compl_col = spell_word_start(startcol); | |
5581 if (compl_col >= (colnr_T)startcol) | |
897 | 5582 { |
5583 compl_length = 0; | |
5584 compl_col = curs_col; | |
5585 } | |
5586 else | |
5587 { | |
5588 spell_expand_check_cap(compl_col); | |
5589 compl_length = (int)curs_col - compl_col; | |
5590 } | |
818 | 5591 /* Need to obtain "line" again, it may have become invalid. */ |
5592 line = ml_get(curwin->w_cursor.lnum); | |
477 | 5593 compl_pattern = vim_strnsave(line + compl_col, compl_length); |
5594 if (compl_pattern == NULL) | |
5595 #endif | |
5596 return FAIL; | |
5597 } | |
449 | 5598 else |
5599 { | |
10359
66f1b5bf3fa6
commit https://github.com/vim/vim/commit/95f096030ed1a8afea028f2ea295d6f6a70f466f
Christian Brabandt <cb@256bit.org>
parents:
10293
diff
changeset
|
5600 internal_error("ins_complete()"); |
449 | 5601 return FAIL; |
5602 } | |
5603 | |
5604 if (compl_cont_status & CONT_ADDING) | |
7 | 5605 { |
5606 edit_submode_pre = (char_u *)_(" Adding"); | |
6657 | 5607 if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)) |
7 | 5608 { |
5609 /* Insert a new line, keep indentation but ignore 'comments' */ | |
5610 #ifdef FEAT_COMMENTS | |
5611 char_u *old = curbuf->b_p_com; | |
5612 | |
5613 curbuf->b_p_com = (char_u *)""; | |
5614 #endif | |
449 | 5615 compl_startpos.lnum = curwin->w_cursor.lnum; |
5616 compl_startpos.col = compl_col; | |
7 | 5617 ins_eol('\r'); |
5618 #ifdef FEAT_COMMENTS | |
5619 curbuf->b_p_com = old; | |
5620 #endif | |
449 | 5621 compl_length = 0; |
5622 compl_col = curwin->w_cursor.col; | |
7 | 5623 } |
5624 } | |
5625 else | |
5626 { | |
5627 edit_submode_pre = NULL; | |
449 | 5628 compl_startpos.col = compl_col; |
5629 } | |
5630 | |
5631 if (compl_cont_status & CONT_LOCAL) | |
5632 edit_submode = (char_u *)_(ctrl_x_msgs[CTRL_X_LOCAL_MSG]); | |
7 | 5633 else |
5634 edit_submode = (char_u *)_(CTRL_X_MSG(ctrl_x_mode)); | |
5635 | |
3095 | 5636 /* If any of the original typed text has been changed we need to fix |
5637 * the redo buffer. */ | |
5638 ins_compl_fixRedoBufForLeader(NULL); | |
5639 | |
694 | 5640 /* Always add completion for the original text. */ |
5641 vim_free(compl_orig_text); | |
449 | 5642 compl_orig_text = vim_strnsave(line + compl_col, compl_length); |
5643 if (compl_orig_text == NULL || ins_compl_add(compl_orig_text, | |
942 | 5644 -1, p_ic, NULL, NULL, 0, ORIGINAL_TEXT, FALSE) != OK) |
449 | 5645 { |
13244
ac42c4b11dbc
patch 8.0.1496: clearing a pointer takes two lines
Christian Brabandt <cb@256bit.org>
parents:
13240
diff
changeset
|
5646 VIM_CLEAR(compl_pattern); |
ac42c4b11dbc
patch 8.0.1496: clearing a pointer takes two lines
Christian Brabandt <cb@256bit.org>
parents:
13240
diff
changeset
|
5647 VIM_CLEAR(compl_orig_text); |
7 | 5648 return FAIL; |
5649 } | |
5650 | |
5651 /* showmode might reset the internal line pointers, so it must | |
5652 * be called before line = ml_get(), or when this address is no | |
5653 * longer needed. -- Acevedo. | |
5654 */ | |
5655 edit_submode_extra = (char_u *)_("-- Searching..."); | |
5656 edit_submode_highl = HLF_COUNT; | |
5657 showmode(); | |
5658 edit_submode_extra = NULL; | |
5659 out_flush(); | |
5660 } | |
10293
0bf1d211e441
commit https://github.com/vim/vim/commit/9ec7fa82a2c4f0283862ed704c2940959e6130ee
Christian Brabandt <cb@256bit.org>
parents:
10291
diff
changeset
|
5661 else if (insert_match && stop_arrow() == FAIL) |
0bf1d211e441
commit https://github.com/vim/vim/commit/9ec7fa82a2c4f0283862ed704c2940959e6130ee
Christian Brabandt <cb@256bit.org>
parents:
10291
diff
changeset
|
5662 return FAIL; |
7 | 5663 |
449 | 5664 compl_shown_match = compl_curr_match; |
5665 compl_shows_dir = compl_direction; | |
7 | 5666 |
5667 /* | |
665 | 5668 * Find next match (and following matches). |
7 | 5669 */ |
2107
4a4287c09953
updated for version 7.2.390
Bram Moolenaar <bram@zimbu.org>
parents:
2047
diff
changeset
|
5670 save_w_wrow = curwin->w_wrow; |
11002
35d4975a5bb5
patch 8.0.0390: when the window scrolls the popup menu may be garbled
Christian Brabandt <cb@256bit.org>
parents:
10980
diff
changeset
|
5671 save_w_leftcol = curwin->w_leftcol; |
10293
0bf1d211e441
commit https://github.com/vim/vim/commit/9ec7fa82a2c4f0283862ed704c2940959e6130ee
Christian Brabandt <cb@256bit.org>
parents:
10291
diff
changeset
|
5672 n = ins_compl_next(TRUE, ins_compl_key2count(c), insert_match, FALSE); |
449 | 5673 |
540 | 5674 /* may undisplay the popup menu */ |
5675 ins_compl_upd_pum(); | |
5676 | |
449 | 5677 if (n > 1) /* all matches have been found */ |
5678 compl_matches = n; | |
5679 compl_curr_match = compl_shown_match; | |
5680 compl_direction = compl_shows_dir; | |
857 | 5681 |
5682 /* Eat the ESC that vgetc() returns after a CTRL-C to avoid leaving Insert | |
5683 * mode. */ | |
7 | 5684 if (got_int && !global_busy) |
5685 { | |
5686 (void)vgetc(); | |
5687 got_int = FALSE; | |
5688 } | |
5689 | |
449 | 5690 /* we found no match if the list has only the "compl_orig_text"-entry */ |
464 | 5691 if (compl_first_match == compl_first_match->cp_next) |
449 | 5692 { |
5693 edit_submode_extra = (compl_cont_status & CONT_ADDING) | |
5694 && compl_length > 1 | |
7 | 5695 ? (char_u *)_(e_hitend) : (char_u *)_(e_patnotf); |
5696 edit_submode_highl = HLF_E; | |
5697 /* remove N_ADDS flag, so next ^X<> won't try to go to ADDING mode, | |
5698 * because we couldn't expand anything at first place, but if we used | |
5699 * ^P, ^N, ^X^I or ^X^D we might want to add-expand a single-char-word | |
5700 * (such as M in M'exico) if not tried already. -- Acevedo */ | |
449 | 5701 if ( compl_length > 1 |
5702 || (compl_cont_status & CONT_ADDING) | |
13210
c1534eb682a6
patch 8.0.1479: insert mode completion state is confusing
Christian Brabandt <cb@256bit.org>
parents:
13150
diff
changeset
|
5703 || (ctrl_x_mode != CTRL_X_NORMAL |
7 | 5704 && ctrl_x_mode != CTRL_X_PATH_PATTERNS |
5705 && ctrl_x_mode != CTRL_X_PATH_DEFINES)) | |
449 | 5706 compl_cont_status &= ~CONT_N_ADDS; |
5707 } | |
5708 | |
464 | 5709 if (compl_curr_match->cp_flags & CONT_S_IPOS) |
449 | 5710 compl_cont_status |= CONT_S_IPOS; |
7 | 5711 else |
449 | 5712 compl_cont_status &= ~CONT_S_IPOS; |
7 | 5713 |
5714 if (edit_submode_extra == NULL) | |
5715 { | |
464 | 5716 if (compl_curr_match->cp_flags & ORIGINAL_TEXT) |
7 | 5717 { |
5718 edit_submode_extra = (char_u *)_("Back at original"); | |
5719 edit_submode_highl = HLF_W; | |
5720 } | |
449 | 5721 else if (compl_cont_status & CONT_S_IPOS) |
7 | 5722 { |
5723 edit_submode_extra = (char_u *)_("Word from other line"); | |
5724 edit_submode_highl = HLF_COUNT; | |
5725 } | |
464 | 5726 else if (compl_curr_match->cp_next == compl_curr_match->cp_prev) |
7 | 5727 { |
5728 edit_submode_extra = (char_u *)_("The only match"); | |
5729 edit_submode_highl = HLF_COUNT; | |
5730 } | |
5731 else | |
5732 { | |
5733 /* Update completion sequence number when needed. */ | |
464 | 5734 if (compl_curr_match->cp_number == -1) |
7 | 5735 { |
464 | 5736 int number = 0; |
5737 compl_T *match; | |
7 | 5738 |
449 | 5739 if (compl_direction == FORWARD) |
7 | 5740 { |
5741 /* search backwards for the first valid (!= -1) number. | |
5742 * This should normally succeed already at the first loop | |
5743 * cycle, so it's fast! */ | |
464 | 5744 for (match = compl_curr_match->cp_prev; match != NULL |
5745 && match != compl_first_match; | |
5746 match = match->cp_prev) | |
5747 if (match->cp_number != -1) | |
7 | 5748 { |
464 | 5749 number = match->cp_number; |
7 | 5750 break; |
5751 } | |
5752 if (match != NULL) | |
5753 /* go up and assign all numbers which are not assigned | |
5754 * yet */ | |
540 | 5755 for (match = match->cp_next; |
5756 match != NULL && match->cp_number == -1; | |
464 | 5757 match = match->cp_next) |
5758 match->cp_number = ++number; | |
7 | 5759 } |
5760 else /* BACKWARD */ | |
5761 { | |
5762 /* search forwards (upwards) for the first valid (!= -1) | |
5763 * number. This should normally succeed already at the | |
5764 * first loop cycle, so it's fast! */ | |
464 | 5765 for (match = compl_curr_match->cp_next; match != NULL |
5766 && match != compl_first_match; | |
5767 match = match->cp_next) | |
5768 if (match->cp_number != -1) | |
7 | 5769 { |
464 | 5770 number = match->cp_number; |
7 | 5771 break; |
5772 } | |
5773 if (match != NULL) | |
5774 /* go down and assign all numbers which are not | |
5775 * assigned yet */ | |
464 | 5776 for (match = match->cp_prev; match |
5777 && match->cp_number == -1; | |
5778 match = match->cp_prev) | |
5779 match->cp_number = ++number; | |
7 | 5780 } |
5781 } | |
5782 | |
540 | 5783 /* The match should always have a sequence number now, this is |
5784 * just a safety check. */ | |
464 | 5785 if (compl_curr_match->cp_number != -1) |
7 | 5786 { |
1063 | 5787 /* Space for 10 text chars. + 2x10-digit no.s = 31. |
5788 * Translations may need more than twice that. */ | |
5789 static char_u match_ref[81]; | |
7 | 5790 |
449 | 5791 if (compl_matches > 0) |
1063 | 5792 vim_snprintf((char *)match_ref, sizeof(match_ref), |
5793 _("match %d of %d"), | |
464 | 5794 compl_curr_match->cp_number, compl_matches); |
7 | 5795 else |
1063 | 5796 vim_snprintf((char *)match_ref, sizeof(match_ref), |
5797 _("match %d"), | |
5798 compl_curr_match->cp_number); | |
7 | 5799 edit_submode_extra = match_ref; |
5800 edit_submode_highl = HLF_R; | |
3318 | 5801 if (dollar_vcol >= 0) |
7 | 5802 curs_columns(FALSE); |
5803 } | |
5804 } | |
5805 } | |
5806 | |
15416
5f8ddd2a7b92
patch 8.1.0716: get warning message when 'completefunc' returns nothing
Bram Moolenaar <Bram@vim.org>
parents:
15400
diff
changeset
|
5807 // Show a message about what (completion) mode we're in. |
5f8ddd2a7b92
patch 8.1.0716: get warning message when 'completefunc' returns nothing
Bram Moolenaar <Bram@vim.org>
parents:
15400
diff
changeset
|
5808 if (!compl_opt_suppress_empty) |
5f8ddd2a7b92
patch 8.1.0716: get warning message when 'completefunc' returns nothing
Bram Moolenaar <Bram@vim.org>
parents:
15400
diff
changeset
|
5809 { |
5f8ddd2a7b92
patch 8.1.0716: get warning message when 'completefunc' returns nothing
Bram Moolenaar <Bram@vim.org>
parents:
15400
diff
changeset
|
5810 showmode(); |
5f8ddd2a7b92
patch 8.1.0716: get warning message when 'completefunc' returns nothing
Bram Moolenaar <Bram@vim.org>
parents:
15400
diff
changeset
|
5811 if (!shortmess(SHM_COMPLETIONMENU)) |
5f8ddd2a7b92
patch 8.1.0716: get warning message when 'completefunc' returns nothing
Bram Moolenaar <Bram@vim.org>
parents:
15400
diff
changeset
|
5812 { |
5f8ddd2a7b92
patch 8.1.0716: get warning message when 'completefunc' returns nothing
Bram Moolenaar <Bram@vim.org>
parents:
15400
diff
changeset
|
5813 if (edit_submode_extra != NULL) |
5f8ddd2a7b92
patch 8.1.0716: get warning message when 'completefunc' returns nothing
Bram Moolenaar <Bram@vim.org>
parents:
15400
diff
changeset
|
5814 { |
5f8ddd2a7b92
patch 8.1.0716: get warning message when 'completefunc' returns nothing
Bram Moolenaar <Bram@vim.org>
parents:
15400
diff
changeset
|
5815 if (!p_smd) |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15521
diff
changeset
|
5816 msg_attr((char *)edit_submode_extra, |
15416
5f8ddd2a7b92
patch 8.1.0716: get warning message when 'completefunc' returns nothing
Bram Moolenaar <Bram@vim.org>
parents:
15400
diff
changeset
|
5817 edit_submode_highl < HLF_COUNT |
5f8ddd2a7b92
patch 8.1.0716: get warning message when 'completefunc' returns nothing
Bram Moolenaar <Bram@vim.org>
parents:
15400
diff
changeset
|
5818 ? HL_ATTR(edit_submode_highl) : 0); |
5f8ddd2a7b92
patch 8.1.0716: get warning message when 'completefunc' returns nothing
Bram Moolenaar <Bram@vim.org>
parents:
15400
diff
changeset
|
5819 } |
5f8ddd2a7b92
patch 8.1.0716: get warning message when 'completefunc' returns nothing
Bram Moolenaar <Bram@vim.org>
parents:
15400
diff
changeset
|
5820 else |
5f8ddd2a7b92
patch 8.1.0716: get warning message when 'completefunc' returns nothing
Bram Moolenaar <Bram@vim.org>
parents:
15400
diff
changeset
|
5821 msg_clr_cmdline(); // necessary for "noshowmode" |
5f8ddd2a7b92
patch 8.1.0716: get warning message when 'completefunc' returns nothing
Bram Moolenaar <Bram@vim.org>
parents:
15400
diff
changeset
|
5822 } |
5946 | 5823 } |
7 | 5824 |
857 | 5825 /* Show the popup menu, unless we got interrupted. */ |
8224
2baf64fead5e
commit https://github.com/vim/vim/commit/8aefbe0ad5d05ee7225b20024b0f3023286ebd0f
Christian Brabandt <cb@256bit.org>
parents:
8090
diff
changeset
|
5826 if (enable_pum && !compl_interrupted) |
11002
35d4975a5bb5
patch 8.0.0390: when the window scrolls the popup menu may be garbled
Christian Brabandt <cb@256bit.org>
parents:
10980
diff
changeset
|
5827 show_pum(save_w_wrow, save_w_leftcol); |
35d4975a5bb5
patch 8.0.0390: when the window scrolls the popup menu may be garbled
Christian Brabandt <cb@256bit.org>
parents:
10980
diff
changeset
|
5828 |
874 | 5829 compl_was_interrupted = compl_interrupted; |
857 | 5830 compl_interrupted = FALSE; |
540 | 5831 |
7 | 5832 return OK; |
5833 } | |
5834 | |
8224
2baf64fead5e
commit https://github.com/vim/vim/commit/8aefbe0ad5d05ee7225b20024b0f3023286ebd0f
Christian Brabandt <cb@256bit.org>
parents:
8090
diff
changeset
|
5835 static void |
11002
35d4975a5bb5
patch 8.0.0390: when the window scrolls the popup menu may be garbled
Christian Brabandt <cb@256bit.org>
parents:
10980
diff
changeset
|
5836 show_pum(int prev_w_wrow, int prev_w_leftcol) |
35d4975a5bb5
patch 8.0.0390: when the window scrolls the popup menu may be garbled
Christian Brabandt <cb@256bit.org>
parents:
10980
diff
changeset
|
5837 { |
35d4975a5bb5
patch 8.0.0390: when the window scrolls the popup menu may be garbled
Christian Brabandt <cb@256bit.org>
parents:
10980
diff
changeset
|
5838 /* RedrawingDisabled may be set when invoked through complete(). */ |
35d4975a5bb5
patch 8.0.0390: when the window scrolls the popup menu may be garbled
Christian Brabandt <cb@256bit.org>
parents:
10980
diff
changeset
|
5839 int n = RedrawingDisabled; |
35d4975a5bb5
patch 8.0.0390: when the window scrolls the popup menu may be garbled
Christian Brabandt <cb@256bit.org>
parents:
10980
diff
changeset
|
5840 |
35d4975a5bb5
patch 8.0.0390: when the window scrolls the popup menu may be garbled
Christian Brabandt <cb@256bit.org>
parents:
10980
diff
changeset
|
5841 RedrawingDisabled = 0; |
35d4975a5bb5
patch 8.0.0390: when the window scrolls the popup menu may be garbled
Christian Brabandt <cb@256bit.org>
parents:
10980
diff
changeset
|
5842 |
35d4975a5bb5
patch 8.0.0390: when the window scrolls the popup menu may be garbled
Christian Brabandt <cb@256bit.org>
parents:
10980
diff
changeset
|
5843 /* If the cursor moved or the display scrolled we need to remove the pum |
35d4975a5bb5
patch 8.0.0390: when the window scrolls the popup menu may be garbled
Christian Brabandt <cb@256bit.org>
parents:
10980
diff
changeset
|
5844 * first. */ |
35d4975a5bb5
patch 8.0.0390: when the window scrolls the popup menu may be garbled
Christian Brabandt <cb@256bit.org>
parents:
10980
diff
changeset
|
5845 setcursor(); |
35d4975a5bb5
patch 8.0.0390: when the window scrolls the popup menu may be garbled
Christian Brabandt <cb@256bit.org>
parents:
10980
diff
changeset
|
5846 if (prev_w_wrow != curwin->w_wrow || prev_w_leftcol != curwin->w_leftcol) |
35d4975a5bb5
patch 8.0.0390: when the window scrolls the popup menu may be garbled
Christian Brabandt <cb@256bit.org>
parents:
10980
diff
changeset
|
5847 ins_compl_del_pum(); |
35d4975a5bb5
patch 8.0.0390: when the window scrolls the popup menu may be garbled
Christian Brabandt <cb@256bit.org>
parents:
10980
diff
changeset
|
5848 |
35d4975a5bb5
patch 8.0.0390: when the window scrolls the popup menu may be garbled
Christian Brabandt <cb@256bit.org>
parents:
10980
diff
changeset
|
5849 ins_compl_show_pum(); |
35d4975a5bb5
patch 8.0.0390: when the window scrolls the popup menu may be garbled
Christian Brabandt <cb@256bit.org>
parents:
10980
diff
changeset
|
5850 setcursor(); |
35d4975a5bb5
patch 8.0.0390: when the window scrolls the popup menu may be garbled
Christian Brabandt <cb@256bit.org>
parents:
10980
diff
changeset
|
5851 RedrawingDisabled = n; |
8224
2baf64fead5e
commit https://github.com/vim/vim/commit/8aefbe0ad5d05ee7225b20024b0f3023286ebd0f
Christian Brabandt <cb@256bit.org>
parents:
8090
diff
changeset
|
5852 } |
2baf64fead5e
commit https://github.com/vim/vim/commit/8aefbe0ad5d05ee7225b20024b0f3023286ebd0f
Christian Brabandt <cb@256bit.org>
parents:
8090
diff
changeset
|
5853 |
7 | 5854 /* |
5855 * Looks in the first "len" chars. of "src" for search-metachars. | |
5856 * If dest is not NULL the chars. are copied there quoting (with | |
5857 * a backslash) the metachars, and dest would be NUL terminated. | |
5858 * Returns the length (needed) of dest | |
5859 */ | |
1872 | 5860 static unsigned |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
5861 quote_meta(char_u *dest, char_u *src, int len) |
7 | 5862 { |
1872 | 5863 unsigned m = (unsigned)len + 1; /* one extra for the NUL */ |
5864 | |
5865 for ( ; --len >= 0; src++) | |
7 | 5866 { |
5867 switch (*src) | |
5868 { | |
5869 case '.': | |
5870 case '*': | |
5871 case '[': | |
5872 if (ctrl_x_mode == CTRL_X_DICTIONARY | |
5873 || ctrl_x_mode == CTRL_X_THESAURUS) | |
5874 break; | |
12674
e769c912fcd9
patch 8.0.1215: newer gcc warns for implicit fallthrough
Christian Brabandt <cb@256bit.org>
parents:
12551
diff
changeset
|
5875 /* FALLTHROUGH */ |
7 | 5876 case '~': |
5877 if (!p_magic) /* quote these only if magic is set */ | |
5878 break; | |
12674
e769c912fcd9
patch 8.0.1215: newer gcc warns for implicit fallthrough
Christian Brabandt <cb@256bit.org>
parents:
12551
diff
changeset
|
5879 /* FALLTHROUGH */ |
7 | 5880 case '\\': |
5881 if (ctrl_x_mode == CTRL_X_DICTIONARY | |
5882 || ctrl_x_mode == CTRL_X_THESAURUS) | |
5883 break; | |
12674
e769c912fcd9
patch 8.0.1215: newer gcc warns for implicit fallthrough
Christian Brabandt <cb@256bit.org>
parents:
12551
diff
changeset
|
5884 /* FALLTHROUGH */ |
7 | 5885 case '^': /* currently it's not needed. */ |
5886 case '$': | |
5887 m++; | |
5888 if (dest != NULL) | |
5889 *dest++ = '\\'; | |
5890 break; | |
5891 } | |
5892 if (dest != NULL) | |
5893 *dest++ = *src; | |
5894 /* Copy remaining bytes of a multibyte character. */ | |
5895 if (has_mbyte) | |
5896 { | |
5897 int i, mb_len; | |
5898 | |
474 | 5899 mb_len = (*mb_ptr2len)(src) - 1; |
7 | 5900 if (mb_len > 0 && len >= mb_len) |
5901 for (i = 0; i < mb_len; ++i) | |
5902 { | |
5903 --len; | |
5904 ++src; | |
5905 if (dest != NULL) | |
5906 *dest++ = *src; | |
5907 } | |
5908 } | |
5909 } | |
5910 if (dest != NULL) | |
5911 *dest = NUL; | |
5912 | |
5913 return m; | |
5914 } | |
5915 #endif /* FEAT_INS_EXPAND */ | |
5916 | |
5917 /* | |
5918 * Next character is interpreted literally. | |
5919 * A one, two or three digit decimal number is interpreted as its byte value. | |
5920 * If one or two digits are entered, the next character is given to vungetc(). | |
5921 * For Unicode a character > 255 may be returned. | |
5922 */ | |
5923 int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
5924 get_literal(void) |
7 | 5925 { |
5926 int cc; | |
5927 int nc; | |
5928 int i; | |
5929 int hex = FALSE; | |
5930 int octal = FALSE; | |
5931 int unicode = 0; | |
5932 | |
5933 if (got_int) | |
5934 return Ctrl_C; | |
5935 | |
5936 #ifdef FEAT_GUI | |
5937 /* | |
5938 * In GUI there is no point inserting the internal code for a special key. | |
5939 * It is more useful to insert the string "<KEY>" instead. This would | |
5940 * probably be useful in a text window too, but it would not be | |
5941 * vi-compatible (maybe there should be an option for it?) -- webb | |
5942 */ | |
5943 if (gui.in_use) | |
5944 ++allow_keys; | |
5945 #endif | |
5946 #ifdef USE_ON_FLY_SCROLL | |
5947 dont_scroll = TRUE; /* disallow scrolling here */ | |
5948 #endif | |
5949 ++no_mapping; /* don't map the next key hits */ | |
5950 cc = 0; | |
5951 i = 0; | |
5952 for (;;) | |
5953 { | |
1389 | 5954 nc = plain_vgetc(); |
7 | 5955 #ifdef FEAT_CMDL_INFO |
15595
1ec942f1b648
patch 8.1.0805: too many #ifdefs
Bram Moolenaar <Bram@vim.org>
parents:
15569
diff
changeset
|
5956 if (!(State & CMDLINE) && MB_BYTE2LEN_CHECK(nc) == 1) |
7 | 5957 add_to_showcmd(nc); |
5958 #endif | |
5959 if (nc == 'x' || nc == 'X') | |
5960 hex = TRUE; | |
5961 else if (nc == 'o' || nc == 'O') | |
5962 octal = TRUE; | |
5963 else if (nc == 'u' || nc == 'U') | |
5964 unicode = nc; | |
5965 else | |
5966 { | |
15595
1ec942f1b648
patch 8.1.0805: too many #ifdefs
Bram Moolenaar <Bram@vim.org>
parents:
15569
diff
changeset
|
5967 if (hex || unicode != 0) |
7 | 5968 { |
5969 if (!vim_isxdigit(nc)) | |
5970 break; | |
5971 cc = cc * 16 + hex2nr(nc); | |
5972 } | |
5973 else if (octal) | |
5974 { | |
5975 if (nc < '0' || nc > '7') | |
5976 break; | |
5977 cc = cc * 8 + nc - '0'; | |
5978 } | |
5979 else | |
5980 { | |
5981 if (!VIM_ISDIGIT(nc)) | |
5982 break; | |
5983 cc = cc * 10 + nc - '0'; | |
5984 } | |
5985 | |
5986 ++i; | |
5987 } | |
5988 | |
15595
1ec942f1b648
patch 8.1.0805: too many #ifdefs
Bram Moolenaar <Bram@vim.org>
parents:
15569
diff
changeset
|
5989 if (cc > 255 && unicode == 0) |
7 | 5990 cc = 255; /* limit range to 0-255 */ |
5991 nc = 0; | |
5992 | |
5993 if (hex) /* hex: up to two chars */ | |
5994 { | |
5995 if (i >= 2) | |
5996 break; | |
5997 } | |
5998 else if (unicode) /* Unicode: up to four or eight chars */ | |
5999 { | |
6000 if ((unicode == 'u' && i >= 4) || (unicode == 'U' && i >= 8)) | |
6001 break; | |
6002 } | |
6003 else if (i >= 3) /* decimal or octal: up to three chars */ | |
6004 break; | |
6005 } | |
6006 if (i == 0) /* no number entered */ | |
6007 { | |
6008 if (nc == K_ZERO) /* NUL is stored as NL */ | |
6009 { | |
6010 cc = '\n'; | |
6011 nc = 0; | |
6012 } | |
6013 else | |
6014 { | |
6015 cc = nc; | |
6016 nc = 0; | |
6017 } | |
6018 } | |
6019 | |
6020 if (cc == 0) /* NUL is stored as NL */ | |
6021 cc = '\n'; | |
221 | 6022 if (enc_dbcs && (cc & 0xff) == 0) |
6023 cc = '?'; /* don't accept an illegal DBCS char, the NUL in the | |
6024 second byte will cause trouble! */ | |
7 | 6025 |
6026 --no_mapping; | |
6027 #ifdef FEAT_GUI | |
6028 if (gui.in_use) | |
6029 --allow_keys; | |
6030 #endif | |
6031 if (nc) | |
6032 vungetc(nc); | |
6033 got_int = FALSE; /* CTRL-C typed after CTRL-V is not an interrupt */ | |
6034 return cc; | |
6035 } | |
6036 | |
6037 /* | |
6038 * Insert character, taking care of special keys and mod_mask | |
6039 */ | |
6040 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
6041 insert_special( |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
6042 int c, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
6043 int allow_modmask, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
6044 int ctrlv) /* c was typed after CTRL-V */ |
7 | 6045 { |
6046 char_u *p; | |
6047 int len; | |
6048 | |
6049 /* | |
6050 * Special function key, translate into "<Key>". Up to the last '>' is | |
6051 * inserted with ins_str(), so as not to replace characters in replace | |
6052 * mode. | |
6053 * Only use mod_mask for special keys, to avoid things like <S-Space>, | |
6054 * unless 'allow_modmask' is TRUE. | |
6055 */ | |
12716
351cf7c67bbe
patch 8.0.1236: Mac features are confusing
Christian Brabandt <cb@256bit.org>
parents:
12674
diff
changeset
|
6056 #ifdef MACOS_X |
7 | 6057 /* Command-key never produces a normal key */ |
6058 if (mod_mask & MOD_MASK_CMD) | |
6059 allow_modmask = TRUE; | |
6060 #endif | |
6061 if (IS_SPECIAL(c) || (mod_mask && allow_modmask)) | |
6062 { | |
6063 p = get_special_key_name(c, mod_mask); | |
6064 len = (int)STRLEN(p); | |
6065 c = p[len - 1]; | |
6066 if (len > 2) | |
6067 { | |
6068 if (stop_arrow() == FAIL) | |
6069 return; | |
6070 p[len - 1] = NUL; | |
6071 ins_str(p); | |
620 | 6072 AppendToRedobuffLit(p, -1); |
7 | 6073 ctrlv = FALSE; |
6074 } | |
6075 } | |
6076 if (stop_arrow() == OK) | |
6077 insertchar(c, ctrlv ? INSCHAR_CTRLV : 0, -1); | |
6078 } | |
6079 | |
6080 /* | |
6081 * Special characters in this context are those that need processing other | |
6082 * than the simple insertion that can be performed here. This includes ESC | |
6083 * which terminates the insert, and CR/NL which need special processing to | |
6084 * open up a new line. This routine tries to optimize insertions performed by | |
6085 * the "redo", "undo" or "put" commands, so it needs to know when it should | |
6086 * stop and defer processing to the "normal" mechanism. | |
6087 * '0' and '^' are special, because they can be followed by CTRL-D. | |
6088 */ | |
6089 #ifdef EBCDIC | |
6090 # define ISSPECIAL(c) ((c) < ' ' || (c) == '0' || (c) == '^') | |
6091 #else | |
6092 # define ISSPECIAL(c) ((c) < ' ' || (c) >= DEL || (c) == '0' || (c) == '^') | |
6093 #endif | |
6094 | |
15595
1ec942f1b648
patch 8.1.0805: too many #ifdefs
Bram Moolenaar <Bram@vim.org>
parents:
15569
diff
changeset
|
6095 #define WHITECHAR(cc) (VIM_ISWHITE(cc) && (!enc_utf8 || !utf_iscomposing(utf_ptr2char(ml_get_cursor() + 1)))) |
7 | 6096 |
3584 | 6097 /* |
6098 * "flags": INSCHAR_FORMAT - force formatting | |
6099 * INSCHAR_CTRLV - char typed just after CTRL-V | |
6100 * INSCHAR_NO_FEX - don't use 'formatexpr' | |
6101 * | |
6102 * NOTE: passes the flags value straight through to internal_format() which, | |
6103 * beside INSCHAR_FORMAT (above), is also looking for these: | |
6104 * INSCHAR_DO_COM - format comments | |
6105 * INSCHAR_COM_LIST - format comments with num list or 2nd line indent | |
6106 */ | |
7 | 6107 void |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
6108 insertchar( |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
6109 int c, /* character to insert or NUL */ |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
6110 int flags, /* INSCHAR_FORMAT, etc. */ |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
6111 int second_indent) /* indent for second line if >= 0 */ |
7 | 6112 { |
6113 int textwidth; | |
6114 #ifdef FEAT_COMMENTS | |
6115 char_u *p; | |
667 | 6116 #endif |
7 | 6117 int fo_ins_blank; |
6667 | 6118 int force_format = flags & INSCHAR_FORMAT; |
6119 | |
6120 textwidth = comp_textwidth(force_format); | |
7 | 6121 fo_ins_blank = has_format_option(FO_INS_BLANK); |
6122 | |
6123 /* | |
6124 * Try to break the line in two or more pieces when: | |
6125 * - Always do this if we have been called to do formatting only. | |
6126 * - Always do this when 'formatoptions' has the 'a' flag and the line | |
6127 * ends in white space. | |
6128 * - Otherwise: | |
6129 * - Don't do this if inserting a blank | |
6130 * - Don't do this if an existing character is being replaced, unless | |
6131 * we're in VREPLACE mode. | |
6132 * - Do this if the cursor is not on the line where insert started | |
6133 * or - 'formatoptions' doesn't have 'l' or the line was not too long | |
6134 * before the insert. | |
6135 * - 'formatoptions' doesn't have 'b' or a blank was inserted at or | |
6136 * before 'textwidth' | |
6137 */ | |
667 | 6138 if (textwidth > 0 |
6667 | 6139 && (force_format |
11129
f4ea50924c6d
patch 8.0.0452: some macros are in lower case
Christian Brabandt <cb@256bit.org>
parents:
11127
diff
changeset
|
6140 || (!VIM_ISWHITE(c) |
7 | 6141 && !((State & REPLACE_FLAG) |
6142 && !(State & VREPLACE_FLAG) | |
6143 && *ml_get_cursor() != NUL) | |
6144 && (curwin->w_cursor.lnum != Insstart.lnum | |
6145 || ((!has_format_option(FO_INS_LONG) | |
6146 || Insstart_textlen <= (colnr_T)textwidth) | |
6147 && (!fo_ins_blank | |
6148 || Insstart_blank_vcol <= (colnr_T)textwidth | |
6149 )))))) | |
6150 { | |
667 | 6151 /* Format with 'formatexpr' when it's set. Use internal formatting |
6152 * when 'formatexpr' isn't set or it returns non-zero. */ | |
6153 #if defined(FEAT_EVAL) | |
6667 | 6154 int do_internal = TRUE; |
6155 colnr_T virtcol = get_nolist_virtcol() | |
6156 + char2cells(c != NUL ? c : gchar_cursor()); | |
6157 | |
6158 if (*curbuf->b_p_fex != NUL && (flags & INSCHAR_NO_FEX) == 0 | |
6159 && (force_format || virtcol > (colnr_T)textwidth)) | |
1000 | 6160 { |
6161 do_internal = (fex_format(curwin->w_cursor.lnum, 1L, c) != 0); | |
6162 /* It may be required to save for undo again, e.g. when setline() | |
6163 * was called. */ | |
6164 ins_need_undo = TRUE; | |
6165 } | |
6166 if (do_internal) | |
667 | 6167 #endif |
2004 | 6168 internal_format(textwidth, second_indent, flags, c == NUL, c); |
667 | 6169 } |
6170 | |
7 | 6171 if (c == NUL) /* only formatting was wanted */ |
6172 return; | |
6173 | |
6174 #ifdef FEAT_COMMENTS | |
6175 /* Check whether this character should end a comment. */ | |
6176 if (did_ai && (int)c == end_comment_pending) | |
6177 { | |
6178 char_u *line; | |
6179 char_u lead_end[COM_MAX_LEN]; /* end-comment string */ | |
6180 int middle_len, end_len; | |
6181 int i; | |
6182 | |
6183 /* | |
6184 * Need to remove existing (middle) comment leader and insert end | |
6185 * comment leader. First, check what comment leader we can find. | |
6186 */ | |
3562 | 6187 i = get_leader_len(line = ml_get_curline(), &p, FALSE, TRUE); |
7 | 6188 if (i > 0 && vim_strchr(p, COM_MIDDLE) != NULL) /* Just checking */ |
6189 { | |
6190 /* Skip middle-comment string */ | |
6191 while (*p && p[-1] != ':') /* find end of middle flags */ | |
6192 ++p; | |
6193 middle_len = copy_option_part(&p, lead_end, COM_MAX_LEN, ","); | |
6194 /* Don't count trailing white space for middle_len */ | |
11129
f4ea50924c6d
patch 8.0.0452: some macros are in lower case
Christian Brabandt <cb@256bit.org>
parents:
11127
diff
changeset
|
6195 while (middle_len > 0 && VIM_ISWHITE(lead_end[middle_len - 1])) |
7 | 6196 --middle_len; |
6197 | |
6198 /* Find the end-comment string */ | |
6199 while (*p && p[-1] != ':') /* find end of end flags */ | |
6200 ++p; | |
6201 end_len = copy_option_part(&p, lead_end, COM_MAX_LEN, ","); | |
6202 | |
6203 /* Skip white space before the cursor */ | |
6204 i = curwin->w_cursor.col; | |
11129
f4ea50924c6d
patch 8.0.0452: some macros are in lower case
Christian Brabandt <cb@256bit.org>
parents:
11127
diff
changeset
|
6205 while (--i >= 0 && VIM_ISWHITE(line[i])) |
7 | 6206 ; |
6207 i++; | |
6208 | |
6209 /* Skip to before the middle leader */ | |
6210 i -= middle_len; | |
6211 | |
6212 /* Check some expected things before we go on */ | |
6213 if (i >= 0 && lead_end[end_len - 1] == end_comment_pending) | |
6214 { | |
6215 /* Backspace over all the stuff we want to replace */ | |
6216 backspace_until_column(i); | |
6217 | |
6218 /* | |
6219 * Insert the end-comment string, except for the last | |
6220 * character, which will get inserted as normal later. | |
6221 */ | |
6222 ins_bytes_len(lead_end, end_len - 1); | |
6223 } | |
6224 } | |
6225 } | |
6226 end_comment_pending = NUL; | |
6227 #endif | |
6228 | |
6229 did_ai = FALSE; | |
6230 #ifdef FEAT_SMARTINDENT | |
6231 did_si = FALSE; | |
6232 can_si = FALSE; | |
6233 can_si_back = FALSE; | |
6234 #endif | |
6235 | |
6236 /* | |
6237 * If there's any pending input, grab up to INPUT_BUFLEN at once. | |
6238 * This speeds up normal text input considerably. | |
6239 * Don't do this when 'cindent' or 'indentexpr' is set, because we might | |
6240 * need to re-indent at a ':', or any other character (but not what | |
6241 * 'paste' is set).. | |
3390 | 6242 * Don't do this when there an InsertCharPre autocommand is defined, |
6243 * because we need to fire the event for every character. | |
13870
08370aad873d
patch 8.0.1806: InsertCharPre causes problems for autocomplete
Christian Brabandt <cb@256bit.org>
parents:
13788
diff
changeset
|
6244 * Do the check for InsertCharPre before the call to vpeekc() because the |
08370aad873d
patch 8.0.1806: InsertCharPre causes problems for autocomplete
Christian Brabandt <cb@256bit.org>
parents:
13788
diff
changeset
|
6245 * InsertCharPre autocommand could change the input buffer. |
7 | 6246 */ |
6247 #ifdef USE_ON_FLY_SCROLL | |
6248 dont_scroll = FALSE; /* allow scrolling here */ | |
6249 #endif | |
6250 | |
6251 if ( !ISSPECIAL(c) | |
6252 && (!has_mbyte || (*mb_char2len)(c) == 1) | |
13870
08370aad873d
patch 8.0.1806: InsertCharPre causes problems for autocomplete
Christian Brabandt <cb@256bit.org>
parents:
13788
diff
changeset
|
6253 && !has_insertcharpre() |
7 | 6254 && vpeekc() != NUL |
6255 && !(State & REPLACE_FLAG) | |
6256 #ifdef FEAT_CINDENT | |
6257 && !cindent_on() | |
6258 #endif | |
6259 #ifdef FEAT_RIGHTLEFT | |
6260 && !p_ri | |
6261 #endif | |
13870
08370aad873d
patch 8.0.1806: InsertCharPre causes problems for autocomplete
Christian Brabandt <cb@256bit.org>
parents:
13788
diff
changeset
|
6262 ) |
7 | 6263 { |
6264 #define INPUT_BUFLEN 100 | |
6265 char_u buf[INPUT_BUFLEN + 1]; | |
6266 int i; | |
6267 colnr_T virtcol = 0; | |
6268 | |
6269 buf[0] = c; | |
6270 i = 1; | |
667 | 6271 if (textwidth > 0) |
7 | 6272 virtcol = get_nolist_virtcol(); |
6273 /* | |
6274 * Stop the string when: | |
6275 * - no more chars available | |
6276 * - finding a special character (command key) | |
6277 * - buffer is full | |
6278 * - running into the 'textwidth' boundary | |
6279 * - need to check for abbreviation: A non-word char after a word-char | |
6280 */ | |
6281 while ( (c = vpeekc()) != NUL | |
6282 && !ISSPECIAL(c) | |
6283 && (!has_mbyte || MB_BYTE2LEN_CHECK(c) == 1) | |
6284 && i < INPUT_BUFLEN | |
10745
265268ea1adc
patch 8.0.0262: Farsi support is barely tested
Christian Brabandt <cb@256bit.org>
parents:
10714
diff
changeset
|
6285 # ifdef FEAT_FKMAP |
265268ea1adc
patch 8.0.0262: Farsi support is barely tested
Christian Brabandt <cb@256bit.org>
parents:
10714
diff
changeset
|
6286 && !(p_fkmap && KeyTyped) /* Farsi mode mapping moves cursor */ |
265268ea1adc
patch 8.0.0262: Farsi support is barely tested
Christian Brabandt <cb@256bit.org>
parents:
10714
diff
changeset
|
6287 # endif |
7 | 6288 && (textwidth == 0 |
6289 || (virtcol += byte2cells(buf[i - 1])) < (colnr_T)textwidth) | |
6290 && !(!no_abbr && !vim_iswordc(c) && vim_iswordc(buf[i - 1]))) | |
6291 { | |
6292 #ifdef FEAT_RIGHTLEFT | |
6293 c = vgetc(); | |
6294 if (p_hkmap && KeyTyped) | |
6295 c = hkmap(c); /* Hebrew mode mapping */ | |
6296 buf[i++] = c; | |
6297 #else | |
6298 buf[i++] = vgetc(); | |
6299 #endif | |
6300 } | |
6301 | |
6302 #ifdef FEAT_DIGRAPHS | |
6303 do_digraph(-1); /* clear digraphs */ | |
6304 do_digraph(buf[i-1]); /* may be the start of a digraph */ | |
6305 #endif | |
6306 buf[i] = NUL; | |
6307 ins_str(buf); | |
6308 if (flags & INSCHAR_CTRLV) | |
6309 { | |
6310 redo_literal(*buf); | |
6311 i = 1; | |
6312 } | |
6313 else | |
6314 i = 0; | |
6315 if (buf[i] != NUL) | |
620 | 6316 AppendToRedobuffLit(buf + i, -1); |
7 | 6317 } |
6318 else | |
6319 { | |
667 | 6320 int cc; |
6321 | |
7 | 6322 if (has_mbyte && (cc = (*mb_char2len)(c)) > 1) |
6323 { | |
6324 char_u buf[MB_MAXBYTES + 1]; | |
6325 | |
6326 (*mb_char2bytes)(c, buf); | |
6327 buf[cc] = NUL; | |
6328 ins_char_bytes(buf, cc); | |
6329 AppendCharToRedobuff(c); | |
6330 } | |
6331 else | |
6332 { | |
6333 ins_char(c); | |
6334 if (flags & INSCHAR_CTRLV) | |
6335 redo_literal(c); | |
6336 else | |
6337 AppendCharToRedobuff(c); | |
6338 } | |
6339 } | |
6340 } | |
6341 | |
6342 /* | |
667 | 6343 * Format text at the current insert position. |
3584 | 6344 * |
6345 * If the INSCHAR_COM_LIST flag is present, then the value of second_indent | |
6346 * will be the comment leader length sent to open_line(). | |
667 | 6347 */ |
6348 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
6349 internal_format( |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
6350 int textwidth, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
6351 int second_indent, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
6352 int flags, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
6353 int format_only, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
6354 int c) /* character to be inserted (can be NUL) */ |
667 | 6355 { |
6356 int cc; | |
6357 int save_char = NUL; | |
6358 int haveto_redraw = FALSE; | |
6359 int fo_ins_blank = has_format_option(FO_INS_BLANK); | |
6360 int fo_multibyte = has_format_option(FO_MBYTE_BREAK); | |
6361 int fo_white_par = has_format_option(FO_WHITE_PAR); | |
6362 int first_line = TRUE; | |
6363 #ifdef FEAT_COMMENTS | |
6364 colnr_T leader_len; | |
6365 int no_leader = FALSE; | |
6366 int do_comments = (flags & INSCHAR_DO_COM); | |
6367 #endif | |
6199 | 6368 #ifdef FEAT_LINEBREAK |
6369 int has_lbr = curwin->w_p_lbr; | |
6370 | |
6371 /* make sure win_lbr_chartabsize() counts correctly */ | |
6372 curwin->w_p_lbr = FALSE; | |
6373 #endif | |
667 | 6374 |
6375 /* | |
6376 * When 'ai' is off we don't want a space under the cursor to be | |
6377 * deleted. Replace it with an 'x' temporarily. | |
6378 */ | |
14424
0a69e6e708f9
patch 8.1.0226: too many #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
14419
diff
changeset
|
6379 if (!curbuf->b_p_ai && !(State & VREPLACE_FLAG)) |
667 | 6380 { |
6381 cc = gchar_cursor(); | |
11129
f4ea50924c6d
patch 8.0.0452: some macros are in lower case
Christian Brabandt <cb@256bit.org>
parents:
11127
diff
changeset
|
6382 if (VIM_ISWHITE(cc)) |
667 | 6383 { |
6384 save_char = cc; | |
6385 pchar_cursor('x'); | |
6386 } | |
6387 } | |
6388 | |
6389 /* | |
6390 * Repeat breaking lines, until the current line is not too long. | |
6391 */ | |
6392 while (!got_int) | |
6393 { | |
6394 int startcol; /* Cursor column at entry */ | |
6395 int wantcol; /* column at textwidth border */ | |
6396 int foundcol; /* column for start of spaces */ | |
6397 int end_foundcol = 0; /* column for start of word */ | |
6398 colnr_T len; | |
6399 colnr_T virtcol; | |
6400 int orig_col = 0; | |
6401 char_u *saved_text = NULL; | |
6402 colnr_T col; | |
2004 | 6403 colnr_T end_col; |
15440
5ecac7734184
patch 8.1.0728: cannot avoid breaking after a single space.
Bram Moolenaar <Bram@vim.org>
parents:
15436
diff
changeset
|
6404 int wcc; // counter for whitespace chars |
2004 | 6405 |
6406 virtcol = get_nolist_virtcol() | |
6407 + char2cells(c != NUL ? c : gchar_cursor()); | |
6408 if (virtcol <= (colnr_T)textwidth) | |
667 | 6409 break; |
6410 | |
6411 #ifdef FEAT_COMMENTS | |
6412 if (no_leader) | |
6413 do_comments = FALSE; | |
6414 else if (!(flags & INSCHAR_FORMAT) | |
6415 && has_format_option(FO_WRAP_COMS)) | |
6416 do_comments = TRUE; | |
6417 | |
6418 /* Don't break until after the comment leader */ | |
6419 if (do_comments) | |
3562 | 6420 leader_len = get_leader_len(ml_get_curline(), NULL, FALSE, TRUE); |
667 | 6421 else |
6422 leader_len = 0; | |
6423 | |
6424 /* If the line doesn't start with a comment leader, then don't | |
6425 * start one in a following broken line. Avoids that a %word | |
6426 * moved to the start of the next line causes all following lines | |
6427 * to start with %. */ | |
6428 if (leader_len == 0) | |
6429 no_leader = TRUE; | |
6430 #endif | |
6431 if (!(flags & INSCHAR_FORMAT) | |
6432 #ifdef FEAT_COMMENTS | |
6433 && leader_len == 0 | |
6434 #endif | |
6435 && !has_format_option(FO_WRAP)) | |
6436 | |
6437 break; | |
6438 if ((startcol = curwin->w_cursor.col) == 0) | |
6439 break; | |
6440 | |
6441 /* find column of textwidth border */ | |
6442 coladvance((colnr_T)textwidth); | |
6443 wantcol = curwin->w_cursor.col; | |
6444 | |
2004 | 6445 curwin->w_cursor.col = startcol; |
667 | 6446 foundcol = 0; |
6447 | |
6448 /* | |
6449 * Find position to break at. | |
6450 * Stop at first entered white when 'formatoptions' has 'v' | |
6451 */ | |
6452 while ((!fo_ins_blank && !has_format_option(FO_INS_VI)) | |
3162 | 6453 || (flags & INSCHAR_FORMAT) |
667 | 6454 || curwin->w_cursor.lnum != Insstart.lnum |
6455 || curwin->w_cursor.col >= Insstart.col) | |
6456 { | |
2004 | 6457 if (curwin->w_cursor.col == startcol && c != NUL) |
6458 cc = c; | |
6459 else | |
6460 cc = gchar_cursor(); | |
667 | 6461 if (WHITECHAR(cc)) |
6462 { | |
6463 /* remember position of blank just before text */ | |
2004 | 6464 end_col = curwin->w_cursor.col; |
667 | 6465 |
15440
5ecac7734184
patch 8.1.0728: cannot avoid breaking after a single space.
Bram Moolenaar <Bram@vim.org>
parents:
15436
diff
changeset
|
6466 // find start of sequence of blanks |
5ecac7734184
patch 8.1.0728: cannot avoid breaking after a single space.
Bram Moolenaar <Bram@vim.org>
parents:
15436
diff
changeset
|
6467 wcc = 0; |
667 | 6468 while (curwin->w_cursor.col > 0 && WHITECHAR(cc)) |
6469 { | |
6470 dec_cursor(); | |
6471 cc = gchar_cursor(); | |
15440
5ecac7734184
patch 8.1.0728: cannot avoid breaking after a single space.
Bram Moolenaar <Bram@vim.org>
parents:
15436
diff
changeset
|
6472 |
5ecac7734184
patch 8.1.0728: cannot avoid breaking after a single space.
Bram Moolenaar <Bram@vim.org>
parents:
15436
diff
changeset
|
6473 // Increment count of how many whitespace chars in this |
5ecac7734184
patch 8.1.0728: cannot avoid breaking after a single space.
Bram Moolenaar <Bram@vim.org>
parents:
15436
diff
changeset
|
6474 // group; we only need to know if it's more than one. |
5ecac7734184
patch 8.1.0728: cannot avoid breaking after a single space.
Bram Moolenaar <Bram@vim.org>
parents:
15436
diff
changeset
|
6475 if (wcc < 2) |
5ecac7734184
patch 8.1.0728: cannot avoid breaking after a single space.
Bram Moolenaar <Bram@vim.org>
parents:
15436
diff
changeset
|
6476 wcc++; |
667 | 6477 } |
6478 if (curwin->w_cursor.col == 0 && WHITECHAR(cc)) | |
6479 break; /* only spaces in front of text */ | |
15440
5ecac7734184
patch 8.1.0728: cannot avoid breaking after a single space.
Bram Moolenaar <Bram@vim.org>
parents:
15436
diff
changeset
|
6480 |
5ecac7734184
patch 8.1.0728: cannot avoid breaking after a single space.
Bram Moolenaar <Bram@vim.org>
parents:
15436
diff
changeset
|
6481 // Don't break after a period when 'formatoptions' has 'p' and |
5ecac7734184
patch 8.1.0728: cannot avoid breaking after a single space.
Bram Moolenaar <Bram@vim.org>
parents:
15436
diff
changeset
|
6482 // there are less than two spaces. |
5ecac7734184
patch 8.1.0728: cannot avoid breaking after a single space.
Bram Moolenaar <Bram@vim.org>
parents:
15436
diff
changeset
|
6483 if (has_format_option(FO_PERIOD_ABBR) && cc == '.' && wcc < 2) |
5ecac7734184
patch 8.1.0728: cannot avoid breaking after a single space.
Bram Moolenaar <Bram@vim.org>
parents:
15436
diff
changeset
|
6484 continue; |
5ecac7734184
patch 8.1.0728: cannot avoid breaking after a single space.
Bram Moolenaar <Bram@vim.org>
parents:
15436
diff
changeset
|
6485 |
667 | 6486 #ifdef FEAT_COMMENTS |
6487 /* Don't break until after the comment leader */ | |
6488 if (curwin->w_cursor.col < leader_len) | |
6489 break; | |
6490 #endif | |
6491 if (has_format_option(FO_ONE_LETTER)) | |
6492 { | |
6493 /* do not break after one-letter words */ | |
6494 if (curwin->w_cursor.col == 0) | |
6495 break; /* one-letter word at begin */ | |
2004 | 6496 #ifdef FEAT_COMMENTS |
6497 /* do not break "#a b" when 'tw' is 2 */ | |
6498 if (curwin->w_cursor.col <= leader_len) | |
6499 break; | |
6500 #endif | |
667 | 6501 col = curwin->w_cursor.col; |
6502 dec_cursor(); | |
6503 cc = gchar_cursor(); | |
6504 | |
6505 if (WHITECHAR(cc)) | |
6506 continue; /* one-letter, continue */ | |
6507 curwin->w_cursor.col = col; | |
6508 } | |
2004 | 6509 |
6510 inc_cursor(); | |
6511 | |
6512 end_foundcol = end_col + 1; | |
6513 foundcol = curwin->w_cursor.col; | |
6514 if (curwin->w_cursor.col <= (colnr_T)wantcol) | |
667 | 6515 break; |
6516 } | |
2004 | 6517 else if (cc >= 0x100 && fo_multibyte) |
667 | 6518 { |
6519 /* Break after or before a multi-byte character. */ | |
2004 | 6520 if (curwin->w_cursor.col != startcol) |
6521 { | |
6522 #ifdef FEAT_COMMENTS | |
6523 /* Don't break until after the comment leader */ | |
6524 if (curwin->w_cursor.col < leader_len) | |
6525 break; | |
6526 #endif | |
6527 col = curwin->w_cursor.col; | |
6528 inc_cursor(); | |
6529 /* Don't change end_foundcol if already set. */ | |
6530 if (foundcol != curwin->w_cursor.col) | |
6531 { | |
6532 foundcol = curwin->w_cursor.col; | |
6533 end_foundcol = foundcol; | |
6534 if (curwin->w_cursor.col <= (colnr_T)wantcol) | |
6535 break; | |
6536 } | |
6537 curwin->w_cursor.col = col; | |
6538 } | |
6539 | |
6540 if (curwin->w_cursor.col == 0) | |
6541 break; | |
6542 | |
6543 col = curwin->w_cursor.col; | |
6544 | |
6545 dec_cursor(); | |
6546 cc = gchar_cursor(); | |
6547 | |
6548 if (WHITECHAR(cc)) | |
6549 continue; /* break with space */ | |
6550 #ifdef FEAT_COMMENTS | |
6551 /* Don't break until after the comment leader */ | |
6552 if (curwin->w_cursor.col < leader_len) | |
6553 break; | |
6554 #endif | |
6555 | |
6556 curwin->w_cursor.col = col; | |
6557 | |
667 | 6558 foundcol = curwin->w_cursor.col; |
6559 end_foundcol = foundcol; | |
2004 | 6560 if (curwin->w_cursor.col <= (colnr_T)wantcol) |
6561 break; | |
667 | 6562 } |
6563 if (curwin->w_cursor.col == 0) | |
6564 break; | |
6565 dec_cursor(); | |
6566 } | |
6567 | |
6568 if (foundcol == 0) /* no spaces, cannot break line */ | |
6569 { | |
6570 curwin->w_cursor.col = startcol; | |
6571 break; | |
6572 } | |
6573 | |
6574 /* Going to break the line, remove any "$" now. */ | |
6575 undisplay_dollar(); | |
6576 | |
6577 /* | |
6578 * Offset between cursor position and line break is used by replace | |
6579 * stack functions. VREPLACE does not use this, and backspaces | |
6580 * over the text instead. | |
6581 */ | |
6582 if (State & VREPLACE_FLAG) | |
6583 orig_col = startcol; /* Will start backspacing from here */ | |
6584 else | |
2004 | 6585 replace_offset = startcol - end_foundcol; |
667 | 6586 |
6587 /* | |
6588 * adjust startcol for spaces that will be deleted and | |
6589 * characters that will remain on top line | |
6590 */ | |
6591 curwin->w_cursor.col = foundcol; | |
2004 | 6592 while ((cc = gchar_cursor(), WHITECHAR(cc)) |
6593 && (!fo_white_par || curwin->w_cursor.col < startcol)) | |
667 | 6594 inc_cursor(); |
6595 startcol -= curwin->w_cursor.col; | |
6596 if (startcol < 0) | |
6597 startcol = 0; | |
6598 | |
6599 if (State & VREPLACE_FLAG) | |
6600 { | |
6601 /* | |
6602 * In VREPLACE mode, we will backspace over the text to be | |
6603 * wrapped, so save a copy now to put on the next line. | |
6604 */ | |
6605 saved_text = vim_strsave(ml_get_cursor()); | |
6606 curwin->w_cursor.col = orig_col; | |
6607 if (saved_text == NULL) | |
6608 break; /* Can't do it, out of memory */ | |
6609 saved_text[startcol] = NUL; | |
6610 | |
6611 /* Backspace over characters that will move to the next line */ | |
6612 if (!fo_white_par) | |
6613 backspace_until_column(foundcol); | |
6614 } | |
6615 else | |
6616 { | |
6617 /* put cursor after pos. to break line */ | |
6618 if (!fo_white_par) | |
6619 curwin->w_cursor.col = foundcol; | |
6620 } | |
6621 | |
6622 /* | |
6623 * Split the line just before the margin. | |
6624 * Only insert/delete lines, but don't really redraw the window. | |
6625 */ | |
6626 open_line(FORWARD, OPENLINE_DELSPACES + OPENLINE_MARKFIX | |
6627 + (fo_white_par ? OPENLINE_KEEPTRAIL : 0) | |
6628 #ifdef FEAT_COMMENTS | |
6629 + (do_comments ? OPENLINE_DO_COM : 0) | |
3584 | 6630 + ((flags & INSCHAR_COM_LIST) ? OPENLINE_COM_LIST : 0) |
6631 #endif | |
6632 , ((flags & INSCHAR_COM_LIST) ? second_indent : old_indent)); | |
6633 if (!(flags & INSCHAR_COM_LIST)) | |
6634 old_indent = 0; | |
667 | 6635 |
6636 replace_offset = 0; | |
6637 if (first_line) | |
6638 { | |
3584 | 6639 if (!(flags & INSCHAR_COM_LIST)) |
6640 { | |
6641 /* | |
3632 | 6642 * This section is for auto-wrap of numeric lists. When not |
6643 * in insert mode (i.e. format_lines()), the INSCHAR_COM_LIST | |
6644 * flag will be set and open_line() will handle it (as seen | |
6645 * above). The code here (and in get_number_indent()) will | |
6646 * recognize comments if needed... | |
3584 | 6647 */ |
6648 if (second_indent < 0 && has_format_option(FO_Q_NUMBER)) | |
3632 | 6649 second_indent = |
6650 get_number_indent(curwin->w_cursor.lnum - 1); | |
3584 | 6651 if (second_indent >= 0) |
6652 { | |
6653 if (State & VREPLACE_FLAG) | |
6654 change_indent(INDENT_SET, second_indent, | |
6655 FALSE, NUL, TRUE); | |
6656 else | |
3632 | 6657 #ifdef FEAT_COMMENTS |
6658 if (leader_len > 0 && second_indent - leader_len > 0) | |
6659 { | |
6660 int i; | |
6661 int padding = second_indent - leader_len; | |
6662 | |
6663 /* We started at the first_line of a numbered list | |
6664 * that has a comment. the open_line() function has | |
6665 * inserted the proper comment leader and positioned | |
6666 * the cursor at the end of the split line. Now we | |
6667 * add the additional whitespace needed after the | |
6668 * comment leader for the numbered list. */ | |
6669 for (i = 0; i < padding; i++) | |
6670 ins_str((char_u *)" "); | |
6671 } | |
6672 else | |
6673 { | |
6674 #endif | |
3584 | 6675 (void)set_indent(second_indent, SIN_CHANGED); |
3632 | 6676 #ifdef FEAT_COMMENTS |
6677 } | |
6678 #endif | |
3584 | 6679 } |
667 | 6680 } |
6681 first_line = FALSE; | |
6682 } | |
6683 | |
6684 if (State & VREPLACE_FLAG) | |
6685 { | |
6686 /* | |
6687 * In VREPLACE mode we have backspaced over the text to be | |
6688 * moved, now we re-insert it into the new line. | |
6689 */ | |
6690 ins_bytes(saved_text); | |
6691 vim_free(saved_text); | |
6692 } | |
6693 else | |
6694 { | |
6695 /* | |
6696 * Check if cursor is not past the NUL off the line, cindent | |
6697 * may have added or removed indent. | |
6698 */ | |
6699 curwin->w_cursor.col += startcol; | |
6700 len = (colnr_T)STRLEN(ml_get_curline()); | |
6701 if (curwin->w_cursor.col > len) | |
6702 curwin->w_cursor.col = len; | |
6703 } | |
6704 | |
6705 haveto_redraw = TRUE; | |
6706 #ifdef FEAT_CINDENT | |
6707 can_cindent = TRUE; | |
6708 #endif | |
6709 /* moved the cursor, don't autoindent or cindent now */ | |
6710 did_ai = FALSE; | |
6711 #ifdef FEAT_SMARTINDENT | |
6712 did_si = FALSE; | |
6713 can_si = FALSE; | |
6714 can_si_back = FALSE; | |
6715 #endif | |
6716 line_breakcheck(); | |
6717 } | |
6718 | |
6719 if (save_char != NUL) /* put back space after cursor */ | |
6720 pchar_cursor(save_char); | |
6721 | |
6199 | 6722 #ifdef FEAT_LINEBREAK |
6723 curwin->w_p_lbr = has_lbr; | |
6724 #endif | |
667 | 6725 if (!format_only && haveto_redraw) |
6726 { | |
6727 update_topline(); | |
6728 redraw_curbuf_later(VALID); | |
6729 } | |
6730 } | |
6731 | |
6732 /* | |
7 | 6733 * Called after inserting or deleting text: When 'formatoptions' includes the |
6734 * 'a' flag format from the current line until the end of the paragraph. | |
6735 * Keep the cursor at the same position relative to the text. | |
6736 * The caller must have saved the cursor line for undo, following ones will be | |
6737 * saved here. | |
6738 */ | |
6739 void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
6740 auto_format( |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
6741 int trailblank, /* when TRUE also format with trailing blank */ |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
6742 int prev_line) /* may start in previous line */ |
7 | 6743 { |
6744 pos_T pos; | |
6745 colnr_T len; | |
6746 char_u *old; | |
6747 char_u *new, *pnew; | |
6748 int wasatend; | |
301 | 6749 int cc; |
7 | 6750 |
6751 if (!has_format_option(FO_AUTO)) | |
6752 return; | |
6753 | |
6754 pos = curwin->w_cursor; | |
6755 old = ml_get_curline(); | |
6756 | |
6757 /* may remove added space */ | |
6758 check_auto_format(FALSE); | |
6759 | |
6760 /* Don't format in Insert mode when the cursor is on a trailing blank, the | |
6761 * user might insert normal text next. Also skip formatting when "1" is | |
6762 * in 'formatoptions' and there is a single character before the cursor. | |
6763 * Otherwise the line would be broken and when typing another non-white | |
6764 * next they are not joined back together. */ | |
1872 | 6765 wasatend = (pos.col == (colnr_T)STRLEN(old)); |
7 | 6766 if (*old != NUL && !trailblank && wasatend) |
6767 { | |
6768 dec_cursor(); | |
301 | 6769 cc = gchar_cursor(); |
6770 if (!WHITECHAR(cc) && curwin->w_cursor.col > 0 | |
6771 && has_format_option(FO_ONE_LETTER)) | |
7 | 6772 dec_cursor(); |
301 | 6773 cc = gchar_cursor(); |
6774 if (WHITECHAR(cc)) | |
7 | 6775 { |
6776 curwin->w_cursor = pos; | |
6777 return; | |
6778 } | |
6779 curwin->w_cursor = pos; | |
6780 } | |
6781 | |
6782 #ifdef FEAT_COMMENTS | |
6783 /* With the 'c' flag in 'formatoptions' and 't' missing: only format | |
6784 * comments. */ | |
6785 if (has_format_option(FO_WRAP_COMS) && !has_format_option(FO_WRAP) | |
3562 | 6786 && get_leader_len(old, NULL, FALSE, TRUE) == 0) |
7 | 6787 return; |
6788 #endif | |
6789 | |
6790 /* | |
6791 * May start formatting in a previous line, so that after "x" a word is | |
6792 * moved to the previous line if it fits there now. Only when this is not | |
6793 * the start of a paragraph. | |
6794 */ | |
6795 if (prev_line && !paragraph_start(curwin->w_cursor.lnum)) | |
6796 { | |
6797 --curwin->w_cursor.lnum; | |
6798 if (u_save_cursor() == FAIL) | |
6799 return; | |
6800 } | |
6801 | |
6802 /* | |
6803 * Do the formatting and restore the cursor position. "saved_cursor" will | |
6804 * be adjusted for the text formatting. | |
6805 */ | |
6806 saved_cursor = pos; | |
1563 | 6807 format_lines((linenr_T)-1, FALSE); |
7 | 6808 curwin->w_cursor = saved_cursor; |
6809 saved_cursor.lnum = 0; | |
6810 | |
6811 if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count) | |
6812 { | |
6813 /* "cannot happen" */ | |
6814 curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count; | |
6815 coladvance((colnr_T)MAXCOL); | |
6816 } | |
6817 else | |
6818 check_cursor_col(); | |
6819 | |
6820 /* Insert mode: If the cursor is now after the end of the line while it | |
6821 * previously wasn't, the line was broken. Because of the rule above we | |
6822 * need to add a space when 'w' is in 'formatoptions' to keep a paragraph | |
6823 * formatted. */ | |
6824 if (!wasatend && has_format_option(FO_WHITE_PAR)) | |
6825 { | |
6826 new = ml_get_curline(); | |
835 | 6827 len = (colnr_T)STRLEN(new); |
7 | 6828 if (curwin->w_cursor.col == len) |
6829 { | |
6830 pnew = vim_strnsave(new, len + 2); | |
6831 pnew[len] = ' '; | |
6832 pnew[len + 1] = NUL; | |
6833 ml_replace(curwin->w_cursor.lnum, pnew, FALSE); | |
6834 /* remove the space later */ | |
6835 did_add_space = TRUE; | |
6836 } | |
6837 else | |
6838 /* may remove added space */ | |
6839 check_auto_format(FALSE); | |
6840 } | |
6841 | |
6842 check_cursor(); | |
6843 } | |
6844 | |
6845 /* | |
6846 * When an extra space was added to continue a paragraph for auto-formatting, | |
6847 * delete it now. The space must be under the cursor, just after the insert | |
6848 * position. | |
6849 */ | |
6850 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
6851 check_auto_format( |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
6852 int end_insert) /* TRUE when ending Insert mode */ |
7 | 6853 { |
6854 int c = ' '; | |
301 | 6855 int cc; |
7 | 6856 |
6857 if (did_add_space) | |
6858 { | |
301 | 6859 cc = gchar_cursor(); |
6860 if (!WHITECHAR(cc)) | |
7 | 6861 /* Somehow the space was removed already. */ |
6862 did_add_space = FALSE; | |
6863 else | |
6864 { | |
6865 if (!end_insert) | |
6866 { | |
6867 inc_cursor(); | |
6868 c = gchar_cursor(); | |
6869 dec_cursor(); | |
6870 } | |
6871 if (c != NUL) | |
6872 { | |
6873 /* The space is no longer at the end of the line, delete it. */ | |
6874 del_char(FALSE); | |
6875 did_add_space = FALSE; | |
6876 } | |
6877 } | |
6878 } | |
6879 } | |
6880 | |
6881 /* | |
6882 * Find out textwidth to be used for formatting: | |
6883 * if 'textwidth' option is set, use it | |
12515
972ea22c946f
patch 8.0.1136: W_WIDTH() is always the same
Christian Brabandt <cb@256bit.org>
parents:
12513
diff
changeset
|
6884 * else if 'wrapmargin' option is set, use curwin->w_width - 'wrapmargin' |
7 | 6885 * if invalid value, use 0. |
6886 * Set default to window width (maximum 79) for "gq" operator. | |
6887 */ | |
6888 int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
6889 comp_textwidth( |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
6890 int ff) /* force formatting (for "gq" command) */ |
7 | 6891 { |
6892 int textwidth; | |
6893 | |
6894 textwidth = curbuf->b_p_tw; | |
6895 if (textwidth == 0 && curbuf->b_p_wm) | |
6896 { | |
6897 /* The width is the window width minus 'wrapmargin' minus all the | |
6898 * things that add to the margin. */ | |
12515
972ea22c946f
patch 8.0.1136: W_WIDTH() is always the same
Christian Brabandt <cb@256bit.org>
parents:
12513
diff
changeset
|
6899 textwidth = curwin->w_width - curbuf->b_p_wm; |
7 | 6900 #ifdef FEAT_CMDWIN |
6901 if (cmdwin_type != 0) | |
6902 textwidth -= 1; | |
6903 #endif | |
6904 #ifdef FEAT_FOLDING | |
6905 textwidth -= curwin->w_p_fdc; | |
6906 #endif | |
6907 #ifdef FEAT_SIGNS | |
9852
4eea48b76d03
commit https://github.com/vim/vim/commit/95ec9d6a6ab3117d60ff638670a803d43974ba51
Christian Brabandt <cb@256bit.org>
parents:
9826
diff
changeset
|
6908 if (signcolumn_on(curwin)) |
7 | 6909 textwidth -= 1; |
6910 #endif | |
2178
c6f1aa1e9f32
Add 'relativenumber' patch from Markus Heidelberg.
Bram Moolenaar <bram@vim.org>
parents:
2107
diff
changeset
|
6911 if (curwin->w_p_nu || curwin->w_p_rnu) |
7 | 6912 textwidth -= 8; |
6913 } | |
6914 if (textwidth < 0) | |
6915 textwidth = 0; | |
6916 if (ff && textwidth == 0) | |
6917 { | |
12515
972ea22c946f
patch 8.0.1136: W_WIDTH() is always the same
Christian Brabandt <cb@256bit.org>
parents:
12513
diff
changeset
|
6918 textwidth = curwin->w_width - 1; |
7 | 6919 if (textwidth > 79) |
6920 textwidth = 79; | |
6921 } | |
6922 return textwidth; | |
6923 } | |
6924 | |
6925 /* | |
6926 * Put a character in the redo buffer, for when just after a CTRL-V. | |
6927 */ | |
6928 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
6929 redo_literal(int c) |
7 | 6930 { |
6931 char_u buf[10]; | |
6932 | |
6933 /* Only digits need special treatment. Translate them into a string of | |
6934 * three digits. */ | |
6935 if (VIM_ISDIGIT(c)) | |
6936 { | |
1872 | 6937 vim_snprintf((char *)buf, sizeof(buf), "%03d", c); |
7 | 6938 AppendToRedobuff(buf); |
6939 } | |
6940 else | |
6941 AppendCharToRedobuff(c); | |
6942 } | |
6943 | |
6944 /* | |
6945 * start_arrow() is called when an arrow key is used in insert mode. | |
484 | 6946 * For undo/redo it resembles hitting the <ESC> key. |
7 | 6947 */ |
6948 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
6949 start_arrow( |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
6950 pos_T *end_insert_pos) /* can be NULL */ |
7074
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
6951 { |
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
6952 start_arrow_common(end_insert_pos, TRUE); |
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
6953 } |
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
6954 |
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
6955 /* |
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
6956 * Like start_arrow() but with end_change argument. |
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
6957 * Will prepare for redo of CTRL-G U if "end_change" is FALSE. |
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
6958 */ |
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
6959 static void |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
6960 start_arrow_with_change( |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
6961 pos_T *end_insert_pos, /* can be NULL */ |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
6962 int end_change) /* end undoable change */ |
7074
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
6963 { |
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
6964 start_arrow_common(end_insert_pos, end_change); |
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
6965 if (!end_change) |
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
6966 { |
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
6967 AppendCharToRedobuff(Ctrl_G); |
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
6968 AppendCharToRedobuff('U'); |
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
6969 } |
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
6970 } |
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
6971 |
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
6972 static void |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
6973 start_arrow_common( |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
6974 pos_T *end_insert_pos, /* can be NULL */ |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
6975 int end_change) /* end undoable change */ |
7074
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
6976 { |
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
6977 if (!arrow_used && end_change) /* something has been inserted */ |
7 | 6978 { |
6979 AppendToRedobuff(ESC_STR); | |
5434 | 6980 stop_insert(end_insert_pos, FALSE, FALSE); |
7 | 6981 arrow_used = TRUE; /* this means we stopped the current insert */ |
6982 } | |
744 | 6983 #ifdef FEAT_SPELL |
221 | 6984 check_spell_redraw(); |
6985 #endif | |
7 | 6986 } |
6987 | |
744 | 6988 #ifdef FEAT_SPELL |
221 | 6989 /* |
6990 * If we skipped highlighting word at cursor, do it now. | |
6991 * It may be skipped again, thus reset spell_redraw_lnum first. | |
6992 */ | |
6993 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
6994 check_spell_redraw(void) |
221 | 6995 { |
6996 if (spell_redraw_lnum != 0) | |
6997 { | |
6998 linenr_T lnum = spell_redraw_lnum; | |
6999 | |
7000 spell_redraw_lnum = 0; | |
15400
ac5542aadd9c
patch 8.1.0708: third argument for redrawWinline() is always FALSE
Bram Moolenaar <Bram@vim.org>
parents:
15382
diff
changeset
|
7001 redrawWinline(curwin, lnum); |
221 | 7002 } |
7003 } | |
484 | 7004 |
7005 /* | |
7006 * Called when starting CTRL_X_SPELL mode: Move backwards to a previous badly | |
7007 * spelled word, if there is one. | |
7008 */ | |
7009 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
7010 spell_back_to_badword(void) |
484 | 7011 { |
7012 pos_T tpos = curwin->w_cursor; | |
7013 | |
499 | 7014 spell_bad_len = spell_move_to(curwin, BACKWARD, TRUE, TRUE, NULL); |
484 | 7015 if (curwin->w_cursor.col != tpos.col) |
7016 start_arrow(&tpos); | |
7017 } | |
221 | 7018 #endif |
7019 | |
7 | 7020 /* |
7021 * stop_arrow() is called before a change is made in insert mode. | |
7022 * If an arrow key has been used, start a new insertion. | |
7023 * Returns FAIL if undo is impossible, shouldn't insert then. | |
7024 */ | |
7025 int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
7026 stop_arrow(void) |
7 | 7027 { |
7028 if (arrow_used) | |
7029 { | |
6138 | 7030 Insstart = curwin->w_cursor; /* new insertion starts here */ |
7031 if (Insstart.col > Insstart_orig.col && !ins_need_undo) | |
7032 /* Don't update the original insert position when moved to the | |
7033 * right, except when nothing was inserted yet. */ | |
7034 update_Insstart_orig = FALSE; | |
7035 Insstart_textlen = (colnr_T)linetabsize(ml_get_curline()); | |
7036 | |
7 | 7037 if (u_save_cursor() == OK) |
7038 { | |
7039 arrow_used = FALSE; | |
7040 ins_need_undo = FALSE; | |
7041 } | |
6138 | 7042 |
7 | 7043 ai_col = 0; |
7044 if (State & VREPLACE_FLAG) | |
7045 { | |
7046 orig_line_count = curbuf->b_ml.ml_line_count; | |
7047 vr_lines_changed = 1; | |
7048 } | |
7049 ResetRedobuff(); | |
7050 AppendToRedobuff((char_u *)"1i"); /* pretend we start an insertion */ | |
613 | 7051 new_insert_skip = 2; |
7 | 7052 } |
7053 else if (ins_need_undo) | |
7054 { | |
7055 if (u_save_cursor() == OK) | |
7056 ins_need_undo = FALSE; | |
7057 } | |
7058 | |
7059 #ifdef FEAT_FOLDING | |
7060 /* Always open fold at the cursor line when inserting something. */ | |
7061 foldOpenCursor(); | |
7062 #endif | |
7063 | |
7064 return (arrow_used || ins_need_undo ? FAIL : OK); | |
7065 } | |
7066 | |
7067 /* | |
840 | 7068 * Do a few things to stop inserting. |
7069 * "end_insert_pos" is where insert ended. It is NULL when we already jumped | |
7070 * to another window/buffer. | |
7 | 7071 */ |
7072 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
7073 stop_insert( |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
7074 pos_T *end_insert_pos, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
7075 int esc, /* called by ins_esc() */ |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
7076 int nomove) /* <c-\><c-o>, don't move cursor */ |
7 | 7077 { |
603 | 7078 int cc; |
7079 char_u *ptr; | |
7 | 7080 |
7081 stop_redo_ins(); | |
7082 replace_flush(); /* abandon replace stack */ | |
7083 | |
7084 /* | |
603 | 7085 * Save the inserted text for later redo with ^@ and CTRL-A. |
7086 * Don't do it when "restart_edit" was set and nothing was inserted, | |
7087 * otherwise CTRL-O w and then <Left> will clear "last_insert". | |
7 | 7088 */ |
603 | 7089 ptr = get_inserted(); |
615 | 7090 if (did_restart_edit == 0 || (ptr != NULL |
7091 && (int)STRLEN(ptr) > new_insert_skip)) | |
603 | 7092 { |
7093 vim_free(last_insert); | |
7094 last_insert = ptr; | |
7095 last_insert_skip = new_insert_skip; | |
7096 } | |
7097 else | |
7098 vim_free(ptr); | |
7 | 7099 |
840 | 7100 if (!arrow_used && end_insert_pos != NULL) |
7 | 7101 { |
7102 /* Auto-format now. It may seem strange to do this when stopping an | |
7103 * insertion (or moving the cursor), but it's required when appending | |
7104 * a line and having it end in a space. But only do it when something | |
7105 * was actually inserted, otherwise undo won't work. */ | |
10 | 7106 if (!ins_need_undo && has_format_option(FO_AUTO)) |
7 | 7107 { |
10 | 7108 pos_T tpos = curwin->w_cursor; |
7109 | |
7 | 7110 /* When the cursor is at the end of the line after a space the |
7111 * formatting will move it to the following word. Avoid that by | |
7112 * moving the cursor onto the space. */ | |
7113 cc = 'x'; | |
7114 if (curwin->w_cursor.col > 0 && gchar_cursor() == NUL) | |
7115 { | |
7116 dec_cursor(); | |
7117 cc = gchar_cursor(); | |
11129
f4ea50924c6d
patch 8.0.0452: some macros are in lower case
Christian Brabandt <cb@256bit.org>
parents:
11127
diff
changeset
|
7118 if (!VIM_ISWHITE(cc)) |
10 | 7119 curwin->w_cursor = tpos; |
7 | 7120 } |
7121 | |
7122 auto_format(TRUE, FALSE); | |
7123 | |
11129
f4ea50924c6d
patch 8.0.0452: some macros are in lower case
Christian Brabandt <cb@256bit.org>
parents:
11127
diff
changeset
|
7124 if (VIM_ISWHITE(cc)) |
10 | 7125 { |
7126 if (gchar_cursor() != NUL) | |
7127 inc_cursor(); | |
7128 #ifdef FEAT_VIRTUALEDIT | |
7129 /* If the cursor is still at the same character, also keep | |
7130 * the "coladd". */ | |
7131 if (gchar_cursor() == NUL | |
7132 && curwin->w_cursor.lnum == tpos.lnum | |
7133 && curwin->w_cursor.col == tpos.col) | |
7134 curwin->w_cursor.coladd = tpos.coladd; | |
7135 #endif | |
7136 } | |
7 | 7137 } |
7138 | |
7139 /* If a space was inserted for auto-formatting, remove it now. */ | |
7140 check_auto_format(TRUE); | |
7141 | |
7142 /* If we just did an auto-indent, remove the white space from the end | |
10 | 7143 * of the line, and put the cursor back. |
1892 | 7144 * Do this when ESC was used or moving the cursor up/down. |
7145 * Check for the old position still being valid, just in case the text | |
7146 * got changed unexpectedly. */ | |
5434 | 7147 if (!nomove && did_ai && (esc || (vim_strchr(p_cpo, CPO_INDENT) == NULL |
1892 | 7148 && curwin->w_cursor.lnum != end_insert_pos->lnum)) |
7149 && end_insert_pos->lnum <= curbuf->b_ml.ml_line_count) | |
7 | 7150 { |
10 | 7151 pos_T tpos = curwin->w_cursor; |
7152 | |
7153 curwin->w_cursor = *end_insert_pos; | |
1892 | 7154 check_cursor_col(); /* make sure it is not past the line */ |
786 | 7155 for (;;) |
7156 { | |
7157 if (gchar_cursor() == NUL && curwin->w_cursor.col > 0) | |
7158 --curwin->w_cursor.col; | |
7159 cc = gchar_cursor(); | |
11129
f4ea50924c6d
patch 8.0.0452: some macros are in lower case
Christian Brabandt <cb@256bit.org>
parents:
11127
diff
changeset
|
7160 if (!VIM_ISWHITE(cc)) |
786 | 7161 break; |
1892 | 7162 if (del_char(TRUE) == FAIL) |
7163 break; /* should not happen */ | |
786 | 7164 } |
10 | 7165 if (curwin->w_cursor.lnum != tpos.lnum) |
7166 curwin->w_cursor = tpos; | |
6318 | 7167 else |
7168 { | |
6363 | 7169 /* reset tpos, could have been invalidated in the loop above */ |
7170 tpos = curwin->w_cursor; | |
6318 | 7171 tpos.col++; |
7172 if (cc != NUL && gchar_pos(&tpos) == NUL) | |
7173 ++curwin->w_cursor.col; /* put cursor back on the NUL */ | |
7174 } | |
7 | 7175 |
7176 /* <C-S-Right> may have started Visual mode, adjust the position for | |
7177 * deleted characters. */ | |
7178 if (VIsual_active && VIsual.lnum == curwin->w_cursor.lnum) | |
7179 { | |
1872 | 7180 int len = (int)STRLEN(ml_get_curline()); |
7181 | |
7182 if (VIsual.col > len) | |
7 | 7183 { |
1872 | 7184 VIsual.col = len; |
5735 | 7185 #ifdef FEAT_VIRTUALEDIT |
7 | 7186 VIsual.coladd = 0; |
5735 | 7187 #endif |
7 | 7188 } |
7189 } | |
7190 } | |
7191 } | |
7192 did_ai = FALSE; | |
7193 #ifdef FEAT_SMARTINDENT | |
7194 did_si = FALSE; | |
7195 can_si = FALSE; | |
7196 can_si_back = FALSE; | |
7197 #endif | |
7198 | |
840 | 7199 /* Set '[ and '] to the inserted text. When end_insert_pos is NULL we are |
7200 * now in a different buffer. */ | |
7201 if (end_insert_pos != NULL) | |
7202 { | |
7203 curbuf->b_op_start = Insstart; | |
5680 | 7204 curbuf->b_op_start_orig = Insstart_orig; |
840 | 7205 curbuf->b_op_end = *end_insert_pos; |
7206 } | |
7 | 7207 } |
7208 | |
7209 /* | |
7210 * Set the last inserted text to a single character. | |
7211 * Used for the replace command. | |
7212 */ | |
7213 void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
7214 set_last_insert(int c) |
7 | 7215 { |
7216 char_u *s; | |
7217 | |
7218 vim_free(last_insert); | |
7219 last_insert = alloc(MB_MAXBYTES * 3 + 5); | |
7220 if (last_insert != NULL) | |
7221 { | |
7222 s = last_insert; | |
7223 /* Use the CTRL-V only when entering a special char */ | |
7224 if (c < ' ' || c == DEL) | |
7225 *s++ = Ctrl_V; | |
7226 s = add_char2buf(c, s); | |
7227 *s++ = ESC; | |
7228 *s++ = NUL; | |
7229 last_insert_skip = 0; | |
7230 } | |
7231 } | |
7232 | |
359 | 7233 #if defined(EXITFREE) || defined(PROTO) |
7234 void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
7235 free_last_insert(void) |
359 | 7236 { |
13244
ac42c4b11dbc
patch 8.0.1496: clearing a pointer takes two lines
Christian Brabandt <cb@256bit.org>
parents:
13240
diff
changeset
|
7237 VIM_CLEAR(last_insert); |
1446 | 7238 # ifdef FEAT_INS_EXPAND |
13244
ac42c4b11dbc
patch 8.0.1496: clearing a pointer takes two lines
Christian Brabandt <cb@256bit.org>
parents:
13240
diff
changeset
|
7239 VIM_CLEAR(compl_orig_text); |
1446 | 7240 # endif |
359 | 7241 } |
7242 #endif | |
7243 | |
7 | 7244 /* |
7245 * Add character "c" to buffer "s". Escape the special meaning of K_SPECIAL | |
7246 * and CSI. Handle multi-byte characters. | |
7247 * Returns a pointer to after the added bytes. | |
7248 */ | |
7249 char_u * | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
7250 add_char2buf(int c, char_u *s) |
7 | 7251 { |
3549 | 7252 char_u temp[MB_MAXBYTES + 1]; |
7 | 7253 int i; |
7254 int len; | |
7255 | |
7256 len = (*mb_char2bytes)(c, temp); | |
7257 for (i = 0; i < len; ++i) | |
7258 { | |
7259 c = temp[i]; | |
7260 /* Need to escape K_SPECIAL and CSI like in the typeahead buffer. */ | |
7261 if (c == K_SPECIAL) | |
7262 { | |
7263 *s++ = K_SPECIAL; | |
7264 *s++ = KS_SPECIAL; | |
7265 *s++ = KE_FILLER; | |
7266 } | |
7267 #ifdef FEAT_GUI | |
7268 else if (c == CSI) | |
7269 { | |
7270 *s++ = CSI; | |
7271 *s++ = KS_EXTRA; | |
7272 *s++ = (int)KE_CSI; | |
7273 } | |
7274 #endif | |
7275 else | |
7276 *s++ = c; | |
15595
1ec942f1b648
patch 8.1.0805: too many #ifdefs
Bram Moolenaar <Bram@vim.org>
parents:
15569
diff
changeset
|
7277 } |
7 | 7278 return s; |
7279 } | |
7280 | |
7281 /* | |
7282 * move cursor to start of line | |
7283 * if flags & BL_WHITE move to first non-white | |
7284 * if flags & BL_SOL move to first non-white if startofline is set, | |
7285 * otherwise keep "curswant" column | |
7286 * if flags & BL_FIX don't leave the cursor on a NUL. | |
7287 */ | |
7288 void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
7289 beginline(int flags) |
7 | 7290 { |
7291 if ((flags & BL_SOL) && !p_sol) | |
7292 coladvance(curwin->w_curswant); | |
7293 else | |
7294 { | |
7295 curwin->w_cursor.col = 0; | |
7296 #ifdef FEAT_VIRTUALEDIT | |
7297 curwin->w_cursor.coladd = 0; | |
7298 #endif | |
7299 | |
7300 if (flags & (BL_WHITE | BL_SOL)) | |
7301 { | |
7302 char_u *ptr; | |
7303 | |
11129
f4ea50924c6d
patch 8.0.0452: some macros are in lower case
Christian Brabandt <cb@256bit.org>
parents:
11127
diff
changeset
|
7304 for (ptr = ml_get_curline(); VIM_ISWHITE(*ptr) |
7 | 7305 && !((flags & BL_FIX) && ptr[1] == NUL); ++ptr) |
7306 ++curwin->w_cursor.col; | |
7307 } | |
7308 curwin->w_set_curswant = TRUE; | |
7309 } | |
7310 } | |
7311 | |
7312 /* | |
7313 * oneright oneleft cursor_down cursor_up | |
7314 * | |
7315 * Move one char {right,left,down,up}. | |
773 | 7316 * Doesn't move onto the NUL past the end of the line, unless it is allowed. |
7 | 7317 * Return OK when successful, FAIL when we hit a line of file boundary. |
7318 */ | |
7319 | |
7320 int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
7321 oneright(void) |
7 | 7322 { |
7323 char_u *ptr; | |
7324 int l; | |
7325 | |
7326 #ifdef FEAT_VIRTUALEDIT | |
7327 if (virtual_active()) | |
7328 { | |
7329 pos_T prevpos = curwin->w_cursor; | |
7330 | |
7331 /* Adjust for multi-wide char (excluding TAB) */ | |
7332 ptr = ml_get_cursor(); | |
15595
1ec942f1b648
patch 8.1.0805: too many #ifdefs
Bram Moolenaar <Bram@vim.org>
parents:
15569
diff
changeset
|
7333 coladvance(getviscol() + ((*ptr != TAB |
1ec942f1b648
patch 8.1.0805: too many #ifdefs
Bram Moolenaar <Bram@vim.org>
parents:
15569
diff
changeset
|
7334 && vim_isprintc((*mb_ptr2char)(ptr))) |
7 | 7335 ? ptr2cells(ptr) : 1)); |
7336 curwin->w_set_curswant = TRUE; | |
7337 /* Return OK if the cursor moved, FAIL otherwise (at window edge). */ | |
7338 return (prevpos.col != curwin->w_cursor.col | |
7339 || prevpos.coladd != curwin->w_cursor.coladd) ? OK : FAIL; | |
7340 } | |
7341 #endif | |
7342 | |
7343 ptr = ml_get_cursor(); | |
773 | 7344 if (*ptr == NUL) |
7345 return FAIL; /* already at the very end */ | |
7346 | |
7347 if (has_mbyte) | |
7348 l = (*mb_ptr2len)(ptr); | |
7 | 7349 else |
773 | 7350 l = 1; |
7351 | |
7352 /* move "l" bytes right, but don't end up on the NUL, unless 'virtualedit' | |
7353 * contains "onemore". */ | |
7354 if (ptr[l] == NUL | |
7355 #ifdef FEAT_VIRTUALEDIT | |
7356 && (ve_flags & VE_ONEMORE) == 0 | |
7357 #endif | |
7358 ) | |
7359 return FAIL; | |
7360 curwin->w_cursor.col += l; | |
7 | 7361 |
7362 curwin->w_set_curswant = TRUE; | |
7363 return OK; | |
7364 } | |
7365 | |
7366 int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
7367 oneleft(void) |
7 | 7368 { |
7369 #ifdef FEAT_VIRTUALEDIT | |
7370 if (virtual_active()) | |
7371 { | |
11617
1d6bcb9ff291
patch 8.0.0691: compiler warning without the linebreak feature
Christian Brabandt <cb@256bit.org>
parents:
11573
diff
changeset
|
7372 # ifdef FEAT_LINEBREAK |
7 | 7373 int width; |
11617
1d6bcb9ff291
patch 8.0.0691: compiler warning without the linebreak feature
Christian Brabandt <cb@256bit.org>
parents:
11573
diff
changeset
|
7374 # endif |
7 | 7375 int v = getviscol(); |
7376 | |
7377 if (v == 0) | |
7378 return FAIL; | |
7379 | |
7380 # ifdef FEAT_LINEBREAK | |
7381 /* We might get stuck on 'showbreak', skip over it. */ | |
7382 width = 1; | |
7383 for (;;) | |
7384 { | |
7385 coladvance(v - width); | |
5995 | 7386 /* getviscol() is slow, skip it when 'showbreak' is empty, |
7387 * 'breakindent' is not set and there are no multi-byte | |
7388 * characters */ | |
7389 if ((*p_sbr == NUL && !curwin->w_p_bri | |
15595
1ec942f1b648
patch 8.1.0805: too many #ifdefs
Bram Moolenaar <Bram@vim.org>
parents:
15569
diff
changeset
|
7390 && !has_mbyte) || getviscol() < v) |
7 | 7391 break; |
7392 ++width; | |
7393 } | |
7394 # else | |
7395 coladvance(v - 1); | |
7396 # endif | |
7397 | |
7398 if (curwin->w_cursor.coladd == 1) | |
7399 { | |
7400 char_u *ptr; | |
7401 | |
7402 /* Adjust for multi-wide char (not a TAB) */ | |
7403 ptr = ml_get_cursor(); | |
15595
1ec942f1b648
patch 8.1.0805: too many #ifdefs
Bram Moolenaar <Bram@vim.org>
parents:
15569
diff
changeset
|
7404 if (*ptr != TAB && vim_isprintc((*mb_ptr2char)(ptr)) |
1ec942f1b648
patch 8.1.0805: too many #ifdefs
Bram Moolenaar <Bram@vim.org>
parents:
15569
diff
changeset
|
7405 && ptr2cells(ptr) > 1) |
7 | 7406 curwin->w_cursor.coladd = 0; |
7407 } | |
7408 | |
7409 curwin->w_set_curswant = TRUE; | |
7410 return OK; | |
7411 } | |
7412 #endif | |
7413 | |
7414 if (curwin->w_cursor.col == 0) | |
7415 return FAIL; | |
7416 | |
7417 curwin->w_set_curswant = TRUE; | |
7418 --curwin->w_cursor.col; | |
7419 | |
7420 /* if the character on the left of the current cursor is a multi-byte | |
7421 * character, move to its first byte */ | |
7422 if (has_mbyte) | |
7423 mb_adjust_cursor(); | |
7424 return OK; | |
7425 } | |
7426 | |
7427 int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
7428 cursor_up( |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
7429 long n, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
7430 int upd_topline) /* When TRUE: update topline */ |
7 | 7431 { |
7432 linenr_T lnum; | |
7433 | |
7434 if (n > 0) | |
7435 { | |
7436 lnum = curwin->w_cursor.lnum; | |
161 | 7437 /* This fails if the cursor is already in the first line or the count |
7438 * is larger than the line number and '-' is in 'cpoptions' */ | |
7439 if (lnum <= 1 || (n >= lnum && vim_strchr(p_cpo, CPO_MINUS) != NULL)) | |
7 | 7440 return FAIL; |
7441 if (n >= lnum) | |
7442 lnum = 1; | |
7443 else | |
7444 #ifdef FEAT_FOLDING | |
7445 if (hasAnyFolding(curwin)) | |
7446 { | |
7447 /* | |
7448 * Count each sequence of folded lines as one logical line. | |
7449 */ | |
4352 | 7450 /* go to the start of the current fold */ |
7 | 7451 (void)hasFolding(lnum, &lnum, NULL); |
7452 | |
7453 while (n--) | |
7454 { | |
7455 /* move up one line */ | |
7456 --lnum; | |
7457 if (lnum <= 1) | |
7458 break; | |
7459 /* If we entered a fold, move to the beginning, unless in | |
7460 * Insert mode or when 'foldopen' contains "all": it will open | |
7461 * in a moment. */ | |
7462 if (n > 0 || !((State & INSERT) || (fdo_flags & FDO_ALL))) | |
7463 (void)hasFolding(lnum, &lnum, NULL); | |
7464 } | |
7465 if (lnum < 1) | |
7466 lnum = 1; | |
7467 } | |
7468 else | |
7469 #endif | |
7470 lnum -= n; | |
7471 curwin->w_cursor.lnum = lnum; | |
7472 } | |
7473 | |
7474 /* try to advance to the column we want to be at */ | |
7475 coladvance(curwin->w_curswant); | |
7476 | |
7477 if (upd_topline) | |
7478 update_topline(); /* make sure curwin->w_topline is valid */ | |
7479 | |
7480 return OK; | |
7481 } | |
7482 | |
7483 /* | |
7484 * Cursor down a number of logical lines. | |
7485 */ | |
7486 int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
7487 cursor_down( |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
7488 long n, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
7489 int upd_topline) /* When TRUE: update topline */ |
7 | 7490 { |
7491 linenr_T lnum; | |
7492 | |
7493 if (n > 0) | |
7494 { | |
7495 lnum = curwin->w_cursor.lnum; | |
7496 #ifdef FEAT_FOLDING | |
7497 /* Move to last line of fold, will fail if it's the end-of-file. */ | |
7498 (void)hasFolding(lnum, NULL, &lnum); | |
7499 #endif | |
161 | 7500 /* This fails if the cursor is already in the last line or would move |
4352 | 7501 * beyond the last line and '-' is in 'cpoptions' */ |
161 | 7502 if (lnum >= curbuf->b_ml.ml_line_count |
7503 || (lnum + n > curbuf->b_ml.ml_line_count | |
7504 && vim_strchr(p_cpo, CPO_MINUS) != NULL)) | |
7 | 7505 return FAIL; |
7506 if (lnum + n >= curbuf->b_ml.ml_line_count) | |
7507 lnum = curbuf->b_ml.ml_line_count; | |
7508 else | |
7509 #ifdef FEAT_FOLDING | |
7510 if (hasAnyFolding(curwin)) | |
7511 { | |
7512 linenr_T last; | |
7513 | |
7514 /* count each sequence of folded lines as one logical line */ | |
7515 while (n--) | |
7516 { | |
7517 if (hasFolding(lnum, NULL, &last)) | |
7518 lnum = last + 1; | |
7519 else | |
7520 ++lnum; | |
7521 if (lnum >= curbuf->b_ml.ml_line_count) | |
7522 break; | |
7523 } | |
7524 if (lnum > curbuf->b_ml.ml_line_count) | |
7525 lnum = curbuf->b_ml.ml_line_count; | |
7526 } | |
7527 else | |
7528 #endif | |
7529 lnum += n; | |
7530 curwin->w_cursor.lnum = lnum; | |
7531 } | |
7532 | |
7533 /* try to advance to the column we want to be at */ | |
7534 coladvance(curwin->w_curswant); | |
7535 | |
7536 if (upd_topline) | |
7537 update_topline(); /* make sure curwin->w_topline is valid */ | |
7538 | |
7539 return OK; | |
7540 } | |
7541 | |
7542 /* | |
7543 * Stuff the last inserted text in the read buffer. | |
7544 * Last_insert actually is a copy of the redo buffer, so we | |
7545 * first have to remove the command. | |
7546 */ | |
7547 int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
7548 stuff_inserted( |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
7549 int c, /* Command character to be inserted */ |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
7550 long count, /* Repeat this many times */ |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
7551 int no_esc) /* Don't add an ESC at the end */ |
7 | 7552 { |
7553 char_u *esc_ptr; | |
7554 char_u *ptr; | |
7555 char_u *last_ptr; | |
7556 char_u last = NUL; | |
7557 | |
7558 ptr = get_last_insert(); | |
7559 if (ptr == NULL) | |
7560 { | |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
15440
diff
changeset
|
7561 emsg(_(e_noinstext)); |
7 | 7562 return FAIL; |
7563 } | |
7564 | |
7565 /* may want to stuff the command character, to start Insert mode */ | |
7566 if (c != NUL) | |
7567 stuffcharReadbuff(c); | |
7568 if ((esc_ptr = (char_u *)vim_strrchr(ptr, ESC)) != NULL) | |
7569 *esc_ptr = NUL; /* remove the ESC */ | |
7570 | |
7571 /* when the last char is either "0" or "^" it will be quoted if no ESC | |
7572 * comes after it OR if it will inserted more than once and "ptr" | |
7573 * starts with ^D. -- Acevedo | |
7574 */ | |
7575 last_ptr = (esc_ptr ? esc_ptr : ptr + STRLEN(ptr)) - 1; | |
7576 if (last_ptr >= ptr && (*last_ptr == '0' || *last_ptr == '^') | |
7577 && (no_esc || (*ptr == Ctrl_D && count > 1))) | |
7578 { | |
7579 last = *last_ptr; | |
7580 *last_ptr = NUL; | |
7581 } | |
7582 | |
7583 do | |
7584 { | |
7585 stuffReadbuff(ptr); | |
7586 /* a trailing "0" is inserted as "<C-V>048", "^" as "<C-V>^" */ | |
7587 if (last) | |
7588 stuffReadbuff((char_u *)(last == '0' | |
7589 ? IF_EB("\026\060\064\070", CTRL_V_STR "xf0") | |
7590 : IF_EB("\026^", CTRL_V_STR "^"))); | |
7591 } | |
7592 while (--count > 0); | |
7593 | |
7594 if (last) | |
7595 *last_ptr = last; | |
7596 | |
7597 if (esc_ptr != NULL) | |
7598 *esc_ptr = ESC; /* put the ESC back */ | |
7599 | |
7600 /* may want to stuff a trailing ESC, to get out of Insert mode */ | |
7601 if (!no_esc) | |
7602 stuffcharReadbuff(ESC); | |
7603 | |
7604 return OK; | |
7605 } | |
7606 | |
7607 char_u * | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
7608 get_last_insert(void) |
7 | 7609 { |
7610 if (last_insert == NULL) | |
7611 return NULL; | |
7612 return last_insert + last_insert_skip; | |
7613 } | |
7614 | |
7615 /* | |
7616 * Get last inserted string, and remove trailing <Esc>. | |
7617 * Returns pointer to allocated memory (must be freed) or NULL. | |
7618 */ | |
7619 char_u * | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
7620 get_last_insert_save(void) |
7 | 7621 { |
7622 char_u *s; | |
7623 int len; | |
7624 | |
7625 if (last_insert == NULL) | |
7626 return NULL; | |
7627 s = vim_strsave(last_insert + last_insert_skip); | |
7628 if (s != NULL) | |
7629 { | |
7630 len = (int)STRLEN(s); | |
7631 if (len > 0 && s[len - 1] == ESC) /* remove trailing ESC */ | |
7632 s[len - 1] = NUL; | |
7633 } | |
7634 return s; | |
7635 } | |
7636 | |
7637 /* | |
7638 * Check the word in front of the cursor for an abbreviation. | |
7639 * Called when the non-id character "c" has been entered. | |
7640 * When an abbreviation is recognized it is removed from the text and | |
7641 * the replacement string is inserted in typebuf.tb_buf[], followed by "c". | |
7642 */ | |
7643 static int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
7644 echeck_abbr(int c) |
7 | 7645 { |
7646 /* Don't check for abbreviation in paste mode, when disabled and just | |
7647 * after moving around with cursor keys. */ | |
7648 if (p_paste || no_abbr || arrow_used) | |
7649 return FALSE; | |
7650 | |
7651 return check_abbr(c, ml_get_curline(), curwin->w_cursor.col, | |
7652 curwin->w_cursor.lnum == Insstart.lnum ? Insstart.col : 0); | |
7653 } | |
7654 | |
7655 /* | |
7656 * replace-stack functions | |
7657 * | |
7658 * When replacing characters, the replaced characters are remembered for each | |
7659 * new character. This is used to re-insert the old text when backspacing. | |
7660 * | |
7661 * There is a NUL headed list of characters for each character that is | |
7662 * currently in the file after the insertion point. When BS is used, one NUL | |
7663 * headed list is put back for the deleted character. | |
7664 * | |
7665 * For a newline, there are two NUL headed lists. One contains the characters | |
7666 * that the NL replaced. The extra one stores the characters after the cursor | |
7667 * that were deleted (always white space). | |
7668 * | |
7669 * Replace_offset is normally 0, in which case replace_push will add a new | |
7670 * character at the end of the stack. If replace_offset is not 0, that many | |
7671 * characters will be left on the stack above the newly inserted character. | |
7672 */ | |
7673 | |
298 | 7674 static char_u *replace_stack = NULL; |
7675 static long replace_stack_nr = 0; /* next entry in replace stack */ | |
7676 static long replace_stack_len = 0; /* max. number of entries */ | |
7 | 7677 |
7678 void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
7679 replace_push( |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
7680 int c) /* character that is replaced (NUL is none) */ |
7 | 7681 { |
7682 char_u *p; | |
7683 | |
7684 if (replace_stack_nr < replace_offset) /* nothing to do */ | |
7685 return; | |
7686 if (replace_stack_len <= replace_stack_nr) | |
7687 { | |
7688 replace_stack_len += 50; | |
7689 p = lalloc(sizeof(char_u) * replace_stack_len, TRUE); | |
7690 if (p == NULL) /* out of memory */ | |
7691 { | |
7692 replace_stack_len -= 50; | |
7693 return; | |
7694 } | |
7695 if (replace_stack != NULL) | |
7696 { | |
7697 mch_memmove(p, replace_stack, | |
7698 (size_t)(replace_stack_nr * sizeof(char_u))); | |
7699 vim_free(replace_stack); | |
7700 } | |
7701 replace_stack = p; | |
7702 } | |
7703 p = replace_stack + replace_stack_nr - replace_offset; | |
7704 if (replace_offset) | |
7705 mch_memmove(p + 1, p, (size_t)(replace_offset * sizeof(char_u))); | |
7706 *p = c; | |
7707 ++replace_stack_nr; | |
7708 } | |
7709 | |
1470 | 7710 /* |
7711 * Push a character onto the replace stack. Handles a multi-byte character in | |
7712 * reverse byte order, so that the first byte is popped off first. | |
7713 * Return the number of bytes done (includes composing characters). | |
7714 */ | |
7715 int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
7716 replace_push_mb(char_u *p) |
1470 | 7717 { |
7718 int l = (*mb_ptr2len)(p); | |
7719 int j; | |
7720 | |
7721 for (j = l - 1; j >= 0; --j) | |
7722 replace_push(p[j]); | |
7723 return l; | |
7724 } | |
7725 | |
7 | 7726 /* |
7727 * Pop one item from the replace stack. | |
7728 * return -1 if stack empty | |
7729 * return replaced character or NUL otherwise | |
7730 */ | |
7731 static int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
7732 replace_pop(void) |
7 | 7733 { |
7734 if (replace_stack_nr == 0) | |
7735 return -1; | |
7736 return (int)replace_stack[--replace_stack_nr]; | |
7737 } | |
7738 | |
7739 /* | |
7740 * Join the top two items on the replace stack. This removes to "off"'th NUL | |
7741 * encountered. | |
7742 */ | |
7743 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
7744 replace_join( |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
7745 int off) /* offset for which NUL to remove */ |
7 | 7746 { |
7747 int i; | |
7748 | |
7749 for (i = replace_stack_nr; --i >= 0; ) | |
7750 if (replace_stack[i] == NUL && off-- <= 0) | |
7751 { | |
7752 --replace_stack_nr; | |
7753 mch_memmove(replace_stack + i, replace_stack + i + 1, | |
7754 (size_t)(replace_stack_nr - i)); | |
7755 return; | |
7756 } | |
7757 } | |
7758 | |
7759 /* | |
7760 * Pop bytes from the replace stack until a NUL is found, and insert them | |
7761 * before the cursor. Can only be used in REPLACE or VREPLACE mode. | |
7762 */ | |
7763 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
7764 replace_pop_ins(void) |
7 | 7765 { |
7766 int cc; | |
7767 int oldState = State; | |
7768 | |
7769 State = NORMAL; /* don't want REPLACE here */ | |
7770 while ((cc = replace_pop()) > 0) | |
7771 { | |
7772 mb_replace_pop_ins(cc); | |
7773 dec_cursor(); | |
7774 } | |
7775 State = oldState; | |
7776 } | |
7777 | |
7778 /* | |
7779 * Insert bytes popped from the replace stack. "cc" is the first byte. If it | |
7780 * indicates a multi-byte char, pop the other bytes too. | |
7781 */ | |
7782 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
7783 mb_replace_pop_ins(int cc) |
7 | 7784 { |
7785 int n; | |
3549 | 7786 char_u buf[MB_MAXBYTES + 1]; |
7 | 7787 int i; |
7788 int c; | |
7789 | |
7790 if (has_mbyte && (n = MB_BYTE2LEN(cc)) > 1) | |
7791 { | |
7792 buf[0] = cc; | |
7793 for (i = 1; i < n; ++i) | |
7794 buf[i] = replace_pop(); | |
7795 ins_bytes_len(buf, n); | |
7796 } | |
7797 else | |
7798 ins_char(cc); | |
7799 | |
7800 if (enc_utf8) | |
7801 /* Handle composing chars. */ | |
7802 for (;;) | |
7803 { | |
7804 c = replace_pop(); | |
7805 if (c == -1) /* stack empty */ | |
7806 break; | |
7807 if ((n = MB_BYTE2LEN(c)) == 1) | |
7808 { | |
7809 /* Not a multi-byte char, put it back. */ | |
7810 replace_push(c); | |
7811 break; | |
7812 } | |
7813 else | |
7814 { | |
7815 buf[0] = c; | |
7816 for (i = 1; i < n; ++i) | |
7817 buf[i] = replace_pop(); | |
7818 if (utf_iscomposing(utf_ptr2char(buf))) | |
7819 ins_bytes_len(buf, n); | |
7820 else | |
7821 { | |
7822 /* Not a composing char, put it back. */ | |
7823 for (i = n - 1; i >= 0; --i) | |
7824 replace_push(buf[i]); | |
7825 break; | |
7826 } | |
7827 } | |
7828 } | |
7829 } | |
7830 | |
7831 /* | |
7832 * make the replace stack empty | |
7833 * (called when exiting replace mode) | |
7834 */ | |
7835 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
7836 replace_flush(void) |
7 | 7837 { |
13244
ac42c4b11dbc
patch 8.0.1496: clearing a pointer takes two lines
Christian Brabandt <cb@256bit.org>
parents:
13240
diff
changeset
|
7838 VIM_CLEAR(replace_stack); |
7 | 7839 replace_stack_len = 0; |
7840 replace_stack_nr = 0; | |
7841 } | |
7842 | |
7843 /* | |
7844 * Handle doing a BS for one character. | |
7845 * cc < 0: replace stack empty, just move cursor | |
7846 * cc == 0: character was inserted, delete it | |
7847 * cc > 0: character was replaced, put cc (first byte of original char) back | |
7848 * and check for more characters to be put back | |
1782 | 7849 * When "limit_col" is >= 0, don't delete before this column. Matters when |
7850 * using composing characters, use del_char_after_col() instead of del_char(). | |
7 | 7851 */ |
7852 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
7853 replace_do_bs(int limit_col) |
7 | 7854 { |
7855 int cc; | |
7856 int orig_len = 0; | |
7857 int ins_len; | |
7858 int orig_vcols = 0; | |
7859 colnr_T start_vcol; | |
7860 char_u *p; | |
7861 int i; | |
7862 int vcol; | |
7863 | |
7864 cc = replace_pop(); | |
7865 if (cc > 0) | |
7866 { | |
15349
6abee072b93c
patch 8.1.0682: text properties not adjusted when backspacing replaced text
Bram Moolenaar <Bram@vim.org>
parents:
15347
diff
changeset
|
7867 #ifdef FEAT_TEXT_PROP |
15382
87a0e3c3734c
patch 8.1.0699: compiler warning for uninitialized variable
Bram Moolenaar <Bram@vim.org>
parents:
15377
diff
changeset
|
7868 size_t len_before = 0; // init to shut up GCC |
15349
6abee072b93c
patch 8.1.0682: text properties not adjusted when backspacing replaced text
Bram Moolenaar <Bram@vim.org>
parents:
15347
diff
changeset
|
7869 |
6abee072b93c
patch 8.1.0682: text properties not adjusted when backspacing replaced text
Bram Moolenaar <Bram@vim.org>
parents:
15347
diff
changeset
|
7870 if (curbuf->b_has_textprop) |
6abee072b93c
patch 8.1.0682: text properties not adjusted when backspacing replaced text
Bram Moolenaar <Bram@vim.org>
parents:
15347
diff
changeset
|
7871 { |
6abee072b93c
patch 8.1.0682: text properties not adjusted when backspacing replaced text
Bram Moolenaar <Bram@vim.org>
parents:
15347
diff
changeset
|
7872 // Do not adjust text properties for individual delete and insert |
6abee072b93c
patch 8.1.0682: text properties not adjusted when backspacing replaced text
Bram Moolenaar <Bram@vim.org>
parents:
15347
diff
changeset
|
7873 // operations, do it afterwards on the resulting text. |
6abee072b93c
patch 8.1.0682: text properties not adjusted when backspacing replaced text
Bram Moolenaar <Bram@vim.org>
parents:
15347
diff
changeset
|
7874 len_before = STRLEN(ml_get_curline()); |
6abee072b93c
patch 8.1.0682: text properties not adjusted when backspacing replaced text
Bram Moolenaar <Bram@vim.org>
parents:
15347
diff
changeset
|
7875 ++text_prop_frozen; |
6abee072b93c
patch 8.1.0682: text properties not adjusted when backspacing replaced text
Bram Moolenaar <Bram@vim.org>
parents:
15347
diff
changeset
|
7876 } |
6abee072b93c
patch 8.1.0682: text properties not adjusted when backspacing replaced text
Bram Moolenaar <Bram@vim.org>
parents:
15347
diff
changeset
|
7877 #endif |
7 | 7878 if (State & VREPLACE_FLAG) |
7879 { | |
7880 /* Get the number of screen cells used by the character we are | |
7881 * going to delete. */ | |
7882 getvcol(curwin, &curwin->w_cursor, NULL, &start_vcol, NULL); | |
7883 orig_vcols = chartabsize(ml_get_cursor(), start_vcol); | |
7884 } | |
7885 if (has_mbyte) | |
7886 { | |
1782 | 7887 (void)del_char_after_col(limit_col); |
7 | 7888 if (State & VREPLACE_FLAG) |
835 | 7889 orig_len = (int)STRLEN(ml_get_cursor()); |
7 | 7890 replace_push(cc); |
7891 } | |
7892 else | |
7893 { | |
7894 pchar_cursor(cc); | |
7895 if (State & VREPLACE_FLAG) | |
835 | 7896 orig_len = (int)STRLEN(ml_get_cursor()) - 1; |
7 | 7897 } |
7898 replace_pop_ins(); | |
7899 | |
7900 if (State & VREPLACE_FLAG) | |
7901 { | |
7902 /* Get the number of screen cells used by the inserted characters */ | |
7903 p = ml_get_cursor(); | |
835 | 7904 ins_len = (int)STRLEN(p) - orig_len; |
7 | 7905 vcol = start_vcol; |
7906 for (i = 0; i < ins_len; ++i) | |
7907 { | |
7908 vcol += chartabsize(p + i, vcol); | |
474 | 7909 i += (*mb_ptr2len)(p) - 1; |
7 | 7910 } |
7911 vcol -= start_vcol; | |
7912 | |
7913 /* Delete spaces that were inserted after the cursor to keep the | |
7914 * text aligned. */ | |
7915 curwin->w_cursor.col += ins_len; | |
7916 while (vcol > orig_vcols && gchar_cursor() == ' ') | |
7917 { | |
7918 del_char(FALSE); | |
7919 ++orig_vcols; | |
7920 } | |
7921 curwin->w_cursor.col -= ins_len; | |
7922 } | |
7923 | |
15349
6abee072b93c
patch 8.1.0682: text properties not adjusted when backspacing replaced text
Bram Moolenaar <Bram@vim.org>
parents:
15347
diff
changeset
|
7924 // mark the buffer as changed and prepare for displaying |
7 | 7925 changed_bytes(curwin->w_cursor.lnum, curwin->w_cursor.col); |
15349
6abee072b93c
patch 8.1.0682: text properties not adjusted when backspacing replaced text
Bram Moolenaar <Bram@vim.org>
parents:
15347
diff
changeset
|
7926 |
6abee072b93c
patch 8.1.0682: text properties not adjusted when backspacing replaced text
Bram Moolenaar <Bram@vim.org>
parents:
15347
diff
changeset
|
7927 #ifdef FEAT_TEXT_PROP |
6abee072b93c
patch 8.1.0682: text properties not adjusted when backspacing replaced text
Bram Moolenaar <Bram@vim.org>
parents:
15347
diff
changeset
|
7928 if (curbuf->b_has_textprop) |
6abee072b93c
patch 8.1.0682: text properties not adjusted when backspacing replaced text
Bram Moolenaar <Bram@vim.org>
parents:
15347
diff
changeset
|
7929 { |
6abee072b93c
patch 8.1.0682: text properties not adjusted when backspacing replaced text
Bram Moolenaar <Bram@vim.org>
parents:
15347
diff
changeset
|
7930 size_t len_now = STRLEN(ml_get_curline()); |
6abee072b93c
patch 8.1.0682: text properties not adjusted when backspacing replaced text
Bram Moolenaar <Bram@vim.org>
parents:
15347
diff
changeset
|
7931 |
6abee072b93c
patch 8.1.0682: text properties not adjusted when backspacing replaced text
Bram Moolenaar <Bram@vim.org>
parents:
15347
diff
changeset
|
7932 --text_prop_frozen; |
6abee072b93c
patch 8.1.0682: text properties not adjusted when backspacing replaced text
Bram Moolenaar <Bram@vim.org>
parents:
15347
diff
changeset
|
7933 adjust_prop_columns(curwin->w_cursor.lnum, curwin->w_cursor.col, |
6abee072b93c
patch 8.1.0682: text properties not adjusted when backspacing replaced text
Bram Moolenaar <Bram@vim.org>
parents:
15347
diff
changeset
|
7934 (int)(len_now - len_before)); |
6abee072b93c
patch 8.1.0682: text properties not adjusted when backspacing replaced text
Bram Moolenaar <Bram@vim.org>
parents:
15347
diff
changeset
|
7935 } |
6abee072b93c
patch 8.1.0682: text properties not adjusted when backspacing replaced text
Bram Moolenaar <Bram@vim.org>
parents:
15347
diff
changeset
|
7936 #endif |
7 | 7937 } |
7938 else if (cc == 0) | |
1782 | 7939 (void)del_char_after_col(limit_col); |
7 | 7940 } |
7941 | |
7942 #ifdef FEAT_CINDENT | |
7943 /* | |
7944 * Return TRUE if C-indenting is on. | |
7945 */ | |
7946 static int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
7947 cindent_on(void) |
7 | 7948 { |
7949 return (!p_paste && (curbuf->b_p_cin | |
7950 # ifdef FEAT_EVAL | |
7951 || *curbuf->b_p_inde != NUL | |
7952 # endif | |
7953 )); | |
7954 } | |
7955 #endif | |
7956 | |
7957 #if defined(FEAT_LISP) || defined(FEAT_CINDENT) || defined(PROTO) | |
7958 /* | |
7959 * Re-indent the current line, based on the current contents of it and the | |
7960 * surrounding lines. Fixing the cursor position seems really easy -- I'm very | |
7961 * confused what all the part that handles Control-T is doing that I'm not. | |
7962 * "get_the_indent" should be get_c_indent, get_expr_indent or get_lisp_indent. | |
7963 */ | |
7964 | |
7965 void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
7966 fixthisline(int (*get_the_indent)(void)) |
7 | 7967 { |
6971 | 7968 int amount = get_the_indent(); |
7969 | |
7970 if (amount >= 0) | |
7971 { | |
7972 change_indent(INDENT_SET, amount, FALSE, 0, TRUE); | |
7973 if (linewhite(curwin->w_cursor.lnum)) | |
7974 did_ai = TRUE; /* delete the indent if the line stays empty */ | |
7975 } | |
7 | 7976 } |
7977 | |
7978 void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
7979 fix_indent(void) |
7 | 7980 { |
7981 if (p_paste) | |
7982 return; | |
7983 # ifdef FEAT_LISP | |
7984 if (curbuf->b_p_lisp && curbuf->b_p_ai) | |
7985 fixthisline(get_lisp_indent); | |
7986 # endif | |
7987 # if defined(FEAT_LISP) && defined(FEAT_CINDENT) | |
7988 else | |
7989 # endif | |
7990 # ifdef FEAT_CINDENT | |
7991 if (cindent_on()) | |
7992 do_c_expr_indent(); | |
7993 # endif | |
7994 } | |
7995 | |
7996 #endif | |
7997 | |
7998 #ifdef FEAT_CINDENT | |
7999 /* | |
8000 * return TRUE if 'cinkeys' contains the key "keytyped", | |
8001 * when == '*': Only if key is preceded with '*' (indent before insert) | |
4352 | 8002 * when == '!': Only if key is preceded with '!' (don't insert) |
7 | 8003 * when == ' ': Only if key is not preceded with '*'(indent afterwards) |
8004 * | |
8005 * "keytyped" can have a few special values: | |
8006 * KEY_OPEN_FORW | |
8007 * KEY_OPEN_BACK | |
8008 * KEY_COMPLETE just finished completion. | |
8009 * | |
8010 * If line_is_empty is TRUE accept keys with '0' before them. | |
8011 */ | |
8012 int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
8013 in_cinkeys( |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
8014 int keytyped, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
8015 int when, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
8016 int line_is_empty) |
7 | 8017 { |
8018 char_u *look; | |
8019 int try_match; | |
8020 int try_match_word; | |
8021 char_u *p; | |
8022 char_u *line; | |
8023 int icase; | |
8024 int i; | |
8025 | |
2025 | 8026 if (keytyped == NUL) |
8027 /* Can happen with CTRL-Y and CTRL-E on a short line. */ | |
8028 return FALSE; | |
8029 | |
7 | 8030 #ifdef FEAT_EVAL |
8031 if (*curbuf->b_p_inde != NUL) | |
8032 look = curbuf->b_p_indk; /* 'indentexpr' set: use 'indentkeys' */ | |
8033 else | |
8034 #endif | |
8035 look = curbuf->b_p_cink; /* 'indentexpr' empty: use 'cinkeys' */ | |
8036 while (*look) | |
8037 { | |
8038 /* | |
8039 * Find out if we want to try a match with this key, depending on | |
8040 * 'when' and a '*' or '!' before the key. | |
8041 */ | |
8042 switch (when) | |
8043 { | |
8044 case '*': try_match = (*look == '*'); break; | |
8045 case '!': try_match = (*look == '!'); break; | |
8046 default: try_match = (*look != '*'); break; | |
8047 } | |
8048 if (*look == '*' || *look == '!') | |
8049 ++look; | |
8050 | |
8051 /* | |
8052 * If there is a '0', only accept a match if the line is empty. | |
8053 * But may still match when typing last char of a word. | |
8054 */ | |
8055 if (*look == '0') | |
8056 { | |
8057 try_match_word = try_match; | |
8058 if (!line_is_empty) | |
8059 try_match = FALSE; | |
8060 ++look; | |
8061 } | |
8062 else | |
8063 try_match_word = FALSE; | |
8064 | |
8065 /* | |
8066 * does it look like a control character? | |
8067 */ | |
8068 if (*look == '^' | |
8069 #ifdef EBCDIC | |
8070 && (Ctrl_chr(look[1]) != 0) | |
8071 #else | |
8072 && look[1] >= '?' && look[1] <= '_' | |
8073 #endif | |
8074 ) | |
8075 { | |
8076 if (try_match && keytyped == Ctrl_chr(look[1])) | |
8077 return TRUE; | |
8078 look += 2; | |
8079 } | |
8080 /* | |
8081 * 'o' means "o" command, open forward. | |
8082 * 'O' means "O" command, open backward. | |
8083 */ | |
8084 else if (*look == 'o') | |
8085 { | |
8086 if (try_match && keytyped == KEY_OPEN_FORW) | |
8087 return TRUE; | |
8088 ++look; | |
8089 } | |
8090 else if (*look == 'O') | |
8091 { | |
8092 if (try_match && keytyped == KEY_OPEN_BACK) | |
8093 return TRUE; | |
8094 ++look; | |
8095 } | |
8096 | |
8097 /* | |
8098 * 'e' means to check for "else" at start of line and just before the | |
8099 * cursor. | |
8100 */ | |
8101 else if (*look == 'e') | |
8102 { | |
8103 if (try_match && keytyped == 'e' && curwin->w_cursor.col >= 4) | |
8104 { | |
8105 p = ml_get_curline(); | |
8106 if (skipwhite(p) == p + curwin->w_cursor.col - 4 && | |
8107 STRNCMP(p + curwin->w_cursor.col - 4, "else", 4) == 0) | |
8108 return TRUE; | |
8109 } | |
8110 ++look; | |
8111 } | |
8112 | |
8113 /* | |
8114 * ':' only causes an indent if it is at the end of a label or case | |
8115 * statement, or when it was before typing the ':' (to fix | |
8116 * class::method for C++). | |
8117 */ | |
8118 else if (*look == ':') | |
8119 { | |
8120 if (try_match && keytyped == ':') | |
8121 { | |
8122 p = ml_get_curline(); | |
5442 | 8123 if (cin_iscase(p, FALSE) || cin_isscopedecl(p) || cin_islabel()) |
7 | 8124 return TRUE; |
1300 | 8125 /* Need to get the line again after cin_islabel(). */ |
8126 p = ml_get_curline(); | |
7 | 8127 if (curwin->w_cursor.col > 2 |
8128 && p[curwin->w_cursor.col - 1] == ':' | |
8129 && p[curwin->w_cursor.col - 2] == ':') | |
8130 { | |
8131 p[curwin->w_cursor.col - 1] = ' '; | |
2297
5ffe000a9ecf
Improve Javascript indenting. Add "J" flag to 'cino'. (Hari Kumar G)
Bram Moolenaar <bram@vim.org>
parents:
2294
diff
changeset
|
8132 i = (cin_iscase(p, FALSE) || cin_isscopedecl(p) |
5442 | 8133 || cin_islabel()); |
7 | 8134 p = ml_get_curline(); |
8135 p[curwin->w_cursor.col - 1] = ':'; | |
8136 if (i) | |
8137 return TRUE; | |
8138 } | |
8139 } | |
8140 ++look; | |
8141 } | |
8142 | |
8143 | |
8144 /* | |
8145 * Is it a key in <>, maybe? | |
8146 */ | |
8147 else if (*look == '<') | |
8148 { | |
8149 if (try_match) | |
8150 { | |
8151 /* | |
8152 * make up some named keys <o>, <O>, <e>, <0>, <>>, <<>, <*>, | |
8153 * <:> and <!> so that people can re-indent on o, O, e, 0, <, | |
8154 * >, *, : and ! keys if they really really want to. | |
8155 */ | |
8156 if (vim_strchr((char_u *)"<>!*oOe0:", look[1]) != NULL | |
8157 && keytyped == look[1]) | |
8158 return TRUE; | |
8159 | |
8160 if (keytyped == get_special_key_code(look + 1)) | |
8161 return TRUE; | |
8162 } | |
8163 while (*look && *look != '>') | |
8164 look++; | |
8165 while (*look == '>') | |
8166 look++; | |
8167 } | |
8168 | |
8169 /* | |
8170 * Is it a word: "=word"? | |
8171 */ | |
8172 else if (*look == '=' && look[1] != ',' && look[1] != NUL) | |
8173 { | |
8174 ++look; | |
8175 if (*look == '~') | |
8176 { | |
8177 icase = TRUE; | |
8178 ++look; | |
8179 } | |
8180 else | |
8181 icase = FALSE; | |
8182 p = vim_strchr(look, ','); | |
8183 if (p == NULL) | |
8184 p = look + STRLEN(look); | |
8185 if ((try_match || try_match_word) | |
8186 && curwin->w_cursor.col >= (colnr_T)(p - look)) | |
8187 { | |
8188 int match = FALSE; | |
8189 | |
8190 #ifdef FEAT_INS_EXPAND | |
8191 if (keytyped == KEY_COMPLETE) | |
8192 { | |
8193 char_u *s; | |
8194 | |
8195 /* Just completed a word, check if it starts with "look". | |
8196 * search back for the start of a word. */ | |
8197 line = ml_get_curline(); | |
8198 if (has_mbyte) | |
8199 { | |
8200 char_u *n; | |
8201 | |
8202 for (s = line + curwin->w_cursor.col; s > line; s = n) | |
8203 { | |
8204 n = mb_prevptr(line, s); | |
8205 if (!vim_iswordp(n)) | |
8206 break; | |
8207 } | |
8208 } | |
8209 else | |
8210 for (s = line + curwin->w_cursor.col; s > line; --s) | |
8211 if (!vim_iswordc(s[-1])) | |
8212 break; | |
8213 if (s + (p - look) <= line + curwin->w_cursor.col | |
8214 && (icase | |
8215 ? MB_STRNICMP(s, look, p - look) | |
8216 : STRNCMP(s, look, p - look)) == 0) | |
8217 match = TRUE; | |
8218 } | |
8219 else | |
8220 #endif | |
8221 /* TODO: multi-byte */ | |
8222 if (keytyped == (int)p[-1] || (icase && keytyped < 256 | |
8223 && TOLOWER_LOC(keytyped) == TOLOWER_LOC((int)p[-1]))) | |
8224 { | |
8225 line = ml_get_cursor(); | |
8226 if ((curwin->w_cursor.col == (colnr_T)(p - look) | |
8227 || !vim_iswordc(line[-(p - look) - 1])) | |
8228 && (icase | |
8229 ? MB_STRNICMP(line - (p - look), look, p - look) | |
8230 : STRNCMP(line - (p - look), look, p - look)) | |
8231 == 0) | |
8232 match = TRUE; | |
8233 } | |
8234 if (match && try_match_word && !try_match) | |
8235 { | |
8236 /* "0=word": Check if there are only blanks before the | |
8237 * word. */ | |
12551
a69d3595d773
patch 8.0.1154: 'indentkeys' does not work properly
Christian Brabandt <cb@256bit.org>
parents:
12515
diff
changeset
|
8238 if (getwhitecols_curline() != |
7 | 8239 (int)(curwin->w_cursor.col - (p - look))) |
8240 match = FALSE; | |
8241 } | |
8242 if (match) | |
8243 return TRUE; | |
8244 } | |
8245 look = p; | |
8246 } | |
8247 | |
8248 /* | |
8249 * ok, it's a boring generic character. | |
8250 */ | |
8251 else | |
8252 { | |
8253 if (try_match && *look == keytyped) | |
8254 return TRUE; | |
10938
3b82ab325d59
patch 8.0.0358: invalid memory access in C-indent code
Christian Brabandt <cb@256bit.org>
parents:
10916
diff
changeset
|
8255 if (*look != NUL) |
3b82ab325d59
patch 8.0.0358: invalid memory access in C-indent code
Christian Brabandt <cb@256bit.org>
parents:
10916
diff
changeset
|
8256 ++look; |
7 | 8257 } |
8258 | |
8259 /* | |
8260 * Skip over ", ". | |
8261 */ | |
8262 look = skip_to_option_part(look); | |
8263 } | |
8264 return FALSE; | |
8265 } | |
8266 #endif /* FEAT_CINDENT */ | |
8267 | |
8268 #if defined(FEAT_RIGHTLEFT) || defined(PROTO) | |
8269 /* | |
8270 * Map Hebrew keyboard when in hkmap mode. | |
8271 */ | |
8272 int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
8273 hkmap(int c) |
7 | 8274 { |
8275 if (p_hkmapp) /* phonetic mapping, by Ilya Dogolazky */ | |
8276 { | |
8277 enum {hALEF=0, BET, GIMEL, DALET, HEI, VAV, ZAIN, HET, TET, IUD, | |
8278 KAFsofit, hKAF, LAMED, MEMsofit, MEM, NUNsofit, NUN, SAMEH, AIN, | |
8279 PEIsofit, PEI, ZADIsofit, ZADI, KOF, RESH, hSHIN, TAV}; | |
8280 static char_u map[26] = | |
8281 {(char_u)hALEF/*a*/, (char_u)BET /*b*/, (char_u)hKAF /*c*/, | |
8282 (char_u)DALET/*d*/, (char_u)-1 /*e*/, (char_u)PEIsofit/*f*/, | |
8283 (char_u)GIMEL/*g*/, (char_u)HEI /*h*/, (char_u)IUD /*i*/, | |
8284 (char_u)HET /*j*/, (char_u)KOF /*k*/, (char_u)LAMED /*l*/, | |
8285 (char_u)MEM /*m*/, (char_u)NUN /*n*/, (char_u)SAMEH /*o*/, | |
8286 (char_u)PEI /*p*/, (char_u)-1 /*q*/, (char_u)RESH /*r*/, | |
8287 (char_u)ZAIN /*s*/, (char_u)TAV /*t*/, (char_u)TET /*u*/, | |
8288 (char_u)VAV /*v*/, (char_u)hSHIN/*w*/, (char_u)-1 /*x*/, | |
8289 (char_u)AIN /*y*/, (char_u)ZADI /*z*/}; | |
8290 | |
8291 if (c == 'N' || c == 'M' || c == 'P' || c == 'C' || c == 'Z') | |
8292 return (int)(map[CharOrd(c)] - 1 + p_aleph); | |
8293 /* '-1'='sofit' */ | |
8294 else if (c == 'x') | |
8295 return 'X'; | |
8296 else if (c == 'q') | |
8297 return '\''; /* {geresh}={'} */ | |
8298 else if (c == 246) | |
8299 return ' '; /* \"o --> ' ' for a german keyboard */ | |
8300 else if (c == 228) | |
8301 return ' '; /* \"a --> ' ' -- / -- */ | |
8302 else if (c == 252) | |
8303 return ' '; /* \"u --> ' ' -- / -- */ | |
8304 #ifdef EBCDIC | |
8305 else if (islower(c)) | |
8306 #else | |
8307 /* NOTE: islower() does not do the right thing for us on Linux so we | |
8308 * do this the same was as 5.7 and previous, so it works correctly on | |
8309 * all systems. Specifically, the e.g. Delete and Arrow keys are | |
8310 * munged and won't work if e.g. searching for Hebrew text. | |
8311 */ | |
8312 else if (c >= 'a' && c <= 'z') | |
8313 #endif | |
8314 return (int)(map[CharOrdLow(c)] + p_aleph); | |
8315 else | |
8316 return c; | |
8317 } | |
8318 else | |
8319 { | |
8320 switch (c) | |
8321 { | |
8322 case '`': return ';'; | |
8323 case '/': return '.'; | |
8324 case '\'': return ','; | |
8325 case 'q': return '/'; | |
8326 case 'w': return '\''; | |
8327 | |
8328 /* Hebrew letters - set offset from 'a' */ | |
8329 case ',': c = '{'; break; | |
8330 case '.': c = 'v'; break; | |
8331 case ';': c = 't'; break; | |
8332 default: { | |
8333 static char str[] = "zqbcxlsjphmkwonu ydafe rig"; | |
8334 | |
8335 #ifdef EBCDIC | |
8336 /* see note about islower() above */ | |
8337 if (!islower(c)) | |
8338 #else | |
8339 if (c < 'a' || c > 'z') | |
8340 #endif | |
8341 return c; | |
8342 c = str[CharOrdLow(c)]; | |
8343 break; | |
8344 } | |
8345 } | |
8346 | |
8347 return (int)(CharOrdLow(c) + p_aleph); | |
8348 } | |
8349 } | |
8350 #endif | |
8351 | |
8352 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
8353 ins_reg(void) |
7 | 8354 { |
8355 int need_redraw = FALSE; | |
8356 int regname; | |
8357 int literally = 0; | |
844 | 8358 int vis_active = VIsual_active; |
7 | 8359 |
8360 /* | |
8361 * If we are going to wait for a character, show a '"'. | |
8362 */ | |
8363 pc_status = PC_STATUS_UNSET; | |
8364 if (redrawing() && !char_avail()) | |
8365 { | |
8366 /* may need to redraw when no more chars available now */ | |
661 | 8367 ins_redraw(FALSE); |
7 | 8368 |
8369 edit_putchar('"', TRUE); | |
8370 #ifdef FEAT_CMDL_INFO | |
8371 add_to_showcmd_c(Ctrl_R); | |
8372 #endif | |
8373 } | |
8374 | |
8375 #ifdef USE_ON_FLY_SCROLL | |
8376 dont_scroll = TRUE; /* disallow scrolling here */ | |
8377 #endif | |
8378 | |
8379 /* | |
8380 * Don't map the register name. This also prevents the mode message to be | |
8381 * deleted when ESC is hit. | |
8382 */ | |
8383 ++no_mapping; | |
1389 | 8384 regname = plain_vgetc(); |
7 | 8385 LANGMAP_ADJUST(regname, TRUE); |
8386 if (regname == Ctrl_R || regname == Ctrl_O || regname == Ctrl_P) | |
8387 { | |
8388 /* Get a third key for literal register insertion */ | |
8389 literally = regname; | |
8390 #ifdef FEAT_CMDL_INFO | |
8391 add_to_showcmd_c(literally); | |
8392 #endif | |
1389 | 8393 regname = plain_vgetc(); |
7 | 8394 LANGMAP_ADJUST(regname, TRUE); |
8395 } | |
8396 --no_mapping; | |
8397 | |
8398 #ifdef FEAT_EVAL | |
4909
2945fe016b93
updated for version 7.3.1200
Bram Moolenaar <bram@vim.org>
parents:
4805
diff
changeset
|
8399 /* Don't call u_sync() while typing the expression or giving an error |
2945fe016b93
updated for version 7.3.1200
Bram Moolenaar <bram@vim.org>
parents:
4805
diff
changeset
|
8400 * message for it. Only call it explicitly. */ |
7 | 8401 ++no_u_sync; |
8402 if (regname == '=') | |
8403 { | |
15569
43fa814a7977
patch 8.1.0792: bad display if opening cmdline window from Insert completion
Bram Moolenaar <Bram@vim.org>
parents:
15543
diff
changeset
|
8404 pos_T curpos = curwin->w_cursor; |
13380
69517d67421f
patch 8.0.1564: too many #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
13244
diff
changeset
|
8405 # ifdef HAVE_INPUT_METHOD |
7 | 8406 int im_on = im_get_status(); |
133 | 8407 # endif |
5120
6e611380b4cf
updated for version 7.3.1303
Bram Moolenaar <bram@vim.org>
parents:
5094
diff
changeset
|
8408 /* Sync undo when evaluating the expression calls setline() or |
6e611380b4cf
updated for version 7.3.1303
Bram Moolenaar <bram@vim.org>
parents:
5094
diff
changeset
|
8409 * append(), so that it can be undone separately. */ |
6e611380b4cf
updated for version 7.3.1303
Bram Moolenaar <bram@vim.org>
parents:
5094
diff
changeset
|
8410 u_sync_once = 2; |
5018
d6a7dea44a86
updated for version 7.3.1253
Bram Moolenaar <bram@vim.org>
parents:
4909
diff
changeset
|
8411 |
7 | 8412 regname = get_expr_register(); |
15569
43fa814a7977
patch 8.1.0792: bad display if opening cmdline window from Insert completion
Bram Moolenaar <Bram@vim.org>
parents:
15543
diff
changeset
|
8413 |
43fa814a7977
patch 8.1.0792: bad display if opening cmdline window from Insert completion
Bram Moolenaar <Bram@vim.org>
parents:
15543
diff
changeset
|
8414 // Cursor may be moved back a column. |
43fa814a7977
patch 8.1.0792: bad display if opening cmdline window from Insert completion
Bram Moolenaar <Bram@vim.org>
parents:
15543
diff
changeset
|
8415 curwin->w_cursor = curpos; |
43fa814a7977
patch 8.1.0792: bad display if opening cmdline window from Insert completion
Bram Moolenaar <Bram@vim.org>
parents:
15543
diff
changeset
|
8416 check_cursor(); |
13380
69517d67421f
patch 8.0.1564: too many #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
13244
diff
changeset
|
8417 # ifdef HAVE_INPUT_METHOD |
15569
43fa814a7977
patch 8.1.0792: bad display if opening cmdline window from Insert completion
Bram Moolenaar <Bram@vim.org>
parents:
15543
diff
changeset
|
8418 // Restore the Input Method. |
7 | 8419 if (im_on) |
8420 im_set_active(TRUE); | |
133 | 8421 # endif |
7 | 8422 } |
140 | 8423 if (regname == NUL || !valid_yank_reg(regname, FALSE)) |
8424 { | |
6949 | 8425 vim_beep(BO_REG); |
7 | 8426 need_redraw = TRUE; /* remove the '"' */ |
140 | 8427 } |
7 | 8428 else |
8429 { | |
8430 #endif | |
8431 if (literally == Ctrl_O || literally == Ctrl_P) | |
8432 { | |
8433 /* Append the command to the redo buffer. */ | |
8434 AppendCharToRedobuff(Ctrl_R); | |
8435 AppendCharToRedobuff(literally); | |
8436 AppendCharToRedobuff(regname); | |
8437 | |
8438 do_put(regname, BACKWARD, 1L, | |
8439 (literally == Ctrl_P ? PUT_FIXINDENT : 0) | PUT_CURSEND); | |
8440 } | |
8441 else if (insert_reg(regname, literally) == FAIL) | |
8442 { | |
6949 | 8443 vim_beep(BO_REG); |
7 | 8444 need_redraw = TRUE; /* remove the '"' */ |
8445 } | |
133 | 8446 else if (stop_insert_mode) |
8447 /* When the '=' register was used and a function was invoked that | |
8448 * did ":stopinsert" then stuff_empty() returns FALSE but we won't | |
8449 * insert anything, need to remove the '"' */ | |
8450 need_redraw = TRUE; | |
8451 | |
7 | 8452 #ifdef FEAT_EVAL |
8453 } | |
8454 --no_u_sync; | |
5120
6e611380b4cf
updated for version 7.3.1303
Bram Moolenaar <bram@vim.org>
parents:
5094
diff
changeset
|
8455 if (u_sync_once == 1) |
6e611380b4cf
updated for version 7.3.1303
Bram Moolenaar <bram@vim.org>
parents:
5094
diff
changeset
|
8456 ins_need_undo = TRUE; |
6e611380b4cf
updated for version 7.3.1303
Bram Moolenaar <bram@vim.org>
parents:
5094
diff
changeset
|
8457 u_sync_once = 0; |
7 | 8458 #endif |
8459 #ifdef FEAT_CMDL_INFO | |
8460 clear_showcmd(); | |
8461 #endif | |
8462 | |
8463 /* If the inserted register is empty, we need to remove the '"' */ | |
8464 if (need_redraw || stuff_empty()) | |
8465 edit_unputchar(); | |
844 | 8466 |
8467 /* Disallow starting Visual mode here, would get a weird mode. */ | |
8468 if (!vis_active && VIsual_active) | |
8469 end_visual_mode(); | |
7 | 8470 } |
8471 | |
8472 /* | |
8473 * CTRL-G commands in Insert mode. | |
8474 */ | |
8475 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
8476 ins_ctrl_g(void) |
7 | 8477 { |
8478 int c; | |
8479 | |
8480 #ifdef FEAT_INS_EXPAND | |
8481 /* Right after CTRL-X the cursor will be after the ruler. */ | |
8482 setcursor(); | |
8483 #endif | |
8484 | |
8485 /* | |
8486 * Don't map the second key. This also prevents the mode message to be | |
8487 * deleted when ESC is hit. | |
8488 */ | |
8489 ++no_mapping; | |
1389 | 8490 c = plain_vgetc(); |
7 | 8491 --no_mapping; |
8492 switch (c) | |
8493 { | |
8494 /* CTRL-G k and CTRL-G <Up>: cursor up to Insstart.col */ | |
8495 case K_UP: | |
8496 case Ctrl_K: | |
8497 case 'k': ins_up(TRUE); | |
8498 break; | |
8499 | |
8500 /* CTRL-G j and CTRL-G <Down>: cursor down to Insstart.col */ | |
8501 case K_DOWN: | |
8502 case Ctrl_J: | |
8503 case 'j': ins_down(TRUE); | |
8504 break; | |
8505 | |
8506 /* CTRL-G u: start new undoable edit */ | |
825 | 8507 case 'u': u_sync(TRUE); |
7 | 8508 ins_need_undo = TRUE; |
626 | 8509 |
8510 /* Need to reset Insstart, esp. because a BS that joins | |
1219 | 8511 * a line to the previous one must save for undo. */ |
5680 | 8512 update_Insstart_orig = FALSE; |
626 | 8513 Insstart = curwin->w_cursor; |
7 | 8514 break; |
8515 | |
7074
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
8516 /* CTRL-G U: do not break undo with the next char */ |
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
8517 case 'U': |
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
8518 /* Allow one left/right cursor movement with the next char, |
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
8519 * without breaking undo. */ |
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
8520 dont_sync_undo = MAYBE; |
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
8521 break; |
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
8522 |
7 | 8523 /* Unknown CTRL-G command, reserved for future expansion. */ |
6949 | 8524 default: vim_beep(BO_CTRLG); |
7 | 8525 } |
8526 } | |
8527 | |
8528 /* | |
449 | 8529 * CTRL-^ in Insert mode. |
8530 */ | |
8531 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
8532 ins_ctrl_hat(void) |
449 | 8533 { |
782 | 8534 if (map_to_exists_mode((char_u *)"", LANGMAP, FALSE)) |
449 | 8535 { |
8536 /* ":lmap" mappings exists, Toggle use of ":lmap" mappings. */ | |
8537 if (State & LANGMAP) | |
8538 { | |
8539 curbuf->b_p_iminsert = B_IMODE_NONE; | |
8540 State &= ~LANGMAP; | |
8541 } | |
8542 else | |
8543 { | |
8544 curbuf->b_p_iminsert = B_IMODE_LMAP; | |
8545 State |= LANGMAP; | |
13380
69517d67421f
patch 8.0.1564: too many #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
13244
diff
changeset
|
8546 #ifdef HAVE_INPUT_METHOD |
449 | 8547 im_set_active(FALSE); |
8548 #endif | |
8549 } | |
8550 } | |
13380
69517d67421f
patch 8.0.1564: too many #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
13244
diff
changeset
|
8551 #ifdef HAVE_INPUT_METHOD |
449 | 8552 else |
8553 { | |
8554 /* There are no ":lmap" mappings, toggle IM */ | |
8555 if (im_get_status()) | |
8556 { | |
8557 curbuf->b_p_iminsert = B_IMODE_NONE; | |
8558 im_set_active(FALSE); | |
8559 } | |
8560 else | |
8561 { | |
8562 curbuf->b_p_iminsert = B_IMODE_IM; | |
8563 State &= ~LANGMAP; | |
8564 im_set_active(TRUE); | |
8565 } | |
8566 } | |
8567 #endif | |
8568 set_iminsert_global(); | |
8569 showmode(); | |
8570 #ifdef FEAT_GUI | |
8571 /* may show different cursor shape or color */ | |
8572 if (gui.in_use) | |
8573 gui_update_cursor(TRUE, FALSE); | |
8574 #endif | |
12477
68d7bc045dbe
patch 8.0.1118: FEAT_WINDOWS adds a lot of #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
12323
diff
changeset
|
8575 #if defined(FEAT_KEYMAP) |
449 | 8576 /* Show/unshow value of 'keymap' in status lines. */ |
8577 status_redraw_curbuf(); | |
8578 #endif | |
8579 } | |
8580 | |
8581 /* | |
7 | 8582 * Handle ESC in insert mode. |
8583 * Returns TRUE when leaving insert mode, FALSE when going to repeat the | |
8584 * insert. | |
8585 */ | |
8586 static int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
8587 ins_esc( |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
8588 long *count, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
8589 int cmdchar, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
8590 int nomove) /* don't move cursor */ |
7 | 8591 { |
8592 int temp; | |
8593 static int disabled_redraw = FALSE; | |
8594 | |
744 | 8595 #ifdef FEAT_SPELL |
449 | 8596 check_spell_redraw(); |
8597 #endif | |
7 | 8598 #if defined(FEAT_HANGULIN) |
8599 # if defined(ESC_CHG_TO_ENG_MODE) | |
8600 hangul_input_state_set(0); | |
8601 # endif | |
8602 if (composing_hangul) | |
8603 { | |
8604 push_raw_key(composing_hangul_buffer, 2); | |
8605 composing_hangul = 0; | |
8606 } | |
8607 #endif | |
8608 | |
8609 temp = curwin->w_cursor.col; | |
8610 if (disabled_redraw) | |
8611 { | |
8612 --RedrawingDisabled; | |
8613 disabled_redraw = FALSE; | |
8614 } | |
8615 if (!arrow_used) | |
8616 { | |
8617 /* | |
8618 * Don't append the ESC for "r<CR>" and "grx". | |
75 | 8619 * When 'insertmode' is set only CTRL-L stops Insert mode. Needed for |
8620 * when "count" is non-zero. | |
7 | 8621 */ |
8622 if (cmdchar != 'r' && cmdchar != 'v') | |
75 | 8623 AppendToRedobuff(p_im ? (char_u *)"\014" : ESC_STR); |
7 | 8624 |
8625 /* | |
8626 * Repeating insert may take a long time. Check for | |
8627 * interrupt now and then. | |
8628 */ | |
8629 if (*count > 0) | |
8630 { | |
8631 line_breakcheck(); | |
8632 if (got_int) | |
8633 *count = 0; | |
8634 } | |
8635 | |
8636 if (--*count > 0) /* repeat what was typed */ | |
8637 { | |
164 | 8638 /* Vi repeats the insert without replacing characters. */ |
8639 if (vim_strchr(p_cpo, CPO_REPLCNT) != NULL) | |
8640 State &= ~REPLACE_FLAG; | |
8641 | |
7 | 8642 (void)start_redo_ins(); |
8643 if (cmdchar == 'r' || cmdchar == 'v') | |
6098 | 8644 stuffRedoReadbuff(ESC_STR); /* no ESC in redo buffer */ |
7 | 8645 ++RedrawingDisabled; |
8646 disabled_redraw = TRUE; | |
8647 return FALSE; /* repeat the insert */ | |
8648 } | |
5434 | 8649 stop_insert(&curwin->w_cursor, TRUE, nomove); |
7 | 8650 undisplay_dollar(); |
8651 } | |
8652 | |
8653 /* When an autoindent was removed, curswant stays after the | |
8654 * indent */ | |
8655 if (restart_edit == NUL && (colnr_T)temp == curwin->w_cursor.col) | |
8656 curwin->w_set_curswant = TRUE; | |
8657 | |
8658 /* Remember the last Insert position in the '^ mark. */ | |
8659 if (!cmdmod.keepjumps) | |
8660 curbuf->b_last_insert = curwin->w_cursor; | |
8661 | |
8662 /* | |
8663 * The cursor should end up on the last inserted character. | |
477 | 8664 * Don't do it for CTRL-O, unless past the end of the line. |
7 | 8665 */ |
477 | 8666 if (!nomove |
8667 && (curwin->w_cursor.col != 0 | |
7 | 8668 #ifdef FEAT_VIRTUALEDIT |
8669 || curwin->w_cursor.coladd > 0 | |
8670 #endif | |
477 | 8671 ) |
8672 && (restart_edit == NUL | |
5735 | 8673 || (gchar_cursor() == NUL && !VIsual_active)) |
7 | 8674 #ifdef FEAT_RIGHTLEFT |
8675 && !revins_on | |
8676 #endif | |
8677 ) | |
8678 { | |
8679 #ifdef FEAT_VIRTUALEDIT | |
8680 if (curwin->w_cursor.coladd > 0 || ve_flags == VE_ALL) | |
8681 { | |
8682 oneleft(); | |
8683 if (restart_edit != NUL) | |
8684 ++curwin->w_cursor.coladd; | |
8685 } | |
8686 else | |
8687 #endif | |
8688 { | |
8689 --curwin->w_cursor.col; | |
8690 /* Correct cursor for multi-byte character. */ | |
8691 if (has_mbyte) | |
8692 mb_adjust_cursor(); | |
8693 } | |
8694 } | |
8695 | |
13380
69517d67421f
patch 8.0.1564: too many #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
13244
diff
changeset
|
8696 #ifdef HAVE_INPUT_METHOD |
7 | 8697 /* Disable IM to allow typing English directly for Normal mode commands. |
8698 * When ":lmap" is enabled don't change 'iminsert' (IM can be enabled as | |
8699 * well). */ | |
8700 if (!(State & LANGMAP)) | |
8701 im_save_status(&curbuf->b_p_iminsert); | |
8702 im_set_active(FALSE); | |
8703 #endif | |
8704 | |
8705 State = NORMAL; | |
8706 /* need to position cursor again (e.g. when on a TAB ) */ | |
8707 changed_cline_bef_curs(); | |
8708 | |
8709 #ifdef FEAT_MOUSE | |
8710 setmouse(); | |
8711 #endif | |
8712 #ifdef CURSOR_SHAPE | |
8713 ui_cursor_shape(); /* may show different cursor shape */ | |
8714 #endif | |
10684
83a36d655a74
patch 8.0.0232: paste does not work when 'esckeys' is off
Christian Brabandt <cb@256bit.org>
parents:
10682
diff
changeset
|
8715 if (!p_ek) |
83a36d655a74
patch 8.0.0232: paste does not work when 'esckeys' is off
Christian Brabandt <cb@256bit.org>
parents:
10682
diff
changeset
|
8716 /* Re-enable bracketed paste mode. */ |
83a36d655a74
patch 8.0.0232: paste does not work when 'esckeys' is off
Christian Brabandt <cb@256bit.org>
parents:
10682
diff
changeset
|
8717 out_str(T_BE); |
7 | 8718 |
8719 /* | |
8720 * When recording or for CTRL-O, need to display the new mode. | |
8721 * Otherwise remove the mode message. | |
8722 */ | |
14004
e124262d435e
patch 8.1.0020: cannot tell whether a register is executing or recording
Christian Brabandt <cb@256bit.org>
parents:
13876
diff
changeset
|
8723 if (reg_recording != 0 || restart_edit != NUL) |
7 | 8724 showmode(); |
15629
dd2e0b83a660
patch 8.1.0822: peeking and flushing output slows down execution
Bram Moolenaar <Bram@vim.org>
parents:
15595
diff
changeset
|
8725 else if (p_smd && !skip_showmode()) |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15521
diff
changeset
|
8726 msg(""); |
7 | 8727 |
8728 return TRUE; /* exit Insert mode */ | |
8729 } | |
8730 | |
8731 #ifdef FEAT_RIGHTLEFT | |
8732 /* | |
8733 * Toggle language: hkmap and revins_on. | |
8734 * Move to end of reverse inserted text. | |
8735 */ | |
8736 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
8737 ins_ctrl_(void) |
7 | 8738 { |
8739 if (revins_on && revins_chars && revins_scol >= 0) | |
8740 { | |
8741 while (gchar_cursor() != NUL && revins_chars--) | |
8742 ++curwin->w_cursor.col; | |
8743 } | |
8744 p_ri = !p_ri; | |
8745 revins_on = (State == INSERT && p_ri); | |
8746 if (revins_on) | |
8747 { | |
8748 revins_scol = curwin->w_cursor.col; | |
8749 revins_legal++; | |
8750 revins_chars = 0; | |
8751 undisplay_dollar(); | |
8752 } | |
8753 else | |
8754 revins_scol = -1; | |
8755 #ifdef FEAT_FKMAP | |
8756 if (p_altkeymap) | |
8757 { | |
8758 /* | |
8759 * to be consistent also for redo command, using '.' | |
8760 * set arrow_used to true and stop it - causing to redo | |
8761 * characters entered in one mode (normal/reverse insert). | |
8762 */ | |
8763 arrow_used = TRUE; | |
8764 (void)stop_arrow(); | |
8765 p_fkmap = curwin->w_p_rl ^ p_ri; | |
8766 if (p_fkmap && p_ri) | |
8767 State = INSERT; | |
8768 } | |
8769 else | |
8770 #endif | |
8771 p_hkmap = curwin->w_p_rl ^ p_ri; /* be consistent! */ | |
8772 showmode(); | |
8773 } | |
8774 #endif | |
8775 | |
8776 /* | |
8777 * If 'keymodel' contains "startsel", may start selection. | |
8778 * Returns TRUE when a CTRL-O and other keys stuffed. | |
8779 */ | |
8780 static int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
8781 ins_start_select(int c) |
7 | 8782 { |
8783 if (km_startsel) | |
8784 switch (c) | |
8785 { | |
8786 case K_KHOME: | |
8787 case K_KEND: | |
8788 case K_PAGEUP: | |
8789 case K_KPAGEUP: | |
8790 case K_PAGEDOWN: | |
8791 case K_KPAGEDOWN: | |
12716
351cf7c67bbe
patch 8.0.1236: Mac features are confusing
Christian Brabandt <cb@256bit.org>
parents:
12674
diff
changeset
|
8792 # ifdef MACOS_X |
7 | 8793 case K_LEFT: |
8794 case K_RIGHT: | |
8795 case K_UP: | |
8796 case K_DOWN: | |
8797 case K_END: | |
8798 case K_HOME: | |
8799 # endif | |
8800 if (!(mod_mask & MOD_MASK_SHIFT)) | |
8801 break; | |
8802 /* FALLTHROUGH */ | |
8803 case K_S_LEFT: | |
8804 case K_S_RIGHT: | |
8805 case K_S_UP: | |
8806 case K_S_DOWN: | |
8807 case K_S_END: | |
8808 case K_S_HOME: | |
8809 /* Start selection right away, the cursor can move with | |
8810 * CTRL-O when beyond the end of the line. */ | |
8811 start_selection(); | |
8812 | |
8813 /* Execute the key in (insert) Select mode. */ | |
8814 stuffcharReadbuff(Ctrl_O); | |
8815 if (mod_mask) | |
8816 { | |
8817 char_u buf[4]; | |
8818 | |
8819 buf[0] = K_SPECIAL; | |
8820 buf[1] = KS_MODIFIER; | |
8821 buf[2] = mod_mask; | |
8822 buf[3] = NUL; | |
8823 stuffReadbuff(buf); | |
8824 } | |
8825 stuffcharReadbuff(c); | |
8826 return TRUE; | |
8827 } | |
8828 return FALSE; | |
8829 } | |
8830 | |
8831 /* | |
4352 | 8832 * <Insert> key in Insert mode: toggle insert/replace mode. |
449 | 8833 */ |
8834 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
8835 ins_insert(int replaceState) |
449 | 8836 { |
8837 #ifdef FEAT_FKMAP | |
8838 if (p_fkmap && p_ri) | |
8839 { | |
8840 beep_flush(); | |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
15440
diff
changeset
|
8841 emsg(farsi_text_3); /* encoded in Farsi */ |
449 | 8842 return; |
8843 } | |
8844 #endif | |
8845 | |
532 | 8846 # ifdef FEAT_EVAL |
449 | 8847 set_vim_var_string(VV_INSERTMODE, |
14424
0a69e6e708f9
patch 8.1.0226: too many #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
14419
diff
changeset
|
8848 (char_u *)((State & REPLACE_FLAG) ? "i" |
0a69e6e708f9
patch 8.1.0226: too many #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
14419
diff
changeset
|
8849 : replaceState == VREPLACE ? "v" |
0a69e6e708f9
patch 8.1.0226: too many #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
14419
diff
changeset
|
8850 : "r"), 1); |
532 | 8851 # endif |
14485
c71d65c3672f
patch 8.1.0256: using setline() in TextChangedI splits undo
Christian Brabandt <cb@256bit.org>
parents:
14465
diff
changeset
|
8852 ins_apply_autocmds(EVENT_INSERTCHANGE); |
449 | 8853 if (State & REPLACE_FLAG) |
8854 State = INSERT | (State & LANGMAP); | |
8855 else | |
8856 State = replaceState | (State & LANGMAP); | |
8857 AppendCharToRedobuff(K_INS); | |
8858 showmode(); | |
8859 #ifdef CURSOR_SHAPE | |
8860 ui_cursor_shape(); /* may show different cursor shape */ | |
8861 #endif | |
8862 } | |
8863 | |
8864 /* | |
8865 * Pressed CTRL-O in Insert mode. | |
8866 */ | |
8867 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
8868 ins_ctrl_o(void) |
449 | 8869 { |
8870 if (State & VREPLACE_FLAG) | |
8871 restart_edit = 'V'; | |
8872 else | |
8873 if (State & REPLACE_FLAG) | |
8874 restart_edit = 'R'; | |
8875 else | |
8876 restart_edit = 'I'; | |
8877 #ifdef FEAT_VIRTUALEDIT | |
8878 if (virtual_active()) | |
8879 ins_at_eol = FALSE; /* cursor always keeps its column */ | |
8880 else | |
8881 #endif | |
8882 ins_at_eol = (gchar_cursor() == NUL); | |
8883 } | |
8884 | |
8885 /* | |
7 | 8886 * If the cursor is on an indent, ^T/^D insert/delete one |
8887 * shiftwidth. Otherwise ^T/^D behave like a "<<" or ">>". | |
1796 | 8888 * Always round the indent to 'shiftwidth', this is compatible |
7 | 8889 * with vi. But vi only supports ^T and ^D after an |
8890 * autoindent, we support it everywhere. | |
8891 */ | |
8892 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
8893 ins_shift(int c, int lastc) |
7 | 8894 { |
8895 if (stop_arrow() == FAIL) | |
8896 return; | |
8897 AppendCharToRedobuff(c); | |
8898 | |
8899 /* | |
8900 * 0^D and ^^D: remove all indent. | |
8901 */ | |
1330 | 8902 if (c == Ctrl_D && (lastc == '0' || lastc == '^') |
8903 && curwin->w_cursor.col > 0) | |
7 | 8904 { |
8905 --curwin->w_cursor.col; | |
8906 (void)del_char(FALSE); /* delete the '^' or '0' */ | |
8907 /* In Replace mode, restore the characters that '^' or '0' replaced. */ | |
8908 if (State & REPLACE_FLAG) | |
8909 replace_pop_ins(); | |
8910 if (lastc == '^') | |
8911 old_indent = get_indent(); /* remember curr. indent */ | |
1516 | 8912 change_indent(INDENT_SET, 0, TRUE, 0, TRUE); |
7 | 8913 } |
8914 else | |
1516 | 8915 change_indent(c == Ctrl_D ? INDENT_DEC : INDENT_INC, 0, TRUE, 0, TRUE); |
7 | 8916 |
8917 if (did_ai && *skipwhite(ml_get_curline()) != NUL) | |
8918 did_ai = FALSE; | |
8919 #ifdef FEAT_SMARTINDENT | |
8920 did_si = FALSE; | |
8921 can_si = FALSE; | |
8922 can_si_back = FALSE; | |
8923 #endif | |
8924 #ifdef FEAT_CINDENT | |
8925 can_cindent = FALSE; /* no cindenting after ^D or ^T */ | |
8926 #endif | |
8927 } | |
8928 | |
8929 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
8930 ins_del(void) |
7 | 8931 { |
8932 int temp; | |
8933 | |
8934 if (stop_arrow() == FAIL) | |
8935 return; | |
8936 if (gchar_cursor() == NUL) /* delete newline */ | |
8937 { | |
8938 temp = curwin->w_cursor.col; | |
8939 if (!can_bs(BS_EOL) /* only if "eol" included */ | |
5848 | 8940 || do_join(2, FALSE, TRUE, FALSE, FALSE) == FAIL) |
6949 | 8941 vim_beep(BO_BS); |
7 | 8942 else |
13402
338b15c63e2c
patch 8.0.1575: crash when using virtual replace
Christian Brabandt <cb@256bit.org>
parents:
13384
diff
changeset
|
8943 { |
7 | 8944 curwin->w_cursor.col = temp; |
13402
338b15c63e2c
patch 8.0.1575: crash when using virtual replace
Christian Brabandt <cb@256bit.org>
parents:
13384
diff
changeset
|
8945 /* Adjust orig_line_count in case more lines have been deleted than |
338b15c63e2c
patch 8.0.1575: crash when using virtual replace
Christian Brabandt <cb@256bit.org>
parents:
13384
diff
changeset
|
8946 * have been added. That makes sure, that open_line() later |
338b15c63e2c
patch 8.0.1575: crash when using virtual replace
Christian Brabandt <cb@256bit.org>
parents:
13384
diff
changeset
|
8947 * can access all buffer lines correctly */ |
338b15c63e2c
patch 8.0.1575: crash when using virtual replace
Christian Brabandt <cb@256bit.org>
parents:
13384
diff
changeset
|
8948 if (State & VREPLACE_FLAG && |
338b15c63e2c
patch 8.0.1575: crash when using virtual replace
Christian Brabandt <cb@256bit.org>
parents:
13384
diff
changeset
|
8949 orig_line_count > curbuf->b_ml.ml_line_count) |
338b15c63e2c
patch 8.0.1575: crash when using virtual replace
Christian Brabandt <cb@256bit.org>
parents:
13384
diff
changeset
|
8950 orig_line_count = curbuf->b_ml.ml_line_count; |
338b15c63e2c
patch 8.0.1575: crash when using virtual replace
Christian Brabandt <cb@256bit.org>
parents:
13384
diff
changeset
|
8951 } |
7 | 8952 } |
6949 | 8953 else if (del_char(FALSE) == FAIL) /* delete char under cursor */ |
8954 vim_beep(BO_BS); | |
7 | 8955 did_ai = FALSE; |
8956 #ifdef FEAT_SMARTINDENT | |
8957 did_si = FALSE; | |
8958 can_si = FALSE; | |
8959 can_si_back = FALSE; | |
8960 #endif | |
8961 AppendCharToRedobuff(K_DEL); | |
8962 } | |
8963 | |
1460 | 8964 /* |
8965 * Delete one character for ins_bs(). | |
8966 */ | |
8967 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
8968 ins_bs_one(colnr_T *vcolp) |
1460 | 8969 { |
8970 dec_cursor(); | |
8971 getvcol(curwin, &curwin->w_cursor, vcolp, NULL, NULL); | |
8972 if (State & REPLACE_FLAG) | |
8973 { | |
8974 /* Don't delete characters before the insert point when in | |
8975 * Replace mode */ | |
8976 if (curwin->w_cursor.lnum != Insstart.lnum | |
8977 || curwin->w_cursor.col >= Insstart.col) | |
1782 | 8978 replace_do_bs(-1); |
1460 | 8979 } |
8980 else | |
8981 (void)del_char(FALSE); | |
8982 } | |
8983 | |
7 | 8984 /* |
8985 * Handle Backspace, delete-word and delete-line in Insert mode. | |
8986 * Return TRUE when backspace was actually used. | |
8987 */ | |
8988 static int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
8989 ins_bs( |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
8990 int c, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
8991 int mode, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
8992 int *inserted_space_p) |
7 | 8993 { |
8994 linenr_T lnum; | |
8995 int cc; | |
8996 int temp = 0; /* init for GCC */ | |
1872 | 8997 colnr_T save_col; |
7 | 8998 colnr_T mincol; |
8999 int did_backspace = FALSE; | |
9000 int in_indent; | |
9001 int oldState; | |
714 | 9002 int cpc[MAX_MCO]; /* composing characters */ |
7 | 9003 |
9004 /* | |
9005 * can't delete anything in an empty file | |
9006 * can't backup past first character in buffer | |
9007 * can't backup past starting point unless 'backspace' > 1 | |
9008 * can backup to a previous line if 'backspace' == 0 | |
9009 */ | |
11121
778c10516955
patch 8.0.0448: some macros are in lower case
Christian Brabandt <cb@256bit.org>
parents:
11105
diff
changeset
|
9010 if ( BUFEMPTY() |
7 | 9011 || ( |
9012 #ifdef FEAT_RIGHTLEFT | |
9013 !revins_on && | |
9014 #endif | |
9015 ((curwin->w_cursor.lnum == 1 && curwin->w_cursor.col == 0) | |
9016 || (!can_bs(BS_START) | |
9017 && (arrow_used | |
5852 | 9018 || (curwin->w_cursor.lnum == Insstart_orig.lnum |
9019 && curwin->w_cursor.col <= Insstart_orig.col))) | |
7 | 9020 || (!can_bs(BS_INDENT) && !arrow_used && ai_col > 0 |
9021 && curwin->w_cursor.col <= ai_col) | |
9022 || (!can_bs(BS_EOL) && curwin->w_cursor.col == 0)))) | |
9023 { | |
6949 | 9024 vim_beep(BO_BS); |
7 | 9025 return FALSE; |
9026 } | |
9027 | |
9028 if (stop_arrow() == FAIL) | |
9029 return FALSE; | |
9030 in_indent = inindent(0); | |
9031 #ifdef FEAT_CINDENT | |
9032 if (in_indent) | |
9033 can_cindent = FALSE; | |
9034 #endif | |
9035 #ifdef FEAT_COMMENTS | |
9036 end_comment_pending = NUL; /* After BS, don't auto-end comment */ | |
9037 #endif | |
9038 #ifdef FEAT_RIGHTLEFT | |
9039 if (revins_on) /* put cursor after last inserted char */ | |
9040 inc_cursor(); | |
9041 #endif | |
9042 | |
9043 #ifdef FEAT_VIRTUALEDIT | |
9044 /* Virtualedit: | |
9045 * BACKSPACE_CHAR eats a virtual space | |
9046 * BACKSPACE_WORD eats all coladd | |
9047 * BACKSPACE_LINE eats all coladd and keeps going | |
9048 */ | |
9049 if (curwin->w_cursor.coladd > 0) | |
9050 { | |
9051 if (mode == BACKSPACE_CHAR) | |
9052 { | |
9053 --curwin->w_cursor.coladd; | |
9054 return TRUE; | |
9055 } | |
9056 if (mode == BACKSPACE_WORD) | |
9057 { | |
9058 curwin->w_cursor.coladd = 0; | |
9059 return TRUE; | |
9060 } | |
9061 curwin->w_cursor.coladd = 0; | |
9062 } | |
9063 #endif | |
9064 | |
9065 /* | |
11295
d772bf077b3f
patch 8.0.0533: abbreviation doesn't work after backspacing newline
Christian Brabandt <cb@256bit.org>
parents:
11289
diff
changeset
|
9066 * Delete newline! |
7 | 9067 */ |
9068 if (curwin->w_cursor.col == 0) | |
9069 { | |
6629 | 9070 lnum = Insstart.lnum; |
5852 | 9071 if (curwin->w_cursor.lnum == lnum |
7 | 9072 #ifdef FEAT_RIGHTLEFT |
9073 || revins_on | |
9074 #endif | |
9075 ) | |
9076 { | |
9077 if (u_save((linenr_T)(curwin->w_cursor.lnum - 2), | |
9078 (linenr_T)(curwin->w_cursor.lnum + 1)) == FAIL) | |
9079 return FALSE; | |
6629 | 9080 --Insstart.lnum; |
11311
be499043ca70
patch 8.0.0541: compiler warning on MS-Windows
Christian Brabandt <cb@256bit.org>
parents:
11295
diff
changeset
|
9081 Insstart.col = (colnr_T)STRLEN(ml_get(Insstart.lnum)); |
7 | 9082 } |
9083 /* | |
9084 * In replace mode: | |
9085 * cc < 0: NL was inserted, delete it | |
9086 * cc >= 0: NL was replaced, put original characters back | |
9087 */ | |
9088 cc = -1; | |
9089 if (State & REPLACE_FLAG) | |
9090 cc = replace_pop(); /* returns -1 if NL was inserted */ | |
9091 /* | |
9092 * In replace mode, in the line we started replacing, we only move the | |
9093 * cursor. | |
9094 */ | |
9095 if ((State & REPLACE_FLAG) && curwin->w_cursor.lnum <= lnum) | |
9096 { | |
9097 dec_cursor(); | |
9098 } | |
9099 else | |
9100 { | |
9101 if (!(State & VREPLACE_FLAG) | |
9102 || curwin->w_cursor.lnum > orig_line_count) | |
9103 { | |
9104 temp = gchar_cursor(); /* remember current char */ | |
9105 --curwin->w_cursor.lnum; | |
278 | 9106 |
9107 /* When "aw" is in 'formatoptions' we must delete the space at | |
9108 * the end of the line, otherwise the line will be broken | |
9109 * again when auto-formatting. */ | |
9110 if (has_format_option(FO_AUTO) | |
9111 && has_format_option(FO_WHITE_PAR)) | |
9112 { | |
9113 char_u *ptr = ml_get_buf(curbuf, curwin->w_cursor.lnum, | |
9114 TRUE); | |
9115 int len; | |
9116 | |
835 | 9117 len = (int)STRLEN(ptr); |
278 | 9118 if (len > 0 && ptr[len - 1] == ' ') |
9119 ptr[len - 1] = NUL; | |
9120 } | |
9121 | |
5848 | 9122 (void)do_join(2, FALSE, FALSE, FALSE, FALSE); |
7 | 9123 if (temp == NUL && gchar_cursor() != NUL) |
9124 inc_cursor(); | |
9125 } | |
9126 else | |
9127 dec_cursor(); | |
9128 | |
9129 /* | |
9130 * In REPLACE mode we have to put back the text that was replaced | |
9131 * by the NL. On the replace stack is first a NUL-terminated | |
9132 * sequence of characters that were deleted and then the | |
9133 * characters that NL replaced. | |
9134 */ | |
9135 if (State & REPLACE_FLAG) | |
9136 { | |
9137 /* | |
9138 * Do the next ins_char() in NORMAL state, to | |
9139 * prevent ins_char() from replacing characters and | |
9140 * avoiding showmatch(). | |
9141 */ | |
9142 oldState = State; | |
9143 State = NORMAL; | |
9144 /* | |
9145 * restore characters (blanks) deleted after cursor | |
9146 */ | |
9147 while (cc > 0) | |
9148 { | |
1872 | 9149 save_col = curwin->w_cursor.col; |
7 | 9150 mb_replace_pop_ins(cc); |
1872 | 9151 curwin->w_cursor.col = save_col; |
7 | 9152 cc = replace_pop(); |
9153 } | |
9154 /* restore the characters that NL replaced */ | |
9155 replace_pop_ins(); | |
9156 State = oldState; | |
9157 } | |
9158 } | |
9159 did_ai = FALSE; | |
9160 } | |
9161 else | |
9162 { | |
9163 /* | |
9164 * Delete character(s) before the cursor. | |
9165 */ | |
9166 #ifdef FEAT_RIGHTLEFT | |
9167 if (revins_on) /* put cursor on last inserted char */ | |
9168 dec_cursor(); | |
9169 #endif | |
9170 mincol = 0; | |
9171 /* keep indent */ | |
1085 | 9172 if (mode == BACKSPACE_LINE |
9173 && (curbuf->b_p_ai | |
9174 #ifdef FEAT_CINDENT | |
2004 | 9175 || cindent_on() |
1085 | 9176 #endif |
9177 ) | |
7 | 9178 #ifdef FEAT_RIGHTLEFT |
9179 && !revins_on | |
9180 #endif | |
9181 ) | |
9182 { | |
1872 | 9183 save_col = curwin->w_cursor.col; |
7 | 9184 beginline(BL_WHITE); |
1988 | 9185 if (curwin->w_cursor.col < save_col) |
7 | 9186 mincol = curwin->w_cursor.col; |
1872 | 9187 curwin->w_cursor.col = save_col; |
7 | 9188 } |
9189 | |
9190 /* | |
9191 * Handle deleting one 'shiftwidth' or 'softtabstop'. | |
9192 */ | |
9193 if ( mode == BACKSPACE_CHAR | |
9194 && ((p_sta && in_indent) | |
14175
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
9195 || ((get_sts_value() != 0 |
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
9196 #ifdef FEAT_VARTABS |
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
9197 || tabstop_count(curbuf->b_p_vsts_array) |
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
9198 #endif |
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
9199 ) |
1497 | 9200 && curwin->w_cursor.col > 0 |
7 | 9201 && (*(ml_get_cursor() - 1) == TAB |
9202 || (*(ml_get_cursor() - 1) == ' ' | |
9203 && (!*inserted_space_p | |
9204 || arrow_used)))))) | |
9205 { | |
9206 int ts; | |
9207 colnr_T vcol; | |
9208 colnr_T want_vcol; | |
1460 | 9209 colnr_T start_vcol; |
7 | 9210 |
9211 *inserted_space_p = FALSE; | |
9212 /* Compute the virtual column where we want to be. Since | |
9213 * 'showbreak' may get in the way, need to get the last column of | |
9214 * the previous character. */ | |
9215 getvcol(curwin, &curwin->w_cursor, &vcol, NULL, NULL); | |
1460 | 9216 start_vcol = vcol; |
7 | 9217 dec_cursor(); |
9218 getvcol(curwin, &curwin->w_cursor, NULL, NULL, &want_vcol); | |
9219 inc_cursor(); | |
14175
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
9220 #ifdef FEAT_VARTABS |
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
9221 if (p_sta && in_indent) |
14276
752ef53d3731
patch 8.1.0154: crash with "set smarttab shiftwidth=0 softtabstop=-1"
Christian Brabandt <cb@256bit.org>
parents:
14243
diff
changeset
|
9222 { |
752ef53d3731
patch 8.1.0154: crash with "set smarttab shiftwidth=0 softtabstop=-1"
Christian Brabandt <cb@256bit.org>
parents:
14243
diff
changeset
|
9223 ts = (int)get_sw_value(curbuf); |
752ef53d3731
patch 8.1.0154: crash with "set smarttab shiftwidth=0 softtabstop=-1"
Christian Brabandt <cb@256bit.org>
parents:
14243
diff
changeset
|
9224 want_vcol = (want_vcol / ts) * ts; |
752ef53d3731
patch 8.1.0154: crash with "set smarttab shiftwidth=0 softtabstop=-1"
Christian Brabandt <cb@256bit.org>
parents:
14243
diff
changeset
|
9225 } |
14175
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
9226 else |
14243
fbf0681606fa
patch 8.1.0138: negative value of 'softtabstop' not used correctly
Christian Brabandt <cb@256bit.org>
parents:
14175
diff
changeset
|
9227 want_vcol = tabstop_start(want_vcol, get_sts_value(), |
14175
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
9228 curbuf->b_p_vsts_array); |
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
9229 #else |
14276
752ef53d3731
patch 8.1.0154: crash with "set smarttab shiftwidth=0 softtabstop=-1"
Christian Brabandt <cb@256bit.org>
parents:
14243
diff
changeset
|
9230 if (p_sta && in_indent) |
752ef53d3731
patch 8.1.0154: crash with "set smarttab shiftwidth=0 softtabstop=-1"
Christian Brabandt <cb@256bit.org>
parents:
14243
diff
changeset
|
9231 ts = (int)get_sw_value(curbuf); |
752ef53d3731
patch 8.1.0154: crash with "set smarttab shiftwidth=0 softtabstop=-1"
Christian Brabandt <cb@256bit.org>
parents:
14243
diff
changeset
|
9232 else |
752ef53d3731
patch 8.1.0154: crash with "set smarttab shiftwidth=0 softtabstop=-1"
Christian Brabandt <cb@256bit.org>
parents:
14243
diff
changeset
|
9233 ts = (int)get_sts_value(); |
7 | 9234 want_vcol = (want_vcol / ts) * ts; |
14175
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
9235 #endif |
7 | 9236 |
9237 /* delete characters until we are at or before want_vcol */ | |
9238 while (vcol > want_vcol | |
11129
f4ea50924c6d
patch 8.0.0452: some macros are in lower case
Christian Brabandt <cb@256bit.org>
parents:
11127
diff
changeset
|
9239 && (cc = *(ml_get_cursor() - 1), VIM_ISWHITE(cc))) |
1460 | 9240 ins_bs_one(&vcol); |
7 | 9241 |
9242 /* insert extra spaces until we are at want_vcol */ | |
9243 while (vcol < want_vcol) | |
9244 { | |
9245 /* Remember the first char we inserted */ | |
5852 | 9246 if (curwin->w_cursor.lnum == Insstart_orig.lnum |
9247 && curwin->w_cursor.col < Insstart_orig.col) | |
9248 Insstart_orig.col = curwin->w_cursor.col; | |
7 | 9249 |
9250 if (State & VREPLACE_FLAG) | |
9251 ins_char(' '); | |
9252 else | |
9253 { | |
9254 ins_str((char_u *)" "); | |
1460 | 9255 if ((State & REPLACE_FLAG)) |
9256 replace_push(NUL); | |
7 | 9257 } |
9258 getvcol(curwin, &curwin->w_cursor, &vcol, NULL, NULL); | |
9259 } | |
1460 | 9260 |
9261 /* If we are now back where we started delete one character. Can | |
9262 * happen when using 'sts' and 'linebreak'. */ | |
9263 if (vcol >= start_vcol) | |
9264 ins_bs_one(&vcol); | |
7 | 9265 } |
9266 | |
9267 /* | |
9268 * Delete upto starting point, start of line or previous word. | |
9269 */ | |
6712 | 9270 else |
9271 { | |
9272 int cclass = 0, prev_cclass = 0; | |
9273 | |
9274 if (has_mbyte) | |
9275 cclass = mb_get_class(ml_get_cursor()); | |
9276 do | |
7 | 9277 { |
9278 #ifdef FEAT_RIGHTLEFT | |
6712 | 9279 if (!revins_on) /* put cursor on char to be deleted */ |
9280 #endif | |
7 | 9281 dec_cursor(); |
6712 | 9282 |
9283 cc = gchar_cursor(); | |
9284 /* look multi-byte character class */ | |
9285 if (has_mbyte) | |
9286 { | |
9287 prev_cclass = cclass; | |
9288 cclass = mb_get_class(ml_get_cursor()); | |
9289 } | |
9290 | |
9291 /* start of word? */ | |
9292 if (mode == BACKSPACE_WORD && !vim_isspace(cc)) | |
9293 { | |
9294 mode = BACKSPACE_WORD_NOT_SPACE; | |
9295 temp = vim_iswordc(cc); | |
9296 } | |
9297 /* end of word? */ | |
9298 else if (mode == BACKSPACE_WORD_NOT_SPACE | |
9299 && ((vim_isspace(cc) || vim_iswordc(cc) != temp) | |
15595
1ec942f1b648
patch 8.1.0805: too many #ifdefs
Bram Moolenaar <Bram@vim.org>
parents:
15569
diff
changeset
|
9300 || prev_cclass != cclass)) |
6712 | 9301 { |
9302 #ifdef FEAT_RIGHTLEFT | |
9303 if (!revins_on) | |
9304 #endif | |
9305 inc_cursor(); | |
9306 #ifdef FEAT_RIGHTLEFT | |
9307 else if (State & REPLACE_FLAG) | |
9308 dec_cursor(); | |
9309 #endif | |
9310 break; | |
9311 } | |
9312 if (State & REPLACE_FLAG) | |
9313 replace_do_bs(-1); | |
9314 else | |
9315 { | |
9316 if (enc_utf8 && p_deco) | |
9317 (void)utfc_ptr2char(ml_get_cursor(), cpc); | |
9318 (void)del_char(FALSE); | |
9319 /* | |
9320 * If there are combining characters and 'delcombine' is set | |
9321 * move the cursor back. Don't back up before the base | |
9322 * character. | |
9323 */ | |
9324 if (enc_utf8 && p_deco && cpc[0] != NUL) | |
9325 inc_cursor(); | |
7 | 9326 #ifdef FEAT_RIGHTLEFT |
6712 | 9327 if (revins_chars) |
9328 { | |
9329 revins_chars--; | |
9330 revins_legal++; | |
9331 } | |
9332 if (revins_on && gchar_cursor() == NUL) | |
9333 break; | |
9334 #endif | |
7 | 9335 } |
6712 | 9336 /* Just a single backspace?: */ |
9337 if (mode == BACKSPACE_CHAR) | |
7 | 9338 break; |
6712 | 9339 } while ( |
7 | 9340 #ifdef FEAT_RIGHTLEFT |
6712 | 9341 revins_on || |
9342 #endif | |
9343 (curwin->w_cursor.col > mincol | |
9344 && (curwin->w_cursor.lnum != Insstart_orig.lnum | |
9345 || curwin->w_cursor.col != Insstart_orig.col))); | |
9346 } | |
7 | 9347 did_backspace = TRUE; |
9348 } | |
9349 #ifdef FEAT_SMARTINDENT | |
9350 did_si = FALSE; | |
9351 can_si = FALSE; | |
9352 can_si_back = FALSE; | |
9353 #endif | |
9354 if (curwin->w_cursor.col <= 1) | |
9355 did_ai = FALSE; | |
9356 /* | |
9357 * It's a little strange to put backspaces into the redo | |
9358 * buffer, but it makes auto-indent a lot easier to deal | |
9359 * with. | |
9360 */ | |
9361 AppendCharToRedobuff(c); | |
9362 | |
9363 /* If deleted before the insertion point, adjust it */ | |
5852 | 9364 if (curwin->w_cursor.lnum == Insstart_orig.lnum |
14037
afce2005fdc8
patch 8.1.0036: not restoring Insert mode if leaving prompt buffer with mouse
Christian Brabandt <cb@256bit.org>
parents:
14035
diff
changeset
|
9365 && curwin->w_cursor.col < Insstart_orig.col) |
5852 | 9366 Insstart_orig.col = curwin->w_cursor.col; |
7 | 9367 |
9368 /* vi behaviour: the cursor moves backward but the character that | |
9369 * was there remains visible | |
9370 * Vim behaviour: the cursor moves backward and the character that | |
9371 * was there is erased from the screen. | |
9372 * We can emulate the vi behaviour by pretending there is a dollar | |
9373 * displayed even when there isn't. | |
9374 * --pkv Sun Jan 19 01:56:40 EST 2003 */ | |
3318 | 9375 if (vim_strchr(p_cpo, CPO_BACKSPACE) != NULL && dollar_vcol == -1) |
7 | 9376 dollar_vcol = curwin->w_virtcol; |
9377 | |
1514 | 9378 #ifdef FEAT_FOLDING |
9379 /* When deleting a char the cursor line must never be in a closed fold. | |
9380 * E.g., when 'foldmethod' is indent and deleting the first non-white | |
9381 * char before a Tab. */ | |
9382 if (did_backspace) | |
9383 foldOpenCursor(); | |
9384 #endif | |
9385 | |
7 | 9386 return did_backspace; |
9387 } | |
9388 | |
9389 #ifdef FEAT_MOUSE | |
9390 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
9391 ins_mouse(int c) |
7 | 9392 { |
9393 pos_T tpos; | |
840 | 9394 win_T *old_curwin = curwin; |
7 | 9395 |
9396 # ifdef FEAT_GUI | |
9397 /* When GUI is active, also move/paste when 'mouse' is empty */ | |
9398 if (!gui.in_use) | |
9399 # endif | |
9400 if (!mouse_has(MOUSE_INSERT)) | |
9401 return; | |
9402 | |
9403 undisplay_dollar(); | |
9404 tpos = curwin->w_cursor; | |
9405 if (do_mouse(NULL, c, BACKWARD, 1L, 0)) | |
9406 { | |
840 | 9407 win_T *new_curwin = curwin; |
9408 | |
9409 if (curwin != old_curwin && win_valid(old_curwin)) | |
9410 { | |
9411 /* Mouse took us to another window. We need to go back to the | |
9412 * previous one to stop insert there properly. */ | |
9413 curwin = old_curwin; | |
9414 curbuf = curwin->w_buffer; | |
14037
afce2005fdc8
patch 8.1.0036: not restoring Insert mode if leaving prompt buffer with mouse
Christian Brabandt <cb@256bit.org>
parents:
14035
diff
changeset
|
9415 #ifdef FEAT_JOB_CHANNEL |
afce2005fdc8
patch 8.1.0036: not restoring Insert mode if leaving prompt buffer with mouse
Christian Brabandt <cb@256bit.org>
parents:
14035
diff
changeset
|
9416 if (bt_prompt(curbuf)) |
afce2005fdc8
patch 8.1.0036: not restoring Insert mode if leaving prompt buffer with mouse
Christian Brabandt <cb@256bit.org>
parents:
14035
diff
changeset
|
9417 // Restart Insert mode when re-entering the prompt buffer. |
afce2005fdc8
patch 8.1.0036: not restoring Insert mode if leaving prompt buffer with mouse
Christian Brabandt <cb@256bit.org>
parents:
14035
diff
changeset
|
9418 curbuf->b_prompt_insert = 'A'; |
afce2005fdc8
patch 8.1.0036: not restoring Insert mode if leaving prompt buffer with mouse
Christian Brabandt <cb@256bit.org>
parents:
14035
diff
changeset
|
9419 #endif |
840 | 9420 } |
9421 start_arrow(curwin == old_curwin ? &tpos : NULL); | |
9422 if (curwin != new_curwin && win_valid(new_curwin)) | |
9423 { | |
9424 curwin = new_curwin; | |
9425 curbuf = curwin->w_buffer; | |
9426 } | |
7 | 9427 # ifdef FEAT_CINDENT |
9428 can_cindent = TRUE; | |
9429 # endif | |
9430 } | |
9431 | |
9432 /* redraw status lines (in case another window became active) */ | |
9433 redraw_statuslines(); | |
9434 } | |
9435 | |
9436 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
9437 ins_mousescroll(int dir) |
7 | 9438 { |
9439 pos_T tpos; | |
12136
60cf03e59402
patch 8.0.0948: crash if timer closes window while dragging status line
Christian Brabandt <cb@256bit.org>
parents:
11617
diff
changeset
|
9440 win_T *old_curwin = curwin, *wp; |
1434 | 9441 # ifdef FEAT_INS_EXPAND |
9442 int did_scroll = FALSE; | |
7 | 9443 # endif |
9444 | |
9445 tpos = curwin->w_cursor; | |
9446 | |
4162 | 9447 if (mouse_row >= 0 && mouse_col >= 0) |
7 | 9448 { |
9449 int row, col; | |
9450 | |
9451 row = mouse_row; | |
9452 col = mouse_col; | |
9453 | |
9454 /* find the window at the pointer coordinates */ | |
12136
60cf03e59402
patch 8.0.0948: crash if timer closes window while dragging status line
Christian Brabandt <cb@256bit.org>
parents:
11617
diff
changeset
|
9455 wp = mouse_find_win(&row, &col); |
60cf03e59402
patch 8.0.0948: crash if timer closes window while dragging status line
Christian Brabandt <cb@256bit.org>
parents:
11617
diff
changeset
|
9456 if (wp == NULL) |
60cf03e59402
patch 8.0.0948: crash if timer closes window while dragging status line
Christian Brabandt <cb@256bit.org>
parents:
11617
diff
changeset
|
9457 return; |
60cf03e59402
patch 8.0.0948: crash if timer closes window while dragging status line
Christian Brabandt <cb@256bit.org>
parents:
11617
diff
changeset
|
9458 curwin = wp; |
7 | 9459 curbuf = curwin->w_buffer; |
9460 } | |
9461 if (curwin == old_curwin) | |
9462 undisplay_dollar(); | |
9463 | |
1434 | 9464 # ifdef FEAT_INS_EXPAND |
9465 /* Don't scroll the window in which completion is being done. */ | |
12477
68d7bc045dbe
patch 8.0.1118: FEAT_WINDOWS adds a lot of #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
12323
diff
changeset
|
9466 if (!pum_visible() || curwin != old_curwin) |
1434 | 9467 # endif |
9468 { | |
2409
0ca06a92adfb
Add support for horizontal scroll wheel. (Bjorn Winckler)
Bram Moolenaar <bram@vim.org>
parents:
2378
diff
changeset
|
9469 if (dir == MSCR_DOWN || dir == MSCR_UP) |
0ca06a92adfb
Add support for horizontal scroll wheel. (Bjorn Winckler)
Bram Moolenaar <bram@vim.org>
parents:
2378
diff
changeset
|
9470 { |
0ca06a92adfb
Add support for horizontal scroll wheel. (Bjorn Winckler)
Bram Moolenaar <bram@vim.org>
parents:
2378
diff
changeset
|
9471 if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) |
0ca06a92adfb
Add support for horizontal scroll wheel. (Bjorn Winckler)
Bram Moolenaar <bram@vim.org>
parents:
2378
diff
changeset
|
9472 scroll_redraw(dir, |
0ca06a92adfb
Add support for horizontal scroll wheel. (Bjorn Winckler)
Bram Moolenaar <bram@vim.org>
parents:
2378
diff
changeset
|
9473 (long)(curwin->w_botline - curwin->w_topline)); |
0ca06a92adfb
Add support for horizontal scroll wheel. (Bjorn Winckler)
Bram Moolenaar <bram@vim.org>
parents:
2378
diff
changeset
|
9474 else |
0ca06a92adfb
Add support for horizontal scroll wheel. (Bjorn Winckler)
Bram Moolenaar <bram@vim.org>
parents:
2378
diff
changeset
|
9475 scroll_redraw(dir, 3L); |
0ca06a92adfb
Add support for horizontal scroll wheel. (Bjorn Winckler)
Bram Moolenaar <bram@vim.org>
parents:
2378
diff
changeset
|
9476 } |
0ca06a92adfb
Add support for horizontal scroll wheel. (Bjorn Winckler)
Bram Moolenaar <bram@vim.org>
parents:
2378
diff
changeset
|
9477 #ifdef FEAT_GUI |
1434 | 9478 else |
2409
0ca06a92adfb
Add support for horizontal scroll wheel. (Bjorn Winckler)
Bram Moolenaar <bram@vim.org>
parents:
2378
diff
changeset
|
9479 { |
0ca06a92adfb
Add support for horizontal scroll wheel. (Bjorn Winckler)
Bram Moolenaar <bram@vim.org>
parents:
2378
diff
changeset
|
9480 int val, step = 6; |
0ca06a92adfb
Add support for horizontal scroll wheel. (Bjorn Winckler)
Bram Moolenaar <bram@vim.org>
parents:
2378
diff
changeset
|
9481 |
0ca06a92adfb
Add support for horizontal scroll wheel. (Bjorn Winckler)
Bram Moolenaar <bram@vim.org>
parents:
2378
diff
changeset
|
9482 if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) |
12515
972ea22c946f
patch 8.0.1136: W_WIDTH() is always the same
Christian Brabandt <cb@256bit.org>
parents:
12513
diff
changeset
|
9483 step = curwin->w_width; |
2409
0ca06a92adfb
Add support for horizontal scroll wheel. (Bjorn Winckler)
Bram Moolenaar <bram@vim.org>
parents:
2378
diff
changeset
|
9484 val = curwin->w_leftcol + (dir == MSCR_RIGHT ? -step : step); |
0ca06a92adfb
Add support for horizontal scroll wheel. (Bjorn Winckler)
Bram Moolenaar <bram@vim.org>
parents:
2378
diff
changeset
|
9485 if (val < 0) |
0ca06a92adfb
Add support for horizontal scroll wheel. (Bjorn Winckler)
Bram Moolenaar <bram@vim.org>
parents:
2378
diff
changeset
|
9486 val = 0; |
0ca06a92adfb
Add support for horizontal scroll wheel. (Bjorn Winckler)
Bram Moolenaar <bram@vim.org>
parents:
2378
diff
changeset
|
9487 gui_do_horiz_scroll(val, TRUE); |
0ca06a92adfb
Add support for horizontal scroll wheel. (Bjorn Winckler)
Bram Moolenaar <bram@vim.org>
parents:
2378
diff
changeset
|
9488 } |
0ca06a92adfb
Add support for horizontal scroll wheel. (Bjorn Winckler)
Bram Moolenaar <bram@vim.org>
parents:
2378
diff
changeset
|
9489 #endif |
1434 | 9490 # ifdef FEAT_INS_EXPAND |
9491 did_scroll = TRUE; | |
9492 # endif | |
9493 } | |
7 | 9494 |
9495 curwin->w_redr_status = TRUE; | |
9496 | |
9497 curwin = old_curwin; | |
9498 curbuf = curwin->w_buffer; | |
9499 | |
1434 | 9500 # ifdef FEAT_INS_EXPAND |
9501 /* The popup menu may overlay the window, need to redraw it. | |
9502 * TODO: Would be more efficient to only redraw the windows that are | |
9503 * overlapped by the popup menu. */ | |
9504 if (pum_visible() && did_scroll) | |
9505 { | |
9506 redraw_all_later(NOT_VALID); | |
9507 ins_compl_show_pum(); | |
9508 } | |
9509 # endif | |
9510 | |
11121
778c10516955
patch 8.0.0448: some macros are in lower case
Christian Brabandt <cb@256bit.org>
parents:
11105
diff
changeset
|
9511 if (!EQUAL_POS(curwin->w_cursor, tpos)) |
7 | 9512 { |
9513 start_arrow(&tpos); | |
9514 # ifdef FEAT_CINDENT | |
9515 can_cindent = TRUE; | |
9516 # endif | |
9517 } | |
9518 } | |
9519 #endif | |
9520 | |
10640
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9521 /* |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9522 * Handle receiving P_PS: start paste mode. Inserts the following text up to |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9523 * P_PE literally. |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9524 * When "drop" is TRUE then consume the text and drop it. |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9525 */ |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9526 int |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9527 bracketed_paste(paste_mode_T mode, int drop, garray_T *gap) |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9528 { |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9529 int c; |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9530 char_u buf[NUMBUFLEN + MB_MAXBYTES]; |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9531 int idx = 0; |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9532 char_u *end = find_termcode((char_u *)"PE"); |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9533 int ret_char = -1; |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9534 int save_allow_keys = allow_keys; |
10696
689e88afdd11
patch 8.0.0238: bracketed paste does not disable autoindent
Christian Brabandt <cb@256bit.org>
parents:
10684
diff
changeset
|
9535 int save_paste = p_paste; |
10640
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9536 |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9537 /* If the end code is too long we can't detect it, read everything. */ |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9538 if (STRLEN(end) >= NUMBUFLEN) |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9539 end = NULL; |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9540 ++no_mapping; |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9541 allow_keys = 0; |
14419
cdc4eacdd81d
patch 8.1.0224: hang in bracketed paste mode when t_PE not encountered
Christian Brabandt <cb@256bit.org>
parents:
14301
diff
changeset
|
9542 if (!p_paste) |
cdc4eacdd81d
patch 8.1.0224: hang in bracketed paste mode when t_PE not encountered
Christian Brabandt <cb@256bit.org>
parents:
14301
diff
changeset
|
9543 // Also have the side effects of setting 'paste' to make it work much |
cdc4eacdd81d
patch 8.1.0224: hang in bracketed paste mode when t_PE not encountered
Christian Brabandt <cb@256bit.org>
parents:
14301
diff
changeset
|
9544 // faster. |
cdc4eacdd81d
patch 8.1.0224: hang in bracketed paste mode when t_PE not encountered
Christian Brabandt <cb@256bit.org>
parents:
14301
diff
changeset
|
9545 set_option_value((char_u *)"paste", TRUE, NULL, 0); |
10696
689e88afdd11
patch 8.0.0238: bracketed paste does not disable autoindent
Christian Brabandt <cb@256bit.org>
parents:
10684
diff
changeset
|
9546 |
10640
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9547 for (;;) |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9548 { |
14419
cdc4eacdd81d
patch 8.1.0224: hang in bracketed paste mode when t_PE not encountered
Christian Brabandt <cb@256bit.org>
parents:
14301
diff
changeset
|
9549 // When the end is not defined read everything there is. |
10640
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9550 if (end == NULL && vpeekc() == NUL) |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9551 break; |
14419
cdc4eacdd81d
patch 8.1.0224: hang in bracketed paste mode when t_PE not encountered
Christian Brabandt <cb@256bit.org>
parents:
14301
diff
changeset
|
9552 do |
cdc4eacdd81d
patch 8.1.0224: hang in bracketed paste mode when t_PE not encountered
Christian Brabandt <cb@256bit.org>
parents:
14301
diff
changeset
|
9553 { |
cdc4eacdd81d
patch 8.1.0224: hang in bracketed paste mode when t_PE not encountered
Christian Brabandt <cb@256bit.org>
parents:
14301
diff
changeset
|
9554 c = vgetc(); |
cdc4eacdd81d
patch 8.1.0224: hang in bracketed paste mode when t_PE not encountered
Christian Brabandt <cb@256bit.org>
parents:
14301
diff
changeset
|
9555 } while (c == K_IGNORE || c == K_VER_SCROLLBAR || c == K_HOR_SCROLLBAR); |
cdc4eacdd81d
patch 8.1.0224: hang in bracketed paste mode when t_PE not encountered
Christian Brabandt <cb@256bit.org>
parents:
14301
diff
changeset
|
9556 if (c == NUL || got_int) |
cdc4eacdd81d
patch 8.1.0224: hang in bracketed paste mode when t_PE not encountered
Christian Brabandt <cb@256bit.org>
parents:
14301
diff
changeset
|
9557 // When CTRL-C was encountered the typeahead will be flushed and we |
cdc4eacdd81d
patch 8.1.0224: hang in bracketed paste mode when t_PE not encountered
Christian Brabandt <cb@256bit.org>
parents:
14301
diff
changeset
|
9558 // won't get the end sequence. |
cdc4eacdd81d
patch 8.1.0224: hang in bracketed paste mode when t_PE not encountered
Christian Brabandt <cb@256bit.org>
parents:
14301
diff
changeset
|
9559 break; |
cdc4eacdd81d
patch 8.1.0224: hang in bracketed paste mode when t_PE not encountered
Christian Brabandt <cb@256bit.org>
parents:
14301
diff
changeset
|
9560 |
10640
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9561 if (has_mbyte) |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9562 idx += (*mb_char2bytes)(c, buf + idx); |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9563 else |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9564 buf[idx++] = c; |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9565 buf[idx] = NUL; |
11317
e45c6e4d78af
patch 8.0.0544: cppcheck warnings
Christian Brabandt <cb@256bit.org>
parents:
11311
diff
changeset
|
9566 if (end != NULL && STRNCMP(buf, end, idx) == 0) |
10640
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9567 { |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9568 if (end[idx] == NUL) |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9569 break; /* Found the end of paste code. */ |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9570 continue; |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9571 } |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9572 if (!drop) |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9573 { |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9574 switch (mode) |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9575 { |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9576 case PASTE_CMDLINE: |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9577 put_on_cmdline(buf, idx, TRUE); |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9578 break; |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9579 |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9580 case PASTE_EX: |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9581 if (gap != NULL && ga_grow(gap, idx) == OK) |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9582 { |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9583 mch_memmove((char *)gap->ga_data + gap->ga_len, |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9584 buf, (size_t)idx); |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9585 gap->ga_len += idx; |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9586 } |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9587 break; |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9588 |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9589 case PASTE_INSERT: |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9590 if (stop_arrow() == OK) |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9591 { |
10680
75c324ab1270
patch 8.0.0230: bracketed paste does not support line breaks
Christian Brabandt <cb@256bit.org>
parents:
10640
diff
changeset
|
9592 c = buf[0]; |
75c324ab1270
patch 8.0.0230: bracketed paste does not support line breaks
Christian Brabandt <cb@256bit.org>
parents:
10640
diff
changeset
|
9593 if (idx == 1 && (c == CAR || c == K_KENTER || c == NL)) |
75c324ab1270
patch 8.0.0230: bracketed paste does not support line breaks
Christian Brabandt <cb@256bit.org>
parents:
10640
diff
changeset
|
9594 ins_eol(c); |
75c324ab1270
patch 8.0.0230: bracketed paste does not support line breaks
Christian Brabandt <cb@256bit.org>
parents:
10640
diff
changeset
|
9595 else |
10682
d564e73ff9ee
patch 8.0.0231: bracketed paste mode is not tested
Christian Brabandt <cb@256bit.org>
parents:
10680
diff
changeset
|
9596 { |
10680
75c324ab1270
patch 8.0.0230: bracketed paste does not support line breaks
Christian Brabandt <cb@256bit.org>
parents:
10640
diff
changeset
|
9597 ins_char_bytes(buf, idx); |
10682
d564e73ff9ee
patch 8.0.0231: bracketed paste mode is not tested
Christian Brabandt <cb@256bit.org>
parents:
10680
diff
changeset
|
9598 AppendToRedobuffLit(buf, idx); |
d564e73ff9ee
patch 8.0.0231: bracketed paste mode is not tested
Christian Brabandt <cb@256bit.org>
parents:
10680
diff
changeset
|
9599 } |
10640
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9600 } |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9601 break; |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9602 |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9603 case PASTE_ONE_CHAR: |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9604 if (ret_char == -1) |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9605 { |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9606 if (has_mbyte) |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9607 ret_char = (*mb_ptr2char)(buf); |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9608 else |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9609 ret_char = buf[0]; |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9610 } |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9611 break; |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9612 } |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9613 } |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9614 idx = 0; |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9615 } |
10696
689e88afdd11
patch 8.0.0238: bracketed paste does not disable autoindent
Christian Brabandt <cb@256bit.org>
parents:
10684
diff
changeset
|
9616 |
10640
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9617 --no_mapping; |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9618 allow_keys = save_allow_keys; |
14419
cdc4eacdd81d
patch 8.1.0224: hang in bracketed paste mode when t_PE not encountered
Christian Brabandt <cb@256bit.org>
parents:
14301
diff
changeset
|
9619 if (!save_paste) |
cdc4eacdd81d
patch 8.1.0224: hang in bracketed paste mode when t_PE not encountered
Christian Brabandt <cb@256bit.org>
parents:
14301
diff
changeset
|
9620 set_option_value((char_u *)"paste", FALSE, NULL, 0); |
10640
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9621 |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9622 return ret_char; |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9623 } |
27be410d6d29
patch 8.0.0210: no support for bracketed paste
Christian Brabandt <cb@256bit.org>
parents:
10636
diff
changeset
|
9624 |
692 | 9625 #if defined(FEAT_GUI_TABLINE) || defined(PROTO) |
724 | 9626 static void |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
9627 ins_tabline(int c) |
692 | 9628 { |
9629 /* We will be leaving the current window, unless closing another tab. */ | |
9630 if (c != K_TABMENU || current_tabmenu != TABLINE_MENU_CLOSE | |
9631 || (current_tab != 0 && current_tab != tabpage_index(curtab))) | |
9632 { | |
9633 undisplay_dollar(); | |
9634 start_arrow(&curwin->w_cursor); | |
9635 # ifdef FEAT_CINDENT | |
9636 can_cindent = TRUE; | |
9637 # endif | |
9638 } | |
9639 | |
9640 if (c == K_TABLINE) | |
9641 goto_tabpage(current_tab); | |
9642 else | |
846 | 9643 { |
692 | 9644 handle_tabmenu(); |
846 | 9645 redraw_statuslines(); /* will redraw the tabline when needed */ |
9646 } | |
692 | 9647 } |
9648 #endif | |
9649 | |
9650 #if defined(FEAT_GUI) || defined(PROTO) | |
7 | 9651 void |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
9652 ins_scroll(void) |
7 | 9653 { |
9654 pos_T tpos; | |
9655 | |
9656 undisplay_dollar(); | |
9657 tpos = curwin->w_cursor; | |
9658 if (gui_do_scroll()) | |
9659 { | |
9660 start_arrow(&tpos); | |
9661 # ifdef FEAT_CINDENT | |
9662 can_cindent = TRUE; | |
9663 # endif | |
9664 } | |
9665 } | |
9666 | |
9667 void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
9668 ins_horscroll(void) |
7 | 9669 { |
9670 pos_T tpos; | |
9671 | |
9672 undisplay_dollar(); | |
9673 tpos = curwin->w_cursor; | |
2409
0ca06a92adfb
Add support for horizontal scroll wheel. (Bjorn Winckler)
Bram Moolenaar <bram@vim.org>
parents:
2378
diff
changeset
|
9674 if (gui_do_horiz_scroll(scrollbar_value, FALSE)) |
7 | 9675 { |
9676 start_arrow(&tpos); | |
9677 # ifdef FEAT_CINDENT | |
9678 can_cindent = TRUE; | |
9679 # endif | |
9680 } | |
9681 } | |
9682 #endif | |
9683 | |
9684 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
9685 ins_left( |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
9686 int end_change) /* end undoable change */ |
7 | 9687 { |
9688 pos_T tpos; | |
9689 | |
9690 #ifdef FEAT_FOLDING | |
9691 if ((fdo_flags & FDO_HOR) && KeyTyped) | |
9692 foldOpenCursor(); | |
9693 #endif | |
9694 undisplay_dollar(); | |
9695 tpos = curwin->w_cursor; | |
9696 if (oneleft() == OK) | |
9697 { | |
941 | 9698 #if defined(FEAT_XIM) && defined(FEAT_GUI_GTK) |
9699 /* Only call start_arrow() when not busy with preediting, it will | |
9700 * break undo. K_LEFT is inserted in im_correct_cursor(). */ | |
12293
1ff5e5dfa9b0
patch 8.0.1026: GTK on-the-spot input has problems
Christian Brabandt <cb@256bit.org>
parents:
12136
diff
changeset
|
9701 if (p_imst == IM_OVER_THE_SPOT || !im_is_preediting()) |
941 | 9702 #endif |
7074
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
9703 { |
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
9704 start_arrow_with_change(&tpos, end_change); |
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
9705 if (!end_change) |
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
9706 AppendCharToRedobuff(K_LEFT); |
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
9707 } |
7 | 9708 #ifdef FEAT_RIGHTLEFT |
9709 /* If exit reversed string, position is fixed */ | |
9710 if (revins_scol != -1 && (int)curwin->w_cursor.col >= revins_scol) | |
9711 revins_legal++; | |
9712 revins_chars++; | |
9713 #endif | |
9714 } | |
9715 | |
9716 /* | |
9717 * if 'whichwrap' set for cursor in insert mode may go to | |
9718 * previous line | |
9719 */ | |
9720 else if (vim_strchr(p_ww, '[') != NULL && curwin->w_cursor.lnum > 1) | |
9721 { | |
7074
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
9722 /* always break undo when moving upwards/downwards, else undo may break */ |
7 | 9723 start_arrow(&tpos); |
9724 --(curwin->w_cursor.lnum); | |
9725 coladvance((colnr_T)MAXCOL); | |
9726 curwin->w_set_curswant = TRUE; /* so we stay at the end */ | |
9727 } | |
9728 else | |
6949 | 9729 vim_beep(BO_CRSR); |
7074
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
9730 dont_sync_undo = FALSE; |
7 | 9731 } |
9732 | |
9733 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
9734 ins_home(int c) |
7 | 9735 { |
9736 pos_T tpos; | |
9737 | |
9738 #ifdef FEAT_FOLDING | |
9739 if ((fdo_flags & FDO_HOR) && KeyTyped) | |
9740 foldOpenCursor(); | |
9741 #endif | |
9742 undisplay_dollar(); | |
9743 tpos = curwin->w_cursor; | |
9744 if (c == K_C_HOME) | |
9745 curwin->w_cursor.lnum = 1; | |
9746 curwin->w_cursor.col = 0; | |
9747 #ifdef FEAT_VIRTUALEDIT | |
9748 curwin->w_cursor.coladd = 0; | |
9749 #endif | |
9750 curwin->w_curswant = 0; | |
9751 start_arrow(&tpos); | |
9752 } | |
9753 | |
9754 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
9755 ins_end(int c) |
7 | 9756 { |
9757 pos_T tpos; | |
9758 | |
9759 #ifdef FEAT_FOLDING | |
9760 if ((fdo_flags & FDO_HOR) && KeyTyped) | |
9761 foldOpenCursor(); | |
9762 #endif | |
9763 undisplay_dollar(); | |
9764 tpos = curwin->w_cursor; | |
9765 if (c == K_C_END) | |
9766 curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count; | |
9767 coladvance((colnr_T)MAXCOL); | |
9768 curwin->w_curswant = MAXCOL; | |
9769 | |
9770 start_arrow(&tpos); | |
9771 } | |
9772 | |
9773 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
9774 ins_s_left(void) |
7 | 9775 { |
9776 #ifdef FEAT_FOLDING | |
9777 if ((fdo_flags & FDO_HOR) && KeyTyped) | |
9778 foldOpenCursor(); | |
9779 #endif | |
9780 undisplay_dollar(); | |
9781 if (curwin->w_cursor.lnum > 1 || curwin->w_cursor.col > 0) | |
9782 { | |
9783 start_arrow(&curwin->w_cursor); | |
9784 (void)bck_word(1L, FALSE, FALSE); | |
9785 curwin->w_set_curswant = TRUE; | |
9786 } | |
9787 else | |
6949 | 9788 vim_beep(BO_CRSR); |
7 | 9789 } |
9790 | |
9791 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
9792 ins_right( |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
9793 int end_change) /* end undoable change */ |
7 | 9794 { |
9795 #ifdef FEAT_FOLDING | |
9796 if ((fdo_flags & FDO_HOR) && KeyTyped) | |
9797 foldOpenCursor(); | |
9798 #endif | |
9799 undisplay_dollar(); | |
1877 | 9800 if (gchar_cursor() != NUL |
9801 #ifdef FEAT_VIRTUALEDIT | |
9802 || virtual_active() | |
9803 #endif | |
7 | 9804 ) |
9805 { | |
7074
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
9806 start_arrow_with_change(&curwin->w_cursor, end_change); |
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
9807 if (!end_change) |
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
9808 AppendCharToRedobuff(K_RIGHT); |
7 | 9809 curwin->w_set_curswant = TRUE; |
9810 #ifdef FEAT_VIRTUALEDIT | |
9811 if (virtual_active()) | |
9812 oneright(); | |
9813 else | |
9814 #endif | |
9815 { | |
9816 if (has_mbyte) | |
474 | 9817 curwin->w_cursor.col += (*mb_ptr2len)(ml_get_cursor()); |
7 | 9818 else |
9819 ++curwin->w_cursor.col; | |
9820 } | |
9821 | |
9822 #ifdef FEAT_RIGHTLEFT | |
9823 revins_legal++; | |
9824 if (revins_chars) | |
9825 revins_chars--; | |
9826 #endif | |
9827 } | |
9828 /* if 'whichwrap' set for cursor in insert mode, may move the | |
9829 * cursor to the next line */ | |
9830 else if (vim_strchr(p_ww, ']') != NULL | |
9831 && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) | |
9832 { | |
9833 start_arrow(&curwin->w_cursor); | |
9834 curwin->w_set_curswant = TRUE; | |
9835 ++curwin->w_cursor.lnum; | |
9836 curwin->w_cursor.col = 0; | |
9837 } | |
9838 else | |
6949 | 9839 vim_beep(BO_CRSR); |
7074
c8efa41dd451
commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
Christian Brabandt <cb@256bit.org>
parents:
6971
diff
changeset
|
9840 dont_sync_undo = FALSE; |
7 | 9841 } |
9842 | |
9843 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
9844 ins_s_right(void) |
7 | 9845 { |
9846 #ifdef FEAT_FOLDING | |
9847 if ((fdo_flags & FDO_HOR) && KeyTyped) | |
9848 foldOpenCursor(); | |
9849 #endif | |
9850 undisplay_dollar(); | |
9851 if (curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count | |
9852 || gchar_cursor() != NUL) | |
9853 { | |
9854 start_arrow(&curwin->w_cursor); | |
9855 (void)fwd_word(1L, FALSE, 0); | |
9856 curwin->w_set_curswant = TRUE; | |
9857 } | |
9858 else | |
6949 | 9859 vim_beep(BO_CRSR); |
7 | 9860 } |
9861 | |
9862 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
9863 ins_up( |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
9864 int startcol) /* when TRUE move to Insstart.col */ |
7 | 9865 { |
9866 pos_T tpos; | |
9867 linenr_T old_topline = curwin->w_topline; | |
9868 #ifdef FEAT_DIFF | |
9869 int old_topfill = curwin->w_topfill; | |
9870 #endif | |
9871 | |
9872 undisplay_dollar(); | |
9873 tpos = curwin->w_cursor; | |
9874 if (cursor_up(1L, TRUE) == OK) | |
9875 { | |
9876 if (startcol) | |
9877 coladvance(getvcol_nolist(&Insstart)); | |
9878 if (old_topline != curwin->w_topline | |
9879 #ifdef FEAT_DIFF | |
9880 || old_topfill != curwin->w_topfill | |
9881 #endif | |
9882 ) | |
9883 redraw_later(VALID); | |
9884 start_arrow(&tpos); | |
9885 #ifdef FEAT_CINDENT | |
9886 can_cindent = TRUE; | |
9887 #endif | |
9888 } | |
9889 else | |
6949 | 9890 vim_beep(BO_CRSR); |
7 | 9891 } |
9892 | |
9893 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
9894 ins_pageup(void) |
7 | 9895 { |
9896 pos_T tpos; | |
9897 | |
9898 undisplay_dollar(); | |
828 | 9899 |
9900 if (mod_mask & MOD_MASK_CTRL) | |
9901 { | |
9902 /* <C-PageUp>: tab page back */ | |
1013 | 9903 if (first_tabpage->tp_next != NULL) |
9904 { | |
9905 start_arrow(&curwin->w_cursor); | |
9906 goto_tabpage(-1); | |
9907 } | |
828 | 9908 return; |
9909 } | |
9910 | |
7 | 9911 tpos = curwin->w_cursor; |
9912 if (onepage(BACKWARD, 1L) == OK) | |
9913 { | |
9914 start_arrow(&tpos); | |
9915 #ifdef FEAT_CINDENT | |
9916 can_cindent = TRUE; | |
9917 #endif | |
9918 } | |
9919 else | |
6949 | 9920 vim_beep(BO_CRSR); |
7 | 9921 } |
9922 | |
9923 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
9924 ins_down( |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
9925 int startcol) /* when TRUE move to Insstart.col */ |
7 | 9926 { |
9927 pos_T tpos; | |
9928 linenr_T old_topline = curwin->w_topline; | |
9929 #ifdef FEAT_DIFF | |
9930 int old_topfill = curwin->w_topfill; | |
9931 #endif | |
9932 | |
9933 undisplay_dollar(); | |
9934 tpos = curwin->w_cursor; | |
9935 if (cursor_down(1L, TRUE) == OK) | |
9936 { | |
9937 if (startcol) | |
9938 coladvance(getvcol_nolist(&Insstart)); | |
9939 if (old_topline != curwin->w_topline | |
9940 #ifdef FEAT_DIFF | |
9941 || old_topfill != curwin->w_topfill | |
9942 #endif | |
9943 ) | |
9944 redraw_later(VALID); | |
9945 start_arrow(&tpos); | |
9946 #ifdef FEAT_CINDENT | |
9947 can_cindent = TRUE; | |
9948 #endif | |
9949 } | |
9950 else | |
6949 | 9951 vim_beep(BO_CRSR); |
7 | 9952 } |
9953 | |
9954 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
9955 ins_pagedown(void) |
7 | 9956 { |
9957 pos_T tpos; | |
9958 | |
9959 undisplay_dollar(); | |
828 | 9960 |
9961 if (mod_mask & MOD_MASK_CTRL) | |
9962 { | |
9963 /* <C-PageDown>: tab page forward */ | |
1013 | 9964 if (first_tabpage->tp_next != NULL) |
9965 { | |
9966 start_arrow(&curwin->w_cursor); | |
9967 goto_tabpage(0); | |
9968 } | |
828 | 9969 return; |
9970 } | |
9971 | |
7 | 9972 tpos = curwin->w_cursor; |
9973 if (onepage(FORWARD, 1L) == OK) | |
9974 { | |
9975 start_arrow(&tpos); | |
9976 #ifdef FEAT_CINDENT | |
9977 can_cindent = TRUE; | |
9978 #endif | |
9979 } | |
9980 else | |
6949 | 9981 vim_beep(BO_CRSR); |
7 | 9982 } |
9983 | |
9984 #ifdef FEAT_DND | |
9985 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
9986 ins_drop(void) |
7 | 9987 { |
9988 do_put('~', BACKWARD, 1L, PUT_CURSEND); | |
9989 } | |
9990 #endif | |
9991 | |
9992 /* | |
9993 * Handle TAB in Insert or Replace mode. | |
9994 * Return TRUE when the TAB needs to be inserted like a normal character. | |
9995 */ | |
9996 static int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
9997 ins_tab(void) |
7 | 9998 { |
9999 int ind; | |
10000 int i; | |
10001 int temp; | |
10002 | |
10003 if (Insstart_blank_vcol == MAXCOL && curwin->w_cursor.lnum == Insstart.lnum) | |
10004 Insstart_blank_vcol = get_nolist_virtcol(); | |
10005 if (echeck_abbr(TAB + ABBR_OFF)) | |
10006 return FALSE; | |
10007 | |
10008 ind = inindent(0); | |
10009 #ifdef FEAT_CINDENT | |
10010 if (ind) | |
10011 can_cindent = FALSE; | |
10012 #endif | |
10013 | |
10014 /* | |
14175
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
10015 * When nothing special, insert TAB like a normal character. |
7 | 10016 */ |
10017 if (!curbuf->b_p_et | |
14175
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
10018 #ifdef FEAT_VARTABS |
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
10019 && !(p_sta && ind |
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
10020 /* These five lines mean 'tabstop' != 'shiftwidth' */ |
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
10021 && ((tabstop_count(curbuf->b_p_vts_array) > 1) |
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
10022 || (tabstop_count(curbuf->b_p_vts_array) == 1 |
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
10023 && tabstop_first(curbuf->b_p_vts_array) |
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
10024 != get_sw_value(curbuf)) |
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
10025 || (tabstop_count(curbuf->b_p_vts_array) == 0 |
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
10026 && curbuf->b_p_ts != get_sw_value(curbuf)))) |
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
10027 && tabstop_count(curbuf->b_p_vsts_array) == 0 |
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
10028 #else |
5438 | 10029 && !(p_sta && ind && curbuf->b_p_ts != get_sw_value(curbuf)) |
14175
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
10030 #endif |
3873 | 10031 && get_sts_value() == 0) |
7 | 10032 return TRUE; |
10033 | |
10034 if (stop_arrow() == FAIL) | |
10035 return TRUE; | |
10036 | |
10037 did_ai = FALSE; | |
10038 #ifdef FEAT_SMARTINDENT | |
10039 did_si = FALSE; | |
10040 can_si = FALSE; | |
10041 can_si_back = FALSE; | |
10042 #endif | |
10043 AppendToRedobuff((char_u *)"\t"); | |
10044 | |
14175
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
10045 #ifdef FEAT_VARTABS |
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
10046 if (p_sta && ind) /* insert tab in indent, use 'shiftwidth' */ |
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
10047 { |
14276
752ef53d3731
patch 8.1.0154: crash with "set smarttab shiftwidth=0 softtabstop=-1"
Christian Brabandt <cb@256bit.org>
parents:
14243
diff
changeset
|
10048 temp = (int)get_sw_value(curbuf); |
14175
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
10049 temp -= get_nolist_virtcol() % temp; |
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
10050 } |
14243
fbf0681606fa
patch 8.1.0138: negative value of 'softtabstop' not used correctly
Christian Brabandt <cb@256bit.org>
parents:
14175
diff
changeset
|
10051 else if (tabstop_count(curbuf->b_p_vsts_array) > 0 || curbuf->b_p_sts != 0) |
14175
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
10052 /* use 'softtabstop' when set */ |
14243
fbf0681606fa
patch 8.1.0138: negative value of 'softtabstop' not used correctly
Christian Brabandt <cb@256bit.org>
parents:
14175
diff
changeset
|
10053 temp = tabstop_padding(get_nolist_virtcol(), get_sts_value(), |
14175
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
10054 curbuf->b_p_vsts_array); |
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
10055 else /* otherwise use 'tabstop' */ |
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
10056 temp = tabstop_padding(get_nolist_virtcol(), curbuf->b_p_ts, |
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
10057 curbuf->b_p_vts_array); |
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
10058 #else |
7 | 10059 if (p_sta && ind) /* insert tab in indent, use 'shiftwidth' */ |
5438 | 10060 temp = (int)get_sw_value(curbuf); |
3873 | 10061 else if (curbuf->b_p_sts != 0) /* use 'softtabstop' when set */ |
10062 temp = (int)get_sts_value(); | |
7 | 10063 else /* otherwise use 'tabstop' */ |
10064 temp = (int)curbuf->b_p_ts; | |
10065 temp -= get_nolist_virtcol() % temp; | |
14175
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
10066 #endif |
7 | 10067 |
10068 /* | |
10069 * Insert the first space with ins_char(). It will delete one char in | |
10070 * replace mode. Insert the rest with ins_str(); it will not delete any | |
10071 * chars. For VREPLACE mode, we use ins_char() for all characters. | |
10072 */ | |
10073 ins_char(' '); | |
10074 while (--temp > 0) | |
10075 { | |
10076 if (State & VREPLACE_FLAG) | |
10077 ins_char(' '); | |
10078 else | |
10079 { | |
10080 ins_str((char_u *)" "); | |
10081 if (State & REPLACE_FLAG) /* no char replaced */ | |
10082 replace_push(NUL); | |
10083 } | |
10084 } | |
10085 | |
10086 /* | |
10087 * When 'expandtab' not set: Replace spaces by TABs where possible. | |
10088 */ | |
14175
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
10089 #ifdef FEAT_VARTABS |
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
10090 if (!curbuf->b_p_et && (tabstop_count(curbuf->b_p_vsts_array) > 0 |
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
10091 || get_sts_value() > 0 |
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
10092 || (p_sta && ind))) |
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
10093 #else |
3873 | 10094 if (!curbuf->b_p_et && (get_sts_value() || (p_sta && ind))) |
14175
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14103
diff
changeset
|
10095 #endif |
7 | 10096 { |
10097 char_u *ptr; | |
10098 char_u *saved_line = NULL; /* init for GCC */ | |
10099 pos_T pos; | |
10100 pos_T fpos; | |
10101 pos_T *cursor; | |
10102 colnr_T want_vcol, vcol; | |
10103 int change_col = -1; | |
10104 int save_list = curwin->w_p_list; | |
10105 | |
10106 /* | |
10107 * Get the current line. For VREPLACE mode, don't make real changes | |
10108 * yet, just work on a copy of the line. | |
10109 */ | |
10110 if (State & VREPLACE_FLAG) | |
10111 { | |
10112 pos = curwin->w_cursor; | |
10113 cursor = &pos; | |
10114 saved_line = vim_strsave(ml_get_curline()); | |
10115 if (saved_line == NULL) | |
10116 return FALSE; | |
10117 ptr = saved_line + pos.col; | |
10118 } | |
10119 else | |
10120 { | |
10121 ptr = ml_get_cursor(); | |
10122 cursor = &curwin->w_cursor; | |
10123 } | |
10124 | |
10125 /* When 'L' is not in 'cpoptions' a tab always takes up 'ts' spaces. */ | |
10126 if (vim_strchr(p_cpo, CPO_LISTWM) == NULL) | |
10127 curwin->w_p_list = FALSE; | |
10128 | |
10129 /* Find first white before the cursor */ | |
10130 fpos = curwin->w_cursor; | |
11129
f4ea50924c6d
patch 8.0.0452: some macros are in lower case
Christian Brabandt <cb@256bit.org>
parents:
11127
diff
changeset
|
10131 while (fpos.col > 0 && VIM_ISWHITE(ptr[-1])) |
7 | 10132 { |
10133 --fpos.col; | |
10134 --ptr; | |
10135 } | |
10136 | |
10137 /* In Replace mode, don't change characters before the insert point. */ | |
10138 if ((State & REPLACE_FLAG) | |
10139 && fpos.lnum == Insstart.lnum | |
10140 && fpos.col < Insstart.col) | |
10141 { | |
10142 ptr += Insstart.col - fpos.col; | |
10143 fpos.col = Insstart.col; | |
10144 } | |
10145 | |
10146 /* compute virtual column numbers of first white and cursor */ | |
10147 getvcol(curwin, &fpos, &vcol, NULL, NULL); | |
10148 getvcol(curwin, cursor, &want_vcol, NULL, NULL); | |
10149 | |
5995 | 10150 /* Use as many TABs as possible. Beware of 'breakindent', 'showbreak' |
10151 * and 'linebreak' adding extra virtual columns. */ | |
11129
f4ea50924c6d
patch 8.0.0452: some macros are in lower case
Christian Brabandt <cb@256bit.org>
parents:
11127
diff
changeset
|
10152 while (VIM_ISWHITE(*ptr)) |
7 | 10153 { |
5995 | 10154 i = lbr_chartabsize(NULL, (char_u *)"\t", vcol); |
7 | 10155 if (vcol + i > want_vcol) |
10156 break; | |
10157 if (*ptr != TAB) | |
10158 { | |
10159 *ptr = TAB; | |
10160 if (change_col < 0) | |
10161 { | |
10162 change_col = fpos.col; /* Column of first change */ | |
10163 /* May have to adjust Insstart */ | |
10164 if (fpos.lnum == Insstart.lnum && fpos.col < Insstart.col) | |
10165 Insstart.col = fpos.col; | |
10166 } | |
10167 } | |
10168 ++fpos.col; | |
10169 ++ptr; | |
10170 vcol += i; | |
10171 } | |
10172 | |
10173 if (change_col >= 0) | |
10174 { | |
10175 int repl_off = 0; | |
5995 | 10176 char_u *line = ptr; |
7 | 10177 |
10178 /* Skip over the spaces we need. */ | |
10179 while (vcol < want_vcol && *ptr == ' ') | |
10180 { | |
5995 | 10181 vcol += lbr_chartabsize(line, ptr, vcol); |
7 | 10182 ++ptr; |
10183 ++repl_off; | |
10184 } | |
10185 if (vcol > want_vcol) | |
10186 { | |
10187 /* Must have a char with 'showbreak' just before it. */ | |
10188 --ptr; | |
10189 --repl_off; | |
10190 } | |
10191 fpos.col += repl_off; | |
10192 | |
10193 /* Delete following spaces. */ | |
10194 i = cursor->col - fpos.col; | |
10195 if (i > 0) | |
10196 { | |
1622 | 10197 STRMOVE(ptr, ptr + i); |
7 | 10198 /* correct replace stack. */ |
14424
0a69e6e708f9
patch 8.1.0226: too many #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
14419
diff
changeset
|
10199 if ((State & REPLACE_FLAG) && !(State & VREPLACE_FLAG)) |
7 | 10200 for (temp = i; --temp >= 0; ) |
10201 replace_join(repl_off); | |
15138
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
15062
diff
changeset
|
10202 #ifdef FEAT_TEXT_PROP |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
15062
diff
changeset
|
10203 curbuf->b_ml.ml_line_len -= i; |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
15062
diff
changeset
|
10204 #endif |
7 | 10205 } |
33 | 10206 #ifdef FEAT_NETBEANS_INTG |
2210 | 10207 if (netbeans_active()) |
33 | 10208 { |
2209
d0ddf7ba1630
Included the patch to support netbeans in a terminal.
Bram Moolenaar <bram@vim.org>
parents:
2178
diff
changeset
|
10209 netbeans_removed(curbuf, fpos.lnum, cursor->col, (long)(i + 1)); |
33 | 10210 netbeans_inserted(curbuf, fpos.lnum, cursor->col, |
10211 (char_u *)"\t", 1); | |
10212 } | |
10213 #endif | |
7 | 10214 cursor->col -= i; |
10215 | |
10216 /* | |
10217 * In VREPLACE mode, we haven't changed anything yet. Do it now by | |
10218 * backspacing over the changed spacing and then inserting the new | |
10219 * spacing. | |
10220 */ | |
10221 if (State & VREPLACE_FLAG) | |
10222 { | |
10223 /* Backspace from real cursor to change_col */ | |
10224 backspace_until_column(change_col); | |
10225 | |
10226 /* Insert each char in saved_line from changed_col to | |
10227 * ptr-cursor */ | |
10228 ins_bytes_len(saved_line + change_col, | |
10229 cursor->col - change_col); | |
10230 } | |
14424
0a69e6e708f9
patch 8.1.0226: too many #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
14419
diff
changeset
|
10231 } |
0a69e6e708f9
patch 8.1.0226: too many #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
14419
diff
changeset
|
10232 |
7 | 10233 if (State & VREPLACE_FLAG) |
10234 vim_free(saved_line); | |
10235 curwin->w_p_list = save_list; | |
10236 } | |
10237 | |
10238 return FALSE; | |
10239 } | |
10240 | |
10241 /* | |
10242 * Handle CR or NL in insert mode. | |
13772
cc21507ee4b1
patch 8.0.1758: open_line() returns TRUE/FALSE for success/failure
Christian Brabandt <cb@256bit.org>
parents:
13718
diff
changeset
|
10243 * Return FAIL when out of memory or can't undo. |
7 | 10244 */ |
10245 static int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
10246 ins_eol(int c) |
7 | 10247 { |
10248 int i; | |
10249 | |
10250 if (echeck_abbr(c + ABBR_OFF)) | |
13788
a27d380b257f
patch 8.0.1766: expanding abbreviation doesn't work
Christian Brabandt <cb@256bit.org>
parents:
13772
diff
changeset
|
10251 return OK; |
7 | 10252 if (stop_arrow() == FAIL) |
13788
a27d380b257f
patch 8.0.1766: expanding abbreviation doesn't work
Christian Brabandt <cb@256bit.org>
parents:
13772
diff
changeset
|
10253 return FAIL; |
7 | 10254 undisplay_dollar(); |
10255 | |
10256 /* | |
10257 * Strange Vi behaviour: In Replace mode, typing a NL will not delete the | |
10258 * character under the cursor. Only push a NUL on the replace stack, | |
10259 * nothing to put back when the NL is deleted. | |
10260 */ | |
14424
0a69e6e708f9
patch 8.1.0226: too many #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
14419
diff
changeset
|
10261 if ((State & REPLACE_FLAG) && !(State & VREPLACE_FLAG)) |
7 | 10262 replace_push(NUL); |
10263 | |
10264 /* | |
10265 * In VREPLACE mode, a NL replaces the rest of the line, and starts | |
10266 * replacing the next line, so we push all of the characters left on the | |
10267 * line onto the replace stack. This is not done here though, it is done | |
10268 * in open_line(). | |
10269 */ | |
10270 | |
844 | 10271 #ifdef FEAT_VIRTUALEDIT |
10272 /* Put cursor on NUL if on the last char and coladd is 1 (happens after | |
10273 * CTRL-O). */ | |
10274 if (virtual_active() && curwin->w_cursor.coladd > 0) | |
10275 coladvance(getviscol()); | |
10276 #endif | |
10277 | |
7 | 10278 #ifdef FEAT_RIGHTLEFT |
10279 # ifdef FEAT_FKMAP | |
10280 if (p_altkeymap && p_fkmap) | |
10281 fkmap(NL); | |
10282 # endif | |
10283 /* NL in reverse insert will always start in the end of | |
10284 * current line. */ | |
10285 if (revins_on) | |
10286 curwin->w_cursor.col += (colnr_T)STRLEN(ml_get_cursor()); | |
10287 #endif | |
10288 | |
10289 AppendToRedobuff(NL_STR); | |
10290 i = open_line(FORWARD, | |
10291 #ifdef FEAT_COMMENTS | |
10292 has_format_option(FO_RET_COMS) ? OPENLINE_DO_COM : | |
10293 #endif | |
10294 0, old_indent); | |
10295 old_indent = 0; | |
10296 #ifdef FEAT_CINDENT | |
10297 can_cindent = TRUE; | |
10298 #endif | |
1032 | 10299 #ifdef FEAT_FOLDING |
10300 /* When inserting a line the cursor line must never be in a closed fold. */ | |
10301 foldOpenCursor(); | |
10302 #endif | |
7 | 10303 |
13772
cc21507ee4b1
patch 8.0.1758: open_line() returns TRUE/FALSE for success/failure
Christian Brabandt <cb@256bit.org>
parents:
13718
diff
changeset
|
10304 return i; |
7 | 10305 } |
10306 | |
10307 #ifdef FEAT_DIGRAPHS | |
10308 /* | |
10309 * Handle digraph in insert mode. | |
10310 * Returns character still to be inserted, or NUL when nothing remaining to be | |
10311 * done. | |
10312 */ | |
10313 static int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
10314 ins_digraph(void) |
7 | 10315 { |
10316 int c; | |
10317 int cc; | |
2811 | 10318 int did_putchar = FALSE; |
7 | 10319 |
10320 pc_status = PC_STATUS_UNSET; | |
10321 if (redrawing() && !char_avail()) | |
10322 { | |
10323 /* may need to redraw when no more chars available now */ | |
661 | 10324 ins_redraw(FALSE); |
7 | 10325 |
10326 edit_putchar('?', TRUE); | |
2811 | 10327 did_putchar = TRUE; |
7 | 10328 #ifdef FEAT_CMDL_INFO |
10329 add_to_showcmd_c(Ctrl_K); | |
10330 #endif | |
10331 } | |
10332 | |
10333 #ifdef USE_ON_FLY_SCROLL | |
10334 dont_scroll = TRUE; /* disallow scrolling here */ | |
10335 #endif | |
10336 | |
10337 /* don't map the digraph chars. This also prevents the | |
10338 * mode message to be deleted when ESC is hit */ | |
10339 ++no_mapping; | |
10340 ++allow_keys; | |
1389 | 10341 c = plain_vgetc(); |
7 | 10342 --no_mapping; |
10343 --allow_keys; | |
2811 | 10344 if (did_putchar) |
10345 /* when the line fits in 'columns' the '?' is at the start of the next | |
10346 * line and will not be removed by the redraw */ | |
10347 edit_unputchar(); | |
2319
c79ccf947487
Fix: When entering a digraph or special character after a line that fits the
Bram Moolenaar <bram@vim.org>
parents:
2297
diff
changeset
|
10348 |
7 | 10349 if (IS_SPECIAL(c) || mod_mask) /* special key */ |
10350 { | |
10351 #ifdef FEAT_CMDL_INFO | |
10352 clear_showcmd(); | |
10353 #endif | |
10354 insert_special(c, TRUE, FALSE); | |
10355 return NUL; | |
10356 } | |
10357 if (c != ESC) | |
10358 { | |
2811 | 10359 did_putchar = FALSE; |
7 | 10360 if (redrawing() && !char_avail()) |
10361 { | |
10362 /* may need to redraw when no more chars available now */ | |
661 | 10363 ins_redraw(FALSE); |
7 | 10364 |
10365 if (char2cells(c) == 1) | |
10366 { | |
661 | 10367 ins_redraw(FALSE); |
7 | 10368 edit_putchar(c, TRUE); |
2811 | 10369 did_putchar = TRUE; |
7 | 10370 } |
10371 #ifdef FEAT_CMDL_INFO | |
10372 add_to_showcmd_c(c); | |
10373 #endif | |
10374 } | |
10375 ++no_mapping; | |
10376 ++allow_keys; | |
1389 | 10377 cc = plain_vgetc(); |
7 | 10378 --no_mapping; |
10379 --allow_keys; | |
2811 | 10380 if (did_putchar) |
10381 /* when the line fits in 'columns' the '?' is at the start of the | |
10382 * next line and will not be removed by a redraw */ | |
10383 edit_unputchar(); | |
7 | 10384 if (cc != ESC) |
10385 { | |
10386 AppendToRedobuff((char_u *)CTRL_V_STR); | |
10387 c = getdigraph(c, cc, TRUE); | |
10388 #ifdef FEAT_CMDL_INFO | |
10389 clear_showcmd(); | |
10390 #endif | |
10391 return c; | |
10392 } | |
10393 } | |
10394 #ifdef FEAT_CMDL_INFO | |
10395 clear_showcmd(); | |
10396 #endif | |
10397 return NUL; | |
10398 } | |
10399 #endif | |
10400 | |
10401 /* | |
10402 * Handle CTRL-E and CTRL-Y in Insert mode: copy char from other line. | |
10403 * Returns the char to be inserted, or NUL if none found. | |
10404 */ | |
3501 | 10405 int |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
10406 ins_copychar(linenr_T lnum) |
7 | 10407 { |
10408 int c; | |
10409 int temp; | |
10410 char_u *ptr, *prev_ptr; | |
5995 | 10411 char_u *line; |
7 | 10412 |
10413 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) | |
10414 { | |
6949 | 10415 vim_beep(BO_COPY); |
7 | 10416 return NUL; |
10417 } | |
10418 | |
10419 /* try to advance to the cursor column */ | |
10420 temp = 0; | |
5995 | 10421 line = ptr = ml_get(lnum); |
7 | 10422 prev_ptr = ptr; |
10423 validate_virtcol(); | |
10424 while ((colnr_T)temp < curwin->w_virtcol && *ptr != NUL) | |
10425 { | |
10426 prev_ptr = ptr; | |
5995 | 10427 temp += lbr_chartabsize_adv(line, &ptr, (colnr_T)temp); |
7 | 10428 } |
10429 if ((colnr_T)temp > curwin->w_virtcol) | |
10430 ptr = prev_ptr; | |
10431 | |
10432 c = (*mb_ptr2char)(ptr); | |
10433 if (c == NUL) | |
6949 | 10434 vim_beep(BO_COPY); |
7 | 10435 return c; |
10436 } | |
10437 | |
449 | 10438 /* |
10439 * CTRL-Y or CTRL-E typed in Insert mode. | |
10440 */ | |
10441 static int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
10442 ins_ctrl_ey(int tc) |
449 | 10443 { |
10444 int c = tc; | |
10445 | |
10446 #ifdef FEAT_INS_EXPAND | |
10447 if (ctrl_x_mode == CTRL_X_SCROLL) | |
10448 { | |
10449 if (c == Ctrl_Y) | |
10450 scrolldown_clamp(); | |
10451 else | |
10452 scrollup_clamp(); | |
10453 redraw_later(VALID); | |
10454 } | |
10455 else | |
10456 #endif | |
10457 { | |
10458 c = ins_copychar(curwin->w_cursor.lnum + (c == Ctrl_Y ? -1 : 1)); | |
10459 if (c != NUL) | |
10460 { | |
10461 long tw_save; | |
10462 | |
10463 /* The character must be taken literally, insert like it | |
10464 * was typed after a CTRL-V, and pretend 'textwidth' | |
10465 * wasn't set. Digits, 'o' and 'x' are special after a | |
10466 * CTRL-V, don't use it for these. */ | |
10467 if (c < 256 && !isalnum(c)) | |
10468 AppendToRedobuff((char_u *)CTRL_V_STR); /* CTRL-V */ | |
10469 tw_save = curbuf->b_p_tw; | |
10470 curbuf->b_p_tw = -1; | |
10471 insert_special(c, TRUE, FALSE); | |
10472 curbuf->b_p_tw = tw_save; | |
10473 #ifdef FEAT_RIGHTLEFT | |
10474 revins_chars++; | |
10475 revins_legal++; | |
10476 #endif | |
10477 c = Ctrl_V; /* pretend CTRL-V is last character */ | |
10478 auto_format(FALSE, TRUE); | |
10479 } | |
10480 } | |
10481 return c; | |
10482 } | |
10483 | |
7 | 10484 #ifdef FEAT_SMARTINDENT |
10485 /* | |
10486 * Try to do some very smart auto-indenting. | |
10487 * Used when inserting a "normal" character. | |
10488 */ | |
10489 static void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
10490 ins_try_si(int c) |
7 | 10491 { |
10492 pos_T *pos, old_pos; | |
10493 char_u *ptr; | |
10494 int i; | |
10495 int temp; | |
10496 | |
10497 /* | |
10498 * do some very smart indenting when entering '{' or '}' | |
10499 */ | |
10500 if (((did_si || can_si_back) && c == '{') || (can_si && c == '}')) | |
10501 { | |
10502 /* | |
10503 * for '}' set indent equal to indent of line containing matching '{' | |
10504 */ | |
10505 if (c == '}' && (pos = findmatch(NULL, '{')) != NULL) | |
10506 { | |
10507 old_pos = curwin->w_cursor; | |
10508 /* | |
10509 * If the matching '{' has a ')' immediately before it (ignoring | |
10510 * white-space), then line up with the start of the line | |
10511 * containing the matching '(' if there is one. This handles the | |
10512 * case where an "if (..\n..) {" statement continues over multiple | |
10513 * lines -- webb | |
10514 */ | |
10515 ptr = ml_get(pos->lnum); | |
10516 i = pos->col; | |
10517 if (i > 0) /* skip blanks before '{' */ | |
11129
f4ea50924c6d
patch 8.0.0452: some macros are in lower case
Christian Brabandt <cb@256bit.org>
parents:
11127
diff
changeset
|
10518 while (--i > 0 && VIM_ISWHITE(ptr[i])) |
7 | 10519 ; |
10520 curwin->w_cursor.lnum = pos->lnum; | |
10521 curwin->w_cursor.col = i; | |
10522 if (ptr[i] == ')' && (pos = findmatch(NULL, '(')) != NULL) | |
10523 curwin->w_cursor = *pos; | |
10524 i = get_indent(); | |
10525 curwin->w_cursor = old_pos; | |
10526 if (State & VREPLACE_FLAG) | |
1516 | 10527 change_indent(INDENT_SET, i, FALSE, NUL, TRUE); |
7 | 10528 else |
10529 (void)set_indent(i, SIN_CHANGED); | |
10530 } | |
10531 else if (curwin->w_cursor.col > 0) | |
10532 { | |
10533 /* | |
10534 * when inserting '{' after "O" reduce indent, but not | |
10535 * more than indent of previous line | |
10536 */ | |
10537 temp = TRUE; | |
10538 if (c == '{' && can_si_back && curwin->w_cursor.lnum > 1) | |
10539 { | |
10540 old_pos = curwin->w_cursor; | |
10541 i = get_indent(); | |
10542 while (curwin->w_cursor.lnum > 1) | |
10543 { | |
10544 ptr = skipwhite(ml_get(--(curwin->w_cursor.lnum))); | |
10545 | |
10546 /* ignore empty lines and lines starting with '#'. */ | |
10547 if (*ptr != '#' && *ptr != NUL) | |
10548 break; | |
10549 } | |
10550 if (get_indent() >= i) | |
10551 temp = FALSE; | |
10552 curwin->w_cursor = old_pos; | |
10553 } | |
10554 if (temp) | |
1516 | 10555 shift_line(TRUE, FALSE, 1, TRUE); |
7 | 10556 } |
10557 } | |
10558 | |
10559 /* | |
10560 * set indent of '#' always to 0 | |
10561 */ | |
10562 if (curwin->w_cursor.col > 0 && can_si && c == '#') | |
10563 { | |
10564 /* remember current indent for next line */ | |
10565 old_indent = get_indent(); | |
10566 (void)set_indent(0, SIN_CHANGED); | |
10567 } | |
10568 | |
10569 /* Adjust ai_col, the char at this position can be deleted. */ | |
10570 if (ai_col > curwin->w_cursor.col) | |
10571 ai_col = curwin->w_cursor.col; | |
10572 } | |
10573 #endif | |
10574 | |
10575 /* | |
10576 * Get the value that w_virtcol would have when 'list' is off. | |
10577 * Unless 'cpo' contains the 'L' flag. | |
10578 */ | |
15062
3a94f7918980
patch 8.1.0542: shiftwidth() does not take 'vartabstop' into account
Bram Moolenaar <Bram@vim.org>
parents:
14985
diff
changeset
|
10579 colnr_T |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
10580 get_nolist_virtcol(void) |
7 | 10581 { |
15062
3a94f7918980
patch 8.1.0542: shiftwidth() does not take 'vartabstop' into account
Bram Moolenaar <Bram@vim.org>
parents:
14985
diff
changeset
|
10582 // check validity of cursor in current buffer |
3a94f7918980
patch 8.1.0542: shiftwidth() does not take 'vartabstop' into account
Bram Moolenaar <Bram@vim.org>
parents:
14985
diff
changeset
|
10583 if (curwin->w_buffer == NULL |
3a94f7918980
patch 8.1.0542: shiftwidth() does not take 'vartabstop' into account
Bram Moolenaar <Bram@vim.org>
parents:
14985
diff
changeset
|
10584 || curwin->w_buffer->b_ml.ml_mfp == NULL |
3a94f7918980
patch 8.1.0542: shiftwidth() does not take 'vartabstop' into account
Bram Moolenaar <Bram@vim.org>
parents:
14985
diff
changeset
|
10585 || curwin->w_cursor.lnum > curwin->w_buffer->b_ml.ml_line_count) |
3a94f7918980
patch 8.1.0542: shiftwidth() does not take 'vartabstop' into account
Bram Moolenaar <Bram@vim.org>
parents:
14985
diff
changeset
|
10586 return 0; |
7 | 10587 if (curwin->w_p_list && vim_strchr(p_cpo, CPO_LISTWM) == NULL) |
10588 return getvcol_nolist(&curwin->w_cursor); | |
10589 validate_virtcol(); | |
10590 return curwin->w_virtcol; | |
10591 } | |
3390 | 10592 |
13380
69517d67421f
patch 8.0.1564: too many #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
13244
diff
changeset
|
10593 #if defined(FEAT_EVAL) |
3390 | 10594 /* |
10595 * Handle the InsertCharPre autocommand. | |
10596 * "c" is the character that was typed. | |
10597 * Return a pointer to allocated memory with the replacement string. | |
10598 * Return NULL to continue inserting "c". | |
10599 */ | |
10600 static char_u * | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
7799
diff
changeset
|
10601 do_insert_char_pre(int c) |
3390 | 10602 { |
3547 | 10603 char_u *res; |
10604 char_u buf[MB_MAXBYTES + 1]; | |
15377
88b0a490816e
patch 8.1.0696: when test_edit fails 'insertmode' may not be reset
Bram Moolenaar <Bram@vim.org>
parents:
15349
diff
changeset
|
10605 int save_State = State; |
3390 | 10606 |
10607 /* Return quickly when there is nothing to do. */ | |
10608 if (!has_insertcharpre()) | |
10609 return NULL; | |
10610 | |
3547 | 10611 if (has_mbyte) |
10612 buf[(*mb_char2bytes)(c, buf)] = NUL; | |
10613 else | |
10614 { | |
10615 buf[0] = c; | |
10616 buf[1] = NUL; | |
10617 } | |
10618 | |
3390 | 10619 /* Lock the text to avoid weird things from happening. */ |
10620 ++textlock; | |
3547 | 10621 set_vim_var_string(VV_CHAR, buf, -1); /* set v:char */ |
10622 | |
10623 res = NULL; | |
14485
c71d65c3672f
patch 8.1.0256: using setline() in TextChangedI splits undo
Christian Brabandt <cb@256bit.org>
parents:
14465
diff
changeset
|
10624 if (ins_apply_autocmds(EVENT_INSERTCHARPRE)) |
3547 | 10625 { |
10626 /* Get the value of v:char. It may be empty or more than one | |
10627 * character. Only use it when changed, otherwise continue with the | |
10628 * original character to avoid breaking autoindent. */ | |
10629 if (STRCMP(buf, get_vim_var_str(VV_CHAR)) != 0) | |
10630 res = vim_strsave(get_vim_var_str(VV_CHAR)); | |
10631 } | |
3390 | 10632 |
10633 set_vim_var_string(VV_CHAR, NULL, -1); /* clear v:char */ | |
10634 --textlock; | |
10635 | |
15377
88b0a490816e
patch 8.1.0696: when test_edit fails 'insertmode' may not be reset
Bram Moolenaar <Bram@vim.org>
parents:
15349
diff
changeset
|
10636 // Restore the State, it may have been changed. |
88b0a490816e
patch 8.1.0696: when test_edit fails 'insertmode' may not be reset
Bram Moolenaar <Bram@vim.org>
parents:
15349
diff
changeset
|
10637 State = save_State; |
88b0a490816e
patch 8.1.0696: when test_edit fails 'insertmode' may not be reset
Bram Moolenaar <Bram@vim.org>
parents:
15349
diff
changeset
|
10638 |
3390 | 10639 return res; |
10640 } | |
10641 #endif | |
14485
c71d65c3672f
patch 8.1.0256: using setline() in TextChangedI splits undo
Christian Brabandt <cb@256bit.org>
parents:
14465
diff
changeset
|
10642 |
c71d65c3672f
patch 8.1.0256: using setline() in TextChangedI splits undo
Christian Brabandt <cb@256bit.org>
parents:
14465
diff
changeset
|
10643 /* |
c71d65c3672f
patch 8.1.0256: using setline() in TextChangedI splits undo
Christian Brabandt <cb@256bit.org>
parents:
14465
diff
changeset
|
10644 * Trigger "event" and take care of fixing undo. |
c71d65c3672f
patch 8.1.0256: using setline() in TextChangedI splits undo
Christian Brabandt <cb@256bit.org>
parents:
14465
diff
changeset
|
10645 */ |
c71d65c3672f
patch 8.1.0256: using setline() in TextChangedI splits undo
Christian Brabandt <cb@256bit.org>
parents:
14465
diff
changeset
|
10646 static int |
c71d65c3672f
patch 8.1.0256: using setline() in TextChangedI splits undo
Christian Brabandt <cb@256bit.org>
parents:
14465
diff
changeset
|
10647 ins_apply_autocmds(event_T event) |
c71d65c3672f
patch 8.1.0256: using setline() in TextChangedI splits undo
Christian Brabandt <cb@256bit.org>
parents:
14465
diff
changeset
|
10648 { |
c71d65c3672f
patch 8.1.0256: using setline() in TextChangedI splits undo
Christian Brabandt <cb@256bit.org>
parents:
14465
diff
changeset
|
10649 varnumber_T tick = CHANGEDTICK(curbuf); |
c71d65c3672f
patch 8.1.0256: using setline() in TextChangedI splits undo
Christian Brabandt <cb@256bit.org>
parents:
14465
diff
changeset
|
10650 int r; |
c71d65c3672f
patch 8.1.0256: using setline() in TextChangedI splits undo
Christian Brabandt <cb@256bit.org>
parents:
14465
diff
changeset
|
10651 |
c71d65c3672f
patch 8.1.0256: using setline() in TextChangedI splits undo
Christian Brabandt <cb@256bit.org>
parents:
14465
diff
changeset
|
10652 r = apply_autocmds(event, NULL, NULL, FALSE, curbuf); |
c71d65c3672f
patch 8.1.0256: using setline() in TextChangedI splits undo
Christian Brabandt <cb@256bit.org>
parents:
14465
diff
changeset
|
10653 |
c71d65c3672f
patch 8.1.0256: using setline() in TextChangedI splits undo
Christian Brabandt <cb@256bit.org>
parents:
14465
diff
changeset
|
10654 // If u_savesub() was called then we are not prepared to start |
c71d65c3672f
patch 8.1.0256: using setline() in TextChangedI splits undo
Christian Brabandt <cb@256bit.org>
parents:
14465
diff
changeset
|
10655 // a new line. Call u_save() with no contents to fix that. |
c71d65c3672f
patch 8.1.0256: using setline() in TextChangedI splits undo
Christian Brabandt <cb@256bit.org>
parents:
14465
diff
changeset
|
10656 if (tick != CHANGEDTICK(curbuf)) |
c71d65c3672f
patch 8.1.0256: using setline() in TextChangedI splits undo
Christian Brabandt <cb@256bit.org>
parents:
14465
diff
changeset
|
10657 u_save(curwin->w_cursor.lnum, (linenr_T)(curwin->w_cursor.lnum + 1)); |
c71d65c3672f
patch 8.1.0256: using setline() in TextChangedI splits undo
Christian Brabandt <cb@256bit.org>
parents:
14465
diff
changeset
|
10658 |
c71d65c3672f
patch 8.1.0256: using setline() in TextChangedI splits undo
Christian Brabandt <cb@256bit.org>
parents:
14465
diff
changeset
|
10659 return r; |
c71d65c3672f
patch 8.1.0256: using setline() in TextChangedI splits undo
Christian Brabandt <cb@256bit.org>
parents:
14465
diff
changeset
|
10660 } |