* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
static char *sccsid
= "@(#)ex_vops3.c 7.4 (Berkeley) %G%";
* Routines to handle structure.
* Operations supported are:
* { } list at same paragraphs
* { and } for C used to attempt to do something with matching {}'s, but
* I couldn't find definitions which worked intuitively very well, so I
* The code here is very hard to understand.
* Find over structure, repeated count times.
* Don't go past line limit. F is the operation to
* be performed eventually. If pastatom then the user said {}
* rather than (), implying past atoms in a list (or a paragraph
* rather than a sentence.
lfind(pastatom
, cnt
, f
, limit
)
* Initialize, saving the current line buffer state
* and computing the limit; a 0 argument means
* directional end of file.
limit
= dir
< 0 ? one
: dol
;
while (cnt
> 0 && word(f
, cnt
))
* If looking for sentence, next line
* Advance so as to not find same thing again.
* Count times find end of sentence/paragraph.
while (!endsent(pastatom
))
if (!pastatom
|| wcursor
== linebuf
&& endPS())
* If going backwards, and didn't hit the end of the buffer,
* then reverse direction.
if (dir
< 0 && (wdot
!= llimit
|| wcursor
!= linebuf
)) {
* Empty line needs special treatement.
* If moved to it from other than begining of next line,
* then a sentence starts on next line.
if (linebuf
[0] == 0 && !pastatom
&&
(wdot
!= dot
- 1 || cursor
!= linebuf
)) {
* If we are not at a section/paragraph division,
if (wcursor
== icurs
&& wdot
== idot
|| wcursor
!= linebuf
|| !endPS())
* Startup by skipping if at a ( going left or a ) going
* right to keep from getting stuck immediately.
if (dir
< 0 && c
== '(' || dir
> 0 && c
== ')') {
* Now chew up repitition count. Each time around
* if at the beginning of an s-exp (going forwards)
* or the end of an s-exp (going backwards)
* skip the s-exp. If not at beg/end resp, then stop
* if we hit a higher level paren, else skip an atom,
* counting it unless pastatom.
if (dir
< 0 && c
== ')' || dir
> 0 && c
== '(') {
* Unless this is the last time going
* backwards, skip past the matching paren
* so we don't think it is a higher level paren.
if (!lnext() || !ltosolid())
} else if (dir
< 0 && c
== '(' || dir
> 0 && c
== ')')
/* Found a higher level paren */
* Is this the end of a sentence?
register char *cp
= wcursor
;
* If this is the beginning of a line, then
* check for the end of a paragraph or section.
* Sentences end with . ! ? not at the beginning
* of the line, and must be either at the end of the line,
* or followed by 2 spaces. Any number of intervening ) ] ' "
* characters are allowed.
if (*cp
== 0 || *cp
++ == ' ' && *cp
== ' ')
* End of paragraphs/sections are respective
* macros as well as blank lines and form feeds.
return (linebuf
[0] == 0 ||
isa(svalue(PARAGRAPHS
)) || isa(svalue(SECTIONS
)));
for (cp
= linebuf
; *cp
; cp
++)
return (whitecnt(linebuf
));
else if (wcursor
== linebuf
)
register char *wp
= wcursor
;
if (!lnext() || !ltosolid() || !lskipatom()) {
i
+= column(wcursor
) - 1;
register char *parens
, *cp
;
for (cp
= cursor
; !any(*cp
, "({[)}]");)
parens
= any(*cp
, "()") ? "()" : any(*cp
, "[]") ? "[]" : "{}";
register char *sp
= save
;
register char *scurs
= cursor
;
cursor
= strend(linebuf
) - 1;
if (lmatchp(dot
- vcline
)) {
register int i
= insmode
;
register int l
= outline
;
vgoto(splitw
? WECHO
: LINE(wdot
- llimit
), column(wcursor
) - 1);
if (!lmatchp((line
*) 0))
if (*parens
&& !*wcursor
&& !lnext())
while (isspace(*wcursor
) || (*wcursor
== 0 && *parens
))
if (any(*wcursor
, parens
) || dir
> 0)
for (cp
= wcursor
; cp
> linebuf
; cp
--)
if (isspace(cp
[-1]) || any(cp
[-1], parens
))
register int level
= dir
;
if (dir
< 0 && wcursor
== linebuf
) {
if (c
&& (isspace(c
) || any(c
, parens
)))
if (dir
> 0 && wcursor
== linebuf
)
return (ltosol1(parens
));
if (lf
== vmove
&& wcursor
> linebuf
)
if (lf
== lindent
&& linebuf
[0] == '(')
wcursor
= linebuf
[0] == 0 ? linebuf
: strend(linebuf
) - 1;
if (addr
< one
|| addr
> dol
) {
value(LISP
) && linebuf
[0] == '(' ||
if (c
== ']' && f
!= vmove
) {
if (c
== ']' && f
!= vmove
&& linebuf
[0] == '}')
wcursor
= c
== ']' ? strend(linebuf
) : linebuf
;
for (; cp
[0] && cp
[1]; cp
+= 2)
if (linebuf
[1] == cp
[0]) {
if (linebuf
[2] == 0 && cp
[1] == ' ')