1 /* $NetBSD: vi.c,v 1.6 2014/01/26 21:43:45 christos Exp $ */
3 * Copyright (c) 1992, 1993, 1994
4 * The Regents of the University of California. All rights reserved.
5 * Copyright (c) 1992, 1993, 1994, 1995, 1996
6 * Keith Bostic. All rights reserved.
8 * See the LICENSE file for redistribution information.
13 #include <sys/cdefs.h>
16 static const char sccsid
[] = "Id: vi.c,v 10.73 2002/04/11 19:49:30 skimo Exp (Berkeley) Date: 2002/04/11 19:49:30 ";
19 __RCSID("$NetBSD: vi.c,v 1.6 2014/01/26 21:43:45 christos Exp $");
22 #include <sys/types.h>
23 #include <sys/queue.h>
26 #include <bitstring.h>
35 #include "../common/common.h"
39 GC_ERR
, GC_ERR_NOFLUSH
, GC_EVENT
, GC_FATAL
, GC_INTERRUPT
, GC_OK
43 *v_alias
__P((SCR
*, VICMD
*, VIKEYS
const *));
44 static gcret_t v_cmd
__P((SCR
*, VICMD
*, VICMD
*, VICMD
*, int *, int *));
45 static int v_count
__P((SCR
*, VICMD
*, ARG_CHAR_T
, u_long
*));
46 static void v_dtoh
__P((SCR
*));
47 static int v_init
__P((SCR
*));
48 static gcret_t v_key
__P((SCR
*, VICMD
*, int, u_int32_t
));
49 static int v_motion
__P((SCR
*, VICMD
*, VICMD
*, int *));
51 #if defined(DEBUG) && defined(COMLOG)
52 static void v_comlog
__P((SCR
*, VICMD
*));
57 * The dot structure can be set by the underlying vi functions,
58 * see v_Put() and v_put().
60 #define DOT (&VIP(sp)->sdot)
61 #define DOTMOTION (&VIP(sp)->sdotmotion)
65 * Main vi command loop.
67 * PUBLIC: int vi __P((SCR **));
78 int comcount
, mapped
, rval
;
80 /* Get the first screen. */
85 /* Initialize the command structure. */
87 memset(vp
, 0, sizeof(VICMD
));
89 /* Reset strange attraction. */
90 F_SET(vp
, VM_RCM_SET
);
92 /* Initialize the vi screen. */
97 (void)sp
->gp
->scr_rename(sp
, sp
->frp
->name
, 1);
99 for (vip
= VIP(sp
), rval
= 0;;) {
100 /* Resolve messages. */
101 if (!MAPPED_KEYS_WAITING(sp
) && vs_resolve(sp
, NULL
, 0))
105 * If not skipping a refresh, return to command mode and
106 * refresh the screen.
108 if (F_ISSET(vip
, VIP_S_REFRESH
))
109 F_CLR(vip
, VIP_S_REFRESH
);
111 sp
->showmode
= SM_COMMAND
;
112 if (vs_refresh(sp
, 0))
116 /* Set the new favorite position. */
117 if (F_ISSET(vp
, VM_RCM_SET
| VM_RCM_SETFNB
| VM_RCM_SETNNB
)) {
118 F_CLR(vip
, VIP_RCM_LAST
);
119 (void)vs_column(sp
, &sp
->rcm
);
123 * If not currently in a map, log the cursor position,
124 * and set a flag so that this command can become the
127 if (MAPPED_KEYS_WAITING(sp
))
136 * There may be an ex command waiting, and we returned here
137 * only because we exited a screen or file. In this case,
138 * we simply go back into the ex parser.
140 if (EXCMD_RUNNING(wp
)) {
141 vp
->kp
= &vikeys
[':'];
145 /* Refresh the command structure. */
146 memset(vp
, 0, sizeof(VICMD
));
149 * We get a command, which may or may not have an associated
150 * motion. If it does, we get it too, calling its underlying
151 * function to get the resulting mark. We then call the
152 * command setting the cursor to the resulting mark.
155 * Vi historically flushed mapped characters on error, but
156 * entering extra <escape> characters at the beginning of
157 * a map wasn't considered an error -- in fact, users would
158 * put leading <escape> characters in maps to clean up vi
159 * state before the map was interpreted. Beauty!
161 switch (v_cmd(sp
, DOT
, vp
, NULL
, &comcount
, &mapped
)) {
175 /* Check for security setting. */
176 if (F_ISSET(vp
->kp
, V_SECURE
) && O_ISSET(sp
, O_SECURE
)) {
177 ex_emsg(sp
, (const char *)KEY_NAME(sp
, vp
->key
),
183 * Historical practice: if a dot command gets a new count,
184 * any motion component goes away, i.e. "d3w2." deletes a
187 if (F_ISSET(vp
, VC_ISDOT
) && comcount
)
188 DOTMOTION
->count
= 1;
190 /* Copy the key flags into the local structure. */
191 F_SET(vp
, vp
->kp
->flags
);
193 /* Prepare to set the previous context. */
194 if (F_ISSET(vp
, V_ABS
| V_ABS_C
| V_ABS_L
)) {
200 * Set the three cursor locations to the current cursor. The
201 * underlying routines don't bother if the cursor doesn't move.
202 * This also handles line commands (e.g. Y) defaulting to the
205 vp
->m_start
.lno
= vp
->m_stop
.lno
= vp
->m_final
.lno
= sp
->lno
;
206 vp
->m_start
.cno
= vp
->m_stop
.cno
= vp
->m_final
.cno
= sp
->cno
;
209 * Do any required motion; v_motion sets the from MARK and the
210 * line mode flag, as well as the VM_RCM flags.
212 if (F_ISSET(vp
, V_MOTION
) &&
213 v_motion(sp
, DOTMOTION
, vp
, &mapped
)) {
220 * If a count is set and the command is line oriented, set the
221 * to MARK here relative to the cursor/from MARK. This is for
222 * commands that take both counts and motions, i.e. "4yy" and
223 * "y%". As there's no way the command can know which the user
224 * did, we have to do it here. (There are commands that are
225 * line oriented and that take counts ("#G", "#H"), for which
226 * this calculation is either completely meaningless or wrong.
227 * Each command must validate the value for itself.
229 if (F_ISSET(vp
, VC_C1SET
) && F_ISSET(vp
, VM_LMODE
))
230 vp
->m_stop
.lno
+= vp
->count
- 1;
232 /* Increment the command count. */
235 #if defined(DEBUG) && defined(COMLOG)
238 /* Call the function. */
239 ex_continue
: if (vp
->kp
->func(sp
, vp
))
242 /* Make sure no function left the temporary space locked. */
243 if (F_ISSET(wp
, W_TMP_INUSE
)) {
244 F_CLR(wp
, W_TMP_INUSE
);
246 "232|vi: temporary buffer not released");
250 * If we're exiting this screen, move to the next one, or, if
251 * there aren't any more, return to the main editor loop. The
252 * ordering is careful, don't discard the contents of sp until
255 if (F_ISSET(sp
, SC_EXIT
| SC_EXIT_FORCE
)) {
256 if (file_end(sp
, NULL
, F_ISSET(sp
, SC_EXIT_FORCE
)))
258 if (vs_discard(sp
, &next
))
260 if (next
== NULL
&& vs_swap(sp
, &next
, NULL
))
268 /* Switch screens, change focus. */
271 (void)sp
->gp
->scr_rename(sp
, sp
->frp
->name
, 1);
273 /* Don't trust the cursor. */
274 F_SET(vip
, VIP_CUR_INVALID
);
280 * Set the dot command structure.
283 * Historically, commands which used mapped keys did not
284 * set the dot command, with the exception of the text
287 if (F_ISSET(vp
, V_DOT
) && !mapped
) {
289 F_SET(DOT
, VC_ISDOT
);
292 * If a count was supplied for both the command and
293 * its motion, the count was used only for the motion.
294 * Turn the count back on for the dot structure.
296 if (F_ISSET(vp
, VC_C1RESET
))
297 F_SET(DOT
, VC_C1SET
);
299 /* VM flags aren't retained. */
300 F_CLR(DOT
, VM_COMMASK
| VM_RCM_MASK
);
304 * Some vi row movements are "attracted" to the last position
305 * set, i.e. the VM_RCM commands are moths to the VM_RCM_SET
306 * commands' candle. If the movement is to the EOL the vi
307 * command handles it. If it's to the beginning, we handle it
310 * Note, some commands (e.g. _, ^) don't set the VM_RCM_SETFNB
311 * flag, but do the work themselves. The reason is that they
312 * have to modify the column in case they're being used as a
313 * motion component. Other similar commands (e.g. +, -) don't
314 * have to modify the column because they are always line mode
315 * operations when used as motions, so the column number isn't
318 * Does this totally violate the screen and editor layering?
319 * You betcha. As they say, if you think you understand it,
322 switch (F_ISSET(vp
, VM_RCM_MASK
)) {
327 vp
->m_final
.cno
= vs_rcm(sp
,
328 vp
->m_final
.lno
, F_ISSET(vip
, VIP_RCM_LAST
));
331 F_SET(vip
, VIP_RCM_LAST
);
337 if (nonblank(sp
, vp
->m_final
.lno
, &vp
->m_final
.cno
))
344 /* Update the cursor. */
345 sp
->lno
= vp
->m_final
.lno
;
346 sp
->cno
= vp
->m_final
.cno
;
349 * Set the absolute mark -- set even if a tags or similar
350 * command, since the tag may be moving to the same file.
352 if ((F_ISSET(vp
, V_ABS
) ||
353 (F_ISSET(vp
, V_ABS_L
) && sp
->lno
!= abst
.lno
) ||
354 (F_ISSET(vp
, V_ABS_C
) &&
355 (sp
->lno
!= abst
.lno
|| sp
->cno
!= abst
.cno
))) &&
356 mark_set(sp
, ABSMARK1
, &abst
, 1))
360 err
: if (v_event_flush(sp
, CH_MAPPED
))
362 "110|Vi command failed: mapped keys discarded");
366 * Check and clear interrupts. There's an obvious race, but
367 * it's not worth fixing.
369 gc_err_noflush
: if (INTERRUPTED(sp
)) {
370 intr
: CLR_INTERRUPT(sp
);
371 if (v_event_flush(sp
, CH_MAPPED
))
373 "231|Interrupted: mapped keys discarded");
375 msgq(sp
, M_ERR
, "236|Interrupted");
378 /* If the last command switched screens, update. */
379 if (F_ISSET(sp
, SC_SSWITCH
)) {
380 F_CLR(sp
, SC_SSWITCH
);
383 * If the current screen is still displayed, it will
384 * need a new status line.
386 F_SET(sp
, SC_STATUS
);
388 /* Switch screens, change focus. */
391 (void)sp
->gp
->scr_rename(sp
, sp
->frp
->name
, 1);
393 /* Don't trust the cursor. */
394 F_SET(vip
, VIP_CUR_INVALID
);
396 /* Refresh so we can display messages. */
397 if (vs_refresh(sp
, 1))
401 /* If the last command switched files, change focus. */
402 if (F_ISSET(sp
, SC_FSWITCH
)) {
403 F_CLR(sp
, SC_FSWITCH
);
404 (void)sp
->gp
->scr_rename(sp
, sp
->frp
->name
, 1);
407 /* If leaving vi, return to the main editor loop. */
408 if (F_ISSET(gp
, G_SRESTART
) || F_ISSET(sp
, SC_EX
)) {
411 gp
->scr_discard(sp
, NULL
);
420 #define KEY(key, ec_flags) { \
421 if ((gcret = v_key(sp, vp, 0, ec_flags)) != GC_OK) \
423 if (vp->ev.e_value == K_ESCAPE) \
425 if (FL_ISSET(vp->ev.e_flags, CH_MAPPED)) \
431 * The O_TILDEOP option makes the ~ command take a motion instead
432 * of a straight count. This is the replacement structure we use
433 * instead of the one currently in the VIKEYS table.
436 * This should probably be deleted -- it's not all that useful, and
437 * we get help messages wrong.
439 VIKEYS
const tmotion
= {
440 v_mulcase
, V_CNT
|V_DOT
|V_MOTION
|VM_RCM_SET
,
441 "[count]~[count]motion",
442 " ~ change case to motion"
450 v_cmd(SCR
*sp
, VICMD
*dp
, VICMD
*vp
, VICMD
*ismotion
, int *comcountp
, int *mappedp
)
453 /* Previous key if getting motion component. */
456 enum { COMMANDMODE
, ISPARTIAL
, NOTPARTIAL
} cpart
;
464 * Get an event command or a key. Event commands are simple, and
465 * don't have any additional information.
467 cpart
= ismotion
== NULL
? COMMANDMODE
: ISPARTIAL
;
468 gcret
= v_key(sp
, vp
, 1, EC_MAPCOMMAND
);
469 if (gcret
!= GC_OK
) {
470 if (gcret
!= GC_EVENT
)
474 if (ismotion
!= NULL
&& !F_ISSET(vp
->kp
, V_MOVE
))
475 v_event_err(sp
, &vp
->ev
);
480 * Keys are not simple. (Although vi's command structure less complex
481 * than ex (and don't think I'm not grateful!) The command syntax is:
483 * [count] [buffer] [count] key [[motion] | [buffer] [character]]
485 * and there are, of course, several special cases. The motion value
486 * is itself a vi command, with the syntax:
488 * [count] key [character]
490 * <escape> cancels partial commands, i.e. a command where at least
491 * one non-numeric character has been entered. Otherwise, it beeps
495 * POSIX 1003.2-1992 explicitly disallows cancelling commands where
496 * all that's been entered is a number, requiring that the terminal
499 if (vp
->ev
.e_value
== K_ESCAPE
)
503 * Commands that are mapped are treated differently (e.g., they
504 * don't set the dot command. Pass that information back.
506 if (FL_ISSET(vp
->ev
.e_flags
, CH_MAPPED
))
510 if (ismotion
== NULL
)
513 /* Pick up an optional buffer. */
516 if (ismotion
!= NULL
) {
517 v_emsg(sp
, NULL
, VIM_COMBUF
);
521 F_SET(vp
, VC_BUFFER
);
523 KEY(key
, EC_MAPCOMMAND
);
527 * Pick up an optional count, where a leading 0 isn't a count, it's
528 * a command. When a count is specified, the dot command behaves
529 * differently, pass the information back.
531 if (ISDIGIT(key
) && key
!= '0') {
532 if (v_count(sp
, vp
, key
, &vp
->count
))
538 KEY(key
, EC_MAPCOMMAND
);
542 /* Pick up optional buffer. */
545 if (F_ISSET(vp
, VC_BUFFER
)) {
546 msgq(sp
, M_ERR
, "234|Only one buffer may be specified");
549 if (ismotion
!= NULL
) {
550 v_emsg(sp
, NULL
, VIM_COMBUF
);
554 F_SET(vp
, VC_BUFFER
);
556 KEY(key
, EC_MAPCOMMAND
);
559 /* Check for an OOB command key. */
561 if (key
> MAXVIKEY
) {
562 v_emsg(sp
, (const char *)KEY_NAME(sp
, key
), VIM_NOCOM
);
565 kp
= &vikeys
[vp
->key
= key
];
569 * Historically, D accepted and then ignored a count. Match it.
571 if (vp
->key
== 'D' && F_ISSET(vp
, VC_C1SET
)) {
578 * There are several commands that we implement as aliases, both
579 * to match historic practice and to ensure consistency. Check
580 * for command aliases.
582 if (kp
->func
== NULL
&& (kp
= v_alias(sp
, vp
, kp
)) == NULL
)
585 /* The tildeop option makes the ~ command take a motion. */
586 if (key
== '~' && O_ISSET(sp
, O_TILDEOP
))
592 * Find the command. The only legal command with no underlying
593 * function is dot. It's historic practice that <escape> doesn't
594 * just erase the preceding number, it beeps the terminal as well.
595 * It's a common problem, so just beep the terminal unless verbose
598 if (kp
->func
== NULL
) {
600 v_emsg(sp
, (const char *)KEY_NAME(sp
, key
),
601 vp
->ev
.e_value
== K_ESCAPE
?
602 VIM_NOCOM_B
: VIM_NOCOM
);
606 /* If called for a motion command, stop now. */
612 * If a '.' is immediately entered after an undo command, we
613 * replay the log instead of redoing the last command. This
614 * is necessary because 'u' can't set the dot command -- see
615 * vi/v_undo.c:v_undo for details.
617 if (VIP(sp
)->u_ccnt
== sp
->ccnt
) {
618 vp
->kp
= &vikeys
['u'];
623 /* Otherwise, a repeatable command must have been executed. */
624 if (!F_ISSET(dp
, VC_ISDOT
)) {
625 msgq(sp
, M_ERR
, "208|No command to repeat");
629 /* Set new count/buffer, if any, and return. */
630 if (F_ISSET(vp
, VC_C1SET
)) {
632 dp
->count
= vp
->count
;
634 if (F_ISSET(vp
, VC_BUFFER
))
635 dp
->buffer
= vp
->buffer
;
641 /* Set the flags based on the command flags. */
644 /* Check for illegal count. */
645 if (F_ISSET(vp
, VC_C1SET
) && !LF_ISSET(V_CNT
))
648 /* Illegal motion command. */
649 if (ismotion
== NULL
) {
650 /* Illegal buffer. */
651 if (!LF_ISSET(V_OBUF
) && F_ISSET(vp
, VC_BUFFER
))
654 /* Required buffer. */
655 if (LF_ISSET(V_RBUF
)) {
657 F_SET(vp
, VC_BUFFER
);
662 * Special case: '[', ']' and 'Z' commands. Doesn't the fact that
663 * the *single* characters don't mean anything but the *doubled*
664 * characters do, just frost your shorts?
666 if (vp
->key
== '[' || vp
->key
== ']' || vp
->key
== 'Z') {
668 * Historically, half entered [[, ]] or Z commands weren't
669 * cancelled by <escape>, the terminal was beeped instead.
670 * POSIX.2-1992 probably didn't notice, and requires that
671 * they be cancelled instead of beeping. Seems fine to me.
673 * Don't set the EC_MAPCOMMAND flag, apparently ] is a popular
674 * vi meta-character, and we don't want the user to wait while
675 * we time out a possible mapping. This *appears* to match
676 * historic vi practice, but with mapping characters, You Just
681 if (vp
->key
!= key
) {
682 usage
: if (ismotion
== NULL
)
684 else if (ismotion
->key
== '~' && O_ISSET(sp
, O_TILDEOP
))
687 s
= vikeys
[ismotion
->key
].usage
;
688 v_emsg(sp
, s
, VIM_USAGE
);
692 /* Special case: 'z' command. */
693 if (vp
->key
== 'z') {
694 KEY(vp
->character
, 0);
695 if (ISDIGIT(vp
->character
)) {
696 if (v_count(sp
, vp
, vp
->character
, &vp
->count2
))
699 KEY(vp
->character
, 0);
704 * Commands that have motion components can be doubled to imply the
707 if (ismotion
!= NULL
&& ismotion
->key
!= key
&& !LF_ISSET(V_MOVE
)) {
708 msgq(sp
, M_ERR
, "210|%s may not be used as a motion command",
713 /* Pick up required trailing character. */
714 if (LF_ISSET(V_CHAR
))
715 KEY(vp
->character
, 0);
717 /* Get any associated cursor word. */
718 if (F_ISSET(kp
, V_KEYW
) && v_curword(sp
))
723 esc
: switch (cpart
) {
725 msgq(sp
, M_BERR
, "211|Already in command mode");
726 return (GC_ERR_NOFLUSH
);
730 (void)sp
->gp
->scr_bell(sp
);
739 * Get resulting motion mark.
742 v_motion(SCR
*sp
, VICMD
*dm
, VICMD
*vp
, int *mappedp
)
749 int tilde_reset
, notused
;
752 * If '.' command, use the dot motion, else get the motion command.
753 * Clear any line motion flags, the subsequent motion isn't always
754 * the same, i.e. "/aaa" may or may not be a line motion.
756 if (F_ISSET(vp
, VC_ISDOT
)) {
758 F_SET(&motion
, VC_ISDOT
);
759 F_CLR(&motion
, VM_COMMASK
);
762 memset(&motion
, 0, sizeof(VICMD
));
763 gcret
= v_cmd(sp
, NULL
, &motion
, vp
, ¬used
, mappedp
);
764 if (gcret
!= GC_OK
&& gcret
!= GC_EVENT
)
769 * A count may be provided both to the command and to the motion, in
770 * which case the count is multiplicative. For example, "3y4y" is the
771 * same as "12yy". This count is provided to the motion command and
772 * not to the regular function.
774 cnt
= motion
.count
= F_ISSET(&motion
, VC_C1SET
) ? motion
.count
: 1;
775 if (F_ISSET(vp
, VC_C1SET
)) {
776 motion
.count
*= vp
->count
;
777 F_SET(&motion
, VC_C1SET
);
780 * Set flags to restore the original values of the command
781 * structure so dot commands can change the count values,
782 * e.g. "2dw" "3." deletes a total of five words.
785 F_SET(vp
, VC_C1RESET
);
789 * Some commands can be repeated to indicate the current line. In
790 * this case, or if the command is a "line command", set the flags
791 * appropriately. If not a doubled command, run the function to get
792 * the resulting mark.
794 if (gcret
!= GC_EVENT
&& vp
->key
== motion
.key
) {
795 F_SET(vp
, VM_LDOUBLE
| VM_LMODE
);
797 /* Set the origin of the command. */
798 vp
->m_start
.lno
= sp
->lno
;
802 * Set the end of the command.
804 * If the current line is missing, i.e. the file is empty,
805 * historic vi permitted a "cc" or "!!" command to insert
808 vp
->m_stop
.lno
= sp
->lno
+ motion
.count
- 1;
809 if (db_get(sp
, vp
->m_stop
.lno
, 0, NULL
, &len
)) {
810 if (vp
->m_stop
.lno
!= 1 ||
811 (vp
->key
!= 'c' && vp
->key
!= '!')) {
812 v_emsg(sp
, NULL
, VIM_EMPTY
);
817 vp
->m_stop
.cno
= len
? len
- 1 : 0;
820 * Motion commands change the underlying movement (*snarl*).
821 * For example, "l" is illegal at the end of a line, but "dl"
822 * is not. Set flags so the function knows the situation.
828 * Use yank instead of creating a new motion command, it's a
829 * lot easier for now.
831 if (vp
->kp
== &tmotion
) {
833 vp
->kp
= &vikeys
['y'];
838 * Copy the key flags into the local structure, except for the
839 * RCM flags -- the motion command will set the RCM flags in
840 * the vp structure if necessary. This means that the motion
841 * command is expected to determine where the cursor ends up!
842 * However, we save off the current RCM mask and restore it if
843 * it no RCM flags are set by the motion command, with a small
846 * We replace the VM_RCM_SET flag with the VM_RCM flag. This
847 * is so that cursor movement doesn't set the relative position
848 * unless the motion command explicitly specified it. This
849 * appears to match historic practice, but I've never been able
850 * to develop a hard-and-fast rule.
852 flags
= F_ISSET(vp
, VM_RCM_MASK
);
853 if (LF_ISSET(VM_RCM_SET
)) {
857 F_CLR(vp
, VM_RCM_MASK
);
858 F_SET(&motion
, motion
.kp
->flags
& ~VM_RCM_MASK
);
861 * Set the three cursor locations to the current cursor. This
862 * permits commands like 'j' and 'k', that are line oriented
863 * motions and have special cursor suck semantics when they are
864 * used as standalone commands, to ignore column positioning.
867 motion
.m_stop
.lno
= motion
.m_start
.lno
= sp
->lno
;
869 motion
.m_stop
.cno
= motion
.m_start
.cno
= sp
->cno
;
871 /* Run the function. */
872 if ((motion
.kp
->func
)(sp
, &motion
))
876 * If the current line is missing, i.e. the file is empty,
877 * historic vi allowed "c<motion>" or "!<motion>" to insert
878 * text. Otherwise fail -- most motion commands will have
879 * already failed, but some, e.g. G, succeed in empty files.
881 if (!db_exist(sp
, vp
->m_stop
.lno
)) {
882 if (vp
->m_stop
.lno
!= 1 ||
883 (vp
->key
!= 'c' && vp
->key
!= '!')) {
884 v_emsg(sp
, NULL
, VIM_EMPTY
);
898 * Copy cut buffer, line mode and cursor position information
899 * from the motion command structure, i.e. anything that the
900 * motion command can set for us. The commands can flag the
901 * movement as a line motion (see v_sentence) as well as set
902 * the VM_RCM_* flags explicitly.
904 F_SET(vp
, F_ISSET(&motion
, VM_COMMASK
| VM_RCM_MASK
));
907 * If the motion command set no relative motion flags, use
908 * the (slightly) modified previous values.
910 if (!F_ISSET(vp
, VM_RCM_MASK
))
914 * Commands can change behaviors based on the motion command
915 * used, for example, the ! command repeated the last bang
916 * command if N or n was used as the motion.
921 * Motion commands can reset all of the cursor information.
922 * If the motion is in the reverse direction, switch the
923 * from and to MARK's so that it's in a forward direction.
924 * Motions are from the from MARK to the to MARK (inclusive).
926 if (motion
.m_start
.lno
> motion
.m_stop
.lno
||
927 (motion
.m_start
.lno
== motion
.m_stop
.lno
&&
928 motion
.m_start
.cno
> motion
.m_stop
.cno
)) {
929 vp
->m_start
= motion
.m_stop
;
930 vp
->m_stop
= motion
.m_start
;
932 vp
->m_start
= motion
.m_start
;
933 vp
->m_stop
= motion
.m_stop
;
935 vp
->m_final
= motion
.m_final
;
939 * If the command sets dot, save the motion structure. The motion
940 * count was changed above and needs to be reset, that's why this
941 * is done here, and not in the calling routine.
943 if (F_ISSET(vp
->kp
, V_DOT
)) {
952 * Initialize the vi screen.
963 /* Switch into vi. */
964 if (gp
->scr_screen(sp
, SC_VI
))
966 (void)gp
->scr_attr(sp
, SA_ALTERNATE
, 1);
968 F_CLR(sp
, SC_EX
| SC_SCR_EX
);
972 * Initialize screen values.
974 * Small windows: see vs_refresh(), section 6a.
977 * t_minrows is the minimum rows to display
978 * t_maxrows is the maximum rows to display (rows - 1)
979 * t_rows is the rows currently being displayed
981 sp
->rows
= vip
->srows
= O_VAL(sp
, O_LINES
);
982 sp
->cols
= O_VAL(sp
, O_COLUMNS
);
983 sp
->t_rows
= sp
->t_minrows
= O_VAL(sp
, O_WINDOW
);
985 if (sp
->t_rows
> sp
->rows
- 1) {
986 sp
->t_minrows
= sp
->t_rows
= sp
->rows
- 1;
988 "214|Windows option value is too large, max is %zu",
991 sp
->t_maxrows
= sp
->rows
- 1;
994 sp
->roff
= sp
->coff
= 0;
996 /* Create a screen map. */
997 CALLOC_RET(sp
, HMAP
, SMAP
*, SIZE_HMAP(sp
), sizeof(SMAP
));
998 TMAP
= HMAP
+ (sp
->t_rows
- 1);
1004 * Fill the screen map from scratch -- try and center the line. That
1005 * way if we're starting with a file we've seen before, we'll put the
1006 * line in the middle, otherwise, it won't work and we'll end up with
1007 * the line at the top.
1009 F_CLR(sp
, SC_SCR_TOP
);
1010 F_SET(sp
, SC_SCR_REFORMAT
| SC_SCR_CENTER
);
1012 /* Invalidate the cursor. */
1013 F_SET(vip
, VIP_CUR_INVALID
);
1015 /* Paint the screen image from scratch. */
1016 F_SET(vip
, VIP_N_EX_PAINT
);
1023 * Move all but the current screen to the hidden queue.
1033 /* Move all screens to the hidden queue, tossing screen maps. */
1034 for (hidden
= 0, gp
= sp
->gp
, wp
= sp
->wp
;
1035 (tsp
= TAILQ_FIRST(&wp
->scrq
)) != NULL
; ++hidden
) {
1036 if (_HMAP(tsp
) != NULL
) {
1040 TAILQ_REMOVE(&wp
->scrq
, tsp
, q
);
1041 TAILQ_INSERT_TAIL(&gp
->hq
, tsp
, q
);
1042 /* XXXX Change if hidden screens per window */
1044 gp
->scr_discard(tsp
, NULL
);
1047 /* Move current screen back to the display queue. */
1048 TAILQ_REMOVE(&gp
->hq
, sp
, q
);
1049 TAILQ_INSERT_TAIL(&wp
->scrq
, sp
, q
);
1054 "319|%d screens backgrounded; use :display to list them",
1060 * Get the word (tagstring, actually) the cursor is on.
1062 * PUBLIC: int v_curword __P((SCR *));
1068 size_t beg
, end
, len
;
1072 if (db_get(sp
, sp
->lno
, DBG_FATAL
, &p
, &len
))
1077 * Historically, tag commands skipped over any leading whitespace
1078 * characters. Make this true in general when using cursor words.
1079 * If movement, getting a cursor word implies moving the cursor to
1080 * its beginning. Refresh now.
1083 * Find the beginning/end of the keyword. Keywords are currently
1084 * used for cursor-word searching and for tags. Historical vi
1085 * only used the word in a tag search from the cursor to the end
1086 * of the word, i.e. if the cursor was on the 'b' in " abc ", the
1087 * tag was "bc". For consistency, we make cursor word searches
1088 * follow the same rule.
1091 beg
= sp
->cno
; beg
< len
&& ISSPACE((UCHAR_T
)p
[beg
]); moved
= 1, ++beg
);
1093 msgq(sp
, M_BERR
, "212|Cursor not in a word");
1098 (void)vs_refresh(sp
, 0);
1102 * Find the end of the word.
1105 * Historically, vi accepted any non-blank as initial character
1106 * when building up a tagstring. Required by IEEE 1003.1-2001.
1108 for (end
= beg
; ++end
< len
&& inword(p
[end
]););
1111 vip
->klen
= len
= end
- beg
;
1112 BINC_RETW(sp
, vip
->keyw
, vip
->keywlen
, len
+1);
1113 MEMMOVEW(vip
->keyw
, p
+ beg
, len
);
1114 vip
->keyw
[len
] = L('\0'); /* XXX */
1120 * Check for a command alias.
1122 static VIKEYS
const *
1123 v_alias(SCR
*sp
, VICMD
*vp
, const VIKEYS
*kp
)
1128 case 'C': /* C -> c$ */
1132 case 'D': /* D -> d$ */
1136 case 'S': /* S -> c_ */
1140 case 'Y': /* Y -> y_ */
1147 return (v_event_push(sp
,
1148 NULL
, &push
, 1, CH_NOMAP
| CH_QUOTED
) ? NULL
: &vikeys
[vp
->key
]);
1153 * Return the next count.
1156 v_count(SCR
*sp
, VICMD
*vp
, ARG_CHAR_T fkey
, u_long
*countp
)
1165 * Assume that overflow results in a smaller number.
1167 tc
= count
* 10 + vp
->ev
.e_c
- '0';
1169 /* Toss to the next non-digit. */
1171 if (v_key(sp
, vp
, 0,
1172 EC_MAPCOMMAND
| EC_MAPNODIGIT
) != GC_OK
)
1174 } while (ISDIGIT(vp
->ev
.e_c
));
1176 "235|Number larger than %lu", ULONG_MAX
);
1180 if (v_key(sp
, vp
, 0, EC_MAPCOMMAND
| EC_MAPNODIGIT
) != GC_OK
)
1182 } while (ISDIGIT(vp
->ev
.e_c
));
1189 * Return the next event.
1192 v_key(SCR
*sp
, VICMD
*vp
, int events_ok
, u_int32_t ec_flags
)
1197 for (evp
= &vp
->ev
, quote
= 0;;) {
1198 if (v_event_get(sp
, evp
, 0, ec_flags
| quote
))
1202 switch (evp
->e_event
) {
1206 * Historically, ^V was ignored in the command stream,
1207 * although it had a useful side-effect of interrupting
1208 * mappings. Adding a quoting bit to the call probably
1209 * extends historic practice, but it feels right.
1211 if (evp
->e_value
== K_VLNEXT
) {
1222 * Historically, vi beeped on command level interrupts.
1224 * Historically, vi exited to ex mode if no file was
1225 * named on the command line, and two interrupts were
1226 * generated in a row. (I figured you might want to
1227 * know that, just in case there's a quiz later.)
1229 (void)sp
->gp
->scr_bell(sp
);
1230 return (GC_INTERRUPT
);
1232 if (v_erepaint(sp
, evp
))
1238 * We don't do anything here, just return an error.
1239 * The vi loop will return because of this, and then
1240 * the main loop will realize that we had to restart
1241 * the world and will call the vi loop again.
1249 v_event_err(sp
, evp
);
1256 #if defined(DEBUG) && defined(COMLOG)
1259 * Log the contents of the command structure.
1266 vtrace(sp
, "vcmd: "WC
, vp
->key
);
1267 if (F_ISSET(vp
, VC_BUFFER
))
1268 vtrace(sp
, " buffer: "WC
, vp
->buffer
);
1269 if (F_ISSET(vp
, VC_C1SET
))
1270 vtrace(sp
, " c1: %lu", vp
->count
);
1271 if (F_ISSET(vp
, VC_C2SET
))
1272 vtrace(sp
, " c2: %lu", vp
->count2
);
1273 vtrace(sp
, " flags: 0x%x\n", vp
->flags
);