Skip to content
Newer
Older
100644 526 lines (465 sloc) 13.8 KB
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
1 /* state.c */
2 /* Copyright 1995 by Steve Kirkendall */
3
4
5 #include "elvis.h"
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored Dec 10, 2011
6 #ifdef FEATURE_RCSID
2fe6e17 @mbert Import Elvis 2.2_1 (written by Steve Kirkendall)
authored Dec 10, 2011
7 char id_state[] = "$Id: state.c,v 2.44 2004/02/05 15:47:35 steve Exp $";
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored Dec 10, 2011
8 #endif
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
9
10 #if USE_PROTOTYPES
11 static void fixbounds(WINDOW win);
12 #endif
13
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored Dec 10, 2011
14
15 /* This is the window that we're sending the character to. At the start of
16 * the processing for each keystroke, this is set to focus. The code
17 * here always uses focus instead of focus from that point on, because
18 * the code here assumes that the window won't switch during the processing
19 * of the keystroke, but focus may in fact change.
20 */
21 WINDOW focus;
22
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
23 /* Push a single state, in the current stratum.
24 *
25 * After this function returns, several fields in the struct will still
26 * need to be initialized. This function is meant to be called only from
27 * vipush() and inputpush(); those functions initialize the other fields.
28 */
29 void statepush(win, flags)
30 WINDOW win; /* window to receive new key state */
31 ELVISSTATE flags; /* flags of the new state */
32 {
33 STATE *newp;
34
35 /* allocate a STATE struct */
36 newp = (STATE *)safealloc(1, sizeof(STATE));
37
38 /* initialize the struct's values */
39 newp->flags = flags;
40 if (win->state != NULL)
41 {
42 newp->flags |= (win->state->flags & ELVIS_BOTTOM);
43 newp->cursor = win->state->cursor;
44 newp->top = win->state->top;
45 newp->bottom = win->state->bottom;
46 newp->acton = win->state->acton;
47 }
48 else if (!gui->moveto)
49 {
50 /* if GUI has no move() function, we can't support full-screen */
51 newp->flags |= ELVIS_BOTTOM;
52 }
53
54 /* link this into the stack */
55 newp->pop = win->state;
56 win->state = newp;
57 }
58
59 /* Pop a single state */
60 void statepop(win)
61 WINDOW win; /* window from which the state will be popped */
62 {
63 STATE *doomed;
64
65 assert(win->state != NULL);
66
67 /* if this is a stratum, then free the marks */
68 if (win->state->enter != NULL)
69 {
70 /* free the marks */
71 markfree(win->state->cursor);
72 markfree(win->state->top);
73 markfree(win->state->bottom);
74
75 /* also restore wantcol */
76 if (win->state->acton)
77 win->wantcol = win->state->acton->wantcol;
78 }
79
80 /* if we were editing a line before, and popping makes us switch
81 * buffers, then we aren't editing that line anymore.
82 */
83 if (!win->state->pop || win->state->cursor != win->state->pop->cursor)
84 {
85 if (win->di->openline)
86 {
87 markfree(win->di->openline);
88 win->di->openline = NULL;
89 }
90 }
91
92 /* if this has an info struct, then free it now, too */
93 if (win->state->info != NULL)
94 {
95 safefree(win->state->info);
96 }
97
98 /* remove the state from the state stack, and free it */
99 doomed = win->state;
100 win->state = doomed->pop;
101 safefree(doomed);
102 }
103
104 /* Push a new stratum. This involves appending a new blank line to a buffer,
105 * possibly adding a the prompt character to that line, and then pushing an
106 * open input state onto the state stack.
107 */
108 void statestratum(win, bufname, prompt, enter)
109 WINDOW win; /* window to receive new stratum */
110 CHAR *bufname; /* name of buffer to use in new stratum */
111 _CHAR_ prompt; /* prompt character, or '\0' for none */
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored Dec 10, 2011
112 RESULT (*enter)P_((WINDOW window));/* function which executes line */
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
113 {
114 BUFFER buf;
115 CHAR newtext[2];
116 MARK mark;
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored Dec 10, 2011
117 MARKBUF tmp;
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
118
119 /* find the buffer. If it doesn't exist, then create it */
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored Dec 10, 2011
120 buf = bufalloc(bufname, 0, ElvTrue); /*!!! sometimes ElvFalse? */
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
121
122 /* create a blank line at the end of the buffer, and insert the prompt
123 * character there, if given.
124 */
125 mark = markalloc(buf, o_bufchars(buf));
126 if (prompt && (prompt != ':' || o_prompt))
127 {
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored Dec 10, 2011
128 /* if no other window is using this buffer, and the buffer
129 * already ends with a line that looks like our prompt line,
130 * then reuse that line.
131 */
132 if (wincount(buf) == 0
133 && o_bufchars(buf) > 2
134 && scanchar(marktmp(tmp, buf, o_bufchars(buf) - 1)) == '\n'
135 && scanchar(marktmp(tmp, buf, o_bufchars(buf) - 2)) == prompt
136 && scanchar(marktmp(tmp, buf, o_bufchars(buf) - 3)) == '\n')
137 {
138 markaddoffset(mark, -1);
139 }
140 else /* add a new prompt line */
141 {
142 newtext[0] = prompt;
143 newtext[1] = '\n';
144 bufreplace(mark, mark, newtext, 2);
145 marksetoffset(mark, o_bufchars(buf) - 1);
146 }
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
147 }
148 else
149 {
150 newtext[0] = '\n';
151 bufreplace(mark, mark, newtext, 1);
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored Dec 10, 2011
152 marksetoffset(mark, o_bufchars(buf) - 1);
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
153 }
154
155 /* use the prompt as a special key in case we hit a [More] prompt
156 * when switching back to the old key state.
157 */
158 win->state->morekey = prompt;
159
160 /* push a new input state */
161 inputpush(win, ELVIS_BOTTOM|ELVIS_1LINE, 'i');
162
163 /* initialize the state to look like a new stratum */
164 win->state->cursor = mark;
165 win->state->top = markdup(mark);
166 win->state->bottom = markdup(mark);
167 win->state->acton = win->state->pop;
168 win->state->enter = enter;
169 win->state->prompt = prompt;
170
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored Dec 10, 2011
171 /* For history buffers, we want to use the MAP_HISTORY map context
172 * instead of the normal MAP_INPUT context. We assume this is a
173 * history buffer if it normally has a prompt.
174 */
175 if (prompt)
176 win->state->mapflags = MAP_HISTORY;
177
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
178 /* save the old stratum's wantcol (if there was an old stratum) */
179 if (win->state->acton)
180 win->state->acton->wantcol = win->wantcol;
181 }
182
183
184 static void fixbounds(win)
185 WINDOW win; /* window whose edit bounds need tweaking */
186 {
187 STATE *state;
188
189 /* Fix the edit bounds.
190 *
191 * Note that we do this for all strata on the stack, not just
192 * the current one. This is mostly for the benefit of the
193 * visual / and ? commands -- After the search, the current
194 * strata is still the regexp line entry one, but we need to
195 * worry about the edit limits of the main strata.
196 */
197 for (state = win->state; state; state = state->acton)
198 {
199 if (markbuffer(state->top) != markbuffer(state->cursor)
200 || markbuffer(state->top) != markbuffer(state->bottom)
201 || markoffset(state->top) > markoffset(state->cursor)
202 || markoffset(state->cursor) > markoffset(state->bottom))
203 {
204 marksetbuffer(state->top, markbuffer(state->cursor));
205 marksetbuffer(state->bottom, markbuffer(state->cursor));
206 if (state->acton == NULL)
207 {
208 /* in the main edit buffer, the edit bounds are
209 * changed to equal the cursor.
210 */
211 marksetoffset(state->top, markoffset(state->cursor));
212 marksetoffset(state->bottom, markoffset(state->cursor));
213 }
214 else
215 {
216 /* in a history buffer, the edit bounds are set
217 * to the whole line that the cursor is on, and
218 * if the cursor has moved to a different line
219 * then it is moved to the end of that line.
220 */
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored Dec 10, 2011
221 marksetoffset(state->top, markoffset((*dmnormal.move)(focus, state->top, 0L, 0L, ElvFalse)));
222 marksetoffset(state->bottom, markoffset((*dmnormal.move)(focus, state->top, 0L, INFINITY, ElvFalse)));
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
223 if (markoffset(state->cursor) < markoffset(state->top)
224 || markoffset(state->cursor) > markoffset(state->bottom))
225 {
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored Dec 10, 2011
226 marksetoffset(state->top, markoffset(dispmove(focus, 0L, 0L)));
227 marksetoffset(state->bottom, markoffset(dispmove(focus, 0L, INFINITY)));
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
228 marksetoffset(state->cursor, markoffset(state->bottom));
229 }
230 }
231 }
232 }
233 }
234
235
236 /* This function processes a single keystroke in the context of the default
237 * window.
238 */
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored Dec 10, 2011
239 RESULT statekey(key)
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
240 _CHAR_ key; /* a single key to be parsed */
241 {
242 RESULT result;
243 STATE *state;
244 CHAR newtext[2];
245 int i, j;
246
247 assert(windefault);
248
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored Dec 10, 2011
249 /* make an unalterable copy of windefault */
250 focus = windefault;
251 state = focus->state;
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
252
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored Dec 10, 2011
253 #ifdef FEATURE_AUTOCMD
254 /* detect when the display mode changes, so we can trigger DispMapLeave
255 * and DispMapEnter autocmds. These are often used for implementing
256 * display-specific maps.
257 */
258 audispmap();
259 #endif
260
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
261 /* If user wants to abort operation, then ignore this key. This is
262 * important to check for, because elvis may be stuck in a recursive
263 * loop.
264 */
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored Dec 10, 2011
265 if (guipoll(ElvFalse))
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
266 {
267 mapalert();
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored Dec 10, 2011
268 return RESULT_ERROR;
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
269 }
270
271 /* if <Enter>, and not quoted, and this is a stratum, then call the
272 * enter() function. If it returns RESULT_MORE then follow that by
273 * processing <Enter> in the usual way; otherwise we're done.
274 */
275 if ((key == '\r' || key == '\n')
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored Dec 10, 2011
276 && (*state->shape)(focus) != CURSOR_QUOTE
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
277 && state->enter)
278 {
279 /* adjust the input line */
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored Dec 10, 2011
280 inputbeforeenter(focus);
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
281
282 /* if this line was entered via a one-time command from
283 * visual mode, then force drawstate to be DRAW_VISUAL so
284 * the user isn't forced to hit <enter> unless there really
285 * is some useful text to be read. EXCEPTION: If this GUI
286 * doesn't do full-screen, then don't bother.
287 */
288 if ((state->flags & ELVIS_1LINE) != 0 && gui->moveto != NULL)
289 {
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored Dec 10, 2011
290 focus->di->drawstate = DRAW_VISUAL;
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
291 }
292
293 /* call the "enter" function for this state, and see whether
294 * the command is complete.
295 */
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored Dec 10, 2011
296 result = (*state->enter)(focus);
297
298 /* if input line wasn't ended by execution of the enter()
299 * function, then end it now.
300 */
301 if (windefault
2fe6e17 @mbert Import Elvis 2.2_1 (written by Steve Kirkendall)
authored Dec 10, 2011
302 && ((focus->state->acton && (focus->state->acton->flags & ELVIS_BOTTOM) != 0)
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored Dec 10, 2011
303 || (focus->state->flags & (ELVIS_ONCE|ELVIS_1LINE|ELVIS_POP)) == 0))
304 drawopencomplete(focus);
305
306 /* check the results */
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
307 if (result != RESULT_MORE)
308 {
309 /* If the window went away, then no more processing
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored Dec 10, 2011
310 * is necessary. Note that we're checking windefault
311 * here, not focus! If windefault has become NULL,
312 * that means the window was destroyed, and focus now
313 * points to freed memory!
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
314 */
315 if (!windefault)
316 {
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored Dec 10, 2011
317 return RESULT_COMPLETE;
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
318 }
319
320 /* We did one command line. Is that all we wanted? */
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored Dec 10, 2011
321 state = focus->state;
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
322 if (state->flags & ELVIS_1LINE)
323 {
324 /* yes, pop the stratum */
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored Dec 10, 2011
325 state = state->acton;
326 while (state != focus->state->pop)
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
327 {
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored Dec 10, 2011
328 statepop(focus);
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
329 }
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored Dec 10, 2011
330 state = focus->state;
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored Dec 10, 2011
331 state->flags |= ELVIS_POP;
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
332 }
333 else
334 {
335 marksetoffset(state->cursor, o_bufchars(markbuffer(state->cursor)));
336 if (state->prompt && (state->prompt != ':' || o_prompt))
337 {
338 newtext[0] = state->prompt;
339 newtext[1] = '\n';
340 bufreplace(state->cursor, state->cursor, newtext, 2);
341 }
342 else
343 {
344 newtext[0] = '\n';
345 bufreplace(state->cursor, state->cursor, newtext, 1);
346 }
347 marksetoffset(state->cursor, o_bufchars(markbuffer(state->cursor)) - 1);
348 }
349
350 /* do the usual after-keystroke processing */
351 goto AfterKeystroke;
352 }
353 }
354
355 /* parse the keystroke for the current window */
356 if (key != (_CHAR_)-1)
357 result = (*state->parse)(key, state->info);
358 else
359 result = RESULT_COMPLETE;
360
361 /* If error, alert the window */
362 if (result == RESULT_ERROR)
363 {
364 /* clobber the "cmdchars" list - all chars entered */
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored Dec 10, 2011
365 focus->cmdchars[0] = '\0';
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
366
367 /* alert the window */
368 mapalert();
369 if (o_errorbells)
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored Dec 10, 2011
370 guibeep(focus);
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
371 }
3a9bb55 @mbert Import Elvis 2.1_3 (written by Steve Kirkendall)
authored Dec 10, 2011
372 else if (result == RESULT_COMPLETE && key != (_CHAR_)-1 && state == focus->state)
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
373 {
374 /* clobber the "cmdchars" list - all chars entered */
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored Dec 10, 2011
375 focus->cmdchars[0] = '\0';
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
376
377 /* We have parsed a complete command. Now perform it */
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored Dec 10, 2011
378 switch ((*state->perform)(focus))
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
379 {
380 case RESULT_ERROR:
381 /* command failed! alert the window */
382 mapalert();
383 if (o_errorbells)
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored Dec 10, 2011
384 guibeep(focus);
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
385 break;
386
387 case RESULT_MORE:
388 /* set the pushed state's ELVIS_MORE flag */
389 state->flags |= ELVIS_MORE;
390 break;
391
392 case RESULT_COMPLETE:
393 /* nothing, just fall through... */
394 ;
395 }
396
397 /* The command may have caused the window to disappear.
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored Dec 10, 2011
398 * If so, then no more processing is necessary. Note that
399 * we check windefault, not focus! If windefault has become
400 * NULL, then the window was destroyed and focus points to
401 * freed memory.
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
402 */
403 if (!windefault)
404 {
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored Dec 10, 2011
405 return RESULT_COMPLETE;
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
406 }
407
408 /* If cursor has moved outside state->top and state->bottom,
409 * then make state->top and state->bottom equal the cursor.
410 */
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored Dec 10, 2011
411 fixbounds(focus);
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
412
413 /* if the "optimize" option is false, and the current window
414 * is in vi mode, then update the current window's image.
415 */
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored Dec 10, 2011
416 if (!o_optimize /* && focus */
417 && !focus->state->pop
418 && focus->di->curchgs != markbuffer(focus->cursor)->changes
419 && (focus->di->drawstate == DRAW_VISUAL
420 || focus->di->drawstate == DRAW_VMSG))
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
421 {
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored Dec 10, 2011
422 drawimage(focus);
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
423 if (gui->flush)
424 (*gui->flush)();
425 }
426 }
427 else if (result == RESULT_MORE)
428 {
429 /* partial command -- add this key to the cmdchars field */
430
431 /* if the array is full, then shift */
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored Dec 10, 2011
432 i = CHARlen(focus->cmdchars);
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored Dec 10, 2011
433 j = (elvcntrl(key) ? 2 : 1);
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored Dec 10, 2011
434 if (i + j >= QTY(focus->cmdchars))
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
435 {
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored Dec 10, 2011
436 for (i = 0; focus->cmdchars[i]; i++)
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
437 {
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored Dec 10, 2011
438 focus->cmdchars[i] = focus->cmdchars[i + j];
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
439 }
440 i -= j;
441 }
442
443 /* stuff the new char into it */
444 switch (o_nonascii)
445 {
446 case 's': key &= 0x7f; break;
447 case 'n': key = '.'; break;
448 case 'm': if (key>0x7f && key<=0x9f)
449 key = '.'; break;
450 }
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored Dec 10, 2011
451 if (elvcntrl(key))
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
452 {
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored Dec 10, 2011
453 focus->cmdchars[i++] = '^';
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
454 key ^= 0x40;
455 }
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored Dec 10, 2011
456 focus->cmdchars[i++] = key;
457 focus->cmdchars[i++] = '\0';
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
458 }
459
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored Dec 10, 2011
460 #ifdef FEATURE_V
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
461 /* if visibly marking, then adjust the marks */
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored Dec 10, 2011
462 if (focus->seltop)
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
463 {
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored Dec 10, 2011
464 (void)v_visible(focus, NULL);
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
465 }
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored Dec 10, 2011
466 #endif
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
467
468 /* if we aren't still parsing, then perform other checks */
469 if (result != RESULT_MORE)
470 {
471 AfterKeystroke:
472 /* pop states, if we're supposed to */
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored Dec 10, 2011
473 while (focus->state && (focus->state->flags & ELVIS_POP))
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
474 {
475 /* pop the state */
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored Dec 10, 2011
476 statepop(focus);
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
477
478 /* if the next state has its ELVIS_MORE flag set, then
479 * call the next state's perform() function again.
480 */
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored Dec 10, 2011
481 if (focus->state
482 && focus->state->flags & ELVIS_MORE)
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
483 {
484 /* call the next state's perform() function again */
485 if (result != RESULT_ERROR)
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored Dec 10, 2011
486 result = (*focus->state->perform)(focus);
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
487 switch (result)
488 {
489 case RESULT_ERROR:
490 /* command failed! alert the window */
491 mapalert();
492 if (o_errorbells)
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored Dec 10, 2011
493 guibeep(focus);
494 focus->state->flags &= ~ELVIS_MORE;
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
495 break;
496
497 case RESULT_COMPLETE:
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored Dec 10, 2011
498 focus->state->flags &= ~ELVIS_MORE;
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
499 break;
500
501 case RESULT_MORE:
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored Dec 10, 2011
502 focus->state->flags |= ELVIS_MORE;
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
503 break;
504 }
505 }
506 }
507
508 /* fix the edit bounds */
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored Dec 10, 2011
509 fixbounds(focus);
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
510
511 /* convert ELVIS_ONCE to ELVIS_POP */
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored Dec 10, 2011
512 if (focus->state && (focus->state->flags & ELVIS_ONCE))
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
513 {
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored Dec 10, 2011
514 focus->state->flags |= ELVIS_POP;
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
515 }
516
517 /* if no states are left, then destroy the window */
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored Dec 10, 2011
518 if (!focus->state)
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
519 {
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored Dec 10, 2011
520 (*gui->destroygw)(focus->gw, ElvTrue);
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
521 }
522 }
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored Dec 10, 2011
523
524 return result;
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored Dec 10, 2011
525 }
Something went wrong with that request. Please try again.