1073 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1073 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* ELLE - Copyright 1982, 1984, 1987 by Ken Harrenstien, SRI International
 | 
						||
 *	This software is quasi-public; it may be used freely with
 | 
						||
 *	like software, but may NOT be sold or made part of licensed
 | 
						||
 *	products without permission of the author.
 | 
						||
 */
 | 
						||
 | 
						||
/* EEBUFF	Buffer and Window functions.
 | 
						||
 *	Each buffer is an independent SB-string described by a
 | 
						||
 *	buffer structure.  All buffer structures are allocated dynamically
 | 
						||
 *	and chained together starting from buf_head.
 | 
						||
 */
 | 
						||
 | 
						||
#include "elle.h"
 | 
						||
 | 
						||
#if FX_FILLMODE
 | 
						||
extern int fill_mode;
 | 
						||
#endif
 | 
						||
#if FX_SKMAC
 | 
						||
extern int kdef_mode;
 | 
						||
#endif
 | 
						||
 | 
						||
struct buffer *make_buf(), *find_buf(), *sel_mbuf(), *sel_nbuf();
 | 
						||
struct window *make_win();
 | 
						||
 | 
						||
/* EFUN: "Select Buffer" */
 | 
						||
/*	Select old buffer or create a new one.  Defaults to previously
 | 
						||
 *	used buffer.
 | 
						||
 */
 | 
						||
f_selbuffer()
 | 
						||
{	register char *ans;
 | 
						||
	register struct buffer *b;
 | 
						||
 | 
						||
	if((b = last_buf) == cur_buf)	/* If default same as current, */
 | 
						||
		if(!(b = sel_mbuf(b)))	/* try to pick a more useful one. */
 | 
						||
			b = sel_nbuf(cur_buf);
 | 
						||
 | 
						||
	ans = ask("Select buffer (%s): ",b->b_name);
 | 
						||
	if (ans == 0)		       /* he aborted */
 | 
						||
		return;
 | 
						||
	if (*ans != '\0')		/* Null string => use last buff */
 | 
						||
	  {	b = find_buf (ans);	/* Else find/create one */
 | 
						||
		if (b == 0)
 | 
						||
			b = make_buf (ans);
 | 
						||
	  }
 | 
						||
	sel_buf(b);
 | 
						||
	chkfree(ans);
 | 
						||
}
 | 
						||
 | 
						||
#if FX_SELXBUFFER
 | 
						||
/* EFUN: "Select Existing Buffer" (not EMACS) - from IMAGEN config */
 | 
						||
 | 
						||
static int findstr();
 | 
						||
 | 
						||
f_selxbuffer()
 | 
						||
{	register char *ans;
 | 
						||
	register struct buffer *b;
 | 
						||
 | 
						||
	b = last_buf;			/* This is default */
 | 
						||
	ans = ask("Select existing buffer (%s): ", b->b_name);
 | 
						||
	if (ans == 0)			/* Aborted */
 | 
						||
		return;
 | 
						||
	if (*ans != 0)
 | 
						||
	  {	for (b = buf_head; b != 0; b = b->b_next)
 | 
						||
			if (findstr(ans, b->b_name))
 | 
						||
				break;
 | 
						||
		if (b == 0)
 | 
						||
			ding("That isn't a substring of any buffer name!");
 | 
						||
	  }
 | 
						||
	chkfree(ans);
 | 
						||
	if (b != 0)
 | 
						||
	  {	saytoo(" => ");
 | 
						||
		sayntoo(b->b_name);
 | 
						||
		sel_buf(b);
 | 
						||
	  }
 | 
						||
}
 | 
						||
 | 
						||
static int
 | 
						||
findstr(str, instr)			/* Find "str" in string "instr" */
 | 
						||
register char *str, *instr;
 | 
						||
{	register char *sp, *isp;
 | 
						||
 | 
						||
	while (*instr)
 | 
						||
	  {	sp = str;
 | 
						||
		isp = instr;
 | 
						||
		while (*sp)
 | 
						||
			if (*sp++ != *isp++)
 | 
						||
				goto next;
 | 
						||
		return(1);
 | 
						||
next:		++instr;
 | 
						||
	  }
 | 
						||
	return(0);
 | 
						||
}
 | 
						||
#endif /*FX_SELXBUFFER*/
 | 
						||
 | 
						||
 | 
						||
/* EFUN: "Kill Buffer"	*/
 | 
						||
/*	Kill specified buffer - defaults to current buffer.
 | 
						||
 * This code assumes a killed buffer will never be on a window list unless it
 | 
						||
 * is pointed to by cur_buf or oth_win->w_buf!!!!
 | 
						||
 */
 | 
						||
f_kbuffer()
 | 
						||
{	register struct buffer *b, *ob;
 | 
						||
	register char *ans;
 | 
						||
 | 
						||
	if((ans = ask("Kill buffer: ")) == 0)
 | 
						||
		return;
 | 
						||
	if(*ans == 0) b = cur_buf;
 | 
						||
	else if(*ans == SP) b = 0;
 | 
						||
	else b = find_buf(ans);
 | 
						||
 | 
						||
	chkfree(ans);
 | 
						||
	if(!b)
 | 
						||
	  {	ding("No such buffer");
 | 
						||
		return;
 | 
						||
	  }
 | 
						||
#if IMAGEN
 | 
						||
	if (b->b_flags & B_PERMANENT)
 | 
						||
	  {	ding("Permanent buffer--cannot kill!");
 | 
						||
		return;
 | 
						||
	  }
 | 
						||
	if (b->b_flags & B_MODIFIED)
 | 
						||
	  {	if ((ans == ask("Buffer is modified; are you sure? ")) == 0)
 | 
						||
			return;
 | 
						||
		if(upcase(*ans) != 'Y')
 | 
						||
		  {	chkfree(ans);
 | 
						||
			return;
 | 
						||
		  }
 | 
						||
		chkfree(ans);
 | 
						||
	  }
 | 
						||
#endif /*IMAGEN*/
 | 
						||
	if(b == cur_buf || (oth_win && (oth_win->w_buf == b)))
 | 
						||
	  {	ob = last_buf;
 | 
						||
		do
 | 
						||
		  {
 | 
						||
			/* If default same as doomed buffer, try to pick
 | 
						||
			 * a more useful alternative. */
 | 
						||
			if((b == ob) && !(ob = sel_mbuf(b)))
 | 
						||
				ob = sel_nbuf(b);
 | 
						||
 | 
						||
			ans = ask("Killing in-use buffer; select which other buffer (%s): ",
 | 
						||
					ob->b_name);
 | 
						||
			if(ans == 0) return;
 | 
						||
			if(*ans)
 | 
						||
			  {	if(*ans == SP) ob = 0;
 | 
						||
				else ob = find_buf(ans);
 | 
						||
			  }
 | 
						||
			chkfree(ans);
 | 
						||
			if(!ob)
 | 
						||
			  {	ding("No such buffer");
 | 
						||
				return;
 | 
						||
			  }
 | 
						||
		  } while (b == ob);
 | 
						||
 | 
						||
		/* B is buffer to kill, OB is buffer to replace it with */
 | 
						||
		if(oth_win && (oth_win->w_buf == b))
 | 
						||
		  {	f_othwind();	/* Select other one */
 | 
						||
			chg_buf(ob);	/* Change to new buffer */
 | 
						||
			f_othwind();
 | 
						||
		  }
 | 
						||
		if(cur_buf == b)
 | 
						||
			chg_buf(ob);
 | 
						||
	  }
 | 
						||
 | 
						||
	kill_buf(b);			/* Die!!!! */
 | 
						||
	if(last_buf == b)
 | 
						||
		last_buf = cur_buf;
 | 
						||
}
 | 
						||
 | 
						||
