Remove building with NOCRYPTO option
[minix.git] / external / bsd / nvi / dist / vi / v_mark.c
blobc68cb80856d5d151666e215add0e7ccbc773720b
1 /* $NetBSD: v_mark.c,v 1.4 2014/01/26 21:43:45 christos Exp $ */
2 /*-
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.
9 */
11 #include "config.h"
13 #include <sys/cdefs.h>
14 #if 0
15 #ifndef lint
16 static const char sccsid[] = "Id: v_mark.c,v 10.12 2001/06/25 15:19:32 skimo Exp (Berkeley) Date: 2001/06/25 15:19:32 ";
17 #endif /* not lint */
18 #else
19 __RCSID("$NetBSD: v_mark.c,v 1.4 2014/01/26 21:43:45 christos Exp $");
20 #endif
22 #include <sys/types.h>
23 #include <sys/queue.h>
24 #include <sys/time.h>
26 #include <bitstring.h>
27 #include <limits.h>
28 #include <stdlib.h>
29 #include <stdio.h>
31 #include "../common/common.h"
32 #include "vi.h"
34 enum which {BQMARK, FQMARK};
35 static int mark __P((SCR *, VICMD *, int, enum which));
38 * v_mark -- m[a-z]
39 * Set a mark.
41 * PUBLIC: int v_mark __P((SCR *, VICMD *));
43 int
44 v_mark(SCR *sp, VICMD *vp)
46 return (mark_set(sp, vp->character, &vp->m_start, 1));
50 * v_bmark -- `['`a-z]
51 * Move to a mark.
53 * Moves to a mark, setting both row and column.
55 * !!!
56 * Although not commonly known, the "'`" and "'`" forms are historically
57 * valid. The behavior is determined by the first character, so "`'" is
58 * the same as "``". Remember this fact -- you'll be amazed at how many
59 * people don't know it and will be delighted that you are able to tell
60 * them.
62 * PUBLIC: int v_bmark __P((SCR *, VICMD *));
64 int
65 v_bmark(SCR *sp, VICMD *vp)
67 return (mark(sp, vp, 1, BQMARK));
71 * v_fmark -- '['`a-z]
72 * Move to a mark.
74 * Move to the first nonblank character of the line containing the mark.
76 * PUBLIC: int v_fmark __P((SCR *, VICMD *));
78 int
79 v_fmark(SCR *sp, VICMD *vp)
81 return (mark(sp, vp, 1, FQMARK));
85 * v_emark -- <mouse click>
86 * Mouse mark.
88 * PUBLIC: int v_emark __P((SCR *, VICMD *));
90 int
91 v_emark(SCR *sp, VICMD *vp)
93 SMAP *smp;
95 smp = HMAP + vp->ev.e_lno;
96 if (smp > TMAP) {
97 msgq(sp, M_BERR, "320|Unknown cursor position.");
98 return (1);
100 vp->m_stop.lno = smp->lno;
101 vp->m_stop.cno =
102 vs_colpos(sp, smp->lno, vp->ev.e_cno + (smp->soff - 1) * sp->cols);
103 return (mark(sp, vp, 0, BQMARK));
107 * mark --
108 * Mark commands.
110 static int
111 mark(SCR *sp, VICMD *vp, int getmark, enum which cmd)
113 MARK m;
114 size_t len;
116 if (getmark && mark_get(sp, vp->character, &vp->m_stop, M_BERR))
117 return (1);
120 * !!!
121 * Historically, BQMARKS for character positions that no longer
122 * existed acted as FQMARKS.
124 * FQMARKS move to the first non-blank.
126 switch (cmd) {
127 case BQMARK:
128 if (db_get(sp, vp->m_stop.lno, DBG_FATAL, NULL, &len))
129 return (1);
130 if (vp->m_stop.cno < len ||
131 (vp->m_stop.cno == len && len == 0))
132 break;
134 if (ISMOTION(vp))
135 F_SET(vp, VM_LMODE);
136 cmd = FQMARK;
137 /* FALLTHROUGH */
138 case FQMARK:
139 vp->m_stop.cno = 0;
140 if (nonblank(sp, vp->m_stop.lno, &vp->m_stop.cno))
141 return (1);
142 break;
143 default:
144 abort();
147 /* Non-motion commands move to the end of the range. */
148 if (!ISMOTION(vp)) {
149 vp->m_final = vp->m_stop;
150 return (0);
154 * !!!
155 * If a motion component to a BQMARK, the cursor has to move.
157 if (cmd == BQMARK &&
158 vp->m_stop.lno == vp->m_start.lno &&
159 vp->m_stop.cno == vp->m_start.cno) {
160 v_nomove(sp);
161 return (1);
165 * If the motion is in the reverse direction, switch the start and
166 * stop MARK's so that it's in a forward direction. (There's no
167 * reason for this other than to make the tests below easier. The
168 * code in vi.c:vi() would have done the switch.) Both forward
169 * and backward motions can happen for any kind of search command.
171 if (vp->m_start.lno > vp->m_stop.lno ||
172 (vp->m_start.lno == vp->m_stop.lno &&
173 vp->m_start.cno > vp->m_stop.cno)) {
174 m = vp->m_start;
175 vp->m_start = vp->m_stop;
176 vp->m_stop = m;
180 * Yank cursor motion, when associated with marks as motion commands,
181 * historically behaved as follows:
183 * ` motion ' motion
184 * Line change? Line change?
185 * Y N Y N
186 * -------------- ---------------
187 * FORWARD: | NM NM | NM NM
188 * | |
189 * BACKWARD: | M M | M NM(1)
191 * where NM means the cursor didn't move, and M means the cursor
192 * moved to the mark.
194 * As the cursor was usually moved for yank commands associated
195 * with backward motions, this implementation regularizes it by
196 * changing the NM at position (1) to be an M. This makes mark
197 * motions match search motions, which is probably A Good Thing.
199 * Delete cursor motion was always to the start of the text region,
200 * regardless. Ignore other motion commands.
202 #ifdef HISTORICAL_PRACTICE
203 if (ISCMD(vp->rkp, 'y')) {
204 if ((cmd == BQMARK ||
205 cmd == FQMARK && vp->m_start.lno != vp->m_stop.lno) &&
206 (vp->m_start.lno > vp->m_stop.lno ||
207 vp->m_start.lno == vp->m_stop.lno &&
208 vp->m_start.cno > vp->m_stop.cno))
209 vp->m_final = vp->m_stop;
210 } else if (ISCMD(vp->rkp, 'd'))
211 if (vp->m_start.lno > vp->m_stop.lno ||
212 vp->m_start.lno == vp->m_stop.lno &&
213 vp->m_start.cno > vp->m_stop.cno)
214 vp->m_final = vp->m_stop;
215 #else
216 vp->m_final = vp->m_start;
217 #endif
220 * Forward marks are always line oriented, and it's set in the
221 * vcmd.c table.
223 if (cmd == FQMARK)
224 return (0);
227 * BQMARK'S moving backward and starting at column 0, and ones moving
228 * forward and ending at column 0 are corrected to the last column of
229 * the previous line. Otherwise, adjust the starting/ending point to
230 * the character before the current one (this is safe because we know
231 * the search had to move to succeed).
233 * Mark motions become line mode opertions if they start at the first
234 * nonblank and end at column 0 of another line.
236 if (vp->m_start.lno < vp->m_stop.lno && vp->m_stop.cno == 0) {
237 if (db_get(sp, --vp->m_stop.lno, DBG_FATAL, NULL, &len))
238 return (1);
239 vp->m_stop.cno = len ? len - 1 : 0;
240 len = 0;
241 if (nonblank(sp, vp->m_start.lno, &len))
242 return (1);
243 if (vp->m_start.cno <= len)
244 F_SET(vp, VM_LMODE);
245 } else
246 --vp->m_stop.cno;
248 return (0);