tools/llvm: Do not build with symbols
[minix3.git] / external / bsd / nvi / dist / vi / v_mark.c
blob4698d7f801ffbcd10371ed0df1244052d9577f49
1 /* $NetBSD: v_mark.c,v 1.2 2013/11/22 15:52:06 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 #ifndef lint
14 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 ";
15 #endif /* not lint */
17 #include <sys/types.h>
18 #include <sys/queue.h>
19 #include <sys/time.h>
21 #include <bitstring.h>
22 #include <limits.h>
23 #include <stdlib.h>
24 #include <stdio.h>
26 #include "../common/common.h"
27 #include "vi.h"
29 enum which {BQMARK, FQMARK};
30 static int mark __P((SCR *, VICMD *, int, enum which));
33 * v_mark -- m[a-z]
34 * Set a mark.
36 * PUBLIC: int v_mark __P((SCR *, VICMD *));
38 int
39 v_mark(SCR *sp, VICMD *vp)
41 return (mark_set(sp, vp->character, &vp->m_start, 1));
45 * v_bmark -- `['`a-z]
46 * Move to a mark.
48 * Moves to a mark, setting both row and column.
50 * !!!
51 * Although not commonly known, the "'`" and "'`" forms are historically
52 * valid. The behavior is determined by the first character, so "`'" is
53 * the same as "``". Remember this fact -- you'll be amazed at how many
54 * people don't know it and will be delighted that you are able to tell
55 * them.
57 * PUBLIC: int v_bmark __P((SCR *, VICMD *));
59 int
60 v_bmark(SCR *sp, VICMD *vp)
62 return (mark(sp, vp, 1, BQMARK));
66 * v_fmark -- '['`a-z]
67 * Move to a mark.
69 * Move to the first nonblank character of the line containing the mark.
71 * PUBLIC: int v_fmark __P((SCR *, VICMD *));
73 int
74 v_fmark(SCR *sp, VICMD *vp)
76 return (mark(sp, vp, 1, FQMARK));
80 * v_emark -- <mouse click>
81 * Mouse mark.
83 * PUBLIC: int v_emark __P((SCR *, VICMD *));
85 int
86 v_emark(SCR *sp, VICMD *vp)
88 SMAP *smp;
90 smp = HMAP + vp->ev.e_lno;
91 if (smp > TMAP) {
92 msgq(sp, M_BERR, "320|Unknown cursor position.");
93 return (1);
95 vp->m_stop.lno = smp->lno;
96 vp->m_stop.cno =
97 vs_colpos(sp, smp->lno, vp->ev.e_cno + (smp->soff - 1) * sp->cols);
98 return (mark(sp, vp, 0, BQMARK));
102 * mark --
103 * Mark commands.
105 static int
106 mark(SCR *sp, VICMD *vp, int getmark, enum which cmd)
108 MARK m;
109 size_t len;
111 if (getmark && mark_get(sp, vp->character, &vp->m_stop, M_BERR))
112 return (1);
115 * !!!
116 * Historically, BQMARKS for character positions that no longer
117 * existed acted as FQMARKS.
119 * FQMARKS move to the first non-blank.
121 switch (cmd) {
122 case BQMARK:
123 if (db_get(sp, vp->m_stop.lno, DBG_FATAL, NULL, &len))
124 return (1);
125 if (vp->m_stop.cno < len ||
126 (vp->m_stop.cno == len && len == 0))
127 break;
129 if (ISMOTION(vp))
130 F_SET(vp, VM_LMODE);
131 cmd = FQMARK;
132 /* FALLTHROUGH */
133 case FQMARK:
134 vp->m_stop.cno = 0;
135 if (nonblank(sp, vp->m_stop.lno, &vp->m_stop.cno))
136 return (1);
137 break;
138 default:
139 abort();
142 /* Non-motion commands move to the end of the range. */
143 if (!ISMOTION(vp)) {
144 vp->m_final = vp->m_stop;
145 return (0);
149 * !!!
150 * If a motion component to a BQMARK, the cursor has to move.
152 if (cmd == BQMARK &&
153 vp->m_stop.lno == vp->m_start.lno &&
154 vp->m_stop.cno == vp->m_start.cno) {
155 v_nomove(sp);
156 return (1);
160 * If the motion is in the reverse direction, switch the start and
161 * stop MARK's so that it's in a forward direction. (There's no
162 * reason for this other than to make the tests below easier. The
163 * code in vi.c:vi() would have done the switch.) Both forward
164 * and backward motions can happen for any kind of search command.
166 if (vp->m_start.lno > vp->m_stop.lno ||
167 (vp->m_start.lno == vp->m_stop.lno &&
168 vp->m_start.cno > vp->m_stop.cno)) {
169 m = vp->m_start;
170 vp->m_start = vp->m_stop;
171 vp->m_stop = m;
172 } else
175 * Yank cursor motion, when associated with marks as motion commands,
176 * historically behaved as follows:
178 * ` motion ' motion
179 * Line change? Line change?
180 * Y N Y N
181 * -------------- ---------------
182 * FORWARD: | NM NM | NM NM
183 * | |
184 * BACKWARD: | M M | M NM(1)
186 * where NM means the cursor didn't move, and M means the cursor
187 * moved to the mark.
189 * As the cursor was usually moved for yank commands associated
190 * with backward motions, this implementation regularizes it by
191 * changing the NM at position (1) to be an M. This makes mark
192 * motions match search motions, which is probably A Good Thing.
194 * Delete cursor motion was always to the start of the text region,
195 * regardless. Ignore other motion commands.
197 #ifdef HISTORICAL_PRACTICE
198 if (ISCMD(vp->rkp, 'y')) {
199 if ((cmd == BQMARK ||
200 cmd == FQMARK && vp->m_start.lno != vp->m_stop.lno) &&
201 (vp->m_start.lno > vp->m_stop.lno ||
202 vp->m_start.lno == vp->m_stop.lno &&
203 vp->m_start.cno > vp->m_stop.cno))
204 vp->m_final = vp->m_stop;
205 } else if (ISCMD(vp->rkp, 'd'))
206 if (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
211 vp->m_final = vp->m_start;
212 #endif
215 * Forward marks are always line oriented, and it's set in the
216 * vcmd.c table.
218 if (cmd == FQMARK)
219 return (0);
222 * BQMARK'S moving backward and starting at column 0, and ones moving
223 * forward and ending at column 0 are corrected to the last column of
224 * the previous line. Otherwise, adjust the starting/ending point to
225 * the character before the current one (this is safe because we know
226 * the search had to move to succeed).
228 * Mark motions become line mode opertions if they start at the first
229 * nonblank and end at column 0 of another line.
231 if (vp->m_start.lno < vp->m_stop.lno && vp->m_stop.cno == 0) {
232 if (db_get(sp, --vp->m_stop.lno, DBG_FATAL, NULL, &len))
233 return (1);
234 vp->m_stop.cno = len ? len - 1 : 0;
235 len = 0;
236 if (nonblank(sp, vp->m_start.lno, &len))
237 return (1);
238 if (vp->m_start.cno <= len)
239 F_SET(vp, VM_LMODE);
240 } else
241 --vp->m_stop.cno;
243 return (0);