1 #if !defined(lint) && !defined(DOS)
2 static char rcsid
[] = "$Id: region.c 761 2007-10-23 22:35:18Z hubert@u.washington.edu $";
6 * ========================================================================
7 * Copyright 2006 University of Washington
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * ========================================================================
19 * Program: Region management routines
21 * The routines in this file
22 * deal with the region, that magic space
23 * between "." and mark. Some functions are
24 * commands. Some functions are just for
30 * Kill the region. Ask "getregion"
31 * to figure out the bounds of the region.
32 * Move "." to the start, and kill the characters.
36 killregion(int f
, int n
)
40 if (curbp
->b_mode
&MDVIEW
) /* don't allow this command if */
41 return(rdonly()); /* we are in read only mode */
43 if (getregion(®ion
, curwp
->w_markp
, curwp
->w_marko
) != TRUE
){
44 return (killtext(f
, n
));
49 if ((lastflag
&CFKILL
) == 0) /* This is a kill type */
50 kdelete(); /* command, so do magic */
52 thisflag
|= CFKILL
; /* kill buffer stuff. */
53 curwp
->w_dotp
= region
.r_linep
;
54 curwp
->w_doto
= region
.r_offset
;
55 curwp
->w_markp
= NULL
;
57 mswin_allowcopycut(NULL
);
60 if(ldelete(region
.r_size
, kinsert
)){
61 if(curwp
->w_dotp
== curwp
->w_linep
&& curwp
->w_dotp
== curbp
->b_linep
){
62 curwp
->w_force
= 0; /* Center dot. */
63 curwp
->w_flag
|= WFFORCE
;
74 * Blast the region without saving . Ask "getregion"
75 * to figure out the bounds of the region.
76 * Move "." to the start, and kill the characters.
80 deleteregion(int f
, int n
)
84 if (curbp
->b_mode
&MDVIEW
) /* don't allow this command if */
85 return(rdonly()); /* we are in read only mode */
87 if (getregion(®ion
, curwp
->w_markp
, curwp
->w_marko
) == TRUE
){
88 curwp
->w_dotp
= region
.r_linep
;
89 curwp
->w_doto
= region
.r_offset
;
90 curwp
->w_markp
= NULL
;
92 mswin_allowcopycut(NULL
);
94 if(ldelete(region
.r_size
, NULL
)){
95 if(curwp
->w_dotp
== curwp
->w_linep
96 && curwp
->w_dotp
== curbp
->b_linep
){
97 curwp
->w_force
= 0; /* Center dot. */
98 curwp
->w_flag
|= WFFORCE
;
110 * Copy all of the characters in the
111 * region to the kill buffer. Don't move dot
112 * at all. This is a bit like a kill region followed
113 * by a yank. Bound to "M-W".
116 copyregion(int f
, int n
)
118 register LINE
*linep
;
123 if ((s
=getregion(®ion
, curwp
->w_markp
, curwp
->w_marko
)) != TRUE
)
126 if ((lastflag
&CFKILL
) == 0) /* Kill type command. */
130 linep
= region
.r_linep
; /* Current line. */
131 loffs
= region
.r_offset
; /* Current offset. */
132 while (region
.r_size
--) {
133 if (loffs
== llength(linep
)) { /* End of line. */
134 if ((s
=kinsert('\n')) != TRUE
)
136 linep
= lforw(linep
);
138 } else { /* Middle of line. */
139 if ((s
=kinsert(lgetc(linep
, loffs
).c
)) != TRUE
)
150 * Lower case region. Zap all of the upper
151 * case characters in the region to lower case. Use
152 * the region code to set the limits. Scan the buffer,
153 * doing the changes. Call "lchange" to ensure that
154 * redisplay is done in all buffers. Bound to
158 lowerregion(int f
, int n
)
160 register LINE
*linep
;
168 if (curbp
->b_mode
&MDVIEW
) /* don't allow this command if */
169 return(rdonly()); /* we are in read only mode */
171 if ((s
=getregion(®ion
, curwp
->w_markp
, curwp
->w_marko
)) != TRUE
)
175 linep
= region
.r_linep
;
176 loffs
= region
.r_offset
;
177 while (region
.r_size
--) {
178 if (loffs
== llength(linep
)) {
179 linep
= lforw(linep
);
182 c
= lgetc(linep
, loffs
).c
;
183 if (c
>='A' && c
<='Z'){
185 lputc(linep
, loffs
, ac
);
195 * Upper case region. Zap all of the lower
196 * case characters in the region to upper case. Use
197 * the region code to set the limits. Scan the buffer,
198 * doing the changes. Call "lchange" to ensure that
199 * redisplay is done in all buffers. Bound to
203 upperregion(int f
, int n
)
205 register LINE
*linep
;
213 if (curbp
->b_mode
&MDVIEW
) /* don't allow this command if */
214 return(rdonly()); /* we are in read only mode */
216 if ((s
=getregion(®ion
, curwp
->w_markp
, curwp
->w_marko
)) != TRUE
)
220 linep
= region
.r_linep
;
221 loffs
= region
.r_offset
;
222 while (region
.r_size
--) {
223 if (loffs
== llength(linep
)) {
224 linep
= lforw(linep
);
227 c
= lgetc(linep
, loffs
).c
;
228 if (c
>='a' && c
<='z'){
229 ac
.c
= c
- 'a' + 'A';
230 lputc(linep
, loffs
, ac
);
240 * This routine figures out the
241 * bounds of the region in the current window, and
242 * fills in the fields of the "REGION" structure pointed
243 * to by "rp". Because the dot and mark are usually very
244 * close together, we scan outward from dot looking for
245 * mark. This should save time. Return a standard code.
246 * Callers of this routine should be prepared to get
247 * an "ABORT" status; we might make this have the
248 * conform thing later.
251 getregion(REGION
*rp
, LINE
*markp
, int marko
)
262 if (curwp
->w_dotp
== markp
) {
263 rp
->r_linep
= curwp
->w_dotp
;
264 if (curwp
->w_doto
< marko
) {
265 rp
->r_offset
= curwp
->w_doto
;
266 rp
->r_size
= marko
- curwp
->w_doto
;
268 rp
->r_offset
= marko
;
269 rp
->r_size
= curwp
->w_doto
- marko
;
275 bsize
= curwp
->w_doto
;
277 fsize
= llength(flp
)-curwp
->w_doto
+1;
278 while (flp
!=curbp
->b_linep
|| lback(blp
)!=curbp
->b_linep
) {
279 if (flp
!= curbp
->b_linep
) {
282 rp
->r_linep
= curwp
->w_dotp
;
283 rp
->r_offset
= curwp
->w_doto
;
284 rp
->r_size
= fsize
+ marko
;
288 fsize
+= llength(flp
) + 1;
291 if (lback(blp
) != curbp
->b_linep
) {
293 bsize
+= llength(blp
)+1;
296 rp
->r_offset
= marko
;
297 rp
->r_size
= bsize
- marko
;
303 emlwrite("Bug: lost mark", NULL
);
309 * set the highlight attribute accordingly on all characters in region
314 register LINE
*linep
;
320 if ((s
=getregion(®ion
, curwp
->w_markp
, curwp
->w_marko
)) != TRUE
)
324 linep
= region
.r_linep
;
325 loffs
= region
.r_offset
;
326 while (region
.r_size
--) {
327 if (loffs
== llength(linep
)) {
328 linep
= lforw(linep
);
331 ac
= lgetc(linep
, loffs
);
333 lputc(linep
, loffs
, ac
);
343 * clear all the attributes of all the characters in the buffer?
344 * this is real dumb. Movement with mark set needs to be smarter!
349 register LINE
*linep
;
353 linep
= curwp
->w_linep
;
354 while(lforw(linep
) != curwp
->w_linep
){
356 for(n
=0; n
< llength(linep
); n
++){
362 linep
= lforw(linep
);