279 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			279 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
/* 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.
 | 
						||
 */
 | 
						||
/*
 | 
						||
 * EEF1	Various functions
 | 
						||
 *		Char move/ins/del
 | 
						||
 *		Case change
 | 
						||
 *		Char/word transpose
 | 
						||
 */
 | 
						||
 | 
						||
#include "elle.h"
 | 
						||
 | 
						||
/* EFUN: "Insert Self" */
 | 
						||
f_insself (c)
 | 
						||
int c;
 | 
						||
{
 | 
						||
#if IMAGEN
 | 
						||
	fim_insself(c);
 | 
						||
#else
 | 
						||
#if FX_FILLMODE
 | 
						||
	extern int fill_mode;
 | 
						||
 | 
						||
	if(fill_mode) fx_insfill(c);
 | 
						||
	else
 | 
						||
#endif /*FX_FILLMODE*/
 | 
						||
	ed_insn(c, exp);	/* Normal stuff */
 | 
						||
#endif /*-IMAGEN*/
 | 
						||
}
 | 
						||
 | 
						||
/* EFUN: "Quoted Insert"
 | 
						||
**	Inserts next char directly, <exp> number of times.
 | 
						||
** Does not check anything about the char and does not do anything
 | 
						||
** depending on the mode.  In particular, CR is not turned into EOL.
 | 
						||
*/
 | 
						||
f_quotins()
 | 
						||
{
 | 
						||
	ed_insn(cmd_read(), exp);	/* Insert next char directly */
 | 
						||
}
 | 
						||
 | 
						||
#if FX_CRLF
 | 
						||
/* EFUN: "CRLF" */
 | 
						||
f_crlf()
 | 
						||
{
 | 
						||
#if IMAGEN
 | 
						||
	fim_crlf();
 | 
						||
#else
 | 
						||
	register int i;
 | 
						||
 | 
						||
	if(e_goeol() == cur_dot		/* If at end of current line */
 | 
						||
	  && exp == 1			/* and inserting only 1 new line */
 | 
						||
	  && e_lblankp() && e_lblankp())	/* and next 2 lines blank */
 | 
						||
	  {	e_gocur();		/* Then just re-use next line. */
 | 
						||
		e_gonl();		/* Go to its start */
 | 
						||
		e_setcur();		/* and establish cur_dot there. */
 | 
						||
		ed_delete(e_dot(), e_eoldot());	/* Ensure any blanks flushed */
 | 
						||
	  }
 | 
						||
	else
 | 
						||
	  {	e_gocur();		/* Otherwise back to original place */
 | 
						||
		if((i = exp) > 0)	/* and simply insert newlines */
 | 
						||
			do ed_crins();
 | 
						||
			while(--i);
 | 
						||
	  }
 | 
						||
#endif /*-IMAGEN*/
 | 
						||
}
 | 
						||
#endif /*FX_CRLF*/
 | 
						||
 | 
						||
/* EFUN: "Forward Character" */
 | 
						||
f_fchar()
 | 
						||
{	ed_igoff(exp);
 | 
						||
}
 | 
						||
 | 
						||
/* EFUN: "Backward Character" */
 | 
						||
f_bchar()
 | 
						||
{	ed_igoff(-exp);
 | 
						||
}
 | 
						||
 | 
						||
/* EFUN: "Delete Character" */
 | 
						||
f_dchar ()
 | 
						||
{
 | 
						||
#if IMAGEN
 | 
						||
	fim_dchar();
 | 
						||
#else
 | 
						||
	ef_deln(exp);
 | 
						||
#endif /*-IMAGEN*/
 | 
						||
}
 | 
						||
 | 
						||
/* EFUN: "Backward Delete Character" */
 | 
						||
f_bdchar ()
 | 
						||
{
 | 
						||
#if IMAGEN
 | 
						||
	fim_bdchar();
 | 
						||
#else
 | 
						||
	ef_deln(-exp);
 | 
						||
#endif /*-IMAGEN*/
 | 
						||
}
 | 
						||
 | 
						||
/* Delete forward or backward N characters.
 | 
						||
 * If arg, kills instead of deleting.
 | 
						||
 */
 | 
						||
ef_deln(x)
 | 
						||
int x;
 | 
						||
{
 | 
						||
	e_igoff(x);
 | 
						||
	if(exp_p) ed_kill(cur_dot, e_dot());
 | 
						||
	else ed_delete(cur_dot, e_dot());
 | 
						||
}
 | 
						||
 | 
						||
