1232633Smp/* $Header: /p/tcsh/cvsroot/tcsh/ed.chared.c,v 3.98 2010/05/08 00:37:39 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. 17100616Smp * 3. Neither the name of the University nor the names of its contributors 1859243Sobrien * may be used to endorse or promote products derived from this software 1959243Sobrien * without specific prior written permission. 2059243Sobrien * 2159243Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2259243Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2359243Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2459243Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2559243Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2659243Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2759243Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2859243Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2959243Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3059243Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3159243Sobrien * SUCH DAMAGE. 3259243Sobrien */ 3359243Sobrien/* 3459243Sobrien Bjorn Knutsson @ Thu Jun 24 19:02:17 1999 3559243Sobrien 3659243Sobrien e_dabbrev_expand() did not do proper completion if quoted spaces were present 3759243Sobrien in the string being completed. Exemple: 3859243Sobrien 3959243Sobrien # echo hello\ world 4059243Sobrien hello world 4159243Sobrien # echo h<press key bound to dabbrev-expande> 4259243Sobrien # echo hello\<cursor> 4359243Sobrien 4459243Sobrien Correct behavior is: 4559243Sobrien # echo h<press key bound to dabbrev-expande> 4659243Sobrien # echo hello\ world<cursor> 4759243Sobrien 4859243Sobrien The same problem occured if spaces were present in a string withing quotation 4959243Sobrien marks. Example: 5059243Sobrien 5159243Sobrien # echo "hello world" 5259243Sobrien hello world 5359243Sobrien # echo "h<press key bound to dabbrev-expande> 5459243Sobrien # echo "hello<cursor> 5559243Sobrien 5659243Sobrien The former problem could be solved with minor modifications of c_preword() 5759243Sobrien and c_endword(). The latter, however, required a significant rewrite of 5859243Sobrien c_preword(), since quoted strings must be parsed from start to end to 5959243Sobrien determine if a given character is inside or outside the quotation marks. 6059243Sobrien 6159243Sobrien Compare the following two strings: 6259243Sobrien 6359243Sobrien # echo \"" 'foo \' bar\" 6459243Sobrien " 'foo \' bar\ 6559243Sobrien # echo '\"" 'foo \' bar\" 6659243Sobrien \"" foo ' bar" 6759243Sobrien 6859243Sobrien The only difference between the two echo lines is in the first character 6959243Sobrien after the echo command. The result is either one or three arguments. 7059243Sobrien 7159243Sobrien */ 7259243Sobrien 7359243Sobrien#include "sh.h" 7459243Sobrien 75232633SmpRCSID("$tcsh: ed.chared.c,v 3.98 2010/05/08 00:37:39 christos Exp $") 7659243Sobrien 7759243Sobrien#include "ed.h" 7859243Sobrien#include "tw.h" 7959243Sobrien#include "ed.defns.h" 8059243Sobrien 8159243Sobrien/* #define SDEBUG */ 8259243Sobrien 8359243Sobrien#define TCSHOP_NOP 0x00 8459243Sobrien#define TCSHOP_DELETE 0x01 8559243Sobrien#define TCSHOP_INSERT 0x02 8659243Sobrien#define TCSHOP_CHANGE 0x04 8759243Sobrien 8859243Sobrien#define CHAR_FWD 0 8959243Sobrien#define CHAR_BACK 1 9059243Sobrien 9159243Sobrien/* 9259243Sobrien * vi word treatment 9359243Sobrien * from: Gert-Jan Vons <vons@cesar.crbca1.sinet.slb.com> 9459243Sobrien */ 9559243Sobrien#define C_CLASS_WHITE 1 9659243Sobrien#define C_CLASS_ALNUM 2 9759243Sobrien#define C_CLASS_OTHER 3 9859243Sobrien 9959243Sobrienstatic Char *InsertPos = InputBuf; /* Where insertion starts */ 10059243Sobrienstatic Char *ActionPos = 0; /* Where action begins */ 10159243Sobrienstatic int ActionFlag = TCSHOP_NOP; /* What delayed action to take */ 10259243Sobrien/* 10359243Sobrien * Word search state 10459243Sobrien */ 10559243Sobrienstatic int searchdir = F_UP_SEARCH_HIST; /* Direction of last search */ 106167465Smpstatic struct Strbuf patbuf; /* = Strbuf_INIT; Search target */ 10759243Sobrien/* 10859243Sobrien * Char search state 10959243Sobrien */ 11059243Sobrienstatic int srch_dir = CHAR_FWD; /* Direction of last search */ 11159243Sobrienstatic Char srch_char = 0; /* Search target */ 11259243Sobrien 11359243Sobrien/* all routines that start with c_ are private to this set of routines */ 114167465Smpstatic void c_alternativ_key_map (int); 115167465Smpvoid c_insert (int); 116167465Smpvoid c_delafter (int); 117167465Smpvoid c_delbefore (int); 118167465Smpstatic int c_to_class (Char); 119167465Smpstatic Char *c_prev_word (Char *, Char *, int); 120167465Smpstatic Char *c_next_word (Char *, Char *, int); 121167465Smpstatic Char *c_number (Char *, int *, int); 122167465Smpstatic Char *c_expand (Char *); 123195609Smpstatic int c_excl (Char *); 124195609Smpstatic int c_substitute (void); 125167465Smpstatic void c_delfini (void); 126167465Smpstatic int c_hmatch (Char *); 127167465Smpstatic void c_hsetpat (void); 12859243Sobrien#ifdef COMMENT 129167465Smpstatic void c_get_word (Char **, Char **); 13059243Sobrien#endif 131167465Smpstatic Char *c_preword (Char *, Char *, int, Char *); 132167465Smpstatic Char *c_nexword (Char *, Char *, int); 133167465Smpstatic Char *c_endword (Char *, Char *, int, Char *); 134167465Smpstatic Char *c_eword (Char *, Char *, int); 135167465Smpstatic void c_push_kill (Char *, Char *); 136167465Smpstatic void c_save_inputbuf (void); 137167465Smpstatic CCRETVAL c_search_line (Char *, int); 138167465Smpstatic CCRETVAL v_repeat_srch (int); 139167465Smpstatic CCRETVAL e_inc_search (int); 140167465Smp#ifdef notyet 141167465Smpstatic CCRETVAL e_insert_str (Char *); 142167465Smp#endif 143167465Smpstatic CCRETVAL v_search (int); 144167465Smpstatic CCRETVAL v_csearch_fwd (Char, int, int); 145167465Smpstatic CCRETVAL v_action (int); 146167465Smpstatic CCRETVAL v_csearch_back (Char, int, int); 14759243Sobrien 14859243Sobrienstatic void 149167465Smpc_alternativ_key_map(int state) 15059243Sobrien{ 15159243Sobrien switch (state) { 15259243Sobrien case 0: 15359243Sobrien CurrentKeyMap = CcKeyMap; 15459243Sobrien break; 15559243Sobrien case 1: 15659243Sobrien CurrentKeyMap = CcAltMap; 15759243Sobrien break; 15859243Sobrien default: 15959243Sobrien return; 16059243Sobrien } 16159243Sobrien 16259243Sobrien AltKeyMap = (Char) state; 16359243Sobrien} 16459243Sobrien 16583098Smpvoid 166167465Smpc_insert(int num) 16759243Sobrien{ 16883098Smp Char *cp; 16959243Sobrien 17059243Sobrien if (LastChar + num >= InputLim) 17159243Sobrien return; /* can't go past end of buffer */ 17259243Sobrien 17359243Sobrien if (Cursor < LastChar) { /* if I must move chars */ 17459243Sobrien for (cp = LastChar; cp >= Cursor; cp--) 17559243Sobrien cp[num] = *cp; 176145479Smp if (Mark && Mark > Cursor) 177145479Smp Mark += num; 17859243Sobrien } 17959243Sobrien LastChar += num; 18059243Sobrien} 18159243Sobrien 18269408Sachevoid 183167465Smpc_delafter(int num) 18459243Sobrien{ 18583098Smp Char *cp, *kp = NULL; 18659243Sobrien 18759243Sobrien if (num > LastChar - Cursor) 18859243Sobrien num = (int) (LastChar - Cursor); /* bounds check */ 18959243Sobrien 19059243Sobrien if (num > 0) { /* if I can delete anything */ 19159243Sobrien if (VImode) { 19259243Sobrien kp = UndoBuf; /* Set Up for VI undo command */ 19359243Sobrien UndoAction = TCSHOP_INSERT; 19459243Sobrien UndoSize = num; 19559243Sobrien UndoPtr = Cursor; 19659243Sobrien for (cp = Cursor; cp <= LastChar; cp++) { 19759243Sobrien *kp++ = *cp; /* Save deleted chars into undobuf */ 19859243Sobrien *cp = cp[num]; 19959243Sobrien } 20059243Sobrien } 20159243Sobrien else 202145479Smp for (cp = Cursor; cp + num <= LastChar; cp++) 20359243Sobrien *cp = cp[num]; 20459243Sobrien LastChar -= num; 205167465Smp /* Mark was within the range of the deleted word? */ 206167465Smp if (Mark && Mark > Cursor && Mark <= Cursor+num) 207167465Smp Mark = Cursor; 208167465Smp /* Mark after the deleted word? */ 209167465Smp else if (Mark && Mark > Cursor) 210145479Smp Mark -= num; 21159243Sobrien } 21259243Sobrien#ifdef notdef 21359243Sobrien else { 21459243Sobrien /* 21559243Sobrien * XXX: We don't want to do that. In emacs mode overwrite should be 21659243Sobrien * sticky. I am not sure how that affects vi mode 21759243Sobrien */ 21859243Sobrien inputmode = MODE_INSERT; 21959243Sobrien } 22059243Sobrien#endif /* notdef */ 22159243Sobrien} 22259243Sobrien 22369408Sachevoid 224167465Smpc_delbefore(int num) /* delete before dot, with bounds checking */ 22559243Sobrien{ 22683098Smp Char *cp, *kp = NULL; 22759243Sobrien 22859243Sobrien if (num > Cursor - InputBuf) 22959243Sobrien num = (int) (Cursor - InputBuf); /* bounds check */ 23059243Sobrien 23159243Sobrien if (num > 0) { /* if I can delete anything */ 23259243Sobrien if (VImode) { 23359243Sobrien kp = UndoBuf; /* Set Up for VI undo command */ 23459243Sobrien UndoAction = TCSHOP_INSERT; 23559243Sobrien UndoSize = num; 23659243Sobrien UndoPtr = Cursor - num; 23759243Sobrien for (cp = Cursor - num; cp <= LastChar; cp++) { 23859243Sobrien *kp++ = *cp; 23959243Sobrien *cp = cp[num]; 24059243Sobrien } 24159243Sobrien } 24259243Sobrien else 243145479Smp for (cp = Cursor - num; cp + num <= LastChar; cp++) 24459243Sobrien *cp = cp[num]; 24559243Sobrien LastChar -= num; 246145479Smp Cursor -= num; 247167465Smp /* Mark was within the range of the deleted word? */ 248167465Smp if (Mark && Mark > Cursor && Mark <= Cursor+num) 249167465Smp Mark = Cursor; 250167465Smp /* Mark after the deleted word? */ 251167465Smp else if (Mark && Mark > Cursor) 252145479Smp Mark -= num; 25359243Sobrien } 25459243Sobrien} 25559243Sobrien 25659243Sobrienstatic Char * 257167465Smpc_preword(Char *p, Char *low, int n, Char *delim) 25859243Sobrien{ 25959243Sobrien while (n--) { 26083098Smp Char *prev = low; 26183098Smp Char *new; 26259243Sobrien 26383098Smp while (prev < p) { /* Skip initial non-word chars */ 26483098Smp if (!Strchr(delim, *prev) || *(prev-1) == (Char)'\\') 26559243Sobrien break; 26659243Sobrien prev++; 26759243Sobrien } 26859243Sobrien 26959243Sobrien new = prev; 27059243Sobrien 27159243Sobrien while (new < p) { 27259243Sobrien prev = new; 27383098Smp new = c_endword(prev-1, p, 1, delim); /* Skip to next non-word char */ 27459243Sobrien new++; /* Step away from end of word */ 27583098Smp while (new <= p) { /* Skip trailing non-word chars */ 27683098Smp if (!Strchr(delim, *new) || *(new-1) == (Char)'\\') 27759243Sobrien break; 27859243Sobrien new++; 27959243Sobrien } 28059243Sobrien } 28159243Sobrien 28259243Sobrien p = prev; /* Set to previous word start */ 28359243Sobrien 28459243Sobrien } 28559243Sobrien if (p < low) 28659243Sobrien p = low; 28759243Sobrien return (p); 28859243Sobrien} 28959243Sobrien 29059243Sobrien/* 29159243Sobrien * c_to_class() returns the class of the given character. 29259243Sobrien * 29359243Sobrien * This is used to make the c_prev_word() and c_next_word() functions 29459243Sobrien * work like vi's, which classify characters. A word is a sequence of 29559243Sobrien * characters belonging to the same class, classes being defined as 29659243Sobrien * follows: 29759243Sobrien * 29859243Sobrien * 1/ whitespace 29959243Sobrien * 2/ alphanumeric chars, + underscore 30059243Sobrien * 3/ others 30159243Sobrien */ 30259243Sobrienstatic int 303167465Smpc_to_class(Char ch) 30459243Sobrien{ 30559243Sobrien if (Isspace(ch)) 30659243Sobrien return C_CLASS_WHITE; 30759243Sobrien 30859243Sobrien if (Isdigit(ch) || Isalpha(ch) || ch == '_') 30959243Sobrien return C_CLASS_ALNUM; 31059243Sobrien 31159243Sobrien return C_CLASS_OTHER; 31259243Sobrien} 31359243Sobrien 31459243Sobrienstatic Char * 315167465Smpc_prev_word(Char *p, Char *low, int n) 31659243Sobrien{ 31759243Sobrien p--; 31859243Sobrien 31959243Sobrien if (!VImode) { 32059243Sobrien while (n--) { 32159243Sobrien while ((p >= low) && !isword(*p)) 32259243Sobrien p--; 32359243Sobrien while ((p >= low) && isword(*p)) 32459243Sobrien p--; 32559243Sobrien } 32659243Sobrien 32759243Sobrien /* cp now points to one character before the word */ 32859243Sobrien p++; 32959243Sobrien if (p < low) 33059243Sobrien p = low; 33159243Sobrien /* cp now points where we want it */ 33259243Sobrien return(p); 33359243Sobrien } 33459243Sobrien 33559243Sobrien while (n--) { 33683098Smp int c_class; 33759243Sobrien 33859243Sobrien if (p < low) 33959243Sobrien break; 34059243Sobrien 34159243Sobrien /* scan until beginning of current word (may be all whitespace!) */ 34259243Sobrien c_class = c_to_class(*p); 34359243Sobrien while ((p >= low) && c_class == c_to_class(*p)) 34459243Sobrien p--; 34559243Sobrien 34659243Sobrien /* if this was a non_whitespace word, we're ready */ 34759243Sobrien if (c_class != C_CLASS_WHITE) 34859243Sobrien continue; 34959243Sobrien 35059243Sobrien /* otherwise, move back to beginning of the word just found */ 35159243Sobrien c_class = c_to_class(*p); 35259243Sobrien while ((p >= low) && c_class == c_to_class(*p)) 35359243Sobrien p--; 35459243Sobrien } 35559243Sobrien 35659243Sobrien p++; /* correct overshoot */ 35759243Sobrien 35859243Sobrien return (p); 35959243Sobrien} 36059243Sobrien 36159243Sobrienstatic Char * 362167465Smpc_next_word(Char *p, Char *high, int n) 36359243Sobrien{ 36459243Sobrien if (!VImode) { 36559243Sobrien while (n--) { 36659243Sobrien while ((p < high) && !isword(*p)) 36759243Sobrien p++; 36859243Sobrien while ((p < high) && isword(*p)) 36959243Sobrien p++; 37059243Sobrien } 37159243Sobrien if (p > high) 37259243Sobrien p = high; 37359243Sobrien /* p now points where we want it */ 37459243Sobrien return(p); 37559243Sobrien } 37659243Sobrien 37759243Sobrien while (n--) { 37883098Smp int c_class; 37959243Sobrien 38059243Sobrien if (p >= high) 38159243Sobrien break; 38259243Sobrien 38359243Sobrien /* scan until end of current word (may be all whitespace!) */ 38459243Sobrien c_class = c_to_class(*p); 38559243Sobrien while ((p < high) && c_class == c_to_class(*p)) 38659243Sobrien p++; 38759243Sobrien 38859243Sobrien /* if this was all whitespace, we're ready */ 38959243Sobrien if (c_class == C_CLASS_WHITE) 39059243Sobrien continue; 39159243Sobrien 39259243Sobrien /* if we've found white-space at the end of the word, skip it */ 39359243Sobrien while ((p < high) && c_to_class(*p) == C_CLASS_WHITE) 39459243Sobrien p++; 39559243Sobrien } 39659243Sobrien 39759243Sobrien p--; /* correct overshoot */ 39859243Sobrien 39959243Sobrien return (p); 40059243Sobrien} 40159243Sobrien 40259243Sobrienstatic Char * 403167465Smpc_nexword(Char *p, Char *high, int n) 40459243Sobrien{ 40559243Sobrien while (n--) { 40659243Sobrien while ((p < high) && !Isspace(*p)) 40759243Sobrien p++; 40859243Sobrien while ((p < high) && Isspace(*p)) 40959243Sobrien p++; 41059243Sobrien } 41159243Sobrien 41259243Sobrien if (p > high) 41359243Sobrien p = high; 41459243Sobrien /* p now points where we want it */ 41559243Sobrien return(p); 41659243Sobrien} 41759243Sobrien 41859243Sobrien/* 41959243Sobrien * Expand-History (originally "Magic-Space") code added by 42059243Sobrien * Ray Moody <ray@gibbs.physics.purdue.edu> 42159243Sobrien * this is a neat, but odd, addition. 42259243Sobrien */ 42359243Sobrien 42459243Sobrien/* 42559243Sobrien * c_number: Ignore character p points to, return number appearing after that. 42659243Sobrien * A '$' by itself means a big number; "$-" is for negative; '^' means 1. 42759243Sobrien * Return p pointing to last char used. 42859243Sobrien */ 42959243Sobrien 43059243Sobrien/* 43159243Sobrien * dval is the number to subtract from for things like $-3 43259243Sobrien */ 43359243Sobrien 43459243Sobrienstatic Char * 435167465Smpc_number(Char *p, int *num, int dval) 43659243Sobrien{ 43783098Smp int i; 43883098Smp int sign = 1; 43959243Sobrien 44059243Sobrien if (*++p == '^') { 44159243Sobrien *num = 1; 44259243Sobrien return(p); 44359243Sobrien } 44459243Sobrien if (*p == '$') { 44559243Sobrien if (*++p != '-') { 446167465Smp *num = INT_MAX; /* Handle $ */ 44759243Sobrien return(--p); 44859243Sobrien } 44959243Sobrien sign = -1; /* Handle $- */ 45059243Sobrien ++p; 45159243Sobrien } 45259243Sobrien for (i = 0; *p >= '0' && *p <= '9'; i = 10 * i + *p++ - '0') 45359243Sobrien continue; 45459243Sobrien *num = (sign < 0 ? dval - i : i); 45559243Sobrien return(--p); 45659243Sobrien} 45759243Sobrien 45859243Sobrien/* 45959243Sobrien * excl_expand: There is an excl to be expanded to p -- do the right thing 46059243Sobrien * with it and return a version of p advanced over the expanded stuff. Also, 46159243Sobrien * update tsh_cur and related things as appropriate... 46259243Sobrien */ 46359243Sobrien 46459243Sobrienstatic Char * 465167465Smpc_expand(Char *p) 46659243Sobrien{ 46783098Smp Char *q; 46883098Smp struct Hist *h = Histlist.Hnext; 46983098Smp struct wordent *l; 47059243Sobrien int i, from, to, dval; 471145479Smp int all_dig; 472145479Smp int been_once = 0; 47359243Sobrien Char *op = p; 474167465Smp Char *buf; 475167465Smp size_t buf_len; 476167465Smp Char *modbuf; 47759243Sobrien 478167465Smp buf = NULL; 47959243Sobrien if (!h) 48059243Sobrien goto excl_err; 48159243Sobrienexcl_sw: 48259243Sobrien switch (*(q = p + 1)) { 48359243Sobrien 48459243Sobrien case '^': 485167465Smp buf = expand_lex(&h->Hlex, 1, 1); 48659243Sobrien break; 48759243Sobrien 48859243Sobrien case '$': 48959243Sobrien if ((l = (h->Hlex).prev) != 0) 490167465Smp buf = expand_lex(l->prev->prev, 0, 0); 49159243Sobrien break; 49259243Sobrien 49359243Sobrien case '*': 494167465Smp buf = expand_lex(&h->Hlex, 1, INT_MAX); 49559243Sobrien break; 49659243Sobrien 49759243Sobrien default: 49859243Sobrien if (been_once) { /* unknown argument */ 49959243Sobrien /* assume it's a modifier, e.g. !foo:h, and get whole cmd */ 500167465Smp buf = expand_lex(&h->Hlex, 0, INT_MAX); 50159243Sobrien q -= 2; 50259243Sobrien break; 50359243Sobrien } 50459243Sobrien been_once = 1; 50559243Sobrien 50659243Sobrien if (*q == ':') /* short form: !:arg */ 50759243Sobrien --q; 50859243Sobrien 509232633Smp if (HIST != '\0' && *q != HIST) { 51059243Sobrien /* 51159243Sobrien * Search for a space, tab, or colon. See if we have a number (as 51259243Sobrien * in !1234:xyz). Remember the number. 51359243Sobrien */ 51459243Sobrien for (i = 0, all_dig = 1; 51559243Sobrien *q != ' ' && *q != '\t' && *q != ':' && q < Cursor; q++) { 51659243Sobrien /* 51759243Sobrien * PWP: !-4 is a valid history argument too, therefore the test 51859243Sobrien * is if not a digit, or not a - as the first character. 51959243Sobrien */ 52059243Sobrien if ((*q < '0' || *q > '9') && (*q != '-' || q != p + 1)) 52159243Sobrien all_dig = 0; 52259243Sobrien else if (*q == '-') 52359243Sobrien all_dig = 2;/* we are sneeky about this */ 52459243Sobrien else 52559243Sobrien i = 10 * i + *q - '0'; 52659243Sobrien } 52759243Sobrien --q; 52859243Sobrien 52959243Sobrien /* 53059243Sobrien * If we have a number, search for event i. Otherwise, search for 53159243Sobrien * a named event (as in !foo). (In this case, I is the length of 53259243Sobrien * the named event). 53359243Sobrien */ 53459243Sobrien if (all_dig) { 53559243Sobrien if (all_dig == 2) 53659243Sobrien i = -i; /* make it negitive */ 53759243Sobrien if (i < 0) /* if !-4 (for example) */ 53859243Sobrien i = eventno + 1 + i; /* remember: i is < 0 */ 53959243Sobrien for (; h; h = h->Hnext) { 54059243Sobrien if (h->Hnum == i) 54159243Sobrien break; 54259243Sobrien } 54359243Sobrien } 54459243Sobrien else { 54559243Sobrien for (i = (int) (q - p); h; h = h->Hnext) { 54659243Sobrien if ((l = &h->Hlex) != 0) { 54759243Sobrien if (!Strncmp(p + 1, l->next->word, (size_t) i)) 54859243Sobrien break; 54959243Sobrien } 55059243Sobrien } 55159243Sobrien } 55259243Sobrien } 55359243Sobrien if (!h) 55459243Sobrien goto excl_err; 55559243Sobrien if (q[1] == ':' || q[1] == '-' || q[1] == '*' || 55659243Sobrien q[1] == '$' || q[1] == '^') { /* get some args */ 55759243Sobrien p = q[1] == ':' ? ++q : q; 55859243Sobrien /* 55959243Sobrien * Go handle !foo:* 56059243Sobrien */ 56159243Sobrien if ((q[1] < '0' || q[1] > '9') && 56259243Sobrien q[1] != '-' && q[1] != '$' && q[1] != '^') 56359243Sobrien goto excl_sw; 56459243Sobrien /* 56559243Sobrien * Go handle !foo:$ 56659243Sobrien */ 56759243Sobrien if (q[1] == '$' && (q[2] != '-' || q[3] < '0' || q[3] > '9')) 56859243Sobrien goto excl_sw; 56959243Sobrien /* 57059243Sobrien * Count up the number of words in this event. Store it in dval. 57159243Sobrien * Dval will be fed to number. 57259243Sobrien */ 57359243Sobrien dval = 0; 57459243Sobrien if ((l = h->Hlex.prev) != 0) { 57559243Sobrien for (l = l->prev; l != h->Hlex.next; l = l->prev, dval++) 57659243Sobrien continue; 57759243Sobrien } 57859243Sobrien if (!dval) 57959243Sobrien goto excl_err; 58059243Sobrien if (q[1] == '-') 58159243Sobrien from = 0; 58259243Sobrien else 58359243Sobrien q = c_number(q, &from, dval); 58459243Sobrien if (q[1] == '-') { 58559243Sobrien ++q; 58659243Sobrien if ((q[1] < '0' || q[1] > '9') && q[1] != '$') 58759243Sobrien to = dval - 1; 58859243Sobrien else 58959243Sobrien q = c_number(q, &to, dval); 59059243Sobrien } 59159243Sobrien else if (q[1] == '*') { 59259243Sobrien ++q; 593167465Smp to = INT_MAX; 59459243Sobrien } 59559243Sobrien else { 59659243Sobrien to = from; 59759243Sobrien } 59859243Sobrien if (from < 0 || to < from) 59959243Sobrien goto excl_err; 600167465Smp buf = expand_lex(&h->Hlex, from, to); 60159243Sobrien } 602167465Smp else /* get whole cmd */ 603167465Smp buf = expand_lex(&h->Hlex, 0, INT_MAX); 60459243Sobrien break; 60559243Sobrien } 606167465Smp if (buf == NULL) 607167465Smp buf = SAVE(""); 60859243Sobrien 60959243Sobrien /* 61059243Sobrien * Apply modifiers, if any. 61159243Sobrien */ 61259243Sobrien if (q[1] == ':') { 613167465Smp modbuf = buf; 61459243Sobrien while (q[1] == ':' && modbuf != NULL) { 61559243Sobrien switch (q[2]) { 61659243Sobrien case 'r': 61759243Sobrien case 'e': 61859243Sobrien case 'h': 61959243Sobrien case 't': 62059243Sobrien case 'q': 62159243Sobrien case 'x': 62259243Sobrien case 'u': 62359243Sobrien case 'l': 624167465Smp if ((modbuf = domod(buf, (int) q[2])) != NULL) { 625167465Smp xfree(buf); 626167465Smp buf = modbuf; 62759243Sobrien } 62859243Sobrien ++q; 62959243Sobrien break; 63059243Sobrien 63159243Sobrien case 'a': 63259243Sobrien case 'g': 63359243Sobrien /* Not implemented; this needs to be done before expanding 63459243Sobrien * lex. We don't have the words available to us anymore. 63559243Sobrien */ 63659243Sobrien ++q; 63759243Sobrien break; 63859243Sobrien 63959243Sobrien case 'p': 64059243Sobrien /* Ok */ 64159243Sobrien ++q; 64259243Sobrien break; 64359243Sobrien 64459243Sobrien case '\0': 64559243Sobrien break; 64659243Sobrien 64759243Sobrien default: 64859243Sobrien ++q; 64959243Sobrien break; 65059243Sobrien } 65159243Sobrien if (q[1]) 65259243Sobrien ++q; 65359243Sobrien } 65459243Sobrien } 65559243Sobrien 656167465Smp buf_len = Strlen(buf); 65759243Sobrien /* 658167465Smp * Now replace the text from op to q inclusive with the text from buf. 65959243Sobrien */ 66059243Sobrien q++; 66159243Sobrien 66259243Sobrien /* 66359243Sobrien * Now replace text non-inclusively like a real CS major! 66459243Sobrien */ 665167465Smp if (LastChar + buf_len - (q - op) >= InputLim) 66659243Sobrien goto excl_err; 667167465Smp (void) memmove(op + buf_len, q, (LastChar - q) * sizeof(Char)); 668167465Smp LastChar += buf_len - (q - op); 669167465Smp Cursor += buf_len - (q - op); 670167465Smp (void) memcpy(op, buf, buf_len * sizeof(Char)); 67159243Sobrien *LastChar = '\0'; 672167465Smp xfree(buf); 673167465Smp return op + buf_len; 67459243Sobrienexcl_err: 675167465Smp xfree(buf); 67659243Sobrien SoundBeep(); 67759243Sobrien return(op + 1); 67859243Sobrien} 67959243Sobrien 68059243Sobrien/* 68159243Sobrien * c_excl: An excl has been found at point p -- back up and find some white 68259243Sobrien * space (or the beginning of the buffer) and properly expand all the excl's 68359243Sobrien * from there up to the current cursor position. We also avoid (trying to) 68459243Sobrien * expanding '>!' 685195609Smp * Returns number of expansions attempted (doesn't matter whether they succeeded 686195609Smp * or not). 68759243Sobrien */ 68859243Sobrien 689195609Smpstatic int 690167465Smpc_excl(Char *p) 69159243Sobrien{ 69283098Smp int i; 69383098Smp Char *q; 694195609Smp int nr_exp; 69559243Sobrien 69659243Sobrien /* 69759243Sobrien * if />[SPC TAB]*![SPC TAB]/, back up p to just after the >. otherwise, 69859243Sobrien * back p up to just before the current word. 69959243Sobrien */ 70059243Sobrien if ((p[1] == ' ' || p[1] == '\t') && 70159243Sobrien (p[-1] == ' ' || p[-1] == '\t' || p[-1] == '>')) { 70259243Sobrien for (q = p - 1; q > InputBuf && (*q == ' ' || *q == '\t'); --q) 70359243Sobrien continue; 70459243Sobrien if (*q == '>') 70559243Sobrien ++p; 70659243Sobrien } 70759243Sobrien else { 70859243Sobrien while (*p != ' ' && *p != '\t' && p > InputBuf) 70959243Sobrien --p; 71059243Sobrien } 71159243Sobrien 71259243Sobrien /* 71359243Sobrien * Forever: Look for history char. (Stop looking when we find the cursor.) 714195609Smp * Count backslashes. If odd, skip history char. Expand if even number of 715195609Smp * backslashes. 71659243Sobrien */ 717195609Smp nr_exp = 0; 71859243Sobrien for (;;) { 719232633Smp if (HIST != '\0') 720232633Smp while (*p != HIST && p < Cursor) 721232633Smp ++p; 72259243Sobrien for (i = 1; (p - i) >= InputBuf && p[-i] == '\\'; i++) 72359243Sobrien continue; 72459243Sobrien if (i % 2 == 0) 72559243Sobrien ++p; 726195609Smp if (p >= Cursor) /* all done */ 727195609Smp return nr_exp; 728195609Smp if (i % 2 == 1) { 72959243Sobrien p = c_expand(p); 730195609Smp ++nr_exp; 731195609Smp } 73259243Sobrien } 73359243Sobrien} 73459243Sobrien 73559243Sobrien 736195609Smpstatic int 737167465Smpc_substitute(void) 73859243Sobrien{ 73983098Smp Char *p; 740195609Smp int nr_exp; 74159243Sobrien 74259243Sobrien /* 74359243Sobrien * Start p out one character before the cursor. Move it backwards looking 74459243Sobrien * for white space, the beginning of the line, or a history character. 74559243Sobrien */ 74659243Sobrien for (p = Cursor - 1; 747232633Smp p > InputBuf && *p != ' ' && *p != '\t' && *p && *p != HIST; --p) 74859243Sobrien continue; 74959243Sobrien 75059243Sobrien /* 75159243Sobrien * If we found a history character, go expand it. 75259243Sobrien */ 753232633Smp if (HIST != '\0' && *p == HIST) 754195609Smp nr_exp = c_excl(p); 755195609Smp else 756195609Smp nr_exp = 0; 75759243Sobrien Refresh(); 758195609Smp 759195609Smp return nr_exp; 76059243Sobrien} 76159243Sobrien 76259243Sobrienstatic void 763167465Smpc_delfini(void) /* Finish up delete action */ 76459243Sobrien{ 76583098Smp int Size; 76659243Sobrien 76759243Sobrien if (ActionFlag & TCSHOP_INSERT) 76859243Sobrien c_alternativ_key_map(0); 76959243Sobrien 77059243Sobrien ActionFlag = TCSHOP_NOP; 77159243Sobrien 77259243Sobrien if (ActionPos == 0) 77359243Sobrien return; 77459243Sobrien 77559243Sobrien UndoAction = TCSHOP_INSERT; 77659243Sobrien 77759243Sobrien if (Cursor > ActionPos) { 77859243Sobrien Size = (int) (Cursor-ActionPos); 77959243Sobrien c_delbefore(Size); 78059243Sobrien RefCursor(); 78159243Sobrien } 78259243Sobrien else if (Cursor < ActionPos) { 78359243Sobrien Size = (int)(ActionPos-Cursor); 78459243Sobrien c_delafter(Size); 78559243Sobrien } 78659243Sobrien else { 78759243Sobrien Size = 1; 78859243Sobrien c_delafter(Size); 78959243Sobrien } 79059243Sobrien UndoPtr = Cursor; 79159243Sobrien UndoSize = Size; 79259243Sobrien} 79359243Sobrien 79459243Sobrienstatic Char * 795167465Smpc_endword(Char *p, Char *high, int n, Char *delim) 79659243Sobrien{ 797145479Smp Char inquote = 0; 79859243Sobrien p++; 79959243Sobrien 80059243Sobrien while (n--) { 80183098Smp while (p < high) { /* Skip non-word chars */ 80283098Smp if (!Strchr(delim, *p) || *(p-1) == (Char)'\\') 80359243Sobrien break; 80459243Sobrien p++; 80559243Sobrien } 80659243Sobrien while (p < high) { /* Skip string */ 80759243Sobrien if ((*p == (Char)'\'' || *p == (Char)'"')) { /* Quotation marks? */ 80883098Smp if (inquote || *(p-1) != (Char)'\\') { /* Should it be honored? */ 80959243Sobrien if (inquote == 0) inquote = *p; 81059243Sobrien else if (inquote == *p) inquote = 0; 81159243Sobrien } 81259243Sobrien } 81383098Smp /* Break if unquoted non-word char */ 81483098Smp if (!inquote && Strchr(delim, *p) && *(p-1) != (Char)'\\') 81559243Sobrien break; 81659243Sobrien p++; 81759243Sobrien } 81859243Sobrien } 81959243Sobrien 82059243Sobrien p--; 82159243Sobrien return(p); 82259243Sobrien} 82359243Sobrien 82459243Sobrien 82559243Sobrienstatic Char * 826167465Smpc_eword(Char *p, Char *high, int n) 82759243Sobrien{ 82859243Sobrien p++; 82959243Sobrien 83059243Sobrien while (n--) { 83159243Sobrien while ((p < high) && Isspace(*p)) 83259243Sobrien p++; 83359243Sobrien 834232633Smp if (isword(*p)) 835232633Smp while ((p < high) && isword(*p)) 83659243Sobrien p++; 83759243Sobrien else 838232633Smp while ((p < high) && !(Isspace(*p) || isword(*p))) 83959243Sobrien p++; 84059243Sobrien } 84159243Sobrien 84259243Sobrien p--; 84359243Sobrien return(p); 84459243Sobrien} 84559243Sobrien 84683098Smp/* Set the max length of the kill ring */ 84783098Smpvoid 848167465SmpSetKillRing(int max) 84983098Smp{ 85083098Smp CStr *new; 85183098Smp int count, i, j; 85283098Smp 85383098Smp if (max < 1) 85483098Smp max = 1; /* no ring, but always one buffer */ 85583098Smp if (max == KillRingMax) 85683098Smp return; 857167465Smp new = xcalloc(max, sizeof(CStr)); 85883098Smp if (KillRing != NULL) { 85983098Smp if (KillRingLen != 0) { 86083098Smp if (max >= KillRingLen) { 86183098Smp count = KillRingLen; 86283098Smp j = KillPos; 86383098Smp } else { 86483098Smp count = max; 86583098Smp j = (KillPos - count + KillRingLen) % KillRingLen; 86683098Smp } 86783098Smp for (i = 0; i < KillRingLen; i++) { 86883098Smp if (i < count) /* copy latest */ 86983098Smp new[i] = KillRing[j]; 87083098Smp else /* free the others */ 87183098Smp xfree(KillRing[j].buf); 87283098Smp j = (j + 1) % KillRingLen; 87383098Smp } 87483098Smp KillRingLen = count; 87583098Smp KillPos = count % max; 87683098Smp YankPos = count - 1; 87783098Smp } 87883098Smp xfree(KillRing); 87983098Smp } 88083098Smp KillRing = new; 88183098Smp KillRingMax = max; 88283098Smp} 88383098Smp 88483098Smp/* Push string from start upto (but not including) end onto kill ring */ 88583098Smpstatic void 886167465Smpc_push_kill(Char *start, Char *end) 88783098Smp{ 88883098Smp CStr save, *pos; 88983098Smp Char *dp, *cp, *kp; 89083098Smp int len = end - start, i, j, k; 89183098Smp 89283098Smp /* Check for duplicates? */ 89383098Smp if (KillRingLen > 0 && (dp = varval(STRkilldup)) != STRNULL) { 89483098Smp YankPos = (KillPos - 1 + KillRingLen) % KillRingLen; 89583098Smp if (eq(dp, STRerase)) { /* erase earlier one (actually move up) */ 89683098Smp j = YankPos; 89783098Smp for (i = 0; i < KillRingLen; i++) { 89883098Smp if (Strncmp(KillRing[j].buf, start, (size_t) len) == 0 && 89983098Smp KillRing[j].buf[len] == '\0') { 90083098Smp save = KillRing[j]; 90183098Smp for ( ; i > 0; i--) { 90283098Smp k = j; 90383098Smp j = (j + 1) % KillRingLen; 90483098Smp KillRing[k] = KillRing[j]; 90583098Smp } 90683098Smp KillRing[j] = save; 90783098Smp return; 90883098Smp } 90983098Smp j = (j - 1 + KillRingLen) % KillRingLen; 91083098Smp } 91183098Smp } else if (eq(dp, STRall)) { /* skip if any earlier */ 91283098Smp for (i = 0; i < KillRingLen; i++) 91383098Smp if (Strncmp(KillRing[i].buf, start, (size_t) len) == 0 && 91483098Smp KillRing[i].buf[len] == '\0') 91583098Smp return; 91683098Smp } else if (eq(dp, STRprev)) { /* skip if immediately previous */ 91783098Smp j = YankPos; 91883098Smp if (Strncmp(KillRing[j].buf, start, (size_t) len) == 0 && 91983098Smp KillRing[j].buf[len] == '\0') 92083098Smp return; 92183098Smp } 92283098Smp } 92383098Smp 92483098Smp /* No duplicate, go ahead and push */ 92583098Smp len++; /* need space for '\0' */ 92683098Smp YankPos = KillPos; 92783098Smp if (KillRingLen < KillRingMax) 92883098Smp KillRingLen++; 92983098Smp pos = &KillRing[KillPos]; 93083098Smp KillPos = (KillPos + 1) % KillRingMax; 93183098Smp if (pos->len < len) { 932167465Smp pos->buf = xrealloc(pos->buf, len * sizeof(Char)); 93383098Smp pos->len = len; 93483098Smp } 93583098Smp cp = start; 93683098Smp kp = pos->buf; 93783098Smp while (cp < end) 93883098Smp *kp++ = *cp++; 93983098Smp *kp = '\0'; 94083098Smp} 94183098Smp 942167465Smp/* Save InputBuf etc in SavedBuf etc for restore after cmd exec */ 943167465Smpstatic void 944167465Smpc_save_inputbuf() 94559243Sobrien{ 946167465Smp SavedBuf.len = 0; 947167465Smp Strbuf_append(&SavedBuf, InputBuf); 948167465Smp Strbuf_terminate(&SavedBuf); 949167465Smp LastSaved = LastChar - InputBuf; 950167465Smp CursSaved = Cursor - InputBuf; 951167465Smp HistSaved = Hist_num; 952167465Smp RestoreSaved = 1; 953167465Smp} 954167465Smp 955167465SmpCCRETVAL 956167465SmpGetHistLine() 957167465Smp{ 95859243Sobrien struct Hist *hp; 95959243Sobrien int h; 96059243Sobrien 96159243Sobrien if (Hist_num == 0) { /* if really the current line */ 962167465Smp if (HistBuf.s != NULL) 963167465Smp copyn(InputBuf, HistBuf.s, INBUFSIZE);/*FIXBUF*/ 964167465Smp else 965167465Smp *InputBuf = '\0'; 966167465Smp LastChar = InputBuf + HistBuf.len; 96759243Sobrien 96859243Sobrien#ifdef KSHVI 96959243Sobrien if (VImode) 97059243Sobrien Cursor = InputBuf; 97159243Sobrien else 97259243Sobrien#endif /* KSHVI */ 97359243Sobrien Cursor = LastChar; 97459243Sobrien 97559243Sobrien return(CC_REFRESH); 97659243Sobrien } 97759243Sobrien 97859243Sobrien hp = Histlist.Hnext; 97959243Sobrien if (hp == NULL) 98059243Sobrien return(CC_ERROR); 98159243Sobrien 98259243Sobrien for (h = 1; h < Hist_num; h++) { 98359243Sobrien if ((hp->Hnext) == NULL) { 98459243Sobrien Hist_num = h; 98559243Sobrien return(CC_ERROR); 98659243Sobrien } 98759243Sobrien hp = hp->Hnext; 98859243Sobrien } 98959243Sobrien 99059243Sobrien if (HistLit && hp->histline) { 991167465Smp copyn(InputBuf, hp->histline, INBUFSIZE);/*FIXBUF*/ 99259243Sobrien CurrentHistLit = 1; 99359243Sobrien } 99459243Sobrien else { 995167465Smp Char *p; 996167465Smp 997167465Smp p = sprlex(&hp->Hlex); 998167465Smp copyn(InputBuf, p, sizeof(InputBuf) / sizeof(Char));/*FIXBUF*/ 999167465Smp xfree(p); 100059243Sobrien CurrentHistLit = 0; 100159243Sobrien } 1002167465Smp LastChar = Strend(InputBuf); 100359243Sobrien 100459243Sobrien if (LastChar > InputBuf) { 100559243Sobrien if (LastChar[-1] == '\n') 100659243Sobrien LastChar--; 100759243Sobrien#if 0 100859243Sobrien if (LastChar[-1] == ' ') 100959243Sobrien LastChar--; 101059243Sobrien#endif 101159243Sobrien if (LastChar < InputBuf) 101259243Sobrien LastChar = InputBuf; 101359243Sobrien } 1014145479Smp 101559243Sobrien#ifdef KSHVI 101659243Sobrien if (VImode) 101759243Sobrien Cursor = InputBuf; 101859243Sobrien else 101959243Sobrien#endif /* KSHVI */ 102059243Sobrien Cursor = LastChar; 102159243Sobrien 102259243Sobrien return(CC_REFRESH); 102359243Sobrien} 102459243Sobrien 102559243Sobrienstatic CCRETVAL 1026167465Smpc_search_line(Char *pattern, int dir) 102759243Sobrien{ 102859243Sobrien Char *cp; 1029167465Smp size_t len; 103059243Sobrien 1031167465Smp len = Strlen(pattern); 103259243Sobrien 103359243Sobrien if (dir == F_UP_SEARCH_HIST) { 103459243Sobrien for (cp = Cursor; cp >= InputBuf; cp--) 1035167465Smp if (Strncmp(cp, pattern, len) == 0 || 103659243Sobrien Gmatch(cp, pattern)) { 103759243Sobrien Cursor = cp; 103859243Sobrien return(CC_NORM); 103959243Sobrien } 104059243Sobrien return(CC_ERROR); 104159243Sobrien } else { 104259243Sobrien for (cp = Cursor; *cp != '\0' && cp < InputLim; cp++) 1043167465Smp if (Strncmp(cp, pattern, len) == 0 || 104459243Sobrien Gmatch(cp, pattern)) { 104559243Sobrien Cursor = cp; 104659243Sobrien return(CC_NORM); 104759243Sobrien } 104859243Sobrien return(CC_ERROR); 104959243Sobrien } 105059243Sobrien} 105159243Sobrien 105259243Sobrienstatic CCRETVAL 1053167465Smpe_inc_search(int dir) 105459243Sobrien{ 1055167465Smp static const Char STRfwd[] = { 'f', 'w', 'd', '\0' }, 1056167465Smp STRbck[] = { 'b', 'c', 'k', '\0' }; 105759243Sobrien static Char pchar = ':'; /* ':' = normal, '?' = failed */ 105859243Sobrien static Char endcmd[2]; 1059167465Smp const Char *cp; 1060167465Smp Char ch, 106159243Sobrien *oldCursor = Cursor, 106259243Sobrien oldpchar = pchar; 106359243Sobrien CCRETVAL ret = CC_NORM; 106459243Sobrien int oldHist_num = Hist_num, 1065167465Smp oldpatlen = patbuf.len, 106659243Sobrien newdir = dir, 106759243Sobrien done, redo; 106859243Sobrien 1069167465Smp if (LastChar + sizeof(STRfwd)/sizeof(Char) + 2 + patbuf.len >= InputLim) 107059243Sobrien return(CC_ERROR); 107159243Sobrien 107259243Sobrien for (;;) { 107359243Sobrien 1074167465Smp if (patbuf.len == 0) { /* first round */ 107559243Sobrien pchar = ':'; 1076167465Smp Strbuf_append1(&patbuf, '*'); 107759243Sobrien } 107859243Sobrien done = redo = 0; 107959243Sobrien *LastChar++ = '\n'; 108059243Sobrien for (cp = newdir == F_UP_SEARCH_HIST ? STRbck : STRfwd; 108159243Sobrien *cp; *LastChar++ = *cp++) 108259243Sobrien continue; 108359243Sobrien *LastChar++ = pchar; 1084167465Smp for (cp = &patbuf.s[1]; cp < &patbuf.s[patbuf.len]; 1085167465Smp *LastChar++ = *cp++) 108659243Sobrien continue; 108759243Sobrien *LastChar = '\0'; 1088167465Smp if (adrof(STRhighlight) && pchar == ':') { 1089167465Smp /* if the no-glob-search patch is applied, remove the - 1 below */ 1090167465Smp IncMatchLen = patbuf.len - 1; 1091167465Smp ClearLines(); 1092167465Smp ClearDisp(); 1093167465Smp } 109459243Sobrien Refresh(); 109559243Sobrien 109659243Sobrien if (GetNextChar(&ch) != 1) 109759243Sobrien return(e_send_eof(0)); 109859243Sobrien 1099145479Smp switch (ch > NT_NUM_KEYS 1100145479Smp ? F_INSERT : CurrentKeyMap[(unsigned char) ch]) { 110159243Sobrien case F_INSERT: 110259243Sobrien case F_DIGIT: 110359243Sobrien case F_MAGIC_SPACE: 1104167465Smp if (LastChar + 1 >= InputLim) /*FIXBUF*/ 110559243Sobrien SoundBeep(); 110659243Sobrien else { 1107167465Smp Strbuf_append1(&patbuf, ch); 110859243Sobrien *LastChar++ = ch; 110959243Sobrien *LastChar = '\0'; 111059243Sobrien Refresh(); 111159243Sobrien } 111259243Sobrien break; 111359243Sobrien 111459243Sobrien case F_INC_FWD: 111559243Sobrien newdir = F_DOWN_SEARCH_HIST; 111659243Sobrien redo++; 111759243Sobrien break; 111859243Sobrien 111959243Sobrien case F_INC_BACK: 112059243Sobrien newdir = F_UP_SEARCH_HIST; 112159243Sobrien redo++; 112259243Sobrien break; 112359243Sobrien 112459243Sobrien case F_DELPREV: 1125167465Smp if (patbuf.len > 1) 112659243Sobrien done++; 112759243Sobrien else 112859243Sobrien SoundBeep(); 112959243Sobrien break; 113059243Sobrien 113159243Sobrien default: 1132167465Smp switch (ASC(ch)) { 113359243Sobrien case 0007: /* ^G: Abort */ 113459243Sobrien ret = CC_ERROR; 113559243Sobrien done++; 113659243Sobrien break; 113759243Sobrien 113859243Sobrien case 0027: /* ^W: Append word */ 113959243Sobrien /* No can do if globbing characters in pattern */ 1140167465Smp for (cp = &patbuf.s[1]; ; cp++) 1141167465Smp if (cp >= &patbuf.s[patbuf.len]) { 1142167465Smp Cursor += patbuf.len - 1; 114359243Sobrien cp = c_next_word(Cursor, LastChar, 1); 114459243Sobrien while (Cursor < cp && *Cursor != '\n') { 1145167465Smp if (LastChar + 1 >= InputLim) {/*FIXBUF*/ 114659243Sobrien SoundBeep(); 114759243Sobrien break; 114859243Sobrien } 1149167465Smp Strbuf_append1(&patbuf, *Cursor); 115059243Sobrien *LastChar++ = *Cursor++; 115159243Sobrien } 115259243Sobrien Cursor = oldCursor; 115359243Sobrien *LastChar = '\0'; 115459243Sobrien Refresh(); 115559243Sobrien break; 115659243Sobrien } else if (isglob(*cp)) { 115759243Sobrien SoundBeep(); 115859243Sobrien break; 115959243Sobrien } 116059243Sobrien break; 116159243Sobrien 116259243Sobrien default: /* Terminate and execute cmd */ 116359243Sobrien endcmd[0] = ch; 116459243Sobrien PushMacro(endcmd); 116559243Sobrien /*FALLTHROUGH*/ 116659243Sobrien 116759243Sobrien case 0033: /* ESC: Terminate */ 116859243Sobrien ret = CC_REFRESH; 116959243Sobrien done++; 117059243Sobrien break; 117159243Sobrien } 117259243Sobrien break; 117359243Sobrien } 117459243Sobrien 117559243Sobrien while (LastChar > InputBuf && *LastChar != '\n') 117659243Sobrien *LastChar-- = '\0'; 117759243Sobrien *LastChar = '\0'; 117859243Sobrien 117959243Sobrien if (!done) { 118059243Sobrien 118159243Sobrien /* Can't search if unmatched '[' */ 1182167465Smp for (cp = &patbuf.s[patbuf.len - 1], ch = ']'; cp > patbuf.s; cp--) 118359243Sobrien if (*cp == '[' || *cp == ']') { 118459243Sobrien ch = *cp; 118559243Sobrien break; 118659243Sobrien } 118759243Sobrien 1188167465Smp if (patbuf.len > 1 && ch != '[') { 118959243Sobrien if (redo && newdir == dir) { 119059243Sobrien if (pchar == '?') { /* wrap around */ 1191167465Smp Hist_num = newdir == F_UP_SEARCH_HIST ? 0 : INT_MAX; 1192167465Smp if (GetHistLine() == CC_ERROR) 119359243Sobrien /* Hist_num was fixed by first call */ 1194167465Smp (void) GetHistLine(); 119559243Sobrien Cursor = newdir == F_UP_SEARCH_HIST ? 119659243Sobrien LastChar : InputBuf; 119759243Sobrien } else 119859243Sobrien Cursor += newdir == F_UP_SEARCH_HIST ? -1 : 1; 119959243Sobrien } 1200167465Smp Strbuf_append1(&patbuf, '*'); 1201167465Smp Strbuf_terminate(&patbuf); 120259243Sobrien if (Cursor < InputBuf || Cursor > LastChar || 1203167465Smp (ret = c_search_line(&patbuf.s[1], newdir)) == CC_ERROR) { 120459243Sobrien LastCmd = (KEYCMD) newdir; /* avoid c_hsetpat */ 120559243Sobrien ret = newdir == F_UP_SEARCH_HIST ? 120659243Sobrien e_up_search_hist(0) : e_down_search_hist(0); 120759243Sobrien if (ret != CC_ERROR) { 120859243Sobrien Cursor = newdir == F_UP_SEARCH_HIST ? 120959243Sobrien LastChar : InputBuf; 1210167465Smp (void) c_search_line(&patbuf.s[1], newdir); 121159243Sobrien } 121259243Sobrien } 1213167465Smp patbuf.s[--patbuf.len] = '\0'; 121459243Sobrien if (ret == CC_ERROR) { 121559243Sobrien SoundBeep(); 121659243Sobrien if (Hist_num != oldHist_num) { 121759243Sobrien Hist_num = oldHist_num; 1218167465Smp if (GetHistLine() == CC_ERROR) 121959243Sobrien return(CC_ERROR); 122059243Sobrien } 122159243Sobrien Cursor = oldCursor; 122259243Sobrien pchar = '?'; 122359243Sobrien } else { 122459243Sobrien pchar = ':'; 122559243Sobrien } 122659243Sobrien } 122759243Sobrien 122859243Sobrien ret = e_inc_search(newdir); 122959243Sobrien 123059243Sobrien if (ret == CC_ERROR && pchar == '?' && oldpchar == ':') { 123159243Sobrien /* break abort of failed search at last non-failed */ 123259243Sobrien ret = CC_NORM; 123359243Sobrien } 123459243Sobrien 123559243Sobrien } 123659243Sobrien 123759243Sobrien if (ret == CC_NORM || (ret == CC_ERROR && oldpatlen == 0)) { 123859243Sobrien /* restore on normal return or error exit */ 123959243Sobrien pchar = oldpchar; 1240167465Smp patbuf.len = oldpatlen; 124159243Sobrien if (Hist_num != oldHist_num) { 124259243Sobrien Hist_num = oldHist_num; 1243167465Smp if (GetHistLine() == CC_ERROR) 124459243Sobrien return(CC_ERROR); 124559243Sobrien } 124659243Sobrien Cursor = oldCursor; 124759243Sobrien if (ret == CC_ERROR) 124859243Sobrien Refresh(); 124959243Sobrien } 125059243Sobrien if (done || ret != CC_NORM) 125159243Sobrien return(ret); 125259243Sobrien 125359243Sobrien } 125459243Sobrien 125559243Sobrien} 125659243Sobrien 125759243Sobrienstatic CCRETVAL 1258167465Smpv_search(int dir) 125959243Sobrien{ 1260167465Smp struct Strbuf tmpbuf = Strbuf_INIT; 126159243Sobrien Char ch; 1262167465Smp Char *oldbuf; 126359243Sobrien Char *oldlc, *oldc; 126459243Sobrien 1265167465Smp cleanup_push(&tmpbuf, Strbuf_cleanup); 1266167465Smp oldbuf = Strsave(InputBuf); 1267167465Smp cleanup_push(oldbuf, xfree); 126859243Sobrien oldlc = LastChar; 126959243Sobrien oldc = Cursor; 1270167465Smp Strbuf_append1(&tmpbuf, '*'); 127159243Sobrien 127259243Sobrien InputBuf[0] = '\0'; 127359243Sobrien LastChar = InputBuf; 127459243Sobrien Cursor = InputBuf; 127559243Sobrien searchdir = dir; 127659243Sobrien 127759243Sobrien c_insert(2); /* prompt + '\n' */ 127859243Sobrien *Cursor++ = '\n'; 127959243Sobrien *Cursor++ = dir == F_UP_SEARCH_HIST ? '?' : '/'; 128059243Sobrien Refresh(); 128159243Sobrien for (ch = 0;ch == 0;) { 1282167465Smp if (GetNextChar(&ch) != 1) { 1283167465Smp cleanup_until(&tmpbuf); 128459243Sobrien return(e_send_eof(0)); 1285167465Smp } 128659243Sobrien switch (ASC(ch)) { 128759243Sobrien case 0010: /* Delete and backspace */ 128859243Sobrien case 0177: 1289167465Smp if (tmpbuf.len > 1) { 129059243Sobrien *Cursor-- = '\0'; 129159243Sobrien LastChar = Cursor; 1292167465Smp tmpbuf.len--; 129359243Sobrien } 129459243Sobrien else { 1295167465Smp copyn(InputBuf, oldbuf, INBUFSIZE);/*FIXBUF*/ 129659243Sobrien LastChar = oldlc; 129759243Sobrien Cursor = oldc; 1298167465Smp cleanup_until(&tmpbuf); 129959243Sobrien return(CC_REFRESH); 130059243Sobrien } 130159243Sobrien Refresh(); 130259243Sobrien ch = 0; 130359243Sobrien break; 130459243Sobrien 130559243Sobrien case 0033: /* ESC */ 130669408Sache#ifdef IS_ASCII 130759243Sobrien case '\r': /* Newline */ 130859243Sobrien case '\n': 130959243Sobrien#else 131069408Sache case '\012': /* ASCII Line feed */ 131169408Sache case '\015': /* ASCII (or EBCDIC) Return */ 131259243Sobrien#endif 131359243Sobrien break; 131459243Sobrien 131559243Sobrien default: 1316167465Smp Strbuf_append1(&tmpbuf, ch); 1317167465Smp *Cursor++ = ch; 1318167465Smp LastChar = Cursor; 131959243Sobrien Refresh(); 132059243Sobrien ch = 0; 132159243Sobrien break; 132259243Sobrien } 132359243Sobrien } 1324167465Smp cleanup_until(oldbuf); 132559243Sobrien 1326167465Smp if (tmpbuf.len == 1) { 132759243Sobrien /* 132859243Sobrien * Use the old pattern, but wild-card it. 132959243Sobrien */ 1330167465Smp if (patbuf.len == 0) { 133159243Sobrien InputBuf[0] = '\0'; 133259243Sobrien LastChar = InputBuf; 133359243Sobrien Cursor = InputBuf; 133459243Sobrien Refresh(); 1335167465Smp cleanup_until(&tmpbuf); 133659243Sobrien return(CC_ERROR); 133759243Sobrien } 1338167465Smp if (patbuf.s[0] != '*') { 1339167465Smp oldbuf = Strsave(patbuf.s); 1340167465Smp patbuf.len = 0; 1341167465Smp Strbuf_append1(&patbuf, '*'); 1342167465Smp Strbuf_append(&patbuf, oldbuf); 1343167465Smp xfree(oldbuf); 1344167465Smp Strbuf_append1(&patbuf, '*'); 1345167465Smp Strbuf_terminate(&patbuf); 134659243Sobrien } 134759243Sobrien } 134859243Sobrien else { 1349167465Smp Strbuf_append1(&tmpbuf, '*'); 1350167465Smp Strbuf_terminate(&tmpbuf); 1351167465Smp patbuf.len = 0; 1352167465Smp Strbuf_append(&patbuf, tmpbuf.s); 1353167465Smp Strbuf_terminate(&patbuf); 135459243Sobrien } 1355167465Smp cleanup_until(&tmpbuf); 135659243Sobrien LastCmd = (KEYCMD) dir; /* avoid c_hsetpat */ 135759243Sobrien Cursor = LastChar = InputBuf; 135859243Sobrien if ((dir == F_UP_SEARCH_HIST ? e_up_search_hist(0) : 135959243Sobrien e_down_search_hist(0)) == CC_ERROR) { 136059243Sobrien Refresh(); 136159243Sobrien return(CC_ERROR); 136259243Sobrien } 136359243Sobrien else { 1364167465Smp if (ASC(ch) == 0033) { 136559243Sobrien Refresh(); 136659243Sobrien *LastChar++ = '\n'; 136759243Sobrien *LastChar = '\0'; 136859243Sobrien PastBottom(); 136959243Sobrien return(CC_NEWLINE); 137059243Sobrien } 137159243Sobrien else 137259243Sobrien return(CC_REFRESH); 137359243Sobrien } 137459243Sobrien} 137559243Sobrien 137659243Sobrien/* 137759243Sobrien * semi-PUBLIC routines. Any routine that is of type CCRETVAL is an 137859243Sobrien * entry point, called from the CcKeyMap indirected into the 137959243Sobrien * CcFuncTbl array. 138059243Sobrien */ 138159243Sobrien 138259243Sobrien/*ARGSUSED*/ 138359243SobrienCCRETVAL 1384167465Smpv_cmd_mode(Char c) 138559243Sobrien{ 138659243Sobrien USE(c); 138759243Sobrien InsertPos = 0; 138859243Sobrien ActionFlag = TCSHOP_NOP; /* [Esc] cancels pending action */ 138959243Sobrien ActionPos = 0; 139059243Sobrien DoingArg = 0; 139159243Sobrien if (UndoPtr > Cursor) 139259243Sobrien UndoSize = (int)(UndoPtr - Cursor); 139359243Sobrien else 139459243Sobrien UndoSize = (int)(Cursor - UndoPtr); 139559243Sobrien 139659243Sobrien inputmode = MODE_INSERT; 139759243Sobrien c_alternativ_key_map(1); 139859243Sobrien#ifdef notdef 139959243Sobrien /* 140059243Sobrien * We don't want to move the cursor, because all the editing 140159243Sobrien * commands don't include the character under the cursor. 140259243Sobrien */ 140359243Sobrien if (Cursor > InputBuf) 140459243Sobrien Cursor--; 140559243Sobrien#endif 140659243Sobrien RefCursor(); 140759243Sobrien return(CC_NORM); 140859243Sobrien} 140959243Sobrien 141059243Sobrien/*ARGSUSED*/ 141159243SobrienCCRETVAL 1412167465Smpe_unassigned(Char c) 141359243Sobrien{ /* bound to keys that arn't really assigned */ 141459243Sobrien USE(c); 141559243Sobrien SoundBeep(); 141659243Sobrien flush(); 141759243Sobrien return(CC_NORM); 141859243Sobrien} 141959243Sobrien 1420167465Smp#ifdef notyet 1421145479Smpstatic CCRETVAL 1422167465Smpe_insert_str(Char *c) 1423145479Smp{ 1424145479Smp int i, n; 1425145479Smp 1426145479Smp n = Strlen(c); 1427145479Smp if (LastChar + Argument * n >= InputLim) 1428145479Smp return(CC_ERROR); /* end of buffer space */ 1429145479Smp if (inputmode != MODE_INSERT) { 1430167465Smp c_delafter(Argument * Strlen(c)); 1431145479Smp } 1432145479Smp c_insert(Argument * n); 1433145479Smp while (Argument--) { 1434145479Smp for (i = 0; i < n; i++) 1435145479Smp *Cursor++ = c[i]; 1436145479Smp } 1437145479Smp Refresh(); 1438145479Smp return(CC_NORM); 1439145479Smp} 1440167465Smp#endif 1441145479Smp 144259243SobrienCCRETVAL 1443167465Smpe_insert(Char c) 144459243Sobrien{ 144559243Sobrien#ifndef SHORT_STRINGS 144659243Sobrien c &= ASCII; /* no meta chars ever */ 144759243Sobrien#endif 144859243Sobrien 144959243Sobrien if (!c) 145059243Sobrien return(CC_ERROR); /* no NULs in the input ever!! */ 145159243Sobrien 145259243Sobrien if (LastChar + Argument >= InputLim) 145359243Sobrien return(CC_ERROR); /* end of buffer space */ 145459243Sobrien 145559243Sobrien if (Argument == 1) { /* How was this optimized ???? */ 145659243Sobrien 145759243Sobrien if (inputmode != MODE_INSERT) { 145859243Sobrien UndoBuf[UndoSize++] = *Cursor; 145959243Sobrien UndoBuf[UndoSize] = '\0'; 146059243Sobrien c_delafter(1); /* Do NOT use the saving ONE */ 146159243Sobrien } 146259243Sobrien 146359243Sobrien c_insert(1); 146459243Sobrien *Cursor++ = (Char) c; 146559243Sobrien DoingArg = 0; /* just in case */ 1466145479Smp RefPlusOne(1); /* fast refresh for one char. */ 146759243Sobrien } 146859243Sobrien else { 146959243Sobrien if (inputmode != MODE_INSERT) { 1470145479Smp int i; 1471145479Smp for(i = 0; i < Argument; i++) 1472145479Smp UndoBuf[UndoSize++] = *(Cursor + i); 147359243Sobrien 147459243Sobrien UndoBuf[UndoSize] = '\0'; 147559243Sobrien c_delafter(Argument); /* Do NOT use the saving ONE */ 147659243Sobrien } 147759243Sobrien 147859243Sobrien c_insert(Argument); 147959243Sobrien 148059243Sobrien while (Argument--) 148159243Sobrien *Cursor++ = (Char) c; 148259243Sobrien Refresh(); 148359243Sobrien } 148459243Sobrien 148559243Sobrien if (inputmode == MODE_REPLACE_1) 148659243Sobrien (void) v_cmd_mode(0); 148759243Sobrien 148859243Sobrien return(CC_NORM); 148959243Sobrien} 149059243Sobrien 149159243Sobrienint 1492167465SmpInsertStr(Char *s) /* insert ASCIZ s at cursor (for complete) */ 149359243Sobrien{ 149483098Smp int len; 149559243Sobrien 149659243Sobrien if ((len = (int) Strlen(s)) <= 0) 149759243Sobrien return -1; 149859243Sobrien if (LastChar + len >= InputLim) 149959243Sobrien return -1; /* end of buffer space */ 150059243Sobrien 150159243Sobrien c_insert(len); 150259243Sobrien while (len--) 150359243Sobrien *Cursor++ = *s++; 150459243Sobrien return 0; 150559243Sobrien} 150659243Sobrien 150759243Sobrienvoid 1508167465SmpDeleteBack(int n) /* delete the n characters before . */ 150959243Sobrien{ 151059243Sobrien if (n <= 0) 151159243Sobrien return; 151259243Sobrien if (Cursor >= &InputBuf[n]) { 151359243Sobrien c_delbefore(n); /* delete before dot */ 151459243Sobrien } 151559243Sobrien} 151659243Sobrien 151759243SobrienCCRETVAL 1518167465Smpe_digit(Char c) /* gray magic here */ 151959243Sobrien{ 152059243Sobrien if (!Isdigit(c)) 152159243Sobrien return(CC_ERROR); /* no NULs in the input ever!! */ 152259243Sobrien 152359243Sobrien if (DoingArg) { /* if doing an arg, add this in... */ 152459243Sobrien if (LastCmd == F_ARGFOUR) /* if last command was ^U */ 152559243Sobrien Argument = c - '0'; 152659243Sobrien else { 152759243Sobrien if (Argument > 1000000) 152859243Sobrien return CC_ERROR; 152959243Sobrien Argument = (Argument * 10) + (c - '0'); 153059243Sobrien } 153159243Sobrien return(CC_ARGHACK); 153259243Sobrien } 153359243Sobrien else { 153459243Sobrien if (LastChar + 1 >= InputLim) 153559243Sobrien return CC_ERROR; /* end of buffer space */ 153659243Sobrien 153759243Sobrien if (inputmode != MODE_INSERT) { 153859243Sobrien UndoBuf[UndoSize++] = *Cursor; 153959243Sobrien UndoBuf[UndoSize] = '\0'; 154059243Sobrien c_delafter(1); /* Do NOT use the saving ONE */ 154159243Sobrien } 154259243Sobrien c_insert(1); 154359243Sobrien *Cursor++ = (Char) c; 154459243Sobrien DoingArg = 0; /* just in case */ 1545145479Smp RefPlusOne(1); /* fast refresh for one char. */ 154659243Sobrien } 154759243Sobrien return(CC_NORM); 154859243Sobrien} 154959243Sobrien 155059243SobrienCCRETVAL 1551167465Smpe_argdigit(Char c) /* for ESC-n */ 155259243Sobrien{ 1553167465Smp#ifdef IS_ASCII 155459243Sobrien c &= ASCII; 1555167465Smp#else 1556167465Smp c = CTL_ESC(ASC(c) & ASCII); /* stripping for EBCDIC done the ASCII way */ 1557167465Smp#endif 155859243Sobrien 155959243Sobrien if (!Isdigit(c)) 156059243Sobrien return(CC_ERROR); /* no NULs in the input ever!! */ 156159243Sobrien 156259243Sobrien if (DoingArg) { /* if doing an arg, add this in... */ 156359243Sobrien if (Argument > 1000000) 156459243Sobrien return CC_ERROR; 156559243Sobrien Argument = (Argument * 10) + (c - '0'); 156659243Sobrien } 156759243Sobrien else { /* else starting an argument */ 156859243Sobrien Argument = c - '0'; 156959243Sobrien DoingArg = 1; 157059243Sobrien } 157159243Sobrien return(CC_ARGHACK); 157259243Sobrien} 157359243Sobrien 157459243SobrienCCRETVAL 1575167465Smpv_zero(Char c) /* command mode 0 for vi */ 157659243Sobrien{ 157759243Sobrien if (DoingArg) { /* if doing an arg, add this in... */ 157859243Sobrien if (Argument > 1000000) 157959243Sobrien return CC_ERROR; 158059243Sobrien Argument = (Argument * 10) + (c - '0'); 158159243Sobrien return(CC_ARGHACK); 158259243Sobrien } 158359243Sobrien else { /* else starting an argument */ 158459243Sobrien Cursor = InputBuf; 158559243Sobrien if (ActionFlag & TCSHOP_DELETE) { 158659243Sobrien c_delfini(); 158759243Sobrien return(CC_REFRESH); 158859243Sobrien } 158959243Sobrien RefCursor(); /* move the cursor */ 159059243Sobrien return(CC_NORM); 159159243Sobrien } 159259243Sobrien} 159359243Sobrien 159459243Sobrien/*ARGSUSED*/ 159559243SobrienCCRETVAL 1596167465Smpe_newline(Char c) 159759243Sobrien{ /* always ignore argument */ 159859243Sobrien USE(c); 1599167465Smp if (adrof(STRhighlight) && MarkIsSet) { 1600167465Smp MarkIsSet = 0; 1601167465Smp ClearLines(); 1602167465Smp ClearDisp(); 1603167465Smp Refresh(); 1604167465Smp } 1605167465Smp MarkIsSet = 0; 1606167465Smp 160759243Sobrien /* PastBottom(); NOW done in ed.inputl.c */ 160859243Sobrien *LastChar++ = '\n'; /* for the benefit of CSH */ 160959243Sobrien *LastChar = '\0'; /* just in case */ 161059243Sobrien if (VImode) 161159243Sobrien InsertPos = InputBuf; /* Reset editing position */ 161259243Sobrien return(CC_NEWLINE); 161359243Sobrien} 161459243Sobrien 161559243Sobrien/*ARGSUSED*/ 161659243SobrienCCRETVAL 1617167465Smpe_newline_hold(Char c) 1618167465Smp{ 1619167465Smp USE(c); 1620167465Smp c_save_inputbuf(); 1621167465Smp HistSaved = 0; 1622167465Smp *LastChar++ = '\n'; /* for the benefit of CSH */ 1623167465Smp *LastChar = '\0'; /* just in case */ 1624167465Smp return(CC_NEWLINE); 1625167465Smp} 1626167465Smp 1627167465Smp/*ARGSUSED*/ 1628167465SmpCCRETVAL 1629167465Smpe_newline_down_hist(Char c) 1630167465Smp{ 1631167465Smp USE(c); 1632167465Smp if (Hist_num > 1) { 1633167465Smp HistSaved = Hist_num; 1634167465Smp } 1635167465Smp *LastChar++ = '\n'; /* for the benefit of CSH */ 1636167465Smp *LastChar = '\0'; /* just in case */ 1637167465Smp return(CC_NEWLINE); 1638167465Smp} 1639167465Smp 1640167465Smp/*ARGSUSED*/ 1641167465SmpCCRETVAL 1642167465Smpe_send_eof(Char c) 164359243Sobrien{ /* for when ^D is ONLY send-eof */ 164459243Sobrien USE(c); 164559243Sobrien PastBottom(); 164659243Sobrien *LastChar = '\0'; /* just in case */ 164759243Sobrien return(CC_EOF); 164859243Sobrien} 164959243Sobrien 165059243Sobrien/*ARGSUSED*/ 165159243SobrienCCRETVAL 1652167465Smpe_complete(Char c) 165359243Sobrien{ 165459243Sobrien USE(c); 165559243Sobrien *LastChar = '\0'; /* just in case */ 165659243Sobrien return(CC_COMPLETE); 165759243Sobrien} 165859243Sobrien 165959243Sobrien/*ARGSUSED*/ 166059243SobrienCCRETVAL 1661167465Smpe_complete_back(Char c) 166259243Sobrien{ 166359243Sobrien USE(c); 166459243Sobrien *LastChar = '\0'; /* just in case */ 166559243Sobrien return(CC_COMPLETE_BACK); 166659243Sobrien} 166759243Sobrien 166859243Sobrien/*ARGSUSED*/ 166959243SobrienCCRETVAL 1670167465Smpe_complete_fwd(Char c) 167159243Sobrien{ 167259243Sobrien USE(c); 167359243Sobrien *LastChar = '\0'; /* just in case */ 167459243Sobrien return(CC_COMPLETE_FWD); 167559243Sobrien} 167659243Sobrien 167759243Sobrien/*ARGSUSED*/ 167859243SobrienCCRETVAL 1679167465Smpe_complete_all(Char c) 168059243Sobrien{ 168159243Sobrien USE(c); 168259243Sobrien *LastChar = '\0'; /* just in case */ 168359243Sobrien return(CC_COMPLETE_ALL); 168459243Sobrien} 168559243Sobrien 168659243Sobrien/*ARGSUSED*/ 168759243SobrienCCRETVAL 1688167465Smpv_cm_complete(Char c) 168959243Sobrien{ 169059243Sobrien USE(c); 169159243Sobrien if (Cursor < LastChar) 169259243Sobrien Cursor++; 169359243Sobrien *LastChar = '\0'; /* just in case */ 169459243Sobrien return(CC_COMPLETE); 169559243Sobrien} 169659243Sobrien 169759243Sobrien/*ARGSUSED*/ 169859243SobrienCCRETVAL 1699167465Smpe_toggle_hist(Char c) 170059243Sobrien{ 170159243Sobrien struct Hist *hp; 170259243Sobrien int h; 170359243Sobrien 170459243Sobrien USE(c); 170559243Sobrien *LastChar = '\0'; /* just in case */ 170659243Sobrien 170759243Sobrien if (Hist_num <= 0) { 170859243Sobrien return CC_ERROR; 170959243Sobrien } 171059243Sobrien 171159243Sobrien hp = Histlist.Hnext; 171259243Sobrien if (hp == NULL) { /* this is only if no history */ 171359243Sobrien return(CC_ERROR); 171459243Sobrien } 171559243Sobrien 171659243Sobrien for (h = 1; h < Hist_num; h++) 171759243Sobrien hp = hp->Hnext; 171859243Sobrien 171959243Sobrien if (!CurrentHistLit) { 172059243Sobrien if (hp->histline) { 1721167465Smp copyn(InputBuf, hp->histline, INBUFSIZE);/*FIXBUF*/ 172259243Sobrien CurrentHistLit = 1; 172359243Sobrien } 172459243Sobrien else { 172559243Sobrien return CC_ERROR; 172659243Sobrien } 172759243Sobrien } 172859243Sobrien else { 1729167465Smp Char *p; 1730167465Smp 1731167465Smp p = sprlex(&hp->Hlex); 1732167465Smp copyn(InputBuf, p, sizeof(InputBuf) / sizeof(Char));/*FIXBUF*/ 1733167465Smp xfree(p); 173459243Sobrien CurrentHistLit = 0; 173559243Sobrien } 173659243Sobrien 1737167465Smp LastChar = Strend(InputBuf); 173859243Sobrien if (LastChar > InputBuf) { 173959243Sobrien if (LastChar[-1] == '\n') 174059243Sobrien LastChar--; 174159243Sobrien if (LastChar[-1] == ' ') 174259243Sobrien LastChar--; 174359243Sobrien if (LastChar < InputBuf) 174459243Sobrien LastChar = InputBuf; 174559243Sobrien } 174659243Sobrien 174759243Sobrien#ifdef KSHVI 174859243Sobrien if (VImode) 174959243Sobrien Cursor = InputBuf; 175059243Sobrien else 175159243Sobrien#endif /* KSHVI */ 175259243Sobrien Cursor = LastChar; 175359243Sobrien 175459243Sobrien return(CC_REFRESH); 175559243Sobrien} 175659243Sobrien 175759243Sobrien/*ARGSUSED*/ 175859243SobrienCCRETVAL 1759167465Smpe_up_hist(Char c) 176059243Sobrien{ 176159243Sobrien Char beep = 0; 176259243Sobrien 176359243Sobrien USE(c); 176459243Sobrien UndoAction = TCSHOP_NOP; 176559243Sobrien *LastChar = '\0'; /* just in case */ 176659243Sobrien 176759243Sobrien if (Hist_num == 0) { /* save the current buffer away */ 1768167465Smp HistBuf.len = 0; 1769167465Smp Strbuf_append(&HistBuf, InputBuf); 1770167465Smp Strbuf_terminate(&HistBuf); 177159243Sobrien } 177259243Sobrien 177359243Sobrien Hist_num += Argument; 177459243Sobrien 1775167465Smp if (GetHistLine() == CC_ERROR) { 177659243Sobrien beep = 1; 1777167465Smp (void) GetHistLine(); /* Hist_num was fixed by first call */ 177859243Sobrien } 177959243Sobrien 178059243Sobrien Refresh(); 178159243Sobrien if (beep) 178259243Sobrien return(CC_ERROR); 178359243Sobrien else 178459243Sobrien return(CC_NORM); /* was CC_UP_HIST */ 178559243Sobrien} 178659243Sobrien 178759243Sobrien/*ARGSUSED*/ 178859243SobrienCCRETVAL 1789167465Smpe_down_hist(Char c) 179059243Sobrien{ 179159243Sobrien USE(c); 179259243Sobrien UndoAction = TCSHOP_NOP; 179359243Sobrien *LastChar = '\0'; /* just in case */ 179459243Sobrien 179559243Sobrien Hist_num -= Argument; 179659243Sobrien 179759243Sobrien if (Hist_num < 0) { 179859243Sobrien Hist_num = 0; 179959243Sobrien return(CC_ERROR); /* make it beep */ 180059243Sobrien } 180159243Sobrien 1802167465Smp return(GetHistLine()); 180359243Sobrien} 180459243Sobrien 180559243Sobrien 180659243Sobrien 180759243Sobrien/* 180859243Sobrien * c_hmatch() return True if the pattern matches the prefix 180959243Sobrien */ 181059243Sobrienstatic int 1811167465Smpc_hmatch(Char *str) 181259243Sobrien{ 1813167465Smp if (Strncmp(patbuf.s, str, patbuf.len) == 0) 181459243Sobrien return 1; 1815167465Smp return Gmatch(str, patbuf.s); 181659243Sobrien} 181759243Sobrien 181859243Sobrien/* 181959243Sobrien * c_hsetpat(): Set the history seatch pattern 182059243Sobrien */ 182159243Sobrienstatic void 1822167465Smpc_hsetpat(void) 182359243Sobrien{ 182459243Sobrien if (LastCmd != F_UP_SEARCH_HIST && LastCmd != F_DOWN_SEARCH_HIST) { 1825167465Smp patbuf.len = 0; 1826167465Smp Strbuf_appendn(&patbuf, InputBuf, Cursor - InputBuf); 1827167465Smp Strbuf_terminate(&patbuf); 182859243Sobrien } 182959243Sobrien#ifdef SDEBUG 183059243Sobrien xprintf("\nHist_num = %d\n", Hist_num); 1831167465Smp xprintf("patlen = %d\n", (int)patbuf.len); 1832167465Smp xprintf("patbuf = \"%S\"\n", patbuf.s); 183359243Sobrien xprintf("Cursor %d LastChar %d\n", Cursor - InputBuf, LastChar - InputBuf); 183459243Sobrien#endif 183559243Sobrien} 183659243Sobrien 183759243Sobrien/*ARGSUSED*/ 183859243SobrienCCRETVAL 1839167465Smpe_up_search_hist(Char c) 184059243Sobrien{ 184159243Sobrien struct Hist *hp; 184259243Sobrien int h; 1843145479Smp int found = 0; 184459243Sobrien 184559243Sobrien USE(c); 184659243Sobrien ActionFlag = TCSHOP_NOP; 184759243Sobrien UndoAction = TCSHOP_NOP; 184859243Sobrien *LastChar = '\0'; /* just in case */ 184959243Sobrien if (Hist_num < 0) { 185059243Sobrien#ifdef DEBUG_EDIT 185159243Sobrien xprintf("%s: e_up_search_hist(): Hist_num < 0; resetting.\n", progname); 185259243Sobrien#endif 185359243Sobrien Hist_num = 0; 185459243Sobrien return(CC_ERROR); 185559243Sobrien } 185659243Sobrien 1857167465Smp if (Hist_num == 0) { 1858167465Smp HistBuf.len = 0; 1859167465Smp Strbuf_append(&HistBuf, InputBuf); 1860167465Smp Strbuf_terminate(&HistBuf); 186159243Sobrien } 186259243Sobrien 186359243Sobrien 186459243Sobrien hp = Histlist.Hnext; 186559243Sobrien if (hp == NULL) 186659243Sobrien return(CC_ERROR); 186759243Sobrien 186859243Sobrien c_hsetpat(); /* Set search pattern !! */ 186959243Sobrien 187059243Sobrien for (h = 1; h <= Hist_num; h++) 187159243Sobrien hp = hp->Hnext; 187259243Sobrien 187359243Sobrien while (hp != NULL) { 1874167465Smp Char *hl; 1875167465Smp int matched; 1876167465Smp 1877167465Smp if (hp->histline == NULL) 1878167465Smp hp->histline = sprlex(&hp->Hlex); 1879167465Smp if (HistLit) 1880167465Smp hl = hp->histline; 1881167465Smp else { 1882167465Smp hl = sprlex(&hp->Hlex); 1883167465Smp cleanup_push(hl, xfree); 188459243Sobrien } 188559243Sobrien#ifdef SDEBUG 188659243Sobrien xprintf("Comparing with \"%S\"\n", hl); 188759243Sobrien#endif 1888167465Smp matched = (Strncmp(hl, InputBuf, (size_t) (LastChar - InputBuf)) || 1889167465Smp hl[LastChar-InputBuf]) && c_hmatch(hl); 1890167465Smp if (!HistLit) 1891167465Smp cleanup_until(hl); 1892167465Smp if (matched) { 189359243Sobrien found++; 189459243Sobrien break; 189559243Sobrien } 189659243Sobrien h++; 189759243Sobrien hp = hp->Hnext; 189859243Sobrien } 189959243Sobrien 190059243Sobrien if (!found) { 190159243Sobrien#ifdef SDEBUG 1902167465Smp xprintf("not found\n"); 190359243Sobrien#endif 190459243Sobrien return(CC_ERROR); 190559243Sobrien } 190659243Sobrien 190759243Sobrien Hist_num = h; 190859243Sobrien 1909167465Smp return(GetHistLine()); 191059243Sobrien} 191159243Sobrien 191259243Sobrien/*ARGSUSED*/ 191359243SobrienCCRETVAL 1914167465Smpe_down_search_hist(Char c) 191559243Sobrien{ 191659243Sobrien struct Hist *hp; 191759243Sobrien int h; 1918145479Smp int found = 0; 191959243Sobrien 192059243Sobrien USE(c); 192159243Sobrien ActionFlag = TCSHOP_NOP; 192259243Sobrien UndoAction = TCSHOP_NOP; 192359243Sobrien *LastChar = '\0'; /* just in case */ 192459243Sobrien 192559243Sobrien if (Hist_num == 0) 192659243Sobrien return(CC_ERROR); 192759243Sobrien 192859243Sobrien hp = Histlist.Hnext; 192959243Sobrien if (hp == 0) 193059243Sobrien return(CC_ERROR); 193159243Sobrien 193259243Sobrien c_hsetpat(); /* Set search pattern !! */ 193359243Sobrien 193459243Sobrien for (h = 1; h < Hist_num && hp; h++) { 1935167465Smp Char *hl; 1936167465Smp if (hp->histline == NULL) 1937167465Smp hp->histline = sprlex(&hp->Hlex); 1938167465Smp if (HistLit) 1939167465Smp hl = hp->histline; 1940167465Smp else { 1941167465Smp hl = sprlex(&hp->Hlex); 1942167465Smp cleanup_push(hl, xfree); 194359243Sobrien } 194459243Sobrien#ifdef SDEBUG 194559243Sobrien xprintf("Comparing with \"%S\"\n", hl); 194659243Sobrien#endif 194759243Sobrien if ((Strncmp(hl, InputBuf, (size_t) (LastChar - InputBuf)) || 194859243Sobrien hl[LastChar-InputBuf]) && c_hmatch(hl)) 194959243Sobrien found = h; 1950167465Smp if (!HistLit) 1951167465Smp cleanup_until(hl); 195259243Sobrien hp = hp->Hnext; 195359243Sobrien } 195459243Sobrien 195559243Sobrien if (!found) { /* is it the current history number? */ 1956167465Smp if (!c_hmatch(HistBuf.s)) { 195759243Sobrien#ifdef SDEBUG 1958167465Smp xprintf("not found\n"); 195959243Sobrien#endif 196059243Sobrien return(CC_ERROR); 196159243Sobrien } 196259243Sobrien } 196359243Sobrien 196459243Sobrien Hist_num = found; 196559243Sobrien 1966167465Smp return(GetHistLine()); 196759243Sobrien} 196859243Sobrien 196959243Sobrien/*ARGSUSED*/ 197059243SobrienCCRETVAL 1971167465Smpe_helpme(Char c) 197259243Sobrien{ 197359243Sobrien USE(c); 197459243Sobrien PastBottom(); 197559243Sobrien *LastChar = '\0'; /* just in case */ 197659243Sobrien return(CC_HELPME); 197759243Sobrien} 197859243Sobrien 197959243Sobrien/*ARGSUSED*/ 198059243SobrienCCRETVAL 1981167465Smpe_correct(Char c) 198259243Sobrien{ 198359243Sobrien USE(c); 198459243Sobrien *LastChar = '\0'; /* just in case */ 198559243Sobrien return(CC_CORRECT); 198659243Sobrien} 198759243Sobrien 198859243Sobrien/*ARGSUSED*/ 198959243SobrienCCRETVAL 1990167465Smpe_correctl(Char c) 199159243Sobrien{ 199259243Sobrien USE(c); 199359243Sobrien *LastChar = '\0'; /* just in case */ 199459243Sobrien return(CC_CORRECT_L); 199559243Sobrien} 199659243Sobrien 199759243Sobrien/*ARGSUSED*/ 199859243SobrienCCRETVAL 1999167465Smpe_run_fg_editor(Char c) 200059243Sobrien{ 200183098Smp struct process *pp; 200259243Sobrien 200359243Sobrien USE(c); 200459243Sobrien if ((pp = find_stop_ed()) != NULL) { 200559243Sobrien /* save our editor state so we can restore it */ 2006167465Smp c_save_inputbuf(); 200759243Sobrien Hist_num = 0; /* for the history commands */ 200859243Sobrien 200959243Sobrien /* put the tty in a sane mode */ 201059243Sobrien PastBottom(); 201159243Sobrien (void) Cookedmode(); /* make sure the tty is set up correctly */ 201259243Sobrien 201359243Sobrien /* do it! */ 201459243Sobrien fg_proc_entry(pp); 201559243Sobrien 201659243Sobrien (void) Rawmode(); /* go on */ 201759243Sobrien Refresh(); 2018167465Smp RestoreSaved = 0; 2019167465Smp HistSaved = 0; 202059243Sobrien } 202159243Sobrien return(CC_NORM); 202259243Sobrien} 202359243Sobrien 202459243Sobrien/*ARGSUSED*/ 202559243SobrienCCRETVAL 2026167465Smpe_list_choices(Char c) 202759243Sobrien{ 202859243Sobrien USE(c); 202959243Sobrien PastBottom(); 203059243Sobrien *LastChar = '\0'; /* just in case */ 203159243Sobrien return(CC_LIST_CHOICES); 203259243Sobrien} 203359243Sobrien 203459243Sobrien/*ARGSUSED*/ 203559243SobrienCCRETVAL 2036167465Smpe_list_all(Char c) 203759243Sobrien{ 203859243Sobrien USE(c); 203959243Sobrien PastBottom(); 204059243Sobrien *LastChar = '\0'; /* just in case */ 204159243Sobrien return(CC_LIST_ALL); 204259243Sobrien} 204359243Sobrien 204459243Sobrien/*ARGSUSED*/ 204559243SobrienCCRETVAL 2046167465Smpe_list_glob(Char c) 204759243Sobrien{ 204859243Sobrien USE(c); 204959243Sobrien PastBottom(); 205059243Sobrien *LastChar = '\0'; /* just in case */ 205159243Sobrien return(CC_LIST_GLOB); 205259243Sobrien} 205359243Sobrien 205459243Sobrien/*ARGSUSED*/ 205559243SobrienCCRETVAL 2056167465Smpe_expand_glob(Char c) 205759243Sobrien{ 205859243Sobrien USE(c); 205959243Sobrien *LastChar = '\0'; /* just in case */ 206059243Sobrien return(CC_EXPAND_GLOB); 206159243Sobrien} 206259243Sobrien 206359243Sobrien/*ARGSUSED*/ 206459243SobrienCCRETVAL 2065167465Smpe_normalize_path(Char c) 206659243Sobrien{ 206759243Sobrien USE(c); 206859243Sobrien *LastChar = '\0'; /* just in case */ 206959243Sobrien return(CC_NORMALIZE_PATH); 207059243Sobrien} 207159243Sobrien 207259243Sobrien/*ARGSUSED*/ 207359243SobrienCCRETVAL 2074167465Smpe_normalize_command(Char c) 207559243Sobrien{ 207659243Sobrien USE(c); 207759243Sobrien *LastChar = '\0'; /* just in case */ 207859243Sobrien return(CC_NORMALIZE_COMMAND); 207959243Sobrien} 208059243Sobrien 208159243Sobrien/*ARGSUSED*/ 208259243SobrienCCRETVAL 2083167465Smpe_expand_vars(Char c) 208459243Sobrien{ 208559243Sobrien USE(c); 208659243Sobrien *LastChar = '\0'; /* just in case */ 208759243Sobrien return(CC_EXPAND_VARS); 208859243Sobrien} 208959243Sobrien 209059243Sobrien/*ARGSUSED*/ 209159243SobrienCCRETVAL 2092167465Smpe_which(Char c) 209359243Sobrien{ /* do a fast command line which(1) */ 209459243Sobrien USE(c); 2095167465Smp c_save_inputbuf(); 2096167465Smp Hist_num = 0; /* for the history commands */ 209759243Sobrien PastBottom(); 209859243Sobrien *LastChar = '\0'; /* just in case */ 209959243Sobrien return(CC_WHICH); 210059243Sobrien} 210159243Sobrien 210259243Sobrien/*ARGSUSED*/ 210359243SobrienCCRETVAL 2104167465Smpe_last_item(Char c) 210559243Sobrien{ /* insert the last element of the prev. cmd */ 210683098Smp struct Hist *hp; 210783098Smp struct wordent *wp, *firstp; 210883098Smp int i; 2109167465Smp Char *expanded; 211059243Sobrien 211159243Sobrien USE(c); 211259243Sobrien if (Argument <= 0) 211359243Sobrien return(CC_ERROR); 211459243Sobrien 211559243Sobrien hp = Histlist.Hnext; 211659243Sobrien if (hp == NULL) { /* this is only if no history */ 211759243Sobrien return(CC_ERROR); 211859243Sobrien } 211959243Sobrien 212059243Sobrien wp = (hp->Hlex).prev; 212159243Sobrien 212259243Sobrien if (wp->prev == (struct wordent *) NULL) 212359243Sobrien return(CC_ERROR); /* an empty history entry */ 212459243Sobrien 212559243Sobrien firstp = (hp->Hlex).next; 212659243Sobrien 212759243Sobrien /* back up arg words in lex */ 212859243Sobrien for (i = 0; i < Argument && wp != firstp; i++) { 212959243Sobrien wp = wp->prev; 213059243Sobrien } 213159243Sobrien 2132167465Smp expanded = expand_lex(wp->prev, 0, i - 1); 2133167465Smp if (InsertStr(expanded)) { 2134167465Smp xfree(expanded); 213559243Sobrien return(CC_ERROR); 2136167465Smp } 213759243Sobrien 2138167465Smp xfree(expanded); 213959243Sobrien return(CC_REFRESH); 214059243Sobrien} 214159243Sobrien 214259243Sobrien/*ARGSUSED*/ 214359243SobrienCCRETVAL 2144167465Smpe_dabbrev_expand(Char c) 214559243Sobrien{ /* expand to preceding word matching prefix */ 214683098Smp Char *cp, *ncp, *bp; 214783098Smp struct Hist *hp; 2148167465Smp int arg = 0, i; 2149167465Smp size_t len = 0; 2150145479Smp int found = 0; 2151167465Smp Char *hbuf; 215259243Sobrien static int oldevent, hist, word; 215359243Sobrien static Char *start, *oldcursor; 215459243Sobrien 215559243Sobrien USE(c); 215659243Sobrien if (Argument <= 0) 215759243Sobrien return(CC_ERROR); 215859243Sobrien 215983098Smp cp = c_preword(Cursor, InputBuf, 1, STRshwordsep); 216059243Sobrien if (cp == Cursor || Isspace(*cp)) 216159243Sobrien return(CC_ERROR); 216259243Sobrien 2163167465Smp hbuf = NULL; 216459243Sobrien hp = Histlist.Hnext; 216559243Sobrien bp = InputBuf; 216659243Sobrien if (Argument == 1 && eventno == oldevent && cp == start && 2167167465Smp Cursor == oldcursor && patbuf.len > 0 2168167465Smp && Strncmp(patbuf.s, cp, patbuf.len) == 0){ 216959243Sobrien /* continue previous search - go to last match (hist/word) */ 217059243Sobrien if (hist != 0) { /* need to move up history */ 217159243Sobrien for (i = 1; i < hist && hp != NULL; i++) 217259243Sobrien hp = hp->Hnext; 217359243Sobrien if (hp == NULL) /* "can't happen" */ 2174167465Smp goto err_hbuf; 2175167465Smp hbuf = expand_lex(&hp->Hlex, 0, INT_MAX); 2176167465Smp cp = Strend(hbuf); 217759243Sobrien bp = hbuf; 217859243Sobrien hp = hp->Hnext; 217959243Sobrien } 218083098Smp cp = c_preword(cp, bp, word, STRshwordsep); 218159243Sobrien } else { /* starting new search */ 218259243Sobrien oldevent = eventno; 218359243Sobrien start = cp; 2184167465Smp patbuf.len = 0; 2185167465Smp Strbuf_appendn(&patbuf, cp, Cursor - cp); 218659243Sobrien hist = 0; 218759243Sobrien word = 0; 218859243Sobrien } 218959243Sobrien 219059243Sobrien while (!found) { 219183098Smp ncp = c_preword(cp, bp, 1, STRshwordsep); 219259243Sobrien if (ncp == cp || Isspace(*ncp)) { /* beginning of line */ 219359243Sobrien hist++; 219459243Sobrien word = 0; 219559243Sobrien if (hp == NULL) 2196167465Smp goto err_hbuf; 2197167465Smp hbuf = expand_lex(&hp->Hlex, 0, INT_MAX); 2198167465Smp cp = Strend(hbuf); 219959243Sobrien bp = hbuf; 220059243Sobrien hp = hp->Hnext; 220159243Sobrien continue; 220259243Sobrien } else { 220359243Sobrien word++; 2204167465Smp len = c_endword(ncp-1, cp, 1, STRshwordsep) - ncp + 1; 220559243Sobrien cp = ncp; 220659243Sobrien } 2207167465Smp if (len > patbuf.len && Strncmp(cp, patbuf.s, patbuf.len) == 0) { 220859243Sobrien /* We don't fully check distinct matches as Gnuemacs does: */ 220959243Sobrien if (Argument > 1) { /* just count matches */ 221059243Sobrien if (++arg >= Argument) 221159243Sobrien found++; 221259243Sobrien } else { /* match if distinct from previous */ 2213167465Smp if (len != (size_t)(Cursor - start) 2214167465Smp || Strncmp(cp, start, len) != 0) 221559243Sobrien found++; 221659243Sobrien } 221759243Sobrien } 221859243Sobrien } 221959243Sobrien 222059243Sobrien if (LastChar + len - (Cursor - start) >= InputLim) 2221167465Smp goto err_hbuf; /* no room */ 222259243Sobrien DeleteBack(Cursor - start); 222359243Sobrien c_insert(len); 222459243Sobrien while (len--) 222559243Sobrien *Cursor++ = *cp++; 222659243Sobrien oldcursor = Cursor; 2227167465Smp xfree(hbuf); 222859243Sobrien return(CC_REFRESH); 2229167465Smp 2230167465Smp err_hbuf: 2231167465Smp xfree(hbuf); 2232167465Smp return CC_ERROR; 223359243Sobrien} 223459243Sobrien 223559243Sobrien/*ARGSUSED*/ 223659243SobrienCCRETVAL 2237167465Smpe_yank_kill(Char c) 223859243Sobrien{ /* almost like GnuEmacs */ 223983098Smp int len; 224083098Smp Char *kp, *cp; 224159243Sobrien 224259243Sobrien USE(c); 224383098Smp if (KillRingLen == 0) /* nothing killed */ 224459243Sobrien return(CC_ERROR); 224583098Smp len = Strlen(KillRing[YankPos].buf); 224683098Smp if (LastChar + len >= InputLim) 224759243Sobrien return(CC_ERROR); /* end of buffer space */ 224859243Sobrien 224959243Sobrien /* else */ 225059243Sobrien cp = Cursor; /* for speed */ 225159243Sobrien 225283098Smp c_insert(len); /* open the space, */ 225383098Smp for (kp = KillRing[YankPos].buf; *kp; kp++) /* copy the chars */ 225459243Sobrien *cp++ = *kp; 225559243Sobrien 225683098Smp if (Argument == 1) { /* if no arg */ 225783098Smp Mark = Cursor; /* mark at beginning, cursor at end */ 225883098Smp Cursor = cp; 225983098Smp } else { 226083098Smp Mark = cp; /* else cursor at beginning, mark at end */ 226183098Smp } 226259243Sobrien 2263167465Smp if (adrof(STRhighlight) && MarkIsSet) { 2264167465Smp ClearLines(); 2265167465Smp ClearDisp(); 2266167465Smp } 2267167465Smp MarkIsSet = 0; 226859243Sobrien return(CC_REFRESH); 226959243Sobrien} 227059243Sobrien 227159243Sobrien/*ARGSUSED*/ 227259243SobrienCCRETVAL 2273167465Smpe_yank_pop(Char c) 227483098Smp{ /* almost like GnuEmacs */ 227583098Smp int m_bef_c, del_len, ins_len; 227683098Smp Char *kp, *cp; 227783098Smp 227883098Smp USE(c); 227983098Smp 228083098Smp#if 0 228183098Smp /* XXX This "should" be here, but doesn't work, since LastCmd 228283098Smp gets set on CC_ERROR and CC_ARGHACK, which it shouldn't(?). 228383098Smp (But what about F_ARGFOUR?) I.e. if you hit M-y twice the 228483098Smp second one will "succeed" even if the first one wasn't preceded 228583098Smp by a yank, and giving an argument is impossible. Now we "succeed" 228683098Smp regardless of previous command, which is wrong too of course. */ 228783098Smp if (LastCmd != F_YANK_KILL && LastCmd != F_YANK_POP) 228883098Smp return(CC_ERROR); 228983098Smp#endif 229083098Smp 229183098Smp if (KillRingLen == 0) /* nothing killed */ 229283098Smp return(CC_ERROR); 229383098Smp YankPos -= Argument; 229483098Smp while (YankPos < 0) 229583098Smp YankPos += KillRingLen; 229683098Smp YankPos %= KillRingLen; 229783098Smp 229883098Smp if (Cursor > Mark) { 229983098Smp del_len = Cursor - Mark; 230083098Smp m_bef_c = 1; 230183098Smp } else { 230283098Smp del_len = Mark - Cursor; 230383098Smp m_bef_c = 0; 230483098Smp } 230583098Smp ins_len = Strlen(KillRing[YankPos].buf); 230683098Smp if (LastChar + ins_len - del_len >= InputLim) 230783098Smp return(CC_ERROR); /* end of buffer space */ 230883098Smp 230983098Smp if (m_bef_c) { 231083098Smp c_delbefore(del_len); 231183098Smp } else { 231283098Smp c_delafter(del_len); 231383098Smp } 231483098Smp cp = Cursor; /* for speed */ 231583098Smp 231683098Smp c_insert(ins_len); /* open the space, */ 231783098Smp for (kp = KillRing[YankPos].buf; *kp; kp++) /* copy the chars */ 231883098Smp *cp++ = *kp; 231983098Smp 232083098Smp if (m_bef_c) { 232183098Smp Mark = Cursor; /* mark at beginning, cursor at end */ 232283098Smp Cursor = cp; 232383098Smp } else { 232483098Smp Mark = cp; /* else cursor at beginning, mark at end */ 232583098Smp } 232683098Smp 2327167465Smp if (adrof(STRhighlight) && MarkIsSet) { 2328167465Smp ClearLines(); 2329167465Smp ClearDisp(); 2330167465Smp } 2331167465Smp MarkIsSet = 0; 233283098Smp return(CC_REFRESH); 233383098Smp} 233483098Smp 233583098Smp/*ARGSUSED*/ 233683098SmpCCRETVAL 2337167465Smpv_delprev(Char c) /* Backspace key in insert mode */ 233859243Sobrien{ 233959243Sobrien int rc; 234059243Sobrien 234159243Sobrien USE(c); 234259243Sobrien rc = CC_ERROR; 234359243Sobrien 234459243Sobrien if (InsertPos != 0) { 234559243Sobrien if (Argument <= Cursor - InsertPos) { 234659243Sobrien c_delbefore(Argument); /* delete before */ 234759243Sobrien rc = CC_REFRESH; 234859243Sobrien } 234959243Sobrien } 235059243Sobrien return(rc); 235159243Sobrien} /* v_delprev */ 235259243Sobrien 235359243Sobrien/*ARGSUSED*/ 235459243SobrienCCRETVAL 2355167465Smpe_delprev(Char c) 235659243Sobrien{ 235759243Sobrien USE(c); 235859243Sobrien if (Cursor > InputBuf) { 235959243Sobrien c_delbefore(Argument); /* delete before dot */ 236059243Sobrien return(CC_REFRESH); 236159243Sobrien } 236259243Sobrien else { 236359243Sobrien return(CC_ERROR); 236459243Sobrien } 236559243Sobrien} 236659243Sobrien 236759243Sobrien/*ARGSUSED*/ 236859243SobrienCCRETVAL 2369167465Smpe_delwordprev(Char c) 237059243Sobrien{ 237183098Smp Char *cp; 237259243Sobrien 237359243Sobrien USE(c); 237459243Sobrien if (Cursor == InputBuf) 237559243Sobrien return(CC_ERROR); 237659243Sobrien /* else */ 237759243Sobrien 237859243Sobrien cp = c_prev_word(Cursor, InputBuf, Argument); 237959243Sobrien 238083098Smp c_push_kill(cp, Cursor); /* save the text */ 238159243Sobrien 238259243Sobrien c_delbefore((int)(Cursor - cp)); /* delete before dot */ 238359243Sobrien return(CC_REFRESH); 238459243Sobrien} 238559243Sobrien 238659243Sobrien/* DCS <dcs@neutron.chem.yale.edu>, 9 Oct 93 238759243Sobrien * 238859243Sobrien * Changed the names of some of the ^D family of editor functions to 238959243Sobrien * correspond to what they actually do and created new e_delnext_list 239059243Sobrien * for completeness. 239159243Sobrien * 239259243Sobrien * Old names: New names: 239359243Sobrien * 239459243Sobrien * delete-char delete-char-or-eof 239559243Sobrien * F_DELNEXT F_DELNEXT_EOF 239659243Sobrien * e_delnext e_delnext_eof 239759243Sobrien * edelnxt edelnxteof 239859243Sobrien * delete-char-or-eof delete-char 239959243Sobrien * F_DELNEXT_EOF F_DELNEXT 240059243Sobrien * e_delnext_eof e_delnext 240159243Sobrien * edelnxteof edelnxt 240259243Sobrien * delete-char-or-list delete-char-or-list-or-eof 240359243Sobrien * F_LIST_DELNEXT F_DELNEXT_LIST_EOF 240459243Sobrien * e_list_delnext e_delnext_list_eof 240559243Sobrien * edellsteof 240659243Sobrien * (no old equivalent) delete-char-or-list 240759243Sobrien * F_DELNEXT_LIST 240859243Sobrien * e_delnext_list 240959243Sobrien * e_delnxtlst 241059243Sobrien */ 241159243Sobrien 241259243Sobrien/* added by mtk@ari.ncl.omron.co.jp (920818) */ 241359243Sobrien/* rename e_delnext() -> e_delnext_eof() */ 241459243Sobrien/*ARGSUSED*/ 241559243SobrienCCRETVAL 2416167465Smpe_delnext(Char c) 241759243Sobrien{ 241859243Sobrien USE(c); 241959243Sobrien if (Cursor == LastChar) {/* if I'm at the end */ 242059243Sobrien if (!VImode) { 242159243Sobrien return(CC_ERROR); 242259243Sobrien } 242359243Sobrien else { 242459243Sobrien if (Cursor != InputBuf) 242559243Sobrien Cursor--; 242659243Sobrien else 242759243Sobrien return(CC_ERROR); 242859243Sobrien } 242959243Sobrien } 243059243Sobrien c_delafter(Argument); /* delete after dot */ 243159243Sobrien if (Cursor > LastChar) 243259243Sobrien Cursor = LastChar; /* bounds check */ 243359243Sobrien return(CC_REFRESH); 243459243Sobrien} 243559243Sobrien 243659243Sobrien 243759243Sobrien/*ARGSUSED*/ 243859243SobrienCCRETVAL 2439167465Smpe_delnext_eof(Char c) 244059243Sobrien{ 244159243Sobrien USE(c); 244259243Sobrien if (Cursor == LastChar) {/* if I'm at the end */ 244359243Sobrien if (!VImode) { 244459243Sobrien if (Cursor == InputBuf) { 244559243Sobrien /* if I'm also at the beginning */ 244659243Sobrien so_write(STReof, 4);/* then do a EOF */ 244759243Sobrien flush(); 244859243Sobrien return(CC_EOF); 244959243Sobrien } 245059243Sobrien else 245159243Sobrien return(CC_ERROR); 245259243Sobrien } 245359243Sobrien else { 245459243Sobrien if (Cursor != InputBuf) 245559243Sobrien Cursor--; 245659243Sobrien else 245759243Sobrien return(CC_ERROR); 245859243Sobrien } 245959243Sobrien } 246059243Sobrien c_delafter(Argument); /* delete after dot */ 246159243Sobrien if (Cursor > LastChar) 246259243Sobrien Cursor = LastChar; /* bounds check */ 246359243Sobrien return(CC_REFRESH); 246459243Sobrien} 246559243Sobrien 246659243Sobrien/*ARGSUSED*/ 246759243SobrienCCRETVAL 2468167465Smpe_delnext_list(Char c) 246959243Sobrien{ 247059243Sobrien USE(c); 247159243Sobrien if (Cursor == LastChar) { /* if I'm at the end */ 247259243Sobrien PastBottom(); 247359243Sobrien *LastChar = '\0'; /* just in case */ 247459243Sobrien return(CC_LIST_CHOICES); 247559243Sobrien } 247659243Sobrien else { 247759243Sobrien c_delafter(Argument); /* delete after dot */ 247859243Sobrien if (Cursor > LastChar) 247959243Sobrien Cursor = LastChar; /* bounds check */ 248059243Sobrien return(CC_REFRESH); 248159243Sobrien } 248259243Sobrien} 248359243Sobrien 248459243Sobrien/*ARGSUSED*/ 248559243SobrienCCRETVAL 2486167465Smpe_delnext_list_eof(Char c) 248759243Sobrien{ 248859243Sobrien USE(c); 248959243Sobrien if (Cursor == LastChar) { /* if I'm at the end */ 249059243Sobrien if (Cursor == InputBuf) { /* if I'm also at the beginning */ 249159243Sobrien so_write(STReof, 4);/* then do a EOF */ 249259243Sobrien flush(); 249359243Sobrien return(CC_EOF); 249459243Sobrien } 249559243Sobrien else { 249659243Sobrien PastBottom(); 249759243Sobrien *LastChar = '\0'; /* just in case */ 249859243Sobrien return(CC_LIST_CHOICES); 249959243Sobrien } 250059243Sobrien } 250159243Sobrien else { 250259243Sobrien c_delafter(Argument); /* delete after dot */ 250359243Sobrien if (Cursor > LastChar) 250459243Sobrien Cursor = LastChar; /* bounds check */ 250559243Sobrien return(CC_REFRESH); 250659243Sobrien } 250759243Sobrien} 250859243Sobrien 250959243Sobrien/*ARGSUSED*/ 251059243SobrienCCRETVAL 2511167465Smpe_list_eof(Char c) 251259243Sobrien{ 251359243Sobrien CCRETVAL rv; 251459243Sobrien 251559243Sobrien USE(c); 251659243Sobrien if (Cursor == LastChar && Cursor == InputBuf) { 251759243Sobrien so_write(STReof, 4); /* then do a EOF */ 251859243Sobrien flush(); 251959243Sobrien rv = CC_EOF; 252059243Sobrien } 252159243Sobrien else { 252259243Sobrien PastBottom(); 252359243Sobrien *LastChar = '\0'; /* just in case */ 252459243Sobrien rv = CC_LIST_CHOICES; 252559243Sobrien } 252659243Sobrien return rv; 252759243Sobrien} 252859243Sobrien 252959243Sobrien/*ARGSUSED*/ 253059243SobrienCCRETVAL 2531167465Smpe_delwordnext(Char c) 253259243Sobrien{ 253383098Smp Char *cp; 253459243Sobrien 253559243Sobrien USE(c); 253659243Sobrien if (Cursor == LastChar) 253759243Sobrien return(CC_ERROR); 253859243Sobrien /* else */ 253959243Sobrien 254059243Sobrien cp = c_next_word(Cursor, LastChar, Argument); 254159243Sobrien 254283098Smp c_push_kill(Cursor, cp); /* save the text */ 254359243Sobrien 254459243Sobrien c_delafter((int)(cp - Cursor)); /* delete after dot */ 254559243Sobrien if (Cursor > LastChar) 254659243Sobrien Cursor = LastChar; /* bounds check */ 254759243Sobrien return(CC_REFRESH); 254859243Sobrien} 254959243Sobrien 255059243Sobrien/*ARGSUSED*/ 255159243SobrienCCRETVAL 2552167465Smpe_toend(Char c) 255359243Sobrien{ 255459243Sobrien USE(c); 255559243Sobrien Cursor = LastChar; 255659243Sobrien if (VImode) 255759243Sobrien if (ActionFlag & TCSHOP_DELETE) { 255859243Sobrien c_delfini(); 255959243Sobrien return(CC_REFRESH); 256059243Sobrien } 256159243Sobrien RefCursor(); /* move the cursor */ 256259243Sobrien return(CC_NORM); 256359243Sobrien} 256459243Sobrien 256559243Sobrien/*ARGSUSED*/ 256659243SobrienCCRETVAL 2567167465Smpe_tobeg(Char c) 256859243Sobrien{ 256959243Sobrien USE(c); 257059243Sobrien Cursor = InputBuf; 257159243Sobrien 257259243Sobrien if (VImode) { 257359243Sobrien while (Isspace(*Cursor)) /* We want FIRST non space character */ 257459243Sobrien Cursor++; 257559243Sobrien if (ActionFlag & TCSHOP_DELETE) { 257659243Sobrien c_delfini(); 257759243Sobrien return(CC_REFRESH); 257859243Sobrien } 257959243Sobrien } 258059243Sobrien 258159243Sobrien RefCursor(); /* move the cursor */ 258259243Sobrien return(CC_NORM); 258359243Sobrien} 258459243Sobrien 258559243Sobrien/*ARGSUSED*/ 258659243SobrienCCRETVAL 2587167465Smpe_killend(Char c) 258859243Sobrien{ 258959243Sobrien USE(c); 259083098Smp c_push_kill(Cursor, LastChar); /* copy it */ 2591167465Smp LastChar = Cursor; /* zap! -- delete to end */ 2592167465Smp if (Mark > Cursor) 2593167465Smp Mark = Cursor; 2594167465Smp MarkIsSet = 0; 259559243Sobrien return(CC_REFRESH); 259659243Sobrien} 259759243Sobrien 259859243Sobrien 259959243Sobrien/*ARGSUSED*/ 260059243SobrienCCRETVAL 2601167465Smpe_killbeg(Char c) 260259243Sobrien{ 260359243Sobrien USE(c); 260483098Smp c_push_kill(InputBuf, Cursor); /* copy it */ 260559243Sobrien c_delbefore((int)(Cursor - InputBuf)); 2606145479Smp if (Mark && Mark > Cursor) 2607145479Smp Mark -= Cursor-InputBuf; 260859243Sobrien return(CC_REFRESH); 260959243Sobrien} 261059243Sobrien 261159243Sobrien/*ARGSUSED*/ 261259243SobrienCCRETVAL 2613167465Smpe_killall(Char c) 261459243Sobrien{ 261559243Sobrien USE(c); 261683098Smp c_push_kill(InputBuf, LastChar); /* copy it */ 2617145479Smp Cursor = Mark = LastChar = InputBuf; /* zap! -- delete all of it */ 2618167465Smp MarkIsSet = 0; 261959243Sobrien return(CC_REFRESH); 262059243Sobrien} 262159243Sobrien 262259243Sobrien/*ARGSUSED*/ 262359243SobrienCCRETVAL 2624167465Smpe_killregion(Char c) 262559243Sobrien{ 262659243Sobrien USE(c); 262759243Sobrien if (!Mark) 262859243Sobrien return(CC_ERROR); 262959243Sobrien 263059243Sobrien if (Mark > Cursor) { 263183098Smp c_push_kill(Cursor, Mark); /* copy it */ 263283098Smp c_delafter((int)(Mark - Cursor)); /* delete it - UNUSED BY VI mode */ 263383098Smp Mark = Cursor; 263459243Sobrien } 263559243Sobrien else { /* mark is before cursor */ 263683098Smp c_push_kill(Mark, Cursor); /* copy it */ 263783098Smp c_delbefore((int)(Cursor - Mark)); 263859243Sobrien } 2639167465Smp if (adrof(STRhighlight) && MarkIsSet) { 2640167465Smp ClearLines(); 2641167465Smp ClearDisp(); 2642167465Smp } 2643167465Smp MarkIsSet = 0; 264459243Sobrien return(CC_REFRESH); 264559243Sobrien} 264659243Sobrien 264759243Sobrien/*ARGSUSED*/ 264859243SobrienCCRETVAL 2649167465Smpe_copyregion(Char c) 265059243Sobrien{ 265159243Sobrien USE(c); 265259243Sobrien if (!Mark) 265359243Sobrien return(CC_ERROR); 265459243Sobrien 265559243Sobrien if (Mark > Cursor) { 265683098Smp c_push_kill(Cursor, Mark); /* copy it */ 265759243Sobrien } 265859243Sobrien else { /* mark is before cursor */ 265983098Smp c_push_kill(Mark, Cursor); /* copy it */ 266059243Sobrien } 266159243Sobrien return(CC_NORM); /* don't even need to Refresh() */ 266259243Sobrien} 266359243Sobrien 266459243Sobrien/*ARGSUSED*/ 266559243SobrienCCRETVAL 2666167465Smpe_charswitch(Char cc) 266759243Sobrien{ 266883098Smp Char c; 266959243Sobrien 267059243Sobrien USE(cc); 267159243Sobrien 267259243Sobrien /* do nothing if we are at beginning of line or have only one char */ 267359243Sobrien if (Cursor == &InputBuf[0] || LastChar == &InputBuf[1]) { 267459243Sobrien return(CC_ERROR); 267559243Sobrien } 267659243Sobrien 267759243Sobrien if (Cursor < LastChar) { 267859243Sobrien Cursor++; 267959243Sobrien } 268059243Sobrien c = Cursor[-2]; 268159243Sobrien Cursor[-2] = Cursor[-1]; 268259243Sobrien Cursor[-1] = c; 268359243Sobrien return(CC_REFRESH); 268459243Sobrien} 268559243Sobrien 268659243Sobrien/*ARGSUSED*/ 268759243SobrienCCRETVAL 2688167465Smpe_gcharswitch(Char cc) 268959243Sobrien{ /* gosmacs style ^T */ 269083098Smp Char c; 269159243Sobrien 269259243Sobrien USE(cc); 269359243Sobrien if (Cursor > &InputBuf[1]) {/* must have at least two chars entered */ 269459243Sobrien c = Cursor[-2]; 269559243Sobrien Cursor[-2] = Cursor[-1]; 269659243Sobrien Cursor[-1] = c; 269759243Sobrien return(CC_REFRESH); 269859243Sobrien } 269959243Sobrien else { 270059243Sobrien return(CC_ERROR); 270159243Sobrien } 270259243Sobrien} 270359243Sobrien 270459243Sobrien/*ARGSUSED*/ 270559243SobrienCCRETVAL 2706167465Smpe_charback(Char c) 270759243Sobrien{ 270859243Sobrien USE(c); 270959243Sobrien if (Cursor > InputBuf) { 2710167465Smp if (Argument > Cursor - InputBuf) 271159243Sobrien Cursor = InputBuf; 271259243Sobrien else 2713167465Smp Cursor -= Argument; 271459243Sobrien 271559243Sobrien if (VImode) 271659243Sobrien if (ActionFlag & TCSHOP_DELETE) { 271759243Sobrien c_delfini(); 271859243Sobrien return(CC_REFRESH); 271959243Sobrien } 272059243Sobrien 272159243Sobrien RefCursor(); 272259243Sobrien return(CC_NORM); 272359243Sobrien } 272459243Sobrien else { 272559243Sobrien return(CC_ERROR); 272659243Sobrien } 272759243Sobrien} 272859243Sobrien 272959243Sobrien/*ARGSUSED*/ 273059243SobrienCCRETVAL 2731167465Smpv_wordback(Char c) 273259243Sobrien{ 273359243Sobrien USE(c); 273459243Sobrien if (Cursor == InputBuf) 273559243Sobrien return(CC_ERROR); 273659243Sobrien /* else */ 273759243Sobrien 273883098Smp Cursor = c_preword(Cursor, InputBuf, Argument, STRshwspace); /* bounds check */ 273959243Sobrien 274059243Sobrien if (ActionFlag & TCSHOP_DELETE) { 274159243Sobrien c_delfini(); 274259243Sobrien return(CC_REFRESH); 274359243Sobrien } 274459243Sobrien 274559243Sobrien RefCursor(); 274659243Sobrien return(CC_NORM); 274759243Sobrien} 274859243Sobrien 274959243Sobrien/*ARGSUSED*/ 275059243SobrienCCRETVAL 2751167465Smpe_wordback(Char c) 275259243Sobrien{ 275359243Sobrien USE(c); 275459243Sobrien if (Cursor == InputBuf) 275559243Sobrien return(CC_ERROR); 275659243Sobrien /* else */ 275759243Sobrien 275859243Sobrien Cursor = c_prev_word(Cursor, InputBuf, Argument); /* bounds check */ 275959243Sobrien 276059243Sobrien if (VImode) 276159243Sobrien if (ActionFlag & TCSHOP_DELETE) { 276259243Sobrien c_delfini(); 276359243Sobrien return(CC_REFRESH); 276459243Sobrien } 276559243Sobrien 276659243Sobrien RefCursor(); 276759243Sobrien return(CC_NORM); 276859243Sobrien} 276959243Sobrien 277059243Sobrien/*ARGSUSED*/ 277159243SobrienCCRETVAL 2772167465Smpe_charfwd(Char c) 277359243Sobrien{ 277459243Sobrien USE(c); 277559243Sobrien if (Cursor < LastChar) { 2776167465Smp Cursor += Argument; 277759243Sobrien if (Cursor > LastChar) 277859243Sobrien Cursor = LastChar; 277959243Sobrien 278059243Sobrien if (VImode) 278159243Sobrien if (ActionFlag & TCSHOP_DELETE) { 278259243Sobrien c_delfini(); 278359243Sobrien return(CC_REFRESH); 278459243Sobrien } 278559243Sobrien 278659243Sobrien RefCursor(); 278759243Sobrien return(CC_NORM); 278859243Sobrien } 278959243Sobrien else { 279059243Sobrien return(CC_ERROR); 279159243Sobrien } 279259243Sobrien} 279359243Sobrien 279459243Sobrien/*ARGSUSED*/ 279559243SobrienCCRETVAL 2796167465Smpe_wordfwd(Char c) 279759243Sobrien{ 279859243Sobrien USE(c); 279959243Sobrien if (Cursor == LastChar) 280059243Sobrien return(CC_ERROR); 280159243Sobrien /* else */ 280259243Sobrien 280359243Sobrien Cursor = c_next_word(Cursor, LastChar, Argument); 280459243Sobrien 280559243Sobrien if (VImode) 280659243Sobrien if (ActionFlag & TCSHOP_DELETE) { 280759243Sobrien c_delfini(); 280859243Sobrien return(CC_REFRESH); 280959243Sobrien } 281059243Sobrien 281159243Sobrien RefCursor(); 281259243Sobrien return(CC_NORM); 281359243Sobrien} 281459243Sobrien 281559243Sobrien/*ARGSUSED*/ 281659243SobrienCCRETVAL 2817167465Smpv_wordfwd(Char c) 281859243Sobrien{ 281959243Sobrien USE(c); 282059243Sobrien if (Cursor == LastChar) 282159243Sobrien return(CC_ERROR); 282259243Sobrien /* else */ 282359243Sobrien 282459243Sobrien Cursor = c_nexword(Cursor, LastChar, Argument); 282559243Sobrien 282659243Sobrien if (VImode) 282759243Sobrien if (ActionFlag & TCSHOP_DELETE) { 282859243Sobrien c_delfini(); 282959243Sobrien return(CC_REFRESH); 283059243Sobrien } 283159243Sobrien 283259243Sobrien RefCursor(); 283359243Sobrien return(CC_NORM); 283459243Sobrien} 283559243Sobrien 283659243Sobrien/*ARGSUSED*/ 283759243SobrienCCRETVAL 2838167465Smpv_wordbegnext(Char c) 283959243Sobrien{ 284059243Sobrien USE(c); 284159243Sobrien if (Cursor == LastChar) 284259243Sobrien return(CC_ERROR); 284359243Sobrien /* else */ 284459243Sobrien 284559243Sobrien Cursor = c_next_word(Cursor, LastChar, Argument); 284659243Sobrien if (Cursor < LastChar) 284759243Sobrien Cursor++; 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 285959243Sobrien/*ARGSUSED*/ 286059243Sobrienstatic CCRETVAL 2861167465Smpv_repeat_srch(int c) 286259243Sobrien{ 286359243Sobrien CCRETVAL rv = CC_ERROR; 286459243Sobrien#ifdef SDEBUG 2865167465Smp xprintf("dir %d patlen %d patbuf %S\n", 2866167465Smp c, (int)patbuf.len, patbuf.s); 286759243Sobrien#endif 286859243Sobrien 286959243Sobrien LastCmd = (KEYCMD) c; /* Hack to stop c_hsetpat */ 287059243Sobrien LastChar = InputBuf; 287159243Sobrien switch (c) { 287259243Sobrien case F_DOWN_SEARCH_HIST: 287359243Sobrien rv = e_down_search_hist(0); 287459243Sobrien break; 287559243Sobrien case F_UP_SEARCH_HIST: 287659243Sobrien rv = e_up_search_hist(0); 287759243Sobrien break; 287859243Sobrien default: 287959243Sobrien break; 288059243Sobrien } 288159243Sobrien return rv; 288259243Sobrien} 288359243Sobrien 288459243Sobrienstatic CCRETVAL 2885167465Smpv_csearch_back(Char ch, int count, int tflag) 288659243Sobrien{ 288759243Sobrien Char *cp; 288859243Sobrien 288959243Sobrien cp = Cursor; 289059243Sobrien while (count--) { 289159243Sobrien if (*cp == ch) 289259243Sobrien cp--; 289359243Sobrien while (cp > InputBuf && *cp != ch) 289459243Sobrien cp--; 289559243Sobrien } 289659243Sobrien 289759243Sobrien if (cp < InputBuf || (cp == InputBuf && *cp != ch)) 289859243Sobrien return(CC_ERROR); 289959243Sobrien 290059243Sobrien if (*cp == ch && tflag) 290159243Sobrien cp++; 290259243Sobrien 290359243Sobrien Cursor = cp; 290459243Sobrien 290559243Sobrien if (ActionFlag & TCSHOP_DELETE) { 290659243Sobrien Cursor++; 290759243Sobrien c_delfini(); 290859243Sobrien return(CC_REFRESH); 290959243Sobrien } 291059243Sobrien 291159243Sobrien RefCursor(); 291259243Sobrien return(CC_NORM); 291359243Sobrien} 291459243Sobrien 291559243Sobrienstatic CCRETVAL 2916167465Smpv_csearch_fwd(Char ch, int count, int tflag) 291759243Sobrien{ 291859243Sobrien Char *cp; 291959243Sobrien 292059243Sobrien cp = Cursor; 292159243Sobrien while (count--) { 292259243Sobrien if(*cp == ch) 292359243Sobrien cp++; 292459243Sobrien while (cp < LastChar && *cp != ch) 292559243Sobrien cp++; 292659243Sobrien } 292759243Sobrien 292859243Sobrien if (cp >= LastChar) 292959243Sobrien return(CC_ERROR); 293059243Sobrien 293159243Sobrien if (*cp == ch && tflag) 293259243Sobrien cp--; 293359243Sobrien 293459243Sobrien Cursor = cp; 293559243Sobrien 293659243Sobrien if (ActionFlag & TCSHOP_DELETE) { 293759243Sobrien Cursor++; 293859243Sobrien c_delfini(); 293959243Sobrien return(CC_REFRESH); 294059243Sobrien } 294159243Sobrien RefCursor(); 294259243Sobrien return(CC_NORM); 294359243Sobrien} 294459243Sobrien 294559243Sobrien/*ARGSUSED*/ 294659243Sobrienstatic CCRETVAL 2947167465Smpv_action(int c) 294859243Sobrien{ 294983098Smp Char *cp, *kp; 295059243Sobrien 295159243Sobrien if (ActionFlag == TCSHOP_DELETE) { 295259243Sobrien ActionFlag = TCSHOP_NOP; 295359243Sobrien ActionPos = 0; 295459243Sobrien 295559243Sobrien UndoSize = 0; 295659243Sobrien kp = UndoBuf; 295759243Sobrien for (cp = InputBuf; cp < LastChar; cp++) { 295859243Sobrien *kp++ = *cp; 295959243Sobrien UndoSize++; 296059243Sobrien } 296159243Sobrien 296259243Sobrien UndoAction = TCSHOP_INSERT; 296359243Sobrien UndoPtr = InputBuf; 296459243Sobrien LastChar = InputBuf; 296559243Sobrien Cursor = InputBuf; 296659243Sobrien if (c & TCSHOP_INSERT) 296759243Sobrien c_alternativ_key_map(0); 296859243Sobrien 296959243Sobrien return(CC_REFRESH); 297059243Sobrien } 297159243Sobrien#ifdef notdef 297259243Sobrien else if (ActionFlag == TCSHOP_NOP) { 297359243Sobrien#endif 297459243Sobrien ActionPos = Cursor; 297559243Sobrien ActionFlag = c; 297659243Sobrien return(CC_ARGHACK); /* Do NOT clear out argument */ 297759243Sobrien#ifdef notdef 297859243Sobrien } 297959243Sobrien else { 298059243Sobrien ActionFlag = 0; 298159243Sobrien ActionPos = 0; 298259243Sobrien return(CC_ERROR); 298359243Sobrien } 298459243Sobrien#endif 298559243Sobrien} 298659243Sobrien 298759243Sobrien#ifdef COMMENT 298859243Sobrien/* by: Brian Allison <uiucdcs!convex!allison@RUTGERS.EDU> */ 298959243Sobrienstatic void 2990167465Smpc_get_word(Char **begin, Char **end) 299159243Sobrien{ 299259243Sobrien Char *cp; 299359243Sobrien 299459243Sobrien cp = &Cursor[0]; 299559243Sobrien while (Argument--) { 299659243Sobrien while ((cp <= LastChar) && (isword(*cp))) 299759243Sobrien cp++; 299859243Sobrien *end = --cp; 299959243Sobrien while ((cp >= InputBuf) && (isword(*cp))) 300059243Sobrien cp--; 300159243Sobrien *begin = ++cp; 300259243Sobrien } 300359243Sobrien} 300459243Sobrien#endif /* COMMENT */ 300559243Sobrien 300659243Sobrien/*ARGSUSED*/ 300759243SobrienCCRETVAL 3008167465Smpe_uppercase(Char c) 300959243Sobrien{ 301059243Sobrien Char *cp, *end; 301159243Sobrien 301259243Sobrien USE(c); 301359243Sobrien end = c_next_word(Cursor, LastChar, Argument); 301459243Sobrien 301559243Sobrien for (cp = Cursor; cp < end; cp++) /* PWP: was cp=begin */ 301659243Sobrien if (Islower(*cp)) 301759243Sobrien *cp = Toupper(*cp); 301859243Sobrien 301959243Sobrien Cursor = end; 302059243Sobrien if (Cursor > LastChar) 302159243Sobrien Cursor = LastChar; 302259243Sobrien return(CC_REFRESH); 302359243Sobrien} 302459243Sobrien 302559243Sobrien 302659243Sobrien/*ARGSUSED*/ 302759243SobrienCCRETVAL 3028167465Smpe_capitolcase(Char c) 302959243Sobrien{ 303059243Sobrien Char *cp, *end; 303159243Sobrien 303259243Sobrien USE(c); 303359243Sobrien end = c_next_word(Cursor, LastChar, Argument); 303459243Sobrien 303559243Sobrien cp = Cursor; 303659243Sobrien for (; cp < end; cp++) { 303759243Sobrien if (Isalpha(*cp)) { 303859243Sobrien if (Islower(*cp)) 303959243Sobrien *cp = Toupper(*cp); 304059243Sobrien cp++; 304159243Sobrien break; 304259243Sobrien } 304359243Sobrien } 304459243Sobrien for (; cp < end; cp++) 304559243Sobrien if (Isupper(*cp)) 304659243Sobrien *cp = Tolower(*cp); 304759243Sobrien 304859243Sobrien Cursor = end; 304959243Sobrien if (Cursor > LastChar) 305059243Sobrien Cursor = LastChar; 305159243Sobrien return(CC_REFRESH); 305259243Sobrien} 305359243Sobrien 305459243Sobrien/*ARGSUSED*/ 305559243SobrienCCRETVAL 3056167465Smpe_lowercase(Char c) 305759243Sobrien{ 305859243Sobrien Char *cp, *end; 305959243Sobrien 306059243Sobrien USE(c); 306159243Sobrien end = c_next_word(Cursor, LastChar, Argument); 306259243Sobrien 306359243Sobrien for (cp = Cursor; cp < end; cp++) 306459243Sobrien if (Isupper(*cp)) 306559243Sobrien *cp = Tolower(*cp); 306659243Sobrien 306759243Sobrien Cursor = end; 306859243Sobrien if (Cursor > LastChar) 306959243Sobrien Cursor = LastChar; 307059243Sobrien return(CC_REFRESH); 307159243Sobrien} 307259243Sobrien 307359243Sobrien 307459243Sobrien/*ARGSUSED*/ 307559243SobrienCCRETVAL 3076167465Smpe_set_mark(Char c) 307759243Sobrien{ 307859243Sobrien USE(c); 3079167465Smp if (adrof(STRhighlight) && MarkIsSet && Mark != Cursor) { 3080167465Smp ClearLines(); 3081167465Smp ClearDisp(); 3082167465Smp Refresh(); 3083167465Smp } 308459243Sobrien Mark = Cursor; 3085167465Smp MarkIsSet = 1; 308659243Sobrien return(CC_NORM); 308759243Sobrien} 308859243Sobrien 308959243Sobrien/*ARGSUSED*/ 309059243SobrienCCRETVAL 3091167465Smpe_exchange_mark(Char c) 309259243Sobrien{ 309383098Smp Char *cp; 309459243Sobrien 309559243Sobrien USE(c); 309659243Sobrien cp = Cursor; 309759243Sobrien Cursor = Mark; 309859243Sobrien Mark = cp; 309959243Sobrien RefCursor(); 310059243Sobrien return(CC_NORM); 310159243Sobrien} 310259243Sobrien 310359243Sobrien/*ARGSUSED*/ 310459243SobrienCCRETVAL 3105167465Smpe_argfour(Char c) 310659243Sobrien{ /* multiply current argument by 4 */ 310759243Sobrien USE(c); 310859243Sobrien if (Argument > 1000000) 310959243Sobrien return CC_ERROR; 311059243Sobrien DoingArg = 1; 311159243Sobrien Argument *= 4; 311259243Sobrien return(CC_ARGHACK); 311359243Sobrien} 311459243Sobrien 3115167465Smpstatic void 3116167465Smpquote_mode_cleanup(void *unused) 3117167465Smp{ 3118167465Smp USE(unused); 3119167465Smp QuoteModeOff(); 3120167465Smp} 3121167465Smp 312259243Sobrien/*ARGSUSED*/ 312359243SobrienCCRETVAL 3124167465Smpe_quote(Char c) 312559243Sobrien{ 312659243Sobrien Char ch; 312759243Sobrien int num; 312859243Sobrien 312959243Sobrien USE(c); 313059243Sobrien QuoteModeOn(); 3131167465Smp cleanup_push(&c, quote_mode_cleanup); /* Using &c just as a mark */ 313259243Sobrien num = GetNextChar(&ch); 3133167465Smp cleanup_until(&c); 313459243Sobrien if (num == 1) 313559243Sobrien return e_insert(ch); 313659243Sobrien else 313759243Sobrien return e_send_eof(0); 313859243Sobrien} 313959243Sobrien 314059243Sobrien/*ARGSUSED*/ 314159243SobrienCCRETVAL 3142167465Smpe_metanext(Char c) 314359243Sobrien{ 314459243Sobrien USE(c); 314559243Sobrien MetaNext = 1; 314659243Sobrien return(CC_ARGHACK); /* preserve argument */ 314759243Sobrien} 314859243Sobrien 314959243Sobrien#ifdef notdef 315059243Sobrien/*ARGSUSED*/ 315159243SobrienCCRETVAL 3152167465Smpe_extendnext(Char c) 315359243Sobrien{ 315459243Sobrien CurrentKeyMap = CcAltMap; 315559243Sobrien return(CC_ARGHACK); /* preserve argument */ 315659243Sobrien} 315759243Sobrien 315859243Sobrien#endif 315959243Sobrien 316059243Sobrien/*ARGSUSED*/ 316159243SobrienCCRETVAL 3162167465Smpv_insbeg(Char c) 316359243Sobrien{ /* move to beginning of line and start vi 316459243Sobrien * insert mode */ 316559243Sobrien USE(c); 316659243Sobrien Cursor = InputBuf; 316759243Sobrien InsertPos = Cursor; 316859243Sobrien 316959243Sobrien UndoPtr = Cursor; 317059243Sobrien UndoAction = TCSHOP_DELETE; 317159243Sobrien 317259243Sobrien RefCursor(); /* move the cursor */ 317359243Sobrien c_alternativ_key_map(0); 317459243Sobrien return(CC_NORM); 317559243Sobrien} 317659243Sobrien 317759243Sobrien/*ARGSUSED*/ 317859243SobrienCCRETVAL 3179167465Smpv_replone(Char c) 318059243Sobrien{ /* vi mode overwrite one character */ 318159243Sobrien USE(c); 318259243Sobrien c_alternativ_key_map(0); 318359243Sobrien inputmode = MODE_REPLACE_1; 318459243Sobrien UndoAction = TCSHOP_CHANGE; /* Set Up for VI undo command */ 318559243Sobrien UndoPtr = Cursor; 318659243Sobrien UndoSize = 0; 318759243Sobrien return(CC_NORM); 318859243Sobrien} 318959243Sobrien 319059243Sobrien/*ARGSUSED*/ 319159243SobrienCCRETVAL 3192167465Smpv_replmode(Char c) 319359243Sobrien{ /* vi mode start overwriting */ 319459243Sobrien USE(c); 319559243Sobrien c_alternativ_key_map(0); 319659243Sobrien inputmode = MODE_REPLACE; 319759243Sobrien UndoAction = TCSHOP_CHANGE; /* Set Up for VI undo command */ 319859243Sobrien UndoPtr = Cursor; 319959243Sobrien UndoSize = 0; 320059243Sobrien return(CC_NORM); 320159243Sobrien} 320259243Sobrien 320359243Sobrien/*ARGSUSED*/ 320459243SobrienCCRETVAL 3205167465Smpv_substchar(Char c) 320659243Sobrien{ /* vi mode substitute for one char */ 320759243Sobrien USE(c); 320859243Sobrien c_delafter(Argument); 320959243Sobrien c_alternativ_key_map(0); 321059243Sobrien return(CC_REFRESH); 321159243Sobrien} 321259243Sobrien 321359243Sobrien/*ARGSUSED*/ 321459243SobrienCCRETVAL 3215167465Smpv_substline(Char c) 321659243Sobrien{ /* vi mode replace whole line */ 321759243Sobrien USE(c); 321859243Sobrien (void) e_killall(0); 321959243Sobrien c_alternativ_key_map(0); 322059243Sobrien return(CC_REFRESH); 322159243Sobrien} 322259243Sobrien 322359243Sobrien/*ARGSUSED*/ 322459243SobrienCCRETVAL 3225167465Smpv_chgtoend(Char c) 322659243Sobrien{ /* vi mode change to end of line */ 322759243Sobrien USE(c); 322859243Sobrien (void) e_killend(0); 322959243Sobrien c_alternativ_key_map(0); 323059243Sobrien return(CC_REFRESH); 323159243Sobrien} 323259243Sobrien 323359243Sobrien/*ARGSUSED*/ 323459243SobrienCCRETVAL 3235167465Smpv_insert(Char c) 323659243Sobrien{ /* vi mode start inserting */ 323759243Sobrien USE(c); 323859243Sobrien c_alternativ_key_map(0); 323959243Sobrien 324059243Sobrien InsertPos = Cursor; 324159243Sobrien UndoPtr = Cursor; 324259243Sobrien UndoAction = TCSHOP_DELETE; 324359243Sobrien 324459243Sobrien return(CC_NORM); 324559243Sobrien} 324659243Sobrien 324759243Sobrien/*ARGSUSED*/ 324859243SobrienCCRETVAL 3249167465Smpv_add(Char c) 325059243Sobrien{ /* vi mode start adding */ 325159243Sobrien USE(c); 325259243Sobrien c_alternativ_key_map(0); 325359243Sobrien if (Cursor < LastChar) 325459243Sobrien { 325559243Sobrien Cursor++; 325659243Sobrien if (Cursor > LastChar) 325759243Sobrien Cursor = LastChar; 325859243Sobrien RefCursor(); 325959243Sobrien } 326059243Sobrien 326159243Sobrien InsertPos = Cursor; 326259243Sobrien UndoPtr = Cursor; 326359243Sobrien UndoAction = TCSHOP_DELETE; 326459243Sobrien 326559243Sobrien return(CC_NORM); 326659243Sobrien} 326759243Sobrien 326859243Sobrien/*ARGSUSED*/ 326959243SobrienCCRETVAL 3270167465Smpv_addend(Char c) 327159243Sobrien{ /* vi mode to add at end of line */ 327259243Sobrien USE(c); 327359243Sobrien c_alternativ_key_map(0); 327459243Sobrien Cursor = LastChar; 327559243Sobrien 327659243Sobrien InsertPos = LastChar; /* Mark where insertion begins */ 327759243Sobrien UndoPtr = LastChar; 327859243Sobrien UndoAction = TCSHOP_DELETE; 327959243Sobrien 328059243Sobrien RefCursor(); 328159243Sobrien return(CC_NORM); 328259243Sobrien} 328359243Sobrien 328459243Sobrien/*ARGSUSED*/ 328559243SobrienCCRETVAL 3286167465Smpv_change_case(Char cc) 328759243Sobrien{ 3288145479Smp Char c; 328959243Sobrien 329059243Sobrien USE(cc); 329159243Sobrien if (Cursor < LastChar) { 329269408Sache#ifndef WINNT_NATIVE 329359243Sobrien c = *Cursor; 329459243Sobrien#else 329559243Sobrien c = CHAR & *Cursor; 329669408Sache#endif /* WINNT_NATIVE */ 329759243Sobrien if (Isupper(c)) 329859243Sobrien *Cursor++ = Tolower(c); 329959243Sobrien else if (Islower(c)) 330059243Sobrien *Cursor++ = Toupper(c); 330159243Sobrien else 330259243Sobrien Cursor++; 3303145479Smp RefPlusOne(1); /* fast refresh for one char */ 330459243Sobrien return(CC_NORM); 330559243Sobrien } 330659243Sobrien return(CC_ERROR); 330759243Sobrien} 330859243Sobrien 330959243Sobrien/*ARGSUSED*/ 331059243SobrienCCRETVAL 3311167465Smpe_expand(Char c) 331259243Sobrien{ 331383098Smp Char *p; 331459243Sobrien 331559243Sobrien USE(c); 331659243Sobrien for (p = InputBuf; Isspace(*p); p++) 331759243Sobrien continue; 331859243Sobrien if (p == LastChar) 331959243Sobrien return(CC_ERROR); 332059243Sobrien 332159243Sobrien justpr++; 332259243Sobrien Expand++; 332359243Sobrien return(e_newline(0)); 332459243Sobrien} 332559243Sobrien 332659243Sobrien/*ARGSUSED*/ 332759243SobrienCCRETVAL 3328167465Smpe_startover(Char c) 332959243Sobrien{ /* erase all of current line, start again */ 333059243Sobrien USE(c); 333159243Sobrien ResetInLine(0); /* reset the input pointers */ 333259243Sobrien return(CC_REFRESH); 333359243Sobrien} 333459243Sobrien 333559243Sobrien/*ARGSUSED*/ 333659243SobrienCCRETVAL 3337167465Smpe_redisp(Char c) 333859243Sobrien{ 333959243Sobrien USE(c); 334059243Sobrien ClearLines(); 334159243Sobrien ClearDisp(); 334259243Sobrien return(CC_REFRESH); 334359243Sobrien} 334459243Sobrien 334559243Sobrien/*ARGSUSED*/ 334659243SobrienCCRETVAL 3347167465Smpe_cleardisp(Char c) 334859243Sobrien{ 334959243Sobrien USE(c); 335059243Sobrien ClearScreen(); /* clear the whole real screen */ 335159243Sobrien ClearDisp(); /* reset everything */ 335259243Sobrien return(CC_REFRESH); 335359243Sobrien} 335459243Sobrien 335559243Sobrien/*ARGSUSED*/ 335659243SobrienCCRETVAL 3357167465Smpe_tty_int(Char c) 335859243Sobrien{ 335959243Sobrien USE(c); 336069408Sache#if defined(_MINIX) || defined(WINNT_NATIVE) 336159243Sobrien /* SAK PATCH: erase all of current line, start again */ 336259243Sobrien ResetInLine(0); /* reset the input pointers */ 336359243Sobrien xputchar('\n'); 336459243Sobrien ClearDisp(); 336559243Sobrien return (CC_REFRESH); 336669408Sache#else /* !_MINIX && !WINNT_NATIVE */ 336759243Sobrien /* do no editing */ 336859243Sobrien return (CC_NORM); 336969408Sache#endif /* _MINIX || WINNT_NATIVE */ 337059243Sobrien} 337159243Sobrien 337259243Sobrien/* 337359243Sobrien * From: ghazi@cesl.rutgers.edu (Kaveh R. Ghazi) 337459243Sobrien * Function to send a character back to the input stream in cooked 337559243Sobrien * mode. Only works if we have TIOCSTI 337659243Sobrien */ 337759243Sobrien/*ARGSUSED*/ 337859243SobrienCCRETVAL 3379167465Smpe_stuff_char(Char c) 338059243Sobrien{ 338159243Sobrien#ifdef TIOCSTI 338259243Sobrien int was_raw = Tty_raw_mode; 3383145479Smp char buf[MB_LEN_MAX]; 3384145479Smp size_t i, len; 338559243Sobrien 338659243Sobrien if (was_raw) 338759243Sobrien (void) Cookedmode(); 338859243Sobrien 3389167465Smp (void) xwrite(SHIN, "\n", 1); 3390145479Smp len = one_wctomb(buf, c & CHAR); 3391145479Smp for (i = 0; i < len; i++) 3392145479Smp (void) ioctl(SHIN, TIOCSTI, (ioctl_t) &buf[i]); 339359243Sobrien 339459243Sobrien if (was_raw) 3395167465Smp (void) Rawmode(); 339659243Sobrien return(e_redisp(c)); 339759243Sobrien#else /* !TIOCSTI */ 339859243Sobrien return(CC_ERROR); 339959243Sobrien#endif /* !TIOCSTI */ 340059243Sobrien} 340159243Sobrien 340259243Sobrien/*ARGSUSED*/ 340359243SobrienCCRETVAL 3404167465Smpe_insovr(Char c) 340559243Sobrien{ 340659243Sobrien USE(c); 340759243Sobrien inputmode = (inputmode == MODE_INSERT ? MODE_REPLACE : MODE_INSERT); 340859243Sobrien return(CC_NORM); 340959243Sobrien} 341059243Sobrien 341159243Sobrien/*ARGSUSED*/ 341259243SobrienCCRETVAL 3413167465Smpe_tty_dsusp(Char c) 341459243Sobrien{ 341559243Sobrien USE(c); 341659243Sobrien /* do no editing */ 341759243Sobrien return(CC_NORM); 341859243Sobrien} 341959243Sobrien 342059243Sobrien/*ARGSUSED*/ 342159243SobrienCCRETVAL 3422167465Smpe_tty_flusho(Char c) 342359243Sobrien{ 342459243Sobrien USE(c); 342559243Sobrien /* do no editing */ 342659243Sobrien return(CC_NORM); 342759243Sobrien} 342859243Sobrien 342959243Sobrien/*ARGSUSED*/ 343059243SobrienCCRETVAL 3431167465Smpe_tty_quit(Char c) 343259243Sobrien{ 343359243Sobrien USE(c); 343459243Sobrien /* do no editing */ 343559243Sobrien return(CC_NORM); 343659243Sobrien} 343759243Sobrien 343859243Sobrien/*ARGSUSED*/ 343959243SobrienCCRETVAL 3440167465Smpe_tty_tsusp(Char c) 344159243Sobrien{ 344259243Sobrien USE(c); 344359243Sobrien /* do no editing */ 344459243Sobrien return(CC_NORM); 344559243Sobrien} 344659243Sobrien 344759243Sobrien/*ARGSUSED*/ 344859243SobrienCCRETVAL 3449167465Smpe_tty_stopo(Char c) 345059243Sobrien{ 345159243Sobrien USE(c); 345259243Sobrien /* do no editing */ 345359243Sobrien return(CC_NORM); 345459243Sobrien} 345559243Sobrien 3456195609Smp/* returns the number of (attempted) expansions */ 3457195609Smpint 3458195609SmpExpandHistory(void) 3459195609Smp{ 3460195609Smp *LastChar = '\0'; /* just in case */ 3461195609Smp return c_substitute(); 3462195609Smp} 3463195609Smp 346459243Sobrien/*ARGSUSED*/ 346559243SobrienCCRETVAL 3466167465Smpe_expand_history(Char c) 346759243Sobrien{ 346859243Sobrien USE(c); 3469195609Smp (void)ExpandHistory(); 347059243Sobrien return(CC_NORM); 347159243Sobrien} 347259243Sobrien 347359243Sobrien/*ARGSUSED*/ 347459243SobrienCCRETVAL 3475167465Smpe_magic_space(Char c) 347659243Sobrien{ 347759243Sobrien USE(c); 347859243Sobrien *LastChar = '\0'; /* just in case */ 3479195609Smp (void)c_substitute(); 348059243Sobrien return(e_insert(' ')); 348159243Sobrien} 348259243Sobrien 348359243Sobrien/*ARGSUSED*/ 348459243SobrienCCRETVAL 3485167465Smpe_inc_fwd(Char c) 348659243Sobrien{ 3487167465Smp CCRETVAL ret; 3488167465Smp 348959243Sobrien USE(c); 3490167465Smp patbuf.len = 0; 3491167465Smp MarkIsSet = 0; 3492167465Smp ret = e_inc_search(F_DOWN_SEARCH_HIST); 3493167465Smp if (adrof(STRhighlight) && IncMatchLen) { 3494167465Smp IncMatchLen = 0; 3495167465Smp ClearLines(); 3496167465Smp ClearDisp(); 3497167465Smp Refresh(); 3498167465Smp } 3499167465Smp IncMatchLen = 0; 3500167465Smp return ret; 350159243Sobrien} 350259243Sobrien 350359243Sobrien 350459243Sobrien/*ARGSUSED*/ 350559243SobrienCCRETVAL 3506167465Smpe_inc_back(Char c) 350759243Sobrien{ 3508167465Smp CCRETVAL ret; 3509167465Smp 351059243Sobrien USE(c); 3511167465Smp patbuf.len = 0; 3512167465Smp MarkIsSet = 0; 3513167465Smp ret = e_inc_search(F_UP_SEARCH_HIST); 3514167465Smp if (adrof(STRhighlight) && IncMatchLen) { 3515167465Smp IncMatchLen = 0; 3516167465Smp ClearLines(); 3517167465Smp ClearDisp(); 3518167465Smp Refresh(); 3519167465Smp } 3520167465Smp IncMatchLen = 0; 3521167465Smp return ret; 352259243Sobrien} 352359243Sobrien 352459243Sobrien/*ARGSUSED*/ 352559243SobrienCCRETVAL 3526167465Smpe_copyprev(Char c) 352759243Sobrien{ 352883098Smp Char *cp, *oldc, *dp; 352959243Sobrien 353059243Sobrien USE(c); 353159243Sobrien if (Cursor == InputBuf) 353259243Sobrien return(CC_ERROR); 353359243Sobrien /* else */ 353459243Sobrien 353559243Sobrien oldc = Cursor; 353659243Sobrien /* does a bounds check */ 353759243Sobrien cp = c_prev_word(Cursor, InputBuf, Argument); 353859243Sobrien 353959243Sobrien c_insert((int)(oldc - cp)); 354059243Sobrien for (dp = oldc; cp < oldc && dp < LastChar; cp++) 354159243Sobrien *dp++ = *cp; 354259243Sobrien 354359243Sobrien Cursor = dp; /* put cursor at end */ 354459243Sobrien 354559243Sobrien return(CC_REFRESH); 354659243Sobrien} 354759243Sobrien 354859243Sobrien/*ARGSUSED*/ 354959243SobrienCCRETVAL 3550167465Smpe_tty_starto(Char c) 355159243Sobrien{ 355259243Sobrien USE(c); 355359243Sobrien /* do no editing */ 355459243Sobrien return(CC_NORM); 355559243Sobrien} 355659243Sobrien 355759243Sobrien/*ARGSUSED*/ 355859243SobrienCCRETVAL 3559167465Smpe_load_average(Char c) 356059243Sobrien{ 356159243Sobrien USE(c); 356259243Sobrien PastBottom(); 356359243Sobrien#ifdef TIOCSTAT 356459243Sobrien /* 356559243Sobrien * Here we pass &c to the ioctl because some os's (NetBSD) expect it 356659243Sobrien * there even if they don't use it. (lukem@netbsd.org) 356759243Sobrien */ 356859243Sobrien if (ioctl(SHIN, TIOCSTAT, (ioctl_t) &c) < 0) 356959243Sobrien#endif 3570195609Smp xprintf("%s", CGETS(5, 1, "Load average unavailable\n")); 357159243Sobrien return(CC_REFRESH); 357259243Sobrien} 357359243Sobrien 357459243Sobrien/*ARGSUSED*/ 357559243SobrienCCRETVAL 3576167465Smpv_chgmeta(Char c) 357759243Sobrien{ 357859243Sobrien USE(c); 357959243Sobrien /* 358059243Sobrien * Delete with insert == change: first we delete and then we leave in 358159243Sobrien * insert mode. 358259243Sobrien */ 358359243Sobrien return(v_action(TCSHOP_DELETE|TCSHOP_INSERT)); 358459243Sobrien} 358559243Sobrien 358659243Sobrien/*ARGSUSED*/ 358759243SobrienCCRETVAL 3588167465Smpv_delmeta(Char c) 358959243Sobrien{ 359059243Sobrien USE(c); 359159243Sobrien return(v_action(TCSHOP_DELETE)); 359259243Sobrien} 359359243Sobrien 359459243Sobrien 359559243Sobrien/*ARGSUSED*/ 359659243SobrienCCRETVAL 3597167465Smpv_endword(Char c) 359859243Sobrien{ 359959243Sobrien USE(c); 360059243Sobrien if (Cursor == LastChar) 360159243Sobrien return(CC_ERROR); 360259243Sobrien /* else */ 360359243Sobrien 360483098Smp Cursor = c_endword(Cursor, LastChar, Argument, STRshwspace); 360559243Sobrien 360659243Sobrien if (ActionFlag & TCSHOP_DELETE) 360759243Sobrien { 360859243Sobrien Cursor++; 360959243Sobrien c_delfini(); 361059243Sobrien return(CC_REFRESH); 361159243Sobrien } 361259243Sobrien 361359243Sobrien RefCursor(); 361459243Sobrien return(CC_NORM); 361559243Sobrien} 361659243Sobrien 361759243Sobrien/*ARGSUSED*/ 361859243SobrienCCRETVAL 3619167465Smpv_eword(Char c) 362059243Sobrien{ 362159243Sobrien USE(c); 362259243Sobrien if (Cursor == LastChar) 362359243Sobrien return(CC_ERROR); 362459243Sobrien /* else */ 362559243Sobrien 362659243Sobrien Cursor = c_eword(Cursor, LastChar, Argument); 362759243Sobrien 362859243Sobrien if (ActionFlag & TCSHOP_DELETE) { 362959243Sobrien Cursor++; 363059243Sobrien c_delfini(); 363159243Sobrien return(CC_REFRESH); 363259243Sobrien } 363359243Sobrien 363459243Sobrien RefCursor(); 363559243Sobrien return(CC_NORM); 363659243Sobrien} 363759243Sobrien 363859243Sobrien/*ARGSUSED*/ 363959243SobrienCCRETVAL 3640167465Smpv_char_fwd(Char c) 364159243Sobrien{ 364259243Sobrien Char ch; 364359243Sobrien 364459243Sobrien USE(c); 364559243Sobrien if (GetNextChar(&ch) != 1) 364659243Sobrien return e_send_eof(0); 364759243Sobrien 364859243Sobrien srch_dir = CHAR_FWD; 364959243Sobrien srch_char = ch; 365059243Sobrien 365159243Sobrien return v_csearch_fwd(ch, Argument, 0); 365259243Sobrien 365359243Sobrien} 365459243Sobrien 365559243Sobrien/*ARGSUSED*/ 365659243SobrienCCRETVAL 3657167465Smpv_char_back(Char c) 365859243Sobrien{ 365959243Sobrien Char ch; 366059243Sobrien 366159243Sobrien USE(c); 366259243Sobrien if (GetNextChar(&ch) != 1) 366359243Sobrien return e_send_eof(0); 366459243Sobrien 366559243Sobrien srch_dir = CHAR_BACK; 366659243Sobrien srch_char = ch; 366759243Sobrien 366859243Sobrien return v_csearch_back(ch, Argument, 0); 366959243Sobrien} 367059243Sobrien 367159243Sobrien/*ARGSUSED*/ 367259243SobrienCCRETVAL 3673167465Smpv_charto_fwd(Char c) 367459243Sobrien{ 367559243Sobrien Char ch; 367659243Sobrien 367759243Sobrien USE(c); 367859243Sobrien if (GetNextChar(&ch) != 1) 367959243Sobrien return e_send_eof(0); 368059243Sobrien 368159243Sobrien return v_csearch_fwd(ch, Argument, 1); 368259243Sobrien 368359243Sobrien} 368459243Sobrien 368559243Sobrien/*ARGSUSED*/ 368659243SobrienCCRETVAL 3687167465Smpv_charto_back(Char c) 368859243Sobrien{ 368959243Sobrien Char ch; 369059243Sobrien 369159243Sobrien USE(c); 369259243Sobrien if (GetNextChar(&ch) != 1) 369359243Sobrien return e_send_eof(0); 369459243Sobrien 369559243Sobrien return v_csearch_back(ch, Argument, 1); 369659243Sobrien} 369759243Sobrien 369859243Sobrien/*ARGSUSED*/ 369959243SobrienCCRETVAL 3700167465Smpv_rchar_fwd(Char c) 370159243Sobrien{ 370259243Sobrien USE(c); 370359243Sobrien if (srch_char == 0) 370459243Sobrien return CC_ERROR; 370559243Sobrien 370659243Sobrien return srch_dir == CHAR_FWD ? v_csearch_fwd(srch_char, Argument, 0) : 370759243Sobrien v_csearch_back(srch_char, Argument, 0); 370859243Sobrien} 370959243Sobrien 371059243Sobrien/*ARGSUSED*/ 371159243SobrienCCRETVAL 3712167465Smpv_rchar_back(Char c) 371359243Sobrien{ 371459243Sobrien USE(c); 371559243Sobrien if (srch_char == 0) 371659243Sobrien return CC_ERROR; 371759243Sobrien 371859243Sobrien return srch_dir == CHAR_BACK ? v_csearch_fwd(srch_char, Argument, 0) : 371959243Sobrien v_csearch_back(srch_char, Argument, 0); 372059243Sobrien} 372159243Sobrien 372259243Sobrien/*ARGSUSED*/ 372359243SobrienCCRETVAL 3724167465Smpv_undo(Char c) 372559243Sobrien{ 372683098Smp int loop; 372783098Smp Char *kp, *cp; 372859243Sobrien Char temp; 372959243Sobrien int size; 373059243Sobrien 373159243Sobrien USE(c); 373259243Sobrien switch (UndoAction) { 373359243Sobrien case TCSHOP_DELETE|TCSHOP_INSERT: 373459243Sobrien case TCSHOP_DELETE: 373559243Sobrien if (UndoSize == 0) return(CC_NORM); 373659243Sobrien cp = UndoPtr; 373759243Sobrien kp = UndoBuf; 373859243Sobrien for (loop=0; loop < UndoSize; loop++) /* copy the chars */ 373959243Sobrien *kp++ = *cp++; /* into UndoBuf */ 374059243Sobrien 374159243Sobrien for (cp = UndoPtr; cp <= LastChar; cp++) 374259243Sobrien *cp = cp[UndoSize]; 374359243Sobrien 374459243Sobrien LastChar -= UndoSize; 374559243Sobrien Cursor = UndoPtr; 374659243Sobrien 374759243Sobrien UndoAction = TCSHOP_INSERT; 374859243Sobrien break; 374959243Sobrien 375059243Sobrien case TCSHOP_INSERT: 375159243Sobrien if (UndoSize == 0) return(CC_NORM); 375259243Sobrien cp = UndoPtr; 375359243Sobrien Cursor = UndoPtr; 375459243Sobrien kp = UndoBuf; 375559243Sobrien c_insert(UndoSize); /* open the space, */ 375659243Sobrien for (loop = 0; loop < UndoSize; loop++) /* copy the chars */ 375759243Sobrien *cp++ = *kp++; 375859243Sobrien 375959243Sobrien UndoAction = TCSHOP_DELETE; 376059243Sobrien break; 376159243Sobrien 376259243Sobrien case TCSHOP_CHANGE: 376359243Sobrien if (UndoSize == 0) return(CC_NORM); 376459243Sobrien cp = UndoPtr; 376559243Sobrien Cursor = UndoPtr; 376659243Sobrien kp = UndoBuf; 376759243Sobrien size = (int)(Cursor-LastChar); /* NOT NSL independant */ 376859243Sobrien if (size < UndoSize) 376959243Sobrien size = UndoSize; 377059243Sobrien for(loop = 0; loop < size; loop++) { 377159243Sobrien temp = *kp; 377259243Sobrien *kp++ = *cp; 377359243Sobrien *cp++ = temp; 377459243Sobrien } 377559243Sobrien break; 377659243Sobrien 377759243Sobrien default: 377859243Sobrien return(CC_ERROR); 377959243Sobrien } 378059243Sobrien 378159243Sobrien return(CC_REFRESH); 378259243Sobrien} 378359243Sobrien 378459243Sobrien/*ARGSUSED*/ 378559243SobrienCCRETVAL 3786167465Smpv_ush_meta(Char c) 378759243Sobrien{ 378859243Sobrien USE(c); 378959243Sobrien return v_search(F_UP_SEARCH_HIST); 379059243Sobrien} 379159243Sobrien 379259243Sobrien/*ARGSUSED*/ 379359243SobrienCCRETVAL 3794167465Smpv_dsh_meta(Char c) 379559243Sobrien{ 379659243Sobrien USE(c); 379759243Sobrien return v_search(F_DOWN_SEARCH_HIST); 379859243Sobrien} 379959243Sobrien 380059243Sobrien/*ARGSUSED*/ 380159243SobrienCCRETVAL 3802167465Smpv_rsrch_fwd(Char c) 380359243Sobrien{ 380459243Sobrien USE(c); 3805167465Smp if (patbuf.len == 0) return(CC_ERROR); 380659243Sobrien return(v_repeat_srch(searchdir)); 380759243Sobrien} 380859243Sobrien 380959243Sobrien/*ARGSUSED*/ 381059243SobrienCCRETVAL 3811167465Smpv_rsrch_back(Char c) 381259243Sobrien{ 381359243Sobrien USE(c); 3814167465Smp if (patbuf.len == 0) return(CC_ERROR); 381559243Sobrien return(v_repeat_srch(searchdir == F_UP_SEARCH_HIST ? 381659243Sobrien F_DOWN_SEARCH_HIST : F_UP_SEARCH_HIST)); 381759243Sobrien} 381859243Sobrien 381969408Sache#ifndef WINNT_NATIVE 382059243Sobrien/* Since ed.defns.h is generated from ed.defns.c, these empty 382159243Sobrien functions will keep the F_NUM_FNS consistent 382259243Sobrien */ 382359243SobrienCCRETVAL 3824167465Smpe_copy_to_clipboard(Char c) 382559243Sobrien{ 382659243Sobrien USE(c); 382759243Sobrien return CC_ERROR; 382859243Sobrien} 382959243Sobrien 383059243SobrienCCRETVAL 3831167465Smpe_paste_from_clipboard(Char c) 383259243Sobrien{ 383359243Sobrien USE(c); 383459243Sobrien return (CC_ERROR); 383559243Sobrien} 383659243Sobrien 383759243SobrienCCRETVAL 3838167465Smpe_dosify_next(Char c) 383959243Sobrien{ 384059243Sobrien USE(c); 384159243Sobrien return (CC_ERROR); 384259243Sobrien} 384359243SobrienCCRETVAL 3844167465Smpe_dosify_prev(Char c) 384559243Sobrien{ 384659243Sobrien USE(c); 384759243Sobrien return (CC_ERROR); 384859243Sobrien} 384959243SobrienCCRETVAL 3850167465Smpe_page_up(Char c) 385159243Sobrien{ 385259243Sobrien USE(c); 385369408Sache return (CC_ERROR); 385459243Sobrien} 385559243SobrienCCRETVAL 3856167465Smpe_page_down(Char c) 385759243Sobrien{ 385859243Sobrien USE(c); 385969408Sache return (CC_ERROR); 386059243Sobrien} 386169408Sache#endif /* !WINNT_NATIVE */ 386259243Sobrien 386359243Sobrien#ifdef notdef 386459243Sobrienvoid 3865167465SmpMoveCursor(int n) /* move cursor + right - left char */ 386659243Sobrien{ 386759243Sobrien Cursor = Cursor + n; 386859243Sobrien if (Cursor < InputBuf) 386959243Sobrien Cursor = InputBuf; 387059243Sobrien if (Cursor > LastChar) 387159243Sobrien Cursor = LastChar; 387259243Sobrien return; 387359243Sobrien} 387459243Sobrien 387559243SobrienChar * 3876167465SmpGetCursor(void) 387759243Sobrien{ 387859243Sobrien return(Cursor); 387959243Sobrien} 388059243Sobrien 388159243Sobrienint 3882167465SmpPutCursor(Char *p) 388359243Sobrien{ 388459243Sobrien if (p < InputBuf || p > LastChar) 388559243Sobrien return 1; /* Error */ 388659243Sobrien Cursor = p; 388759243Sobrien return 0; 388859243Sobrien} 388959243Sobrien#endif 3890