2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved.
5 * %sccs.include.redist.c%
9 static char sccsid
[] = "$Id: v_paragraph.c,v 8.3 1993/11/13 18:01:41 bostic Exp $ (Berkeley) $Date: 1993/11/13 18:01:41 $";
12 #include <sys/types.h>
22 * Paragraphs are empty lines after text or values from the paragraph or
27 * v_paragraphf -- [count]}
28 * Move forward count paragraphs.
31 v_paragraphf(sp
, ep
, vp
, fm
, tm
, rp
)
37 enum { P_INTEXT
, P_INBLANK
} pstate
;
39 recno_t cnt
, lastlno
, lno
;
42 /* Figure out what state we're currently in. */
44 if ((p
= file_gline(sp
, ep
, lno
, &len
)) == NULL
)
48 * If we start in text, we want to switch states 2 * N - 1
49 * times, in non-text, 2 * N times.
51 cnt
= F_ISSET(vp
, VC_C1SET
) ? vp
->count
: 1;
53 if (len
== 0 || v_isempty(p
, len
))
63 if ((p
= file_gline(sp
, ep
, ++lno
, &len
)) == NULL
)
67 if (p
[0] == '.' && len
>= 2)
68 for (lp
= VIP(sp
)->paragraph
; *lp
; lp
+= 2)
70 (lp
[1] == ' ' || lp
[1] == p
[2]) &&
73 if (len
== 0 || v_isempty(p
, len
)) {
80 if (len
== 0 || v_isempty(p
, len
))
87 * Historically, a motion command was up to the end
88 * of the previous line, whereas the movement command
89 * was to the start of the new "paragraph".
91 found
: if (F_ISSET(vp
, VC_C
| VC_D
| VC_Y
)) {
93 rp
->cno
= lastlen
? lastlen
+ 1 : 0;
105 * EOF is a movement sink, however, the } command historically
106 * moved to the end of the last line if repeatedly invoked.
108 eof
: if (fm
->lno
!= lno
- 1) {
110 rp
->cno
= len
? len
- 1 : 0;
113 if ((p
= file_gline(sp
, ep
, fm
->lno
, &len
)) == NULL
)
114 GETLINE_ERR(sp
, fm
->lno
);
115 if (fm
->cno
!= (len
? len
- 1 : 0)) {
117 rp
->cno
= len
? len
- 1 : 0;
125 * v_paragraphb -- [count]{
126 * Move forward count paragraph.
129 v_paragraphb(sp
, ep
, vp
, fm
, tm
, rp
)
135 enum { P_INTEXT
, P_INBLANK
} pstate
;
141 * The { command historically moved to the beginning of the first
142 * line if invoked on the first line.
156 /* Figure out what state we're currently in. */
158 if ((p
= file_gline(sp
, ep
, lno
, &len
)) == NULL
)
162 * If we start in text, we want to switch states 2 * N - 1
163 * times, in non-text, 2 * N times.
165 cnt
= F_ISSET(vp
, VC_C1SET
) ? vp
->count
: 1;
167 if (len
== 0 || v_isempty(p
, len
))
175 if ((p
= file_gline(sp
, ep
, --lno
, &len
)) == NULL
)
179 if (p
[0] == '.' && len
>= 2)
180 for (lp
= VIP(sp
)->paragraph
; *lp
; lp
+= 2)
182 (lp
[1] == ' ' || lp
[1] == p
[2]) &&
185 if (len
== 0 || v_isempty(p
, len
)) {
192 if (len
!= 0 && !v_isempty(p
, len
)) {
194 found
: rp
->lno
= lno
;
206 /* SOF is a movement sink. */
213 * v_buildparagraph --
214 * Build the paragraph command search pattern.
225 * The vi paragraph command searches for either a paragraph or
226 * section option macro.
228 p_len
= (p_p
= O_STR(sp
, O_PARAGRAPHS
)) == NULL
? 0 : strlen(p_p
);
229 s_len
= (s_p
= O_STR(sp
, O_SECTIONS
)) == NULL
? 0 : strlen(s_p
);
231 if (p_len
== 0 && s_len
== 0)
234 if ((p
= malloc(p_len
+ s_len
+ 1)) == NULL
) {
235 msgq(sp
, M_SYSERR
, NULL
);
240 if (vip
->paragraph
!= NULL
)
241 FREE(vip
->paragraph
, vip
->paragraph_len
);
244 memmove(p
, p_p
, p_len
+ 1);
246 memmove(p
+ p_len
, s_p
, s_len
+ 1);
248 vip
->paragraph_len
= p_len
+ s_len
+ 1;