2 * Copyright (c) 1992, 1993, 1994
3 * The Regents of the University of California. All rights reserved.
4 * Copyright (c) 1992, 1993, 1994, 1995, 1996
5 * Keith Bostic. All rights reserved.
7 * See the LICENSE file for redistribution information.
13 static const char sccsid[] = "$Id: vi.c,v 10.61 2011/12/21 13:08:30 zy Exp $";
16 #include <sys/types.h>
17 #include <sys/queue.h>
20 #include <bitstring.h>
29 #include "../common/common.h"
33 GC_ERR, GC_ERR_NOFLUSH, GC_EVENT, GC_FATAL, GC_INTERRUPT, GC_OK
37 *v_alias __P((SCR *, VICMD *, VIKEYS const *));
38 static gcret_t v_cmd __P((SCR *, VICMD *, VICMD *, VICMD *, int *, int *));
39 static int v_count __P((SCR *, ARG_CHAR_T, u_long *));
40 static void v_dtoh __P((SCR *));
41 static int v_init __P((SCR *));
42 static gcret_t v_key __P((SCR *, int, EVENT *, u_int32_t));
43 static int v_motion __P((SCR *, VICMD *, VICMD *, int *));
45 #if defined(DEBUG) && defined(COMLOG)
46 static void v_comlog __P((SCR *, VICMD *));
51 * The dot structure can be set by the underlying vi functions,
52 * see v_Put() and v_put().
54 #define DOT (&VIP(sp)->sdot)
55 #define DOTMOTION (&VIP(sp)->sdotmotion)
59 * Main vi command loop.
61 * PUBLIC: int vi __P((SCR **));
69 VICMD cmd = { 0 }, *vp;
71 int comcount, mapped, rval;
73 /* Get the first screen. */
77 /* Point to the command structure. */
80 /* Reset strange attraction. */
81 F_SET(vp, VM_RCM_SET);
83 /* Initialize the vi screen. */
88 (void)sp->gp->scr_rename(sp, sp->frp->name, 1);
90 for (vip = VIP(sp), rval = 0;;) {
91 /* Resolve messages. */
92 if (!MAPPED_KEYS_WAITING(sp) && vs_resolve(sp, NULL, 0))
96 * If not skipping a refresh, return to command mode and
99 if (F_ISSET(vip, VIP_S_REFRESH))
100 F_CLR(vip, VIP_S_REFRESH);
102 sp->showmode = SM_COMMAND;
103 if (vs_refresh(sp, 0))
107 /* Set the new favorite position. */
108 if (F_ISSET(vp, VM_RCM_SET | VM_RCM_SETFNB | VM_RCM_SETNNB)) {
109 F_CLR(vip, VIP_RCM_LAST);
110 (void)vs_column(sp, &sp->rcm);
114 * If not currently in a map, log the cursor position,
115 * and set a flag so that this command can become the
118 if (MAPPED_KEYS_WAITING(sp))
127 * There may be an ex command waiting, and we returned here
128 * only because we exited a screen or file. In this case,
129 * we simply go back into the ex parser.
131 if (EXCMD_RUNNING(gp)) {
132 vp->kp = &vikeys[':'];
136 /* Refresh the command structure. */
137 memset(vp, 0, sizeof(VICMD));
140 * We get a command, which may or may not have an associated
141 * motion. If it does, we get it too, calling its underlying
142 * function to get the resulting mark. We then call the
143 * command setting the cursor to the resulting mark.
146 * Vi historically flushed mapped characters on error, but
147 * entering extra <escape> characters at the beginning of
148 * a map wasn't considered an error -- in fact, users would
149 * put leading <escape> characters in maps to clean up vi
150 * state before the map was interpreted. Beauty!
152 switch (v_cmd(sp, DOT, vp, NULL, &comcount, &mapped)) {
167 /* Check for security setting. */
168 if (F_ISSET(vp->kp, V_SECURE) && O_ISSET(sp, O_SECURE)) {
169 ex_emsg(sp, KEY_NAME(sp, vp->key), EXM_SECURE);
174 * Historical practice: if a dot command gets a new count,
175 * any motion component goes away, i.e. "d3w2." deletes a
178 if (F_ISSET(vp, VC_ISDOT) && comcount)
179 DOTMOTION->count = 1;
181 /* Copy the key flags into the local structure. */
182 F_SET(vp, vp->kp->flags);
184 /* Prepare to set the previous context. */
185 if (F_ISSET(vp, V_ABS | V_ABS_C | V_ABS_L)) {
191 * Set the three cursor locations to the current cursor. The
192 * underlying routines don't bother if the cursor doesn't move.
193 * This also handles line commands (e.g. Y) defaulting to the
196 vp->m_start.lno = vp->m_stop.lno = vp->m_final.lno = sp->lno;
197 vp->m_start.cno = vp->m_stop.cno = vp->m_final.cno = sp->cno;
200 * Do any required motion; v_motion sets the from MARK and the
201 * line mode flag, as well as the VM_RCM flags.
203 if (F_ISSET(vp, V_MOTION) &&
204 v_motion(sp, DOTMOTION, vp, &mapped)) {
211 * If a count is set and the command is line oriented, set the
212 * to MARK here relative to the cursor/from MARK. This is for
213 * commands that take both counts and motions, i.e. "4yy" and
214 * "y%". As there's no way the command can know which the user
215 * did, we have to do it here. (There are commands that are
216 * line oriented and that take counts ("#G", "#H"), for which
217 * this calculation is either completely meaningless or wrong.
218 * Each command must validate the value for itself.
220 if (F_ISSET(vp, VC_C1SET) && F_ISSET(vp, VM_LMODE))
221 vp->m_stop.lno += vp->count - 1;
223 /* Increment the command count. */
226 #if defined(DEBUG) && defined(COMLOG)
229 /* Call the function. */
230 ex_continue: if (vp->kp->func(sp, vp))
234 /* Make sure no function left the temporary space locked. */
235 if (F_ISSET(gp, G_TMP_INUSE)) {
236 F_CLR(gp, G_TMP_INUSE);
238 "232|vi: temporary buffer not released");
242 * If we're exiting this screen, move to the next one, or, if
243 * there aren't any more, return to the main editor loop. The
244 * ordering is careful, don't discard the contents of sp until
247 if (F_ISSET(sp, SC_EXIT | SC_EXIT_FORCE)) {
248 if (file_end(sp, NULL, F_ISSET(sp, SC_EXIT_FORCE)))
250 if (vs_discard(sp, &next))
252 if (next == NULL && vs_swap(sp, &next, NULL))
260 /* Switch screens, change focus. */
263 (void)sp->gp->scr_rename(sp, sp->frp->name, 1);
265 /* Don't trust the cursor. */
266 F_SET(vip, VIP_CUR_INVALID);
272 * Set the dot command structure.
275 * Historically, commands which used mapped keys did not
276 * set the dot command, with the exception of the text
279 if (F_ISSET(vp, V_DOT) && !mapped) {
281 F_SET(DOT, VC_ISDOT);
284 * If a count was supplied for both the command and
285 * its motion, the count was used only for the motion.
286 * Turn the count back on for the dot structure.
288 if (F_ISSET(vp, VC_C1RESET))
289 F_SET(DOT, VC_C1SET);
291 /* VM flags aren't retained. */
292 F_CLR(DOT, VM_COMMASK | VM_RCM_MASK);
296 * Some vi row movements are "attracted" to the last position
297 * set, i.e. the VM_RCM commands are moths to the VM_RCM_SET
298 * commands' candle. If the movement is to the EOL the vi
299 * command handles it. If it's to the beginning, we handle it
302 * Note, some commands (e.g. _, ^) don't set the VM_RCM_SETFNB
303 * flag, but do the work themselves. The reason is that they
304 * have to modify the column in case they're being used as a
305 * motion component. Other similar commands (e.g. +, -) don't
306 * have to modify the column because they are always line mode
307 * operations when used as motions, so the column number isn't
310 * Does this totally violate the screen and editor layering?
311 * You betcha. As they say, if you think you understand it,
314 switch (F_ISSET(vp, VM_RCM_MASK)) {
319 vp->m_final.cno = vs_rcm(sp,
320 vp->m_final.lno, F_ISSET(vip, VIP_RCM_LAST));
323 F_SET(vip, VIP_RCM_LAST);
329 if (nonblank(sp, vp->m_final.lno, &vp->m_final.cno))
336 /* Update the cursor. */
337 sp->lno = vp->m_final.lno;
338 sp->cno = vp->m_final.cno;
341 * Set the absolute mark -- set even if a tags or similar
342 * command, since the tag may be moving to the same file.
344 if ((F_ISSET(vp, V_ABS) ||
345 (F_ISSET(vp, V_ABS_L) && sp->lno != abs.lno) ||
346 (F_ISSET(vp, V_ABS_C) &&
347 (sp->lno != abs.lno || sp->cno != abs.cno))) &&
348 mark_set(sp, ABSMARK1, &abs, 1))
352 err: if (v_event_flush(sp, CH_MAPPED))
354 "110|Vi command failed: mapped keys discarded");
358 * Check and clear interrupts. There's an obvious race, but
359 * it's not worth fixing.
361 gc_err_noflush: if (INTERRUPTED(sp)) {
362 intr: CLR_INTERRUPT(sp);
363 if (v_event_flush(sp, CH_MAPPED))
365 "231|Interrupted: mapped keys discarded");
367 msgq(sp, M_ERR, "236|Interrupted");
370 /* If the last command switched screens, update. */
371 if (F_ISSET(sp, SC_SSWITCH)) {
372 F_CLR(sp, SC_SSWITCH);
375 * If the current screen is still displayed, it will
376 * need a new status line.
378 F_SET(sp, SC_STATUS);
380 /* Switch screens, change focus. */
383 (void)sp->gp->scr_rename(sp, sp->frp->name, 1);
385 /* Don't trust the cursor. */
386 F_SET(vip, VIP_CUR_INVALID);
388 /* Refresh so we can display messages. */
389 if (vs_refresh(sp, 1))
393 /* If the last command switched files, change focus. */
394 if (F_ISSET(sp, SC_FSWITCH)) {
395 F_CLR(sp, SC_FSWITCH);
396 (void)sp->gp->scr_rename(sp, sp->frp->name, 1);
399 /* If leaving vi, return to the main editor loop. */
400 if (F_ISSET(gp, G_SRESTART) || F_ISSET(sp, SC_EX)) {
403 gp->scr_discard(sp, NULL);
412 #define KEY(key, ec_flags) { \
413 if ((gcret = v_key(sp, 0, &ev, ec_flags)) != GC_OK) \
415 if (ev.e_value == K_ESCAPE) \
417 if (F_ISSET(&ev.e_ch, CH_MAPPED)) \
423 * The O_TILDEOP option makes the ~ command take a motion instead
424 * of a straight count. This is the replacement structure we use
425 * instead of the one currently in the VIKEYS table.
428 * This should probably be deleted -- it's not all that useful, and
429 * we get help messages wrong.
431 VIKEYS const tmotion = {
432 v_mulcase, V_CNT|V_DOT|V_MOTION|VM_RCM_SET,
433 "[count]~[count]motion",
434 " ~ change case to motion"
440 * The command structure for vi is less complex than ex (and don't think
441 * I'm not grateful!) The command syntax is:
443 * [count] [buffer] [count] key [[motion] | [buffer] [character]]
445 * and there are several special cases. The motion value is itself a vi
446 * command, with the syntax:
448 * [count] key [character]
455 VICMD *ismotion, /* Previous key if getting motion component. */
459 enum { COMMANDMODE, ISPARTIAL, NOTPARTIAL } cpart;
470 * <escape> cancels partial commands, i.e. a command where at least
471 * one non-numeric character has been entered. Otherwise, it beeps
475 * POSIX 1003.2-1992 explicitly disallows cancelling commands where
476 * all that's been entered is a number, requiring that the terminal
479 cpart = ismotion == NULL ? COMMANDMODE : ISPARTIAL;
481 v_key(sp, ismotion == NULL, &ev, EC_MAPCOMMAND)) != GC_OK) {
482 if (gcret == GC_EVENT)
486 if (ev.e_value == K_ESCAPE)
488 if (F_ISSET(&ev.e_ch, CH_MAPPED))
492 if (ismotion == NULL)
495 /* Pick up an optional buffer. */
498 if (ismotion != NULL) {
499 v_emsg(sp, NULL, VIM_COMBUF);
503 F_SET(vp, VC_BUFFER);
505 KEY(key, EC_MAPCOMMAND);
509 * Pick up an optional count, where a leading 0 is not a count,
512 if (ISDIGIT(key) && key != '0') {
513 if (v_count(sp, key, &vp->count))
518 KEY(key, EC_MAPCOMMAND);
522 /* Pick up optional buffer. */
525 if (F_ISSET(vp, VC_BUFFER)) {
526 msgq(sp, M_ERR, "234|Only one buffer may be specified");
529 if (ismotion != NULL) {
530 v_emsg(sp, NULL, VIM_COMBUF);
534 F_SET(vp, VC_BUFFER);
536 KEY(key, EC_MAPCOMMAND);
539 /* Check for an OOB command key. */
541 if (key > MAXVIKEY) {
542 v_emsg(sp, KEY_NAME(sp, key), VIM_NOCOM);
545 kp = &vikeys[vp->key = key];
549 * Historically, D accepted and then ignored a count. Match it.
551 if (vp->key == 'D' && F_ISSET(vp, VC_C1SET)) {
557 /* Check for command aliases. */
558 if (kp->func == NULL && (kp = v_alias(sp, vp, kp)) == NULL)
561 /* The tildeop option makes the ~ command take a motion. */
562 if (key == '~' && O_ISSET(sp, O_TILDEOP))
568 * Find the command. The only legal command with no underlying
569 * function is dot. It's historic practice that <escape> doesn't
570 * just erase the preceding number, it beeps the terminal as well.
571 * It's a common problem, so just beep the terminal unless verbose
574 if (kp->func == NULL) {
576 v_emsg(sp, KEY_NAME(sp, key),
577 ev.e_value == K_ESCAPE ? VIM_NOCOM_B : VIM_NOCOM);
581 /* If called for a motion command, stop now. */
587 * If a '.' is immediately entered after an undo command, we
588 * replay the log instead of redoing the last command. This
589 * is necessary because 'u' can't set the dot command -- see
590 * vi/v_undo.c:v_undo for details.
592 if (VIP(sp)->u_ccnt == sp->ccnt) {
593 vp->kp = &vikeys['u'];
598 /* Otherwise, a repeatable command must have been executed. */
599 if (!F_ISSET(dp, VC_ISDOT)) {
600 msgq(sp, M_ERR, "208|No command to repeat");
604 /* Set new count/buffer, if any, and return. */
605 if (F_ISSET(vp, VC_C1SET)) {
607 dp->count = vp->count;
609 if (F_ISSET(vp, VC_BUFFER))
610 dp->buffer = vp->buffer;
616 /* Set the flags based on the command flags. */
619 /* Check for illegal count. */
620 if (F_ISSET(vp, VC_C1SET) && !LF_ISSET(V_CNT))
623 /* Illegal motion command. */
624 if (ismotion == NULL) {
625 /* Illegal buffer. */
626 if (!LF_ISSET(V_OBUF) && F_ISSET(vp, VC_BUFFER))
629 /* Required buffer. */
630 if (LF_ISSET(V_RBUF)) {
632 F_SET(vp, VC_BUFFER);
637 * Special case: '[', ']' and 'Z' commands. Doesn't the fact that
638 * the *single* characters don't mean anything but the *doubled*
639 * characters do, just frost your shorts?
641 if (vp->key == '[' || vp->key == ']' || vp->key == 'Z') {
643 * Historically, half entered [[, ]] or Z commands weren't
644 * cancelled by <escape>, the terminal was beeped instead.
645 * POSIX.2-1992 probably didn't notice, and requires that
646 * they be cancelled instead of beeping. Seems fine to me.
648 * Don't set the EC_MAPCOMMAND flag, apparently ] is a popular
649 * vi meta-character, and we don't want the user to wait while
650 * we time out a possible mapping. This *appears* to match
651 * historic vi practice, but with mapping characters, You Just
656 if (vp->key != key) {
657 usage: if (ismotion == NULL)
659 else if (ismotion->key == '~' && O_ISSET(sp, O_TILDEOP))
662 s = vikeys[ismotion->key].usage;
663 v_emsg(sp, s, VIM_USAGE);
667 /* Special case: 'z' command. */
668 if (vp->key == 'z') {
669 KEY(vp->character, 0);
670 if (ISDIGIT(vp->character)) {
671 if (v_count(sp, vp->character, &vp->count2))
674 KEY(vp->character, 0);
679 * Commands that have motion components can be doubled to imply the
682 if (ismotion != NULL && ismotion->key != key && !LF_ISSET(V_MOVE)) {
683 msgq(sp, M_ERR, "210|%s may not be used as a motion command",
688 /* Pick up required trailing character. */
689 if (LF_ISSET(V_CHAR))
690 KEY(vp->character, 0);
692 /* Get any associated cursor word. */
693 if (F_ISSET(kp, V_KEYW) && v_curword(sp))
698 esc: switch (cpart) {
700 msgq(sp, M_BERR, "211|Already in command mode");
701 return (GC_ERR_NOFLUSH);
705 (void)sp->gp->scr_bell(sp);
714 * Get resulting motion mark.
727 int tilde_reset, notused;
730 * If '.' command, use the dot motion, else get the motion command.
731 * Clear any line motion flags, the subsequent motion isn't always
732 * the same, i.e. "/aaa" may or may not be a line motion.
734 if (F_ISSET(vp, VC_ISDOT)) {
736 F_SET(&motion, VC_ISDOT);
737 F_CLR(&motion, VM_COMMASK);
739 memset(&motion, 0, sizeof(VICMD));
740 if (v_cmd(sp, NULL, &motion, vp, ¬used, mappedp) != GC_OK)
745 * A count may be provided both to the command and to the motion, in
746 * which case the count is multiplicative. For example, "3y4y" is the
747 * same as "12yy". This count is provided to the motion command and
748 * not to the regular function.
750 cnt = motion.count = F_ISSET(&motion, VC_C1SET) ? motion.count : 1;
751 if (F_ISSET(vp, VC_C1SET)) {
752 motion.count *= vp->count;
753 F_SET(&motion, VC_C1SET);
756 * Set flags to restore the original values of the command
757 * structure so dot commands can change the count values,
758 * e.g. "2dw" "3." deletes a total of five words.
761 F_SET(vp, VC_C1RESET);
765 * Some commands can be repeated to indicate the current line. In
766 * this case, or if the command is a "line command", set the flags
767 * appropriately. If not a doubled command, run the function to get
768 * the resulting mark.
770 if (vp->key == motion.key) {
771 F_SET(vp, VM_LDOUBLE | VM_LMODE);
773 /* Set the origin of the command. */
774 vp->m_start.lno = sp->lno;
778 * Set the end of the command.
780 * If the current line is missing, i.e. the file is empty,
781 * historic vi permitted a "cc" or "!!" command to insert
784 vp->m_stop.lno = sp->lno + motion.count - 1;
785 if (db_get(sp, vp->m_stop.lno, 0, NULL, &len)) {
786 if (vp->m_stop.lno != 1 ||
787 (vp->key != 'c' && vp->key != '!')) {
788 v_emsg(sp, NULL, VIM_EMPTY);
793 vp->m_stop.cno = len ? len - 1 : 0;
796 * Motion commands change the underlying movement (*snarl*).
797 * For example, "l" is illegal at the end of a line, but "dl"
798 * is not. Set flags so the function knows the situation.
804 * Use yank instead of creating a new motion command, it's a
805 * lot easier for now.
807 if (vp->kp == &tmotion) {
809 vp->kp = &vikeys['y'];
814 * Copy the key flags into the local structure, except for the
815 * RCM flags -- the motion command will set the RCM flags in
816 * the vp structure if necessary. This means that the motion
817 * command is expected to determine where the cursor ends up!
818 * However, we save off the current RCM mask and restore it if
819 * it no RCM flags are set by the motion command, with a small
822 * We replace the VM_RCM_SET flag with the VM_RCM flag. This
823 * is so that cursor movement doesn't set the relative position
824 * unless the motion command explicitly specified it. This
825 * appears to match historic practice, but I've never been able
826 * to develop a hard-and-fast rule.
828 flags = F_ISSET(vp, VM_RCM_MASK);
829 if (LF_ISSET(VM_RCM_SET)) {
833 F_CLR(vp, VM_RCM_MASK);
834 F_SET(&motion, motion.kp->flags & ~VM_RCM_MASK);
837 * Set the three cursor locations to the current cursor. This
838 * permits commands like 'j' and 'k', that are line oriented
839 * motions and have special cursor suck semantics when they are
840 * used as standalone commands, to ignore column positioning.
843 motion.m_stop.lno = motion.m_start.lno = sp->lno;
845 motion.m_stop.cno = motion.m_start.cno = sp->cno;
847 /* Run the function. */
848 if ((motion.kp->func)(sp, &motion))
852 * If the current line is missing, i.e. the file is empty,
853 * historic vi allowed "c<motion>" or "!<motion>" to insert
854 * text. Otherwise fail -- most motion commands will have
855 * already failed, but some, e.g. G, succeed in empty files.
857 if (!db_exist(sp, vp->m_stop.lno)) {
858 if (vp->m_stop.lno != 1 ||
859 (vp->key != 'c' && vp->key != '!')) {
860 v_emsg(sp, NULL, VIM_EMPTY);
874 * Copy cut buffer, line mode and cursor position information
875 * from the motion command structure, i.e. anything that the
876 * motion command can set for us. The commands can flag the
877 * movement as a line motion (see v_sentence) as well as set
878 * the VM_RCM_* flags explicitly.
880 F_SET(vp, F_ISSET(&motion, VM_COMMASK | VM_RCM_MASK));
883 * If the motion command set no relative motion flags, use
884 * the (slightly) modified previous values.
886 if (!F_ISSET(vp, VM_RCM_MASK))
890 * Commands can change behaviors based on the motion command
891 * used, for example, the ! command repeated the last bang
892 * command if N or n was used as the motion.
897 * Motion commands can reset all of the cursor information.
898 * If the motion is in the reverse direction, switch the
899 * from and to MARK's so that it's in a forward direction.
900 * Motions are from the from MARK to the to MARK (inclusive).
902 if (motion.m_start.lno > motion.m_stop.lno ||
903 (motion.m_start.lno == motion.m_stop.lno &&
904 motion.m_start.cno > motion.m_stop.cno)) {
905 vp->m_start = motion.m_stop;
906 vp->m_stop = motion.m_start;
908 vp->m_start = motion.m_start;
909 vp->m_stop = motion.m_stop;
911 vp->m_final = motion.m_final;
915 * If the command sets dot, save the motion structure. The motion
916 * count was changed above and needs to be reset, that's why this
917 * is done here, and not in the calling routine.
919 if (F_ISSET(vp->kp, V_DOT)) {
928 * Initialize the vi screen.
939 /* Switch into vi. */
940 if (gp->scr_screen(sp, SC_VI))
942 (void)gp->scr_attr(sp, SA_ALTERNATE, 1);
944 F_CLR(sp, SC_EX | SC_SCR_EX);
948 * Initialize screen values.
950 * Small windows: see vs_refresh(), section 6a.
953 * t_minrows is the minimum rows to display
954 * t_maxrows is the maximum rows to display (rows - 1)
955 * t_rows is the rows currently being displayed
957 sp->rows = vip->srows = O_VAL(sp, O_LINES);
958 sp->cols = O_VAL(sp, O_COLUMNS);
959 sp->t_rows = sp->t_minrows = O_VAL(sp, O_WINDOW);
961 if (sp->t_rows > sp->rows - 1) {
962 sp->t_minrows = sp->t_rows = sp->rows - 1;
964 "214|Windows option value is too large, max is %u",
967 sp->t_maxrows = sp->rows - 1;
970 sp->roff = sp->coff = 0;
972 /* Create a screen map. */
973 CALLOC_RET(sp, HMAP, SMAP *, SIZE_HMAP(sp), sizeof(SMAP));
974 TMAP = HMAP + (sp->t_rows - 1);
980 * Fill the screen map from scratch -- try and center the line. That
981 * way if we're starting with a file we've seen before, we'll put the
982 * line in the middle, otherwise, it won't work and we'll end up with
983 * the line at the top.
985 F_SET(sp, SC_SCR_REFORMAT | SC_SCR_CENTER);
987 /* Invalidate the cursor. */
988 F_SET(vip, VIP_CUR_INVALID);
990 /* Paint the screen image from scratch. */
991 F_SET(vip, VIP_N_EX_PAINT);
998 * Move all but the current screen to the hidden queue.
1007 /* Move all screens to the hidden queue, tossing screen maps. */
1008 for (hidden = 0, gp = sp->gp;
1009 (tsp = TAILQ_FIRST(gp->dq)) != NULL; ++hidden) {
1010 if (_HMAP(tsp) != NULL) {
1014 TAILQ_REMOVE(gp->dq, tsp, q);
1015 TAILQ_INSERT_TAIL(gp->hq, tsp, q);
1016 /* XXXX Change if hidden screens per window */
1017 gp->scr_discard(tsp, NULL);
1020 /* Move current screen back to the display queue. */
1021 TAILQ_REMOVE(gp->hq, sp, q);
1022 TAILQ_INSERT_TAIL(gp->dq, sp, q);
1026 "319|%d screens backgrounded; use :display to list them",
1032 * Get the word (tagstring, actually) the cursor is on.
1034 * PUBLIC: int v_curword __P((SCR *));
1040 size_t beg, end, len;
1044 if (db_get(sp, sp->lno, DBG_FATAL, &p, &len))
1049 * Historically, tag commands skipped over any leading whitespace
1050 * characters. Make this true in general when using cursor words.
1051 * If movement, getting a cursor word implies moving the cursor to
1052 * its beginning. Refresh now.
1055 * Find the beginning/end of the keyword. Keywords are currently
1056 * used for cursor-word searching and for tags. Historical vi
1057 * only used the word in a tag search from the cursor to the end
1058 * of the word, i.e. if the cursor was on the 'b' in " abc ", the
1059 * tag was "bc". For consistency, we make cursor word searches
1060 * follow the same rule.
1063 beg = sp->cno; beg < len && ISSPACE(p[beg]); moved = 1, ++beg);
1065 msgq(sp, M_BERR, "212|Cursor not in a word");
1070 (void)vs_refresh(sp, 0);
1074 * Find the end of the word.
1077 * Historically, vi accepted any non-blank as initial character
1078 * when building up a tagstring. Required by IEEE 1003.1-2001.
1080 for (end = beg; ++end < len && inword(p[end]););
1083 vip->klen = len = (end - beg);
1084 BINC_RETW(sp, vip->keyw, vip->keywlen, len+1);
1085 MEMMOVE(vip->keyw, p + beg, len);
1086 vip->keyw[len] = '\0'; /* XXX */
1092 * Check for a command alias.
1094 static VIKEYS const *
1103 case 'C': /* C -> c$ */
1107 case 'D': /* D -> d$ */
1111 case 'S': /* S -> c_ */
1115 case 'Y': /* Y -> y_ */
1122 return (v_event_push(sp,
1123 NULL, &push, 1, CH_NOMAP | CH_QUOTED) ? NULL : &vikeys[vp->key]);
1128 * Return the next count.
1144 * Assume that overflow results in a smaller number.
1146 tc = count * 10 + ev.e_c - '0';
1148 /* Toss to the next non-digit. */
1150 if (v_key(sp, 0, &ev,
1151 EC_MAPCOMMAND | EC_MAPNODIGIT) != GC_OK)
1153 } while (ISDIGIT(ev.e_c));
1155 "235|Number larger than %lu", ULONG_MAX);
1159 if (v_key(sp, 0, &ev, EC_MAPCOMMAND | EC_MAPNODIGIT) != GC_OK)
1161 } while (ISDIGIT(ev.e_c));
1168 * Return the next event.
1180 if (v_event_get(sp, evp, 0, ec_flags | quote))
1184 switch (evp->e_event) {
1188 * Historically, ^V was ignored in the command stream,
1189 * although it had a useful side-effect of interrupting
1190 * mappings. Adding a quoting bit to the call probably
1191 * extends historic practice, but it feels right.
1193 if (evp->e_value == K_VLNEXT) {
1204 * Historically, vi beeped on command level interrupts.
1206 * Historically, vi exited to ex mode if no file was
1207 * named on the command line, and two interrupts were
1208 * generated in a row. (Just figured you might want
1211 (void)sp->gp->scr_bell(sp);
1212 return (GC_INTERRUPT);
1214 if (vs_repaint(sp, evp))
1221 v_event_err(sp, evp);
1228 #if defined(DEBUG) && defined(COMLOG)
1231 * Log the contents of the command structure.
1238 TRACE(sp, "vcmd: "WC, vp->key);
1239 if (F_ISSET(vp, VC_BUFFER))
1240 TRACE(sp, " buffer: "WC, vp->buffer);
1241 if (F_ISSET(vp, VC_C1SET))
1242 TRACE(sp, " c1: %lu", vp->count);
1243 if (F_ISSET(vp, VC_C2SET))
1244 TRACE(sp, " c2: %lu", vp->count2);
1245 TRACE(sp, " flags: 0x%x\n", vp->flags);