1 | /* ELLE - Copyright 1982, 1984, 1987 by Ken Harrenstien, SRI International
|
---|
2 | * This software is quasi-public; it may be used freely with
|
---|
3 | * like software, but may NOT be sold or made part of licensed
|
---|
4 | * products without permission of the author.
|
---|
5 | */
|
---|
6 |
|
---|
7 | /* EEBUFF Buffer and Window functions.
|
---|
8 | * Each buffer is an independent SB-string described by a
|
---|
9 | * buffer structure. All buffer structures are allocated dynamically
|
---|
10 | * and chained together starting from buf_head.
|
---|
11 | */
|
---|
12 |
|
---|
13 | #include "elle.h"
|
---|
14 |
|
---|
15 | #if FX_FILLMODE
|
---|
16 | extern int fill_mode;
|
---|
17 | #endif
|
---|
18 | #if FX_SKMAC
|
---|
19 | extern int kdef_mode;
|
---|
20 | #endif
|
---|
21 |
|
---|
22 | struct buffer *make_buf(), *find_buf(), *sel_mbuf(), *sel_nbuf();
|
---|
23 | struct window *make_win();
|
---|
24 |
|
---|
25 | /* EFUN: "Select Buffer" */
|
---|
26 | /* Select old buffer or create a new one. Defaults to previously
|
---|
27 | * used buffer.
|
---|
28 | */
|
---|
29 | f_selbuffer()
|
---|
30 | { register char *ans;
|
---|
31 | register struct buffer *b;
|
---|
32 |
|
---|
33 | if((b = last_buf) == cur_buf) /* If default same as current, */
|
---|
34 | if(!(b = sel_mbuf(b))) /* try to pick a more useful one. */
|
---|
35 | b = sel_nbuf(cur_buf);
|
---|
36 |
|
---|
37 | ans = ask("Select buffer (%s): ",b->b_name);
|
---|
38 | if (ans == 0) /* he aborted */
|
---|
39 | return;
|
---|
40 | if (*ans != '\0') /* Null string => use last buff */
|
---|
41 | { b = find_buf (ans); /* Else find/create one */
|
---|
42 | if (b == 0)
|
---|
43 | b = make_buf (ans);
|
---|
44 | }
|
---|
45 | sel_buf(b);
|
---|
46 | chkfree(ans);
|
---|
47 | }
|
---|
48 |
|
---|
49 | #if FX_SELXBUFFER
|
---|
50 | /* EFUN: "Select Existing Buffer" (not EMACS) - from IMAGEN config */
|
---|
51 |
|
---|
52 | static int findstr();
|
---|
53 |
|
---|
54 | f_selxbuffer()
|
---|
55 | { register char *ans;
|
---|
56 | register struct buffer *b;
|
---|
57 |
|
---|
58 | b = last_buf; /* This is default */
|
---|
59 | ans = ask("Select existing buffer (%s): ", b->b_name);
|
---|
60 | if (ans == 0) /* Aborted */
|
---|
61 | return;
|
---|
62 | if (*ans != 0)
|
---|
63 | { for (b = buf_head; b != 0; b = b->b_next)
|
---|
64 | if (findstr(ans, b->b_name))
|
---|
65 | break;
|
---|
66 | if (b == 0)
|
---|
67 | ding("That isn't a substring of any buffer name!");
|
---|
68 | }
|
---|
69 | chkfree(ans);
|
---|
70 | if (b != 0)
|
---|
71 | { saytoo(" => ");
|
---|
72 | sayntoo(b->b_name);
|
---|
73 | sel_buf(b);
|
---|
74 | }
|
---|
75 | }
|
---|
76 |
|
---|
77 | static int
|
---|
78 | findstr(str, instr) /* Find "str" in string "instr" */
|
---|
79 | register char *str, *instr;
|
---|
80 | { register char *sp, *isp;
|
---|
81 |
|
---|
82 | while (*instr)
|
---|
83 | { sp = str;
|
---|
84 | isp = instr;
|
---|
85 | while (*sp)
|
---|
86 | if (*sp++ != *isp++)
|
---|
87 | goto next;
|
---|
88 | return(1);
|
---|
89 | next: ++instr;
|
---|
90 | }
|
---|
91 | return(0);
|
---|
92 | }
|
---|
93 | #endif /*FX_SELXBUFFER*/
|
---|
94 |
|
---|
95 |
|
---|
96 | /* EFUN: "Kill Buffer" */
|
---|
97 | /* Kill specified buffer - defaults to current buffer.
|
---|
98 | * This code assumes a killed buffer will never be on a window list unless it
|
---|
99 | * is pointed to by cur_buf or oth_win->w_buf!!!!
|
---|
100 | */
|
---|
101 | f_kbuffer()
|
---|
102 | { register struct buffer *b, *ob;
|
---|
103 | register char *ans;
|
---|
104 |
|
---|
105 | if((ans = ask("Kill buffer: ")) == 0)
|
---|
106 | return;
|
---|
107 | if(*ans == 0) b = cur_buf;
|
---|
108 | else if(*ans == SP) b = 0;
|
---|
109 | else b = find_buf(ans);
|
---|
110 |
|
---|
111 | chkfree(ans);
|
---|
112 | if(!b)
|
---|
113 | { ding("No such buffer");
|
---|
114 | return;
|
---|
115 | }
|
---|
116 | #if IMAGEN
|
---|
117 | if (b->b_flags & B_PERMANENT)
|
---|
118 | { ding("Permanent buffer--cannot kill!");
|
---|
119 | return;
|
---|
120 | }
|
---|
121 | if (b->b_flags & B_MODIFIED)
|
---|
122 | { if ((ans == ask("Buffer is modified; are you sure? ")) == 0)
|
---|
123 | return;
|
---|
124 | if(upcase(*ans) != 'Y')
|
---|
125 | { chkfree(ans);
|
---|
126 | return;
|
---|
127 | }
|
---|
128 | chkfree(ans);
|
---|
129 | }
|
---|
130 | #endif /*IMAGEN*/
|
---|
131 | if(b == cur_buf || (oth_win && (oth_win->w_buf == b)))
|
---|
132 | { ob = last_buf;
|
---|
133 | do
|
---|
134 | {
|
---|
135 | /* If default same as doomed buffer, try to pick
|
---|
136 | * a more useful alternative. */
|
---|
137 | if((b == ob) && !(ob = sel_mbuf(b)))
|
---|
138 | ob = sel_nbuf(b);
|
---|
139 |
|
---|
140 | ans = ask("Killing in-use buffer; select which other buffer (%s): ",
|
---|
141 | ob->b_name);
|
---|
142 | if(ans == 0) return;
|
---|
143 | if(*ans)
|
---|
144 | { if(*ans == SP) ob = 0;
|
---|
145 | else ob = find_buf(ans);
|
---|
146 | }
|
---|
147 | chkfree(ans);
|
---|
148 | if(!ob)
|
---|
149 | { ding("No such buffer");
|
---|
150 | return;
|
---|
151 | }
|
---|
152 | } while (b == ob);
|
---|
153 |
|
---|
154 | /* B is buffer to kill, OB is buffer to replace it with */
|
---|
155 | if(oth_win && (oth_win->w_buf == b))
|
---|
156 | { f_othwind(); /* Select other one */
|
---|
157 | chg_buf(ob); /* Change to new buffer */
|
---|
158 | f_othwind();
|
---|
159 | }
|
---|
160 | if(cur_buf == b)
|
---|
161 | chg_buf(ob);
|
---|
162 | }
|
---|
163 |
|
---|
164 | kill_buf(b); /* Die!!!! */
|
---|
165 | if(last_buf == b)
|
---|
166 | last_buf = cur_buf;
|
---|
167 | }
|
---|
168 |
|
---|
169 | /* EFUN: "List Buffers" */
|
---|
170 | /* Display a list of all user buffers. Internal buffers, whose names
|
---|
171 | * start with a space, are not shown.
|
---|
172 | */
|
---|
173 | f_listbufs()
|
---|
174 | {
|
---|
175 | register struct buffer *b;
|
---|
176 | register char *cp;
|
---|
177 | register int i;
|
---|
178 | struct buffer *tbuf, *savbuf;
|
---|
179 | char temp[20];
|
---|
180 |
|
---|
181 | /* First must set up special buffer... */
|
---|
182 | savbuf = cur_buf;
|
---|
183 | chg_buf(tbuf = make_buf(" **SHOW**"));
|
---|
184 | e_sputz("Buffers in this ELLE:\n\n");
|
---|
185 | for(b = buf_head; b; b = b->b_next)
|
---|
186 | { cp = b->b_name;
|
---|
187 | if(*cp == SP) continue; /* Ignore internal buffs */
|
---|
188 | e_sputz((b->b_flags&B_MODIFIED) ? "* " : " ");
|
---|
189 | e_sputz(cp); /* Insert buffer name */
|
---|
190 | dottoa(temp,ex_blen(b)); /* Get buff-length string */
|
---|
191 | if((i = ((FNAMELEN > 14) ? 30 : 20)
|
---|
192 | - strlen(cp) - strlen(temp)) > 0)
|
---|
193 | e_insn(SP, i);
|
---|
194 | e_sputz(" (");
|
---|
195 | e_sputz(temp);
|
---|
196 | e_sputz(") ");
|
---|
197 | if(cp = b->b_fn)
|
---|
198 | e_sputz(cp);
|
---|
199 | #if IMAGEN
|
---|
200 | if (b->b_flags & B_CMODE)
|
---|
201 | e_sputz(" (C)");
|
---|
202 | else if (b->b_flags & B_TEXTMODE)
|
---|
203 | e_sputz(" (Text)");
|
---|
204 | else
|
---|
205 | e_sputz(" (Fundamental)");
|
---|
206 | #endif /*IMAGEN*/
|
---|
207 | e_putc(LF);
|
---|
208 | }
|
---|
209 | mk_showin(tbuf); /* Show this buffer in temp window */
|
---|
210 | chg_buf(savbuf); /* Return to real current buffer */
|
---|
211 | kill_buf(tbuf);
|
---|
212 | }
|
---|
213 | |
---|
214 |
|
---|
215 | /* EFUN: "Buffer Not Modified" */
|
---|
216 | /* Mark the current buffer as not modified.
|
---|
217 | */
|
---|
218 | f_bufnotmod()
|
---|
219 | {
|
---|
220 | cur_buf -> b_flags &= ~B_MODIFIED;
|
---|
221 | redp(RD_MODE);
|
---|
222 | }
|
---|
223 |
|
---|
224 | #if FX_EOLMODE
|
---|
225 | /* EFUN: "EOL CRLF Mode" (not EMACS) */
|
---|
226 | /* Toggle the EOL mode of the current buffer.
|
---|
227 | ** LF EOL Mode means LF alone is an EOL.
|
---|
228 | ** CRLF EOL Mode means CRLF together is an EOL.
|
---|
229 | */
|
---|
230 | f_eolmode()
|
---|
231 | {
|
---|
232 | cur_buf->b_flags ^= B_EOLCRLF; /* Flip this bit */
|
---|
233 | say((cur_buf->b_flags & B_EOLCRLF)
|
---|
234 | ? "EOL Mode is CRLF" /* If now on */
|
---|
235 | : "EOL Mode is LF"); /* If now off */
|
---|
236 |
|
---|
237 | redp(RD_WINRES); /* Redo window for this buf */
|
---|
238 | }
|
---|
239 | #endif /*FX_EOLMODE*/
|
---|
240 | |
---|
241 |
|
---|
242 | #if FX_GOBEG
|
---|
243 | /* EFUN: "Goto Beginning" */
|
---|
244 | f_gobeg()
|
---|
245 | { e_gobob();
|
---|
246 | ed_setcur();
|
---|
247 | }
|
---|
248 | #endif /*FX_GOBEG*/
|
---|
249 |
|
---|
250 | #if FX_GOEND
|
---|
251 | /* EFUN: "Goto End" */
|
---|
252 | f_goend()
|
---|
253 | { e_goeob();
|
---|
254 | ed_setcur();
|
---|
255 | }
|
---|
256 | #endif /*FX_GOEND*/
|
---|
257 |
|
---|
258 | #if FX_WHATPAGE
|
---|
259 | /* EFUN: "What Page" */
|
---|
260 | /* Extra info added as per earlier ICONOGRAPHICS "What Buffer Position"
|
---|
261 | ** Reports on current position as follows:
|
---|
262 | ** Dot=<n>, Page <n> Line <n> (line <n> of <m>)
|
---|
263 | */
|
---|
264 | f_whatpage()
|
---|
265 | {
|
---|
266 | register chroff cnt;
|
---|
267 | register int c;
|
---|
268 | register int page, line;
|
---|
269 | int lineatp;
|
---|
270 | char tempstr[12], *dottoa ();
|
---|
271 |
|
---|
272 | saynow("Dot=");
|
---|
273 | dottoa(tempstr, cur_dot);
|
---|
274 | sayntoo(tempstr);
|
---|
275 |
|
---|
276 | e_gobob();
|
---|
277 | page = line = lineatp = 1;
|
---|
278 | for (cnt = cur_dot; --cnt >= 0;)
|
---|
279 | if ((c = e_getc()) == LF)
|
---|
280 | ++line;
|
---|
281 | else if (c == FF)
|
---|
282 | { ++page;
|
---|
283 | lineatp = line;
|
---|
284 | }
|
---|
285 |
|
---|
286 | saytoo(", Page ");
|
---|
287 | dottoa(tempstr, (chroff)page);
|
---|
288 | saytoo(tempstr);
|
---|
289 | saytoo(" Line ");
|
---|
290 | dottoa(tempstr, (chroff)(1 + line - lineatp));
|
---|
291 | saytoo(tempstr);
|
---|
292 | saytoo(" Col ");
|
---|
293 | dottoa(tempstr, (chroff)indtion(cur_dot));
|
---|
294 | saytoo(tempstr);
|
---|
295 | saytoo(" [line ");
|
---|
296 | dottoa(tempstr, (chroff)line);
|
---|
297 | saytoo(tempstr);
|
---|
298 | sayntoo(" of "); /* Force out while scan rest */
|
---|
299 |
|
---|
300 | for(e_gocur(); e_gonl() ; ++line) ; /* Count lines until EOF */
|
---|
301 | c = e_rgetc(); /* Remember what last char is */
|
---|
302 | dottoa(tempstr, (chroff)line);
|
---|
303 | saytoo(tempstr);
|
---|
304 | if (c != LF) /* Check last char */
|
---|
305 | saytoo(" (no EOL at EOF!)");
|
---|
306 | sayntoo("]");
|
---|
307 | e_gocur(); /* Back to original position */
|
---|
308 | }
|
---|
309 | #endif /*FX_WHATPAGE*/
|
---|
310 | |
---|
311 |
|
---|
312 | init_buf () /* init buffer stuff */
|
---|
313 | {
|
---|
314 | buf_head = 0;
|
---|
315 | lines_buf = cur_buf = make_buf(" **LINES**"); /* For sep_win */
|
---|
316 | e_insn('-',scr_wid-2); /* Fill with dashes */
|
---|
317 | last_buf = cur_buf = make_buf ("Main"); /* Make Main buffer */
|
---|
318 | init_win(); /* Now can init windows */
|
---|
319 | }
|
---|
320 |
|
---|
321 | struct buffer *
|
---|
322 | make_buf(bname) /* create buffer "bname" if it doesn't exist */
|
---|
323 | char *bname;
|
---|
324 | { register struct buffer *b;
|
---|
325 | register char *name;
|
---|
326 |
|
---|
327 | b = find_buf(name = bname);
|
---|
328 | if (b) /* if it exists already */
|
---|
329 | return(b);
|
---|
330 | b = (struct buffer *) memalloc(sizeof (struct buffer));
|
---|
331 | b -> b_next = buf_head; /* link it in */
|
---|
332 | buf_head = b;
|
---|
333 | b->b_name = strdup(name); /* Allocate copy of name string */
|
---|
334 | b->b_dot = 0; /* Set dot to beg */
|
---|
335 | sb_open(b,(SBSTR *)0); /* Open buffer with null initial sbstring */
|
---|
336 | b->b_fn = 0;
|
---|
337 | b->b_flags = 0;
|
---|
338 | b->b_mode = cur_mode; /* Inherit current mode */
|
---|
339 | return(b);
|
---|
340 | }
|
---|
341 |
|
---|
342 |
|
---|
343 | struct buffer *
|
---|
344 | find_buf(name) /* returns pointer to buffer of that name or 0 */
|
---|
345 | char *name;
|
---|
346 | { register struct buffer *b = buf_head;
|
---|
347 |
|
---|
348 | while (b && strcmp(b->b_name, name))
|
---|
349 | b = b -> b_next;
|
---|
350 | return(b);
|
---|
351 | }
|
---|
352 |
|
---|
353 | sel_buf(b) /* select buffer, saving last */
|
---|
354 | struct buffer *b;
|
---|
355 | {
|
---|
356 | if(b != cur_buf) last_buf = cur_buf;
|
---|
357 | chg_buf(b);
|
---|
358 | }
|
---|
359 |
|
---|
360 | chg_buf (newbuf) /* change current buffer to newbuf */
|
---|
361 | struct buffer *newbuf;
|
---|
362 | { register struct buffer *obuf, *nbuf;
|
---|
363 |
|
---|
364 | if ((nbuf = newbuf) == (obuf = cur_buf))
|
---|
365 | return; /* Do nothing if same buffers */
|
---|
366 | obuf->b_dot = cur_dot;
|
---|
367 | cur_buf = nbuf;
|
---|
368 | cur_mode = nbuf->b_mode;
|
---|
369 | e_gosetcur(nbuf->b_dot); /* Set cur_dot and go there */
|
---|
370 | cur_win->w_buf = nbuf;
|
---|
371 | cur_win->w_dot = cur_dot;
|
---|
372 | #if IMAGEN
|
---|
373 | cur_win->w_redp = RD_WINRES|RD_REDO;
|
---|
374 | #else
|
---|
375 | cur_win->w_redp = RD_WINRES; /* Reset flags - do complete update */
|
---|
376 | #endif /*-IMAGEN*/
|
---|
377 | unlk_buf(obuf); /* Unlock previous buffer if can */
|
---|
378 | mark_p = 0; /* this is lazy */
|
---|
379 | redp(RD_MODE|RD_WINRES);
|
---|
380 | }
|
---|
381 |
|
---|
382 | /* See if specified buffer belongs to any active window, and
|
---|
383 | * if not then get it into an idle, unlocked state; this helps the
|
---|
384 | * edit package compact and swap stuff out while it's not being used.
|
---|
385 | * Assumes proper state of dot has been stored into b_dot.
|
---|
386 | */
|
---|
387 | unlk_buf(bufp)
|
---|
388 | struct buffer *bufp;
|
---|
389 | { register struct buffer *b;
|
---|
390 | register struct window *w;
|
---|
391 |
|
---|
392 | b = bufp;
|
---|
393 | for(w = win_head; w; w = w->w_next)
|
---|
394 | if(b == w->w_buf)
|
---|
395 | return; /* Buffer is actively being shown */
|
---|
396 | sb_rewind((SBBUF *)b); /* Return to idle state */
|
---|
397 | }
|
---|
398 |
|
---|
399 | /* SEL_NBUF(buf) - Select next user buffer. Ignores internal buffers.
|
---|
400 | * Arg of 0 starts at beg of buffer list. Always returns
|
---|
401 | * a buffer pointer - returns argument (which may be 0)
|
---|
402 | * if found no other user buffers.
|
---|
403 | *
|
---|
404 | * SEL_MBUF(buf) - Select next modified buffer.
|
---|
405 | * Returns buffer ptr to "next" modified buffer, if any.
|
---|
406 | * Arg of 0 starts at beg of buffer list and scans all of them.
|
---|
407 | * Returns 0 if no other modified buffers exist (unlike SEL_NBUF!)
|
---|
408 | * Ignores internal buffers, whose names start with a space.
|
---|
409 | */
|
---|
410 | /* struct buffer *buf_mptr; */
|
---|
411 | #if 0
|
---|
412 | struct buffer *
|
---|
413 | sel_mbuf(buf)
|
---|
414 | struct buffer *buf;
|
---|
415 | { register struct buffer *b;
|
---|
416 | register int sweep;
|
---|
417 |
|
---|
418 | sweep = 0; /* Make 2 sweeps only */
|
---|
419 | if(b = buf) b = b->b_next;
|
---|
420 | do {
|
---|
421 | if(b == 0) /* Initialize if needed */
|
---|
422 | b = buf_head;
|
---|
423 | for(; b; b = b->b_next)
|
---|
424 | if((b->b_flags & B_MODIFIED) && (*b->b_name != SP))
|
---|
425 | return((b == buf) ? 0 : b);
|
---|
426 | } while(sweep++ != 0);
|
---|
427 | return(0);
|
---|
428 | }
|
---|
429 | #endif /*COMMENT*/
|
---|
430 |
|
---|
431 | struct buffer *
|
---|
432 | sel_mbuf(buf)
|
---|
433 | register struct buffer *buf;
|
---|
434 | { register struct buffer *b, *b2;
|
---|
435 | b = b2 = sel_nbuf(buf);
|
---|
436 | do { if(b == buf) break;
|
---|
437 | if(b->b_flags & B_MODIFIED)
|
---|
438 | return(b);
|
---|
439 | } while((b = sel_nbuf(b)) != b2);
|
---|
440 |
|
---|
441 | return(0);
|
---|
442 | }
|
---|
443 |
|
---|
444 | struct buffer *
|
---|
445 | sel_nbuf(buf)
|
---|
446 | register struct buffer *buf;
|
---|
447 | { register struct buffer *b;
|
---|
448 |
|
---|
449 | b = buf;
|
---|
450 | do {
|
---|
451 | if(!b || !(b = b->b_next))
|
---|
452 | b = buf_head;
|
---|
453 | if(*b->b_name != SP)
|
---|
454 | break;
|
---|
455 | } while (b != buf);
|
---|
456 | return(b);
|
---|
457 | }
|
---|
458 |
|
---|
459 |
|
---|
460 | kill_buf(buf)
|
---|
461 | struct buffer *buf;
|
---|
462 | { register struct buffer *b, *b1, *bt;
|
---|
463 |
|
---|
464 | b = buf;
|
---|
465 | b1 = 0;
|
---|
466 | for(bt = buf_head; bt && bt != b; bt = bt -> b_next)
|
---|
467 | b1 = bt;
|
---|
468 | if(bt == 0)
|
---|
469 | { ring_bell();
|
---|
470 | errbarf("No such buffer"); /* Internal error */
|
---|
471 | return;
|
---|
472 | }
|
---|
473 | if (b1 == 0)
|
---|
474 | buf_head = b->b_next;
|
---|
475 | else
|
---|
476 | b1->b_next = b->b_next;
|
---|
477 | sbs_del(sb_close((SBBUF *)b)); /* Close buffer & delete sbstring */
|
---|
478 | sb_fdcls(-1); /* Make sweep for unused FD's */
|
---|
479 | if(b->b_fn)
|
---|
480 | chkfree(b->b_fn); /* Flush filename if one */
|
---|
481 | chkfree(b->b_name); /* Flush name */
|
---|
482 | chkfree((char *)b); /* Flush buffer */
|
---|
483 | }
|
---|
484 | |
---|
485 |
|
---|
486 | /* ZAP_BUFFER - Delete all of the buffer, but if it's been modified,
|
---|
487 | * ask first. Returns 0 if user aborts.
|
---|
488 | */
|
---|
489 | zap_buffer()
|
---|
490 | {
|
---|
491 | #if IMAGEN
|
---|
492 | extern struct buffer *exec_buf; /* in e_make.c */
|
---|
493 |
|
---|
494 | if(cur_buf != exec_buf && cur_buf -> b_flags & B_MODIFIED)
|
---|
495 | #else
|
---|
496 | if(cur_buf -> b_flags & B_MODIFIED)
|
---|
497 | #endif /*-IMAGEN*/
|
---|
498 | if(ask_kbuf(cur_buf) <= 0)
|
---|
499 | return(0); /* Aborted */
|
---|
500 | ed_reset(); /* This takes care of redisplay too */
|
---|
501 | mark_p = 0;
|
---|
502 | #if IMAGEN
|
---|
503 | cur_buf->b_flags &= ~B_BACKEDUP; /* Clear backed-up flag */
|
---|
504 | #endif
|
---|
505 | return(1);
|
---|
506 | }
|
---|
507 |
|
---|
508 |
|
---|
509 | |
---|
510 |
|
---|
511 | /* ASK_KBUF - Ask user "are you sure?" before killing a buffer.
|
---|
512 | * Returns +1 if user says "yes" - OK to kill.
|
---|
513 | * 0 if user aborts (^G)
|
---|
514 | * -1 if user says "no".
|
---|
515 | */
|
---|
516 | ask_kbuf(buf)
|
---|
517 | struct buffer *buf;
|
---|
518 | { register struct buffer *b;
|
---|
519 | register char *s;
|
---|
520 | register int ans;
|
---|
521 |
|
---|
522 | b = buf;
|
---|
523 | s = ask("Buffer %s contains changes - forget them? ", b->b_name);
|
---|
524 | if(s == 0) return(0);
|
---|
525 | ans = (upcase(*s) == 'Y') ? 1 : -1;
|
---|
526 | chkfree(s);
|
---|
527 | return(ans);
|
---|
528 | }
|
---|
529 | |
---|
530 |
|
---|
531 | /* Window stuff */
|
---|
532 |
|
---|
533 | /* Like EMACS, ELLE only provides at most two user windows.
|
---|
534 | * The current user window is pointed to by user_win;
|
---|
535 | * the "other" one is oth_win. If oth_win == 0, there is only one user
|
---|
536 | * window.
|
---|
537 | */
|
---|
538 |
|
---|
539 | #if FX_2MODEWINDS
|
---|
540 | int sepmode_p = 0; /* Set true if separator window is a 2nd mode win */
|
---|
541 | #endif
|
---|
542 |
|
---|
543 | /* EFUN: "Two Windows" */
|
---|
544 | /* Divide the current window in half, put the current buffer in the
|
---|
545 | * other window, and go to the new window.
|
---|
546 | */
|
---|
547 | f_2winds()
|
---|
548 | { register int h, t;
|
---|
549 | register struct window *w;
|
---|
550 |
|
---|
551 | if (oth_win)
|
---|
552 | {
|
---|
553 | #if !(IMAGEN)
|
---|
554 | ding("Already 2 windows");
|
---|
555 | #endif /*-IMAGEN*/
|
---|
556 | return;
|
---|
557 | }
|
---|
558 | w = cur_win;
|
---|
559 | d_fixcur(); /* Stabilize current window */
|
---|
560 | h = (w->w_ht) / 2;
|
---|
561 | t = w->w_pos + h; /* Pos of dividing window */
|
---|
562 | sep_win = make_win(t, 1, lines_buf);
|
---|
563 | /* assume using dashes to separate */
|
---|
564 | oth_win = make_win(t + 1, w->w_ht - (h + 1), cur_buf);
|
---|
565 | /* Other window has balance */
|
---|
566 | #if FX_SOWIND
|
---|
567 | oth_win->w_flags |= cur_win->w_flags&W_STANDOUT;
|
---|
568 | sep_win->w_flags |= mode_win->w_flags&W_STANDOUT;
|
---|
569 | #endif
|
---|
570 | #if FX_2MODEWINDS
|
---|
571 | chk2modws(); /* Update 2-mode-wind status */
|
---|
572 | #endif
|
---|
573 | w->w_ht = h; /* Decrease current window to half */
|
---|
574 |
|
---|
575 | /* Minimize redisplay by moving each window's dot into
|
---|
576 | * a currently displayed area */
|
---|
577 | if(cur_dot < (oth_win->w_topldot = scr[t+1]->sl_boff))
|
---|
578 | oth_win->w_dot = oth_win->w_topldot; /* Adj bottom win */
|
---|
579 | else /* Adjust top window */
|
---|
580 | { oth_win->w_dot = cur_dot; /* Bottom keeps dot */
|
---|
581 | cur_dot = scr[t-1]->sl_boff; /* but top needs new one. */
|
---|
582 | }
|
---|
583 | f_othwind(); /* switch to other window */
|
---|
584 | redp(RD_WINDS); /* Update all windows */
|
---|
585 | }
|
---|
586 |
|
---|
587 |
|
---|
588 | /* EFUN: "One Window" */
|
---|
589 | /* Revert to using only one window; use the current buffer (unlike
|
---|
590 | * EMACS which always selects the top window's buffer)
|
---|
591 | * Ensures that current window's vars are correctly set for
|
---|
592 | * new dimensions (w_pos, w_ht, plus w_topldot to minimize redisplay),
|
---|
593 | * then kills unneeded windows.
|
---|
594 | */
|
---|
595 | f_1wind()
|
---|
596 | { register struct window *w;
|
---|
597 |
|
---|
598 | if (oth_win == 0)
|
---|
599 | {
|
---|
600 | #if (!IMAGEN)
|
---|
601 | ding("Only 1 window");
|
---|
602 | #endif /*-IMAGEN*/
|
---|
603 | return;
|
---|
604 | }
|
---|
605 | w = cur_win;
|
---|
606 | if(w->w_pos) /* If not top window */
|
---|
607 | { d_fixcur(); /* Ensure screen-line data correct */
|
---|
608 | e_go(w->w_topldot); /* Beginning from top of window, */
|
---|
609 | d_fgoloff(-w->w_pos); /* Move back enough lines */
|
---|
610 | w->w_topldot = e_dot(); /* To set new start of window */
|
---|
611 | e_gocur(); /* Then move back to orig place */
|
---|
612 | w->w_pos = 0;
|
---|
613 | }
|
---|
614 | w->w_ht += oth_win -> w_ht + 1;
|
---|
615 | kill_win (oth_win);
|
---|
616 | kill_win (sep_win);
|
---|
617 | oth_win = sep_win = 0;
|
---|
618 | #if FX_2MODEWINDS
|
---|
619 | chk2modws(); /* Update notion of whether have 2 mode winds */
|
---|
620 | #endif
|
---|
621 | redp(RD_FIXWIN|RD_WINDS|RD_MODE); /* New topldot for this window,
|
---|
622 | * and check all remaining windows */
|
---|
623 | }
|
---|
624 |
|
---|
625 | /* EFUN: "Other Window" */
|
---|
626 | /* Move to the "other" user window.
|
---|
627 | */
|
---|
628 | f_othwind ()
|
---|
629 | { if (oth_win == 0)
|
---|
630 | {
|
---|
631 | #if !(IMAGEN)
|
---|
632 | ding("Only 1 window");
|
---|
633 | #endif /*-IMAGEN*/
|
---|
634 | return;
|
---|
635 | }
|
---|
636 | chg_win(oth_win);
|
---|
637 | oth_win = user_win;
|
---|
638 | user_win = cur_win;
|
---|
639 | redp(RD_MODE);
|
---|
640 | }
|
---|
641 |
|
---|
642 | /* EFUN: "Grow Window" */
|
---|
643 | /* Grow the current window - while in two window mode,
|
---|
644 | * increase the size of the current window by the arg
|
---|
645 | * and decrease the other accordingly
|
---|
646 | */
|
---|
647 | f_growind()
|
---|
648 | { register struct window *cw, *ow;
|
---|
649 | register int e;
|
---|
650 |
|
---|
651 | if ((ow = oth_win) == 0)
|
---|
652 | {
|
---|
653 | #if !(IMAGEN)
|
---|
654 | ding("Only 1 window");
|
---|
655 | #endif /*-IMAGEN*/
|
---|
656 | return;
|
---|
657 | }
|
---|
658 | e = exp;
|
---|
659 | if((cw = cur_win)->w_pos != 0) /* If current window is on bottom */
|
---|
660 | { cw = ow; /* Then fake code to think it's top */
|
---|
661 | ow = cur_win;
|
---|
662 | e = -e;
|
---|
663 | }
|
---|
664 | if( cw->w_ht + e < 1
|
---|
665 | || ow->w_ht + e < 1)
|
---|
666 | { ding("Too much");
|
---|
667 | return;
|
---|
668 | }
|
---|
669 | cw -> w_ht += e;
|
---|
670 | ow -> w_pos += e;
|
---|
671 | ow -> w_ht -= e;
|
---|
672 | sep_win -> w_pos += e;
|
---|
673 | redp(RD_WINDS | RD_MODE); /* Update all windows */
|
---|
674 | }
|
---|
675 |
|
---|
676 | #if FX_SHRINKWIND
|
---|
677 | /* EFUN: "Shrink Window" (not EMACS) - from IMAGEN config */
|
---|
678 | f_shrinkwind()
|
---|
679 | {
|
---|
680 | if (! oth_win)
|
---|
681 | return;
|
---|
682 | f_othwind();
|
---|
683 | f_growind();
|
---|
684 | f_othwind();
|
---|
685 | }
|
---|
686 | #endif /*FX_SHRINKWIND*/
|
---|
687 |
|
---|
688 | #if FX_DELWIND
|
---|
689 | /* EFUN: "Delete Window" (not EMACS) - from IMAGEN config */
|
---|
690 | f_delwind()
|
---|
691 | {
|
---|
692 | if(!oth_win)
|
---|
693 | return;
|
---|
694 | f_othwind();
|
---|
695 | f_1wind();
|
---|
696 | }
|
---|
697 | #endif /*FX_DELWIND*/
|
---|
698 |
|
---|
699 | #if FX_SOWIND
|
---|
700 | /* EFUN: "Standout Window" (not EMACS) */
|
---|
701 | /* Toggles the display standout mode for the current window.
|
---|
702 | ** With argument of 4, toggles the standout mode for the non-buffer
|
---|
703 | ** parts of the screen, such as the ELLE mode line.
|
---|
704 | ** (This corresponds to FS INVMOD$ in EMACS)
|
---|
705 | ** With argument of 0, turns standout mode off for all windows.
|
---|
706 | */
|
---|
707 | /* It suffices to set the window flag bit and force a RD_WINRES for that
|
---|
708 | * window; the redisplay code will do the rest.
|
---|
709 | */
|
---|
710 | static void tgso_wind();
|
---|
711 |
|
---|
712 | f_sowind()
|
---|
713 | {
|
---|
714 | register struct window *w;
|
---|
715 | switch(exp)
|
---|
716 | { default: /* Toggle current window */
|
---|
717 | tgso_wind(cur_win);
|
---|
718 | break;
|
---|
719 | case 4: /* Toggle mode & separator windows */
|
---|
720 | tgso_wind(mode_win);
|
---|
721 | tgso_wind(sep_win); /* This may not exist */
|
---|
722 | break;
|
---|
723 | case 0: /* Turn off standout for all winds */
|
---|
724 | for(w = win_head; w; w = w->w_next)
|
---|
725 | if(w->w_flags&W_STANDOUT)
|
---|
726 | tgso_wind(w);
|
---|
727 | }
|
---|
728 | #if FX_2MODEWINDS
|
---|
729 | chk2modws(); /* Update notion of whether have 2 mode winds */
|
---|
730 | #endif
|
---|
731 | }
|
---|
732 |
|
---|
733 | static void
|
---|
734 | tgso_wind(w) /* Toggle standout mode for given window */
|
---|
735 | register struct window *w;
|
---|
736 | {
|
---|
737 | if (w == 0) return; /* For case of no sep_win */
|
---|
738 | if (w->w_flags & W_STANDOUT)
|
---|
739 | w->w_flags &= ~W_STANDOUT;
|
---|
740 | else w->w_flags |= W_STANDOUT;
|
---|
741 | w->w_redp |= RD_WINRES; /* Re-do this particular window */
|
---|
742 | redp(RD_CHKALL); /* Check all windows for changes */
|
---|
743 | }
|
---|
744 | #endif /*FX_SOWIND*/
|
---|
745 |
|
---|
746 |
|
---|
747 | #if FX_2MODEWINDS
|
---|
748 | /* EFUN: "Two Mode Windows" (not EMACS) */
|
---|
749 | /* With arg, sets ev_2modws to that value (0, 1, or 2).
|
---|
750 | ** No arg, toggles current setting between 0 and 2.
|
---|
751 | */
|
---|
752 |
|
---|
753 | f_2modewinds()
|
---|
754 | {
|
---|
755 | ev_2modws = exp_p ? exp : (ev_2modws ? 0 : 2);
|
---|
756 | chk2modws();
|
---|
757 | }
|
---|
758 |
|
---|
759 | /* CHK2MODWS - Called after anything changes which might affect
|
---|
760 | ** whether 2 mode windows are in effect or not. Fixes up
|
---|
761 | ** sep_win to either be or not be a mode window.
|
---|
762 | */
|
---|
763 | chk2modws()
|
---|
764 | { register struct window *w;
|
---|
765 | static struct buffer *sep_buf = 0;
|
---|
766 |
|
---|
767 | if(!(w = sep_win))
|
---|
768 | { sepmode_p = 0; /* Don't have 2 windows at all */
|
---|
769 | return;
|
---|
770 | }
|
---|
771 | sepmode_p = (ev_2modws == 1)
|
---|
772 | ? (mode_win->w_flags&W_STANDOUT)
|
---|
773 | : ev_2modws;
|
---|
774 |
|
---|
775 | if(sepmode_p) /* Turn 2-mode-winds on? */
|
---|
776 | {
|
---|
777 | if(!sep_buf)
|
---|
778 | sep_buf = make_buf(" **SEPMODE**");
|
---|
779 | w->w_buf = sep_buf;
|
---|
780 | w->w_flags |= W_MODE;
|
---|
781 | }
|
---|
782 | else /* Turn 2-mode-winds off */
|
---|
783 | { w->w_buf = lines_buf;
|
---|
784 | w->w_flags &= ~W_MODE;
|
---|
785 | redp(RD_CHKALL); /* No longer a mode win, so must */
|
---|
786 | /* check all to ensure it's updated */
|
---|
787 | }
|
---|
788 | w->w_redp |= RD_WINRES;
|
---|
789 | redp(RD_MODE);
|
---|
790 | }
|
---|
791 | #endif /*FX_2MODEWINDS*/
|
---|
792 | |
---|
793 |
|
---|
794 | init_win ()
|
---|
795 | {
|
---|
796 | win_head = 0;
|
---|
797 | oth_win = 0;
|
---|
798 | user_win = make_win(0, scr_ht - (ECHOLINES+1), cur_buf); /* Main */
|
---|
799 | mode_win = make_win(scr_ht - (ECHOLINES+1), 1, make_buf(" **MODE**"));
|
---|
800 | ask_win = make_win(scr_ht - ECHOLINES, 1, make_buf(" **ASK**"));
|
---|
801 | #if FX_SOWIND
|
---|
802 | if(ev_modwso)
|
---|
803 | mode_win->w_flags |= W_STANDOUT;
|
---|
804 | #endif
|
---|
805 |
|
---|
806 | cur_win = user_win;
|
---|
807 | }
|
---|
808 |
|
---|
809 | chg_win(newwin) /* change current window to newwin */
|
---|
810 | struct window *newwin;
|
---|
811 | {
|
---|
812 | cur_win->w_dot = cur_dot; /* Save window's current dot */
|
---|
813 | cur_win->w_redp |= rd_type&RDS_WINFLGS; /* and its redisplay flags */
|
---|
814 | cur_win = newwin; /* OK, switch to new current window */
|
---|
815 | cur_buf = newwin->w_buf; /* Set new buffer from win */
|
---|
816 | e_gosetcur(newwin->w_dot); /* Set new cur_dot from win too */
|
---|
817 | /* Note done this way to canonicalize the location
|
---|
818 | ** (may be past new EOB) and ensure SB buffer
|
---|
819 | ** internals agree with cur_dot.
|
---|
820 | */
|
---|
821 | rd_type &= ~RDS_WINFLGS; /* Remove old per-window flags */
|
---|
822 | redp(RD_WINRES|RD_MODE); /* Maybe caller shd handle? */
|
---|
823 | /* Note WINRES must be set in case we are pointing
|
---|
824 | * to a buffer that was modified while we were in
|
---|
825 | * the other window!
|
---|
826 | */
|
---|
827 | }
|
---|
828 |
|
---|
829 |
|
---|
830 | struct window *
|
---|
831 | make_win (pos, ht, buf)
|
---|
832 | int pos, ht;
|
---|
833 | struct buffer *buf;
|
---|
834 | { register struct window *w;
|
---|
835 | register struct buffer *b;
|
---|
836 |
|
---|
837 | b = buf;
|
---|
838 | w = (struct window *) memalloc(sizeof (struct window));
|
---|
839 | w->w_flags = 0;
|
---|
840 | w->w_pos = pos;
|
---|
841 | w->w_ht = ht;
|
---|
842 | w->w_buf = b;
|
---|
843 | w->w_dot = b->b_dot; /* Set dot from buffer value */
|
---|
844 | w->w_topldot = 0; /* Set top of window to beg of buffer */
|
---|
845 | w->w_pct = 200; /* Assume "ALL" */
|
---|
846 | w->w_bmod = 0;
|
---|
847 | w->w_emod = 0;
|
---|
848 | w->w_oldz = 0;
|
---|
849 | w->w_redp = RD_WINRES; /* Window will need complete update */
|
---|
850 | w->w_next = win_head; /* Done, now link it in */
|
---|
851 | win_head = w;
|
---|
852 | return (w);
|
---|
853 | }
|
---|
854 |
|
---|
855 | kill_win (win)
|
---|
856 | struct window *win;
|
---|
857 | { register struct window *w, *w1, *kw;
|
---|
858 |
|
---|
859 | kw = win;
|
---|
860 | w1 = 0;
|
---|
861 | for (w = win_head; w && w != kw; w = w -> w_next)
|
---|
862 | w1 = w;
|
---|
863 | if (w == 0)
|
---|
864 | { ring_bell();
|
---|
865 | errbarf("No such window"); /* Internal error */
|
---|
866 | return;
|
---|
867 | }
|
---|
868 | if (w1 == 0)
|
---|
869 | win_head = w -> w_next;
|
---|
870 | else
|
---|
871 | w1 -> w_next = w -> w_next;
|
---|
872 | kw->w_buf->b_dot = (kw == cur_win) ? cur_dot : kw->w_dot;
|
---|
873 | chkfree (kw);
|
---|
874 | #if IMAGEN /* Not needed? */
|
---|
875 | redp (RD_WINRES|RD_WINDS|RD_REDO);
|
---|
876 | #endif /*IMAGEN*/
|
---|
877 | }
|
---|
878 | |
---|
879 |
|
---|
880 | /*
|
---|
881 | * "Show-window" routines, used to set up, step through, and close a
|
---|
882 | * temporary "show" window.
|
---|
883 | * MK_SHOWIN(bufp)
|
---|
884 | * UP_SHOWIN()
|
---|
885 | * KL_SHOWIN()
|
---|
886 | */
|
---|
887 |
|
---|
888 | /* MK_SHOWIN(bufp) - Temporarily display a buffer
|
---|
889 | */
|
---|
890 | mk_showin(b)
|
---|
891 | struct buffer *b;
|
---|
892 | { register struct window *w;
|
---|
893 | register int i;
|
---|
894 | int moreflg, intflg; /* Interrupt flag */
|
---|
895 | struct window *savwin;
|
---|
896 |
|
---|
897 | /* First must set up special window... */
|
---|
898 | savwin = cur_win;
|
---|
899 | chg_win(w = make_win(0, scr_ht-(ECHOLINES+3), b));
|
---|
900 | redo:
|
---|
901 | d_fixcur(); /* Fix up screen image of current window */
|
---|
902 |
|
---|
903 | /* Find how many lines actually used, and reduce size to that */
|
---|
904 | i = w->w_ht;
|
---|
905 | while(--i >= 0)
|
---|
906 | {
|
---|
907 | if(scr[i]->sl_boff != w->w_oldz) break;
|
---|
908 | }
|
---|
909 | if(++i <= 0)
|
---|
910 | goto skipit; /* Punt the whole thing */
|
---|
911 | if(!(moreflg = (i >= w->w_ht)))
|
---|
912 | w->w_ht = i; /* Reduce size of window */
|
---|
913 |
|
---|
914 | intflg = upd_wind(w); /* Update the window! */
|
---|
915 | if(!intflg) /* Unless input waiting, add prompt. */
|
---|
916 | {
|
---|
917 | yellat( moreflg ?
|
---|
918 | "--MORE-- (type Space for more, or type any command to flush)" :
|
---|
919 | "------------------------------------------------ (Hit space to continue)--",
|
---|
920 | w->w_ht);
|
---|
921 |
|
---|
922 | }
|
---|
923 | tbufls(); /* Ensure all output forced out */
|
---|
924 | i = cmd_read(); /* then wait for user to input a char */
|
---|
925 | if(i == SP)
|
---|
926 | { if(moreflg)
|
---|
927 | { yellat("", w->w_ht);
|
---|
928 | d_screen(1);
|
---|
929 | w->w_redp |= RD_WINRES;
|
---|
930 | goto redo;
|
---|
931 | }
|
---|
932 | }
|
---|
933 | #if !(IMAGEN) /* IMAGEN - always ignore what was typed */
|
---|
934 | else unrchf = i;
|
---|
935 | #endif /*-IMAGEN*/
|
---|
936 | skipit: chg_win(savwin);
|
---|
937 | kill_win(w);
|
---|
938 | redp(RD_WINDS); /* Update all remaining windows */
|
---|
939 | }
|
---|
940 | |
---|
941 |
|
---|
942 | /* Mode Line generation */
|
---|
943 |
|
---|
944 | struct window *
|
---|
945 | make_mode(bw)
|
---|
946 | register struct window *bw; /* Base window we are reporting status of */
|
---|
947 | {
|
---|
948 | register struct buffer *b; /* Buffer of this window */
|
---|
949 | struct window *mw, *savew; /* Save current window */
|
---|
950 | struct buffer *saveb; /* and current buffer (in case different) */
|
---|
951 | char temp[20];
|
---|
952 |
|
---|
953 | saveb = cur_buf; /* Save values prior to context switch */
|
---|
954 | savew = cur_win;
|
---|
955 | b = bw->w_buf; /* Get buffer for that window */
|
---|
956 |
|
---|
957 | #if FX_2MODEWINDS
|
---|
958 | if((mw = sep_win) && (mw->w_flags&W_MODE) &&
|
---|
959 | (bw->w_pos == 0)) /* Base window is top window? */
|
---|
960 | { /* Use sep_win as mode wind */
|
---|
961 | }
|
---|
962 | else
|
---|
963 | #endif
|
---|
964 | mw = mode_win; /* Default is normal mode window */
|
---|
965 | chg_win(mw); /* Go to mode line window */
|
---|
966 | e_gobob(); /* go to beginning */
|
---|
967 | e_reset(); /* Flush buffer */
|
---|
968 | #if IMAGEN
|
---|
969 | e_sputz(" ");
|
---|
970 | e_sputz(b->b_name);
|
---|
971 | if (b -> b_flags & B_MODIFIED)
|
---|
972 | e_sputz("*");
|
---|
973 | e_sputz(" (");
|
---|
974 | if (b->b_flags & B_QUERYREP)
|
---|
975 | e_sputz("[Query Replace] ");
|
---|
976 | if (b->b_flags & B_CMODE)
|
---|
977 | e_sputz("C");
|
---|
978 | else if (b->b_flags & B_TEXTMODE)
|
---|
979 | e_sputz("Text");
|
---|
980 | else
|
---|
981 | e_sputz("Fundamental");
|
---|
982 | e_sputz(") ");
|
---|
983 | if (b->b_fn)
|
---|
984 | e_sputz(b->b_fn);
|
---|
985 | e_sputz(" ");
|
---|
986 | #else
|
---|
987 | e_sputz(ev_verstr); /* Editor name/version */
|
---|
988 | e_sputz(" (");
|
---|
989 | e_sputz(cur_mode->mjm_name); /* insert major mode name */
|
---|
990 | #if FX_FILLMODE
|
---|
991 | if(fill_mode) e_sputz(" Fill");
|
---|
992 | #endif /*FX_FILLMODE*/
|
---|
993 | #if FX_SKMAC
|
---|
994 | if(kdef_mode) e_sputz(" MacroDef");
|
---|
995 | #endif /*FX_SKMAC*/
|
---|
996 | e_sputz(") ");
|
---|
997 | e_sputz(b->b_name); /* buffer name */
|
---|
998 | e_sputz(": ");
|
---|
999 | if (b->b_fn)
|
---|
1000 | e_sputz(b->b_fn); /* file name */
|
---|
1001 | if (b->b_flags & B_MODIFIED)
|
---|
1002 | e_sputz(" *");
|
---|
1003 | else e_sputz(" ");
|
---|
1004 | #endif /*-IMAGEN*/
|
---|
1005 | if(bw->w_pct < 200) /* Not ALL? */
|
---|
1006 | { e_sputz(" --");
|
---|
1007 | switch(bw->w_pct)
|
---|
1008 | { case -1:
|
---|
1009 | e_sputz("TOP");
|
---|
1010 | break;
|
---|
1011 | case 150:
|
---|
1012 | e_sputz("BOT");
|
---|
1013 | break;
|
---|
1014 | default:
|
---|
1015 | dottoa(&temp[0],(chroff)bw->w_pct);
|
---|
1016 | e_sputz(&temp[0]);
|
---|
1017 | e_putc('%');
|
---|
1018 | }
|
---|
1019 | e_sputz("--");
|
---|
1020 | }
|
---|
1021 | #if FX_SOWIND
|
---|
1022 | if(mw->w_flags&W_STANDOUT)
|
---|
1023 | e_insn(SP, (int)(scr_wd0 - e_blen())); /* Stuff out with spaces */
|
---|
1024 | #endif
|
---|
1025 |
|
---|
1026 | redp(RD_WINRES);
|
---|
1027 | chg_win(savew); /* Restore context */
|
---|
1028 | chg_buf(saveb);
|
---|
1029 | return(mw); /* Return mode window */
|
---|
1030 | }
|
---|
1031 |
|
---|
1032 |
|
---|
1033 | buf_mod()
|
---|
1034 | { register struct buffer *b;
|
---|
1035 |
|
---|
1036 | b = cur_buf;
|
---|
1037 | if((b->b_flags & B_MODIFIED) == 0)
|
---|
1038 | { b->b_flags |= B_MODIFIED;
|
---|
1039 | redp(RD_MODE);
|
---|
1040 | }
|
---|
1041 | }
|
---|
1042 |
|
---|
1043 | /* BUF_TMOD - called when text modified in buffer, to set all
|
---|
1044 | * the appropriate indicators so that redisplay works right.
|
---|
1045 | * Changed text is everything from CUR_DOT to the given offset
|
---|
1046 | * from same. If stuff was deleted, offset should be 0.
|
---|
1047 | * BUF_TMAT - similar but argument is location of other end of range,
|
---|
1048 | * when caller knows that and wants life easy.
|
---|
1049 | */
|
---|
1050 |
|
---|
1051 | buf_tmat(dot)
|
---|
1052 | chroff dot;
|
---|
1053 | { buf_tmod(dot - cur_dot); /* Convert to offset */
|
---|
1054 | }
|
---|
1055 | buf_tmod(offset)
|
---|
1056 | chroff offset;
|
---|
1057 | { register struct window *w;
|
---|
1058 | chroff a, b, tmp;
|
---|
1059 |
|
---|
1060 | w = cur_win;
|
---|
1061 | a = cur_dot;
|
---|
1062 | b = a + offset;
|
---|
1063 | if(a > b) /* Get into right order */
|
---|
1064 | { tmp = a;
|
---|
1065 | a = b;
|
---|
1066 | b = tmp;
|
---|
1067 | }
|
---|
1068 | b = e_blen() - b; /* Make upper bound relative to EOB */
|
---|
1069 | if(w->w_bmod < 0) /* Have range vars been set yet? */
|
---|
1070 | { w->w_bmod = a; /* Nope, so can just set 'em now. */
|
---|
1071 | w->w_emod = b;
|
---|
1072 | }
|
---|
1073 | else
|
---|
1074 | { if(a < w->w_bmod)
|
---|
1075 | w->w_bmod = a;
|
---|
1076 | if(b < w->w_emod)
|
---|
1077 | w->w_emod = b;
|
---|
1078 | }
|
---|
1079 | buf_mod(); /* Maybe later just insert here? */
|
---|
1080 | redp(RD_TMOD);
|
---|
1081 | }
|
---|