284 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			284 lines
		
	
	
		
			5.9 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.
 | 
						||
 */
 | 
						||
/*	EEFED - ED-type functions
 | 
						||
 */
 | 
						||
#include "elle.h"
 | 
						||
 | 
						||
/*
 | 
						||
 * ED_INSERT -- Insert character given as argument.
 | 
						||
 */
 | 
						||
 | 
						||
ed_insert(c)
 | 
						||
int c;
 | 
						||
{	register SBBUF *sb;
 | 
						||
 | 
						||
	sb = (SBBUF *) cur_buf;		/* For a little speed */
 | 
						||
	sb_putc(sb,c);		/* Insert the char */
 | 
						||
	cur_dot++;		/* Advance dot */
 | 
						||
	buf_tmod((chroff)-1);	/* Mark buffer modified, for redisplay etc. */
 | 
						||
				/* Perhaps later use specialized routine? */
 | 
						||
}
 | 
						||
 | 
						||
ed_insn(ch, cnt)
 | 
						||
int ch, cnt;
 | 
						||
{	register int i;
 | 
						||
	if((i = cnt) > 0)
 | 
						||
		do { ed_insert(ch);
 | 
						||
		  } while(--i);
 | 
						||
}
 | 
						||
 | 
						||
ed_crins()
 | 
						||
{
 | 
						||
#if FX_EOLMODE
 | 
						||
	if (eolcrlf(cur_buf))	/* If EOL is made of CR-LF */
 | 
						||
		ed_insert(CR);	/* then first insert CR, then drop down to */
 | 
						||
#endif
 | 
						||
	ed_insert(LF);		/* Insert LF */
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
ed_sins (s)			       /* insert this string */
 | 
						||
register char *s;
 | 
						||
{	register c;
 | 
						||
	while (c = *s++)
 | 
						||
		ed_insert (c);
 | 
						||
}
 | 
						||
 | 
						||
ed_nsins (s, i)		/* Insert string of N chars */
 | 
						||
register char *s;
 | 
						||
register int i;
 | 
						||
{	if(i > 0)
 | 
						||
		do { ed_insert(*s++); } while(--i);
 | 
						||
}
 | 
						||
 | 
						||
/* ED_INDTO(col) - Indent to specified column.
 | 
						||
**	Finds current cursor position, and inserts tabs and spaces
 | 
						||
** so cursor ends up at column goal.  Does nothing if already at or past
 | 
						||
** specified column.
 | 
						||
*/
 | 
						||
 | 
						||
ed_indto(goal)
 | 
						||
register int goal;
 | 
						||
{	register int ng;
 | 
						||
 | 
						||
	ng = goal & ~07;		/* Get distance to tab stop */
 | 
						||
	ed_insn(TAB, ((ng - (d_curind() & ~07)) >> 3));
 | 
						||
	ed_insn(SP, goal-ng);
 | 
						||
}
 | 
						||
 | 
						||
/* Oddball routine - Set cur_dot to actual I/O location and
 | 
						||
 * tell display that cursor probably moved.  This is not really a
 | 
						||
 * function of itself; it provides support for real functions.
 | 
						||
 */
 | 
						||
ed_setcur()
 | 
						||
{	e_setcur();	/* Set cur_dot */
 | 
						||
	redp(RD_MOVE);	/* Alert redisplay to check cursor loc */
 | 
						||
}
 | 
						||
 | 
						||
/* Go to given dot */
 | 
						||
ed_go (dot)
 | 
						||
chroff dot;
 | 
						||
{	e_go(dot);
 | 
						||
	ed_setcur();
 | 
						||
}
 | 
						||
 | 
						||
/* Go to given offset from current location */
 | 
						||
ed_goff(off)
 | 
						||
chroff off;
 | 
						||
{	e_goff(off);
 | 
						||
	ed_setcur();
 | 
						||
}
 | 
						||
 | 
						||
/* Go to given INTEGER offset from current location */
 | 
						||
ed_igoff(ioff)
 | 
						||
int ioff;
 | 
						||
{	e_igoff(ioff);
 | 
						||
	ed_setcur();
 | 
						||
}
 | 
						||
 | 
						||
/* Reset (delete all of) Buffer
 | 
						||
 * Should buffer be marked modified or not? Currently isn't.
 | 
						||
 */
 | 
						||
ed_reset()
 | 
						||
{	if(e_blen() == 0)
 | 
						||
		return;		/* Already empty */
 | 
						||
	e_reset();
 | 
						||
	cur_dot = 0;
 | 
						||
	cur_win->w_topldot = 0;	/* Is this necessary? */
 | 
						||
#if IMAGEN
 | 
						||
	redp(RD_WINRES|RD_REDO);
 | 
						||
#else
 | 
						||
	redp(RD_WINRES);	/* This window needs complete update */
 | 
						||
#endif /*-IMAGEN*/
 | 
						||
 | 
						||
/*	buf_mod(); */		/* Mark modified ?? */
 | 
						||
/*	mark_p = 0; */		/* Say no mark set ?? */
 | 
						||
}
 | 
						||
 | 
						||
ed_deln(off)
 | 
						||
chroff off;
 | 
						||
{	chroff dot;
 | 
						||
	dot = e_dot();
 | 
						||
	e_goff(off);	
 | 
						||
	ed_delete(e_dot(), dot);
 | 
						||
}
 | 
						||
 | 
						||
/* ED_DELETE(dot1,dot2) -  Delete all characters between the two
 | 
						||
 *	positions indicated by dot1 and dot2.  Their order does not
 | 
						||
 *	matter; cur_dot and mark_dot are updated as necessary.
 | 
						||
 */
 | 
						||
ed_delete(dot1,dot2)
 | 
						||
chroff dot1,dot2;
 | 
						||
{	chroff tmpdot, savdot;
 | 
						||
 | 
						||
	if(dot1 > dot2)
 | 
						||
	  {	tmpdot = dot1;
 | 
						||
		dot1 = dot2;
 | 
						||
		dot2 = tmpdot;
 | 
						||
	  }
 | 
						||
	e_go(dot1);
 | 
						||
	tmpdot = dot2-dot1;
 | 
						||
	sb_deln((SBBUF *)cur_buf,tmpdot);
 | 
						||
 | 
						||
	savdot = cur_dot;		/* Save cur_dot value */
 | 
						||
	cur_dot = dot1;			/* so can set up for */
 | 
						||
	buf_tmod((chroff)0);		/* call to update disp-change vars */
 | 
						||
	cur_dot = savdot;
 | 
						||
 | 
						||
	if(cur_dot >= dot2)
 | 
						||
		cur_dot -= tmpdot;
 | 
						||
	else if(cur_dot > dot1)
 | 
						||
		cur_dot = dot1;
 | 
						||
	if(mark_dot >= dot2)
 | 
						||
		mark_dot -= tmpdot;
 | 
						||
	else if(mark_dot > dot1)
 | 
						||
		mark_dot = dot1;
 | 
						||
	e_gocur();
 | 
						||
}
 | 
						||
 | 
						||
/* ED_KILL(dot1,dot2) - Kill (save and delete) text between two places in
 | 
						||
 *	the buffer.
 | 
						||
 * We assume we are deleting from dot1 to dot2, thus if dot1 > dot2
 | 
						||
 * then backwards deletion is implied, and the saved text is prefixed
 | 
						||
 * (instead of appended) to any previously killed text.
 | 
						||
 */
 | 
						||
ed_kill(dot1,dot2)
 | 
						||
chroff dot1,dot2;
 | 
						||
{	register SBSTR *sd, *sdo;
 | 
						||
	SBSTR *e_copyn();
 | 
						||
 | 
						||
	e_go(dot1);
 | 
						||
	sd = e_copyn(dot2-dot1);
 | 
						||
	if(sd == 0) return;
 | 
						||
	if(last_cmd == KILLCMD && (sdo = kill_ring[kill_ptr]))
 | 
						||
	  {	if(dot1 > dot2)	/* Prefix new killed stuff onto old stuff */
 | 
						||
		  {	sbs_app(sd,sdo);
 | 
						||
			kill_ring[kill_ptr] = sd;
 | 
						||
		  }
 | 
						||
		else		/* Append new stuff to old stuff */
 | 
						||
			sbs_app(sdo,sd);
 | 
						||
	  }
 | 
						||
	else kill_push(sd);
 | 
						||
	ed_delete(dot1,dot2);
 | 
						||
}
 | 
						||
 | 
						||
kill_push(sdp)
 | 
						||
SBSTR *sdp;
 | 
						||
{	register SBSTR *sd;
 | 
						||
 | 
						||
	if(++kill_ptr >= KILL_LEN) kill_ptr = 0;
 | 
						||
	if(sd = kill_ring[kill_ptr])
 | 
						||
		sbs_del(sd);
 | 
						||
	kill_ring[kill_ptr] = sdp;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
#define isupper(c) (('A' <= c) && (c <= 'Z'))
 | 
						||
#define islower(c) (('a' <= c) && (c <= 'z'))
 | 
						||
#define toupper(c) (c + ('A' - 'a'))
 | 
						||
#define tolower(c) (c + ('a' - 'A'))
 | 
						||
 | 
						||
#if FX_UCWORD||FX_LCWORD||FX_UCIWORD||FX_UCREG||FX_LCREG
 | 
						||
 | 
						||
/* ED_CASE(dot1,dot2,downp) - Change the case within a region.
 | 
						||
 *	downp = 0 for uppercase, 1 for lowercase, 2 for capitalize.
 | 
						||
 */
 | 
						||
ed_case(dot1, dot2, downp)
 | 
						||
chroff dot1, dot2;
 | 
						||
int downp;
 | 
						||
{	chroff dcnt;
 | 
						||
	register int c, a, z;
 | 
						||
	int modflg;
 | 
						||
 | 
						||
	modflg = 0;
 | 
						||
	if((dcnt = dot2 - dot1) < 0)
 | 
						||
	  {	dcnt = dot1;
 | 
						||
		dot1 = dot2;
 | 
						||
		dot2 = dcnt;
 | 
						||
		dcnt -= dot1;
 | 
						||
	  }
 | 
						||
	e_go(dot1);
 | 
						||
 | 
						||
	if(downp==2)
 | 
						||
	  {	a = 0;	/* 0 looking for wd, 1 in word */
 | 
						||
		while(--dcnt >= 0)
 | 
						||
		  {	if(delimp(c = e_getc()))	/* Char in wd? */
 | 
						||
			  {	a = 0;			/* No */
 | 
						||
				continue;
 | 
						||
			  }
 | 
						||
			 if(a)		/* If already inside word */
 | 
						||
			  {	if(isupper(c))
 | 
						||
					c = tolower(c);
 | 
						||
				else continue;
 | 
						||
			  }
 | 
						||
			else	/* If encountered start of word */
 | 
						||
			  {	a = 1;
 | 
						||
				if(islower(c))
 | 
						||
					c = toupper(c);
 | 
						||
				else continue;
 | 
						||
			  }
 | 
						||
			e_backc();
 | 
						||
			e_ovwc(c);
 | 
						||
			modflg++;
 | 
						||
		  }
 | 
						||
		goto casdon;
 | 
						||
	  }
 | 
						||
	if(downp==0)
 | 
						||
	  {	a = 'a';		/* Convert to lower case */
 | 
						||
		z = 'z';
 | 
						||
		downp = -040;
 | 
						||
	  }
 | 
						||
	else
 | 
						||
	  {	a = 'A';		/* Convert to upper case */
 | 
						||
		z = 'Z';
 | 
						||
		downp = 040;
 | 
						||
	  }
 | 
						||
	while(--dcnt >= 0)
 | 
						||
	  {	if(a <= (c = e_getc()) && c <= z)
 | 
						||
		  {	e_backc();
 | 
						||
			e_ovwc(c+downp);
 | 
						||
			modflg++;
 | 
						||
		  }
 | 
						||
	  }
 | 
						||
 | 
						||
casdon:	dot2 = cur_dot;			/* Save dot */
 | 
						||
	e_setcur();			/* Set up for modification range chk*/
 | 
						||
	if(modflg)
 | 
						||
		buf_tmat(dot1);		/* Stuff munged from there to here */
 | 
						||
	ed_go(dot2);
 | 
						||
}
 | 
						||
#endif /* any ed_case caller */
 | 
						||
 | 
						||
 | 
						||
/* UPCASE(c) - Return upper-case version of character */
 | 
						||
upcase(ch)
 | 
						||
int ch;
 | 
						||
{	register int c;
 | 
						||
	c = ch&0177;
 | 
						||
	return(islower(c) ? toupper(c) : c);
 | 
						||
}
 | 
						||
 |