#if FX_DELSPC
 | 
						||
/* EFUN: "Delete Horizontal Space" */
 | 
						||
/*	Delete spaces/tabs around point.
 | 
						||
 */
 | 
						||
f_delspc()
 | 
						||
{	chroff dot1;
 | 
						||
 | 
						||
	e_gobwsp();			/* Move backward over whitespace */
 | 
						||
	dot1 = e_dot();			/* Save point */
 | 
						||
	e_gofwsp();			/* Move forward over whitespace */
 | 
						||
	ed_delete(dot1,e_dot());	/* Delete twixt start and here */
 | 
						||
}
 | 
						||
#endif /*FX_DELSPC*/
 | 
						||
 | 
						||
#if FX_TCHARS
 | 
						||
/* EFUN: "Transpose Characters"
 | 
						||
 *	Transpose chars before and after cursor.  Doesn't hack args yet.
 | 
						||
 * EMACS: With positive arg, exchs chars before & after cursor, moves right,
 | 
						||
 *	and repeats the specified # of times, dragging the char to the
 | 
						||
 *	left of the cursor right.
 | 
						||
 *	With negative arg, transposes 2 chars to left of cursor, moves
 | 
						||
 *	between them, and repeats the specified # of times, exactly undoing
 | 
						||
 *	the positive arg form.  With zero arg, transposes chars at point
 | 
						||
 *	and mark.
 | 
						||
 *	HOWEVER: at the end of a line, with no arg, the preceding 2 chars
 | 
						||
 *	are transposed.
 | 
						||
 */
 | 
						||
f_tchars()
 | 
						||
{	register int c, c2;
 | 
						||
#if IMAGEN
 | 
						||
	c = e_rgetc();			/* Gosmacs style: twiddle prev 2 */
 | 
						||
	if (c == EOF)
 | 
						||
		return(e_gocur());	/* Do nothing at beginning of bfr */
 | 
						||
#else
 | 
						||
 | 
						||
	if((c = e_getc()) == EOF	/* If at EOF */
 | 
						||
	  || e_rgetc() == LF)		/* or at end of line, */
 | 
						||
		c = e_rgetc();		/* use preceding 2 chars */
 | 
						||
#endif /*-IMAGEN*/
 | 
						||
 | 
						||
	if((c2 = e_rgetc()) == EOF)	/* At beginning of buffer? */
 | 
						||
		return(e_gocur());	/* Yes, do nothing */
 | 
						||
	e_ovwc(c);
 | 
						||
	e_ovwc(c2);
 | 
						||
	e_setcur();
 | 
						||
	buf_tmod((chroff)-2);		/* Munged these 2 chars */
 | 
						||
}
 | 
						||
#endif /*FX_TCHARS*/
 | 
						||
 | 
						||
#if FX_FWORD
 | 
						||
/* EFUN: "Forward Word" */
 | 
						||
f_fword()
 | 
						||
{	chroff retdot;
 | 
						||
	if(e_wding(&retdot, exp))
 | 
						||
		ed_go(retdot);
 | 
						||
}
 | 
						||
#endif
 | 
						||
 | 
						||
#if FX_BWORD
 | 
						||
/* EFUN: "Backward Word" */
 | 
						||
f_bword()
 | 
						||
{	exp = -exp;
 | 
						||
	f_fword();
 | 
						||
}
 | 
						||
#endif
 | 
						||
 | 
						||
#if FX_KWORD
 | 
						||
/* EFUN: "Kill Word" */
 | 
						||
f_kword()
 | 
						||
{	chroff retdot;
 | 
						||
 | 
						||
	if(e_wding(&retdot,exp))
 | 
						||
	  {	ed_kill(cur_dot,retdot);
 | 
						||
		this_cmd = KILLCMD;
 | 
						||
	  }
 | 
						||
}
 | 
						||
#endif
 | 
						||
 | 
						||
#if FX_BKWORD
 | 
						||
/* EFUN: "Backward Kill Word" */
 | 
						||
f_bkword()
 | 
						||
{	exp = -exp;
 | 
						||
	f_kword();
 | 
						||
}
 | 
						||
#endif
 | 
						||
 | 
						||
#if FX_TWORDS
 | 
						||
/* EFUN: "Transpose Words" */
 | 
						||