/* EFUN: "List Buffers" */
 | 
						||
/*	Display a list of all user buffers.  Internal buffers, whose names
 | 
						||
 *	start with a space, are not shown.
 | 
						||
 */
 | 
						||
f_listbufs()
 | 
						||
{
 | 
						||
	register struct buffer *b;
 | 
						||
	register char *cp;
 | 
						||
	register int i;
 | 
						||
	struct buffer *tbuf, *savbuf;
 | 
						||
	char temp[20];
 | 
						||
 | 
						||
	/* First must set up special buffer... */
 | 
						||
	savbuf = cur_buf;
 | 
						||
	chg_buf(tbuf = make_buf(" **SHOW**"));
 | 
						||
	e_sputz("Buffers in this ELLE:\n\n");
 | 
						||
	for(b = buf_head; b; b = b->b_next)
 | 
						||
	  {	cp = b->b_name;
 | 
						||
		if(*cp == SP) continue;	/* Ignore internal buffs */
 | 
						||
		e_sputz((b->b_flags&B_MODIFIED) ? "* " : "  ");
 | 
						||
		e_sputz(cp);			/* Insert buffer name */
 | 
						||
		dottoa(temp,ex_blen(b));	/* Get buff-length string */
 | 
						||
		if((i = ((FNAMELEN > 14) ? 30 : 20)
 | 
						||
			 - strlen(cp) - strlen(temp)) > 0)
 | 
						||
			e_insn(SP, i);
 | 
						||
		e_sputz(" (");
 | 
						||
		e_sputz(temp);
 | 
						||
		e_sputz(") ");
 | 
						||
		if(cp = b->b_fn)
 | 
						||
			e_sputz(cp);
 | 
						||
#if IMAGEN
 | 
						||
		if (b->b_flags & B_CMODE)
 | 
						||
			e_sputz(" (C)");
 | 
						||
		else if (b->b_flags & B_TEXTMODE)
 | 
						||
			e_sputz(" (Text)");
 | 
						||
		else
 | 
						||
			e_sputz(" (Fundamental)");
 | 
						||
#endif /*IMAGEN*/
 | 
						||
		e_putc(LF);
 | 
						||
	  }
 | 
						||
	mk_showin(tbuf);	/* Show this buffer in temp window */
 | 
						||
	chg_buf(savbuf);	/* Return to real current buffer */
 | 
						||
	kill_buf(tbuf);
 | 
						||
}
 | 
						||
 | 
						||
/* EFUN: "Buffer Not Modified" */
 | 
						||
/*	Mark the current buffer as not modified.
 | 
						||
 */
 | 
						||
f_bufnotmod()
 | 
						||
{
 | 
						||
	cur_buf -> b_flags &= ~B_MODIFIED;
 | 
						||
	redp(RD_MODE);
 | 
						||
}
 | 
						||
 | 
						||
#if FX_EOLMODE
 | 
						||
/* EFUN: "EOL CRLF Mode" (not EMACS) */
 | 
						||
/*	Toggle the EOL mode of the current buffer.
 | 
						||
**		LF EOL Mode means LF alone is an EOL.
 | 
						||
**		CRLF EOL Mode means CRLF together is an EOL.
 | 
						||
*/
 | 
						||
f_eolmode()
 | 
						||
{
 | 
						||
	cur_buf->b_flags ^= B_EOLCRLF;		/* Flip this bit */
 | 
						||
	say((cur_buf->b_flags & B_EOLCRLF)
 | 
						||
		? "EOL Mode is CRLF"		/* If now on */
 | 
						||
		: "EOL Mode is LF");		/* If now off */
 | 
						||
 | 
						||
	redp(RD_WINRES);			/* Redo window for this buf */
 | 
						||
}
 | 
						||
#endif /*FX_EOLMODE*/
 | 
						||
 | 
						||
#if FX_GOBEG
 | 
						||
/* EFUN: "Goto Beginning" */
 | 
						||
f_gobeg()
 | 
						||
{	e_gobob();
 | 
						||
	ed_setcur();
 | 
						||
}
 | 
						||
#endif /*FX_GOBEG*/
 | 
						||
 | 
						||
#if FX_GOEND
 | 
						||
/* EFUN: "Goto End" */
 | 
						||
f_goend()
 | 
						||
{	e_goeob();
 | 
						||
	ed_setcur();
 | 
						||
}
 | 
						||
#endif /*FX_GOEND*/
 | 
						||
 | 
						||
#if FX_WHATPAGE
 | 
						||
/* EFUN: "What Page" */
 | 
						||
/*	Extra info added as per earlier ICONOGRAPHICS "What Buffer Position"
 | 
						||
** Reports on current position as follows:
 | 
						||
**	Dot=<n>, Page <n>  Line <n> (line <n> of <m>)
 | 
						||
*/
 | 
						||
