Explicitly request literal mode after .Xr.
[netbsd-mini2440.git] / dist / nvi / vi / v_mark.c
blob8941c84a53c8d3ea357eab6c6b3766cd5774b934
1 /* $NetBSD: v_mark.c,v 1.1.1.2 2008/05/18 14:31:42 aymeric Exp $ */
3 /*-
4 * Copyright (c) 1992, 1993, 1994
5 * The Regents of the University of California. All rights reserved.
6 * Copyright (c) 1992, 1993, 1994, 1995, 1996
7 * Keith Bostic. All rights reserved.
9 * See the LICENSE file for redistribution information.
12 #include "config.h"
14 #ifndef lint
15 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";
16 #endif /* not lint */
18 #include <sys/types.h>
19 #include <sys/queue.h>
20 #include <sys/time.h>
22 #include <bitstring.h>
23 #include <limits.h>
24 #include <stdlib.h>
25 #include <stdio.h>
27 #include "../common/common.h"
28 #include "vi.h"
30 enum which {BQMARK, FQMARK};
31 static int mark __P((SCR *, VICMD *, int, enum which));
34 * v_mark -- m[a-z]
35 * Set a mark.
37 * PUBLIC: int v_mark __P((SCR *, VICMD *));
39 int
40 v_mark(SCR *sp, VICMD *vp)
42 return (mark_set(sp, vp->character, &vp->m_start, 1));
46 * v_bmark -- `['`a-z]
47 * Move to a mark.
49 * Moves to a mark, setting both row and column.
51 * !!!
52 * Although not commonly known, the "'`" and "'`" forms are historically
53 * valid. The behavior is determined by the first character, so "`'" is
54 * the same as "``". Remember this fact -- you'll be amazed at how many
55 * people don't know it and will be delighted that you are able to tell
56 * them.
58 * PUBLIC: int v_bmark __P((SCR *, VICMD *));
60 int
61 v_bmark(SCR *sp, VICMD *vp)
63 return (mark(sp, vp, 1, BQMARK));
67 * v_fmark -- '['`a-z]
68 * Move to a mark.
70 * Move to the first nonblank character of the line containing the mark.
72 * PUBLIC: int v_fmark __P((SCR *, VICMD *));
74 int
75 v_fmark(SCR *sp, VICMD *vp)
77 return (mark(sp, vp, 1, FQMARK));
81 * v_emark -- <mouse click>
82 * Mouse mark.
84 * PUBLIC: int v_emark __P((SCR *, VICMD *));
86 int
87 v_emark(SCR *sp, VICMD *vp)
89 SMAP *smp;
91 smp = HMAP + vp->ev.e_lno;
92 if (smp > TMAP) {
93 msgq(sp, M_BERR, "320|Unknown cursor position.");
94 return (1);
96 vp->m_stop.lno = smp->lno;
97 vp->m_stop.cno =
98 vs_colpos(sp, smp->lno, vp->ev.e_cno + (smp->soff - 1) * sp->cols);
99 return (mark(sp, vp, 0, BQMARK));
103 * mark --
104 * Mark commands.
106 static int
107 mark(SCR *sp, VICMD *vp, int getmark, enum which cmd)
109 dir_t dir;
110 MARK m;
111 size_t len;
113 if (getmark && mark_get(sp, vp->character, &vp->m_stop, M_BERR))
114 return (1);
117 * !!!
118 * Historically, BQMARKS for character positions that no longer
119 * existed acted as FQMARKS.
121 * FQMARKS move to the first non-blank.
123 switch (cmd) {
124 case BQMARK:
125 if (db_get(sp, vp->m_stop.lno, DBG_FATAL, NULL, &len))
126 return (1);
127 if (vp->m_stop.cno < len ||
128 (vp->m_stop.cno == len && len == 0))
129 break;
131 if (ISMOTION(vp))
132 F_SET(vp, VM_LMODE);
133 cmd = FQMARK;
134 /* FALLTHROUGH */
135 case FQMARK:
136 vp->m_stop.cno = 0;
137 if (nonblank(sp, vp->m_stop.lno, &vp->m_stop.cno))
138 return (1);
139 break;
140 default:
141 abort();
144 /* Non-motion commands move to the end of the range. */
145 if (!ISMOTION(vp)) {
146 vp->m_final = vp->m_stop;
147 return (0);
151 * !!!
152 * If a motion component to a BQMARK, the cursor has to move.
154 if (cmd == BQMARK &&
155 vp->m_stop.lno == vp->m_start.lno &&
156 vp->m_stop.cno == vp->m_start.cno) {
157 v_nomove(sp);
158 return (1);
162 * If the motion is in the reverse direction, switch the start and
163 * stop MARK's so that it's in a forward direction. (There's no
164 * reason for this other than to make the tests below easier. The
165 * code in vi.c:vi() would have done the switch.) Both forward
166 * and backward motions can happen for any kind of search command.
168 if (vp->m_start.lno > vp->m_stop.lno ||
169 (vp->m_start.lno == vp->m_stop.lno &&
170 vp->m_start.cno > vp->m_stop.cno)) {
171 m = vp->m_start;
172 vp->m_start = vp->m_stop;
173 vp->m_stop = m;
174 dir = BACKWARD;
175 } else
176 dir = FORWARD;
179 * Yank cursor motion, when associated with marks as motion commands,
180 * historically behaved as follows:
182 * ` motion ' motion
183 * Line change? Line change?
184 * Y N Y N
185 * -------------- ---------------
186 * FORWARD: | NM NM | NM NM
187 * | |
188 * BACKWARD: | M M | M NM(1)
190 * where NM means the cursor didn't move, and M means the cursor
191 * moved to the mark.
193 * As the cursor was usually moved for yank commands associated
194 * with backward motions, this implementation regularizes it by
195 * changing the NM at position (1) to be an M. This makes mark
196 * motions match search motions, which is probably A Good Thing.
198 * Delete cursor motion was always to the start of the text region,
199 * regardless. Ignore other motion commands.
201 #ifdef HISTORICAL_PRACTICE
202 if (ISCMD(vp->rkp, 'y')) {
203 if ((cmd == BQMARK ||
204 cmd == FQMARK && vp->m_start.lno != vp->m_stop.lno) &&
205 (vp->m_start.lno > vp->m_stop.lno ||
206 vp->m_start.lno == vp->m_stop.lno &&
207 vp->m_start.cno > vp->m_stop.cno))
208 vp->m_final = vp->m_stop;
209 } else if (ISCMD(vp->rkp, 'd'))
210 if (vp->m_start.lno > vp->m_stop.lno ||
211 vp->m_start.lno == vp->m_stop.lno &&
212 vp->m_start.cno > vp->m_stop.cno)
213 vp->m_final = vp->m_stop;
214 #else
215 vp->m_final = vp->m_start;
216 #endif
219 * Forward marks are always line oriented, and it's set in the
220 * vcmd.c table.
222 if (cmd == FQMARK)
223 return (0);
226 * BQMARK'S moving backward and starting at column 0, and ones moving
227 * forward and ending at column 0 are corrected to the last column of
228 * the previous line. Otherwise, adjust the starting/ending point to
229 * the character before the current one (this is safe because we know
230 * the search had to move to succeed).
232 * Mark motions become line mode opertions if they start at the first
233 * nonblank and end at column 0 of another line.
235 if (vp->m_start.lno < vp->m_stop.lno && vp->m_stop.cno == 0) {
236 if (db_get(sp, --vp->m_stop.lno, DBG_FATAL, NULL, &len))
237 return (1);
238 vp->m_stop.cno = len ? len - 1 : 0;
239 len = 0;
240 if (nonblank(sp, vp->m_start.lno, &len))
241 return (1);
242 if (vp->m_start.cno <= len)
243 F_SET(vp, VM_LMODE);
244 } else
245 --vp->m_stop.cno;
247 return (0);