2 * ========================================================================
3 * Copyright 2006 University of Washington
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * ========================================================================
15 * Program: Region management routines
17 * The routines in this file
18 * deal with the region, that magic space
19 * between "." and mark. Some functions are
20 * commands. Some functions are just for
26 * Kill the region. Ask "getregion"
27 * to figure out the bounds of the region.
28 * Move "." to the start, and kill the characters.
32 killregion(int f
, int n
)
36 if (curbp
->b_mode
&MDVIEW
) /* don't allow this command if */
37 return(rdonly()); /* we are in read only mode */
39 if (getregion(®ion
, curwp
->w_markp
, curwp
->w_marko
) != TRUE
){
40 return (killtext(f
, n
));
45 if ((lastflag
&CFKILL
) == 0) /* This is a kill type */
46 kdelete(); /* command, so do magic */
48 thisflag
|= CFKILL
; /* kill buffer stuff. */
49 curwp
->w_dotp
= region
.r_linep
;
50 curwp
->w_doto
= region
.r_offset
;
51 curwp
->w_markp
= NULL
;
53 mswin_allowcopycut(NULL
);
56 if(ldelete(region
.r_size
, kinsert
)){
57 if(curwp
->w_dotp
== curwp
->w_linep
&& curwp
->w_dotp
== curbp
->b_linep
){
58 curwp
->w_force
= 0; /* Center dot. */
59 curwp
->w_flag
|= WFFORCE
;
70 * Blast the region without saving . Ask "getregion"
71 * to figure out the bounds of the region.
72 * Move "." to the start, and kill the characters.
76 deleteregion(int f
, int n
)
80 if (curbp
->b_mode
&MDVIEW
) /* don't allow this command if */
81 return(rdonly()); /* we are in read only mode */
83 if (getregion(®ion
, curwp
->w_markp
, curwp
->w_marko
) == TRUE
){
84 curwp
->w_dotp
= region
.r_linep
;
85 curwp
->w_doto
= region
.r_offset
;
86 curwp
->w_markp
= NULL
;
88 mswin_allowcopycut(NULL
);
90 if(ldelete(region
.r_size
, NULL
)){
91 if(curwp
->w_dotp
== curwp
->w_linep
92 && curwp
->w_dotp
== curbp
->b_linep
){
93 curwp
->w_force
= 0; /* Center dot. */
94 curwp
->w_flag
|= WFFORCE
;
106 * Copy all of the characters in the
107 * region to the kill buffer. Don't move dot
108 * at all. This is a bit like a kill region followed
109 * by a yank. Bound to "M-W".
112 copyregion(int f
, int n
)
114 register LINE
*linep
;
119 if ((s
=getregion(®ion
, curwp
->w_markp
, curwp
->w_marko
)) != TRUE
)
122 if ((lastflag
&CFKILL
) == 0) /* Kill type command. */
126 linep
= region
.r_linep
; /* Current line. */
127 loffs
= region
.r_offset
; /* Current offset. */
128 while (region
.r_size
--) {
129 if (loffs
== llength(linep
)) { /* End of line. */
130 if ((s
=kinsert('\n')) != TRUE
)
132 linep
= lforw(linep
);
134 } else { /* Middle of line. */
135 if ((s
=kinsert(lgetc(linep
, loffs
).c
)) != TRUE
)
146 * Lower case region. Zap all of the upper
147 * case characters in the region to lower case. Use
148 * the region code to set the limits. Scan the buffer,
149 * doing the changes. Call "lchange" to ensure that
150 * redisplay is done in all buffers. Bound to
154 lowerregion(int f
, int n
)
156 register LINE
*linep
;
164 if (curbp
->b_mode
&MDVIEW
) /* don't allow this command if */
165 return(rdonly()); /* we are in read only mode */
167 if ((s
=getregion(®ion
, curwp
->w_markp
, curwp
->w_marko
)) != TRUE
)
171 linep
= region
.r_linep
;
172 loffs
= region
.r_offset
;
173 while (region
.r_size
--) {
174 if (loffs
== llength(linep
)) {
175 linep
= lforw(linep
);
178 c
= lgetc(linep
, loffs
).c
;
179 if (c
>='A' && c
<='Z'){
181 lputc(linep
, loffs
, ac
);
191 * Upper case region. Zap all of the lower
192 * case characters in the region to upper case. Use
193 * the region code to set the limits. Scan the buffer,
194 * doing the changes. Call "lchange" to ensure that
195 * redisplay is done in all buffers. Bound to
199 upperregion(int f
, int n
)
201 register LINE
*linep
;
209 if (curbp
->b_mode
&MDVIEW
) /* don't allow this command if */
210 return(rdonly()); /* we are in read only mode */
212 if ((s
=getregion(®ion
, curwp
->w_markp
, curwp
->w_marko
)) != TRUE
)
216 linep
= region
.r_linep
;
217 loffs
= region
.r_offset
;
218 while (region
.r_size
--) {
219 if (loffs
== llength(linep
)) {
220 linep
= lforw(linep
);
223 c
= lgetc(linep
, loffs
).c
;
224 if (c
>='a' && c
<='z'){
225 ac
.c
= c
- 'a' + 'A';
226 lputc(linep
, loffs
, ac
);
236 * This routine figures out the
237 * bounds of the region in the current window, and
238 * fills in the fields of the "REGION" structure pointed
239 * to by "rp". Because the dot and mark are usually very
240 * close together, we scan outward from dot looking for
241 * mark. This should save time. Return a standard code.
242 * Callers of this routine should be prepared to get
243 * an "ABORT" status; we might make this have the
244 * conform thing later.
247 getregion(REGION
*rp
, LINE
*markp
, int marko
)
258 if (curwp
->w_dotp
== markp
) {
259 rp
->r_linep
= curwp
->w_dotp
;
260 if (curwp
->w_doto
< marko
) {
261 rp
->r_offset
= curwp
->w_doto
;
262 rp
->r_size
= marko
- curwp
->w_doto
;
264 rp
->r_offset
= marko
;
265 rp
->r_size
= curwp
->w_doto
- marko
;
271 bsize
= curwp
->w_doto
;
273 fsize
= llength(flp
)-curwp
->w_doto
+1;
274 while (flp
!=curbp
->b_linep
|| lback(blp
)!=curbp
->b_linep
) {
275 if (flp
!= curbp
->b_linep
) {
278 rp
->r_linep
= curwp
->w_dotp
;
279 rp
->r_offset
= curwp
->w_doto
;
280 rp
->r_size
= fsize
+ marko
;
284 fsize
+= llength(flp
) + 1;
287 if (lback(blp
) != curbp
->b_linep
) {
289 bsize
+= llength(blp
)+1;
292 rp
->r_offset
= marko
;
293 rp
->r_size
= bsize
- marko
;
299 emlwrite("Bug: lost mark", NULL
);
305 * set the highlight attribute accordingly on all characters in region
310 register LINE
*linep
;
316 if ((s
=getregion(®ion
, curwp
->w_markp
, curwp
->w_marko
)) != TRUE
)
320 linep
= region
.r_linep
;
321 loffs
= region
.r_offset
;
322 while (region
.r_size
--) {
323 if (loffs
== llength(linep
)) {
324 linep
= lforw(linep
);
327 ac
= lgetc(linep
, loffs
);
329 lputc(linep
, loffs
, ac
);
339 * clear all the attributes of all the characters in the buffer?
340 * this is real dumb. Movement with mark set needs to be smarter!
345 register LINE
*linep
;
349 linep
= curwp
->w_linep
;
350 while(lforw(linep
) != curwp
->w_linep
){
352 for(n
=0; n
< llength(linep
); n
++){
358 linep
= lforw(linep
);