f_whatpage()
 | 
						||
{
 | 
						||
	register chroff cnt;
 | 
						||
	register int c;
 | 
						||
	register int page, line;
 | 
						||
	int lineatp;
 | 
						||
	char tempstr[12], *dottoa ();
 | 
						||
 | 
						||
        saynow("Dot=");
 | 
						||
        dottoa(tempstr, cur_dot);
 | 
						||
        sayntoo(tempstr);
 | 
						||
 | 
						||
	e_gobob();
 | 
						||
	page = line = lineatp = 1;
 | 
						||
	for (cnt = cur_dot; --cnt >= 0;)
 | 
						||
		if ((c = e_getc()) == LF)
 | 
						||
			++line;
 | 
						||
		else if (c == FF)
 | 
						||
		  {	++page;
 | 
						||
			lineatp = line;
 | 
						||
		  }
 | 
						||
 | 
						||
        saytoo(", Page ");
 | 
						||
        dottoa(tempstr, (chroff)page);
 | 
						||
        saytoo(tempstr);
 | 
						||
	saytoo("  Line ");
 | 
						||
        dottoa(tempstr, (chroff)(1 + line - lineatp));
 | 
						||
        saytoo(tempstr);
 | 
						||
	saytoo("  Col ");
 | 
						||
        dottoa(tempstr, (chroff)indtion(cur_dot));
 | 
						||
        saytoo(tempstr);
 | 
						||
	saytoo("  [line ");
 | 
						||
	dottoa(tempstr, (chroff)line);
 | 
						||
	saytoo(tempstr);
 | 
						||
	sayntoo(" of ");		/* Force out while scan rest */
 | 
						||
 | 
						||
        for(e_gocur(); e_gonl() ; ++line) ;	/* Count lines until EOF */
 | 
						||
	c = e_rgetc();			/* Remember what last char is */
 | 
						||
        dottoa(tempstr, (chroff)line);
 | 
						||
        saytoo(tempstr);
 | 
						||
        if (c != LF)		/* Check last char */
 | 
						||
            saytoo(" (no EOL at EOF!)");
 | 
						||
        sayntoo("]");
 | 
						||
	e_gocur();			/* Back to original position */
 | 
						||
}
 | 
						||
#endif /*FX_WHATPAGE*/
 | 
						||
 | 
						||
init_buf ()			       /* init buffer stuff */
 | 
						||
{
 | 
						||
	buf_head = 0;
 | 
						||
	lines_buf = cur_buf = make_buf(" **LINES**");	/* For sep_win */
 | 
						||
	e_insn('-',scr_wid-2);			/* Fill with dashes */
 | 
						||
	last_buf = cur_buf = make_buf ("Main");	/* Make Main buffer */
 | 
						||
	init_win();				/* Now can init windows */
 | 
						||
}
 | 
						||
 | 
						||
struct buffer *
 | 
						||
make_buf(bname)	       /* create buffer "bname" if it doesn't exist */
 | 
						||
