1 /* ELLE - Copyright 1982, 1985, 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.
7 * EEFILL Fill Mode functions
12 extern int ev_fcolumn
; /* Fill Column variable (defined in EEVINI) */
14 char *fill_prefix
; /* Fill Prefix variable */
15 int fill_plen
; /* Length of Fill Prefix (0 = no prefix) */
19 int fill_mode
= 0; /* TRUE when Auto Fill Mode is on */
20 int *fill_trig
; /* Pointer to fill-trigger chbit array */
21 static char *fill_initrig
= " \t.,;:)!";
22 #endif /*FX_FILLMODE*/
24 /* Following stuff for testing routines on */
28 0123456789012345678901234567890123456789012345678901234567890123456789012345
30 Okay... more stuff to hack. Okay. a b c d e f g h i j k l m
31 n o p q r s t u v w x y z dfsd stuff to hack 01234 Okay testing
32 more stuff to hack. Okay... more stuff to hack more stuff to
33 hack. Okay... more stuff to line long stuff to hack. Okay...
34 even more gap and. period. okay, end of stuff.
35 This is another fence.
40 /* EFUN: "Set Fill Column" */
45 linel
= exp_p
? exp
: d_curind();
46 if(linel
< 0) linel
= 0;
47 say("Fill column = ");
48 dottoa(temp
,(chroff
)linel
);
56 /* EFUN: "Set Fill Prefix" */
61 if((i
= cur_dot
- e_boldot()) > MAXLINE
)
62 { ding("Absurd Fill Prefix");
66 { chkfree(fill_prefix
);
74 { fill_prefix
= cp
= memalloc((SBMO
)(i
+1));
77 do { *cp
++ = e_getc(); }
82 say("Fill Prefix = \"");
88 /* TSTFILLP(lim) - Check for existence of Fill Prefix at current dot. If
89 * not there, returns 0 without changing dot. If there, returns
90 * 1 and leaves dot immediately after the Fill Prefix.
91 * Lim = # of chars allowed to scan from buffer.
99 if(!(i
= fill_plen
) || (i
> lim
))
103 do { if(*cp
++ != e_getc())
112 #if FX_FILLREG || FX_FILLPARA
114 /* ED_FILL(start, end, flag) - Fill a region.
115 * Flag 0 for full filling; extra whitespace is flushed. First
116 * word is always retained.
117 * 1 for skimpy filling such as Auto-Fill likes.
118 * Extra whitespace is NOT flushed, except at
119 * beginning of a newly created line.
120 * This is not yet implemented however.
121 * Note: updates cur_dot to compensate for changes in buffer, and returns
123 * Note: Checks for Fill Prefix when it exists.
125 ed_fill(begloc
, endloc
, flag
)
126 chroff begloc
, endloc
;
129 register int len
, lastc
;
134 parlen
= endloc
- begloc
;
140 len
= d_curind(); /* Set up current col */
143 /* If at beg of line, check for fill prefix and skip over it */
144 if((len
== 0) && tstfillp(parlen
))
145 { parlen
-= fill_plen
;
149 lastbrk
= 0; /* Put next word on no matter what. */
154 if (c
!= ')' && c
!= '"') /* allow for two sp after .) or ." */
155 #endif /*ICONOGRAPHICS*/
157 if(--parlen
< 0) break;
162 /* If at beg of line, check for fill prefix and flush it */
163 if((c
== LF
) && tstfillp(parlen
))
164 { e_igoff(-(fill_plen
+1));
166 e_deln((chroff
)fill_plen
);
168 if(cur_dot
>= e_dot())
169 cur_dot
-= fill_plen
;
172 if(c
== TAB
|| c
== LF
) /* Replace tabs+eols by sps */
173 { e_backc(); /* Back up 1 */
179 if(cur_dot
> e_dot()) --cur_dot
;
183 if(lastc
== '.' || lastc
== '!' || lastc
== '?'
186 #endif /*ICONOGRAPHICS*/
188 { if(--parlen
< 0) goto done
;
189 if((c
= e_getc()) == EOF
)
195 if(cur_dot
>= e_dot()) ++cur_dot
;
200 if (c
== BS
) /* adjust for backspaces */
201 if ((len
-= 2) < 0) len
= 0;
202 #endif /*ICONOGRAPHICS*/
204 if(++len
> ev_fcolumn
&& lastbrk
) /* If went too far */
205 { c
= lastbrk
- len
; /* Must put EOL at last SP */
207 parlen
-= c
; /* C is negative, actually adding */
212 c
= SP
; /* Pretend this char was space */
215 { if(cur_dot
>= e_dot())
216 cur_dot
+= fill_plen
;
217 /* Better hope no nulls in prefix! */
218 e_sputz(fill_prefix
);
224 done
: savloc
= cur_dot
;
225 e_setcur(); /* Reached paragraph end, set cur_dot temporarily */
226 buf_tmod(begloc
-cur_dot
); /* So that proper range is marked */
227 e_gosetcur(savloc
); /* Then restore original cur_dot */
229 #endif /*FX_FILLREG || FX_FILLPARA*/
233 /* EFUN: "Auto Fill Mode" */
234 /* Toggles Auto Fill Mode (a minor mode). */
239 fill_mode
= fill_mode
? 0 : 1;
241 { fill_trig
= chballoc(128);
242 for(cp
= fill_initrig
; *cp
; ++cp
)
243 chbis(fill_trig
, *cp
);
248 /* Called by F_INSSELF to handle char insertion in Auto Fill mode */
253 if(chbit(fill_trig
, c
))
262 register int foundit
, i
;
263 chroff lastbrkdot
, boldot
;
267 /* First back up to find place to make first break. */
269 lastbrkdot
= e_dot();
271 for(foundit
= 0; foundit
>= 0;)
272 { if((i
= d_curind()) <= ev_fcolumn
)
278 while (!c_wsp (e_rgetc ())) ;
280 lastbrkdot
= e_dot();
281 if(lastbrkdot
<= boldot
)
282 { lastbrkdot
= boldot
;
288 ed_fill(lastbrkdot
, e_eoldot(), 1);
290 #endif /*FX_FILLMODE*/
295 /* EFUN: "Text Mode Toggle" (not EMACS) */
298 cur_buf
->b_flags
^= B_TEXTMODE
;
301 #endif /*FX_TEXTMODE*/
303 int curr_indent
= -1; /* Current indent (for text mode autowrap) */
304 /* (misnomered: actually current column) */
305 chroff best_break
; /* Best break point so far */
308 /* Fill-mode version of "Insert Self" */
313 register int ind
, flags
= cur_buf
->b_flags
;
315 /* In Text mode, auto-wrap happens at spaces after fill column */
316 if (c
== SP
&& flags
& B_TEXTMODE
&& exp
== 1 && magic_wrap(c
))
319 /* In C-mode, tab stops are every 4 columns */
320 else if (c
== TAB
&& flags
& B_CMODE
&&
321 (ind
= magic_backto_bol()) >= 0)
322 ed_indto((ind
+ 4) & ~3);
326 /* Keep track of indent, once we have a grip on it */
327 if (last_cmd
== INSCMD
&& curr_indent
!= -1)
328 { this_cmd
= INSCMD
; /* Keep the ball rolling */
330 curr_indent
= ((curr_indent
+ 8) & ~7)
334 else if (c
< SP
|| c
> 0176)
335 curr_indent
+= (2 * exp
);
342 /* Fill-mode version of "Delete Character" */
345 { /* In C mode, deleting at BOL should do fake TAB preservation */
346 if (cur_buf
->b_flags
& B_CMODE
)
348 register int c
, indent
;
351 { /* Only hack this at BOL */
358 while ((c
= e_getc()) == SP
|| c
== TAB
)
362 indent
= (indent
+ 8) & ~7;
365 { ed_delete(savdot
, e_dot());
366 ed_indto((indent
- 4) & ~3);
367 f_begline(); /* HACK!!!! */
375 normal
: return (ef_deln(exp
));
378 /* Fill-mode version of "Backward Delete Character" */
383 /* If in C mode, and deleting into white space at BOL, hack tabs */
384 if (exp
== 1 && cur_buf
->b_flags
& B_CMODE
&&
385 (ind
= magic_backto_bol()) > 0)
386 ed_indto(ind
< 4 ? ind
- 1 : ((ind
- 4) & ~3));
388 return (ef_deln (-exp
));
391 /* Fill-mode version of "CRLF" */
397 && e_lblankp() && e_lblankp())
401 ed_delete(e_dot(), e_eoldot());
406 if (cur_buf
->b_flags
& B_TEXTMODE
&& exp
== 1 &&
417 /* Do all magic for auto-wrap in Text mode:
418 * return as did wrap (i.e., everything is taken care of)
421 int tc
; /* "trigger char" */
423 register int c
, indent
, i
, nc
;
424 chroff savdot
, modstart
, breakdot
;
428 if (last_cmd
== INSCMD
&& curr_indent
!= -1)
429 { indent
= curr_indent
; /* Already know our indent */
430 breakdot
= best_break
;
435 barf2("Full indent calculation");
437 for (nc
= 0; (c
= e_rgetc()) != EOF
&& c
!= '\n'; ++nc
)
438 ; /* nc: # chars to look at */
439 if (c
== '\n') /* Go back over NL */
443 /* Search for last line break point, leaving it in breakdot */
444 breakdot
= (chroff
)0;
448 indent
= (indent
+ 8) & ~7;
449 else if (c
< SP
|| c
> 0176)
453 if ((c
== SP
|| c
== TAB
) &&
454 (breakdot
== (chroff
)0 || (indent
<= ev_fcolumn
)))
459 /* If there is nothing to do, get out */
460 if (indent
<= ev_fcolumn
)
463 { curr_indent
= indent
;
464 best_break
= (chroff
)(savdot
+ 1); /* Remember here, also */
465 this_cmd
= INSCMD
; /* We do know current indent */
469 best_break
= (chroff
)0;
473 errbarf("bad trigger");
477 if (breakdot
== (chroff
)0)
479 /* No breakpoint found or none needed, just break line at end
487 /* Get to breakpoint and replace with newline
491 modstart
= e_dot(); /* Remember where changes start */
492 e_putc('\n'); /* Insert line break */
493 e_go(savdot
); /* Get back to trigger point */
495 if (e_rgetc() != '\n')
496 { /* If not at line start, */
498 e_putc(tc
); /* insert trigger character */
500 /* Once again, compute new indent by backing up to BOL */
501 for (nc
= 0; (c
= e_rgetc()) != EOF
&& c
!= '\n'; ++nc
)
503 if (c
== '\n') /* Go back over NL */
506 breakdot
= (chroff
)0;
508 { /* Get back to current dot */
511 indent
= (indent
+ 8) & ~7;
512 else if (c
< SP
|| c
> 0176)
516 if ((c
== SP
|| c
== TAB
) &&
517 (breakdot
== (chroff
)0 || (indent
<= ev_fcolumn
)))
520 if (breakdot
== (chroff
)0) /* If no good break found, use dot */
522 curr_indent
= indent
; /* Now we know where we are */
523 if (tc
== '\n') /* If trigger was NL */
524 best_break
= (chroff
)0; /* indent is 0, and no best break */
526 best_break
= breakdot
; /* This is best break so far */
530 curr_indent
= 0; /* At line start, no indent */
531 best_break
= (chroff
)0; /* Do not have a best break so far */
534 buf_tmat(modstart
); /* Alert to potential changes */
535 this_cmd
= INSCMD
; /* Say we know where we are */
539 /* Do lots of magic things for C-mode indent:
540 * erase back to BOL iff we are looking back at white space only,
541 * returning the indent level of the original dot
542 * (< 0 means no erasure done)
544 /*#define MYDEBUG /* */
546 reveal(msg
, v1
, v2
, v3
)
550 sprintf(ahint
, msg
, v1
, v2
, v3
);
558 register int c
, indent
, nc
, i
;
562 while ((c
= e_rgetc()) != EOF
&& c
!= LF
)
563 { ++nc
; /* Count # chars */
564 if (c
!= SP
&& c
!= TAB
)
567 reveal("fail: nc: %d", nc
);
572 if (c
== LF
) /* Go back over the LF */
574 indent
= 0; /* (zero-based indent) */
575 savdot
= e_dot(); /* BOL is now origin for delete */
576 for (i
= 1; i
<= nc
; ++i
)
577 if ((c
= e_getc()) == SP
)
580 indent
= (indent
+ 8) & ~7;
581 if (nc
> 0) /* Don't bother deleting nothing */
582 ed_delete(savdot
, e_dot());
584 reveal("indent: %d, nc: %d, foo: %d", indent
, nc
, 234);
591 /* Iconographics hack for Auto-Fill mode. Too big and clumsy, but
592 * retained for posterity in case it has some obscure feature.
597 chroff startpos
, endpos
, savepos
, limitpos
;
602 while (d_curind() > ev_fcolumn
)
607 while (d_curind() > ev_fcolumn
) /* back up to ends of wds*/
608 { /* until <= fill column */
609 while (!c_wsp (e_rgetc ())) ;
612 if (e_dot () == e_boldot ())
613 { /* ding ("Word does not fit in fill column"); */
616 savep
= e_copyn (startpos
- e_dot ());
617 e_setcur (); /* ed_delete does gocur */
618 ed_delete (savepos
= e_dot (), startpos
);
620 f_crlf(); /* Now insert newline */
621 e_sputz(fill_prefix
); /* With fill prefix */
622 startpos
+= e_dot () - savepos
;
623 if (d_curind() > ev_fcolumn
)
624 { ed_delete (savepos
, e_dot ());
625 sb_sins (cur_buf
, savep
);
627 ding ("Fill prefix > fill column???");
630 savepos
= e_dot (); /* gun inherited initial whitespace */
631 sb_sins (cur_buf
, savep
);
634 if ((limitpos
= e_dot ()) > startpos
) limitpos
= startpos
;
635 /* in case rest of line was white */
636 ed_delete (savepos
, limitpos
);
637 e_gosetcur (startpos
+ savepos
- limitpos
);
642 #endif /*ICONOGRAPHICS*/