/*	Transpose word.  Urk!
 | 
						||
 */
 | 
						||
f_twords()
 | 
						||
{	register SBSTR *sd1, *sd2;
 | 
						||
	register SBBUF *sb;
 | 
						||
	chroff begwd1, endwd1, begwd2, endwd2;
 | 
						||
 | 
						||
	endwd2 = e_wdot(cur_dot, 1);	/* Go to end of 2nd word */
 | 
						||
	begwd2 = e_wdot(endwd2, -1);	/* Go to beg of 2nd word */
 | 
						||
	if(begwd2 >= endwd2)		/* If no 2nd word, punt. */
 | 
						||
		return;
 | 
						||
	begwd1 = e_wdot(begwd2, -1);	/* Go to beg of 1st word */
 | 
						||
	endwd1 = e_wdot(begwd1, 1);	/* Go to end of 1st word */
 | 
						||
	if(begwd1 >= endwd1)		/* If no 1st word, punt. */
 | 
						||
		return;
 | 
						||
	if(endwd1 > begwd2)		/* Avoid possible overlap */
 | 
						||
		return;
 | 
						||
 | 
						||
	e_go(begwd2);
 | 
						||
	sb = (SBBUF *)cur_buf;
 | 
						||
	sd2 = sb_killn(sb, endwd2 - begwd2);	/* Excise wd 2 first */
 | 
						||
	e_go(begwd1);
 | 
						||
	sd1 = sb_killn(sb, endwd1 - begwd1);	/* Excise wd 1 */
 | 
						||
	sb_sins(sb, sd2);			/* Replace with wd 2 */
 | 
						||
	e_goff(begwd2 - endwd1);		/* Move past between stuff */
 | 
						||
	sb_sins(sb, sd1);			/* Insert wd 1 */
 | 
						||
	e_setcur();
 | 
						||
	buf_tmat(begwd1);			/* Modified this range */
 | 
						||
}
 | 
						||
#endif /*FX_TWORDS*/
 | 
						||
 | 
						||
/* Case hacking functions and support */
 | 
						||
 | 
						||
#if FX_UCWORD
 | 
						||
/* EFUN: "Uppercase Word" */
 | 
						||
f_ucword()
 | 
						||
{	case_word(0);
 | 
						||
}
 | 
						||
#endif /*FX_UCWORD*/
 | 
						||
 | 
						||
#if FX_LCWORD
 | 
						||
/* EFUN: "Lowercase Word" */
 | 
						||
f_lcword()
 | 
						||
{	case_word(1);
 | 
						||
}
 | 
						||
#endif /*FX_LCWORD*/
 | 
						||
 | 
						||
#if FX_UCIWORD
 | 
						||
/* EFUN: "Uppercase Initial" */
 | 
						||
f_uciword()
 | 
						||
{	case_word(2);
 | 
						||
}
 | 
						||
#endif /*FX_UCIWORD*/
 | 
						||
 | 
						||
#if FX_UCWORD||FX_LCWORD||FX_UCIWORD
 | 
						||
case_word (downp)
 | 
						||
{	chroff retdot;
 | 
						||
#if IMAGEN
 | 
						||
	chroff startdot;
 | 
						||
 | 
						||
	/* Normalize our position to beginning of "current" word,
 | 
						||
	 * where "current" is defined to be the current word we are in,
 | 
						||
	 * or else the previous word if we are not in any word.
 | 
						||
	 * All this silly nonsense just to perpetuate Gosmacs's
 | 
						||
	 * wrong behaviour!
 | 
						||
	 */
 | 
						||
	startdot = cur_dot;	/* Save current position */
 | 
						||
	e_getc();	/* If at beg of word, ensure we get inside it */
 | 
						||
	e_gowd(-1);	/* Go to start of this or prev word */
 | 
						||
	e_setcur();	/* Set cur_dot */
 | 
						||
#endif /*IMAGEN*/
 | 
						||
 | 
						||
	if(e_wding(&retdot, exp))
 | 
						||
	  {	ed_case(cur_dot,retdot,downp);
 | 
						||
		e_gosetcur(retdot);
 | 
						||
	  }
 | 
						||
#if IMAGEN
 | 
						||
	e_gosetcur(startdot);
 | 
						||
#endif /*IMAGEN*/
 | 
						||
}
 | 
						||
#endif /* any case_word caller */
 |