ed.chared.c revision 83098
183098Smp/* $Header: /src/pub/tcsh/ed.chared.c,v 3.70 2001/09/02 21:06:02 christos Exp $ */
259243Sobrien/*
359243Sobrien * ed.chared.c: Character editing functions.
459243Sobrien */
559243Sobrien/*-
659243Sobrien * Copyright (c) 1980, 1991 The Regents of the University of California.
759243Sobrien * All rights reserved.
859243Sobrien *
959243Sobrien * Redistribution and use in source and binary forms, with or without
1059243Sobrien * modification, are permitted provided that the following conditions
1159243Sobrien * are met:
1259243Sobrien * 1. Redistributions of source code must retain the above copyright
1359243Sobrien *    notice, this list of conditions and the following disclaimer.
1459243Sobrien * 2. Redistributions in binary form must reproduce the above copyright
1559243Sobrien *    notice, this list of conditions and the following disclaimer in the
1659243Sobrien *    documentation and/or other materials provided with the distribution.
1759243Sobrien * 3. All advertising materials mentioning features or use of this software
1859243Sobrien *    must display the following acknowledgement:
1959243Sobrien *	This product includes software developed by the University of
2059243Sobrien *	California, Berkeley and its contributors.
2159243Sobrien * 4. Neither the name of the University nor the names of its contributors
2259243Sobrien *    may be used to endorse or promote products derived from this software
2359243Sobrien *    without specific prior written permission.
2459243Sobrien *
2559243Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2659243Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2759243Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2859243Sobrien * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2959243Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3059243Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3159243Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3259243Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3359243Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3459243Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3559243Sobrien * SUCH DAMAGE.
3659243Sobrien */
3759243Sobrien/*
3859243Sobrien  Bjorn Knutsson @ Thu Jun 24 19:02:17 1999
3959243Sobrien
4059243Sobrien  e_dabbrev_expand() did not do proper completion if quoted spaces were present
4159243Sobrien  in the string being completed. Exemple:
4259243Sobrien
4359243Sobrien  # echo hello\ world
4459243Sobrien  hello world
4559243Sobrien  # echo h<press key bound to dabbrev-expande>
4659243Sobrien  # echo hello\<cursor>
4759243Sobrien
4859243Sobrien  Correct behavior is:
4959243Sobrien  # echo h<press key bound to dabbrev-expande>
5059243Sobrien  # echo hello\ world<cursor>
5159243Sobrien
5259243Sobrien  The same problem occured if spaces were present in a string withing quotation
5359243Sobrien  marks. Example:
5459243Sobrien
5559243Sobrien  # echo "hello world"
5659243Sobrien  hello world
5759243Sobrien  # echo "h<press key bound to dabbrev-expande>
5859243Sobrien  # echo "hello<cursor>
5959243Sobrien
6059243Sobrien  The former problem could be solved with minor modifications of c_preword()
6159243Sobrien  and c_endword(). The latter, however, required a significant rewrite of
6259243Sobrien  c_preword(), since quoted strings must be parsed from start to end to
6359243Sobrien  determine if a given character is inside or outside the quotation marks.
6459243Sobrien
6559243Sobrien  Compare the following two strings:
6659243Sobrien
6759243Sobrien  # echo \"" 'foo \' bar\"
6859243Sobrien  " 'foo \' bar\
6959243Sobrien  # echo '\"" 'foo \' bar\"
7059243Sobrien  \"" foo ' bar"
7159243Sobrien
7259243Sobrien  The only difference between the two echo lines is in the first character
7359243Sobrien  after the echo command. The result is either one or three arguments.
7459243Sobrien
7559243Sobrien */
7659243Sobrien
7759243Sobrien#include "sh.h"
7859243Sobrien
7983098SmpRCSID("$Id: ed.chared.c,v 3.70 2001/09/02 21:06:02 christos Exp $")
8059243Sobrien
8159243Sobrien#include "ed.h"
8259243Sobrien#include "tw.h"
8359243Sobrien#include "ed.defns.h"
8459243Sobrien
8559243Sobrien/* #define SDEBUG */
8659243Sobrien
8759243Sobrien#define TCSHOP_NOP    	  0x00
8859243Sobrien#define TCSHOP_DELETE 	  0x01
8959243Sobrien#define TCSHOP_INSERT 	  0x02
9059243Sobrien#define TCSHOP_CHANGE 	  0x04
9159243Sobrien
9259243Sobrien#define CHAR_FWD	0
9359243Sobrien#define CHAR_BACK	1
9459243Sobrien
9559243Sobrien/*
9659243Sobrien * vi word treatment
9759243Sobrien * from: Gert-Jan Vons <vons@cesar.crbca1.sinet.slb.com>
9859243Sobrien */
9959243Sobrien#define C_CLASS_WHITE	1
10059243Sobrien#define C_CLASS_ALNUM	2
10159243Sobrien#define C_CLASS_OTHER	3
10259243Sobrien
10359243Sobrienstatic Char *InsertPos = InputBuf; /* Where insertion starts */
10459243Sobrienstatic Char *ActionPos = 0;	   /* Where action begins  */
10559243Sobrienstatic int  ActionFlag = TCSHOP_NOP;	   /* What delayed action to take */
10659243Sobrien/*
10759243Sobrien * Word search state
10859243Sobrien */
10959243Sobrienstatic int  searchdir = F_UP_SEARCH_HIST; 	/* Direction of last search */
11059243Sobrienstatic Char patbuf[INBUFSIZE];			/* Search target */
11159243Sobrienstatic int patlen = 0;
11259243Sobrien/*
11359243Sobrien * Char search state
11459243Sobrien */
11559243Sobrienstatic int  srch_dir = CHAR_FWD;		/* Direction of last search */
11659243Sobrienstatic Char srch_char = 0;			/* Search target */
11759243Sobrien
11859243Sobrien/* all routines that start with c_ are private to this set of routines */
11959243Sobrienstatic	void	 c_alternativ_key_map	__P((int));
12083098Smpvoid	 c_insert		__P((int));
12169408Sachevoid	 c_delafter		__P((int));
12269408Sachevoid	 c_delbefore		__P((int));
12359243Sobrienstatic 	int	 c_to_class		__P((int));
12459243Sobrienstatic	Char	*c_prev_word		__P((Char *, Char *, int));
12559243Sobrienstatic	Char	*c_next_word		__P((Char *, Char *, int));
12659243Sobrienstatic	Char	*c_number		__P((Char *, int *, int));
12759243Sobrienstatic	Char	*c_expand		__P((Char *));
12859243Sobrienstatic	void	 c_excl			__P((Char *));
12959243Sobrienstatic	void	 c_substitute		__P((void));
13059243Sobrienstatic	void	 c_delfini		__P((void));
13159243Sobrienstatic	int	 c_hmatch		__P((Char *));
13259243Sobrienstatic	void	 c_hsetpat		__P((void));
13359243Sobrien#ifdef COMMENT
13459243Sobrienstatic	void	 c_get_word		__P((Char **, Char **));
13559243Sobrien#endif
13683098Smpstatic	Char	*c_preword		__P((Char *, Char *, int, Char *));
13759243Sobrienstatic	Char	*c_nexword		__P((Char *, Char *, int));
13883098Smpstatic	Char	*c_endword		__P((Char *, Char *, int, Char *));
13959243Sobrienstatic	Char	*c_eword		__P((Char *, Char *, int));
14083098Smpstatic	void	 c_push_kill		__P((Char *, Char *));
14159243Sobrienstatic  CCRETVAL c_get_histline		__P((void));
14259243Sobrienstatic  CCRETVAL c_search_line		__P((Char *, int));
14359243Sobrienstatic  CCRETVAL v_repeat_srch		__P((int));
14459243Sobrienstatic	CCRETVAL e_inc_search		__P((int));
14559243Sobrienstatic	CCRETVAL v_search		__P((int));
14659243Sobrienstatic	CCRETVAL v_csearch_fwd		__P((int, int, int));
14759243Sobrienstatic	CCRETVAL v_action		__P((int));
14859243Sobrienstatic	CCRETVAL v_csearch_back		__P((int, int, int));
14959243Sobrien
15059243Sobrien#if defined(DSPMBYTE)
15159243Sobrienstatic	void 	 e_charfwd_mbyte	__P((int));
15259243Sobrienstatic	void 	 e_charback_mbyte	__P((int));
15359243Sobrienstatic  int extdel;
15459243Sobrienstatic  int extins = 0;
15559243Sobrien#endif
15659243Sobrien
15759243Sobrienstatic void
15859243Sobrienc_alternativ_key_map(state)
15959243Sobrien    int     state;
16059243Sobrien{
16159243Sobrien    switch (state) {
16259243Sobrien    case 0:
16359243Sobrien	CurrentKeyMap = CcKeyMap;
16459243Sobrien	break;
16559243Sobrien    case 1:
16659243Sobrien	CurrentKeyMap = CcAltMap;
16759243Sobrien	break;
16859243Sobrien    default:
16959243Sobrien	return;
17059243Sobrien    }
17159243Sobrien
17259243Sobrien    AltKeyMap = (Char) state;
17359243Sobrien}
17459243Sobrien
17583098Smpvoid
17659243Sobrienc_insert(num)
17783098Smp    int num;
17859243Sobrien{
17983098Smp    Char *cp;
18059243Sobrien
18159243Sobrien    if (LastChar + num >= InputLim)
18259243Sobrien	return;			/* can't go past end of buffer */
18359243Sobrien
18459243Sobrien    if (Cursor < LastChar) {	/* if I must move chars */
18559243Sobrien	for (cp = LastChar; cp >= Cursor; cp--)
18659243Sobrien	    cp[num] = *cp;
18759243Sobrien    }
18859243Sobrien    LastChar += num;
18959243Sobrien}
19059243Sobrien
19169408Sachevoid
19259243Sobrienc_delafter(num)
19383098Smp    int num;
19459243Sobrien{
19583098Smp    Char *cp, *kp = NULL;
19659243Sobrien
19759243Sobrien#if defined(DSPMBYTE)
19859243Sobrien    Char *wkcp;
19959243Sobrien
20059243Sobrien    extdel = 0;
20159243Sobrien#endif
20259243Sobrien
20359243Sobrien    if (num > LastChar - Cursor)
20459243Sobrien	num = (int) (LastChar - Cursor);	/* bounds check */
20559243Sobrien
20659243Sobrien    if (num > 0) {			/* if I can delete anything */
20759243Sobrien#if defined(DSPMBYTE)
20859243Sobrien	/* check for code of deleted character */
20959243Sobrien	if (_enable_mbdisp) {
21059243Sobrien	    for (wkcp = Cursor ; wkcp < Cursor + num; wkcp++) {
21159243Sobrien		if (extdel == 0)
21259243Sobrien		    extdel = Ismbyte1(*wkcp); /* check to 1st. byte */
21359243Sobrien		else
21459243Sobrien		    extdel = 0;	/* if 2nd. byte, force set to 0 */
21559243Sobrien	    }
21659243Sobrien	}
21759243Sobrien#endif
21859243Sobrien	if (VImode) {
21959243Sobrien	    kp = UndoBuf;		/* Set Up for VI undo command */
22059243Sobrien	    UndoAction = TCSHOP_INSERT;
22159243Sobrien	    UndoSize = num;
22259243Sobrien	    UndoPtr  = Cursor;
22359243Sobrien	    for (cp = Cursor; cp <= LastChar; cp++) {
22459243Sobrien		*kp++ = *cp;	/* Save deleted chars into undobuf */
22559243Sobrien		*cp = cp[num];
22659243Sobrien	    }
22759243Sobrien	}
22859243Sobrien	else
22959243Sobrien	    for (cp = Cursor; cp <= LastChar; cp++)
23059243Sobrien		*cp = cp[num];
23159243Sobrien	LastChar -= num;
23259243Sobrien#if defined(DSPMBYTE)
23359243Sobrien	if (_enable_mbdisp && extdel && Ismbyte2(*Cursor)) {
23459243Sobrien	    if( VImode ) {
23559243Sobrien		UndoSize++;
23659243Sobrien		*kp++ = *Cursor; /* Save deleted chars into undobuf */
23759243Sobrien	    }
23859243Sobrien	    for (cp = Cursor; cp <= LastChar; cp++)
23959243Sobrien		*cp = cp[1];
24059243Sobrien	    LastChar--;
24159243Sobrien	    e_redisp( 1 );
24259243Sobrien	}
24359243Sobrien	else
24459243Sobrien	    extdel = 0;
24559243Sobrien#endif
24659243Sobrien    }
24759243Sobrien#ifdef notdef
24859243Sobrien    else {
24959243Sobrien	/*
25059243Sobrien	 * XXX: We don't want to do that. In emacs mode overwrite should be
25159243Sobrien	 * sticky. I am not sure how that affects vi mode
25259243Sobrien	 */
25359243Sobrien	inputmode = MODE_INSERT;
25459243Sobrien    }
25559243Sobrien#endif /* notdef */
25659243Sobrien}
25759243Sobrien
25869408Sachevoid
25959243Sobrienc_delbefore(num)		/* delete before dot, with bounds checking */
26083098Smp    int num;
26159243Sobrien{
26283098Smp    Char *cp, *kp = NULL;
26359243Sobrien
26459243Sobrien#if defined(DSPMBYTE)
26559243Sobrien    Char *nowcur, *wkcp;
26659243Sobrien    Char delc;
26759243Sobrien
26859243Sobrien    extdel = 0;
26959243Sobrien#endif
27059243Sobrien
27159243Sobrien    if (num > Cursor - InputBuf)
27259243Sobrien	num = (int) (Cursor - InputBuf);	/* bounds check */
27359243Sobrien
27459243Sobrien    if (num > 0) {			/* if I can delete anything */
27559243Sobrien#if defined(DSPMBYTE)
27659243Sobrien	nowcur = Cursor - num;
27759243Sobrien	delc = *nowcur;
27859243Sobrien#endif
27959243Sobrien	if (VImode) {
28059243Sobrien	    kp = UndoBuf;		/* Set Up for VI undo command */
28159243Sobrien	    UndoAction = TCSHOP_INSERT;
28259243Sobrien	    UndoSize = num;
28359243Sobrien	    UndoPtr  = Cursor - num;
28459243Sobrien	    for (cp = Cursor - num; cp <= LastChar; cp++) {
28559243Sobrien		*kp++ = *cp;
28659243Sobrien		*cp = cp[num];
28759243Sobrien	    }
28859243Sobrien	}
28959243Sobrien	else
29059243Sobrien	    for (cp = Cursor - num; cp <= LastChar; cp++)
29159243Sobrien		*cp = cp[num];
29259243Sobrien	LastChar -= num;
29359243Sobrien#if defined(DSPMBYTE)
29459243Sobrien	if (_enable_mbdisp) {
29559243Sobrien	    for (wkcp = InputBuf; wkcp < nowcur; wkcp++) {
29659243Sobrien		if(extdel == 0)
29759243Sobrien		    extdel = Ismbyte1(*wkcp); /* check to 1st. byte */
29859243Sobrien		else
29959243Sobrien		    extdel = 0;	/* if 2nd. byte, force set to 0 */
30059243Sobrien	    }
30159243Sobrien	    if (extdel && Ismbyte2(delc)) {
30259243Sobrien		if( VImode ) {
30359243Sobrien		    UndoSize++;
30459243Sobrien		    UndoPtr--;
30559243Sobrien		    *kp++ = *(nowcur-1);
30659243Sobrien				/* Save deleted chars into undobuf */
30759243Sobrien		}
30859243Sobrien		for (cp = nowcur - 1; cp <= LastChar; cp++)
30959243Sobrien		    *cp = cp[1];
31059243Sobrien		LastChar--;
31159243Sobrien	    }
31259243Sobrien	}
31359243Sobrien	else
31459243Sobrien	    extdel = 0;
31559243Sobrien#endif
31659243Sobrien    }
31759243Sobrien}
31859243Sobrien
31959243Sobrienstatic Char *
32083098Smpc_preword(p, low, n, delim)
32183098Smp    Char *p, *low, *delim;
32283098Smp    int n;
32359243Sobrien{
32459243Sobrien  while (n--) {
32583098Smp    Char *prev = low;
32683098Smp    Char *new;
32759243Sobrien
32883098Smp    while (prev < p) {		/* Skip initial non-word chars */
32983098Smp      if (!Strchr(delim, *prev) || *(prev-1) == (Char)'\\')
33059243Sobrien	break;
33159243Sobrien      prev++;
33259243Sobrien    }
33359243Sobrien
33459243Sobrien    new = prev;
33559243Sobrien
33659243Sobrien    while (new < p) {
33759243Sobrien      prev = new;
33883098Smp      new = c_endword(prev-1, p, 1, delim); /* Skip to next non-word char */
33959243Sobrien      new++;			/* Step away from end of word */
34083098Smp      while (new <= p) {	/* Skip trailing non-word chars */
34183098Smp	if (!Strchr(delim, *new) || *(new-1) == (Char)'\\')
34259243Sobrien	  break;
34359243Sobrien	new++;
34459243Sobrien      }
34559243Sobrien    }
34659243Sobrien
34759243Sobrien    p = prev;			/* Set to previous word start */
34859243Sobrien
34959243Sobrien  }
35059243Sobrien  if (p < low)
35159243Sobrien    p = low;
35259243Sobrien  return (p);
35359243Sobrien}
35459243Sobrien
35559243Sobrien/*
35659243Sobrien * c_to_class() returns the class of the given character.
35759243Sobrien *
35859243Sobrien * This is used to make the c_prev_word() and c_next_word() functions
35959243Sobrien * work like vi's, which classify characters. A word is a sequence of
36059243Sobrien * characters belonging to the same class, classes being defined as
36159243Sobrien * follows:
36259243Sobrien *
36359243Sobrien *	1/ whitespace
36459243Sobrien *	2/ alphanumeric chars, + underscore
36559243Sobrien *	3/ others
36659243Sobrien */
36759243Sobrienstatic int
36859243Sobrienc_to_class(ch)
36983098Smpint  ch;
37059243Sobrien{
37159243Sobrien    if (Isspace(ch))
37259243Sobrien        return C_CLASS_WHITE;
37359243Sobrien
37459243Sobrien    if (Isdigit(ch) || Isalpha(ch) || ch == '_')
37559243Sobrien        return C_CLASS_ALNUM;
37659243Sobrien
37759243Sobrien    return C_CLASS_OTHER;
37859243Sobrien}
37959243Sobrien
38059243Sobrienstatic Char *
38159243Sobrienc_prev_word(p, low, n)
38283098Smp    Char *p, *low;
38383098Smp    int n;
38459243Sobrien{
38559243Sobrien    p--;
38659243Sobrien
38759243Sobrien    if (!VImode) {
38859243Sobrien	while (n--) {
38959243Sobrien	    while ((p >= low) && !isword(*p))
39059243Sobrien		p--;
39159243Sobrien	    while ((p >= low) && isword(*p))
39259243Sobrien		p--;
39359243Sobrien	}
39459243Sobrien
39559243Sobrien	/* cp now points to one character before the word */
39659243Sobrien	p++;
39759243Sobrien	if (p < low)
39859243Sobrien	    p = low;
39959243Sobrien	/* cp now points where we want it */
40059243Sobrien	return(p);
40159243Sobrien    }
40259243Sobrien
40359243Sobrien    while (n--) {
40483098Smp        int  c_class;
40559243Sobrien
40659243Sobrien        if (p < low)
40759243Sobrien            break;
40859243Sobrien
40959243Sobrien        /* scan until beginning of current word (may be all whitespace!) */
41059243Sobrien        c_class = c_to_class(*p);
41159243Sobrien        while ((p >= low) && c_class == c_to_class(*p))
41259243Sobrien            p--;
41359243Sobrien
41459243Sobrien        /* if this was a non_whitespace word, we're ready */
41559243Sobrien        if (c_class != C_CLASS_WHITE)
41659243Sobrien            continue;
41759243Sobrien
41859243Sobrien        /* otherwise, move back to beginning of the word just found */
41959243Sobrien        c_class = c_to_class(*p);
42059243Sobrien        while ((p >= low) && c_class == c_to_class(*p))
42159243Sobrien            p--;
42259243Sobrien    }
42359243Sobrien
42459243Sobrien    p++;                        /* correct overshoot */
42559243Sobrien
42659243Sobrien    return (p);
42759243Sobrien}
42859243Sobrien
42959243Sobrienstatic Char *
43059243Sobrienc_next_word(p, high, n)
43183098Smp    Char *p, *high;
43283098Smp    int n;
43359243Sobrien{
43459243Sobrien    if (!VImode) {
43559243Sobrien	while (n--) {
43659243Sobrien	    while ((p < high) && !isword(*p))
43759243Sobrien		p++;
43859243Sobrien	    while ((p < high) && isword(*p))
43959243Sobrien		p++;
44059243Sobrien	}
44159243Sobrien	if (p > high)
44259243Sobrien	    p = high;
44359243Sobrien	/* p now points where we want it */
44459243Sobrien	return(p);
44559243Sobrien    }
44659243Sobrien
44759243Sobrien    while (n--) {
44883098Smp        int  c_class;
44959243Sobrien
45059243Sobrien        if (p >= high)
45159243Sobrien            break;
45259243Sobrien
45359243Sobrien        /* scan until end of current word (may be all whitespace!) */
45459243Sobrien        c_class = c_to_class(*p);
45559243Sobrien        while ((p < high) && c_class == c_to_class(*p))
45659243Sobrien            p++;
45759243Sobrien
45859243Sobrien        /* if this was all whitespace, we're ready */
45959243Sobrien        if (c_class == C_CLASS_WHITE)
46059243Sobrien            continue;
46159243Sobrien
46259243Sobrien	/* if we've found white-space at the end of the word, skip it */
46359243Sobrien        while ((p < high) && c_to_class(*p) == C_CLASS_WHITE)
46459243Sobrien            p++;
46559243Sobrien    }
46659243Sobrien
46759243Sobrien    p--;                        /* correct overshoot */
46859243Sobrien
46959243Sobrien    return (p);
47059243Sobrien}
47159243Sobrien
47259243Sobrienstatic Char *
47359243Sobrienc_nexword(p, high, n)
47483098Smp    Char *p, *high;
47583098Smp    int n;
47659243Sobrien{
47759243Sobrien    while (n--) {
47859243Sobrien	while ((p < high) && !Isspace(*p))
47959243Sobrien	    p++;
48059243Sobrien	while ((p < high) && Isspace(*p))
48159243Sobrien	    p++;
48259243Sobrien    }
48359243Sobrien
48459243Sobrien    if (p > high)
48559243Sobrien	p = high;
48659243Sobrien    /* p now points where we want it */
48759243Sobrien    return(p);
48859243Sobrien}
48959243Sobrien
49059243Sobrien/*
49159243Sobrien * Expand-History (originally "Magic-Space") code added by
49259243Sobrien * Ray Moody <ray@gibbs.physics.purdue.edu>
49359243Sobrien * this is a neat, but odd, addition.
49459243Sobrien */
49559243Sobrien
49659243Sobrien/*
49759243Sobrien * c_number: Ignore character p points to, return number appearing after that.
49859243Sobrien * A '$' by itself means a big number; "$-" is for negative; '^' means 1.
49959243Sobrien * Return p pointing to last char used.
50059243Sobrien */
50159243Sobrien
50259243Sobrien/*
50359243Sobrien * dval is the number to subtract from for things like $-3
50459243Sobrien */
50559243Sobrien
50659243Sobrienstatic Char *
50759243Sobrienc_number(p, num, dval)
50883098Smp    Char *p;
50983098Smp    int *num;
51083098Smp    int dval;
51159243Sobrien{
51283098Smp    int i;
51383098Smp    int sign = 1;
51459243Sobrien
51559243Sobrien    if (*++p == '^') {
51659243Sobrien	*num = 1;
51759243Sobrien	return(p);
51859243Sobrien    }
51959243Sobrien    if (*p == '$') {
52059243Sobrien	if (*++p != '-') {
52159243Sobrien	    *num = NCARGS;	/* Handle $ */
52259243Sobrien	    return(--p);
52359243Sobrien	}
52459243Sobrien	sign = -1;		/* Handle $- */
52559243Sobrien	++p;
52659243Sobrien    }
52759243Sobrien    for (i = 0; *p >= '0' && *p <= '9'; i = 10 * i + *p++ - '0')
52859243Sobrien	continue;
52959243Sobrien    *num = (sign < 0 ? dval - i : i);
53059243Sobrien    return(--p);
53159243Sobrien}
53259243Sobrien
53359243Sobrien/*
53459243Sobrien * excl_expand: There is an excl to be expanded to p -- do the right thing
53559243Sobrien * with it and return a version of p advanced over the expanded stuff.  Also,
53659243Sobrien * update tsh_cur and related things as appropriate...
53759243Sobrien */
53859243Sobrien
53959243Sobrienstatic Char *
54059243Sobrienc_expand(p)
54183098Smp    Char *p;
54259243Sobrien{
54383098Smp    Char *q;
54483098Smp    struct Hist *h = Histlist.Hnext;
54583098Smp    struct wordent *l;
54659243Sobrien    int     i, from, to, dval;
54759243Sobrien    bool    all_dig;
54859243Sobrien    bool    been_once = 0;
54959243Sobrien    Char   *op = p;
55059243Sobrien    Char    buf[INBUFSIZE];
55159243Sobrien    Char   *bend = buf;
55259243Sobrien    Char   *modbuf, *omodbuf;
55359243Sobrien
55459243Sobrien    if (!h)
55559243Sobrien	goto excl_err;
55659243Sobrienexcl_sw:
55759243Sobrien    switch (*(q = p + 1)) {
55859243Sobrien
55959243Sobrien    case '^':
56059243Sobrien	bend = expand_lex(buf, INBUFSIZE, &h->Hlex, 1, 1);
56159243Sobrien	break;
56259243Sobrien
56359243Sobrien    case '$':
56459243Sobrien	if ((l = (h->Hlex).prev) != 0)
56559243Sobrien	    bend = expand_lex(buf, INBUFSIZE, l->prev->prev, 0, 0);
56659243Sobrien	break;
56759243Sobrien
56859243Sobrien    case '*':
56959243Sobrien	bend = expand_lex(buf, INBUFSIZE, &h->Hlex, 1, NCARGS);
57059243Sobrien	break;
57159243Sobrien
57259243Sobrien    default:
57359243Sobrien	if (been_once) {	/* unknown argument */
57459243Sobrien	    /* assume it's a modifier, e.g. !foo:h, and get whole cmd */
57559243Sobrien	    bend = expand_lex(buf, INBUFSIZE, &h->Hlex, 0, NCARGS);
57659243Sobrien	    q -= 2;
57759243Sobrien	    break;
57859243Sobrien	}
57959243Sobrien	been_once = 1;
58059243Sobrien
58159243Sobrien	if (*q == ':')		/* short form: !:arg */
58259243Sobrien	    --q;
58359243Sobrien
58459243Sobrien	if (*q != HIST) {
58559243Sobrien	    /*
58659243Sobrien	     * Search for a space, tab, or colon.  See if we have a number (as
58759243Sobrien	     * in !1234:xyz).  Remember the number.
58859243Sobrien	     */
58959243Sobrien	    for (i = 0, all_dig = 1;
59059243Sobrien		 *q != ' ' && *q != '\t' && *q != ':' && q < Cursor; q++) {
59159243Sobrien		/*
59259243Sobrien		 * PWP: !-4 is a valid history argument too, therefore the test
59359243Sobrien		 * is if not a digit, or not a - as the first character.
59459243Sobrien		 */
59559243Sobrien		if ((*q < '0' || *q > '9') && (*q != '-' || q != p + 1))
59659243Sobrien		    all_dig = 0;
59759243Sobrien		else if (*q == '-')
59859243Sobrien		    all_dig = 2;/* we are sneeky about this */
59959243Sobrien		else
60059243Sobrien		    i = 10 * i + *q - '0';
60159243Sobrien	    }
60259243Sobrien	    --q;
60359243Sobrien
60459243Sobrien	    /*
60559243Sobrien	     * If we have a number, search for event i.  Otherwise, search for
60659243Sobrien	     * a named event (as in !foo).  (In this case, I is the length of
60759243Sobrien	     * the named event).
60859243Sobrien	     */
60959243Sobrien	    if (all_dig) {
61059243Sobrien		if (all_dig == 2)
61159243Sobrien		    i = -i;	/* make it negitive */
61259243Sobrien		if (i < 0)	/* if !-4 (for example) */
61359243Sobrien		    i = eventno + 1 + i;	/* remember: i is < 0 */
61459243Sobrien		for (; h; h = h->Hnext) {
61559243Sobrien		    if (h->Hnum == i)
61659243Sobrien			break;
61759243Sobrien		}
61859243Sobrien	    }
61959243Sobrien	    else {
62059243Sobrien		for (i = (int) (q - p); h; h = h->Hnext) {
62159243Sobrien		    if ((l = &h->Hlex) != 0) {
62259243Sobrien			if (!Strncmp(p + 1, l->next->word, (size_t) i))
62359243Sobrien			    break;
62459243Sobrien		    }
62559243Sobrien		}
62659243Sobrien	    }
62759243Sobrien	}
62859243Sobrien	if (!h)
62959243Sobrien	    goto excl_err;
63059243Sobrien	if (q[1] == ':' || q[1] == '-' || q[1] == '*' ||
63159243Sobrien	    q[1] == '$' || q[1] == '^') {	/* get some args */
63259243Sobrien	    p = q[1] == ':' ? ++q : q;
63359243Sobrien	    /*
63459243Sobrien	     * Go handle !foo:*
63559243Sobrien	     */
63659243Sobrien	    if ((q[1] < '0' || q[1] > '9') &&
63759243Sobrien		q[1] != '-' && q[1] != '$' && q[1] != '^')
63859243Sobrien		goto excl_sw;
63959243Sobrien	    /*
64059243Sobrien	     * Go handle !foo:$
64159243Sobrien	     */
64259243Sobrien	    if (q[1] == '$' && (q[2] != '-' || q[3] < '0' || q[3] > '9'))
64359243Sobrien		goto excl_sw;
64459243Sobrien	    /*
64559243Sobrien	     * Count up the number of words in this event.  Store it in dval.
64659243Sobrien	     * Dval will be fed to number.
64759243Sobrien	     */
64859243Sobrien	    dval = 0;
64959243Sobrien	    if ((l = h->Hlex.prev) != 0) {
65059243Sobrien		for (l = l->prev; l != h->Hlex.next; l = l->prev, dval++)
65159243Sobrien		    continue;
65259243Sobrien	    }
65359243Sobrien	    if (!dval)
65459243Sobrien		goto excl_err;
65559243Sobrien	    if (q[1] == '-')
65659243Sobrien		from = 0;
65759243Sobrien	    else
65859243Sobrien		q = c_number(q, &from, dval);
65959243Sobrien	    if (q[1] == '-') {
66059243Sobrien		++q;
66159243Sobrien		if ((q[1] < '0' || q[1] > '9') && q[1] != '$')
66259243Sobrien		    to = dval - 1;
66359243Sobrien		else
66459243Sobrien		    q = c_number(q, &to, dval);
66559243Sobrien	    }
66659243Sobrien	    else if (q[1] == '*') {
66759243Sobrien		++q;
66859243Sobrien		to = NCARGS;
66959243Sobrien	    }
67059243Sobrien	    else {
67159243Sobrien		to = from;
67259243Sobrien	    }
67359243Sobrien	    if (from < 0 || to < from)
67459243Sobrien		goto excl_err;
67559243Sobrien	    bend = expand_lex(buf, INBUFSIZE, &h->Hlex, from, to);
67659243Sobrien	}
67759243Sobrien	else {			/* get whole cmd */
67859243Sobrien	    bend = expand_lex(buf, INBUFSIZE, &h->Hlex, 0, NCARGS);
67959243Sobrien	}
68059243Sobrien	break;
68159243Sobrien    }
68259243Sobrien
68359243Sobrien    /*
68459243Sobrien     * Apply modifiers, if any.
68559243Sobrien     */
68659243Sobrien    if (q[1] == ':') {
68759243Sobrien	*bend = '\0';
68859243Sobrien	modbuf = omodbuf = buf;
68959243Sobrien	while (q[1] == ':' && modbuf != NULL) {
69059243Sobrien	    switch (q[2]) {
69159243Sobrien	    case 'r':
69259243Sobrien	    case 'e':
69359243Sobrien	    case 'h':
69459243Sobrien	    case 't':
69559243Sobrien	    case 'q':
69659243Sobrien	    case 'x':
69759243Sobrien	    case 'u':
69859243Sobrien	    case 'l':
69959243Sobrien		if ((modbuf = domod(omodbuf, (int) q[2])) != NULL) {
70059243Sobrien		    if (omodbuf != buf)
70159243Sobrien			xfree((ptr_t) omodbuf);
70259243Sobrien		    omodbuf = modbuf;
70359243Sobrien		}
70459243Sobrien		++q;
70559243Sobrien		break;
70659243Sobrien
70759243Sobrien	    case 'a':
70859243Sobrien	    case 'g':
70959243Sobrien		/* Not implemented; this needs to be done before expanding
71059243Sobrien		 * lex. We don't have the words available to us anymore.
71159243Sobrien		 */
71259243Sobrien		++q;
71359243Sobrien		break;
71459243Sobrien
71559243Sobrien	    case 'p':
71659243Sobrien		/* Ok */
71759243Sobrien		++q;
71859243Sobrien		break;
71959243Sobrien
72059243Sobrien	    case '\0':
72159243Sobrien		break;
72259243Sobrien
72359243Sobrien	    default:
72459243Sobrien		++q;
72559243Sobrien		break;
72659243Sobrien	    }
72759243Sobrien	    if (q[1])
72859243Sobrien		++q;
72959243Sobrien	}
73059243Sobrien	if (omodbuf != buf) {
73159243Sobrien	    (void) Strcpy(buf, omodbuf);
73259243Sobrien	    xfree((ptr_t) omodbuf);
73359243Sobrien	    bend = Strend(buf);
73459243Sobrien	}
73559243Sobrien    }
73659243Sobrien
73759243Sobrien    /*
73859243Sobrien     * Now replace the text from op to q inclusive with the text from buf to
73959243Sobrien     * bend.
74059243Sobrien     */
74159243Sobrien    q++;
74259243Sobrien
74359243Sobrien    /*
74459243Sobrien     * Now replace text non-inclusively like a real CS major!
74559243Sobrien     */
74659243Sobrien    if (LastChar + (bend - buf) - (q - op) >= InputLim)
74759243Sobrien	goto excl_err;
74859243Sobrien    (void) memmove((ptr_t) (q + (bend - buf) - (q - op)), (ptr_t) q,
74959243Sobrien		   (size_t) ((LastChar - q) * sizeof(Char)));
75059243Sobrien    LastChar += (bend - buf) - (q - op);
75159243Sobrien    Cursor += (bend - buf) - (q - op);
75259243Sobrien    (void) memmove((ptr_t) op, (ptr_t) buf,
75359243Sobrien		   (size_t) ((bend - buf) * sizeof(Char)));
75459243Sobrien    *LastChar = '\0';
75559243Sobrien    return(op + (bend - buf));
75659243Sobrienexcl_err:
75759243Sobrien    SoundBeep();
75859243Sobrien    return(op + 1);
75959243Sobrien}
76059243Sobrien
76159243Sobrien/*
76259243Sobrien * c_excl: An excl has been found at point p -- back up and find some white
76359243Sobrien * space (or the beginning of the buffer) and properly expand all the excl's
76459243Sobrien * from there up to the current cursor position. We also avoid (trying to)
76559243Sobrien * expanding '>!'
76659243Sobrien */
76759243Sobrien
76859243Sobrienstatic void
76959243Sobrienc_excl(p)
77083098Smp    Char *p;
77159243Sobrien{
77283098Smp    int i;
77383098Smp    Char *q;
77459243Sobrien
77559243Sobrien    /*
77659243Sobrien     * if />[SPC TAB]*![SPC TAB]/, back up p to just after the >. otherwise,
77759243Sobrien     * back p up to just before the current word.
77859243Sobrien     */
77959243Sobrien    if ((p[1] == ' ' || p[1] == '\t') &&
78059243Sobrien	(p[-1] == ' ' || p[-1] == '\t' || p[-1] == '>')) {
78159243Sobrien	for (q = p - 1; q > InputBuf && (*q == ' ' || *q == '\t'); --q)
78259243Sobrien	    continue;
78359243Sobrien	if (*q == '>')
78459243Sobrien	    ++p;
78559243Sobrien    }
78659243Sobrien    else {
78759243Sobrien	while (*p != ' ' && *p != '\t' && p > InputBuf)
78859243Sobrien	    --p;
78959243Sobrien    }
79059243Sobrien
79159243Sobrien    /*
79259243Sobrien     * Forever: Look for history char.  (Stop looking when we find the cursor.)
79359243Sobrien     * Count backslashes.  Of odd, skip history char. Return if all done.
79459243Sobrien     * Expand if even number of backslashes.
79559243Sobrien     */
79659243Sobrien    for (;;) {
79759243Sobrien	while (*p != HIST && p < Cursor)
79859243Sobrien	    ++p;
79959243Sobrien	for (i = 1; (p - i) >= InputBuf && p[-i] == '\\'; i++)
80059243Sobrien	    continue;
80159243Sobrien	if (i % 2 == 0)
80259243Sobrien	    ++p;
80359243Sobrien	if (p >= Cursor)
80459243Sobrien	    return;
80559243Sobrien	if (i % 2 == 1)
80659243Sobrien	    p = c_expand(p);
80759243Sobrien    }
80859243Sobrien}
80959243Sobrien
81059243Sobrien
81159243Sobrienstatic void
81259243Sobrienc_substitute()
81359243Sobrien{
81483098Smp    Char *p;
81559243Sobrien
81659243Sobrien    /*
81759243Sobrien     * Start p out one character before the cursor.  Move it backwards looking
81859243Sobrien     * for white space, the beginning of the line, or a history character.
81959243Sobrien     */
82059243Sobrien    for (p = Cursor - 1;
82159243Sobrien	 p > InputBuf && *p != ' ' && *p != '\t' && *p != HIST; --p)
82259243Sobrien	continue;
82359243Sobrien
82459243Sobrien    /*
82559243Sobrien     * If we found a history character, go expand it.
82659243Sobrien     */
82759243Sobrien    if (*p == HIST)
82859243Sobrien	c_excl(p);
82959243Sobrien    Refresh();
83059243Sobrien}
83159243Sobrien
83259243Sobrienstatic void
83359243Sobrienc_delfini()		/* Finish up delete action */
83459243Sobrien{
83583098Smp    int Size;
83659243Sobrien
83759243Sobrien    if (ActionFlag & TCSHOP_INSERT)
83859243Sobrien	c_alternativ_key_map(0);
83959243Sobrien
84059243Sobrien    ActionFlag = TCSHOP_NOP;
84159243Sobrien
84259243Sobrien    if (ActionPos == 0)
84359243Sobrien	return;
84459243Sobrien
84559243Sobrien    UndoAction = TCSHOP_INSERT;
84659243Sobrien
84759243Sobrien    if (Cursor > ActionPos) {
84859243Sobrien	Size = (int) (Cursor-ActionPos);
84959243Sobrien	c_delbefore(Size);
85059243Sobrien	Cursor = ActionPos;
85159243Sobrien#if defined(DSPMBYTE)
85259243Sobrien	if (_enable_mbdisp && extdel) {
85359243Sobrien	    Cursor--;
85459243Sobrien	    e_redisp(1);
85559243Sobrien	}
85659243Sobrien#endif
85759243Sobrien	RefCursor();
85859243Sobrien    }
85959243Sobrien    else if (Cursor < ActionPos) {
86059243Sobrien	Size = (int)(ActionPos-Cursor);
86159243Sobrien	c_delafter(Size);
86259243Sobrien    }
86359243Sobrien    else  {
86459243Sobrien	Size = 1;
86559243Sobrien	c_delafter(Size);
86659243Sobrien    }
86759243Sobrien    UndoPtr = Cursor;
86859243Sobrien    UndoSize = Size;
86959243Sobrien}
87059243Sobrien
87159243Sobrienstatic Char *
87283098Smpc_endword(p, high, n, delim)
87383098Smp    Char *p, *high, *delim;
87483098Smp    int n;
87559243Sobrien{
87683098Smp    int inquote = 0;
87759243Sobrien    p++;
87859243Sobrien
87959243Sobrien    while (n--) {
88083098Smp        while (p < high) {	/* Skip non-word chars */
88183098Smp	  if (!Strchr(delim, *p) || *(p-1) == (Char)'\\')
88259243Sobrien	    break;
88359243Sobrien	  p++;
88459243Sobrien        }
88559243Sobrien	while (p < high) {	/* Skip string */
88659243Sobrien	  if ((*p == (Char)'\'' || *p == (Char)'"')) { /* Quotation marks? */
88783098Smp	    if (inquote || *(p-1) != (Char)'\\') { /* Should it be honored? */
88859243Sobrien	      if (inquote == 0) inquote = *p;
88959243Sobrien	      else if (inquote == *p) inquote = 0;
89059243Sobrien	    }
89159243Sobrien	  }
89283098Smp	  /* Break if unquoted non-word char */
89383098Smp	  if (!inquote && Strchr(delim, *p) && *(p-1) != (Char)'\\')
89459243Sobrien	    break;
89559243Sobrien	  p++;
89659243Sobrien	}
89759243Sobrien    }
89859243Sobrien
89959243Sobrien    p--;
90059243Sobrien    return(p);
90159243Sobrien}
90259243Sobrien
90359243Sobrien
90459243Sobrienstatic Char *
90559243Sobrienc_eword(p, high, n)
90683098Smp    Char *p, *high;
90783098Smp    int n;
90859243Sobrien{
90959243Sobrien    p++;
91059243Sobrien
91159243Sobrien    while (n--) {
91259243Sobrien	while ((p < high) && Isspace(*p))
91359243Sobrien	    p++;
91459243Sobrien
91559243Sobrien	if (Isalnum(*p))
91659243Sobrien	    while ((p < high) && Isalnum(*p))
91759243Sobrien		p++;
91859243Sobrien	else
91959243Sobrien	    while ((p < high) && !(Isspace(*p) || Isalnum(*p)))
92059243Sobrien		p++;
92159243Sobrien    }
92259243Sobrien
92359243Sobrien    p--;
92459243Sobrien    return(p);
92559243Sobrien}
92659243Sobrien
92783098Smp/* Set the max length of the kill ring */
92883098Smpvoid
92983098SmpSetKillRing(max)
93083098Smp    int max;
93183098Smp{
93283098Smp    CStr *new;
93383098Smp    int count, i, j;
93483098Smp
93583098Smp    if (max < 1)
93683098Smp	max = 1;		/* no ring, but always one buffer */
93783098Smp    if (max == KillRingMax)
93883098Smp	return;
93983098Smp    new = (CStr *)xcalloc((size_t) max, sizeof(CStr));
94083098Smp    if (KillRing != NULL) {
94183098Smp	if (KillRingLen != 0) {
94283098Smp	    if (max >= KillRingLen) {
94383098Smp		count = KillRingLen;
94483098Smp		j = KillPos;
94583098Smp	    } else {
94683098Smp		count = max;
94783098Smp		j = (KillPos - count + KillRingLen) % KillRingLen;
94883098Smp	    }
94983098Smp	    for (i = 0; i < KillRingLen; i++) {
95083098Smp		if (i < count)	/* copy latest */
95183098Smp		    new[i] = KillRing[j];
95283098Smp		else		/* free the others */
95383098Smp		    xfree(KillRing[j].buf);
95483098Smp		j = (j + 1) % KillRingLen;
95583098Smp	    }
95683098Smp	    KillRingLen = count;
95783098Smp	    KillPos = count % max;
95883098Smp	    YankPos = count - 1;
95983098Smp	}
96083098Smp	xfree(KillRing);
96183098Smp    }
96283098Smp    KillRing = new;
96383098Smp    KillRingMax = max;
96483098Smp}
96583098Smp
96683098Smp/* Push string from start upto (but not including) end onto kill ring */
96783098Smpstatic void
96883098Smpc_push_kill(start, end)
96983098Smp    Char *start, *end;
97083098Smp{
97183098Smp    CStr save, *pos;
97283098Smp    Char *dp, *cp, *kp;
97383098Smp    int len = end - start, i, j, k;
97483098Smp
97583098Smp    /* Check for duplicates? */
97683098Smp    if (KillRingLen > 0 && (dp = varval(STRkilldup)) != STRNULL) {
97783098Smp	YankPos = (KillPos - 1 + KillRingLen) % KillRingLen;
97883098Smp	if (eq(dp, STRerase)) {	/* erase earlier one (actually move up) */
97983098Smp	    j = YankPos;
98083098Smp	    for (i = 0; i < KillRingLen; i++) {
98183098Smp		if (Strncmp(KillRing[j].buf, start, (size_t) len) == 0 &&
98283098Smp		    KillRing[j].buf[len] == '\0') {
98383098Smp		    save = KillRing[j];
98483098Smp		    for ( ; i > 0; i--) {
98583098Smp			k = j;
98683098Smp			j = (j + 1) % KillRingLen;
98783098Smp			KillRing[k] = KillRing[j];
98883098Smp		    }
98983098Smp		    KillRing[j] = save;
99083098Smp		    return;
99183098Smp		}
99283098Smp		j = (j - 1 + KillRingLen) % KillRingLen;
99383098Smp	    }
99483098Smp	} else if (eq(dp, STRall)) { /* skip if any earlier */
99583098Smp	    for (i = 0; i < KillRingLen; i++)
99683098Smp		if (Strncmp(KillRing[i].buf, start, (size_t) len) == 0 &&
99783098Smp		    KillRing[i].buf[len] == '\0')
99883098Smp		    return;
99983098Smp	} else if (eq(dp, STRprev)) { /* skip if immediately previous */
100083098Smp	    j = YankPos;
100183098Smp	    if (Strncmp(KillRing[j].buf, start, (size_t) len) == 0 &&
100283098Smp		KillRing[j].buf[len] == '\0')
100383098Smp		return;
100483098Smp	}
100583098Smp    }
100683098Smp
100783098Smp    /* No duplicate, go ahead and push */
100883098Smp    len++;			/* need space for '\0' */
100983098Smp    YankPos = KillPos;
101083098Smp    if (KillRingLen < KillRingMax)
101183098Smp	KillRingLen++;
101283098Smp    pos = &KillRing[KillPos];
101383098Smp    KillPos = (KillPos + 1) % KillRingMax;
101483098Smp    if (pos->len < len) {
101583098Smp	if (pos->buf == NULL)
101683098Smp	    pos->buf = (Char *) xmalloc(len * sizeof(Char));
101783098Smp	else
101883098Smp	    pos->buf = (Char *) xrealloc((ptr_t) pos->buf, len * sizeof(Char));
101983098Smp	pos->len = len;
102083098Smp    }
102183098Smp    cp = start;
102283098Smp    kp = pos->buf;
102383098Smp    while (cp < end)
102483098Smp	*kp++ = *cp++;
102583098Smp    *kp = '\0';
102683098Smp}
102783098Smp
102859243Sobrienstatic CCRETVAL
102959243Sobrienc_get_histline()
103059243Sobrien{
103159243Sobrien    struct Hist *hp;
103259243Sobrien    int     h;
103359243Sobrien
103459243Sobrien    if (Hist_num == 0) {	/* if really the current line */
103559243Sobrien	copyn(InputBuf, HistBuf, INBUFSIZE);
103659243Sobrien	LastChar = InputBuf + (LastHist - HistBuf);
103759243Sobrien
103859243Sobrien#ifdef KSHVI
103959243Sobrien    if (VImode)
104059243Sobrien	Cursor = InputBuf;
104159243Sobrien    else
104259243Sobrien#endif /* KSHVI */
104359243Sobrien	Cursor = LastChar;
104459243Sobrien
104559243Sobrien	return(CC_REFRESH);
104659243Sobrien    }
104759243Sobrien
104859243Sobrien    hp = Histlist.Hnext;
104959243Sobrien    if (hp == NULL)
105059243Sobrien	return(CC_ERROR);
105159243Sobrien
105259243Sobrien    for (h = 1; h < Hist_num; h++) {
105359243Sobrien	if ((hp->Hnext) == NULL) {
105459243Sobrien	    Hist_num = h;
105559243Sobrien	    return(CC_ERROR);
105659243Sobrien	}
105759243Sobrien	hp = hp->Hnext;
105859243Sobrien    }
105959243Sobrien
106059243Sobrien    if (HistLit && hp->histline) {
106159243Sobrien	copyn(InputBuf, hp->histline, INBUFSIZE);
106259243Sobrien	CurrentHistLit = 1;
106359243Sobrien    }
106459243Sobrien    else {
106561524Sobrien	(void) sprlex(InputBuf, sizeof(InputBuf) / sizeof(Char), &hp->Hlex);
106659243Sobrien	CurrentHistLit = 0;
106759243Sobrien    }
106859243Sobrien    LastChar = InputBuf + Strlen(InputBuf);
106959243Sobrien
107059243Sobrien    if (LastChar > InputBuf) {
107159243Sobrien	if (LastChar[-1] == '\n')
107259243Sobrien	    LastChar--;
107359243Sobrien#if 0
107459243Sobrien	if (LastChar[-1] == ' ')
107559243Sobrien	    LastChar--;
107659243Sobrien#endif
107759243Sobrien	if (LastChar < InputBuf)
107859243Sobrien	    LastChar = InputBuf;
107959243Sobrien    }
108059243Sobrien
108159243Sobrien#ifdef KSHVI
108259243Sobrien    if (VImode)
108359243Sobrien	Cursor = InputBuf;
108459243Sobrien    else
108559243Sobrien#endif /* KSHVI */
108659243Sobrien	Cursor = LastChar;
108759243Sobrien
108859243Sobrien    return(CC_REFRESH);
108959243Sobrien}
109059243Sobrien
109159243Sobrienstatic CCRETVAL
109259243Sobrienc_search_line(pattern, dir)
109359243SobrienChar *pattern;
109459243Sobrienint dir;
109559243Sobrien{
109659243Sobrien    Char *cp;
109759243Sobrien    int len;
109859243Sobrien
109959243Sobrien    len = (int) Strlen(pattern);
110059243Sobrien
110159243Sobrien    if (dir == F_UP_SEARCH_HIST) {
110259243Sobrien	for (cp = Cursor; cp >= InputBuf; cp--)
110359243Sobrien	    if (Strncmp(cp, pattern, (size_t) len) == 0 ||
110459243Sobrien		Gmatch(cp, pattern)) {
110559243Sobrien		Cursor = cp;
110659243Sobrien		return(CC_NORM);
110759243Sobrien	    }
110859243Sobrien	return(CC_ERROR);
110959243Sobrien    } else {
111059243Sobrien	for (cp = Cursor; *cp != '\0' && cp < InputLim; cp++)
111159243Sobrien	    if (Strncmp(cp, pattern, (size_t) len) == 0 ||
111259243Sobrien		Gmatch(cp, pattern)) {
111359243Sobrien		Cursor = cp;
111459243Sobrien		return(CC_NORM);
111559243Sobrien	    }
111659243Sobrien	return(CC_ERROR);
111759243Sobrien    }
111859243Sobrien}
111959243Sobrien
112059243Sobrienstatic CCRETVAL
112159243Sobriene_inc_search(dir)
112259243Sobrien    int dir;
112359243Sobrien{
112459243Sobrien    static Char STRfwd[] = { 'f', 'w', 'd', '\0' },
112559243Sobrien		STRbck[] = { 'b', 'c', 'k', '\0' };
112659243Sobrien    static Char pchar = ':';	/* ':' = normal, '?' = failed */
112759243Sobrien    static Char endcmd[2];
112859243Sobrien    Char ch, *cp,
112959243Sobrien	*oldCursor = Cursor,
113059243Sobrien	oldpchar = pchar;
113159243Sobrien    CCRETVAL ret = CC_NORM;
113259243Sobrien    int oldHist_num = Hist_num,
113359243Sobrien	oldpatlen = patlen,
113459243Sobrien	newdir = dir,
113559243Sobrien        done, redo;
113659243Sobrien
113759243Sobrien    if (LastChar + sizeof(STRfwd)/sizeof(Char) + 2 + patlen >= InputLim)
113859243Sobrien	return(CC_ERROR);
113959243Sobrien
114059243Sobrien    for (;;) {
114159243Sobrien
114259243Sobrien	if (patlen == 0) {	/* first round */
114359243Sobrien	    pchar = ':';
114459243Sobrien	    patbuf[patlen++] = '*';
114559243Sobrien	}
114659243Sobrien	done = redo = 0;
114759243Sobrien	*LastChar++ = '\n';
114859243Sobrien	for (cp = newdir == F_UP_SEARCH_HIST ? STRbck : STRfwd;
114959243Sobrien	     *cp; *LastChar++ = *cp++)
115059243Sobrien	    continue;
115159243Sobrien	*LastChar++ = pchar;
115259243Sobrien	for (cp = &patbuf[1]; cp < &patbuf[patlen]; *LastChar++ = *cp++)
115359243Sobrien	    continue;
115459243Sobrien	*LastChar = '\0';
115559243Sobrien	Refresh();
115659243Sobrien
115759243Sobrien	if (GetNextChar(&ch) != 1)
115859243Sobrien	    return(e_send_eof(0));
115959243Sobrien
116059243Sobrien	switch (CurrentKeyMap[(unsigned char) ch]) {
116159243Sobrien	case F_INSERT:
116259243Sobrien	case F_DIGIT:
116359243Sobrien	case F_MAGIC_SPACE:
116459243Sobrien	    if (patlen > INBUFSIZE - 3)
116559243Sobrien		SoundBeep();
116659243Sobrien	    else {
116759243Sobrien		patbuf[patlen++] = ch;
116859243Sobrien		*LastChar++ = ch;
116959243Sobrien		*LastChar = '\0';
117059243Sobrien		Refresh();
117159243Sobrien	    }
117259243Sobrien	    break;
117359243Sobrien
117459243Sobrien	case F_INC_FWD:
117559243Sobrien	    newdir = F_DOWN_SEARCH_HIST;
117659243Sobrien	    redo++;
117759243Sobrien	    break;
117859243Sobrien
117959243Sobrien	case F_INC_BACK:
118059243Sobrien	    newdir = F_UP_SEARCH_HIST;
118159243Sobrien	    redo++;
118259243Sobrien	    break;
118359243Sobrien
118459243Sobrien	case F_DELPREV:
118559243Sobrien	    if (patlen > 1)
118659243Sobrien		done++;
118759243Sobrien	    else
118859243Sobrien		SoundBeep();
118959243Sobrien	    break;
119059243Sobrien
119159243Sobrien	default:
119259243Sobrien	    switch (ch) {
119359243Sobrien	    case 0007:		/* ^G: Abort */
119459243Sobrien		ret = CC_ERROR;
119559243Sobrien		done++;
119659243Sobrien		break;
119759243Sobrien
119859243Sobrien	    case 0027:		/* ^W: Append word */
119959243Sobrien		/* No can do if globbing characters in pattern */
120059243Sobrien		for (cp = &patbuf[1]; ; cp++)
120159243Sobrien		    if (cp >= &patbuf[patlen]) {
120259243Sobrien			Cursor += patlen - 1;
120359243Sobrien			cp = c_next_word(Cursor, LastChar, 1);
120459243Sobrien			while (Cursor < cp && *Cursor != '\n') {
120559243Sobrien			    if (patlen > INBUFSIZE - 3) {
120659243Sobrien				SoundBeep();
120759243Sobrien				break;
120859243Sobrien			    }
120959243Sobrien			    patbuf[patlen++] = *Cursor;
121059243Sobrien			    *LastChar++ = *Cursor++;
121159243Sobrien			}
121259243Sobrien			Cursor = oldCursor;
121359243Sobrien			*LastChar = '\0';
121459243Sobrien			Refresh();
121559243Sobrien			break;
121659243Sobrien		    } else if (isglob(*cp)) {
121759243Sobrien			SoundBeep();
121859243Sobrien			break;
121959243Sobrien		    }
122059243Sobrien		break;
122159243Sobrien
122259243Sobrien	    default:		/* Terminate and execute cmd */
122359243Sobrien		endcmd[0] = ch;
122459243Sobrien		PushMacro(endcmd);
122559243Sobrien		/*FALLTHROUGH*/
122659243Sobrien
122759243Sobrien	    case 0033:		/* ESC: Terminate */
122859243Sobrien		ret = CC_REFRESH;
122959243Sobrien		done++;
123059243Sobrien		break;
123159243Sobrien	    }
123259243Sobrien	    break;
123359243Sobrien	}
123459243Sobrien
123559243Sobrien	while (LastChar > InputBuf && *LastChar != '\n')
123659243Sobrien	    *LastChar-- = '\0';
123759243Sobrien	*LastChar = '\0';
123859243Sobrien
123959243Sobrien	if (!done) {
124059243Sobrien
124159243Sobrien	    /* Can't search if unmatched '[' */
124259243Sobrien	    for (cp = &patbuf[patlen - 1], ch = ']'; cp > patbuf; cp--)
124359243Sobrien		if (*cp == '[' || *cp == ']') {
124459243Sobrien		    ch = *cp;
124559243Sobrien		    break;
124659243Sobrien		}
124759243Sobrien
124859243Sobrien	    if (patlen > 1 && ch != '[') {
124959243Sobrien		if (redo && newdir == dir) {
125059243Sobrien		    if (pchar == '?') {	/* wrap around */
125159243Sobrien			Hist_num = newdir == F_UP_SEARCH_HIST ? 0 : 0x7fffffff;
125259243Sobrien			if (c_get_histline() == CC_ERROR)
125359243Sobrien			    /* Hist_num was fixed by first call */
125459243Sobrien			    (void) c_get_histline();
125559243Sobrien			Cursor = newdir == F_UP_SEARCH_HIST ?
125659243Sobrien			    LastChar : InputBuf;
125759243Sobrien		    } else
125859243Sobrien			Cursor += newdir == F_UP_SEARCH_HIST ? -1 : 1;
125959243Sobrien		}
126059243Sobrien		patbuf[patlen++] = '*';
126159243Sobrien		patbuf[patlen] = '\0';
126259243Sobrien		if (Cursor < InputBuf || Cursor > LastChar ||
126359243Sobrien		    (ret = c_search_line(&patbuf[1], newdir)) == CC_ERROR) {
126459243Sobrien		    LastCmd = (KEYCMD) newdir; /* avoid c_hsetpat */
126559243Sobrien		    ret = newdir == F_UP_SEARCH_HIST ?
126659243Sobrien			e_up_search_hist(0) : e_down_search_hist(0);
126759243Sobrien		    if (ret != CC_ERROR) {
126859243Sobrien			Cursor = newdir == F_UP_SEARCH_HIST ?
126959243Sobrien			    LastChar : InputBuf;
127059243Sobrien			(void) c_search_line(&patbuf[1], newdir);
127159243Sobrien		    }
127259243Sobrien		}
127359243Sobrien		patbuf[--patlen] = '\0';
127459243Sobrien		if (ret == CC_ERROR) {
127559243Sobrien		    SoundBeep();
127659243Sobrien		    if (Hist_num != oldHist_num) {
127759243Sobrien			Hist_num = oldHist_num;
127859243Sobrien			if (c_get_histline() == CC_ERROR)
127959243Sobrien			    return(CC_ERROR);
128059243Sobrien		    }
128159243Sobrien		    Cursor = oldCursor;
128259243Sobrien		    pchar = '?';
128359243Sobrien		} else {
128459243Sobrien		    pchar = ':';
128559243Sobrien		}
128659243Sobrien	    }
128759243Sobrien
128859243Sobrien	    ret = e_inc_search(newdir);
128959243Sobrien
129059243Sobrien	    if (ret == CC_ERROR && pchar == '?' && oldpchar == ':') {
129159243Sobrien		/* break abort of failed search at last non-failed */
129259243Sobrien		ret = CC_NORM;
129359243Sobrien	    }
129459243Sobrien
129559243Sobrien	}
129659243Sobrien
129759243Sobrien	if (ret == CC_NORM || (ret == CC_ERROR && oldpatlen == 0)) {
129859243Sobrien	    /* restore on normal return or error exit */
129959243Sobrien	    pchar = oldpchar;
130059243Sobrien	    patlen = oldpatlen;
130159243Sobrien	    if (Hist_num != oldHist_num) {
130259243Sobrien		Hist_num = oldHist_num;
130359243Sobrien		if (c_get_histline() == CC_ERROR)
130459243Sobrien		    return(CC_ERROR);
130559243Sobrien	    }
130659243Sobrien	    Cursor = oldCursor;
130759243Sobrien	    if (ret == CC_ERROR)
130859243Sobrien		Refresh();
130959243Sobrien	}
131059243Sobrien	if (done || ret != CC_NORM)
131159243Sobrien	    return(ret);
131259243Sobrien
131359243Sobrien    }
131459243Sobrien
131559243Sobrien}
131659243Sobrien
131759243Sobrienstatic CCRETVAL
131859243Sobrienv_search(dir)
131959243Sobrien    int dir;
132059243Sobrien{
132159243Sobrien    Char ch;
132259243Sobrien    Char tmpbuf[INBUFSIZE];
132359243Sobrien    Char oldbuf[INBUFSIZE];
132459243Sobrien    Char *oldlc, *oldc;
132559243Sobrien    int tmplen;
132659243Sobrien
132759243Sobrien    copyn(oldbuf, InputBuf, INBUFSIZE);
132859243Sobrien    oldlc = LastChar;
132959243Sobrien    oldc = Cursor;
133059243Sobrien    tmplen = 0;
133159243Sobrien    tmpbuf[tmplen++] = '*';
133259243Sobrien
133359243Sobrien    InputBuf[0] = '\0';
133459243Sobrien    LastChar = InputBuf;
133559243Sobrien    Cursor = InputBuf;
133659243Sobrien    searchdir = dir;
133759243Sobrien
133859243Sobrien    c_insert(2);	/* prompt + '\n' */
133959243Sobrien    *Cursor++ = '\n';
134059243Sobrien    *Cursor++ = dir == F_UP_SEARCH_HIST ? '?' : '/';
134159243Sobrien    Refresh();
134259243Sobrien    for (ch = 0;ch == 0;) {
134359243Sobrien	if (GetNextChar(&ch) != 1)
134459243Sobrien	    return(e_send_eof(0));
134559243Sobrien	switch (ASC(ch)) {
134659243Sobrien	case 0010:	/* Delete and backspace */
134759243Sobrien	case 0177:
134859243Sobrien	    if (tmplen > 1) {
134959243Sobrien		*Cursor-- = '\0';
135059243Sobrien		LastChar = Cursor;
135159243Sobrien		tmpbuf[tmplen--] = '\0';
135259243Sobrien	    }
135359243Sobrien	    else {
135459243Sobrien		copyn(InputBuf, oldbuf, INBUFSIZE);
135559243Sobrien		LastChar = oldlc;
135659243Sobrien		Cursor = oldc;
135759243Sobrien		return(CC_REFRESH);
135859243Sobrien	    }
135959243Sobrien	    Refresh();
136059243Sobrien	    ch = 0;
136159243Sobrien	    break;
136259243Sobrien
136359243Sobrien	case 0033:	/* ESC */
136469408Sache#ifdef IS_ASCII
136559243Sobrien	case '\r':	/* Newline */
136659243Sobrien	case '\n':
136759243Sobrien#else
136869408Sache	case '\012':    /* ASCII Line feed */
136969408Sache	case '\015':    /* ASCII (or EBCDIC) Return */
137059243Sobrien#endif
137159243Sobrien	    break;
137259243Sobrien
137359243Sobrien	default:
137459243Sobrien	    if (tmplen >= INBUFSIZE)
137559243Sobrien		SoundBeep();
137659243Sobrien	    else {
137759243Sobrien		tmpbuf[tmplen++] = ch;
137859243Sobrien		*Cursor++ = ch;
137959243Sobrien		LastChar = Cursor;
138059243Sobrien	    }
138159243Sobrien	    Refresh();
138259243Sobrien	    ch = 0;
138359243Sobrien	    break;
138459243Sobrien	}
138559243Sobrien    }
138659243Sobrien
138759243Sobrien    if (tmplen == 1) {
138859243Sobrien	/*
138959243Sobrien	 * Use the old pattern, but wild-card it.
139059243Sobrien	 */
139159243Sobrien	if (patlen == 0) {
139259243Sobrien	    InputBuf[0] = '\0';
139359243Sobrien	    LastChar = InputBuf;
139459243Sobrien	    Cursor = InputBuf;
139559243Sobrien	    Refresh();
139659243Sobrien	    return(CC_ERROR);
139759243Sobrien	}
139859243Sobrien	if (patbuf[0] != '*') {
139959243Sobrien	    (void) Strcpy(tmpbuf, patbuf);
140059243Sobrien	    patbuf[0] = '*';
140159243Sobrien	    (void) Strcpy(&patbuf[1], tmpbuf);
140259243Sobrien	    patlen++;
140359243Sobrien	    patbuf[patlen++] = '*';
140459243Sobrien	    patbuf[patlen] = '\0';
140559243Sobrien	}
140659243Sobrien    }
140759243Sobrien    else {
140859243Sobrien	tmpbuf[tmplen++] = '*';
140959243Sobrien	tmpbuf[tmplen] = '\0';
141059243Sobrien	(void) Strcpy(patbuf, tmpbuf);
141159243Sobrien	patlen = tmplen;
141259243Sobrien    }
141359243Sobrien    LastCmd = (KEYCMD) dir; /* avoid c_hsetpat */
141459243Sobrien    Cursor = LastChar = InputBuf;
141559243Sobrien    if ((dir == F_UP_SEARCH_HIST ? e_up_search_hist(0) :
141659243Sobrien				   e_down_search_hist(0)) == CC_ERROR) {
141759243Sobrien	Refresh();
141859243Sobrien	return(CC_ERROR);
141959243Sobrien    }
142059243Sobrien    else {
142159243Sobrien	if (ch == 0033) {
142259243Sobrien	    Refresh();
142359243Sobrien	    *LastChar++ = '\n';
142459243Sobrien	    *LastChar = '\0';
142559243Sobrien	    PastBottom();
142659243Sobrien	    return(CC_NEWLINE);
142759243Sobrien	}
142859243Sobrien	else
142959243Sobrien	    return(CC_REFRESH);
143059243Sobrien    }
143159243Sobrien}
143259243Sobrien
143359243Sobrien/*
143459243Sobrien * semi-PUBLIC routines.  Any routine that is of type CCRETVAL is an
143559243Sobrien * entry point, called from the CcKeyMap indirected into the
143659243Sobrien * CcFuncTbl array.
143759243Sobrien */
143859243Sobrien
143959243Sobrien/*ARGSUSED*/
144059243SobrienCCRETVAL
144159243Sobrienv_cmd_mode(c)
144259243Sobrien    int c;
144359243Sobrien{
144459243Sobrien    USE(c);
144559243Sobrien    InsertPos = 0;
144659243Sobrien    ActionFlag = TCSHOP_NOP;	/* [Esc] cancels pending action */
144759243Sobrien    ActionPos = 0;
144859243Sobrien    DoingArg = 0;
144959243Sobrien    if (UndoPtr > Cursor)
145059243Sobrien	UndoSize = (int)(UndoPtr - Cursor);
145159243Sobrien    else
145259243Sobrien	UndoSize = (int)(Cursor - UndoPtr);
145359243Sobrien
145459243Sobrien    inputmode = MODE_INSERT;
145559243Sobrien    c_alternativ_key_map(1);
145659243Sobrien#ifdef notdef
145759243Sobrien    /*
145859243Sobrien     * We don't want to move the cursor, because all the editing
145959243Sobrien     * commands don't include the character under the cursor.
146059243Sobrien     */
146159243Sobrien    if (Cursor > InputBuf)
146259243Sobrien	Cursor--;
146359243Sobrien#endif
146459243Sobrien    RefCursor();
146559243Sobrien    return(CC_NORM);
146659243Sobrien}
146759243Sobrien
146859243Sobrien/*ARGSUSED*/
146959243SobrienCCRETVAL
147059243Sobriene_unassigned(c)
147159243Sobrien    int c;
147259243Sobrien{				/* bound to keys that arn't really assigned */
147359243Sobrien    USE(c);
147459243Sobrien    SoundBeep();
147559243Sobrien    flush();
147659243Sobrien    return(CC_NORM);
147759243Sobrien}
147859243Sobrien
147959243SobrienCCRETVAL
148059243Sobriene_insert(c)
148183098Smp    int c;
148259243Sobrien{
148383098Smp    int i;
148459243Sobrien#if defined(DSPMBYTE)
148559243Sobrien    CCRETVAL ret;
148659243Sobrien    static Char savec;
148759243Sobrien    static int exterr = 0;
148859243Sobrien#endif
148959243Sobrien#ifndef SHORT_STRINGS
149059243Sobrien    c &= ASCII;			/* no meta chars ever */
149159243Sobrien#endif
149259243Sobrien#if defined(DSPMBYTE)
149359243Sobrien    ret = (CCRETVAL) CC_NORM;
149459243Sobrien#endif
149559243Sobrien
149659243Sobrien    if (!c)
149759243Sobrien	return(CC_ERROR);	/* no NULs in the input ever!! */
149859243Sobrien
149959243Sobrien    if (LastChar + Argument >= InputLim)
150059243Sobrien	return(CC_ERROR);	/* end of buffer space */
150159243Sobrien
150259243Sobrien    if (Argument == 1) {  	/* How was this optimized ???? */
150359243Sobrien
150459243Sobrien#if defined(DSPMBYTE)
150559243Sobrien	if(_enable_mbdisp && extins && exterr && Ismbyte2(c)) {
150659243Sobrien	    extins = 0;
150759243Sobrien	    exterr = 0;
150859243Sobrien	    return(CC_ERROR);
150959243Sobrien	}
151059243Sobrien#endif
151159243Sobrien	if (inputmode != MODE_INSERT) {
151259243Sobrien	    UndoBuf[UndoSize++] = *Cursor;
151359243Sobrien	    UndoBuf[UndoSize] = '\0';
151459243Sobrien	    c_delafter(1);   /* Do NOT use the saving ONE */
151559243Sobrien    	}
151659243Sobrien
151759243Sobrien        c_insert(1);
151859243Sobrien
151959243Sobrien#if defined(DSPMBYTE)
152059243Sobrien	/* 1st. byte is store to special buffer, and replace space */
152159243Sobrien	if(_enable_mbdisp && extins == 0 && Ismbyte1(c)) {
152259243Sobrien	    extins++;
152359243Sobrien	    savec = (Char) c;
152459243Sobrien	    *Cursor++ = (Char) ' ';
152559243Sobrien	}
152659243Sobrien	else if (_enable_mbdisp && extins && Ismbyte2(c)) {
152759243Sobrien	    *(Cursor-1) = savec;
152859243Sobrien	    *Cursor++ = (Char) c;
152959243Sobrien	    extins = 0;
153059243Sobrien	    e_redisp(1);
153159243Sobrien	    Refresh();
153259243Sobrien	    ret = CC_REFRESH;
153359243Sobrien	}
153459243Sobrien	else
153559243Sobrien	    *Cursor++ = (Char) c;
153659243Sobrien	DoingArg = 0;		/* just in case */
153759243Sobrien	if (ret != CC_REFRESH)
153859243Sobrien	    RefPlusOne();	/* fast refresh for one char. */
153959243Sobrien#else
154059243Sobrien	*Cursor++ = (Char) c;
154159243Sobrien	DoingArg = 0;		/* just in case */
154259243Sobrien	RefPlusOne();		/* fast refresh for one char. */
154359243Sobrien#endif
154459243Sobrien    }
154559243Sobrien    else {
154659243Sobrien#if defined(DSPMBYTE)
154759243Sobrien	/* Cannot use ESC-(number) for multi-byte */
154859243Sobrien	if (_enable_mbdisp && extins == 0 && Ismbyte1(c)) {
154959243Sobrien	    extins++;
155059243Sobrien	    exterr++;
155159243Sobrien	    return(CC_ERROR);
155259243Sobrien	}
155359243Sobrien	else if (_enable_mbdisp && extins && exterr && Ismbyte2(c))
155459243Sobrien	{
155559243Sobrien	    extins = 0;
155659243Sobrien	    exterr = 0;
155759243Sobrien	    return(CC_ERROR);
155859243Sobrien	}
155959243Sobrien#endif
156059243Sobrien	if (inputmode != MODE_INSERT) {
156159243Sobrien
156259243Sobrien	    for(i=0;i<Argument;i++)
156359243Sobrien		UndoBuf[UndoSize++] = *(Cursor+i);
156459243Sobrien
156559243Sobrien	    UndoBuf[UndoSize] = '\0';
156659243Sobrien	    c_delafter(Argument);   /* Do NOT use the saving ONE */
156759243Sobrien    	}
156859243Sobrien
156959243Sobrien        c_insert(Argument);
157059243Sobrien
157159243Sobrien	while (Argument--)
157259243Sobrien	    *Cursor++ = (Char) c;
157359243Sobrien	Refresh();
157459243Sobrien    }
157559243Sobrien
157659243Sobrien    if (inputmode == MODE_REPLACE_1)
157759243Sobrien	(void) v_cmd_mode(0);
157859243Sobrien
157959243Sobrien#if defined(DSPMBYTE)
158059243Sobrien    return(ret);
158159243Sobrien#else
158259243Sobrien    return(CC_NORM);
158359243Sobrien#endif
158459243Sobrien}
158559243Sobrien
158659243Sobrienint
158759243SobrienInsertStr(s)			/* insert ASCIZ s at cursor (for complete) */
158859243Sobrien    Char   *s;
158959243Sobrien{
159083098Smp    int len;
159159243Sobrien
159259243Sobrien    if ((len = (int) Strlen(s)) <= 0)
159359243Sobrien	return -1;
159459243Sobrien    if (LastChar + len >= InputLim)
159559243Sobrien	return -1;		/* end of buffer space */
159659243Sobrien
159759243Sobrien    c_insert(len);
159859243Sobrien    while (len--)
159959243Sobrien	*Cursor++ = *s++;
160059243Sobrien    return 0;
160159243Sobrien}
160259243Sobrien
160359243Sobrienvoid
160459243SobrienDeleteBack(n)			/* delete the n characters before . */
160559243Sobrien    int     n;
160659243Sobrien{
160759243Sobrien    if (n <= 0)
160859243Sobrien	return;
160959243Sobrien    if (Cursor >= &InputBuf[n]) {
161059243Sobrien	c_delbefore(n);		/* delete before dot */
161159243Sobrien	if (n > Cursor - InputBuf)
161259243Sobrien	    Cursor = InputBuf;	/* bounds check */
161359243Sobrien	else
161459243Sobrien	    Cursor -= n;
161559243Sobrien#if defined(DSPMBYTE)
161659243Sobrien	if(_enable_mbdisp && extdel && Cursor > InputBuf) {
161759243Sobrien	    Cursor--;
161859243Sobrien	    e_redisp(1);
161959243Sobrien	}
162059243Sobrien#endif
162159243Sobrien    }
162259243Sobrien}
162359243Sobrien
162459243SobrienCCRETVAL
162559243Sobriene_digit(c)			/* gray magic here */
162683098Smp    int c;
162759243Sobrien{
162859243Sobrien    if (!Isdigit(c))
162959243Sobrien	return(CC_ERROR);	/* no NULs in the input ever!! */
163059243Sobrien
163159243Sobrien    if (DoingArg) {		/* if doing an arg, add this in... */
163259243Sobrien	if (LastCmd == F_ARGFOUR)	/* if last command was ^U */
163359243Sobrien	    Argument = c - '0';
163459243Sobrien	else {
163559243Sobrien	    if (Argument > 1000000)
163659243Sobrien		return CC_ERROR;
163759243Sobrien	    Argument = (Argument * 10) + (c - '0');
163859243Sobrien	}
163959243Sobrien	return(CC_ARGHACK);
164059243Sobrien    }
164159243Sobrien    else {
164259243Sobrien	if (LastChar + 1 >= InputLim)
164359243Sobrien	    return CC_ERROR;	/* end of buffer space */
164459243Sobrien
164559243Sobrien	if (inputmode != MODE_INSERT) {
164659243Sobrien	    UndoBuf[UndoSize++] = *Cursor;
164759243Sobrien	    UndoBuf[UndoSize] = '\0';
164859243Sobrien	    c_delafter(1);   /* Do NOT use the saving ONE */
164959243Sobrien    	}
165059243Sobrien	c_insert(1);
165159243Sobrien	*Cursor++ = (Char) c;
165259243Sobrien	DoingArg = 0;		/* just in case */
165359243Sobrien	RefPlusOne();		/* fast refresh for one char. */
165459243Sobrien    }
165559243Sobrien    return(CC_NORM);
165659243Sobrien}
165759243Sobrien
165859243SobrienCCRETVAL
165959243Sobriene_argdigit(c)			/* for ESC-n */
166083098Smp    int c;
166159243Sobrien{
166259243Sobrien    c &= ASCII;
166359243Sobrien
166459243Sobrien    if (!Isdigit(c))
166559243Sobrien	return(CC_ERROR);	/* no NULs in the input ever!! */
166659243Sobrien
166759243Sobrien    if (DoingArg) {		/* if doing an arg, add this in... */
166859243Sobrien	if (Argument > 1000000)
166959243Sobrien	    return CC_ERROR;
167059243Sobrien	Argument = (Argument * 10) + (c - '0');
167159243Sobrien    }
167259243Sobrien    else {			/* else starting an argument */
167359243Sobrien	Argument = c - '0';
167459243Sobrien	DoingArg = 1;
167559243Sobrien    }
167659243Sobrien    return(CC_ARGHACK);
167759243Sobrien}
167859243Sobrien
167959243SobrienCCRETVAL
168059243Sobrienv_zero(c)			/* command mode 0 for vi */
168183098Smp    int c;
168259243Sobrien{
168359243Sobrien    if (DoingArg) {		/* if doing an arg, add this in... */
168459243Sobrien	if (Argument > 1000000)
168559243Sobrien	    return CC_ERROR;
168659243Sobrien	Argument = (Argument * 10) + (c - '0');
168759243Sobrien	return(CC_ARGHACK);
168859243Sobrien    }
168959243Sobrien    else {			/* else starting an argument */
169059243Sobrien	Cursor = InputBuf;
169159243Sobrien	if (ActionFlag & TCSHOP_DELETE) {
169259243Sobrien	   c_delfini();
169359243Sobrien	   return(CC_REFRESH);
169459243Sobrien        }
169559243Sobrien	RefCursor();		/* move the cursor */
169659243Sobrien	return(CC_NORM);
169759243Sobrien    }
169859243Sobrien}
169959243Sobrien
170059243Sobrien/*ARGSUSED*/
170159243SobrienCCRETVAL
170259243Sobriene_newline(c)
170359243Sobrien    int c;
170459243Sobrien{				/* always ignore argument */
170559243Sobrien    USE(c);
170659243Sobrien  /*  PastBottom();  NOW done in ed.inputl.c */
170759243Sobrien    *LastChar++ = '\n';		/* for the benefit of CSH */
170859243Sobrien    *LastChar = '\0';		/* just in case */
170959243Sobrien    if (VImode)
171059243Sobrien	InsertPos = InputBuf;	/* Reset editing position */
171159243Sobrien    return(CC_NEWLINE);
171259243Sobrien}
171359243Sobrien
171459243Sobrien/*ARGSUSED*/
171559243SobrienCCRETVAL
171659243Sobriene_send_eof(c)
171759243Sobrien    int c;
171859243Sobrien{				/* for when ^D is ONLY send-eof */
171959243Sobrien    USE(c);
172059243Sobrien    PastBottom();
172159243Sobrien    *LastChar = '\0';		/* just in case */
172259243Sobrien    return(CC_EOF);
172359243Sobrien}
172459243Sobrien
172559243Sobrien/*ARGSUSED*/
172659243SobrienCCRETVAL
172759243Sobriene_complete(c)
172859243Sobrien    int c;
172959243Sobrien{
173059243Sobrien    USE(c);
173159243Sobrien    *LastChar = '\0';		/* just in case */
173259243Sobrien    return(CC_COMPLETE);
173359243Sobrien}
173459243Sobrien
173559243Sobrien/*ARGSUSED*/
173659243SobrienCCRETVAL
173759243Sobriene_complete_back(c)
173859243Sobrien    int c;
173959243Sobrien{
174059243Sobrien    USE(c);
174159243Sobrien    *LastChar = '\0';		/* just in case */
174259243Sobrien    return(CC_COMPLETE_BACK);
174359243Sobrien}
174459243Sobrien
174559243Sobrien/*ARGSUSED*/
174659243SobrienCCRETVAL
174759243Sobriene_complete_fwd(c)
174859243Sobrien    int c;
174959243Sobrien{
175059243Sobrien    USE(c);
175159243Sobrien    *LastChar = '\0';		/* just in case */
175259243Sobrien    return(CC_COMPLETE_FWD);
175359243Sobrien}
175459243Sobrien
175559243Sobrien/*ARGSUSED*/
175659243SobrienCCRETVAL
175759243Sobriene_complete_all(c)
175859243Sobrien    int c;
175959243Sobrien{
176059243Sobrien    USE(c);
176159243Sobrien    *LastChar = '\0';		/* just in case */
176259243Sobrien    return(CC_COMPLETE_ALL);
176359243Sobrien}
176459243Sobrien
176559243Sobrien/*ARGSUSED*/
176659243SobrienCCRETVAL
176759243Sobrienv_cm_complete(c)
176859243Sobrien    int c;
176959243Sobrien{
177059243Sobrien    USE(c);
177159243Sobrien    if (Cursor < LastChar)
177259243Sobrien	Cursor++;
177359243Sobrien    *LastChar = '\0';		/* just in case */
177459243Sobrien    return(CC_COMPLETE);
177559243Sobrien}
177659243Sobrien
177759243Sobrien/*ARGSUSED*/
177859243SobrienCCRETVAL
177959243Sobriene_toggle_hist(c)
178059243Sobrien    int c;
178159243Sobrien{
178259243Sobrien    struct Hist *hp;
178359243Sobrien    int     h;
178459243Sobrien
178559243Sobrien    USE(c);
178659243Sobrien    *LastChar = '\0';		/* just in case */
178759243Sobrien
178859243Sobrien    if (Hist_num <= 0) {
178959243Sobrien	return CC_ERROR;
179059243Sobrien    }
179159243Sobrien
179259243Sobrien    hp = Histlist.Hnext;
179359243Sobrien    if (hp == NULL) {	/* this is only if no history */
179459243Sobrien	return(CC_ERROR);
179559243Sobrien    }
179659243Sobrien
179759243Sobrien    for (h = 1; h < Hist_num; h++)
179859243Sobrien	hp = hp->Hnext;
179959243Sobrien
180059243Sobrien    if (!CurrentHistLit) {
180159243Sobrien	if (hp->histline) {
180259243Sobrien	    copyn(InputBuf, hp->histline, INBUFSIZE);
180359243Sobrien	    CurrentHistLit = 1;
180459243Sobrien	}
180559243Sobrien	else {
180659243Sobrien	    return CC_ERROR;
180759243Sobrien	}
180859243Sobrien    }
180959243Sobrien    else {
181061524Sobrien	(void) sprlex(InputBuf, sizeof(InputBuf) / sizeof(Char), &hp->Hlex);
181159243Sobrien	CurrentHistLit = 0;
181259243Sobrien    }
181359243Sobrien
181459243Sobrien    LastChar = InputBuf + Strlen(InputBuf);
181559243Sobrien    if (LastChar > InputBuf) {
181659243Sobrien	if (LastChar[-1] == '\n')
181759243Sobrien	    LastChar--;
181859243Sobrien	if (LastChar[-1] == ' ')
181959243Sobrien	    LastChar--;
182059243Sobrien	if (LastChar < InputBuf)
182159243Sobrien	    LastChar = InputBuf;
182259243Sobrien    }
182359243Sobrien
182459243Sobrien#ifdef KSHVI
182559243Sobrien    if (VImode)
182659243Sobrien	Cursor = InputBuf;
182759243Sobrien    else
182859243Sobrien#endif /* KSHVI */
182959243Sobrien	Cursor = LastChar;
183059243Sobrien
183159243Sobrien    return(CC_REFRESH);
183259243Sobrien}
183359243Sobrien
183459243Sobrien/*ARGSUSED*/
183559243SobrienCCRETVAL
183659243Sobriene_up_hist(c)
183759243Sobrien    int c;
183859243Sobrien{
183959243Sobrien    Char    beep = 0;
184059243Sobrien
184159243Sobrien    USE(c);
184259243Sobrien    UndoAction = TCSHOP_NOP;
184359243Sobrien    *LastChar = '\0';		/* just in case */
184459243Sobrien
184559243Sobrien    if (Hist_num == 0) {	/* save the current buffer away */
184659243Sobrien	copyn(HistBuf, InputBuf, INBUFSIZE);
184759243Sobrien	LastHist = HistBuf + (LastChar - InputBuf);
184859243Sobrien    }
184959243Sobrien
185059243Sobrien    Hist_num += Argument;
185159243Sobrien
185259243Sobrien    if (c_get_histline() == CC_ERROR) {
185359243Sobrien	beep = 1;
185459243Sobrien	(void) c_get_histline(); /* Hist_num was fixed by first call */
185559243Sobrien    }
185659243Sobrien
185759243Sobrien    Refresh();
185859243Sobrien    if (beep)
185959243Sobrien	return(CC_ERROR);
186059243Sobrien    else
186159243Sobrien	return(CC_NORM);	/* was CC_UP_HIST */
186259243Sobrien}
186359243Sobrien
186459243Sobrien/*ARGSUSED*/
186559243SobrienCCRETVAL
186659243Sobriene_down_hist(c)
186759243Sobrien    int c;
186859243Sobrien{
186959243Sobrien    USE(c);
187059243Sobrien    UndoAction = TCSHOP_NOP;
187159243Sobrien    *LastChar = '\0';		/* just in case */
187259243Sobrien
187359243Sobrien    Hist_num -= Argument;
187459243Sobrien
187559243Sobrien    if (Hist_num < 0) {
187659243Sobrien	Hist_num = 0;
187759243Sobrien	return(CC_ERROR);	/* make it beep */
187859243Sobrien    }
187959243Sobrien
188059243Sobrien    return(c_get_histline());
188159243Sobrien}
188259243Sobrien
188359243Sobrien
188459243Sobrien
188559243Sobrien/*
188659243Sobrien * c_hmatch() return True if the pattern matches the prefix
188759243Sobrien */
188859243Sobrienstatic int
188959243Sobrienc_hmatch(str)
189059243SobrienChar *str;
189159243Sobrien{
189259243Sobrien    if (Strncmp(patbuf, str, (size_t) patlen) == 0)
189359243Sobrien	return 1;
189459243Sobrien    return Gmatch(str, patbuf);
189559243Sobrien}
189659243Sobrien
189759243Sobrien/*
189859243Sobrien * c_hsetpat(): Set the history seatch pattern
189959243Sobrien */
190059243Sobrienstatic void
190159243Sobrienc_hsetpat()
190259243Sobrien{
190359243Sobrien    if (LastCmd != F_UP_SEARCH_HIST && LastCmd != F_DOWN_SEARCH_HIST) {
190459243Sobrien	patlen = (int) (Cursor - InputBuf);
190559243Sobrien	if (patlen >= INBUFSIZE) patlen = INBUFSIZE -1;
190659243Sobrien	if (patlen >= 0)  {
190759243Sobrien	    (void) Strncpy(patbuf, InputBuf, (size_t) patlen);
190859243Sobrien	    patbuf[patlen] = '\0';
190959243Sobrien	}
191059243Sobrien	else
191159243Sobrien	    patlen = (int) Strlen(patbuf);
191259243Sobrien    }
191359243Sobrien#ifdef SDEBUG
191459243Sobrien    xprintf("\nHist_num = %d\n", Hist_num);
191559243Sobrien    xprintf("patlen = %d\n", patlen);
191659243Sobrien    xprintf("patbuf = \"%S\"\n", patbuf);
191759243Sobrien    xprintf("Cursor %d LastChar %d\n", Cursor - InputBuf, LastChar - InputBuf);
191859243Sobrien#endif
191959243Sobrien}
192059243Sobrien
192159243Sobrien/*ARGSUSED*/
192259243SobrienCCRETVAL
192359243Sobriene_up_search_hist(c)
192459243Sobrien    int c;
192559243Sobrien{
192659243Sobrien    struct Hist *hp;
192759243Sobrien    int h;
192859243Sobrien    bool    found = 0;
192959243Sobrien
193059243Sobrien    USE(c);
193159243Sobrien    ActionFlag = TCSHOP_NOP;
193259243Sobrien    UndoAction = TCSHOP_NOP;
193359243Sobrien    *LastChar = '\0';		/* just in case */
193459243Sobrien    if (Hist_num < 0) {
193559243Sobrien#ifdef DEBUG_EDIT
193659243Sobrien	xprintf("%s: e_up_search_hist(): Hist_num < 0; resetting.\n", progname);
193759243Sobrien#endif
193859243Sobrien	Hist_num = 0;
193959243Sobrien	return(CC_ERROR);
194059243Sobrien    }
194159243Sobrien
194259243Sobrien    if (Hist_num == 0)
194359243Sobrien    {
194459243Sobrien	copyn(HistBuf, InputBuf, INBUFSIZE);
194559243Sobrien	LastHist = HistBuf + (LastChar - InputBuf);
194659243Sobrien    }
194759243Sobrien
194859243Sobrien
194959243Sobrien    hp = Histlist.Hnext;
195059243Sobrien    if (hp == NULL)
195159243Sobrien	return(CC_ERROR);
195259243Sobrien
195359243Sobrien    c_hsetpat();		/* Set search pattern !! */
195459243Sobrien
195559243Sobrien    for (h = 1; h <= Hist_num; h++)
195659243Sobrien	hp = hp->Hnext;
195759243Sobrien
195859243Sobrien    while (hp != NULL) {
195959243Sobrien	Char sbuf[INBUFSIZE], *hl;
196059243Sobrien	if (hp->histline == NULL) {
196161524Sobrien	    hp->histline = Strsave(sprlex(sbuf, sizeof(sbuf) / sizeof(Char),
196261524Sobrien				   &hp->Hlex));
196359243Sobrien	}
196461524Sobrien	hl = HistLit ? hp->histline : sprlex(sbuf, sizeof(sbuf) / sizeof(Char),
196561524Sobrien					     &hp->Hlex);
196659243Sobrien#ifdef SDEBUG
196759243Sobrien	xprintf("Comparing with \"%S\"\n", hl);
196859243Sobrien#endif
196959243Sobrien	if ((Strncmp(hl, InputBuf, (size_t) (LastChar - InputBuf)) ||
197059243Sobrien	     hl[LastChar-InputBuf]) && c_hmatch(hl)) {
197159243Sobrien	    found++;
197259243Sobrien	    break;
197359243Sobrien	}
197459243Sobrien	h++;
197559243Sobrien	hp = hp->Hnext;
197659243Sobrien    }
197759243Sobrien
197859243Sobrien    if (!found) {
197959243Sobrien#ifdef SDEBUG
198059243Sobrien	xprintf("not found\n");
198159243Sobrien#endif
198259243Sobrien	return(CC_ERROR);
198359243Sobrien    }
198459243Sobrien
198559243Sobrien    Hist_num = h;
198659243Sobrien
198759243Sobrien    return(c_get_histline());
198859243Sobrien}
198959243Sobrien
199059243Sobrien/*ARGSUSED*/
199159243SobrienCCRETVAL
199259243Sobriene_down_search_hist(c)
199359243Sobrien    int c;
199459243Sobrien{
199559243Sobrien    struct Hist *hp;
199659243Sobrien    int h;
199759243Sobrien    bool    found = 0;
199859243Sobrien
199959243Sobrien    USE(c);
200059243Sobrien    ActionFlag = TCSHOP_NOP;
200159243Sobrien    UndoAction = TCSHOP_NOP;
200259243Sobrien    *LastChar = '\0';		/* just in case */
200359243Sobrien
200459243Sobrien    if (Hist_num == 0)
200559243Sobrien	return(CC_ERROR);
200659243Sobrien
200759243Sobrien    hp = Histlist.Hnext;
200859243Sobrien    if (hp == 0)
200959243Sobrien	return(CC_ERROR);
201059243Sobrien
201159243Sobrien    c_hsetpat();		/* Set search pattern !! */
201259243Sobrien
201359243Sobrien    for (h = 1; h < Hist_num && hp; h++) {
201459243Sobrien	Char sbuf[INBUFSIZE], *hl;
201559243Sobrien	if (hp->histline == NULL) {
201661524Sobrien	    hp->histline = Strsave(sprlex(sbuf, sizeof(sbuf) / sizeof(Char),
201761524Sobrien				   &hp->Hlex));
201859243Sobrien	}
201961524Sobrien	hl = HistLit ? hp->histline : sprlex(sbuf, sizeof(sbuf) / sizeof(Char),
202061524Sobrien					     &hp->Hlex);
202159243Sobrien#ifdef SDEBUG
202259243Sobrien	xprintf("Comparing with \"%S\"\n", hl);
202359243Sobrien#endif
202459243Sobrien	if ((Strncmp(hl, InputBuf, (size_t) (LastChar - InputBuf)) ||
202559243Sobrien	     hl[LastChar-InputBuf]) && c_hmatch(hl))
202659243Sobrien	    found = h;
202759243Sobrien	hp = hp->Hnext;
202859243Sobrien    }
202959243Sobrien
203059243Sobrien    if (!found) {		/* is it the current history number? */
203159243Sobrien	if (!c_hmatch(HistBuf)) {
203259243Sobrien#ifdef SDEBUG
203359243Sobrien	    xprintf("not found\n");
203459243Sobrien#endif
203559243Sobrien	    return(CC_ERROR);
203659243Sobrien	}
203759243Sobrien    }
203859243Sobrien
203959243Sobrien    Hist_num = found;
204059243Sobrien
204159243Sobrien    return(c_get_histline());
204259243Sobrien}
204359243Sobrien
204459243Sobrien/*ARGSUSED*/
204559243SobrienCCRETVAL
204659243Sobriene_helpme(c)
204759243Sobrien    int c;
204859243Sobrien{
204959243Sobrien    USE(c);
205059243Sobrien    PastBottom();
205159243Sobrien    *LastChar = '\0';		/* just in case */
205259243Sobrien    return(CC_HELPME);
205359243Sobrien}
205459243Sobrien
205559243Sobrien/*ARGSUSED*/
205659243SobrienCCRETVAL
205759243Sobriene_correct(c)
205859243Sobrien    int c;
205959243Sobrien{
206059243Sobrien    USE(c);
206159243Sobrien    *LastChar = '\0';		/* just in case */
206259243Sobrien    return(CC_CORRECT);
206359243Sobrien}
206459243Sobrien
206559243Sobrien/*ARGSUSED*/
206659243SobrienCCRETVAL
206759243Sobriene_correctl(c)
206859243Sobrien    int c;
206959243Sobrien{
207059243Sobrien    USE(c);
207159243Sobrien    *LastChar = '\0';		/* just in case */
207259243Sobrien    return(CC_CORRECT_L);
207359243Sobrien}
207459243Sobrien
207559243Sobrien/*ARGSUSED*/
207659243SobrienCCRETVAL
207759243Sobriene_run_fg_editor(c)
207859243Sobrien    int c;
207959243Sobrien{
208083098Smp    struct process *pp;
208159243Sobrien    extern bool tellwhat;
208259243Sobrien
208359243Sobrien    USE(c);
208459243Sobrien    if ((pp = find_stop_ed()) != NULL) {
208559243Sobrien	/* save our editor state so we can restore it */
208659243Sobrien	tellwhat = 1;
208759243Sobrien	copyn(WhichBuf, InputBuf, INBUFSIZE);
208859243Sobrien	LastWhich = WhichBuf + (LastChar - InputBuf);
208959243Sobrien	CursWhich = WhichBuf + (Cursor - InputBuf);
209059243Sobrien	HistWhich = Hist_num;
209159243Sobrien	Hist_num = 0;		/* for the history commands */
209259243Sobrien
209359243Sobrien	/* put the tty in a sane mode */
209459243Sobrien	PastBottom();
209559243Sobrien	(void) Cookedmode();	/* make sure the tty is set up correctly */
209659243Sobrien
209759243Sobrien	/* do it! */
209859243Sobrien	fg_proc_entry(pp);
209959243Sobrien
210059243Sobrien	(void) Rawmode();	/* go on */
210159243Sobrien	Refresh();
210259243Sobrien	tellwhat = 0;
210359243Sobrien    }
210459243Sobrien    return(CC_NORM);
210559243Sobrien}
210659243Sobrien
210759243Sobrien/*ARGSUSED*/
210859243SobrienCCRETVAL
210959243Sobriene_list_choices(c)
211059243Sobrien    int c;
211159243Sobrien{
211259243Sobrien    USE(c);
211359243Sobrien    PastBottom();
211459243Sobrien    *LastChar = '\0';		/* just in case */
211559243Sobrien    return(CC_LIST_CHOICES);
211659243Sobrien}
211759243Sobrien
211859243Sobrien/*ARGSUSED*/
211959243SobrienCCRETVAL
212059243Sobriene_list_all(c)
212159243Sobrien    int c;
212259243Sobrien{
212359243Sobrien    USE(c);
212459243Sobrien    PastBottom();
212559243Sobrien    *LastChar = '\0';		/* just in case */
212659243Sobrien    return(CC_LIST_ALL);
212759243Sobrien}
212859243Sobrien
212959243Sobrien/*ARGSUSED*/
213059243SobrienCCRETVAL
213159243Sobriene_list_glob(c)
213259243Sobrien    int c;
213359243Sobrien{
213459243Sobrien    USE(c);
213559243Sobrien    PastBottom();
213659243Sobrien    *LastChar = '\0';		/* just in case */
213759243Sobrien    return(CC_LIST_GLOB);
213859243Sobrien}
213959243Sobrien
214059243Sobrien/*ARGSUSED*/
214159243SobrienCCRETVAL
214259243Sobriene_expand_glob(c)
214359243Sobrien    int c;
214459243Sobrien{
214559243Sobrien    USE(c);
214659243Sobrien    *LastChar = '\0';		/* just in case */
214759243Sobrien    return(CC_EXPAND_GLOB);
214859243Sobrien}
214959243Sobrien
215059243Sobrien/*ARGSUSED*/
215159243SobrienCCRETVAL
215259243Sobriene_normalize_path(c)
215359243Sobrien    int c;
215459243Sobrien{
215559243Sobrien    USE(c);
215659243Sobrien    *LastChar = '\0';		/* just in case */
215759243Sobrien    return(CC_NORMALIZE_PATH);
215859243Sobrien}
215959243Sobrien
216059243Sobrien/*ARGSUSED*/
216159243SobrienCCRETVAL
216259243Sobriene_normalize_command(c)
216359243Sobrien    int c;
216459243Sobrien{
216559243Sobrien    USE(c);
216659243Sobrien    *LastChar = '\0';		/* just in case */
216759243Sobrien    return(CC_NORMALIZE_COMMAND);
216859243Sobrien}
216959243Sobrien
217059243Sobrien/*ARGSUSED*/
217159243SobrienCCRETVAL
217259243Sobriene_expand_vars(c)
217359243Sobrien    int c;
217459243Sobrien{
217559243Sobrien    USE(c);
217659243Sobrien    *LastChar = '\0';		/* just in case */
217759243Sobrien    return(CC_EXPAND_VARS);
217859243Sobrien}
217959243Sobrien
218059243Sobrien/*ARGSUSED*/
218159243SobrienCCRETVAL
218259243Sobriene_which(c)
218359243Sobrien    int c;
218459243Sobrien{				/* do a fast command line which(1) */
218559243Sobrien    USE(c);
218659243Sobrien    PastBottom();
218759243Sobrien    *LastChar = '\0';		/* just in case */
218859243Sobrien    return(CC_WHICH);
218959243Sobrien}
219059243Sobrien
219159243Sobrien/*ARGSUSED*/
219259243SobrienCCRETVAL
219359243Sobriene_last_item(c)
219459243Sobrien    int c;
219559243Sobrien{				/* insert the last element of the prev. cmd */
219683098Smp    Char *cp;
219783098Smp    struct Hist *hp;
219883098Smp    struct wordent *wp, *firstp;
219983098Smp    int i;
220059243Sobrien    Char buf[INBUFSIZE];
220159243Sobrien
220259243Sobrien    USE(c);
220359243Sobrien    if (Argument <= 0)
220459243Sobrien	return(CC_ERROR);
220559243Sobrien
220659243Sobrien    hp = Histlist.Hnext;
220759243Sobrien    if (hp == NULL) {	/* this is only if no history */
220859243Sobrien	return(CC_ERROR);
220959243Sobrien    }
221059243Sobrien
221159243Sobrien    wp = (hp->Hlex).prev;
221259243Sobrien
221359243Sobrien    if (wp->prev == (struct wordent *) NULL)
221459243Sobrien	return(CC_ERROR);	/* an empty history entry */
221559243Sobrien
221659243Sobrien    firstp = (hp->Hlex).next;
221759243Sobrien
221859243Sobrien    /* back up arg words in lex */
221959243Sobrien    for (i = 0; i < Argument && wp != firstp; i++) {
222059243Sobrien	wp = wp->prev;
222159243Sobrien    }
222259243Sobrien
222359243Sobrien    cp = expand_lex(buf, INBUFSIZE, wp->prev, 0, i - 1);
222459243Sobrien    *cp = '\0';
222559243Sobrien    if (InsertStr(buf))
222659243Sobrien	return(CC_ERROR);
222759243Sobrien
222859243Sobrien    return(CC_REFRESH);
222959243Sobrien}
223059243Sobrien
223159243Sobrien/*ARGSUSED*/
223259243SobrienCCRETVAL
223359243Sobriene_dabbrev_expand(c)
223459243Sobrien    int c;
223559243Sobrien{				/* expand to preceding word matching prefix */
223683098Smp    Char *cp, *ncp, *bp;
223783098Smp    struct Hist *hp;
223883098Smp    int arg = 0, len = 0, i; /* len = 0 to shut up gcc -Wall */
223983098Smp    bool found = 0;
224059243Sobrien    Char hbuf[INBUFSIZE];
224159243Sobrien    static int oldevent, hist, word;
224259243Sobrien    static Char *start, *oldcursor;
224359243Sobrien
224459243Sobrien    USE(c);
224559243Sobrien    if (Argument <= 0)
224659243Sobrien	return(CC_ERROR);
224759243Sobrien
224883098Smp    cp = c_preword(Cursor, InputBuf, 1, STRshwordsep);
224959243Sobrien    if (cp == Cursor || Isspace(*cp))
225059243Sobrien	return(CC_ERROR);
225159243Sobrien
225259243Sobrien    hp = Histlist.Hnext;
225359243Sobrien    bp = InputBuf;
225459243Sobrien    if (Argument == 1 && eventno == oldevent && cp == start &&
225559243Sobrien	Cursor == oldcursor && patlen > 0 && Strncmp(patbuf, cp, patlen) == 0){
225659243Sobrien	/* continue previous search - go to last match (hist/word) */
225759243Sobrien	if (hist != 0) {		/* need to move up history */
225859243Sobrien	    for (i = 1; i < hist && hp != NULL; i++)
225959243Sobrien		hp = hp->Hnext;
226059243Sobrien	    if (hp == NULL)	/* "can't happen" */
226159243Sobrien		return(CC_ERROR);
226259243Sobrien	    cp = expand_lex(hbuf, INBUFSIZE, &hp->Hlex, 0, NCARGS);
226359243Sobrien	    *cp = '\0';
226459243Sobrien	    bp = hbuf;
226559243Sobrien	    hp = hp->Hnext;
226659243Sobrien	}
226783098Smp	cp = c_preword(cp, bp, word, STRshwordsep);
226859243Sobrien    } else {			/* starting new search */
226959243Sobrien	oldevent = eventno;
227059243Sobrien	start = cp;
227159243Sobrien	patlen = (int) (Cursor - cp);
227259243Sobrien	(void) Strncpy(patbuf, cp, patlen);
227359243Sobrien	hist = 0;
227459243Sobrien	word = 0;
227559243Sobrien    }
227659243Sobrien
227759243Sobrien    while (!found) {
227883098Smp	ncp = c_preword(cp, bp, 1, STRshwordsep);
227959243Sobrien	if (ncp == cp || Isspace(*ncp)) { /* beginning of line */
228059243Sobrien	    hist++;
228159243Sobrien	    word = 0;
228259243Sobrien	    if (hp == NULL)
228359243Sobrien		return(CC_ERROR);
228459243Sobrien	    cp = expand_lex(hbuf, INBUFSIZE, &hp->Hlex, 0, NCARGS);
228559243Sobrien	    *cp = '\0';
228659243Sobrien	    bp = hbuf;
228759243Sobrien	    hp = hp->Hnext;
228859243Sobrien	    continue;
228959243Sobrien	} else {
229059243Sobrien	    word++;
229183098Smp	    len = (int) (c_endword(ncp-1, cp, 1, STRshwordsep) - ncp + 1);
229259243Sobrien	    cp = ncp;
229359243Sobrien	}
229459243Sobrien	if (len > patlen && Strncmp(cp, patbuf, patlen) == 0) {
229559243Sobrien	    /* We don't fully check distinct matches as Gnuemacs does: */
229659243Sobrien	    if (Argument > 1) {	/* just count matches */
229759243Sobrien		if (++arg >= Argument)
229859243Sobrien		    found++;
229959243Sobrien	    } else {		/* match if distinct from previous */
230059243Sobrien		if (len != Cursor - start || Strncmp(cp, start, len) != 0)
230159243Sobrien		    found++;
230259243Sobrien	    }
230359243Sobrien	}
230459243Sobrien    }
230559243Sobrien
230659243Sobrien    if (LastChar + len - (Cursor - start) >= InputLim)
230759243Sobrien	return(CC_ERROR);	/* no room */
230859243Sobrien    DeleteBack(Cursor - start);
230959243Sobrien    c_insert(len);
231059243Sobrien    while (len--)
231159243Sobrien	*Cursor++ = *cp++;
231259243Sobrien    oldcursor = Cursor;
231359243Sobrien    return(CC_REFRESH);
231459243Sobrien}
231559243Sobrien
231659243Sobrien/*ARGSUSED*/
231759243SobrienCCRETVAL
231859243Sobriene_yank_kill(c)
231959243Sobrien    int c;
232059243Sobrien{				/* almost like GnuEmacs */
232183098Smp    int len;
232283098Smp    Char *kp, *cp;
232359243Sobrien
232459243Sobrien    USE(c);
232583098Smp    if (KillRingLen == 0)	/* nothing killed */
232659243Sobrien	return(CC_ERROR);
232783098Smp    len = Strlen(KillRing[YankPos].buf);
232883098Smp    if (LastChar + len >= InputLim)
232959243Sobrien	return(CC_ERROR);	/* end of buffer space */
233059243Sobrien
233159243Sobrien    /* else */
233259243Sobrien    cp = Cursor;		/* for speed */
233359243Sobrien
233483098Smp    c_insert(len);		/* open the space, */
233583098Smp    for (kp = KillRing[YankPos].buf; *kp; kp++)	/* copy the chars */
233659243Sobrien	*cp++ = *kp;
233759243Sobrien
233883098Smp    if (Argument == 1) {	/* if no arg */
233983098Smp	Mark = Cursor;		/* mark at beginning, cursor at end */
234083098Smp	Cursor = cp;
234183098Smp    } else {
234283098Smp	Mark = cp;		/* else cursor at beginning, mark at end */
234383098Smp    }
234459243Sobrien
234559243Sobrien    return(CC_REFRESH);
234659243Sobrien}
234759243Sobrien
234859243Sobrien/*ARGSUSED*/
234959243SobrienCCRETVAL
235083098Smpe_yank_pop(c)
235183098Smp    int c;
235283098Smp{				/* almost like GnuEmacs */
235383098Smp    int m_bef_c, del_len, ins_len;
235483098Smp    Char *kp, *cp;
235583098Smp
235683098Smp    USE(c);
235783098Smp
235883098Smp#if 0
235983098Smp    /* XXX This "should" be here, but doesn't work, since LastCmd
236083098Smp       gets set on CC_ERROR and CC_ARGHACK, which it shouldn't(?).
236183098Smp       (But what about F_ARGFOUR?) I.e. if you hit M-y twice the
236283098Smp       second one will "succeed" even if the first one wasn't preceded
236383098Smp       by a yank, and giving an argument is impossible. Now we "succeed"
236483098Smp       regardless of previous command, which is wrong too of course. */
236583098Smp    if (LastCmd != F_YANK_KILL && LastCmd != F_YANK_POP)
236683098Smp	return(CC_ERROR);
236783098Smp#endif
236883098Smp
236983098Smp    if (KillRingLen == 0)	/* nothing killed */
237083098Smp	return(CC_ERROR);
237183098Smp    YankPos -= Argument;
237283098Smp    while (YankPos < 0)
237383098Smp	YankPos += KillRingLen;
237483098Smp    YankPos %= KillRingLen;
237583098Smp
237683098Smp    if (Cursor > Mark) {
237783098Smp	del_len = Cursor - Mark;
237883098Smp	m_bef_c = 1;
237983098Smp    } else {
238083098Smp	del_len = Mark - Cursor;
238183098Smp	m_bef_c = 0;
238283098Smp    }
238383098Smp    ins_len = Strlen(KillRing[YankPos].buf);
238483098Smp    if (LastChar + ins_len - del_len >= InputLim)
238583098Smp	return(CC_ERROR);	/* end of buffer space */
238683098Smp
238783098Smp    if (m_bef_c) {
238883098Smp	c_delbefore(del_len);
238983098Smp	Cursor = Mark;
239083098Smp    } else {
239183098Smp	c_delafter(del_len);
239283098Smp    }
239383098Smp    cp = Cursor;		/* for speed */
239483098Smp
239583098Smp    c_insert(ins_len);		/* open the space, */
239683098Smp    for (kp = KillRing[YankPos].buf; *kp; kp++)	/* copy the chars */
239783098Smp	*cp++ = *kp;
239883098Smp
239983098Smp    if (m_bef_c) {
240083098Smp	Mark = Cursor;		/* mark at beginning, cursor at end */
240183098Smp	Cursor = cp;
240283098Smp    } else {
240383098Smp	Mark = cp;		/* else cursor at beginning, mark at end */
240483098Smp    }
240583098Smp
240683098Smp    return(CC_REFRESH);
240783098Smp}
240883098Smp
240983098Smp/*ARGSUSED*/
241083098SmpCCRETVAL
241159243Sobrienv_delprev(c) 		/* Backspace key in insert mode */
241259243Sobrien    int c;
241359243Sobrien{
241459243Sobrien    int rc;
241559243Sobrien
241659243Sobrien    USE(c);
241759243Sobrien    rc = CC_ERROR;
241859243Sobrien
241959243Sobrien    if (InsertPos != 0) {
242059243Sobrien	if (Argument <= Cursor - InsertPos) {
242159243Sobrien	    c_delbefore(Argument);	/* delete before */
242259243Sobrien	    Cursor -= Argument;
242359243Sobrien#if defined(DSPMBYTE)
242459243Sobrien	if (_enable_mbdisp && extdel) {
242559243Sobrien	    Cursor--;
242659243Sobrien	    e_redisp(c);
242759243Sobrien	}
242859243Sobrien#endif
242959243Sobrien	    rc = CC_REFRESH;
243059243Sobrien	}
243159243Sobrien    }
243259243Sobrien    return(rc);
243359243Sobrien}   /* v_delprev  */
243459243Sobrien
243559243Sobrien/*ARGSUSED*/
243659243SobrienCCRETVAL
243759243Sobriene_delprev(c)
243859243Sobrien    int c;
243959243Sobrien{
244059243Sobrien    USE(c);
244159243Sobrien    if (Cursor > InputBuf) {
244259243Sobrien	c_delbefore(Argument);	/* delete before dot */
244359243Sobrien	if (Argument > Cursor - InputBuf)
244459243Sobrien	    Cursor = InputBuf;	/* bounds check */
244559243Sobrien	else
244659243Sobrien	    Cursor -= Argument;
244759243Sobrien#if defined(DSPMBYTE)
244859243Sobrien	if (_enable_mbdisp && extdel && Cursor > InputBuf) {
244959243Sobrien	    Cursor--;
245059243Sobrien	    e_redisp(c);
245159243Sobrien	}
245259243Sobrien#endif
245359243Sobrien	return(CC_REFRESH);
245459243Sobrien    }
245559243Sobrien    else {
245659243Sobrien	return(CC_ERROR);
245759243Sobrien    }
245859243Sobrien}
245959243Sobrien
246059243Sobrien/*ARGSUSED*/
246159243SobrienCCRETVAL
246259243Sobriene_delwordprev(c)
246359243Sobrien    int c;
246459243Sobrien{
246583098Smp    Char *cp;
246659243Sobrien
246759243Sobrien    USE(c);
246859243Sobrien    if (Cursor == InputBuf)
246959243Sobrien	return(CC_ERROR);
247059243Sobrien    /* else */
247159243Sobrien
247259243Sobrien    cp = c_prev_word(Cursor, InputBuf, Argument);
247359243Sobrien
247483098Smp    c_push_kill(cp, Cursor);	/* save the text */
247559243Sobrien
247659243Sobrien    c_delbefore((int)(Cursor - cp));	/* delete before dot */
247759243Sobrien    Cursor = cp;
247859243Sobrien    if (Cursor < InputBuf)
247959243Sobrien	Cursor = InputBuf;	/* bounds check */
248059243Sobrien    return(CC_REFRESH);
248159243Sobrien}
248259243Sobrien
248359243Sobrien/* DCS <dcs@neutron.chem.yale.edu>, 9 Oct 93
248459243Sobrien *
248559243Sobrien * Changed the names of some of the ^D family of editor functions to
248659243Sobrien * correspond to what they actually do and created new e_delnext_list
248759243Sobrien * for completeness.
248859243Sobrien *
248959243Sobrien *   Old names:			New names:
249059243Sobrien *
249159243Sobrien *   delete-char		delete-char-or-eof
249259243Sobrien *     F_DELNEXT		  F_DELNEXT_EOF
249359243Sobrien *     e_delnext		  e_delnext_eof
249459243Sobrien *     edelnxt			  edelnxteof
249559243Sobrien *   delete-char-or-eof		delete-char
249659243Sobrien *     F_DELNEXT_EOF		  F_DELNEXT
249759243Sobrien *     e_delnext_eof		  e_delnext
249859243Sobrien *     edelnxteof		  edelnxt
249959243Sobrien *   delete-char-or-list	delete-char-or-list-or-eof
250059243Sobrien *     F_LIST_DELNEXT		  F_DELNEXT_LIST_EOF
250159243Sobrien *     e_list_delnext		  e_delnext_list_eof
250259243Sobrien *   				  edellsteof
250359243Sobrien *   (no old equivalent)	delete-char-or-list
250459243Sobrien *   				  F_DELNEXT_LIST
250559243Sobrien *   				  e_delnext_list
250659243Sobrien *   				  e_delnxtlst
250759243Sobrien */
250859243Sobrien
250959243Sobrien/* added by mtk@ari.ncl.omron.co.jp (920818) */
251059243Sobrien/* rename e_delnext() -> e_delnext_eof() */
251159243Sobrien/*ARGSUSED*/
251259243SobrienCCRETVAL
251359243Sobriene_delnext(c)
251459243Sobrien    int c;
251559243Sobrien{
251659243Sobrien    USE(c);
251759243Sobrien    if (Cursor == LastChar) {/* if I'm at the end */
251859243Sobrien	if (!VImode) {
251959243Sobrien		return(CC_ERROR);
252059243Sobrien	}
252159243Sobrien	else {
252259243Sobrien	    if (Cursor != InputBuf)
252359243Sobrien		Cursor--;
252459243Sobrien	    else
252559243Sobrien		return(CC_ERROR);
252659243Sobrien	}
252759243Sobrien    }
252859243Sobrien    c_delafter(Argument);	/* delete after dot */
252959243Sobrien    if (Cursor > LastChar)
253059243Sobrien	Cursor = LastChar;	/* bounds check */
253159243Sobrien    return(CC_REFRESH);
253259243Sobrien}
253359243Sobrien
253459243Sobrien
253559243Sobrien/*ARGSUSED*/
253659243SobrienCCRETVAL
253759243Sobriene_delnext_eof(c)
253859243Sobrien    int c;
253959243Sobrien{
254059243Sobrien    USE(c);
254159243Sobrien    if (Cursor == LastChar) {/* if I'm at the end */
254259243Sobrien	if (!VImode) {
254359243Sobrien	    if (Cursor == InputBuf) {
254459243Sobrien		/* if I'm also at the beginning */
254559243Sobrien		so_write(STReof, 4);/* then do a EOF */
254659243Sobrien		flush();
254759243Sobrien		return(CC_EOF);
254859243Sobrien	    }
254959243Sobrien	    else
255059243Sobrien		return(CC_ERROR);
255159243Sobrien	}
255259243Sobrien	else {
255359243Sobrien	    if (Cursor != InputBuf)
255459243Sobrien		Cursor--;
255559243Sobrien	    else
255659243Sobrien		return(CC_ERROR);
255759243Sobrien	}
255859243Sobrien    }
255959243Sobrien    c_delafter(Argument);	/* delete after dot */
256059243Sobrien    if (Cursor > LastChar)
256159243Sobrien	Cursor = LastChar;	/* bounds check */
256259243Sobrien    return(CC_REFRESH);
256359243Sobrien}
256459243Sobrien
256559243Sobrien/*ARGSUSED*/
256659243SobrienCCRETVAL
256759243Sobriene_delnext_list(c)
256859243Sobrien    int c;
256959243Sobrien{
257059243Sobrien    USE(c);
257159243Sobrien    if (Cursor == LastChar) {	/* if I'm at the end */
257259243Sobrien	PastBottom();
257359243Sobrien	*LastChar = '\0';	/* just in case */
257459243Sobrien	return(CC_LIST_CHOICES);
257559243Sobrien    }
257659243Sobrien    else {
257759243Sobrien	c_delafter(Argument);	/* delete after dot */
257859243Sobrien	if (Cursor > LastChar)
257959243Sobrien	    Cursor = LastChar;	/* bounds check */
258059243Sobrien	return(CC_REFRESH);
258159243Sobrien    }
258259243Sobrien}
258359243Sobrien
258459243Sobrien/*ARGSUSED*/
258559243SobrienCCRETVAL
258659243Sobriene_delnext_list_eof(c)
258759243Sobrien    int c;
258859243Sobrien{
258959243Sobrien    USE(c);
259059243Sobrien    if (Cursor == LastChar) {	/* if I'm at the end */
259159243Sobrien	if (Cursor == InputBuf) {	/* if I'm also at the beginning */
259259243Sobrien	    so_write(STReof, 4);/* then do a EOF */
259359243Sobrien	    flush();
259459243Sobrien	    return(CC_EOF);
259559243Sobrien	}
259659243Sobrien	else {
259759243Sobrien	    PastBottom();
259859243Sobrien	    *LastChar = '\0';	/* just in case */
259959243Sobrien	    return(CC_LIST_CHOICES);
260059243Sobrien	}
260159243Sobrien    }
260259243Sobrien    else {
260359243Sobrien	c_delafter(Argument);	/* delete after dot */
260459243Sobrien	if (Cursor > LastChar)
260559243Sobrien	    Cursor = LastChar;	/* bounds check */
260659243Sobrien	return(CC_REFRESH);
260759243Sobrien    }
260859243Sobrien}
260959243Sobrien
261059243Sobrien/*ARGSUSED*/
261159243SobrienCCRETVAL
261259243Sobriene_list_eof(c)
261359243Sobrien    int c;
261459243Sobrien{
261559243Sobrien    CCRETVAL rv;
261659243Sobrien
261759243Sobrien    USE(c);
261859243Sobrien    if (Cursor == LastChar && Cursor == InputBuf) {
261959243Sobrien	so_write(STReof, 4);	/* then do a EOF */
262059243Sobrien	flush();
262159243Sobrien	rv = CC_EOF;
262259243Sobrien    }
262359243Sobrien    else {
262459243Sobrien	PastBottom();
262559243Sobrien	*LastChar = '\0';	/* just in case */
262659243Sobrien	rv = CC_LIST_CHOICES;
262759243Sobrien    }
262859243Sobrien    return rv;
262959243Sobrien}
263059243Sobrien
263159243Sobrien/*ARGSUSED*/
263259243SobrienCCRETVAL
263359243Sobriene_delwordnext(c)
263459243Sobrien    int c;
263559243Sobrien{
263683098Smp    Char *cp;
263759243Sobrien
263859243Sobrien    USE(c);
263959243Sobrien    if (Cursor == LastChar)
264059243Sobrien	return(CC_ERROR);
264159243Sobrien    /* else */
264259243Sobrien
264359243Sobrien    cp = c_next_word(Cursor, LastChar, Argument);
264459243Sobrien
264583098Smp    c_push_kill(Cursor, cp);	/* save the text */
264659243Sobrien
264759243Sobrien    c_delafter((int)(cp - Cursor));	/* delete after dot */
264859243Sobrien    if (Cursor > LastChar)
264959243Sobrien	Cursor = LastChar;	/* bounds check */
265059243Sobrien    return(CC_REFRESH);
265159243Sobrien}
265259243Sobrien
265359243Sobrien/*ARGSUSED*/
265459243SobrienCCRETVAL
265559243Sobriene_toend(c)
265659243Sobrien    int c;
265759243Sobrien{
265859243Sobrien    USE(c);
265959243Sobrien    Cursor = LastChar;
266059243Sobrien    if (VImode)
266159243Sobrien	if (ActionFlag & TCSHOP_DELETE) {
266259243Sobrien	    c_delfini();
266359243Sobrien	    return(CC_REFRESH);
266459243Sobrien	}
266559243Sobrien    RefCursor();		/* move the cursor */
266659243Sobrien    return(CC_NORM);
266759243Sobrien}
266859243Sobrien
266959243Sobrien/*ARGSUSED*/
267059243SobrienCCRETVAL
267159243Sobriene_tobeg(c)
267259243Sobrien    int c;
267359243Sobrien{
267459243Sobrien    USE(c);
267559243Sobrien    Cursor = InputBuf;
267659243Sobrien
267759243Sobrien    if (VImode) {
267859243Sobrien       while (Isspace(*Cursor)) /* We want FIRST non space character */
267959243Sobrien	Cursor++;
268059243Sobrien	if (ActionFlag & TCSHOP_DELETE) {
268159243Sobrien	    c_delfini();
268259243Sobrien	    return(CC_REFRESH);
268359243Sobrien	}
268459243Sobrien    }
268559243Sobrien
268659243Sobrien    RefCursor();		/* move the cursor */
268759243Sobrien    return(CC_NORM);
268859243Sobrien}
268959243Sobrien
269059243Sobrien/*ARGSUSED*/
269159243SobrienCCRETVAL
269259243Sobriene_killend(c)
269359243Sobrien    int c;
269459243Sobrien{
269559243Sobrien    USE(c);
269683098Smp    c_push_kill(Cursor, LastChar); /* copy it */
269759243Sobrien    LastChar = Cursor;		/* zap! -- delete to end */
269859243Sobrien    return(CC_REFRESH);
269959243Sobrien}
270059243Sobrien
270159243Sobrien
270259243Sobrien/*ARGSUSED*/
270359243SobrienCCRETVAL
270459243Sobriene_killbeg(c)
270559243Sobrien    int c;
270659243Sobrien{
270759243Sobrien    USE(c);
270883098Smp    c_push_kill(InputBuf, Cursor); /* copy it */
270959243Sobrien    c_delbefore((int)(Cursor - InputBuf));
271059243Sobrien    Cursor = InputBuf;		/* zap! */
271159243Sobrien    return(CC_REFRESH);
271259243Sobrien}
271359243Sobrien
271459243Sobrien/*ARGSUSED*/
271559243SobrienCCRETVAL
271659243Sobriene_killall(c)
271759243Sobrien    int c;
271859243Sobrien{
271959243Sobrien    USE(c);
272083098Smp    c_push_kill(InputBuf, LastChar); /* copy it */
272159243Sobrien    LastChar = InputBuf;	/* zap! -- delete all of it */
272259243Sobrien    Cursor = InputBuf;
272359243Sobrien    return(CC_REFRESH);
272459243Sobrien}
272559243Sobrien
272659243Sobrien/*ARGSUSED*/
272759243SobrienCCRETVAL
272859243Sobriene_killregion(c)
272959243Sobrien    int c;
273059243Sobrien{
273159243Sobrien    USE(c);
273259243Sobrien    if (!Mark)
273359243Sobrien	return(CC_ERROR);
273459243Sobrien
273559243Sobrien    if (Mark > Cursor) {
273683098Smp	c_push_kill(Cursor, Mark); /* copy it */
273783098Smp	c_delafter((int)(Mark - Cursor)); /* delete it - UNUSED BY VI mode */
273883098Smp	Mark = Cursor;
273959243Sobrien    }
274059243Sobrien    else {			/* mark is before cursor */
274183098Smp	c_push_kill(Mark, Cursor); /* copy it */
274283098Smp	c_delbefore((int)(Cursor - Mark));
274359243Sobrien	Cursor = Mark;
274459243Sobrien    }
274559243Sobrien    return(CC_REFRESH);
274659243Sobrien}
274759243Sobrien
274859243Sobrien/*ARGSUSED*/
274959243SobrienCCRETVAL
275059243Sobriene_copyregion(c)
275159243Sobrien    int c;
275259243Sobrien{
275359243Sobrien    USE(c);
275459243Sobrien    if (!Mark)
275559243Sobrien	return(CC_ERROR);
275659243Sobrien
275759243Sobrien    if (Mark > Cursor) {
275883098Smp	c_push_kill(Cursor, Mark); /* copy it */
275959243Sobrien    }
276059243Sobrien    else {			/* mark is before cursor */
276183098Smp	c_push_kill(Mark, Cursor); /* copy it */
276259243Sobrien    }
276359243Sobrien    return(CC_NORM);		/* don't even need to Refresh() */
276459243Sobrien}
276559243Sobrien
276659243Sobrien/*ARGSUSED*/
276759243SobrienCCRETVAL
276859243Sobriene_charswitch(cc)
276959243Sobrien    int cc;
277059243Sobrien{
277183098Smp    Char c;
277259243Sobrien
277359243Sobrien    USE(cc);
277459243Sobrien
277559243Sobrien    /* do nothing if we are at beginning of line or have only one char */
277659243Sobrien    if (Cursor == &InputBuf[0] || LastChar == &InputBuf[1]) {
277759243Sobrien	return(CC_ERROR);
277859243Sobrien    }
277959243Sobrien
278059243Sobrien    if (Cursor < LastChar) {
278159243Sobrien	Cursor++;
278259243Sobrien    }
278359243Sobrien    c = Cursor[-2];
278459243Sobrien    Cursor[-2] = Cursor[-1];
278559243Sobrien    Cursor[-1] = c;
278659243Sobrien    return(CC_REFRESH);
278759243Sobrien}
278859243Sobrien
278959243Sobrien/*ARGSUSED*/
279059243SobrienCCRETVAL
279159243Sobriene_gcharswitch(cc)
279259243Sobrien    int cc;
279359243Sobrien{				/* gosmacs style ^T */
279483098Smp    Char c;
279559243Sobrien
279659243Sobrien    USE(cc);
279759243Sobrien    if (Cursor > &InputBuf[1]) {/* must have at least two chars entered */
279859243Sobrien	c = Cursor[-2];
279959243Sobrien	Cursor[-2] = Cursor[-1];
280059243Sobrien	Cursor[-1] = c;
280159243Sobrien	return(CC_REFRESH);
280259243Sobrien    }
280359243Sobrien    else {
280459243Sobrien	return(CC_ERROR);
280559243Sobrien    }
280659243Sobrien}
280759243Sobrien
280859243Sobrien#if defined(DSPMBYTE) /* BY TAGA Nayuta VERY THANKS */
280959243Sobrien/*ARGSUSED*/
281059243Sobrienstatic void
281159243Sobriene_charback_mbyte(argument)
281259243Sobrien     int argument;
281359243Sobrien{
281459243Sobrien    if (!_enable_mbdisp) {
281559243Sobrien	if (Argument > Cursor - InputBuf)
281659243Sobrien	    Cursor = InputBuf;
281759243Sobrien	else
281859243Sobrien	    Cursor -= Argument;
281959243Sobrien    }
282059243Sobrien    else {
282159243Sobrien	while (0 < argument && Cursor > InputBuf) {
282259243Sobrien	    if (Cursor - 1 != InputBuf &&
282359243Sobrien		Ismbyte1(*(Cursor - 2)) && Ismbyte2(*(Cursor - 1))) {
282459243Sobrien		Cursor--;
282559243Sobrien	    }
282659243Sobrien	    Cursor--;
282759243Sobrien	    argument--;
282859243Sobrien	}
282959243Sobrien    }
283059243Sobrien}
283159243Sobrien#endif
283259243Sobrien
283359243Sobrien/*ARGSUSED*/
283459243SobrienCCRETVAL
283559243Sobriene_charback(c)
283659243Sobrien    int c;
283759243Sobrien{
283859243Sobrien    USE(c);
283959243Sobrien    if (Cursor > InputBuf) {
284059243Sobrien#if defined(DSPMBYTE) /* BY TAGA Nayuta VERY THANKS */
284159243Sobrien	e_charback_mbyte(Argument);
284259243Sobrien#else
284359243Sobrien	if (Argument > Cursor - InputBuf)
284459243Sobrien	    Cursor = InputBuf;
284559243Sobrien	else
284659243Sobrien	    Cursor -= Argument;
284759243Sobrien#endif
284859243Sobrien
284959243Sobrien	if (VImode)
285059243Sobrien	    if (ActionFlag & TCSHOP_DELETE) {
285159243Sobrien		c_delfini();
285259243Sobrien		return(CC_REFRESH);
285359243Sobrien	    }
285459243Sobrien
285559243Sobrien	RefCursor();
285659243Sobrien	return(CC_NORM);
285759243Sobrien    }
285859243Sobrien    else {
285959243Sobrien	return(CC_ERROR);
286059243Sobrien    }
286159243Sobrien}
286259243Sobrien
286359243Sobrien/*ARGSUSED*/
286459243SobrienCCRETVAL
286559243Sobrienv_wordback(c)
286659243Sobrien    int c;
286759243Sobrien{
286859243Sobrien    USE(c);
286959243Sobrien    if (Cursor == InputBuf)
287059243Sobrien	return(CC_ERROR);
287159243Sobrien    /* else */
287259243Sobrien
287383098Smp    Cursor = c_preword(Cursor, InputBuf, Argument, STRshwspace); /* bounds check */
287459243Sobrien
287559243Sobrien    if (ActionFlag & TCSHOP_DELETE) {
287659243Sobrien	c_delfini();
287759243Sobrien	return(CC_REFRESH);
287859243Sobrien    }
287959243Sobrien
288059243Sobrien    RefCursor();
288159243Sobrien    return(CC_NORM);
288259243Sobrien}
288359243Sobrien
288459243Sobrien/*ARGSUSED*/
288559243SobrienCCRETVAL
288659243Sobriene_wordback(c)
288759243Sobrien    int c;
288859243Sobrien{
288959243Sobrien    USE(c);
289059243Sobrien    if (Cursor == InputBuf)
289159243Sobrien	return(CC_ERROR);
289259243Sobrien    /* else */
289359243Sobrien
289459243Sobrien    Cursor = c_prev_word(Cursor, InputBuf, Argument); /* bounds check */
289559243Sobrien
289659243Sobrien    if (VImode)
289759243Sobrien	if (ActionFlag & TCSHOP_DELETE) {
289859243Sobrien	    c_delfini();
289959243Sobrien	    return(CC_REFRESH);
290059243Sobrien	}
290159243Sobrien
290259243Sobrien    RefCursor();
290359243Sobrien    return(CC_NORM);
290459243Sobrien}
290559243Sobrien
290659243Sobrien#if defined(DSPMBYTE) /* BY TAGA Nayuta VERY THANKS */
290759243Sobrien/*ARGSUSED*/
290859243Sobrienstatic void
290959243Sobriene_charfwd_mbyte(argument)
291059243Sobrien     int argument;
291159243Sobrien{
291259243Sobrien    if (!_enable_mbdisp)
291359243Sobrien	Cursor += argument;
291459243Sobrien    else
291559243Sobrien	while (0 < argument && Cursor < LastChar) {
291659243Sobrien	    if (Cursor + 1 != LastChar &&
291759243Sobrien		Ismbyte1(*Cursor) && Ismbyte2(*(Cursor + 1))) {
291859243Sobrien		Cursor++;
291959243Sobrien	    }
292059243Sobrien	    Cursor++;
292159243Sobrien	    argument--;
292259243Sobrien	}
292359243Sobrien}
292459243Sobrien#endif
292559243Sobrien
292659243Sobrien/*ARGSUSED*/
292759243SobrienCCRETVAL
292859243Sobriene_charfwd(c)
292959243Sobrien    int c;
293059243Sobrien{
293159243Sobrien    USE(c);
293259243Sobrien    if (Cursor < LastChar) {
293359243Sobrien#if defined(DSPMBYTE) /* BY TAGA Nayuta VERY THANKS */
293459243Sobrien	e_charfwd_mbyte(Argument);
293559243Sobrien#else
293659243Sobrien	Cursor += Argument;
293759243Sobrien#endif
293859243Sobrien	if (Cursor > LastChar)
293959243Sobrien	    Cursor = LastChar;
294059243Sobrien
294159243Sobrien	if (VImode)
294259243Sobrien	    if (ActionFlag & TCSHOP_DELETE) {
294359243Sobrien		c_delfini();
294459243Sobrien		return(CC_REFRESH);
294559243Sobrien	    }
294659243Sobrien
294759243Sobrien	RefCursor();
294859243Sobrien	return(CC_NORM);
294959243Sobrien    }
295059243Sobrien    else {
295159243Sobrien	return(CC_ERROR);
295259243Sobrien    }
295359243Sobrien}
295459243Sobrien
295559243Sobrien/*ARGSUSED*/
295659243SobrienCCRETVAL
295759243Sobriene_wordfwd(c)
295859243Sobrien    int c;
295959243Sobrien{
296059243Sobrien    USE(c);
296159243Sobrien    if (Cursor == LastChar)
296259243Sobrien	return(CC_ERROR);
296359243Sobrien    /* else */
296459243Sobrien
296559243Sobrien    Cursor = c_next_word(Cursor, LastChar, Argument);
296659243Sobrien
296759243Sobrien    if (VImode)
296859243Sobrien	if (ActionFlag & TCSHOP_DELETE) {
296959243Sobrien	    c_delfini();
297059243Sobrien	    return(CC_REFRESH);
297159243Sobrien	}
297259243Sobrien
297359243Sobrien    RefCursor();
297459243Sobrien    return(CC_NORM);
297559243Sobrien}
297659243Sobrien
297759243Sobrien/*ARGSUSED*/
297859243SobrienCCRETVAL
297959243Sobrienv_wordfwd(c)
298059243Sobrien    int c;
298159243Sobrien{
298259243Sobrien    USE(c);
298359243Sobrien    if (Cursor == LastChar)
298459243Sobrien	return(CC_ERROR);
298559243Sobrien    /* else */
298659243Sobrien
298759243Sobrien    Cursor = c_nexword(Cursor, LastChar, Argument);
298859243Sobrien
298959243Sobrien    if (VImode)
299059243Sobrien	if (ActionFlag & TCSHOP_DELETE) {
299159243Sobrien	    c_delfini();
299259243Sobrien	    return(CC_REFRESH);
299359243Sobrien	}
299459243Sobrien
299559243Sobrien    RefCursor();
299659243Sobrien    return(CC_NORM);
299759243Sobrien}
299859243Sobrien
299959243Sobrien/*ARGSUSED*/
300059243SobrienCCRETVAL
300159243Sobrienv_wordbegnext(c)
300259243Sobrien    int c;
300359243Sobrien{
300459243Sobrien    USE(c);
300559243Sobrien    if (Cursor == LastChar)
300659243Sobrien	return(CC_ERROR);
300759243Sobrien    /* else */
300859243Sobrien
300959243Sobrien    Cursor = c_next_word(Cursor, LastChar, Argument);
301059243Sobrien    if (Cursor < LastChar)
301159243Sobrien	Cursor++;
301259243Sobrien
301359243Sobrien    if (VImode)
301459243Sobrien	if (ActionFlag & TCSHOP_DELETE) {
301559243Sobrien	    c_delfini();
301659243Sobrien	    return(CC_REFRESH);
301759243Sobrien	}
301859243Sobrien
301959243Sobrien    RefCursor();
302059243Sobrien    return(CC_NORM);
302159243Sobrien}
302259243Sobrien
302359243Sobrien/*ARGSUSED*/
302459243Sobrienstatic CCRETVAL
302559243Sobrienv_repeat_srch(c)
302659243Sobrien    int c;
302759243Sobrien{
302859243Sobrien    CCRETVAL rv = CC_ERROR;
302959243Sobrien#ifdef SDEBUG
303059243Sobrien    xprintf("dir %d patlen %d patbuf %S\n",
303159243Sobrien	    c, patlen, patbuf);
303259243Sobrien#endif
303359243Sobrien
303459243Sobrien    LastCmd = (KEYCMD) c;  /* Hack to stop c_hsetpat */
303559243Sobrien    LastChar = InputBuf;
303659243Sobrien    switch (c) {
303759243Sobrien    case F_DOWN_SEARCH_HIST:
303859243Sobrien	rv = e_down_search_hist(0);
303959243Sobrien	break;
304059243Sobrien    case F_UP_SEARCH_HIST:
304159243Sobrien	rv = e_up_search_hist(0);
304259243Sobrien	break;
304359243Sobrien    default:
304459243Sobrien	break;
304559243Sobrien    }
304659243Sobrien    return rv;
304759243Sobrien}
304859243Sobrien
304959243Sobrienstatic CCRETVAL
305059243Sobrienv_csearch_back(ch, count, tflag)
305159243Sobrien    int ch, count, tflag;
305259243Sobrien{
305359243Sobrien    Char *cp;
305459243Sobrien
305559243Sobrien    cp = Cursor;
305659243Sobrien    while (count--) {
305759243Sobrien	if (*cp == ch)
305859243Sobrien	    cp--;
305959243Sobrien	while (cp > InputBuf && *cp != ch)
306059243Sobrien	    cp--;
306159243Sobrien    }
306259243Sobrien
306359243Sobrien    if (cp < InputBuf || (cp == InputBuf && *cp != ch))
306459243Sobrien	return(CC_ERROR);
306559243Sobrien
306659243Sobrien    if (*cp == ch && tflag)
306759243Sobrien	cp++;
306859243Sobrien
306959243Sobrien    Cursor = cp;
307059243Sobrien
307159243Sobrien    if (ActionFlag & TCSHOP_DELETE) {
307259243Sobrien	Cursor++;
307359243Sobrien	c_delfini();
307459243Sobrien	return(CC_REFRESH);
307559243Sobrien    }
307659243Sobrien
307759243Sobrien    RefCursor();
307859243Sobrien    return(CC_NORM);
307959243Sobrien}
308059243Sobrien
308159243Sobrienstatic CCRETVAL
308259243Sobrienv_csearch_fwd(ch, count, tflag)
308359243Sobrien    int ch, count, tflag;
308459243Sobrien{
308559243Sobrien    Char *cp;
308659243Sobrien
308759243Sobrien    cp = Cursor;
308859243Sobrien    while (count--) {
308959243Sobrien	if(*cp == ch)
309059243Sobrien	    cp++;
309159243Sobrien	while (cp < LastChar && *cp != ch)
309259243Sobrien	    cp++;
309359243Sobrien    }
309459243Sobrien
309559243Sobrien    if (cp >= LastChar)
309659243Sobrien	return(CC_ERROR);
309759243Sobrien
309859243Sobrien    if (*cp == ch && tflag)
309959243Sobrien	cp--;
310059243Sobrien
310159243Sobrien    Cursor = cp;
310259243Sobrien
310359243Sobrien    if (ActionFlag & TCSHOP_DELETE) {
310459243Sobrien	Cursor++;
310559243Sobrien	c_delfini();
310659243Sobrien	return(CC_REFRESH);
310759243Sobrien    }
310859243Sobrien    RefCursor();
310959243Sobrien    return(CC_NORM);
311059243Sobrien}
311159243Sobrien
311259243Sobrien/*ARGSUSED*/
311359243Sobrienstatic CCRETVAL
311459243Sobrienv_action(c)
311559243Sobrien    int c;
311659243Sobrien{
311783098Smp    Char *cp, *kp;
311859243Sobrien
311959243Sobrien    if (ActionFlag == TCSHOP_DELETE) {
312059243Sobrien	ActionFlag = TCSHOP_NOP;
312159243Sobrien	ActionPos = 0;
312259243Sobrien
312359243Sobrien	UndoSize = 0;
312459243Sobrien	kp = UndoBuf;
312559243Sobrien	for (cp = InputBuf; cp < LastChar; cp++) {
312659243Sobrien	    *kp++ = *cp;
312759243Sobrien	    UndoSize++;
312859243Sobrien	}
312959243Sobrien
313059243Sobrien	UndoAction = TCSHOP_INSERT;
313159243Sobrien	UndoPtr  = InputBuf;
313259243Sobrien	LastChar = InputBuf;
313359243Sobrien	Cursor   = InputBuf;
313459243Sobrien	if (c & TCSHOP_INSERT)
313559243Sobrien	    c_alternativ_key_map(0);
313659243Sobrien
313759243Sobrien	return(CC_REFRESH);
313859243Sobrien    }
313959243Sobrien#ifdef notdef
314059243Sobrien    else if (ActionFlag == TCSHOP_NOP) {
314159243Sobrien#endif
314259243Sobrien	ActionPos = Cursor;
314359243Sobrien	ActionFlag = c;
314459243Sobrien	return(CC_ARGHACK);  /* Do NOT clear out argument */
314559243Sobrien#ifdef notdef
314659243Sobrien    }
314759243Sobrien    else {
314859243Sobrien	ActionFlag = 0;
314959243Sobrien	ActionPos = 0;
315059243Sobrien	return(CC_ERROR);
315159243Sobrien    }
315259243Sobrien#endif
315359243Sobrien}
315459243Sobrien
315559243Sobrien#ifdef COMMENT
315659243Sobrien/* by: Brian Allison <uiucdcs!convex!allison@RUTGERS.EDU> */
315759243Sobrienstatic void
315859243Sobrienc_get_word(begin, end)
315959243Sobrien    Char  **begin;
316059243Sobrien    Char  **end;
316159243Sobrien{
316259243Sobrien    Char   *cp;
316359243Sobrien
316459243Sobrien    cp = &Cursor[0];
316559243Sobrien    while (Argument--) {
316659243Sobrien	while ((cp <= LastChar) && (isword(*cp)))
316759243Sobrien	    cp++;
316859243Sobrien	*end = --cp;
316959243Sobrien	while ((cp >= InputBuf) && (isword(*cp)))
317059243Sobrien	    cp--;
317159243Sobrien	*begin = ++cp;
317259243Sobrien    }
317359243Sobrien}
317459243Sobrien#endif /* COMMENT */
317559243Sobrien
317659243Sobrien/*ARGSUSED*/
317759243SobrienCCRETVAL
317859243Sobriene_uppercase(c)
317959243Sobrien    int c;
318059243Sobrien{
318159243Sobrien    Char   *cp, *end;
318259243Sobrien
318359243Sobrien    USE(c);
318459243Sobrien    end = c_next_word(Cursor, LastChar, Argument);
318559243Sobrien
318659243Sobrien    for (cp = Cursor; cp < end; cp++)	/* PWP: was cp=begin */
318759243Sobrien	if (Islower(*cp))
318859243Sobrien	    *cp = Toupper(*cp);
318959243Sobrien
319059243Sobrien    Cursor = end;
319159243Sobrien    if (Cursor > LastChar)
319259243Sobrien	Cursor = LastChar;
319359243Sobrien    return(CC_REFRESH);
319459243Sobrien}
319559243Sobrien
319659243Sobrien
319759243Sobrien/*ARGSUSED*/
319859243SobrienCCRETVAL
319959243Sobriene_capitolcase(c)
320059243Sobrien    int c;
320159243Sobrien{
320259243Sobrien    Char   *cp, *end;
320359243Sobrien
320459243Sobrien    USE(c);
320559243Sobrien    end = c_next_word(Cursor, LastChar, Argument);
320659243Sobrien
320759243Sobrien    cp = Cursor;
320859243Sobrien    for (; cp < end; cp++) {
320959243Sobrien	if (Isalpha(*cp)) {
321059243Sobrien	    if (Islower(*cp))
321159243Sobrien		*cp = Toupper(*cp);
321259243Sobrien	    cp++;
321359243Sobrien	    break;
321459243Sobrien	}
321559243Sobrien    }
321659243Sobrien    for (; cp < end; cp++)
321759243Sobrien	if (Isupper(*cp))
321859243Sobrien	    *cp = Tolower(*cp);
321959243Sobrien
322059243Sobrien    Cursor = end;
322159243Sobrien    if (Cursor > LastChar)
322259243Sobrien	Cursor = LastChar;
322359243Sobrien    return(CC_REFRESH);
322459243Sobrien}
322559243Sobrien
322659243Sobrien/*ARGSUSED*/
322759243SobrienCCRETVAL
322859243Sobriene_lowercase(c)
322959243Sobrien    int c;
323059243Sobrien{
323159243Sobrien    Char   *cp, *end;
323259243Sobrien
323359243Sobrien    USE(c);
323459243Sobrien    end = c_next_word(Cursor, LastChar, Argument);
323559243Sobrien
323659243Sobrien    for (cp = Cursor; cp < end; cp++)
323759243Sobrien	if (Isupper(*cp))
323859243Sobrien	    *cp = Tolower(*cp);
323959243Sobrien
324059243Sobrien    Cursor = end;
324159243Sobrien    if (Cursor > LastChar)
324259243Sobrien	Cursor = LastChar;
324359243Sobrien    return(CC_REFRESH);
324459243Sobrien}
324559243Sobrien
324659243Sobrien
324759243Sobrien/*ARGSUSED*/
324859243SobrienCCRETVAL
324959243Sobriene_set_mark(c)
325059243Sobrien    int c;
325159243Sobrien{
325259243Sobrien    USE(c);
325359243Sobrien    Mark = Cursor;
325459243Sobrien    return(CC_NORM);
325559243Sobrien}
325659243Sobrien
325759243Sobrien/*ARGSUSED*/
325859243SobrienCCRETVAL
325959243Sobriene_exchange_mark(c)
326059243Sobrien    int c;
326159243Sobrien{
326283098Smp    Char *cp;
326359243Sobrien
326459243Sobrien    USE(c);
326559243Sobrien    cp = Cursor;
326659243Sobrien    Cursor = Mark;
326759243Sobrien    Mark = cp;
326859243Sobrien    RefCursor();
326959243Sobrien    return(CC_NORM);
327059243Sobrien}
327159243Sobrien
327259243Sobrien/*ARGSUSED*/
327359243SobrienCCRETVAL
327459243Sobriene_argfour(c)
327559243Sobrien    int c;
327659243Sobrien{				/* multiply current argument by 4 */
327759243Sobrien    USE(c);
327859243Sobrien    if (Argument > 1000000)
327959243Sobrien	return CC_ERROR;
328059243Sobrien    DoingArg = 1;
328159243Sobrien    Argument *= 4;
328259243Sobrien    return(CC_ARGHACK);
328359243Sobrien}
328459243Sobrien
328559243Sobrien/*ARGSUSED*/
328659243SobrienCCRETVAL
328759243Sobriene_quote(c)
328859243Sobrien    int c;
328959243Sobrien{
329059243Sobrien    Char    ch;
329159243Sobrien    int     num;
329259243Sobrien
329359243Sobrien    USE(c);
329459243Sobrien    QuoteModeOn();
329559243Sobrien    num = GetNextChar(&ch);
329659243Sobrien    QuoteModeOff();
329759243Sobrien    if (num == 1)
329859243Sobrien	return e_insert(ch);
329959243Sobrien    else
330059243Sobrien	return e_send_eof(0);
330159243Sobrien}
330259243Sobrien
330359243Sobrien/*ARGSUSED*/
330459243SobrienCCRETVAL
330559243Sobriene_metanext(c)
330659243Sobrien    int c;
330759243Sobrien{
330859243Sobrien    USE(c);
330959243Sobrien    MetaNext = 1;
331059243Sobrien    return(CC_ARGHACK);	/* preserve argument */
331159243Sobrien}
331259243Sobrien
331359243Sobrien#ifdef notdef
331459243Sobrien/*ARGSUSED*/
331559243SobrienCCRETVAL
331659243Sobriene_extendnext(c)
331759243Sobrien    int c;
331859243Sobrien{
331959243Sobrien    CurrentKeyMap = CcAltMap;
332059243Sobrien    return(CC_ARGHACK);	/* preserve argument */
332159243Sobrien}
332259243Sobrien
332359243Sobrien#endif
332459243Sobrien
332559243Sobrien/*ARGSUSED*/
332659243SobrienCCRETVAL
332759243Sobrienv_insbeg(c)
332859243Sobrien    int c;
332959243Sobrien{				/* move to beginning of line and start vi
333059243Sobrien				 * insert mode */
333159243Sobrien    USE(c);
333259243Sobrien    Cursor = InputBuf;
333359243Sobrien    InsertPos = Cursor;
333459243Sobrien
333559243Sobrien    UndoPtr  = Cursor;
333659243Sobrien    UndoAction = TCSHOP_DELETE;
333759243Sobrien
333859243Sobrien    RefCursor();		/* move the cursor */
333959243Sobrien    c_alternativ_key_map(0);
334059243Sobrien    return(CC_NORM);
334159243Sobrien}
334259243Sobrien
334359243Sobrien/*ARGSUSED*/
334459243SobrienCCRETVAL
334559243Sobrienv_replone(c)
334659243Sobrien    int c;
334759243Sobrien{				/* vi mode overwrite one character */
334859243Sobrien    USE(c);
334959243Sobrien    c_alternativ_key_map(0);
335059243Sobrien    inputmode = MODE_REPLACE_1;
335159243Sobrien    UndoAction = TCSHOP_CHANGE;	/* Set Up for VI undo command */
335259243Sobrien    UndoPtr = Cursor;
335359243Sobrien    UndoSize = 0;
335459243Sobrien    return(CC_NORM);
335559243Sobrien}
335659243Sobrien
335759243Sobrien/*ARGSUSED*/
335859243SobrienCCRETVAL
335959243Sobrienv_replmode(c)
336059243Sobrien    int c;
336159243Sobrien{				/* vi mode start overwriting */
336259243Sobrien    USE(c);
336359243Sobrien    c_alternativ_key_map(0);
336459243Sobrien    inputmode = MODE_REPLACE;
336559243Sobrien    UndoAction = TCSHOP_CHANGE;	/* Set Up for VI undo command */
336659243Sobrien    UndoPtr = Cursor;
336759243Sobrien    UndoSize = 0;
336859243Sobrien    return(CC_NORM);
336959243Sobrien}
337059243Sobrien
337159243Sobrien/*ARGSUSED*/
337259243SobrienCCRETVAL
337359243Sobrienv_substchar(c)
337459243Sobrien    int c;
337559243Sobrien{				/* vi mode substitute for one char */
337659243Sobrien    USE(c);
337759243Sobrien    c_delafter(Argument);
337859243Sobrien    c_alternativ_key_map(0);
337959243Sobrien    return(CC_REFRESH);
338059243Sobrien}
338159243Sobrien
338259243Sobrien/*ARGSUSED*/
338359243SobrienCCRETVAL
338459243Sobrienv_substline(c)
338559243Sobrien    int c;
338659243Sobrien{				/* vi mode replace whole line */
338759243Sobrien    USE(c);
338859243Sobrien    (void) e_killall(0);
338959243Sobrien    c_alternativ_key_map(0);
339059243Sobrien    return(CC_REFRESH);
339159243Sobrien}
339259243Sobrien
339359243Sobrien/*ARGSUSED*/
339459243SobrienCCRETVAL
339559243Sobrienv_chgtoend(c)
339659243Sobrien    int c;
339759243Sobrien{				/* vi mode change to end of line */
339859243Sobrien    USE(c);
339959243Sobrien    (void) e_killend(0);
340059243Sobrien    c_alternativ_key_map(0);
340159243Sobrien    return(CC_REFRESH);
340259243Sobrien}
340359243Sobrien
340459243Sobrien/*ARGSUSED*/
340559243SobrienCCRETVAL
340659243Sobrienv_insert(c)
340759243Sobrien    int c;
340859243Sobrien{				/* vi mode start inserting */
340959243Sobrien    USE(c);
341059243Sobrien    c_alternativ_key_map(0);
341159243Sobrien
341259243Sobrien    InsertPos = Cursor;
341359243Sobrien    UndoPtr = Cursor;
341459243Sobrien    UndoAction = TCSHOP_DELETE;
341559243Sobrien
341659243Sobrien    return(CC_NORM);
341759243Sobrien}
341859243Sobrien
341959243Sobrien/*ARGSUSED*/
342059243SobrienCCRETVAL
342159243Sobrienv_add(c)
342259243Sobrien    int c;
342359243Sobrien{				/* vi mode start adding */
342459243Sobrien    USE(c);
342559243Sobrien    c_alternativ_key_map(0);
342659243Sobrien    if (Cursor < LastChar)
342759243Sobrien    {
342859243Sobrien	Cursor++;
342959243Sobrien	if (Cursor > LastChar)
343059243Sobrien	    Cursor = LastChar;
343159243Sobrien	RefCursor();
343259243Sobrien    }
343359243Sobrien
343459243Sobrien    InsertPos = Cursor;
343559243Sobrien    UndoPtr = Cursor;
343659243Sobrien    UndoAction = TCSHOP_DELETE;
343759243Sobrien
343859243Sobrien    return(CC_NORM);
343959243Sobrien}
344059243Sobrien
344159243Sobrien/*ARGSUSED*/
344259243SobrienCCRETVAL
344359243Sobrienv_addend(c)
344459243Sobrien    int c;
344559243Sobrien{				/* vi mode to add at end of line */
344659243Sobrien    USE(c);
344759243Sobrien    c_alternativ_key_map(0);
344859243Sobrien    Cursor = LastChar;
344959243Sobrien
345059243Sobrien    InsertPos = LastChar;	/* Mark where insertion begins */
345159243Sobrien    UndoPtr = LastChar;
345259243Sobrien    UndoAction = TCSHOP_DELETE;
345359243Sobrien
345459243Sobrien    RefCursor();
345559243Sobrien    return(CC_NORM);
345659243Sobrien}
345759243Sobrien
345859243Sobrien/*ARGSUSED*/
345959243SobrienCCRETVAL
346059243Sobrienv_change_case(cc)
346159243Sobrien    int cc;
346259243Sobrien{
346359243Sobrien    char    c;
346459243Sobrien
346559243Sobrien    USE(cc);
346659243Sobrien    if (Cursor < LastChar) {
346769408Sache#ifndef WINNT_NATIVE
346859243Sobrien	c = *Cursor;
346959243Sobrien#else
347059243Sobrien	c = CHAR & *Cursor;
347169408Sache#endif /* WINNT_NATIVE */
347259243Sobrien	if (Isupper(c))
347359243Sobrien	    *Cursor++ = Tolower(c);
347459243Sobrien	else if (Islower(c))
347559243Sobrien	    *Cursor++ = Toupper(c);
347659243Sobrien	else
347759243Sobrien	    Cursor++;
347859243Sobrien	RefPlusOne();		/* fast refresh for one char */
347959243Sobrien	return(CC_NORM);
348059243Sobrien    }
348159243Sobrien    return(CC_ERROR);
348259243Sobrien}
348359243Sobrien
348459243Sobrien/*ARGSUSED*/
348559243SobrienCCRETVAL
348659243Sobriene_expand(c)
348759243Sobrien    int c;
348859243Sobrien{
348983098Smp    Char *p;
349059243Sobrien    extern bool justpr;
349159243Sobrien
349259243Sobrien    USE(c);
349359243Sobrien    for (p = InputBuf; Isspace(*p); p++)
349459243Sobrien	continue;
349559243Sobrien    if (p == LastChar)
349659243Sobrien	return(CC_ERROR);
349759243Sobrien
349859243Sobrien    justpr++;
349959243Sobrien    Expand++;
350059243Sobrien    return(e_newline(0));
350159243Sobrien}
350259243Sobrien
350359243Sobrien/*ARGSUSED*/
350459243SobrienCCRETVAL
350559243Sobriene_startover(c)
350659243Sobrien    int c;
350759243Sobrien{				/* erase all of current line, start again */
350859243Sobrien    USE(c);
350959243Sobrien    ResetInLine(0);		/* reset the input pointers */
351059243Sobrien    return(CC_REFRESH);
351159243Sobrien}
351259243Sobrien
351359243Sobrien/*ARGSUSED*/
351459243SobrienCCRETVAL
351559243Sobriene_redisp(c)
351659243Sobrien    int c;
351759243Sobrien{
351859243Sobrien    USE(c);
351959243Sobrien    ClearLines();
352059243Sobrien    ClearDisp();
352159243Sobrien    return(CC_REFRESH);
352259243Sobrien}
352359243Sobrien
352459243Sobrien/*ARGSUSED*/
352559243SobrienCCRETVAL
352659243Sobriene_cleardisp(c)
352759243Sobrien    int c;
352859243Sobrien{
352959243Sobrien    USE(c);
353059243Sobrien    ClearScreen();		/* clear the whole real screen */
353159243Sobrien    ClearDisp();		/* reset everything */
353259243Sobrien    return(CC_REFRESH);
353359243Sobrien}
353459243Sobrien
353559243Sobrien/*ARGSUSED*/
353659243SobrienCCRETVAL
353759243Sobriene_tty_int(c)
353859243Sobrien    int c;
353959243Sobrien{
354059243Sobrien    USE(c);
354169408Sache#if defined(_MINIX) || defined(WINNT_NATIVE)
354259243Sobrien    /* SAK PATCH: erase all of current line, start again */
354359243Sobrien    ResetInLine(0);		/* reset the input pointers */
354459243Sobrien    xputchar('\n');
354559243Sobrien    ClearDisp();
354659243Sobrien    return (CC_REFRESH);
354769408Sache#else /* !_MINIX && !WINNT_NATIVE */
354859243Sobrien    /* do no editing */
354959243Sobrien    return (CC_NORM);
355069408Sache#endif /* _MINIX || WINNT_NATIVE */
355159243Sobrien}
355259243Sobrien
355359243Sobrien/*
355459243Sobrien * From: ghazi@cesl.rutgers.edu (Kaveh R. Ghazi)
355559243Sobrien * Function to send a character back to the input stream in cooked
355659243Sobrien * mode. Only works if we have TIOCSTI
355759243Sobrien */
355859243Sobrien/*ARGSUSED*/
355959243SobrienCCRETVAL
356059243Sobriene_stuff_char(c)
356159243Sobrien     int c;
356259243Sobrien{
356359243Sobrien#ifdef TIOCSTI
356459243Sobrien     extern int Tty_raw_mode;
356559243Sobrien     int was_raw = Tty_raw_mode;
356659243Sobrien     char ch = (char) c;
356759243Sobrien
356859243Sobrien     if (was_raw)
356959243Sobrien         (void) Cookedmode();
357059243Sobrien
357159243Sobrien     (void) write(SHIN, "\n", 1);
357259243Sobrien     (void) ioctl(SHIN, TIOCSTI, (ioctl_t) &ch);
357359243Sobrien
357459243Sobrien     if (was_raw)
357559243Sobrien         (void) Rawmode();
357659243Sobrien     return(e_redisp(c));
357759243Sobrien#else /* !TIOCSTI */
357859243Sobrien     return(CC_ERROR);
357959243Sobrien#endif /* !TIOCSTI */
358059243Sobrien}
358159243Sobrien
358259243Sobrien/*ARGSUSED*/
358359243SobrienCCRETVAL
358459243Sobriene_insovr(c)
358559243Sobrien    int c;
358659243Sobrien{
358759243Sobrien    USE(c);
358859243Sobrien    inputmode = (inputmode == MODE_INSERT ? MODE_REPLACE : MODE_INSERT);
358959243Sobrien    return(CC_NORM);
359059243Sobrien}
359159243Sobrien
359259243Sobrien/*ARGSUSED*/
359359243SobrienCCRETVAL
359459243Sobriene_tty_dsusp(c)
359559243Sobrien    int c;
359659243Sobrien{
359759243Sobrien    USE(c);
359859243Sobrien    /* do no editing */
359959243Sobrien    return(CC_NORM);
360059243Sobrien}
360159243Sobrien
360259243Sobrien/*ARGSUSED*/
360359243SobrienCCRETVAL
360459243Sobriene_tty_flusho(c)
360559243Sobrien    int c;
360659243Sobrien{
360759243Sobrien    USE(c);
360859243Sobrien    /* do no editing */
360959243Sobrien    return(CC_NORM);
361059243Sobrien}
361159243Sobrien
361259243Sobrien/*ARGSUSED*/
361359243SobrienCCRETVAL
361459243Sobriene_tty_quit(c)
361559243Sobrien    int c;
361659243Sobrien{
361759243Sobrien    USE(c);
361859243Sobrien    /* do no editing */
361959243Sobrien    return(CC_NORM);
362059243Sobrien}
362159243Sobrien
362259243Sobrien/*ARGSUSED*/
362359243SobrienCCRETVAL
362459243Sobriene_tty_tsusp(c)
362559243Sobrien    int c;
362659243Sobrien{
362759243Sobrien    USE(c);
362859243Sobrien    /* do no editing */
362959243Sobrien    return(CC_NORM);
363059243Sobrien}
363159243Sobrien
363259243Sobrien/*ARGSUSED*/
363359243SobrienCCRETVAL
363459243Sobriene_tty_stopo(c)
363559243Sobrien    int c;
363659243Sobrien{
363759243Sobrien    USE(c);
363859243Sobrien    /* do no editing */
363959243Sobrien    return(CC_NORM);
364059243Sobrien}
364159243Sobrien
364259243Sobrien/*ARGSUSED*/
364359243SobrienCCRETVAL
364459243Sobriene_expand_history(c)
364559243Sobrien    int c;
364659243Sobrien{
364759243Sobrien    USE(c);
364859243Sobrien    *LastChar = '\0';		/* just in case */
364959243Sobrien    c_substitute();
365059243Sobrien    return(CC_NORM);
365159243Sobrien}
365259243Sobrien
365359243Sobrien/*ARGSUSED*/
365459243SobrienCCRETVAL
365559243Sobriene_magic_space(c)
365659243Sobrien    int c;
365759243Sobrien{
365859243Sobrien    USE(c);
365959243Sobrien    *LastChar = '\0';		/* just in case */
366059243Sobrien    c_substitute();
366159243Sobrien    return(e_insert(' '));
366259243Sobrien}
366359243Sobrien
366459243Sobrien/*ARGSUSED*/
366559243SobrienCCRETVAL
366659243Sobriene_inc_fwd(c)
366759243Sobrien    int c;
366859243Sobrien{
366959243Sobrien    USE(c);
367059243Sobrien    patlen = 0;
367159243Sobrien    return e_inc_search(F_DOWN_SEARCH_HIST);
367259243Sobrien}
367359243Sobrien
367459243Sobrien
367559243Sobrien/*ARGSUSED*/
367659243SobrienCCRETVAL
367759243Sobriene_inc_back(c)
367859243Sobrien    int c;
367959243Sobrien{
368059243Sobrien    USE(c);
368159243Sobrien    patlen = 0;
368259243Sobrien    return e_inc_search(F_UP_SEARCH_HIST);
368359243Sobrien}
368459243Sobrien
368559243Sobrien/*ARGSUSED*/
368659243SobrienCCRETVAL
368759243Sobriene_copyprev(c)
368859243Sobrien    int c;
368959243Sobrien{
369083098Smp    Char *cp, *oldc, *dp;
369159243Sobrien
369259243Sobrien    USE(c);
369359243Sobrien    if (Cursor == InputBuf)
369459243Sobrien	return(CC_ERROR);
369559243Sobrien    /* else */
369659243Sobrien
369759243Sobrien    oldc = Cursor;
369859243Sobrien    /* does a bounds check */
369959243Sobrien    cp = c_prev_word(Cursor, InputBuf, Argument);
370059243Sobrien
370159243Sobrien    c_insert((int)(oldc - cp));
370259243Sobrien    for (dp = oldc; cp < oldc && dp < LastChar; cp++)
370359243Sobrien	*dp++ = *cp;
370459243Sobrien
370559243Sobrien    Cursor = dp;		/* put cursor at end */
370659243Sobrien
370759243Sobrien    return(CC_REFRESH);
370859243Sobrien}
370959243Sobrien
371059243Sobrien/*ARGSUSED*/
371159243SobrienCCRETVAL
371259243Sobriene_tty_starto(c)
371359243Sobrien    int c;
371459243Sobrien{
371559243Sobrien    USE(c);
371659243Sobrien    /* do no editing */
371759243Sobrien    return(CC_NORM);
371859243Sobrien}
371959243Sobrien
372059243Sobrien/*ARGSUSED*/
372159243SobrienCCRETVAL
372259243Sobriene_load_average(c)
372359243Sobrien    int c;
372459243Sobrien{
372559243Sobrien    USE(c);
372659243Sobrien    PastBottom();
372759243Sobrien#ifdef TIOCSTAT
372859243Sobrien    /*
372959243Sobrien     * Here we pass &c to the ioctl because some os's (NetBSD) expect it
373059243Sobrien     * there even if they don't use it. (lukem@netbsd.org)
373159243Sobrien     */
373259243Sobrien    if (ioctl(SHIN, TIOCSTAT, (ioctl_t) &c) < 0)
373359243Sobrien#endif
373459243Sobrien	xprintf(CGETS(5, 1, "Load average unavailable\n"));
373559243Sobrien    return(CC_REFRESH);
373659243Sobrien}
373759243Sobrien
373859243Sobrien/*ARGSUSED*/
373959243SobrienCCRETVAL
374059243Sobrienv_chgmeta(c)
374159243Sobrien    int c;
374259243Sobrien{
374359243Sobrien    USE(c);
374459243Sobrien    /*
374559243Sobrien     * Delete with insert == change: first we delete and then we leave in
374659243Sobrien     * insert mode.
374759243Sobrien     */
374859243Sobrien    return(v_action(TCSHOP_DELETE|TCSHOP_INSERT));
374959243Sobrien}
375059243Sobrien
375159243Sobrien/*ARGSUSED*/
375259243SobrienCCRETVAL
375359243Sobrienv_delmeta(c)
375459243Sobrien    int c;
375559243Sobrien{
375659243Sobrien    USE(c);
375759243Sobrien    return(v_action(TCSHOP_DELETE));
375859243Sobrien}
375959243Sobrien
376059243Sobrien
376159243Sobrien/*ARGSUSED*/
376259243SobrienCCRETVAL
376359243Sobrienv_endword(c)
376459243Sobrien    int c;
376559243Sobrien{
376659243Sobrien    USE(c);
376759243Sobrien    if (Cursor == LastChar)
376859243Sobrien	return(CC_ERROR);
376959243Sobrien    /* else */
377059243Sobrien
377183098Smp    Cursor = c_endword(Cursor, LastChar, Argument, STRshwspace);
377259243Sobrien
377359243Sobrien    if (ActionFlag & TCSHOP_DELETE)
377459243Sobrien    {
377559243Sobrien	Cursor++;
377659243Sobrien	c_delfini();
377759243Sobrien	return(CC_REFRESH);
377859243Sobrien    }
377959243Sobrien
378059243Sobrien    RefCursor();
378159243Sobrien    return(CC_NORM);
378259243Sobrien}
378359243Sobrien
378459243Sobrien/*ARGSUSED*/
378559243SobrienCCRETVAL
378659243Sobrienv_eword(c)
378759243Sobrien    int c;
378859243Sobrien{
378959243Sobrien    USE(c);
379059243Sobrien    if (Cursor == LastChar)
379159243Sobrien	return(CC_ERROR);
379259243Sobrien    /* else */
379359243Sobrien
379459243Sobrien    Cursor = c_eword(Cursor, LastChar, Argument);
379559243Sobrien
379659243Sobrien    if (ActionFlag & TCSHOP_DELETE) {
379759243Sobrien	Cursor++;
379859243Sobrien	c_delfini();
379959243Sobrien	return(CC_REFRESH);
380059243Sobrien    }
380159243Sobrien
380259243Sobrien    RefCursor();
380359243Sobrien    return(CC_NORM);
380459243Sobrien}
380559243Sobrien
380659243Sobrien/*ARGSUSED*/
380759243SobrienCCRETVAL
380859243Sobrienv_char_fwd(c)
380959243Sobrien    int c;
381059243Sobrien{
381159243Sobrien    Char ch;
381259243Sobrien
381359243Sobrien    USE(c);
381459243Sobrien    if (GetNextChar(&ch) != 1)
381559243Sobrien	return e_send_eof(0);
381659243Sobrien
381759243Sobrien    srch_dir = CHAR_FWD;
381859243Sobrien    srch_char = ch;
381959243Sobrien
382059243Sobrien    return v_csearch_fwd(ch, Argument, 0);
382159243Sobrien
382259243Sobrien}
382359243Sobrien
382459243Sobrien/*ARGSUSED*/
382559243SobrienCCRETVAL
382659243Sobrienv_char_back(c)
382759243Sobrien    int c;
382859243Sobrien{
382959243Sobrien    Char ch;
383059243Sobrien
383159243Sobrien    USE(c);
383259243Sobrien    if (GetNextChar(&ch) != 1)
383359243Sobrien	return e_send_eof(0);
383459243Sobrien
383559243Sobrien    srch_dir = CHAR_BACK;
383659243Sobrien    srch_char = ch;
383759243Sobrien
383859243Sobrien    return v_csearch_back(ch, Argument, 0);
383959243Sobrien}
384059243Sobrien
384159243Sobrien/*ARGSUSED*/
384259243SobrienCCRETVAL
384359243Sobrienv_charto_fwd(c)
384459243Sobrien    int c;
384559243Sobrien{
384659243Sobrien    Char ch;
384759243Sobrien
384859243Sobrien    USE(c);
384959243Sobrien    if (GetNextChar(&ch) != 1)
385059243Sobrien	return e_send_eof(0);
385159243Sobrien
385259243Sobrien    return v_csearch_fwd(ch, Argument, 1);
385359243Sobrien
385459243Sobrien}
385559243Sobrien
385659243Sobrien/*ARGSUSED*/
385759243SobrienCCRETVAL
385859243Sobrienv_charto_back(c)
385959243Sobrien    int c;
386059243Sobrien{
386159243Sobrien    Char ch;
386259243Sobrien
386359243Sobrien    USE(c);
386459243Sobrien    if (GetNextChar(&ch) != 1)
386559243Sobrien	return e_send_eof(0);
386659243Sobrien
386759243Sobrien    return v_csearch_back(ch, Argument, 1);
386859243Sobrien}
386959243Sobrien
387059243Sobrien/*ARGSUSED*/
387159243SobrienCCRETVAL
387259243Sobrienv_rchar_fwd(c)
387359243Sobrien    int c;
387459243Sobrien{
387559243Sobrien    USE(c);
387659243Sobrien    if (srch_char == 0)
387759243Sobrien	return CC_ERROR;
387859243Sobrien
387959243Sobrien    return srch_dir == CHAR_FWD ? v_csearch_fwd(srch_char, Argument, 0) :
388059243Sobrien			          v_csearch_back(srch_char, Argument, 0);
388159243Sobrien}
388259243Sobrien
388359243Sobrien/*ARGSUSED*/
388459243SobrienCCRETVAL
388559243Sobrienv_rchar_back(c)
388659243Sobrien    int c;
388759243Sobrien{
388859243Sobrien    USE(c);
388959243Sobrien    if (srch_char == 0)
389059243Sobrien	return CC_ERROR;
389159243Sobrien
389259243Sobrien    return srch_dir == CHAR_BACK ? v_csearch_fwd(srch_char, Argument, 0) :
389359243Sobrien			           v_csearch_back(srch_char, Argument, 0);
389459243Sobrien}
389559243Sobrien
389659243Sobrien/*ARGSUSED*/
389759243SobrienCCRETVAL
389859243Sobrienv_undo(c)
389959243Sobrien    int c;
390059243Sobrien{
390183098Smp    int  loop;
390283098Smp    Char *kp, *cp;
390359243Sobrien    Char temp;
390459243Sobrien    int	 size;
390559243Sobrien
390659243Sobrien    USE(c);
390759243Sobrien    switch (UndoAction) {
390859243Sobrien    case TCSHOP_DELETE|TCSHOP_INSERT:
390959243Sobrien    case TCSHOP_DELETE:
391059243Sobrien	if (UndoSize == 0) return(CC_NORM);
391159243Sobrien	cp = UndoPtr;
391259243Sobrien	kp = UndoBuf;
391359243Sobrien	for (loop=0; loop < UndoSize; loop++)	/* copy the chars */
391459243Sobrien	    *kp++ = *cp++;			/* into UndoBuf   */
391559243Sobrien
391659243Sobrien	for (cp = UndoPtr; cp <= LastChar; cp++)
391759243Sobrien	    *cp = cp[UndoSize];
391859243Sobrien
391959243Sobrien	LastChar -= UndoSize;
392059243Sobrien	Cursor   =  UndoPtr;
392159243Sobrien
392259243Sobrien	UndoAction = TCSHOP_INSERT;
392359243Sobrien	break;
392459243Sobrien
392559243Sobrien    case TCSHOP_INSERT:
392659243Sobrien	if (UndoSize == 0) return(CC_NORM);
392759243Sobrien	cp = UndoPtr;
392859243Sobrien	Cursor = UndoPtr;
392959243Sobrien	kp = UndoBuf;
393059243Sobrien	c_insert(UndoSize);		/* open the space, */
393159243Sobrien	for (loop = 0; loop < UndoSize; loop++)	/* copy the chars */
393259243Sobrien	    *cp++ = *kp++;
393359243Sobrien
393459243Sobrien	UndoAction = TCSHOP_DELETE;
393559243Sobrien	break;
393659243Sobrien
393759243Sobrien    case TCSHOP_CHANGE:
393859243Sobrien	if (UndoSize == 0) return(CC_NORM);
393959243Sobrien	cp = UndoPtr;
394059243Sobrien	Cursor = UndoPtr;
394159243Sobrien	kp = UndoBuf;
394259243Sobrien	size = (int)(Cursor-LastChar); /*  NOT NSL independant */
394359243Sobrien	if (size < UndoSize)
394459243Sobrien	    size = UndoSize;
394559243Sobrien	for(loop = 0; loop < size; loop++) {
394659243Sobrien	    temp = *kp;
394759243Sobrien	    *kp++ = *cp;
394859243Sobrien	    *cp++ = temp;
394959243Sobrien	}
395059243Sobrien	break;
395159243Sobrien
395259243Sobrien    default:
395359243Sobrien	return(CC_ERROR);
395459243Sobrien    }
395559243Sobrien
395659243Sobrien    return(CC_REFRESH);
395759243Sobrien}
395859243Sobrien
395959243Sobrien/*ARGSUSED*/
396059243SobrienCCRETVAL
396159243Sobrienv_ush_meta(c)
396259243Sobrien    int c;
396359243Sobrien{
396459243Sobrien    USE(c);
396559243Sobrien    return v_search(F_UP_SEARCH_HIST);
396659243Sobrien}
396759243Sobrien
396859243Sobrien/*ARGSUSED*/
396959243SobrienCCRETVAL
397059243Sobrienv_dsh_meta(c)
397159243Sobrien    int c;
397259243Sobrien{
397359243Sobrien    USE(c);
397459243Sobrien    return v_search(F_DOWN_SEARCH_HIST);
397559243Sobrien}
397659243Sobrien
397759243Sobrien/*ARGSUSED*/
397859243SobrienCCRETVAL
397959243Sobrienv_rsrch_fwd(c)
398059243Sobrien    int c;
398159243Sobrien{
398259243Sobrien    USE(c);
398359243Sobrien    if (patlen == 0) return(CC_ERROR);
398459243Sobrien    return(v_repeat_srch(searchdir));
398559243Sobrien}
398659243Sobrien
398759243Sobrien/*ARGSUSED*/
398859243SobrienCCRETVAL
398959243Sobrienv_rsrch_back(c)
399059243Sobrien    int c;
399159243Sobrien{
399259243Sobrien    USE(c);
399359243Sobrien    if (patlen == 0) return(CC_ERROR);
399459243Sobrien    return(v_repeat_srch(searchdir == F_UP_SEARCH_HIST ?
399559243Sobrien			 F_DOWN_SEARCH_HIST : F_UP_SEARCH_HIST));
399659243Sobrien}
399759243Sobrien
399869408Sache#ifndef WINNT_NATIVE
399959243Sobrien/* Since ed.defns.h  is generated from ed.defns.c, these empty
400059243Sobrien   functions will keep the F_NUM_FNS consistent
400159243Sobrien */
400259243SobrienCCRETVAL
400359243Sobriene_copy_to_clipboard(c)
400459243Sobrien    int c;
400559243Sobrien{
400659243Sobrien    USE(c);
400759243Sobrien    return CC_ERROR;
400859243Sobrien}
400959243Sobrien
401059243SobrienCCRETVAL
401159243Sobriene_paste_from_clipboard(c)
401259243Sobrien    int c;
401359243Sobrien{
401459243Sobrien    USE(c);
401559243Sobrien    return (CC_ERROR);
401659243Sobrien}
401759243Sobrien
401859243SobrienCCRETVAL
401959243Sobriene_dosify_next(c)
402059243Sobrien    int c;
402159243Sobrien{
402259243Sobrien    USE(c);
402359243Sobrien    return (CC_ERROR);
402459243Sobrien}
402559243SobrienCCRETVAL
402659243Sobriene_dosify_prev(c)
402759243Sobrien    int c;
402859243Sobrien{
402959243Sobrien    USE(c);
403059243Sobrien    return (CC_ERROR);
403159243Sobrien}
403259243SobrienCCRETVAL
403369408Sachee_page_up(c)
403459243Sobrien    int c;
403559243Sobrien{
403659243Sobrien    USE(c);
403769408Sache    return (CC_ERROR);
403859243Sobrien}
403959243SobrienCCRETVAL
404069408Sachee_page_down(c)
404159243Sobrien    int c;
404259243Sobrien{
404359243Sobrien    USE(c);
404469408Sache    return (CC_ERROR);
404559243Sobrien}
404669408Sache#endif /* !WINNT_NATIVE */
404759243Sobrien
404859243Sobrien#ifdef notdef
404959243Sobrienvoid
405059243SobrienMoveCursor(n)			/* move cursor + right - left char */
405159243Sobrien    int     n;
405259243Sobrien{
405359243Sobrien    Cursor = Cursor + n;
405459243Sobrien    if (Cursor < InputBuf)
405559243Sobrien	Cursor = InputBuf;
405659243Sobrien    if (Cursor > LastChar)
405759243Sobrien	Cursor = LastChar;
405859243Sobrien    return;
405959243Sobrien}
406059243Sobrien
406159243SobrienChar *
406259243SobrienGetCursor()
406359243Sobrien{
406459243Sobrien    return(Cursor);
406559243Sobrien}
406659243Sobrien
406759243Sobrienint
406859243SobrienPutCursor(p)
406959243Sobrien    Char   *p;
407059243Sobrien{
407159243Sobrien    if (p < InputBuf || p > LastChar)
407259243Sobrien	return 1;		/* Error */
407359243Sobrien    Cursor = p;
407459243Sobrien    return 0;
407559243Sobrien}
407659243Sobrien#endif
4077