char *bname;
 | 
						||
{	register struct buffer *b;
 | 
						||
	register char *name;
 | 
						||
 | 
						||
	b = find_buf(name = bname);
 | 
						||
	if (b)				/* if it exists already */
 | 
						||
		return(b);
 | 
						||
	b = (struct buffer *) memalloc(sizeof (struct buffer));
 | 
						||
	b -> b_next = buf_head;	       /* link it in */
 | 
						||
	buf_head = b;
 | 
						||
	b->b_name = strdup(name);	/* Allocate copy of name string */
 | 
						||
	b->b_dot = 0;		/* Set dot to beg */
 | 
						||
	sb_open(b,(SBSTR *)0);		/* Open buffer with null initial sbstring */
 | 
						||
	b->b_fn = 0;
 | 
						||
	b->b_flags = 0;
 | 
						||
	b->b_mode = cur_mode;	/* Inherit current mode */
 | 
						||
	return(b);
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
struct buffer *
 | 
						||
find_buf(name)	       /* returns pointer to buffer of that name or 0 */
 | 
						||
char *name;
 | 
						||
{	register struct buffer *b = buf_head;
 | 
						||
 | 
						||
	while (b && strcmp(b->b_name, name))
 | 
						||
		b = b -> b_next;
 | 
						||
	return(b);
 | 
						||
}
 | 
						||
 | 
						||
sel_buf(b)				/* select buffer, saving last */
 | 
						||
struct buffer *b;
 | 
						||
{
 | 
						||
	if(b != cur_buf) last_buf = cur_buf;
 | 
						||
	chg_buf(b);
 | 
						||
}
 | 
						||
 | 
						||
chg_buf (newbuf)		       /* change current buffer to newbuf */
 | 
						||
struct buffer *newbuf;
 | 
						||
{	register struct buffer *obuf, *nbuf;
 | 
						||
 | 
						||
	if ((nbuf = newbuf) == (obuf = cur_buf))
 | 
						||
		return;			/* Do nothing if same buffers */
 | 
						||
	obuf->b_dot = cur_dot;
 | 
						||
	cur_buf = nbuf;
 | 
						||
	cur_mode = nbuf->b_mode;
 | 
						||
	e_gosetcur(nbuf->b_dot);	/* Set cur_dot and go there */
 | 
						||
	cur_win->w_buf = nbuf;
 | 
						||
	cur_win->w_dot = cur_dot;
 | 
						||
#if IMAGEN
 | 
						||
	cur_win->w_redp = RD_WINRES|RD_REDO;
 | 
						||
#else
 | 
						||
	cur_win->w_redp = RD_WINRES;	/* Reset flags - do complete update */
 | 
						||
#endif /*-IMAGEN*/
 | 
						||
	unlk_buf(obuf);			/* Unlock previous buffer if can */
 | 
						||
	mark_p = 0;			/* this is lazy */
 | 
						||
	redp(RD_MODE|RD_WINRES);
 | 
						||
}
 | 
						||
 | 
						||
/* See if specified buffer belongs to any active window, and
 | 
						||
 * if not then get it into an idle, unlocked state; this helps the
 | 
						||
 * edit package compact and swap stuff out while it's not being used.
 | 
						||
 * Assumes proper state of dot has been stored into b_dot.
 | 
						||
 */
 | 
						||
unlk_buf(bufp)
 | 
						||
struct buffer *bufp;
 | 
						||
{	register struct buffer *b;
 | 
						||
	register struct window *w;
 | 
						||
 | 
						||
	b = bufp;
 | 
						||
	for(w = win_head; w; w = w->w_next)
 | 
						||
		if(b == w->w_buf)
 | 
						||
			return;		/* Buffer is actively being shown */
 | 
						||
	sb_rewind((SBBUF *)b);		/* Return to idle state */
 | 
						||
}
 | 
						||
 | 
						||
/* SEL_NBUF(buf) - Select next user buffer.  Ignores internal buffers.
 | 
						||
 *	Arg of 0 starts at beg of buffer list.  Always returns
 | 
						||
 *	a buffer pointer - returns argument (which may be 0)
 | 
						||
 *	if found no other user buffers.
 | 
						||
 *
 | 
						||
 * SEL_MBUF(buf) - Select next modified buffer.
 | 
						||
 *	Returns buffer ptr to "next" modified buffer, if any.
 | 
						||
 *	Arg of 0 starts at beg of buffer list and scans all of them.
 | 
						||
 *	Returns 0 if no other modified buffers exist (unlike SEL_NBUF!)
 | 
						||
 *	Ignores internal buffers, whose names start with a space.
 | 
						||
 */
 | 
						||
/* struct buffer *buf_mptr; */
 | 
						||
#if 0
 | 
						||
struct buffer *
 | 
						||
sel_mbuf(buf)
 | 
						||
struct buffer *buf;
 | 
						||
{	register struct buffer *b;
 | 
						||
	register int sweep;
 | 
						||
 | 
						||
	sweep = 0;			/* Make 2 sweeps only */
 | 
						||
	if(b = buf) b = b->b_next;
 | 
						||
	do {
 | 
						||
		if(b == 0)		/* Initialize if needed */
 | 
						||
			b = buf_head;
 | 
						||
		for(; b; b = b->b_next)
 | 
						||
			if((b->b_flags & B_MODIFIED) && (*b->b_name != SP))
 | 
						||
				return((b == buf) ? 0 : b);
 | 
						||
	  } while(sweep++ != 0);
 | 
						||
	return(0);
 | 
						||
}
 | 
						||
#endif /*COMMENT*/
 | 
						||
 | 
						||
struct buffer *
 | 
						||
sel_mbuf(buf)
 | 
						||
register struct buffer *buf;
 | 
						||
{	register struct buffer *b, *b2;
 | 
						||
	b = b2 = sel_nbuf(buf);
 | 
						||
	do {	if(b == buf) break;
 | 
						||
		if(b->b_flags & B_MODIFIED)
 | 
						||
			return(b);
 | 
						||
	  } while((b = sel_nbuf(b)) != b2);
 | 
						||
 | 
						||
	return(0);
 | 
						||
}
 | 
						||
 | 
						||
struct buffer *
 | 
						||
sel_nbuf(buf)
 | 
						||
register struct buffer *buf;
 | 
						||
{	register struct buffer *b;
 | 
						||
 | 
						||
	b = buf;
 | 
						||
	do {
 | 
						||
		if(!b || !(b = b->b_next))
 | 
						||
			b = buf_head;
 | 
						||
		if(*b->b_name != SP)
 | 
						||
			break;
 | 
						||
	  } while (b != buf);
 | 
						||
	return(b);
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
kill_buf(buf)
 | 
						||
struct buffer *buf;
 | 
						||
{	register struct buffer *b, *b1, *bt;
 | 
						||
 | 
						||
	b = buf;
 | 
						||
	b1 = 0;
 | 
						||
	for(bt = buf_head; bt && bt != b; bt = bt -> b_next)
 | 
						||
		b1 = bt;
 | 
						||
	if(bt == 0)
 | 
						||
	  {	ring_bell();
 | 
						||
		errbarf("No such buffer");	/* Internal error */
 | 
						||
		return;
 | 
						||
	  }
 | 
						||
	if (b1 == 0)
 | 
						||
		buf_head = b->b_next;
 | 
						||
	else
 | 
						||
		b1->b_next = b->b_next;
 | 
						||
	sbs_del(sb_close((SBBUF *)b));	/* Close buffer & delete sbstring */
 | 
						||
	sb_fdcls(-1);			/* Make sweep for unused FD's */
 | 
						||
	if(b->b_fn)
 | 
						||
		chkfree(b->b_fn);	/* Flush filename if one */
 | 
						||
	chkfree(b->b_name);		/* Flush name */
 | 
						||
	chkfree((char *)b);		/* Flush buffer */
 | 
						||
}
 | 
						||
 | 
						||
/* ZAP_BUFFER - Delete all of the buffer, but if it's been modified,
 | 
						||
 *	ask first.  Returns 0 if user aborts.
 | 
						||
 */
 | 
						||
zap_buffer()
 | 
						||
{
 | 
						||
#if IMAGEN
 | 
						||
	extern struct buffer *exec_buf;	/* in e_make.c */
 | 
						||
 | 
						||
	if(cur_buf != exec_buf && cur_buf -> b_flags & B_MODIFIED)
 | 
						||
#else
 | 
						||
	if(cur_buf -> b_flags & B_MODIFIED)
 | 
						||
#endif /*-IMAGEN*/
 | 
						||
		if(ask_kbuf(cur_buf) <= 0)
 | 
						||
			return(0);		/* Aborted */
 | 
						||
	ed_reset();		/* This takes care of redisplay too */
 | 
						||
	mark_p = 0;
 | 
						||
#if IMAGEN
 | 
						||
	cur_buf->b_flags &= ~B_BACKEDUP; /* Clear backed-up flag */
 | 
						||
#endif
 | 
						||
	return(1);
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
/* ASK_KBUF - Ask user "are you sure?" before killing a buffer.
 | 
						||
 *	Returns +1 if user says "yes" - OK to kill.
 | 
						||
 *		 0 if user aborts (^G)
 | 
						||
 *		-1 if user says "no".
 | 
						||
 */
 | 
						||
ask_kbuf(buf)
 | 
						||
struct buffer *buf;
 | 
						||
{	register struct buffer *b;
 | 
						||
	register char *s;
 | 
						||
	register int ans;
 | 
						||
 | 
						||
	b = buf;
 | 
						||
	s = ask("Buffer %s contains changes - forget them? ", b->b_name);
 | 
						||
	if(s == 0) return(0);
 | 
						||
	ans = (upcase(*s) == 'Y') ? 1 : -1;
 | 
						||
	chkfree(s);
 | 
						||
	return(ans);
 | 
						||
}
 | 
						||
 | 
						||
/* Window stuff */
 | 
						||
 | 
						||
/* Like EMACS, ELLE only provides at most two user windows.
 | 
						||
 * The current user window is pointed to by user_win;
 | 
						||
 * the "other" one is oth_win.  If oth_win == 0, there is only one user
 | 
						||
 * window.
 | 
						||
 */
 | 
						||
 | 
						||
#if FX_2MODEWINDS
 | 
						||
int sepmode_p = 0;	/* Set true if separator window is a 2nd mode win */
 | 
						||
#endif
 | 
						||
 | 
						||
/* EFUN: "Two Windows" */
 | 
						||
/*	Divide the current window in half, put the current buffer in the
 | 
						||
 *	other window, and go to the new window.
 | 
						||
 */
 | 
						||
f_2winds()
 | 
						||
{	register int h, t;
 | 
						||
	register struct window *w;
 | 
						||
 | 
						||
	if (oth_win)
 | 
						||
	  {
 | 
						||
#if !(IMAGEN)
 | 
						||
		ding("Already 2 windows");
 | 
						||
#endif /*-IMAGEN*/
 | 
						||
		return;
 | 
						||
	  }
 | 
						||
	w = cur_win;
 | 
						||
	d_fixcur();			/* Stabilize current window */
 | 
						||
	h = (w->w_ht) / 2;
 | 
						||
	t = w->w_pos + h;		/* Pos of dividing window */
 | 
						||
	sep_win = make_win(t, 1, lines_buf);
 | 
						||
					/* assume using dashes to separate */
 | 
						||
	oth_win = make_win(t + 1, w->w_ht - (h + 1), cur_buf);
 | 
						||
					/* Other window has balance */
 | 
						||
#if FX_SOWIND
 | 
						||
	oth_win->w_flags |= cur_win->w_flags&W_STANDOUT;
 | 
						||
	sep_win->w_flags |= mode_win->w_flags&W_STANDOUT;
 | 
						||
#endif
 | 
						||
#if FX_2MODEWINDS
 | 
						||
	chk2modws();			/* Update 2-mode-wind status */
 | 
						||
#endif
 | 
						||
	w->w_ht = h;			/* Decrease current window to half */
 | 
						||
 | 
						||
	/* Minimize redisplay by moving each window's dot into
 | 
						||
	 * a currently displayed area */
 | 
						||
	if(cur_dot < (oth_win->w_topldot = scr[t+1]->sl_boff))
 | 
						||
		oth_win->w_dot = oth_win->w_topldot;	/* Adj bottom win */
 | 
						||
	else					/* Adjust top window */
 | 
						||
	  {	oth_win->w_dot = cur_dot;	/* Bottom keeps dot */
 | 
						||
		cur_dot = scr[t-1]->sl_boff;	/* but top needs new one. */
 | 
						||
	  }
 | 
						||
	f_othwind();			/* switch to other window */
 | 
						||
	redp(RD_WINDS);			/* Update all windows */
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
/* EFUN: "One Window" */
 | 
						||
/*	Revert to using only one window; use the current buffer (unlike
 | 
						||
 *	EMACS which always selects the top window's buffer)
 | 
						||
 *	Ensures that current window's vars are correctly set for
 | 
						||
 *	new dimensions (w_pos, w_ht, plus w_topldot to minimize redisplay),
 | 
						||
 *	then kills unneeded windows.
 | 
						||
 */
 | 
						||
f_1wind()
 | 
						||
{	register struct window *w;
 | 
						||
 | 
						||
	if (oth_win == 0)
 | 
						||
	  {
 | 
						||
#if (!IMAGEN)
 | 
						||
		ding("Only 1 window");
 | 
						||
#endif /*-IMAGEN*/
 | 
						||
		return;
 | 
						||
	  }
 | 
						||
	w = cur_win;
 | 
						||
	if(w->w_pos)		/* If not top window */
 | 
						||
	  {	d_fixcur();		/* Ensure screen-line data correct */
 | 
						||
		e_go(w->w_topldot);	/* Beginning from top of window, */
 | 
						||
		d_fgoloff(-w->w_pos);	/* Move back enough lines */
 | 
						||
		w->w_topldot = e_dot();	/* To set new start of window */
 | 
						||
		e_gocur();		/* Then move back to orig place */
 | 
						||
		w->w_pos = 0;
 | 
						||
	  }
 | 
						||
	w->w_ht += oth_win -> w_ht + 1;
 | 
						||
	kill_win (oth_win);
 | 
						||
	kill_win (sep_win);
 | 
						||
	oth_win = sep_win = 0;
 | 
						||
#if FX_2MODEWINDS
 | 
						||
	chk2modws();	/* Update notion of whether have 2 mode winds */
 | 
						||
#endif
 | 
						||
	redp(RD_FIXWIN|RD_WINDS|RD_MODE); /* New topldot for this window,
 | 
						||
					 * and check all remaining windows */
 | 
						||
}
 | 
						||
 | 
						||
/* EFUN: "Other Window" */
 | 
						||
/*	Move to the "other" user window.
 | 
						||
 */
 | 
						||
f_othwind ()
 | 
						||
{	if (oth_win == 0)
 | 
						||
	  {
 | 
						||
#if !(IMAGEN)
 | 
						||
		ding("Only 1 window");
 | 
						||
#endif /*-IMAGEN*/
 | 
						||
		return;
 | 
						||
	  }
 | 
						||
	chg_win(oth_win);
 | 
						||
	oth_win = user_win;
 | 
						||
	user_win = cur_win;
 | 
						||
	redp(RD_MODE);
 | 
						||
}
 | 
						||
 | 
						||
/* EFUN: "Grow Window" */
 | 
						||
/*	Grow the current window - while in two window mode,
 | 
						||
 *	increase the size of the current window by the arg
 | 
						||
 *	and decrease the other accordingly
 | 
						||
 */
 | 
						||
f_growind()
 | 
						||
{	register struct window *cw, *ow;
 | 
						||
	register int e;
 | 
						||
 | 
						||
	if ((ow = oth_win) == 0)
 | 
						||
	  {
 | 
						||
#if !(IMAGEN)
 | 
						||
		ding("Only 1 window");
 | 
						||
#endif /*-IMAGEN*/
 | 
						||
		return;
 | 
						||
	  }
 | 
						||
	e = exp;
 | 
						||
	if((cw = cur_win)->w_pos != 0)	/* If current window is on bottom */
 | 
						||
	  {	cw = ow;		/* Then fake code to think it's top */
 | 
						||
		ow = cur_win;
 | 
						||
		e = -e;
 | 
						||
	  }
 | 
						||
	if(  cw->w_ht + e < 1
 | 
						||
	  || ow->w_ht + e < 1)
 | 
						||
	  {	ding("Too much");
 | 
						||
		return;
 | 
						||
	  }
 | 
						||
	cw -> w_ht += e;
 | 
						||
	ow -> w_pos += e;
 | 
						||
	ow -> w_ht -= e;
 | 
						||
	sep_win -> w_pos += e;
 | 
						||
	redp(RD_WINDS | RD_MODE);		/* Update all windows */
 | 
						||
}
 | 
						||
 | 
						||
#if FX_SHRINKWIND
 | 
						||
/* EFUN: "Shrink Window" (not EMACS) - from IMAGEN config */
 | 
						||
f_shrinkwind()
 | 
						||
{
 | 
						||
	if (! oth_win)
 | 
						||
		return;
 | 
						||
	f_othwind();
 | 
						||
	f_growind();
 | 
						||
	f_othwind();
 | 
						||
}
 | 
						||
#endif /*FX_SHRINKWIND*/
 | 
						||
 | 
						||
#if FX_DELWIND
 | 
						||
/* EFUN: "Delete Window" (not EMACS) - from IMAGEN config */
 | 
						||
f_delwind()
 | 
						||
{
 | 
						||
	if(!oth_win)
 | 
						||
		return;
 | 
						||
	f_othwind();
 | 
						||
	f_1wind();
 | 
						||
}
 | 
						||
#endif /*FX_DELWIND*/
 | 
						||
 | 
						||
#if FX_SOWIND
 | 
						||
/* EFUN: "Standout Window" (not EMACS) */
 | 
						||
/*	Toggles the display standout mode for the current window.
 | 
						||
**	With argument of 4, toggles the standout mode for the non-buffer
 | 
						||
**	parts of the screen, such as the ELLE mode line.
 | 
						||
** (This corresponds to FS INVMOD$ in EMACS)
 | 
						||
**	With argument of 0, turns standout mode off for all windows.
 | 
						||
*/
 | 
						||
/* It suffices to set the window flag bit and force a RD_WINRES for that
 | 
						||
 * window; the redisplay code will do the rest.
 | 
						||
*/
 | 
						||
static void tgso_wind();
 | 
						||
 | 
						||
f_sowind()
 | 
						||
{
 | 
						||
	register struct window *w;
 | 
						||
	switch(exp)
 | 
						||
	  {	default:		/* Toggle current window */
 | 
						||
			tgso_wind(cur_win);
 | 
						||
			break;
 | 
						||
		case 4:			/* Toggle mode & separator windows */
 | 
						||
			tgso_wind(mode_win);
 | 
						||
			tgso_wind(sep_win);	/* This may not exist */
 | 
						||
			break;
 | 
						||
		case 0:			/* Turn off standout for all winds */
 | 
						||
			for(w = win_head; w; w = w->w_next)
 | 
						||
				if(w->w_flags&W_STANDOUT)
 | 
						||
					tgso_wind(w);
 | 
						||
	  }
 | 
						||
#if FX_2MODEWINDS
 | 
						||
	chk2modws();	/* Update notion of whether have 2 mode winds */
 | 
						||
#endif
 | 
						||
}
 | 
						||
 | 
						||
static void
 | 
						||
tgso_wind(w)		/* Toggle standout mode for given window */
 | 
						||
register struct window *w;
 | 
						||
{
 | 
						||
	if (w == 0) return;		/* For case of no sep_win */
 | 
						||
	if (w->w_flags & W_STANDOUT)
 | 
						||
		w->w_flags &= ~W_STANDOUT;
 | 
						||
	else w->w_flags |= W_STANDOUT;
 | 
						||
	w->w_redp |= RD_WINRES;		/* Re-do this particular window */
 | 
						||
	redp(RD_CHKALL);		/* Check all windows for changes */
 | 
						||
}
 | 
						||
#endif /*FX_SOWIND*/
 | 
						||
 | 
						||
 | 
						||
#if FX_2MODEWINDS
 | 
						||
/* EFUN: "Two Mode Windows" (not EMACS) */
 | 
						||
/*	With arg, sets ev_2modws to that value (0, 1, or 2).
 | 
						||
**	No arg, toggles current setting between 0 and 2.
 | 
						||
*/
 | 
						||
 | 
						||
f_2modewinds()
 | 
						||
{
 | 
						||
	ev_2modws = exp_p ? exp : (ev_2modws ? 0 : 2);
 | 
						||
	chk2modws();
 | 
						||
}
 | 
						||
 | 
						||
/* CHK2MODWS - Called after anything changes which might affect
 | 
						||
**	whether 2 mode windows are in effect or not.  Fixes up
 | 
						||
**	sep_win to either be or not be a mode window.
 | 
						||
*/
 | 
						||
chk2modws()
 | 
						||
{	register struct window *w;
 | 
						||
	static struct buffer *sep_buf = 0;
 | 
						||
 | 
						||
	if(!(w = sep_win))
 | 
						||
	  {	sepmode_p = 0;		/* Don't have 2 windows at all */
 | 
						||
		return;
 | 
						||
	  }
 | 
						||
	sepmode_p = (ev_2modws == 1)
 | 
						||
			? (mode_win->w_flags&W_STANDOUT)
 | 
						||
			: ev_2modws;
 | 
						||
 | 
						||
	if(sepmode_p)		/* Turn 2-mode-winds on? */
 | 
						||
	  {
 | 
						||
		if(!sep_buf)
 | 
						||
			sep_buf = make_buf(" **SEPMODE**");
 | 
						||
		w->w_buf = sep_buf;
 | 
						||
		w->w_flags |= W_MODE;
 | 
						||
	  }
 | 
						||
	else			/* Turn 2-mode-winds off */
 | 
						||
	  {	w->w_buf = lines_buf;
 | 
						||
		w->w_flags &= ~W_MODE;
 | 
						||
		redp(RD_CHKALL);	/* No longer a mode win, so must */
 | 
						||
					/* check all to ensure it's updated */
 | 
						||
	  }
 | 
						||
	w->w_redp |= RD_WINRES;
 | 
						||
	redp(RD_MODE);
 | 
						||
}
 | 
						||
#endif /*FX_2MODEWINDS*/
 | 
						||
 | 
						||
init_win ()
 | 
						||
{
 | 
						||
	win_head = 0;
 | 
						||
	oth_win = 0;
 | 
						||
	user_win = make_win(0, scr_ht - (ECHOLINES+1), cur_buf); /* Main */
 | 
						||
	mode_win = make_win(scr_ht - (ECHOLINES+1), 1, make_buf(" **MODE**"));
 | 
						||
	ask_win  = make_win(scr_ht - ECHOLINES,     1, make_buf(" **ASK**"));
 | 
						||
#if FX_SOWIND
 | 
						||
	if(ev_modwso)
 | 
						||
		mode_win->w_flags |= W_STANDOUT;
 | 
						||
#endif
 | 
						||
 | 
						||
	cur_win = user_win;
 | 
						||
}
 | 
						||
 | 
						||
chg_win(newwin)		       /* change current window to newwin */
 | 
						||
struct window *newwin;
 | 
						||
{
 | 
						||
	cur_win->w_dot = cur_dot;	/* Save window's current dot */
 | 
						||
	cur_win->w_redp |= rd_type&RDS_WINFLGS;	/* and its redisplay flags */
 | 
						||
	cur_win = newwin;		/* OK, switch to new current window */
 | 
						||
	cur_buf = newwin->w_buf;	/* Set new buffer from win */
 | 
						||
	e_gosetcur(newwin->w_dot);	/* Set new cur_dot from win too */
 | 
						||
			/* Note done this way to canonicalize the location
 | 
						||
			** (may be past new EOB) and ensure SB buffer
 | 
						||
			** internals agree with cur_dot.
 | 
						||
			*/
 | 
						||
	rd_type &= ~RDS_WINFLGS;	/* Remove old per-window flags */
 | 
						||
	redp(RD_WINRES|RD_MODE);	/* Maybe caller shd handle? */
 | 
						||
			/* Note WINRES must be set in case we are pointing
 | 
						||
			 * to a buffer that was modified while we were in
 | 
						||
			 * the other window!
 | 
						||
			 */
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
struct window *
 | 
						||
make_win (pos, ht, buf)
 | 
						||
int pos, ht;
 | 
						||
struct buffer *buf;
 | 
						||
{	register struct window *w;
 | 
						||
	register struct buffer *b;
 | 
						||
 | 
						||
	b = buf;
 | 
						||
	w = (struct window *) memalloc(sizeof (struct window));
 | 
						||
	w->w_flags = 0;
 | 
						||
	w->w_pos = pos;
 | 
						||
	w->w_ht = ht;
 | 
						||
	w->w_buf = b;
 | 
						||
	w->w_dot = b->b_dot;	/* Set dot from buffer value */
 | 
						||
	w->w_topldot = 0;	/* Set top of window to beg of buffer */
 | 
						||
	w->w_pct = 200;		/* Assume "ALL" */
 | 
						||
	w->w_bmod = 0;
 | 
						||
	w->w_emod = 0;
 | 
						||
	w->w_oldz = 0;
 | 
						||
	w->w_redp = RD_WINRES;	/* Window will need complete update */
 | 
						||
	w->w_next = win_head;	/* Done, now link it in */
 | 
						||
	win_head = w;
 | 
						||
	return (w);
 | 
						||
}
 | 
						||
 | 
						||
kill_win (win)
 | 
						||
struct window *win;
 | 
						||
{	register struct window *w, *w1, *kw;
 | 
						||
 | 
						||
	kw = win;
 | 
						||
	w1 = 0;
 | 
						||
	for (w = win_head; w && w != kw; w = w -> w_next)
 | 
						||
		w1 = w;
 | 
						||
	if (w == 0)
 | 
						||
	  {	ring_bell();
 | 
						||
		errbarf("No such window");	/* Internal error */
 | 
						||
		return;
 | 
						||
	  }
 | 
						||
	if (w1 == 0)
 | 
						||
		win_head = w -> w_next;
 | 
						||
	else
 | 
						||
		w1 -> w_next = w -> w_next;
 | 
						||
	kw->w_buf->b_dot = (kw == cur_win) ? cur_dot : kw->w_dot;
 | 
						||
	chkfree (kw);
 | 
						||
#if IMAGEN		/* Not needed? */
 | 
						||
	redp (RD_WINRES|RD_WINDS|RD_REDO);
 | 
						||
#endif /*IMAGEN*/
 | 
						||
}
 | 
						||
 | 
						||
/*
 | 
						||
 * "Show-window" routines, used to set up, step through, and close a
 | 
						||
 * temporary "show" window.
 | 
						||
 * MK_SHOWIN(bufp)
 | 
						||
 * UP_SHOWIN()
 | 
						||
 * KL_SHOWIN()
 | 
						||
 */
 | 
						||
 | 
						||
/* MK_SHOWIN(bufp) - Temporarily display a buffer
 | 
						||
 */
 | 
						||
mk_showin(b)
 | 
						||
struct buffer *b;
 | 
						||
{	register struct window *w;
 | 
						||
	register int i;
 | 
						||
	int moreflg, intflg;		/* Interrupt flag */
 | 
						||
	struct window *savwin;
 | 
						||
 | 
						||
	/* First must set up special window... */
 | 
						||
	savwin = cur_win;
 | 
						||
	chg_win(w = make_win(0, scr_ht-(ECHOLINES+3), b));
 | 
						||
 redo:
 | 
						||
	d_fixcur();		/* Fix up screen image of current window */
 | 
						||
 | 
						||
	/* Find how many lines actually used, and reduce size to that */
 | 
						||
	i = w->w_ht;
 | 
						||
	while(--i >= 0)
 | 
						||
	  {
 | 
						||
		if(scr[i]->sl_boff != w->w_oldz) break;
 | 
						||
	  }
 | 
						||
	if(++i <= 0)
 | 
						||
		goto skipit;	/* Punt the whole thing */
 | 
						||
	if(!(moreflg = (i >= w->w_ht)))
 | 
						||
		w->w_ht = i;	/* Reduce size of window */
 | 
						||
 | 
						||
	intflg = upd_wind(w);	/* Update the window! */
 | 
						||
	if(!intflg)		/* Unless input waiting, add prompt. */
 | 
						||
	  {
 | 
						||
		yellat( moreflg ?
 | 
						||
	"--MORE-- (type Space for more, or type any command to flush)" :
 | 
						||
	"------------------------------------------------ (Hit space to continue)--",
 | 
						||
			w->w_ht);
 | 
						||
		
 | 
						||
	  }
 | 
						||
	tbufls();		/* Ensure all output forced out */
 | 
						||
	i = cmd_read();		/* then wait for user to input a char */
 | 
						||
	if(i == SP)
 | 
						||
	  {	if(moreflg)
 | 
						||
		  {	yellat("", w->w_ht);
 | 
						||
			d_screen(1);
 | 
						||
			w->w_redp |= RD_WINRES;
 | 
						||
			goto redo;
 | 
						||
		  }
 | 
						||
	  }
 | 
						||
#if !(IMAGEN)		/* IMAGEN - always ignore what was typed */
 | 
						||
	else unrchf = i;
 | 
						||
#endif /*-IMAGEN*/
 | 
						||
skipit:	chg_win(savwin);
 | 
						||
	kill_win(w);
 | 
						||
	redp(RD_WINDS);		/* Update all remaining windows */
 | 
						||
}
 | 
						||
 | 
						||
/* Mode Line generation */
 | 
						||
 | 
						||
struct window *
 | 
						||
make_mode(bw)
 | 
						||
register struct window *bw;	/* Base window we are reporting status of */
 | 
						||
{
 | 
						||
	register struct buffer *b;	/* Buffer of this window */
 | 
						||
	struct window *mw, *savew;	/* Save current window */
 | 
						||
	struct buffer *saveb;	/* and current buffer (in case different) */
 | 
						||
	char temp[20];
 | 
						||
 | 
						||
	saveb = cur_buf;	/* Save values prior to context switch */
 | 
						||
	savew = cur_win;
 | 
						||
	b = bw->w_buf;		/* Get buffer for that window */
 | 
						||
 | 
						||
#if FX_2MODEWINDS
 | 
						||
	if((mw = sep_win) && (mw->w_flags&W_MODE) &&
 | 
						||
	    (bw->w_pos == 0))		/* Base window is top window? */
 | 
						||
	  {				/* Use sep_win as mode wind */
 | 
						||
	  }
 | 
						||
	else
 | 
						||
#endif
 | 
						||
		mw = mode_win;		/* Default is normal mode window */
 | 
						||
	chg_win(mw);			/* Go to mode line window */
 | 
						||
	e_gobob();			/* go to beginning */
 | 
						||
	e_reset();			/* Flush buffer */
 | 
						||
#if IMAGEN
 | 
						||
	e_sputz(" ");
 | 
						||
	e_sputz(b->b_name);
 | 
						||
	if (b -> b_flags & B_MODIFIED)
 | 
						||
		e_sputz("*");
 | 
						||
	e_sputz(" (");
 | 
						||
	if (b->b_flags & B_QUERYREP)
 | 
						||
		e_sputz("[Query Replace] ");
 | 
						||
	if (b->b_flags & B_CMODE)
 | 
						||
		e_sputz("C");
 | 
						||
	else if (b->b_flags & B_TEXTMODE)
 | 
						||
		e_sputz("Text");
 | 
						||
	else
 | 
						||
		e_sputz("Fundamental");
 | 
						||
	e_sputz(")  ");
 | 
						||
	if (b->b_fn)
 | 
						||
		e_sputz(b->b_fn);
 | 
						||
	e_sputz("      ");
 | 
						||
#else
 | 
						||
	e_sputz(ev_verstr);		/* Editor name/version */
 | 
						||
	e_sputz(" (");
 | 
						||
	e_sputz(cur_mode->mjm_name);	/* insert major mode name */
 | 
						||
#if FX_FILLMODE
 | 
						||
	if(fill_mode) e_sputz(" Fill");
 | 
						||
#endif /*FX_FILLMODE*/
 | 
						||
#if FX_SKMAC
 | 
						||
	if(kdef_mode) e_sputz(" MacroDef");
 | 
						||
#endif /*FX_SKMAC*/
 | 
						||
	e_sputz(") ");
 | 
						||
	e_sputz(b->b_name);		/* buffer name */
 | 
						||
	e_sputz(": ");
 | 
						||
	if (b->b_fn)
 | 
						||
		e_sputz(b->b_fn);       /* file name */
 | 
						||
	if (b->b_flags & B_MODIFIED)
 | 
						||
		e_sputz(" *");
 | 
						||
	else	e_sputz("  ");
 | 
						||
#endif /*-IMAGEN*/
 | 
						||
	if(bw->w_pct < 200)		/* Not ALL? */
 | 
						||
	  {	e_sputz(" --");
 | 
						||
		switch(bw->w_pct)
 | 
						||
		  {	case -1:
 | 
						||
				e_sputz("TOP");
 | 
						||
				break;
 | 
						||
			case 150:
 | 
						||
				e_sputz("BOT");
 | 
						||
				break;
 | 
						||
			default:
 | 
						||
				dottoa(&temp[0],(chroff)bw->w_pct);
 | 
						||
				e_sputz(&temp[0]);
 | 
						||
				e_putc('%');
 | 
						||
		  }
 | 
						||
		e_sputz("--");
 | 
						||
	  }
 | 
						||
#if FX_SOWIND
 | 
						||
	if(mw->w_flags&W_STANDOUT)
 | 
						||
		e_insn(SP, (int)(scr_wd0 - e_blen()));	/* Stuff out with spaces */
 | 
						||
#endif
 | 
						||
 | 
						||
	redp(RD_WINRES);
 | 
						||
	chg_win(savew);		/* Restore context */
 | 
						||
	chg_buf(saveb);
 | 
						||
	return(mw);		/* Return mode window */
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
buf_mod()
 | 
						||
{	register struct buffer *b;
 | 
						||
 | 
						||
	b = cur_buf;
 | 
						||
	if((b->b_flags & B_MODIFIED) == 0)
 | 
						||
	  {	b->b_flags |= B_MODIFIED;
 | 
						||
		redp(RD_MODE);
 | 
						||
	  }
 | 
						||
}
 | 
						||
 | 
						||
/* BUF_TMOD - called when text modified in buffer, to set all
 | 
						||
 *	the appropriate indicators so that redisplay works right.
 | 
						||
 *	Changed text is everything from CUR_DOT to the given offset
 | 
						||
 *	from same.  If stuff was deleted, offset should be 0.
 | 
						||
 * BUF_TMAT - similar but argument is location of other end of range,
 | 
						||
 *	when caller knows that and wants life easy.
 | 
						||
 */
 | 
						||
 | 
						||
buf_tmat(dot)
 | 
						||
chroff dot;
 | 
						||
{	buf_tmod(dot - cur_dot);	/* Convert to offset */
 | 
						||
}
 | 
						||
buf_tmod(offset)
 | 
						||
chroff offset;
 | 
						||
{	register struct window *w;
 | 
						||
	chroff a, b, tmp;
 | 
						||
 | 
						||
	w = cur_win;
 | 
						||
	a = cur_dot;
 | 
						||
	b = a + offset;
 | 
						||
	if(a > b)	/* Get into right order */
 | 
						||
	  {	tmp = a;
 | 
						||
		a = b;
 | 
						||
		b = tmp;
 | 
						||
	  }
 | 
						||
	b = e_blen() - b;	/* Make upper bound relative to EOB */
 | 
						||
	if(w->w_bmod < 0)	/* Have range vars been set yet? */
 | 
						||
	  {	w->w_bmod = a;	/* Nope, so can just set 'em now. */
 | 
						||
		w->w_emod = b;
 | 
						||
	  }
 | 
						||
	else
 | 
						||
	  {	if(a < w->w_bmod)
 | 
						||
			w->w_bmod = a;
 | 
						||
		if(b < w->w_emod)
 | 
						||
			w->w_emod = b;
 | 
						||
	  }
 | 
						||
	buf_mod();		/* Maybe later just insert here? */
 | 
						||
	redp(RD_TMOD);
 | 
						||
}
 |