159243Sobrien/* 259243Sobrien * ed.chared.c: Character editing functions. 359243Sobrien */ 459243Sobrien/*- 559243Sobrien * Copyright (c) 1980, 1991 The Regents of the University of California. 659243Sobrien * All rights reserved. 759243Sobrien * 859243Sobrien * Redistribution and use in source and binary forms, with or without 959243Sobrien * modification, are permitted provided that the following conditions 1059243Sobrien * are met: 1159243Sobrien * 1. Redistributions of source code must retain the above copyright 1259243Sobrien * notice, this list of conditions and the following disclaimer. 1359243Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1459243Sobrien * notice, this list of conditions and the following disclaimer in the 1559243Sobrien * documentation and/or other materials provided with the distribution. 16100616Smp * 3. Neither the name of the University nor the names of its contributors 1759243Sobrien * may be used to endorse or promote products derived from this software 1859243Sobrien * without specific prior written permission. 1959243Sobrien * 2059243Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2159243Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2259243Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2359243Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2459243Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2559243Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2659243Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2759243Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2859243Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2959243Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3059243Sobrien * SUCH DAMAGE. 3159243Sobrien */ 3259243Sobrien/* 3359243Sobrien Bjorn Knutsson @ Thu Jun 24 19:02:17 1999 3459243Sobrien 3559243Sobrien e_dabbrev_expand() did not do proper completion if quoted spaces were present 3659243Sobrien in the string being completed. Exemple: 3759243Sobrien 3859243Sobrien # echo hello\ world 3959243Sobrien hello world 4059243Sobrien # echo h<press key bound to dabbrev-expande> 4159243Sobrien # echo hello\<cursor> 4259243Sobrien 4359243Sobrien Correct behavior is: 4459243Sobrien # echo h<press key bound to dabbrev-expande> 4559243Sobrien # echo hello\ world<cursor> 4659243Sobrien 4759243Sobrien The same problem occured if spaces were present in a string withing quotation 4859243Sobrien marks. Example: 4959243Sobrien 5059243Sobrien # echo "hello world" 5159243Sobrien hello world 5259243Sobrien # echo "h<press key bound to dabbrev-expande> 5359243Sobrien # echo "hello<cursor> 5459243Sobrien 5559243Sobrien The former problem could be solved with minor modifications of c_preword() 5659243Sobrien and c_endword(). The latter, however, required a significant rewrite of 5759243Sobrien c_preword(), since quoted strings must be parsed from start to end to 5859243Sobrien determine if a given character is inside or outside the quotation marks. 5959243Sobrien 6059243Sobrien Compare the following two strings: 6159243Sobrien 6259243Sobrien # echo \"" 'foo \' bar\" 6359243Sobrien " 'foo \' bar\ 6459243Sobrien # echo '\"" 'foo \' bar\" 6559243Sobrien \"" foo ' bar" 6659243Sobrien 6759243Sobrien The only difference between the two echo lines is in the first character 6859243Sobrien after the echo command. The result is either one or three arguments. 6959243Sobrien 7059243Sobrien */ 7159243Sobrien 7259243Sobrien#include "sh.h" 7359243Sobrien#include "ed.h" 7459243Sobrien#include "tw.h" 7559243Sobrien#include "ed.defns.h" 7659243Sobrien 7759243Sobrien/* #define SDEBUG */ 7859243Sobrien 7959243Sobrien#define TCSHOP_NOP 0x00 8059243Sobrien#define TCSHOP_DELETE 0x01 8159243Sobrien#define TCSHOP_INSERT 0x02 8259243Sobrien#define TCSHOP_CHANGE 0x04 8359243Sobrien 8459243Sobrien#define CHAR_FWD 0 8559243Sobrien#define CHAR_BACK 1 8659243Sobrien 8759243Sobrien/* 8859243Sobrien * vi word treatment 8959243Sobrien * from: Gert-Jan Vons <vons@cesar.crbca1.sinet.slb.com> 9059243Sobrien */ 9159243Sobrien#define C_CLASS_WHITE 1 92316957Sdchagin#define C_CLASS_WORD 2 9359243Sobrien#define C_CLASS_OTHER 3 9459243Sobrien 9559243Sobrienstatic Char *InsertPos = InputBuf; /* Where insertion starts */ 9659243Sobrienstatic Char *ActionPos = 0; /* Where action begins */ 9759243Sobrienstatic int ActionFlag = TCSHOP_NOP; /* What delayed action to take */ 9859243Sobrien/* 9959243Sobrien * Word search state 10059243Sobrien */ 10159243Sobrienstatic int searchdir = F_UP_SEARCH_HIST; /* Direction of last search */ 102167465Smpstatic struct Strbuf patbuf; /* = Strbuf_INIT; Search target */ 10359243Sobrien/* 10459243Sobrien * Char search state 10559243Sobrien */ 10659243Sobrienstatic int srch_dir = CHAR_FWD; /* Direction of last search */ 10759243Sobrienstatic Char srch_char = 0; /* Search target */ 10859243Sobrien 10959243Sobrien/* all routines that start with c_ are private to this set of routines */ 110167465Smpstatic void c_alternativ_key_map (int); 111167465Smpvoid c_insert (int); 112167465Smpvoid c_delafter (int); 113167465Smpvoid c_delbefore (int); 114167465Smpstatic int c_to_class (Char); 115167465Smpstatic Char *c_prev_word (Char *, Char *, int); 116167465Smpstatic Char *c_next_word (Char *, Char *, int); 117167465Smpstatic Char *c_number (Char *, int *, int); 118167465Smpstatic Char *c_expand (Char *); 119195609Smpstatic int c_excl (Char *); 120195609Smpstatic int c_substitute (void); 121167465Smpstatic void c_delfini (void); 122167465Smpstatic int c_hmatch (Char *); 123167465Smpstatic void c_hsetpat (void); 12459243Sobrien#ifdef COMMENT 125167465Smpstatic void c_get_word (Char **, Char **); 12659243Sobrien#endif 127167465Smpstatic Char *c_preword (Char *, Char *, int, Char *); 128167465Smpstatic Char *c_nexword (Char *, Char *, int); 129167465Smpstatic Char *c_endword (Char *, Char *, int, Char *); 130167465Smpstatic Char *c_eword (Char *, Char *, int); 131167465Smpstatic void c_push_kill (Char *, Char *); 132167465Smpstatic void c_save_inputbuf (void); 133167465Smpstatic CCRETVAL c_search_line (Char *, int); 134167465Smpstatic CCRETVAL v_repeat_srch (int); 135167465Smpstatic CCRETVAL e_inc_search (int); 136167465Smp#ifdef notyet 137167465Smpstatic CCRETVAL e_insert_str (Char *); 138167465Smp#endif 139167465Smpstatic CCRETVAL v_search (int); 140167465Smpstatic CCRETVAL v_csearch_fwd (Char, int, int); 141167465Smpstatic CCRETVAL v_action (int); 142167465Smpstatic CCRETVAL v_csearch_back (Char, int, int); 14359243Sobrien 14459243Sobrienstatic void 145167465Smpc_alternativ_key_map(int state) 14659243Sobrien{ 14759243Sobrien switch (state) { 14859243Sobrien case 0: 14959243Sobrien CurrentKeyMap = CcKeyMap; 15059243Sobrien break; 15159243Sobrien case 1: 15259243Sobrien CurrentKeyMap = CcAltMap; 15359243Sobrien break; 15459243Sobrien default: 15559243Sobrien return; 15659243Sobrien } 15759243Sobrien 15859243Sobrien AltKeyMap = (Char) state; 15959243Sobrien} 16059243Sobrien 16183098Smpvoid 162167465Smpc_insert(int num) 16359243Sobrien{ 16483098Smp Char *cp; 16559243Sobrien 16659243Sobrien if (LastChar + num >= InputLim) 16759243Sobrien return; /* can't go past end of buffer */ 16859243Sobrien 16959243Sobrien if (Cursor < LastChar) { /* if I must move chars */ 17059243Sobrien for (cp = LastChar; cp >= Cursor; cp--) 17159243Sobrien cp[num] = *cp; 172145479Smp if (Mark && Mark > Cursor) 173145479Smp Mark += num; 17459243Sobrien } 17559243Sobrien LastChar += num; 17659243Sobrien} 17759243Sobrien 17869408Sachevoid 179167465Smpc_delafter(int num) 18059243Sobrien{ 18183098Smp Char *cp, *kp = NULL; 18259243Sobrien 18359243Sobrien if (num > LastChar - Cursor) 18459243Sobrien num = (int) (LastChar - Cursor); /* bounds check */ 18559243Sobrien 18659243Sobrien if (num > 0) { /* if I can delete anything */ 18759243Sobrien if (VImode) { 18859243Sobrien kp = UndoBuf; /* Set Up for VI undo command */ 18959243Sobrien UndoAction = TCSHOP_INSERT; 19059243Sobrien UndoSize = num; 19159243Sobrien UndoPtr = Cursor; 19259243Sobrien for (cp = Cursor; cp <= LastChar; cp++) { 19359243Sobrien *kp++ = *cp; /* Save deleted chars into undobuf */ 19459243Sobrien *cp = cp[num]; 19559243Sobrien } 19659243Sobrien } 19759243Sobrien else 198145479Smp for (cp = Cursor; cp + num <= LastChar; cp++) 19959243Sobrien *cp = cp[num]; 20059243Sobrien LastChar -= num; 201167465Smp /* Mark was within the range of the deleted word? */ 202167465Smp if (Mark && Mark > Cursor && Mark <= Cursor+num) 203167465Smp Mark = Cursor; 204167465Smp /* Mark after the deleted word? */ 205167465Smp else if (Mark && Mark > Cursor) 206145479Smp Mark -= num; 20759243Sobrien } 20859243Sobrien#ifdef notdef 20959243Sobrien else { 21059243Sobrien /* 21159243Sobrien * XXX: We don't want to do that. In emacs mode overwrite should be 21259243Sobrien * sticky. I am not sure how that affects vi mode 21359243Sobrien */ 21459243Sobrien inputmode = MODE_INSERT; 21559243Sobrien } 21659243Sobrien#endif /* notdef */ 21759243Sobrien} 21859243Sobrien 21969408Sachevoid 220167465Smpc_delbefore(int num) /* delete before dot, with bounds checking */ 22159243Sobrien{ 22283098Smp Char *cp, *kp = NULL; 22359243Sobrien 22459243Sobrien if (num > Cursor - InputBuf) 22559243Sobrien num = (int) (Cursor - InputBuf); /* bounds check */ 22659243Sobrien 22759243Sobrien if (num > 0) { /* if I can delete anything */ 22859243Sobrien if (VImode) { 22959243Sobrien kp = UndoBuf; /* Set Up for VI undo command */ 23059243Sobrien UndoAction = TCSHOP_INSERT; 23159243Sobrien UndoSize = num; 23259243Sobrien UndoPtr = Cursor - num; 23359243Sobrien for (cp = Cursor - num; cp <= LastChar; cp++) { 23459243Sobrien *kp++ = *cp; 23559243Sobrien *cp = cp[num]; 23659243Sobrien } 23759243Sobrien } 23859243Sobrien else 239145479Smp for (cp = Cursor - num; cp + num <= LastChar; cp++) 24059243Sobrien *cp = cp[num]; 24159243Sobrien LastChar -= num; 242145479Smp Cursor -= num; 243167465Smp /* Mark was within the range of the deleted word? */ 244167465Smp if (Mark && Mark > Cursor && Mark <= Cursor+num) 245167465Smp Mark = Cursor; 246167465Smp /* Mark after the deleted word? */ 247167465Smp else if (Mark && Mark > Cursor) 248145479Smp Mark -= num; 24959243Sobrien } 25059243Sobrien} 25159243Sobrien 25259243Sobrienstatic Char * 253167465Smpc_preword(Char *p, Char *low, int n, Char *delim) 25459243Sobrien{ 25559243Sobrien while (n--) { 25683098Smp Char *prev = low; 25783098Smp Char *new; 25859243Sobrien 25983098Smp while (prev < p) { /* Skip initial non-word chars */ 26083098Smp if (!Strchr(delim, *prev) || *(prev-1) == (Char)'\\') 26159243Sobrien break; 26259243Sobrien prev++; 26359243Sobrien } 26459243Sobrien 26559243Sobrien new = prev; 26659243Sobrien 26759243Sobrien while (new < p) { 26859243Sobrien prev = new; 26983098Smp new = c_endword(prev-1, p, 1, delim); /* Skip to next non-word char */ 27059243Sobrien new++; /* Step away from end of word */ 27183098Smp while (new <= p) { /* Skip trailing non-word chars */ 27283098Smp if (!Strchr(delim, *new) || *(new-1) == (Char)'\\') 27359243Sobrien break; 27459243Sobrien new++; 27559243Sobrien } 27659243Sobrien } 27759243Sobrien 27859243Sobrien p = prev; /* Set to previous word start */ 27959243Sobrien 28059243Sobrien } 28159243Sobrien if (p < low) 28259243Sobrien p = low; 28359243Sobrien return (p); 28459243Sobrien} 28559243Sobrien 28659243Sobrien/* 28759243Sobrien * c_to_class() returns the class of the given character. 28859243Sobrien * 289316957Sdchagin * This is used to make the c_prev_word(), c_next_word() and c_eword() functions 29059243Sobrien * work like vi's, which classify characters. A word is a sequence of 29159243Sobrien * characters belonging to the same class, classes being defined as 29259243Sobrien * follows: 29359243Sobrien * 29459243Sobrien * 1/ whitespace 29559243Sobrien * 2/ alphanumeric chars, + underscore 29659243Sobrien * 3/ others 29759243Sobrien */ 29859243Sobrienstatic int 299167465Smpc_to_class(Char ch) 30059243Sobrien{ 30159243Sobrien if (Isspace(ch)) 30259243Sobrien return C_CLASS_WHITE; 30359243Sobrien 304316957Sdchagin if (isword(ch)) 305316957Sdchagin return C_CLASS_WORD; 30659243Sobrien 30759243Sobrien return C_CLASS_OTHER; 30859243Sobrien} 30959243Sobrien 31059243Sobrienstatic Char * 311167465Smpc_prev_word(Char *p, Char *low, int n) 31259243Sobrien{ 31359243Sobrien p--; 31459243Sobrien 31559243Sobrien if (!VImode) { 31659243Sobrien while (n--) { 31759243Sobrien while ((p >= low) && !isword(*p)) 31859243Sobrien p--; 31959243Sobrien while ((p >= low) && isword(*p)) 32059243Sobrien p--; 32159243Sobrien } 32259243Sobrien 32359243Sobrien /* cp now points to one character before the word */ 32459243Sobrien p++; 32559243Sobrien if (p < low) 32659243Sobrien p = low; 32759243Sobrien /* cp now points where we want it */ 32859243Sobrien return(p); 32959243Sobrien } 33059243Sobrien 33159243Sobrien while (n--) { 33283098Smp int c_class; 33359243Sobrien 33459243Sobrien if (p < low) 33559243Sobrien break; 33659243Sobrien 33759243Sobrien /* scan until beginning of current word (may be all whitespace!) */ 33859243Sobrien c_class = c_to_class(*p); 33959243Sobrien while ((p >= low) && c_class == c_to_class(*p)) 34059243Sobrien p--; 34159243Sobrien 34259243Sobrien /* if this was a non_whitespace word, we're ready */ 34359243Sobrien if (c_class != C_CLASS_WHITE) 34459243Sobrien continue; 34559243Sobrien 34659243Sobrien /* otherwise, move back to beginning of the word just found */ 34759243Sobrien c_class = c_to_class(*p); 34859243Sobrien while ((p >= low) && c_class == c_to_class(*p)) 34959243Sobrien p--; 35059243Sobrien } 35159243Sobrien 35259243Sobrien p++; /* correct overshoot */ 35359243Sobrien 35459243Sobrien return (p); 35559243Sobrien} 35659243Sobrien 35759243Sobrienstatic Char * 358167465Smpc_next_word(Char *p, Char *high, int n) 35959243Sobrien{ 36059243Sobrien if (!VImode) { 36159243Sobrien while (n--) { 36259243Sobrien while ((p < high) && !isword(*p)) 36359243Sobrien p++; 36459243Sobrien while ((p < high) && isword(*p)) 36559243Sobrien p++; 36659243Sobrien } 36759243Sobrien if (p > high) 36859243Sobrien p = high; 36959243Sobrien /* p now points where we want it */ 37059243Sobrien return(p); 37159243Sobrien } 37259243Sobrien 37359243Sobrien while (n--) { 37483098Smp int c_class; 37559243Sobrien 37659243Sobrien if (p >= high) 37759243Sobrien break; 37859243Sobrien 37959243Sobrien /* scan until end of current word (may be all whitespace!) */ 38059243Sobrien c_class = c_to_class(*p); 38159243Sobrien while ((p < high) && c_class == c_to_class(*p)) 38259243Sobrien p++; 38359243Sobrien 38459243Sobrien /* if this was all whitespace, we're ready */ 38559243Sobrien if (c_class == C_CLASS_WHITE) 38659243Sobrien continue; 38759243Sobrien 38859243Sobrien /* if we've found white-space at the end of the word, skip it */ 38959243Sobrien while ((p < high) && c_to_class(*p) == C_CLASS_WHITE) 39059243Sobrien p++; 39159243Sobrien } 39259243Sobrien 39359243Sobrien p--; /* correct overshoot */ 39459243Sobrien 39559243Sobrien return (p); 39659243Sobrien} 39759243Sobrien 39859243Sobrienstatic Char * 399167465Smpc_nexword(Char *p, Char *high, int n) 40059243Sobrien{ 40159243Sobrien while (n--) { 40259243Sobrien while ((p < high) && !Isspace(*p)) 40359243Sobrien p++; 40459243Sobrien while ((p < high) && Isspace(*p)) 40559243Sobrien p++; 40659243Sobrien } 40759243Sobrien 40859243Sobrien if (p > high) 40959243Sobrien p = high; 41059243Sobrien /* p now points where we want it */ 41159243Sobrien return(p); 41259243Sobrien} 41359243Sobrien 41459243Sobrien/* 41559243Sobrien * Expand-History (originally "Magic-Space") code added by 41659243Sobrien * Ray Moody <ray@gibbs.physics.purdue.edu> 41759243Sobrien * this is a neat, but odd, addition. 41859243Sobrien */ 41959243Sobrien 42059243Sobrien/* 42159243Sobrien * c_number: Ignore character p points to, return number appearing after that. 42259243Sobrien * A '$' by itself means a big number; "$-" is for negative; '^' means 1. 42359243Sobrien * Return p pointing to last char used. 42459243Sobrien */ 42559243Sobrien 42659243Sobrien/* 42759243Sobrien * dval is the number to subtract from for things like $-3 42859243Sobrien */ 42959243Sobrien 43059243Sobrienstatic Char * 431167465Smpc_number(Char *p, int *num, int dval) 43259243Sobrien{ 43383098Smp int i; 43483098Smp int sign = 1; 43559243Sobrien 43659243Sobrien if (*++p == '^') { 43759243Sobrien *num = 1; 43859243Sobrien return(p); 43959243Sobrien } 44059243Sobrien if (*p == '$') { 44159243Sobrien if (*++p != '-') { 442167465Smp *num = INT_MAX; /* Handle $ */ 44359243Sobrien return(--p); 44459243Sobrien } 44559243Sobrien sign = -1; /* Handle $- */ 44659243Sobrien ++p; 44759243Sobrien } 44859243Sobrien for (i = 0; *p >= '0' && *p <= '9'; i = 10 * i + *p++ - '0') 44959243Sobrien continue; 45059243Sobrien *num = (sign < 0 ? dval - i : i); 45159243Sobrien return(--p); 45259243Sobrien} 45359243Sobrien 45459243Sobrien/* 45559243Sobrien * excl_expand: There is an excl to be expanded to p -- do the right thing 45659243Sobrien * with it and return a version of p advanced over the expanded stuff. Also, 45759243Sobrien * update tsh_cur and related things as appropriate... 45859243Sobrien */ 45959243Sobrien 46059243Sobrienstatic Char * 461167465Smpc_expand(Char *p) 46259243Sobrien{ 46383098Smp Char *q; 46483098Smp struct Hist *h = Histlist.Hnext; 46583098Smp struct wordent *l; 46659243Sobrien int i, from, to, dval; 467145479Smp int all_dig; 468145479Smp int been_once = 0; 46959243Sobrien Char *op = p; 470167465Smp Char *buf; 471167465Smp size_t buf_len; 472167465Smp Char *modbuf; 47359243Sobrien 474167465Smp buf = NULL; 47559243Sobrien if (!h) 47659243Sobrien goto excl_err; 47759243Sobrienexcl_sw: 47859243Sobrien switch (*(q = p + 1)) { 47959243Sobrien 48059243Sobrien case '^': 481167465Smp buf = expand_lex(&h->Hlex, 1, 1); 48259243Sobrien break; 48359243Sobrien 48459243Sobrien case '$': 48559243Sobrien if ((l = (h->Hlex).prev) != 0) 486167465Smp buf = expand_lex(l->prev->prev, 0, 0); 48759243Sobrien break; 48859243Sobrien 48959243Sobrien case '*': 490167465Smp buf = expand_lex(&h->Hlex, 1, INT_MAX); 49159243Sobrien break; 49259243Sobrien 49359243Sobrien default: 49459243Sobrien if (been_once) { /* unknown argument */ 49559243Sobrien /* assume it's a modifier, e.g. !foo:h, and get whole cmd */ 496167465Smp buf = expand_lex(&h->Hlex, 0, INT_MAX); 49759243Sobrien q -= 2; 49859243Sobrien break; 49959243Sobrien } 50059243Sobrien been_once = 1; 50159243Sobrien 50259243Sobrien if (*q == ':') /* short form: !:arg */ 50359243Sobrien --q; 50459243Sobrien 505231990Smp if (HIST != '\0' && *q != HIST) { 50659243Sobrien /* 50759243Sobrien * Search for a space, tab, or colon. See if we have a number (as 50859243Sobrien * in !1234:xyz). Remember the number. 50959243Sobrien */ 51059243Sobrien for (i = 0, all_dig = 1; 51159243Sobrien *q != ' ' && *q != '\t' && *q != ':' && q < Cursor; q++) { 51259243Sobrien /* 51359243Sobrien * PWP: !-4 is a valid history argument too, therefore the test 51459243Sobrien * is if not a digit, or not a - as the first character. 51559243Sobrien */ 51659243Sobrien if ((*q < '0' || *q > '9') && (*q != '-' || q != p + 1)) 51759243Sobrien all_dig = 0; 51859243Sobrien else if (*q == '-') 51959243Sobrien all_dig = 2;/* we are sneeky about this */ 52059243Sobrien else 52159243Sobrien i = 10 * i + *q - '0'; 52259243Sobrien } 52359243Sobrien --q; 52459243Sobrien 52559243Sobrien /* 52659243Sobrien * If we have a number, search for event i. Otherwise, search for 52759243Sobrien * a named event (as in !foo). (In this case, I is the length of 52859243Sobrien * the named event). 52959243Sobrien */ 53059243Sobrien if (all_dig) { 53159243Sobrien if (all_dig == 2) 53259243Sobrien i = -i; /* make it negitive */ 53359243Sobrien if (i < 0) /* if !-4 (for example) */ 53459243Sobrien i = eventno + 1 + i; /* remember: i is < 0 */ 53559243Sobrien for (; h; h = h->Hnext) { 53659243Sobrien if (h->Hnum == i) 53759243Sobrien break; 53859243Sobrien } 53959243Sobrien } 54059243Sobrien else { 54159243Sobrien for (i = (int) (q - p); h; h = h->Hnext) { 54259243Sobrien if ((l = &h->Hlex) != 0) { 54359243Sobrien if (!Strncmp(p + 1, l->next->word, (size_t) i)) 54459243Sobrien break; 54559243Sobrien } 54659243Sobrien } 54759243Sobrien } 54859243Sobrien } 54959243Sobrien if (!h) 55059243Sobrien goto excl_err; 55159243Sobrien if (q[1] == ':' || q[1] == '-' || q[1] == '*' || 55259243Sobrien q[1] == '$' || q[1] == '^') { /* get some args */ 55359243Sobrien p = q[1] == ':' ? ++q : q; 55459243Sobrien /* 55559243Sobrien * Go handle !foo:* 55659243Sobrien */ 55759243Sobrien if ((q[1] < '0' || q[1] > '9') && 55859243Sobrien q[1] != '-' && q[1] != '$' && q[1] != '^') 55959243Sobrien goto excl_sw; 56059243Sobrien /* 56159243Sobrien * Go handle !foo:$ 56259243Sobrien */ 56359243Sobrien if (q[1] == '$' && (q[2] != '-' || q[3] < '0' || q[3] > '9')) 56459243Sobrien goto excl_sw; 56559243Sobrien /* 56659243Sobrien * Count up the number of words in this event. Store it in dval. 56759243Sobrien * Dval will be fed to number. 56859243Sobrien */ 56959243Sobrien dval = 0; 57059243Sobrien if ((l = h->Hlex.prev) != 0) { 57159243Sobrien for (l = l->prev; l != h->Hlex.next; l = l->prev, dval++) 57259243Sobrien continue; 57359243Sobrien } 57459243Sobrien if (!dval) 57559243Sobrien goto excl_err; 57659243Sobrien if (q[1] == '-') 57759243Sobrien from = 0; 57859243Sobrien else 57959243Sobrien q = c_number(q, &from, dval); 58059243Sobrien if (q[1] == '-') { 58159243Sobrien ++q; 58259243Sobrien if ((q[1] < '0' || q[1] > '9') && q[1] != '$') 58359243Sobrien to = dval - 1; 58459243Sobrien else 58559243Sobrien q = c_number(q, &to, dval); 58659243Sobrien } 58759243Sobrien else if (q[1] == '*') { 58859243Sobrien ++q; 589167465Smp to = INT_MAX; 59059243Sobrien } 59159243Sobrien else { 59259243Sobrien to = from; 59359243Sobrien } 59459243Sobrien if (from < 0 || to < from) 59559243Sobrien goto excl_err; 596167465Smp buf = expand_lex(&h->Hlex, from, to); 59759243Sobrien } 598167465Smp else /* get whole cmd */ 599167465Smp buf = expand_lex(&h->Hlex, 0, INT_MAX); 60059243Sobrien break; 60159243Sobrien } 602167465Smp if (buf == NULL) 603167465Smp buf = SAVE(""); 60459243Sobrien 60559243Sobrien /* 60659243Sobrien * Apply modifiers, if any. 60759243Sobrien */ 60859243Sobrien if (q[1] == ':') { 609167465Smp modbuf = buf; 61059243Sobrien while (q[1] == ':' && modbuf != NULL) { 61159243Sobrien switch (q[2]) { 61259243Sobrien case 'r': 61359243Sobrien case 'e': 61459243Sobrien case 'h': 61559243Sobrien case 't': 61659243Sobrien case 'q': 61759243Sobrien case 'x': 61859243Sobrien case 'u': 61959243Sobrien case 'l': 620167465Smp if ((modbuf = domod(buf, (int) q[2])) != NULL) { 621167465Smp xfree(buf); 622167465Smp buf = modbuf; 62359243Sobrien } 62459243Sobrien ++q; 62559243Sobrien break; 62659243Sobrien 62759243Sobrien case 'a': 62859243Sobrien case 'g': 62959243Sobrien /* Not implemented; this needs to be done before expanding 63059243Sobrien * lex. We don't have the words available to us anymore. 63159243Sobrien */ 63259243Sobrien ++q; 63359243Sobrien break; 63459243Sobrien 63559243Sobrien case 'p': 63659243Sobrien /* Ok */ 63759243Sobrien ++q; 63859243Sobrien break; 63959243Sobrien 64059243Sobrien case '\0': 64159243Sobrien break; 64259243Sobrien 64359243Sobrien default: 64459243Sobrien ++q; 64559243Sobrien break; 64659243Sobrien } 64759243Sobrien if (q[1]) 64859243Sobrien ++q; 64959243Sobrien } 65059243Sobrien } 65159243Sobrien 652167465Smp buf_len = Strlen(buf); 65359243Sobrien /* 654167465Smp * Now replace the text from op to q inclusive with the text from buf. 65559243Sobrien */ 65659243Sobrien q++; 65759243Sobrien 65859243Sobrien /* 65959243Sobrien * Now replace text non-inclusively like a real CS major! 66059243Sobrien */ 661167465Smp if (LastChar + buf_len - (q - op) >= InputLim) 66259243Sobrien goto excl_err; 663167465Smp (void) memmove(op + buf_len, q, (LastChar - q) * sizeof(Char)); 664167465Smp LastChar += buf_len - (q - op); 665167465Smp Cursor += buf_len - (q - op); 666167465Smp (void) memcpy(op, buf, buf_len * sizeof(Char)); 66759243Sobrien *LastChar = '\0'; 668167465Smp xfree(buf); 669167465Smp return op + buf_len; 67059243Sobrienexcl_err: 671167465Smp xfree(buf); 67259243Sobrien SoundBeep(); 67359243Sobrien return(op + 1); 67459243Sobrien} 67559243Sobrien 67659243Sobrien/* 67759243Sobrien * c_excl: An excl has been found at point p -- back up and find some white 67859243Sobrien * space (or the beginning of the buffer) and properly expand all the excl's 67959243Sobrien * from there up to the current cursor position. We also avoid (trying to) 68059243Sobrien * expanding '>!' 681195609Smp * Returns number of expansions attempted (doesn't matter whether they succeeded 682195609Smp * or not). 68359243Sobrien */ 68459243Sobrien 685195609Smpstatic int 686167465Smpc_excl(Char *p) 68759243Sobrien{ 68883098Smp int i; 68983098Smp Char *q; 690195609Smp int nr_exp; 69159243Sobrien 69259243Sobrien /* 69359243Sobrien * if />[SPC TAB]*![SPC TAB]/, back up p to just after the >. otherwise, 69459243Sobrien * back p up to just before the current word. 69559243Sobrien */ 69659243Sobrien if ((p[1] == ' ' || p[1] == '\t') && 69759243Sobrien (p[-1] == ' ' || p[-1] == '\t' || p[-1] == '>')) { 69859243Sobrien for (q = p - 1; q > InputBuf && (*q == ' ' || *q == '\t'); --q) 69959243Sobrien continue; 70059243Sobrien if (*q == '>') 70159243Sobrien ++p; 70259243Sobrien } 70359243Sobrien else { 70459243Sobrien while (*p != ' ' && *p != '\t' && p > InputBuf) 70559243Sobrien --p; 70659243Sobrien } 70759243Sobrien 70859243Sobrien /* 70959243Sobrien * Forever: Look for history char. (Stop looking when we find the cursor.) 710195609Smp * Count backslashes. If odd, skip history char. Expand if even number of 711195609Smp * backslashes. 71259243Sobrien */ 713195609Smp nr_exp = 0; 71459243Sobrien for (;;) { 715231990Smp if (HIST != '\0') 716231990Smp while (*p != HIST && p < Cursor) 717231990Smp ++p; 71859243Sobrien for (i = 1; (p - i) >= InputBuf && p[-i] == '\\'; i++) 71959243Sobrien continue; 72059243Sobrien if (i % 2 == 0) 72159243Sobrien ++p; 722195609Smp if (p >= Cursor) /* all done */ 723195609Smp return nr_exp; 724195609Smp if (i % 2 == 1) { 72559243Sobrien p = c_expand(p); 726195609Smp ++nr_exp; 727195609Smp } 72859243Sobrien } 72959243Sobrien} 73059243Sobrien 73159243Sobrien 732195609Smpstatic int 733167465Smpc_substitute(void) 73459243Sobrien{ 73583098Smp Char *p; 736195609Smp int nr_exp; 73759243Sobrien 73859243Sobrien /* 73959243Sobrien * Start p out one character before the cursor. Move it backwards looking 74059243Sobrien * for white space, the beginning of the line, or a history character. 74159243Sobrien */ 74259243Sobrien for (p = Cursor - 1; 743231990Smp p > InputBuf && *p != ' ' && *p != '\t' && *p && *p != HIST; --p) 74459243Sobrien continue; 74559243Sobrien 74659243Sobrien /* 74759243Sobrien * If we found a history character, go expand it. 74859243Sobrien */ 749316957Sdchagin if (p >= InputBuf && HIST != '\0' && *p == HIST) 750195609Smp nr_exp = c_excl(p); 751195609Smp else 752195609Smp nr_exp = 0; 75359243Sobrien Refresh(); 754195609Smp 755195609Smp return nr_exp; 75659243Sobrien} 75759243Sobrien 75859243Sobrienstatic void 759167465Smpc_delfini(void) /* Finish up delete action */ 76059243Sobrien{ 76183098Smp int Size; 76259243Sobrien 76359243Sobrien if (ActionFlag & TCSHOP_INSERT) 76459243Sobrien c_alternativ_key_map(0); 76559243Sobrien 76659243Sobrien ActionFlag = TCSHOP_NOP; 76759243Sobrien 76859243Sobrien if (ActionPos == 0) 76959243Sobrien return; 77059243Sobrien 77159243Sobrien UndoAction = TCSHOP_INSERT; 77259243Sobrien 77359243Sobrien if (Cursor > ActionPos) { 77459243Sobrien Size = (int) (Cursor-ActionPos); 77559243Sobrien c_delbefore(Size); 77659243Sobrien RefCursor(); 77759243Sobrien } 77859243Sobrien else if (Cursor < ActionPos) { 77959243Sobrien Size = (int)(ActionPos-Cursor); 78059243Sobrien c_delafter(Size); 78159243Sobrien } 78259243Sobrien else { 78359243Sobrien Size = 1; 78459243Sobrien c_delafter(Size); 78559243Sobrien } 78659243Sobrien UndoPtr = Cursor; 78759243Sobrien UndoSize = Size; 78859243Sobrien} 78959243Sobrien 79059243Sobrienstatic Char * 791167465Smpc_endword(Char *p, Char *high, int n, Char *delim) 79259243Sobrien{ 793145479Smp Char inquote = 0; 79459243Sobrien p++; 79559243Sobrien 79659243Sobrien while (n--) { 79783098Smp while (p < high) { /* Skip non-word chars */ 79883098Smp if (!Strchr(delim, *p) || *(p-1) == (Char)'\\') 79959243Sobrien break; 80059243Sobrien p++; 80159243Sobrien } 80259243Sobrien while (p < high) { /* Skip string */ 80359243Sobrien if ((*p == (Char)'\'' || *p == (Char)'"')) { /* Quotation marks? */ 80483098Smp if (inquote || *(p-1) != (Char)'\\') { /* Should it be honored? */ 80559243Sobrien if (inquote == 0) inquote = *p; 80659243Sobrien else if (inquote == *p) inquote = 0; 80759243Sobrien } 80859243Sobrien } 80983098Smp /* Break if unquoted non-word char */ 81083098Smp if (!inquote && Strchr(delim, *p) && *(p-1) != (Char)'\\') 81159243Sobrien break; 81259243Sobrien p++; 81359243Sobrien } 81459243Sobrien } 81559243Sobrien 81659243Sobrien p--; 81759243Sobrien return(p); 81859243Sobrien} 81959243Sobrien 82059243Sobrien 82159243Sobrienstatic Char * 822167465Smpc_eword(Char *p, Char *high, int n) 82359243Sobrien{ 82459243Sobrien p++; 82559243Sobrien 82659243Sobrien while (n--) { 827316957Sdchagin int c_class; 82859243Sobrien 829316957Sdchagin if (p >= high) 830316957Sdchagin break; 831316957Sdchagin 832316957Sdchagin /* scan until end of current word (may be all whitespace!) */ 833316957Sdchagin c_class = c_to_class(*p); 834316957Sdchagin while ((p < high) && c_class == c_to_class(*p)) 835316957Sdchagin p++; 836316957Sdchagin 837316957Sdchagin /* if this was a non_whitespace word, we're ready */ 838316957Sdchagin if (c_class != C_CLASS_WHITE) 839316957Sdchagin continue; 840316957Sdchagin 841316957Sdchagin /* otherwise, move to the end of the word just found */ 842316957Sdchagin c_class = c_to_class(*p); 843316957Sdchagin while ((p < high) && c_class == c_to_class(*p)) 844316957Sdchagin p++; 84559243Sobrien } 84659243Sobrien 84759243Sobrien p--; 84859243Sobrien return(p); 84959243Sobrien} 85059243Sobrien 85183098Smp/* Set the max length of the kill ring */ 85283098Smpvoid 853167465SmpSetKillRing(int max) 85483098Smp{ 85583098Smp CStr *new; 85683098Smp int count, i, j; 85783098Smp 85883098Smp if (max < 1) 85983098Smp max = 1; /* no ring, but always one buffer */ 86083098Smp if (max == KillRingMax) 86183098Smp return; 862167465Smp new = xcalloc(max, sizeof(CStr)); 86383098Smp if (KillRing != NULL) { 86483098Smp if (KillRingLen != 0) { 86583098Smp if (max >= KillRingLen) { 86683098Smp count = KillRingLen; 86783098Smp j = KillPos; 86883098Smp } else { 86983098Smp count = max; 87083098Smp j = (KillPos - count + KillRingLen) % KillRingLen; 87183098Smp } 87283098Smp for (i = 0; i < KillRingLen; i++) { 87383098Smp if (i < count) /* copy latest */ 87483098Smp new[i] = KillRing[j]; 87583098Smp else /* free the others */ 87683098Smp xfree(KillRing[j].buf); 87783098Smp j = (j + 1) % KillRingLen; 87883098Smp } 87983098Smp KillRingLen = count; 88083098Smp KillPos = count % max; 88183098Smp YankPos = count - 1; 88283098Smp } 88383098Smp xfree(KillRing); 88483098Smp } 88583098Smp KillRing = new; 88683098Smp KillRingMax = max; 88783098Smp} 88883098Smp 88983098Smp/* Push string from start upto (but not including) end onto kill ring */ 89083098Smpstatic void 891167465Smpc_push_kill(Char *start, Char *end) 89283098Smp{ 89383098Smp CStr save, *pos; 89483098Smp Char *dp, *cp, *kp; 89583098Smp int len = end - start, i, j, k; 89683098Smp 89783098Smp /* Check for duplicates? */ 89883098Smp if (KillRingLen > 0 && (dp = varval(STRkilldup)) != STRNULL) { 89983098Smp YankPos = (KillPos - 1 + KillRingLen) % KillRingLen; 90083098Smp if (eq(dp, STRerase)) { /* erase earlier one (actually move up) */ 90183098Smp j = YankPos; 90283098Smp for (i = 0; i < KillRingLen; i++) { 90383098Smp if (Strncmp(KillRing[j].buf, start, (size_t) len) == 0 && 90483098Smp KillRing[j].buf[len] == '\0') { 90583098Smp save = KillRing[j]; 90683098Smp for ( ; i > 0; i--) { 90783098Smp k = j; 90883098Smp j = (j + 1) % KillRingLen; 90983098Smp KillRing[k] = KillRing[j]; 91083098Smp } 91183098Smp KillRing[j] = save; 91283098Smp return; 91383098Smp } 91483098Smp j = (j - 1 + KillRingLen) % KillRingLen; 91583098Smp } 91683098Smp } else if (eq(dp, STRall)) { /* skip if any earlier */ 91783098Smp for (i = 0; i < KillRingLen; i++) 91883098Smp if (Strncmp(KillRing[i].buf, start, (size_t) len) == 0 && 91983098Smp KillRing[i].buf[len] == '\0') 92083098Smp return; 92183098Smp } else if (eq(dp, STRprev)) { /* skip if immediately previous */ 92283098Smp j = YankPos; 92383098Smp if (Strncmp(KillRing[j].buf, start, (size_t) len) == 0 && 92483098Smp KillRing[j].buf[len] == '\0') 92583098Smp return; 92683098Smp } 92783098Smp } 92883098Smp 92983098Smp /* No duplicate, go ahead and push */ 93083098Smp len++; /* need space for '\0' */ 93183098Smp YankPos = KillPos; 93283098Smp if (KillRingLen < KillRingMax) 93383098Smp KillRingLen++; 93483098Smp pos = &KillRing[KillPos]; 93583098Smp KillPos = (KillPos + 1) % KillRingMax; 93683098Smp if (pos->len < len) { 937167465Smp pos->buf = xrealloc(pos->buf, len * sizeof(Char)); 93883098Smp pos->len = len; 93983098Smp } 94083098Smp cp = start; 94183098Smp kp = pos->buf; 94283098Smp while (cp < end) 94383098Smp *kp++ = *cp++; 94483098Smp *kp = '\0'; 94583098Smp} 94683098Smp 947167465Smp/* Save InputBuf etc in SavedBuf etc for restore after cmd exec */ 948167465Smpstatic void 949316957Sdchaginc_save_inputbuf(void) 95059243Sobrien{ 951167465Smp SavedBuf.len = 0; 952167465Smp Strbuf_append(&SavedBuf, InputBuf); 953167465Smp Strbuf_terminate(&SavedBuf); 954167465Smp LastSaved = LastChar - InputBuf; 955167465Smp CursSaved = Cursor - InputBuf; 956167465Smp HistSaved = Hist_num; 957167465Smp RestoreSaved = 1; 958167465Smp} 959167465Smp 960167465SmpCCRETVAL 961316957SdchaginGetHistLine(void) 962167465Smp{ 96359243Sobrien struct Hist *hp; 96459243Sobrien int h; 96559243Sobrien 96659243Sobrien if (Hist_num == 0) { /* if really the current line */ 967167465Smp if (HistBuf.s != NULL) 968167465Smp copyn(InputBuf, HistBuf.s, INBUFSIZE);/*FIXBUF*/ 969167465Smp else 970167465Smp *InputBuf = '\0'; 971167465Smp LastChar = InputBuf + HistBuf.len; 97259243Sobrien 97359243Sobrien#ifdef KSHVI 97459243Sobrien if (VImode) 97559243Sobrien Cursor = InputBuf; 97659243Sobrien else 97759243Sobrien#endif /* KSHVI */ 97859243Sobrien Cursor = LastChar; 97959243Sobrien 98059243Sobrien return(CC_REFRESH); 98159243Sobrien } 98259243Sobrien 98359243Sobrien hp = Histlist.Hnext; 98459243Sobrien if (hp == NULL) 98559243Sobrien return(CC_ERROR); 98659243Sobrien 98759243Sobrien for (h = 1; h < Hist_num; h++) { 98859243Sobrien if ((hp->Hnext) == NULL) { 98959243Sobrien Hist_num = h; 99059243Sobrien return(CC_ERROR); 99159243Sobrien } 99259243Sobrien hp = hp->Hnext; 99359243Sobrien } 99459243Sobrien 99559243Sobrien if (HistLit && hp->histline) { 996167465Smp copyn(InputBuf, hp->histline, INBUFSIZE);/*FIXBUF*/ 99759243Sobrien CurrentHistLit = 1; 99859243Sobrien } 99959243Sobrien else { 1000167465Smp Char *p; 1001167465Smp 1002167465Smp p = sprlex(&hp->Hlex); 1003167465Smp copyn(InputBuf, p, sizeof(InputBuf) / sizeof(Char));/*FIXBUF*/ 1004167465Smp xfree(p); 100559243Sobrien CurrentHistLit = 0; 100659243Sobrien } 1007167465Smp LastChar = Strend(InputBuf); 100859243Sobrien 100959243Sobrien if (LastChar > InputBuf) { 101059243Sobrien if (LastChar[-1] == '\n') 101159243Sobrien LastChar--; 101259243Sobrien#if 0 101359243Sobrien if (LastChar[-1] == ' ') 101459243Sobrien LastChar--; 101559243Sobrien#endif 101659243Sobrien if (LastChar < InputBuf) 101759243Sobrien LastChar = InputBuf; 101859243Sobrien } 1019145479Smp 102059243Sobrien#ifdef KSHVI 102159243Sobrien if (VImode) 102259243Sobrien Cursor = InputBuf; 102359243Sobrien else 102459243Sobrien#endif /* KSHVI */ 102559243Sobrien Cursor = LastChar; 102659243Sobrien 102759243Sobrien return(CC_REFRESH); 102859243Sobrien} 102959243Sobrien 103059243Sobrienstatic CCRETVAL 1031167465Smpc_search_line(Char *pattern, int dir) 103259243Sobrien{ 103359243Sobrien Char *cp; 1034167465Smp size_t len; 103559243Sobrien 1036167465Smp len = Strlen(pattern); 103759243Sobrien 103859243Sobrien if (dir == F_UP_SEARCH_HIST) { 103959243Sobrien for (cp = Cursor; cp >= InputBuf; cp--) 1040167465Smp if (Strncmp(cp, pattern, len) == 0 || 104159243Sobrien Gmatch(cp, pattern)) { 104259243Sobrien Cursor = cp; 104359243Sobrien return(CC_NORM); 104459243Sobrien } 104559243Sobrien return(CC_ERROR); 104659243Sobrien } else { 104759243Sobrien for (cp = Cursor; *cp != '\0' && cp < InputLim; cp++) 1048167465Smp if (Strncmp(cp, pattern, len) == 0 || 104959243Sobrien Gmatch(cp, pattern)) { 105059243Sobrien Cursor = cp; 105159243Sobrien return(CC_NORM); 105259243Sobrien } 105359243Sobrien return(CC_ERROR); 105459243Sobrien } 105559243Sobrien} 105659243Sobrien 105759243Sobrienstatic CCRETVAL 1058167465Smpe_inc_search(int dir) 105959243Sobrien{ 1060167465Smp static const Char STRfwd[] = { 'f', 'w', 'd', '\0' }, 1061167465Smp STRbck[] = { 'b', 'c', 'k', '\0' }; 106259243Sobrien static Char pchar = ':'; /* ':' = normal, '?' = failed */ 106359243Sobrien static Char endcmd[2]; 1064167465Smp const Char *cp; 1065167465Smp Char ch, 106659243Sobrien *oldCursor = Cursor, 106759243Sobrien oldpchar = pchar; 106859243Sobrien CCRETVAL ret = CC_NORM; 106959243Sobrien int oldHist_num = Hist_num, 1070167465Smp oldpatlen = patbuf.len, 107159243Sobrien newdir = dir, 107259243Sobrien done, redo; 107359243Sobrien 1074167465Smp if (LastChar + sizeof(STRfwd)/sizeof(Char) + 2 + patbuf.len >= InputLim) 107559243Sobrien return(CC_ERROR); 107659243Sobrien 107759243Sobrien for (;;) { 107859243Sobrien 1079167465Smp if (patbuf.len == 0) { /* first round */ 108059243Sobrien pchar = ':'; 1081167465Smp Strbuf_append1(&patbuf, '*'); 108259243Sobrien } 108359243Sobrien done = redo = 0; 108459243Sobrien *LastChar++ = '\n'; 108559243Sobrien for (cp = newdir == F_UP_SEARCH_HIST ? STRbck : STRfwd; 108659243Sobrien *cp; *LastChar++ = *cp++) 108759243Sobrien continue; 108859243Sobrien *LastChar++ = pchar; 1089167465Smp for (cp = &patbuf.s[1]; cp < &patbuf.s[patbuf.len]; 1090167465Smp *LastChar++ = *cp++) 109159243Sobrien continue; 109259243Sobrien *LastChar = '\0'; 1093167465Smp if (adrof(STRhighlight) && pchar == ':') { 1094167465Smp /* if the no-glob-search patch is applied, remove the - 1 below */ 1095167465Smp IncMatchLen = patbuf.len - 1; 1096167465Smp ClearLines(); 1097167465Smp ClearDisp(); 1098167465Smp } 109959243Sobrien Refresh(); 110059243Sobrien 110159243Sobrien if (GetNextChar(&ch) != 1) 110259243Sobrien return(e_send_eof(0)); 110359243Sobrien 1104354195Sbrooks switch (GetCmdChar(ch)) { 110559243Sobrien case F_INSERT: 110659243Sobrien case F_DIGIT: 110759243Sobrien case F_MAGIC_SPACE: 1108167465Smp if (LastChar + 1 >= InputLim) /*FIXBUF*/ 110959243Sobrien SoundBeep(); 111059243Sobrien else { 1111167465Smp Strbuf_append1(&patbuf, ch); 111259243Sobrien *LastChar++ = ch; 111359243Sobrien *LastChar = '\0'; 111459243Sobrien Refresh(); 111559243Sobrien } 111659243Sobrien break; 111759243Sobrien 111859243Sobrien case F_INC_FWD: 111959243Sobrien newdir = F_DOWN_SEARCH_HIST; 112059243Sobrien redo++; 112159243Sobrien break; 112259243Sobrien 112359243Sobrien case F_INC_BACK: 112459243Sobrien newdir = F_UP_SEARCH_HIST; 112559243Sobrien redo++; 112659243Sobrien break; 112759243Sobrien 112859243Sobrien case F_DELPREV: 1129167465Smp if (patbuf.len > 1) 113059243Sobrien done++; 113159243Sobrien else 113259243Sobrien SoundBeep(); 113359243Sobrien break; 113459243Sobrien 113559243Sobrien default: 1136167465Smp switch (ASC(ch)) { 113759243Sobrien case 0007: /* ^G: Abort */ 113859243Sobrien ret = CC_ERROR; 113959243Sobrien done++; 114059243Sobrien break; 114159243Sobrien 114259243Sobrien case 0027: /* ^W: Append word */ 114359243Sobrien /* No can do if globbing characters in pattern */ 1144167465Smp for (cp = &patbuf.s[1]; ; cp++) 1145167465Smp if (cp >= &patbuf.s[patbuf.len]) { 1146167465Smp Cursor += patbuf.len - 1; 114759243Sobrien cp = c_next_word(Cursor, LastChar, 1); 114859243Sobrien while (Cursor < cp && *Cursor != '\n') { 1149167465Smp if (LastChar + 1 >= InputLim) {/*FIXBUF*/ 115059243Sobrien SoundBeep(); 115159243Sobrien break; 115259243Sobrien } 1153167465Smp Strbuf_append1(&patbuf, *Cursor); 115459243Sobrien *LastChar++ = *Cursor++; 115559243Sobrien } 115659243Sobrien Cursor = oldCursor; 115759243Sobrien *LastChar = '\0'; 115859243Sobrien Refresh(); 115959243Sobrien break; 116059243Sobrien } else if (isglob(*cp)) { 116159243Sobrien SoundBeep(); 116259243Sobrien break; 116359243Sobrien } 116459243Sobrien break; 116559243Sobrien 116659243Sobrien default: /* Terminate and execute cmd */ 116759243Sobrien endcmd[0] = ch; 116859243Sobrien PushMacro(endcmd); 116959243Sobrien /*FALLTHROUGH*/ 117059243Sobrien 117159243Sobrien case 0033: /* ESC: Terminate */ 117259243Sobrien ret = CC_REFRESH; 117359243Sobrien done++; 117459243Sobrien break; 117559243Sobrien } 117659243Sobrien break; 117759243Sobrien } 117859243Sobrien 117959243Sobrien while (LastChar > InputBuf && *LastChar != '\n') 118059243Sobrien *LastChar-- = '\0'; 118159243Sobrien *LastChar = '\0'; 118259243Sobrien 118359243Sobrien if (!done) { 118459243Sobrien 118559243Sobrien /* Can't search if unmatched '[' */ 1186167465Smp for (cp = &patbuf.s[patbuf.len - 1], ch = ']'; cp > patbuf.s; cp--) 118759243Sobrien if (*cp == '[' || *cp == ']') { 118859243Sobrien ch = *cp; 118959243Sobrien break; 119059243Sobrien } 119159243Sobrien 1192167465Smp if (patbuf.len > 1 && ch != '[') { 119359243Sobrien if (redo && newdir == dir) { 119459243Sobrien if (pchar == '?') { /* wrap around */ 1195167465Smp Hist_num = newdir == F_UP_SEARCH_HIST ? 0 : INT_MAX; 1196167465Smp if (GetHistLine() == CC_ERROR) 119759243Sobrien /* Hist_num was fixed by first call */ 1198167465Smp (void) GetHistLine(); 119959243Sobrien Cursor = newdir == F_UP_SEARCH_HIST ? 120059243Sobrien LastChar : InputBuf; 120159243Sobrien } else 120259243Sobrien Cursor += newdir == F_UP_SEARCH_HIST ? -1 : 1; 120359243Sobrien } 1204167465Smp Strbuf_append1(&patbuf, '*'); 1205167465Smp Strbuf_terminate(&patbuf); 120659243Sobrien if (Cursor < InputBuf || Cursor > LastChar || 1207167465Smp (ret = c_search_line(&patbuf.s[1], newdir)) == CC_ERROR) { 120859243Sobrien LastCmd = (KEYCMD) newdir; /* avoid c_hsetpat */ 120959243Sobrien ret = newdir == F_UP_SEARCH_HIST ? 121059243Sobrien e_up_search_hist(0) : e_down_search_hist(0); 121159243Sobrien if (ret != CC_ERROR) { 121259243Sobrien Cursor = newdir == F_UP_SEARCH_HIST ? 121359243Sobrien LastChar : InputBuf; 1214167465Smp (void) c_search_line(&patbuf.s[1], newdir); 121559243Sobrien } 121659243Sobrien } 1217167465Smp patbuf.s[--patbuf.len] = '\0'; 121859243Sobrien if (ret == CC_ERROR) { 121959243Sobrien SoundBeep(); 122059243Sobrien if (Hist_num != oldHist_num) { 122159243Sobrien Hist_num = oldHist_num; 1222167465Smp if (GetHistLine() == CC_ERROR) 122359243Sobrien return(CC_ERROR); 122459243Sobrien } 122559243Sobrien Cursor = oldCursor; 122659243Sobrien pchar = '?'; 122759243Sobrien } else { 122859243Sobrien pchar = ':'; 122959243Sobrien } 123059243Sobrien } 123159243Sobrien 123259243Sobrien ret = e_inc_search(newdir); 123359243Sobrien 123459243Sobrien if (ret == CC_ERROR && pchar == '?' && oldpchar == ':') { 123559243Sobrien /* break abort of failed search at last non-failed */ 123659243Sobrien ret = CC_NORM; 123759243Sobrien } 123859243Sobrien 123959243Sobrien } 124059243Sobrien 124159243Sobrien if (ret == CC_NORM || (ret == CC_ERROR && oldpatlen == 0)) { 124259243Sobrien /* restore on normal return or error exit */ 124359243Sobrien pchar = oldpchar; 1244167465Smp patbuf.len = oldpatlen; 124559243Sobrien if (Hist_num != oldHist_num) { 124659243Sobrien Hist_num = oldHist_num; 1247167465Smp if (GetHistLine() == CC_ERROR) 124859243Sobrien return(CC_ERROR); 124959243Sobrien } 125059243Sobrien Cursor = oldCursor; 125159243Sobrien if (ret == CC_ERROR) 125259243Sobrien Refresh(); 125359243Sobrien } 125459243Sobrien if (done || ret != CC_NORM) 125559243Sobrien return(ret); 125659243Sobrien 125759243Sobrien } 125859243Sobrien 125959243Sobrien} 126059243Sobrien 126159243Sobrienstatic CCRETVAL 1262167465Smpv_search(int dir) 126359243Sobrien{ 1264167465Smp struct Strbuf tmpbuf = Strbuf_INIT; 126559243Sobrien Char ch; 1266167465Smp Char *oldbuf; 126759243Sobrien Char *oldlc, *oldc; 126859243Sobrien 1269167465Smp cleanup_push(&tmpbuf, Strbuf_cleanup); 1270167465Smp oldbuf = Strsave(InputBuf); 1271167465Smp cleanup_push(oldbuf, xfree); 127259243Sobrien oldlc = LastChar; 127359243Sobrien oldc = Cursor; 1274167465Smp Strbuf_append1(&tmpbuf, '*'); 127559243Sobrien 127659243Sobrien InputBuf[0] = '\0'; 127759243Sobrien LastChar = InputBuf; 127859243Sobrien Cursor = InputBuf; 127959243Sobrien searchdir = dir; 128059243Sobrien 128159243Sobrien c_insert(2); /* prompt + '\n' */ 128259243Sobrien *Cursor++ = '\n'; 128359243Sobrien *Cursor++ = dir == F_UP_SEARCH_HIST ? '?' : '/'; 128459243Sobrien Refresh(); 128559243Sobrien for (ch = 0;ch == 0;) { 1286167465Smp if (GetNextChar(&ch) != 1) { 1287167465Smp cleanup_until(&tmpbuf); 128859243Sobrien return(e_send_eof(0)); 1289167465Smp } 129059243Sobrien switch (ASC(ch)) { 129159243Sobrien case 0010: /* Delete and backspace */ 129259243Sobrien case 0177: 1293167465Smp if (tmpbuf.len > 1) { 129459243Sobrien *Cursor-- = '\0'; 129559243Sobrien LastChar = Cursor; 1296167465Smp tmpbuf.len--; 129759243Sobrien } 129859243Sobrien else { 1299167465Smp copyn(InputBuf, oldbuf, INBUFSIZE);/*FIXBUF*/ 130059243Sobrien LastChar = oldlc; 130159243Sobrien Cursor = oldc; 1302167465Smp cleanup_until(&tmpbuf); 130359243Sobrien return(CC_REFRESH); 130459243Sobrien } 130559243Sobrien Refresh(); 130659243Sobrien ch = 0; 130759243Sobrien break; 130859243Sobrien 130959243Sobrien case 0033: /* ESC */ 131069408Sache#ifdef IS_ASCII 131159243Sobrien case '\r': /* Newline */ 131259243Sobrien case '\n': 131359243Sobrien#else 131469408Sache case '\012': /* ASCII Line feed */ 131569408Sache case '\015': /* ASCII (or EBCDIC) Return */ 131659243Sobrien#endif 131759243Sobrien break; 131859243Sobrien 131959243Sobrien default: 1320167465Smp Strbuf_append1(&tmpbuf, ch); 1321167465Smp *Cursor++ = ch; 1322167465Smp LastChar = Cursor; 132359243Sobrien Refresh(); 132459243Sobrien ch = 0; 132559243Sobrien break; 132659243Sobrien } 132759243Sobrien } 1328167465Smp cleanup_until(oldbuf); 132959243Sobrien 1330167465Smp if (tmpbuf.len == 1) { 133159243Sobrien /* 133259243Sobrien * Use the old pattern, but wild-card it. 133359243Sobrien */ 1334167465Smp if (patbuf.len == 0) { 133559243Sobrien InputBuf[0] = '\0'; 133659243Sobrien LastChar = InputBuf; 133759243Sobrien Cursor = InputBuf; 133859243Sobrien Refresh(); 1339167465Smp cleanup_until(&tmpbuf); 134059243Sobrien return(CC_ERROR); 134159243Sobrien } 1342167465Smp if (patbuf.s[0] != '*') { 1343167465Smp oldbuf = Strsave(patbuf.s); 1344167465Smp patbuf.len = 0; 1345167465Smp Strbuf_append1(&patbuf, '*'); 1346167465Smp Strbuf_append(&patbuf, oldbuf); 1347167465Smp xfree(oldbuf); 1348167465Smp Strbuf_append1(&patbuf, '*'); 1349167465Smp Strbuf_terminate(&patbuf); 135059243Sobrien } 135159243Sobrien } 135259243Sobrien else { 1353167465Smp Strbuf_append1(&tmpbuf, '*'); 1354167465Smp Strbuf_terminate(&tmpbuf); 1355167465Smp patbuf.len = 0; 1356167465Smp Strbuf_append(&patbuf, tmpbuf.s); 1357167465Smp Strbuf_terminate(&patbuf); 135859243Sobrien } 1359167465Smp cleanup_until(&tmpbuf); 136059243Sobrien LastCmd = (KEYCMD) dir; /* avoid c_hsetpat */ 136159243Sobrien Cursor = LastChar = InputBuf; 136259243Sobrien if ((dir == F_UP_SEARCH_HIST ? e_up_search_hist(0) : 136359243Sobrien e_down_search_hist(0)) == CC_ERROR) { 136459243Sobrien Refresh(); 136559243Sobrien return(CC_ERROR); 136659243Sobrien } 136759243Sobrien else { 1368167465Smp if (ASC(ch) == 0033) { 136959243Sobrien Refresh(); 137059243Sobrien *LastChar++ = '\n'; 137159243Sobrien *LastChar = '\0'; 137259243Sobrien PastBottom(); 137359243Sobrien return(CC_NEWLINE); 137459243Sobrien } 137559243Sobrien else 137659243Sobrien return(CC_REFRESH); 137759243Sobrien } 137859243Sobrien} 137959243Sobrien 138059243Sobrien/* 138159243Sobrien * semi-PUBLIC routines. Any routine that is of type CCRETVAL is an 138259243Sobrien * entry point, called from the CcKeyMap indirected into the 138359243Sobrien * CcFuncTbl array. 138459243Sobrien */ 138559243Sobrien 138659243Sobrien/*ARGSUSED*/ 138759243SobrienCCRETVAL 1388167465Smpv_cmd_mode(Char c) 138959243Sobrien{ 139059243Sobrien USE(c); 139159243Sobrien InsertPos = 0; 139259243Sobrien ActionFlag = TCSHOP_NOP; /* [Esc] cancels pending action */ 139359243Sobrien ActionPos = 0; 139459243Sobrien DoingArg = 0; 139559243Sobrien if (UndoPtr > Cursor) 139659243Sobrien UndoSize = (int)(UndoPtr - Cursor); 139759243Sobrien else 139859243Sobrien UndoSize = (int)(Cursor - UndoPtr); 139959243Sobrien 140059243Sobrien inputmode = MODE_INSERT; 140159243Sobrien c_alternativ_key_map(1); 140259243Sobrien#ifdef notdef 140359243Sobrien /* 140459243Sobrien * We don't want to move the cursor, because all the editing 140559243Sobrien * commands don't include the character under the cursor. 140659243Sobrien */ 140759243Sobrien if (Cursor > InputBuf) 140859243Sobrien Cursor--; 140959243Sobrien#endif 141059243Sobrien RefCursor(); 141159243Sobrien return(CC_NORM); 141259243Sobrien} 141359243Sobrien 141459243Sobrien/*ARGSUSED*/ 141559243SobrienCCRETVAL 1416167465Smpe_unassigned(Char c) 141759243Sobrien{ /* bound to keys that arn't really assigned */ 141859243Sobrien USE(c); 141959243Sobrien SoundBeep(); 142059243Sobrien flush(); 142159243Sobrien return(CC_NORM); 142259243Sobrien} 142359243Sobrien 1424167465Smp#ifdef notyet 1425145479Smpstatic CCRETVAL 1426167465Smpe_insert_str(Char *c) 1427145479Smp{ 1428145479Smp int i, n; 1429145479Smp 1430145479Smp n = Strlen(c); 1431145479Smp if (LastChar + Argument * n >= InputLim) 1432145479Smp return(CC_ERROR); /* end of buffer space */ 1433145479Smp if (inputmode != MODE_INSERT) { 1434167465Smp c_delafter(Argument * Strlen(c)); 1435145479Smp } 1436145479Smp c_insert(Argument * n); 1437145479Smp while (Argument--) { 1438145479Smp for (i = 0; i < n; i++) 1439145479Smp *Cursor++ = c[i]; 1440145479Smp } 1441145479Smp Refresh(); 1442145479Smp return(CC_NORM); 1443145479Smp} 1444167465Smp#endif 1445145479Smp 144659243SobrienCCRETVAL 1447167465Smpe_insert(Char c) 144859243Sobrien{ 144959243Sobrien#ifndef SHORT_STRINGS 145059243Sobrien c &= ASCII; /* no meta chars ever */ 145159243Sobrien#endif 145259243Sobrien 145359243Sobrien if (!c) 145459243Sobrien return(CC_ERROR); /* no NULs in the input ever!! */ 145559243Sobrien 145659243Sobrien if (LastChar + Argument >= InputLim) 145759243Sobrien return(CC_ERROR); /* end of buffer space */ 145859243Sobrien 145959243Sobrien if (Argument == 1) { /* How was this optimized ???? */ 146059243Sobrien 146159243Sobrien if (inputmode != MODE_INSERT) { 146259243Sobrien UndoBuf[UndoSize++] = *Cursor; 146359243Sobrien UndoBuf[UndoSize] = '\0'; 146459243Sobrien c_delafter(1); /* Do NOT use the saving ONE */ 146559243Sobrien } 146659243Sobrien 146759243Sobrien c_insert(1); 146859243Sobrien *Cursor++ = (Char) c; 146959243Sobrien DoingArg = 0; /* just in case */ 1470145479Smp RefPlusOne(1); /* fast refresh for one char. */ 147159243Sobrien } 147259243Sobrien else { 147359243Sobrien if (inputmode != MODE_INSERT) { 1474145479Smp int i; 1475145479Smp for(i = 0; i < Argument; i++) 1476145479Smp UndoBuf[UndoSize++] = *(Cursor + i); 147759243Sobrien 147859243Sobrien UndoBuf[UndoSize] = '\0'; 147959243Sobrien c_delafter(Argument); /* Do NOT use the saving ONE */ 148059243Sobrien } 148159243Sobrien 148259243Sobrien c_insert(Argument); 148359243Sobrien 148459243Sobrien while (Argument--) 148559243Sobrien *Cursor++ = (Char) c; 148659243Sobrien Refresh(); 148759243Sobrien } 148859243Sobrien 148959243Sobrien if (inputmode == MODE_REPLACE_1) 149059243Sobrien (void) v_cmd_mode(0); 149159243Sobrien 149259243Sobrien return(CC_NORM); 149359243Sobrien} 149459243Sobrien 149559243Sobrienint 1496167465SmpInsertStr(Char *s) /* insert ASCIZ s at cursor (for complete) */ 149759243Sobrien{ 149883098Smp int len; 149959243Sobrien 150059243Sobrien if ((len = (int) Strlen(s)) <= 0) 150159243Sobrien return -1; 150259243Sobrien if (LastChar + len >= InputLim) 150359243Sobrien return -1; /* end of buffer space */ 150459243Sobrien 150559243Sobrien c_insert(len); 150659243Sobrien while (len--) 150759243Sobrien *Cursor++ = *s++; 150859243Sobrien return 0; 150959243Sobrien} 151059243Sobrien 151159243Sobrienvoid 1512167465SmpDeleteBack(int n) /* delete the n characters before . */ 151359243Sobrien{ 151459243Sobrien if (n <= 0) 151559243Sobrien return; 151659243Sobrien if (Cursor >= &InputBuf[n]) { 151759243Sobrien c_delbefore(n); /* delete before dot */ 151859243Sobrien } 151959243Sobrien} 152059243Sobrien 152159243SobrienCCRETVAL 1522167465Smpe_digit(Char c) /* gray magic here */ 152359243Sobrien{ 152459243Sobrien if (!Isdigit(c)) 152559243Sobrien return(CC_ERROR); /* no NULs in the input ever!! */ 152659243Sobrien 152759243Sobrien if (DoingArg) { /* if doing an arg, add this in... */ 152859243Sobrien if (LastCmd == F_ARGFOUR) /* if last command was ^U */ 152959243Sobrien Argument = c - '0'; 153059243Sobrien else { 153159243Sobrien if (Argument > 1000000) 153259243Sobrien return CC_ERROR; 153359243Sobrien Argument = (Argument * 10) + (c - '0'); 153459243Sobrien } 153559243Sobrien return(CC_ARGHACK); 153659243Sobrien } 153759243Sobrien else { 153859243Sobrien if (LastChar + 1 >= InputLim) 153959243Sobrien return CC_ERROR; /* end of buffer space */ 154059243Sobrien 154159243Sobrien if (inputmode != MODE_INSERT) { 154259243Sobrien UndoBuf[UndoSize++] = *Cursor; 154359243Sobrien UndoBuf[UndoSize] = '\0'; 154459243Sobrien c_delafter(1); /* Do NOT use the saving ONE */ 154559243Sobrien } 154659243Sobrien c_insert(1); 154759243Sobrien *Cursor++ = (Char) c; 154859243Sobrien DoingArg = 0; /* just in case */ 1549145479Smp RefPlusOne(1); /* fast refresh for one char. */ 155059243Sobrien } 155159243Sobrien return(CC_NORM); 155259243Sobrien} 155359243Sobrien 155459243SobrienCCRETVAL 1555167465Smpe_argdigit(Char c) /* for ESC-n */ 155659243Sobrien{ 1557167465Smp#ifdef IS_ASCII 155859243Sobrien c &= ASCII; 1559167465Smp#else 1560167465Smp c = CTL_ESC(ASC(c) & ASCII); /* stripping for EBCDIC done the ASCII way */ 1561167465Smp#endif 156259243Sobrien 156359243Sobrien if (!Isdigit(c)) 156459243Sobrien return(CC_ERROR); /* no NULs in the input ever!! */ 156559243Sobrien 156659243Sobrien if (DoingArg) { /* if doing an arg, add this in... */ 156759243Sobrien if (Argument > 1000000) 156859243Sobrien return CC_ERROR; 156959243Sobrien Argument = (Argument * 10) + (c - '0'); 157059243Sobrien } 157159243Sobrien else { /* else starting an argument */ 157259243Sobrien Argument = c - '0'; 157359243Sobrien DoingArg = 1; 157459243Sobrien } 157559243Sobrien return(CC_ARGHACK); 157659243Sobrien} 157759243Sobrien 157859243SobrienCCRETVAL 1579167465Smpv_zero(Char c) /* command mode 0 for vi */ 158059243Sobrien{ 158159243Sobrien if (DoingArg) { /* if doing an arg, add this in... */ 158259243Sobrien if (Argument > 1000000) 158359243Sobrien return CC_ERROR; 158459243Sobrien Argument = (Argument * 10) + (c - '0'); 158559243Sobrien return(CC_ARGHACK); 158659243Sobrien } 158759243Sobrien else { /* else starting an argument */ 158859243Sobrien Cursor = InputBuf; 158959243Sobrien if (ActionFlag & TCSHOP_DELETE) { 159059243Sobrien c_delfini(); 159159243Sobrien return(CC_REFRESH); 159259243Sobrien } 159359243Sobrien RefCursor(); /* move the cursor */ 159459243Sobrien return(CC_NORM); 159559243Sobrien } 159659243Sobrien} 159759243Sobrien 159859243Sobrien/*ARGSUSED*/ 159959243SobrienCCRETVAL 1600167465Smpe_newline(Char c) 160159243Sobrien{ /* always ignore argument */ 160259243Sobrien USE(c); 1603167465Smp if (adrof(STRhighlight) && MarkIsSet) { 1604167465Smp MarkIsSet = 0; 1605167465Smp ClearLines(); 1606167465Smp ClearDisp(); 1607167465Smp Refresh(); 1608167465Smp } 1609167465Smp MarkIsSet = 0; 1610167465Smp 161159243Sobrien /* PastBottom(); NOW done in ed.inputl.c */ 161259243Sobrien *LastChar++ = '\n'; /* for the benefit of CSH */ 161359243Sobrien *LastChar = '\0'; /* just in case */ 161459243Sobrien if (VImode) 161559243Sobrien InsertPos = InputBuf; /* Reset editing position */ 161659243Sobrien return(CC_NEWLINE); 161759243Sobrien} 161859243Sobrien 161959243Sobrien/*ARGSUSED*/ 162059243SobrienCCRETVAL 1621167465Smpe_newline_hold(Char c) 1622167465Smp{ 1623167465Smp USE(c); 1624167465Smp c_save_inputbuf(); 1625167465Smp HistSaved = 0; 1626167465Smp *LastChar++ = '\n'; /* for the benefit of CSH */ 1627167465Smp *LastChar = '\0'; /* just in case */ 1628167465Smp return(CC_NEWLINE); 1629167465Smp} 1630167465Smp 1631167465Smp/*ARGSUSED*/ 1632167465SmpCCRETVAL 1633167465Smpe_newline_down_hist(Char c) 1634167465Smp{ 1635167465Smp USE(c); 1636167465Smp if (Hist_num > 1) { 1637167465Smp HistSaved = Hist_num; 1638167465Smp } 1639167465Smp *LastChar++ = '\n'; /* for the benefit of CSH */ 1640167465Smp *LastChar = '\0'; /* just in case */ 1641167465Smp return(CC_NEWLINE); 1642167465Smp} 1643167465Smp 1644167465Smp/*ARGSUSED*/ 1645167465SmpCCRETVAL 1646167465Smpe_send_eof(Char c) 164759243Sobrien{ /* for when ^D is ONLY send-eof */ 164859243Sobrien USE(c); 164959243Sobrien PastBottom(); 165059243Sobrien *LastChar = '\0'; /* just in case */ 165159243Sobrien return(CC_EOF); 165259243Sobrien} 165359243Sobrien 165459243Sobrien/*ARGSUSED*/ 165559243SobrienCCRETVAL 1656167465Smpe_complete(Char c) 165759243Sobrien{ 165859243Sobrien USE(c); 165959243Sobrien *LastChar = '\0'; /* just in case */ 166059243Sobrien return(CC_COMPLETE); 166159243Sobrien} 166259243Sobrien 166359243Sobrien/*ARGSUSED*/ 166459243SobrienCCRETVAL 1665167465Smpe_complete_back(Char c) 166659243Sobrien{ 166759243Sobrien USE(c); 166859243Sobrien *LastChar = '\0'; /* just in case */ 166959243Sobrien return(CC_COMPLETE_BACK); 167059243Sobrien} 167159243Sobrien 167259243Sobrien/*ARGSUSED*/ 167359243SobrienCCRETVAL 1674167465Smpe_complete_fwd(Char c) 167559243Sobrien{ 167659243Sobrien USE(c); 167759243Sobrien *LastChar = '\0'; /* just in case */ 167859243Sobrien return(CC_COMPLETE_FWD); 167959243Sobrien} 168059243Sobrien 168159243Sobrien/*ARGSUSED*/ 168259243SobrienCCRETVAL 1683167465Smpe_complete_all(Char c) 168459243Sobrien{ 168559243Sobrien USE(c); 168659243Sobrien *LastChar = '\0'; /* just in case */ 168759243Sobrien return(CC_COMPLETE_ALL); 168859243Sobrien} 168959243Sobrien 169059243Sobrien/*ARGSUSED*/ 169159243SobrienCCRETVAL 1692167465Smpv_cm_complete(Char c) 169359243Sobrien{ 169459243Sobrien USE(c); 169559243Sobrien if (Cursor < LastChar) 169659243Sobrien Cursor++; 169759243Sobrien *LastChar = '\0'; /* just in case */ 169859243Sobrien return(CC_COMPLETE); 169959243Sobrien} 170059243Sobrien 170159243Sobrien/*ARGSUSED*/ 170259243SobrienCCRETVAL 1703167465Smpe_toggle_hist(Char c) 170459243Sobrien{ 170559243Sobrien struct Hist *hp; 170659243Sobrien int h; 170759243Sobrien 170859243Sobrien USE(c); 170959243Sobrien *LastChar = '\0'; /* just in case */ 171059243Sobrien 171159243Sobrien if (Hist_num <= 0) { 171259243Sobrien return CC_ERROR; 171359243Sobrien } 171459243Sobrien 171559243Sobrien hp = Histlist.Hnext; 171659243Sobrien if (hp == NULL) { /* this is only if no history */ 171759243Sobrien return(CC_ERROR); 171859243Sobrien } 171959243Sobrien 172059243Sobrien for (h = 1; h < Hist_num; h++) 172159243Sobrien hp = hp->Hnext; 172259243Sobrien 172359243Sobrien if (!CurrentHistLit) { 172459243Sobrien if (hp->histline) { 1725167465Smp copyn(InputBuf, hp->histline, INBUFSIZE);/*FIXBUF*/ 172659243Sobrien CurrentHistLit = 1; 172759243Sobrien } 172859243Sobrien else { 172959243Sobrien return CC_ERROR; 173059243Sobrien } 173159243Sobrien } 173259243Sobrien else { 1733167465Smp Char *p; 1734167465Smp 1735167465Smp p = sprlex(&hp->Hlex); 1736167465Smp copyn(InputBuf, p, sizeof(InputBuf) / sizeof(Char));/*FIXBUF*/ 1737167465Smp xfree(p); 173859243Sobrien CurrentHistLit = 0; 173959243Sobrien } 174059243Sobrien 1741167465Smp LastChar = Strend(InputBuf); 174259243Sobrien if (LastChar > InputBuf) { 174359243Sobrien if (LastChar[-1] == '\n') 174459243Sobrien LastChar--; 174559243Sobrien if (LastChar[-1] == ' ') 174659243Sobrien LastChar--; 174759243Sobrien if (LastChar < InputBuf) 174859243Sobrien LastChar = InputBuf; 174959243Sobrien } 175059243Sobrien 175159243Sobrien#ifdef KSHVI 175259243Sobrien if (VImode) 175359243Sobrien Cursor = InputBuf; 175459243Sobrien else 175559243Sobrien#endif /* KSHVI */ 175659243Sobrien Cursor = LastChar; 175759243Sobrien 175859243Sobrien return(CC_REFRESH); 175959243Sobrien} 176059243Sobrien 176159243Sobrien/*ARGSUSED*/ 176259243SobrienCCRETVAL 1763167465Smpe_up_hist(Char c) 176459243Sobrien{ 176559243Sobrien Char beep = 0; 176659243Sobrien 176759243Sobrien USE(c); 176859243Sobrien UndoAction = TCSHOP_NOP; 176959243Sobrien *LastChar = '\0'; /* just in case */ 177059243Sobrien 177159243Sobrien if (Hist_num == 0) { /* save the current buffer away */ 1772167465Smp HistBuf.len = 0; 1773167465Smp Strbuf_append(&HistBuf, InputBuf); 1774167465Smp Strbuf_terminate(&HistBuf); 177559243Sobrien } 177659243Sobrien 177759243Sobrien Hist_num += Argument; 177859243Sobrien 1779167465Smp if (GetHistLine() == CC_ERROR) { 178059243Sobrien beep = 1; 1781167465Smp (void) GetHistLine(); /* Hist_num was fixed by first call */ 178259243Sobrien } 178359243Sobrien 178459243Sobrien Refresh(); 178559243Sobrien if (beep) 178659243Sobrien return(CC_ERROR); 178759243Sobrien else 178859243Sobrien return(CC_NORM); /* was CC_UP_HIST */ 178959243Sobrien} 179059243Sobrien 179159243Sobrien/*ARGSUSED*/ 179259243SobrienCCRETVAL 1793167465Smpe_down_hist(Char c) 179459243Sobrien{ 179559243Sobrien USE(c); 179659243Sobrien UndoAction = TCSHOP_NOP; 179759243Sobrien *LastChar = '\0'; /* just in case */ 179859243Sobrien 179959243Sobrien Hist_num -= Argument; 180059243Sobrien 180159243Sobrien if (Hist_num < 0) { 180259243Sobrien Hist_num = 0; 180359243Sobrien return(CC_ERROR); /* make it beep */ 180459243Sobrien } 180559243Sobrien 1806167465Smp return(GetHistLine()); 180759243Sobrien} 180859243Sobrien 180959243Sobrien 181059243Sobrien 181159243Sobrien/* 181259243Sobrien * c_hmatch() return True if the pattern matches the prefix 181359243Sobrien */ 181459243Sobrienstatic int 1815167465Smpc_hmatch(Char *str) 181659243Sobrien{ 1817167465Smp if (Strncmp(patbuf.s, str, patbuf.len) == 0) 181859243Sobrien return 1; 1819167465Smp return Gmatch(str, patbuf.s); 182059243Sobrien} 182159243Sobrien 182259243Sobrien/* 182359243Sobrien * c_hsetpat(): Set the history seatch pattern 182459243Sobrien */ 182559243Sobrienstatic void 1826167465Smpc_hsetpat(void) 182759243Sobrien{ 182859243Sobrien if (LastCmd != F_UP_SEARCH_HIST && LastCmd != F_DOWN_SEARCH_HIST) { 1829167465Smp patbuf.len = 0; 1830167465Smp Strbuf_appendn(&patbuf, InputBuf, Cursor - InputBuf); 1831167465Smp Strbuf_terminate(&patbuf); 183259243Sobrien } 183359243Sobrien#ifdef SDEBUG 183459243Sobrien xprintf("\nHist_num = %d\n", Hist_num); 1835167465Smp xprintf("patlen = %d\n", (int)patbuf.len); 1836167465Smp xprintf("patbuf = \"%S\"\n", patbuf.s); 183759243Sobrien xprintf("Cursor %d LastChar %d\n", Cursor - InputBuf, LastChar - InputBuf); 183859243Sobrien#endif 183959243Sobrien} 184059243Sobrien 184159243Sobrien/*ARGSUSED*/ 184259243SobrienCCRETVAL 1843167465Smpe_up_search_hist(Char c) 184459243Sobrien{ 184559243Sobrien struct Hist *hp; 184659243Sobrien int h; 1847145479Smp int found = 0; 184859243Sobrien 184959243Sobrien USE(c); 185059243Sobrien ActionFlag = TCSHOP_NOP; 185159243Sobrien UndoAction = TCSHOP_NOP; 185259243Sobrien *LastChar = '\0'; /* just in case */ 185359243Sobrien if (Hist_num < 0) { 185459243Sobrien#ifdef DEBUG_EDIT 185559243Sobrien xprintf("%s: e_up_search_hist(): Hist_num < 0; resetting.\n", progname); 185659243Sobrien#endif 185759243Sobrien Hist_num = 0; 185859243Sobrien return(CC_ERROR); 185959243Sobrien } 186059243Sobrien 1861167465Smp if (Hist_num == 0) { 1862167465Smp HistBuf.len = 0; 1863167465Smp Strbuf_append(&HistBuf, InputBuf); 1864167465Smp Strbuf_terminate(&HistBuf); 186559243Sobrien } 186659243Sobrien 186759243Sobrien 186859243Sobrien hp = Histlist.Hnext; 186959243Sobrien if (hp == NULL) 187059243Sobrien return(CC_ERROR); 187159243Sobrien 187259243Sobrien c_hsetpat(); /* Set search pattern !! */ 187359243Sobrien 187459243Sobrien for (h = 1; h <= Hist_num; h++) 187559243Sobrien hp = hp->Hnext; 187659243Sobrien 187759243Sobrien while (hp != NULL) { 1878167465Smp Char *hl; 1879167465Smp int matched; 1880167465Smp 1881167465Smp if (hp->histline == NULL) 1882167465Smp hp->histline = sprlex(&hp->Hlex); 1883167465Smp if (HistLit) 1884167465Smp hl = hp->histline; 1885167465Smp else { 1886167465Smp hl = sprlex(&hp->Hlex); 1887167465Smp cleanup_push(hl, xfree); 188859243Sobrien } 188959243Sobrien#ifdef SDEBUG 189059243Sobrien xprintf("Comparing with \"%S\"\n", hl); 189159243Sobrien#endif 1892167465Smp matched = (Strncmp(hl, InputBuf, (size_t) (LastChar - InputBuf)) || 1893167465Smp hl[LastChar-InputBuf]) && c_hmatch(hl); 1894167465Smp if (!HistLit) 1895167465Smp cleanup_until(hl); 1896167465Smp if (matched) { 189759243Sobrien found++; 189859243Sobrien break; 189959243Sobrien } 190059243Sobrien h++; 190159243Sobrien hp = hp->Hnext; 190259243Sobrien } 190359243Sobrien 190459243Sobrien if (!found) { 190559243Sobrien#ifdef SDEBUG 1906167465Smp xprintf("not found\n"); 190759243Sobrien#endif 190859243Sobrien return(CC_ERROR); 190959243Sobrien } 191059243Sobrien 191159243Sobrien Hist_num = h; 191259243Sobrien 1913167465Smp return(GetHistLine()); 191459243Sobrien} 191559243Sobrien 191659243Sobrien/*ARGSUSED*/ 191759243SobrienCCRETVAL 1918167465Smpe_down_search_hist(Char c) 191959243Sobrien{ 192059243Sobrien struct Hist *hp; 192159243Sobrien int h; 1922145479Smp int found = 0; 192359243Sobrien 192459243Sobrien USE(c); 192559243Sobrien ActionFlag = TCSHOP_NOP; 192659243Sobrien UndoAction = TCSHOP_NOP; 192759243Sobrien *LastChar = '\0'; /* just in case */ 192859243Sobrien 192959243Sobrien if (Hist_num == 0) 193059243Sobrien return(CC_ERROR); 193159243Sobrien 193259243Sobrien hp = Histlist.Hnext; 193359243Sobrien if (hp == 0) 193459243Sobrien return(CC_ERROR); 193559243Sobrien 193659243Sobrien c_hsetpat(); /* Set search pattern !! */ 193759243Sobrien 193859243Sobrien for (h = 1; h < Hist_num && hp; h++) { 1939167465Smp Char *hl; 1940167465Smp if (hp->histline == NULL) 1941167465Smp hp->histline = sprlex(&hp->Hlex); 1942167465Smp if (HistLit) 1943167465Smp hl = hp->histline; 1944167465Smp else { 1945167465Smp hl = sprlex(&hp->Hlex); 1946167465Smp cleanup_push(hl, xfree); 194759243Sobrien } 194859243Sobrien#ifdef SDEBUG 194959243Sobrien xprintf("Comparing with \"%S\"\n", hl); 195059243Sobrien#endif 195159243Sobrien if ((Strncmp(hl, InputBuf, (size_t) (LastChar - InputBuf)) || 195259243Sobrien hl[LastChar-InputBuf]) && c_hmatch(hl)) 195359243Sobrien found = h; 1954167465Smp if (!HistLit) 1955167465Smp cleanup_until(hl); 195659243Sobrien hp = hp->Hnext; 195759243Sobrien } 195859243Sobrien 195959243Sobrien if (!found) { /* is it the current history number? */ 1960167465Smp if (!c_hmatch(HistBuf.s)) { 196159243Sobrien#ifdef SDEBUG 1962167465Smp xprintf("not found\n"); 196359243Sobrien#endif 196459243Sobrien return(CC_ERROR); 196559243Sobrien } 196659243Sobrien } 196759243Sobrien 196859243Sobrien Hist_num = found; 196959243Sobrien 1970167465Smp return(GetHistLine()); 197159243Sobrien} 197259243Sobrien 197359243Sobrien/*ARGSUSED*/ 197459243SobrienCCRETVAL 1975167465Smpe_helpme(Char c) 197659243Sobrien{ 197759243Sobrien USE(c); 197859243Sobrien PastBottom(); 197959243Sobrien *LastChar = '\0'; /* just in case */ 198059243Sobrien return(CC_HELPME); 198159243Sobrien} 198259243Sobrien 198359243Sobrien/*ARGSUSED*/ 198459243SobrienCCRETVAL 1985167465Smpe_correct(Char c) 198659243Sobrien{ 198759243Sobrien USE(c); 198859243Sobrien *LastChar = '\0'; /* just in case */ 198959243Sobrien return(CC_CORRECT); 199059243Sobrien} 199159243Sobrien 199259243Sobrien/*ARGSUSED*/ 199359243SobrienCCRETVAL 1994167465Smpe_correctl(Char c) 199559243Sobrien{ 199659243Sobrien USE(c); 199759243Sobrien *LastChar = '\0'; /* just in case */ 199859243Sobrien return(CC_CORRECT_L); 199959243Sobrien} 200059243Sobrien 200159243Sobrien/*ARGSUSED*/ 200259243SobrienCCRETVAL 2003167465Smpe_run_fg_editor(Char c) 200459243Sobrien{ 200583098Smp struct process *pp; 200659243Sobrien 200759243Sobrien USE(c); 200859243Sobrien if ((pp = find_stop_ed()) != NULL) { 200959243Sobrien /* save our editor state so we can restore it */ 2010167465Smp c_save_inputbuf(); 201159243Sobrien Hist_num = 0; /* for the history commands */ 201259243Sobrien 201359243Sobrien /* put the tty in a sane mode */ 201459243Sobrien PastBottom(); 201559243Sobrien (void) Cookedmode(); /* make sure the tty is set up correctly */ 201659243Sobrien 201759243Sobrien /* do it! */ 201859243Sobrien fg_proc_entry(pp); 201959243Sobrien 202059243Sobrien (void) Rawmode(); /* go on */ 202159243Sobrien Refresh(); 2022167465Smp RestoreSaved = 0; 2023167465Smp HistSaved = 0; 202459243Sobrien } 202559243Sobrien return(CC_NORM); 202659243Sobrien} 202759243Sobrien 202859243Sobrien/*ARGSUSED*/ 202959243SobrienCCRETVAL 2030167465Smpe_list_choices(Char c) 203159243Sobrien{ 203259243Sobrien USE(c); 203359243Sobrien PastBottom(); 203459243Sobrien *LastChar = '\0'; /* just in case */ 203559243Sobrien return(CC_LIST_CHOICES); 203659243Sobrien} 203759243Sobrien 203859243Sobrien/*ARGSUSED*/ 203959243SobrienCCRETVAL 2040167465Smpe_list_all(Char c) 204159243Sobrien{ 204259243Sobrien USE(c); 204359243Sobrien PastBottom(); 204459243Sobrien *LastChar = '\0'; /* just in case */ 204559243Sobrien return(CC_LIST_ALL); 204659243Sobrien} 204759243Sobrien 204859243Sobrien/*ARGSUSED*/ 204959243SobrienCCRETVAL 2050167465Smpe_list_glob(Char c) 205159243Sobrien{ 205259243Sobrien USE(c); 205359243Sobrien PastBottom(); 205459243Sobrien *LastChar = '\0'; /* just in case */ 205559243Sobrien return(CC_LIST_GLOB); 205659243Sobrien} 205759243Sobrien 205859243Sobrien/*ARGSUSED*/ 205959243SobrienCCRETVAL 2060167465Smpe_expand_glob(Char c) 206159243Sobrien{ 206259243Sobrien USE(c); 206359243Sobrien *LastChar = '\0'; /* just in case */ 206459243Sobrien return(CC_EXPAND_GLOB); 206559243Sobrien} 206659243Sobrien 206759243Sobrien/*ARGSUSED*/ 206859243SobrienCCRETVAL 2069167465Smpe_normalize_path(Char c) 207059243Sobrien{ 207159243Sobrien USE(c); 207259243Sobrien *LastChar = '\0'; /* just in case */ 207359243Sobrien return(CC_NORMALIZE_PATH); 207459243Sobrien} 207559243Sobrien 207659243Sobrien/*ARGSUSED*/ 207759243SobrienCCRETVAL 2078167465Smpe_normalize_command(Char c) 207959243Sobrien{ 208059243Sobrien USE(c); 208159243Sobrien *LastChar = '\0'; /* just in case */ 208259243Sobrien return(CC_NORMALIZE_COMMAND); 208359243Sobrien} 208459243Sobrien 208559243Sobrien/*ARGSUSED*/ 208659243SobrienCCRETVAL 2087167465Smpe_expand_vars(Char c) 208859243Sobrien{ 208959243Sobrien USE(c); 209059243Sobrien *LastChar = '\0'; /* just in case */ 209159243Sobrien return(CC_EXPAND_VARS); 209259243Sobrien} 209359243Sobrien 209459243Sobrien/*ARGSUSED*/ 209559243SobrienCCRETVAL 2096167465Smpe_which(Char c) 209759243Sobrien{ /* do a fast command line which(1) */ 209859243Sobrien USE(c); 2099167465Smp c_save_inputbuf(); 2100167465Smp Hist_num = 0; /* for the history commands */ 210159243Sobrien PastBottom(); 210259243Sobrien *LastChar = '\0'; /* just in case */ 210359243Sobrien return(CC_WHICH); 210459243Sobrien} 210559243Sobrien 210659243Sobrien/*ARGSUSED*/ 210759243SobrienCCRETVAL 2108167465Smpe_last_item(Char c) 210959243Sobrien{ /* insert the last element of the prev. cmd */ 211083098Smp struct Hist *hp; 211183098Smp struct wordent *wp, *firstp; 211283098Smp int i; 2113167465Smp Char *expanded; 211459243Sobrien 211559243Sobrien USE(c); 211659243Sobrien if (Argument <= 0) 211759243Sobrien return(CC_ERROR); 211859243Sobrien 211959243Sobrien hp = Histlist.Hnext; 212059243Sobrien if (hp == NULL) { /* this is only if no history */ 212159243Sobrien return(CC_ERROR); 212259243Sobrien } 212359243Sobrien 212459243Sobrien wp = (hp->Hlex).prev; 212559243Sobrien 212659243Sobrien if (wp->prev == (struct wordent *) NULL) 212759243Sobrien return(CC_ERROR); /* an empty history entry */ 212859243Sobrien 212959243Sobrien firstp = (hp->Hlex).next; 213059243Sobrien 213159243Sobrien /* back up arg words in lex */ 213259243Sobrien for (i = 0; i < Argument && wp != firstp; i++) { 213359243Sobrien wp = wp->prev; 213459243Sobrien } 213559243Sobrien 2136167465Smp expanded = expand_lex(wp->prev, 0, i - 1); 2137167465Smp if (InsertStr(expanded)) { 2138167465Smp xfree(expanded); 213959243Sobrien return(CC_ERROR); 2140167465Smp } 214159243Sobrien 2142167465Smp xfree(expanded); 214359243Sobrien return(CC_REFRESH); 214459243Sobrien} 214559243Sobrien 214659243Sobrien/*ARGSUSED*/ 214759243SobrienCCRETVAL 2148167465Smpe_dabbrev_expand(Char c) 214959243Sobrien{ /* expand to preceding word matching prefix */ 215083098Smp Char *cp, *ncp, *bp; 215183098Smp struct Hist *hp; 2152167465Smp int arg = 0, i; 2153167465Smp size_t len = 0; 2154145479Smp int found = 0; 2155167465Smp Char *hbuf; 215659243Sobrien static int oldevent, hist, word; 215759243Sobrien static Char *start, *oldcursor; 215859243Sobrien 215959243Sobrien USE(c); 216059243Sobrien if (Argument <= 0) 216159243Sobrien return(CC_ERROR); 216259243Sobrien 216383098Smp cp = c_preword(Cursor, InputBuf, 1, STRshwordsep); 216459243Sobrien if (cp == Cursor || Isspace(*cp)) 216559243Sobrien return(CC_ERROR); 216659243Sobrien 2167167465Smp hbuf = NULL; 216859243Sobrien hp = Histlist.Hnext; 216959243Sobrien bp = InputBuf; 217059243Sobrien if (Argument == 1 && eventno == oldevent && cp == start && 2171167465Smp Cursor == oldcursor && patbuf.len > 0 2172167465Smp && Strncmp(patbuf.s, cp, patbuf.len) == 0){ 217359243Sobrien /* continue previous search - go to last match (hist/word) */ 217459243Sobrien if (hist != 0) { /* need to move up history */ 217559243Sobrien for (i = 1; i < hist && hp != NULL; i++) 217659243Sobrien hp = hp->Hnext; 217759243Sobrien if (hp == NULL) /* "can't happen" */ 2178167465Smp goto err_hbuf; 2179167465Smp hbuf = expand_lex(&hp->Hlex, 0, INT_MAX); 2180167465Smp cp = Strend(hbuf); 218159243Sobrien bp = hbuf; 218259243Sobrien hp = hp->Hnext; 218359243Sobrien } 218483098Smp cp = c_preword(cp, bp, word, STRshwordsep); 218559243Sobrien } else { /* starting new search */ 218659243Sobrien oldevent = eventno; 218759243Sobrien start = cp; 2188167465Smp patbuf.len = 0; 2189167465Smp Strbuf_appendn(&patbuf, cp, Cursor - cp); 219059243Sobrien hist = 0; 219159243Sobrien word = 0; 219259243Sobrien } 219359243Sobrien 219459243Sobrien while (!found) { 219583098Smp ncp = c_preword(cp, bp, 1, STRshwordsep); 219659243Sobrien if (ncp == cp || Isspace(*ncp)) { /* beginning of line */ 219759243Sobrien hist++; 219859243Sobrien word = 0; 219959243Sobrien if (hp == NULL) 2200167465Smp goto err_hbuf; 2201167465Smp hbuf = expand_lex(&hp->Hlex, 0, INT_MAX); 2202167465Smp cp = Strend(hbuf); 220359243Sobrien bp = hbuf; 220459243Sobrien hp = hp->Hnext; 220559243Sobrien continue; 220659243Sobrien } else { 220759243Sobrien word++; 2208167465Smp len = c_endword(ncp-1, cp, 1, STRshwordsep) - ncp + 1; 220959243Sobrien cp = ncp; 221059243Sobrien } 2211167465Smp if (len > patbuf.len && Strncmp(cp, patbuf.s, patbuf.len) == 0) { 221259243Sobrien /* We don't fully check distinct matches as Gnuemacs does: */ 221359243Sobrien if (Argument > 1) { /* just count matches */ 221459243Sobrien if (++arg >= Argument) 221559243Sobrien found++; 221659243Sobrien } else { /* match if distinct from previous */ 2217167465Smp if (len != (size_t)(Cursor - start) 2218167465Smp || Strncmp(cp, start, len) != 0) 221959243Sobrien found++; 222059243Sobrien } 222159243Sobrien } 222259243Sobrien } 222359243Sobrien 222459243Sobrien if (LastChar + len - (Cursor - start) >= InputLim) 2225167465Smp goto err_hbuf; /* no room */ 222659243Sobrien DeleteBack(Cursor - start); 222759243Sobrien c_insert(len); 222859243Sobrien while (len--) 222959243Sobrien *Cursor++ = *cp++; 223059243Sobrien oldcursor = Cursor; 2231167465Smp xfree(hbuf); 223259243Sobrien return(CC_REFRESH); 2233167465Smp 2234167465Smp err_hbuf: 2235167465Smp xfree(hbuf); 2236167465Smp return CC_ERROR; 223759243Sobrien} 223859243Sobrien 223959243Sobrien/*ARGSUSED*/ 224059243SobrienCCRETVAL 2241167465Smpe_yank_kill(Char c) 224259243Sobrien{ /* almost like GnuEmacs */ 224383098Smp int len; 224483098Smp Char *kp, *cp; 224559243Sobrien 224659243Sobrien USE(c); 224783098Smp if (KillRingLen == 0) /* nothing killed */ 224859243Sobrien return(CC_ERROR); 224983098Smp len = Strlen(KillRing[YankPos].buf); 225083098Smp if (LastChar + len >= InputLim) 225159243Sobrien return(CC_ERROR); /* end of buffer space */ 225259243Sobrien 225359243Sobrien /* else */ 225459243Sobrien cp = Cursor; /* for speed */ 225559243Sobrien 225683098Smp c_insert(len); /* open the space, */ 225783098Smp for (kp = KillRing[YankPos].buf; *kp; kp++) /* copy the chars */ 225859243Sobrien *cp++ = *kp; 225959243Sobrien 226083098Smp if (Argument == 1) { /* if no arg */ 226183098Smp Mark = Cursor; /* mark at beginning, cursor at end */ 226283098Smp Cursor = cp; 226383098Smp } else { 226483098Smp Mark = cp; /* else cursor at beginning, mark at end */ 226583098Smp } 226659243Sobrien 2267167465Smp if (adrof(STRhighlight) && MarkIsSet) { 2268167465Smp ClearLines(); 2269167465Smp ClearDisp(); 2270167465Smp } 2271167465Smp MarkIsSet = 0; 227259243Sobrien return(CC_REFRESH); 227359243Sobrien} 227459243Sobrien 227559243Sobrien/*ARGSUSED*/ 227659243SobrienCCRETVAL 2277167465Smpe_yank_pop(Char c) 227883098Smp{ /* almost like GnuEmacs */ 227983098Smp int m_bef_c, del_len, ins_len; 228083098Smp Char *kp, *cp; 228183098Smp 228283098Smp USE(c); 228383098Smp 228483098Smp#if 0 228583098Smp /* XXX This "should" be here, but doesn't work, since LastCmd 228683098Smp gets set on CC_ERROR and CC_ARGHACK, which it shouldn't(?). 228783098Smp (But what about F_ARGFOUR?) I.e. if you hit M-y twice the 228883098Smp second one will "succeed" even if the first one wasn't preceded 228983098Smp by a yank, and giving an argument is impossible. Now we "succeed" 229083098Smp regardless of previous command, which is wrong too of course. */ 229183098Smp if (LastCmd != F_YANK_KILL && LastCmd != F_YANK_POP) 229283098Smp return(CC_ERROR); 229383098Smp#endif 229483098Smp 229583098Smp if (KillRingLen == 0) /* nothing killed */ 229683098Smp return(CC_ERROR); 229783098Smp YankPos -= Argument; 229883098Smp while (YankPos < 0) 229983098Smp YankPos += KillRingLen; 230083098Smp YankPos %= KillRingLen; 230183098Smp 230283098Smp if (Cursor > Mark) { 230383098Smp del_len = Cursor - Mark; 230483098Smp m_bef_c = 1; 230583098Smp } else { 230683098Smp del_len = Mark - Cursor; 230783098Smp m_bef_c = 0; 230883098Smp } 230983098Smp ins_len = Strlen(KillRing[YankPos].buf); 231083098Smp if (LastChar + ins_len - del_len >= InputLim) 231183098Smp return(CC_ERROR); /* end of buffer space */ 231283098Smp 231383098Smp if (m_bef_c) { 231483098Smp c_delbefore(del_len); 231583098Smp } else { 231683098Smp c_delafter(del_len); 231783098Smp } 231883098Smp cp = Cursor; /* for speed */ 231983098Smp 232083098Smp c_insert(ins_len); /* open the space, */ 232183098Smp for (kp = KillRing[YankPos].buf; *kp; kp++) /* copy the chars */ 232283098Smp *cp++ = *kp; 232383098Smp 232483098Smp if (m_bef_c) { 232583098Smp Mark = Cursor; /* mark at beginning, cursor at end */ 232683098Smp Cursor = cp; 232783098Smp } else { 232883098Smp Mark = cp; /* else cursor at beginning, mark at end */ 232983098Smp } 233083098Smp 2331167465Smp if (adrof(STRhighlight) && MarkIsSet) { 2332167465Smp ClearLines(); 2333167465Smp ClearDisp(); 2334167465Smp } 2335167465Smp MarkIsSet = 0; 233683098Smp return(CC_REFRESH); 233783098Smp} 233883098Smp 233983098Smp/*ARGSUSED*/ 234083098SmpCCRETVAL 2341167465Smpv_delprev(Char c) /* Backspace key in insert mode */ 234259243Sobrien{ 234359243Sobrien int rc; 234459243Sobrien 234559243Sobrien USE(c); 234659243Sobrien rc = CC_ERROR; 234759243Sobrien 234859243Sobrien if (InsertPos != 0) { 234959243Sobrien if (Argument <= Cursor - InsertPos) { 235059243Sobrien c_delbefore(Argument); /* delete before */ 235159243Sobrien rc = CC_REFRESH; 235259243Sobrien } 235359243Sobrien } 235459243Sobrien return(rc); 235559243Sobrien} /* v_delprev */ 235659243Sobrien 235759243Sobrien/*ARGSUSED*/ 235859243SobrienCCRETVAL 2359167465Smpe_delprev(Char c) 236059243Sobrien{ 236159243Sobrien USE(c); 236259243Sobrien if (Cursor > InputBuf) { 236359243Sobrien c_delbefore(Argument); /* delete before dot */ 236459243Sobrien return(CC_REFRESH); 236559243Sobrien } 236659243Sobrien else { 236759243Sobrien return(CC_ERROR); 236859243Sobrien } 236959243Sobrien} 237059243Sobrien 237159243Sobrien/*ARGSUSED*/ 237259243SobrienCCRETVAL 2373167465Smpe_delwordprev(Char c) 237459243Sobrien{ 237583098Smp Char *cp; 237659243Sobrien 237759243Sobrien USE(c); 237859243Sobrien if (Cursor == InputBuf) 237959243Sobrien return(CC_ERROR); 238059243Sobrien /* else */ 238159243Sobrien 238259243Sobrien cp = c_prev_word(Cursor, InputBuf, Argument); 238359243Sobrien 238483098Smp c_push_kill(cp, Cursor); /* save the text */ 238559243Sobrien 238659243Sobrien c_delbefore((int)(Cursor - cp)); /* delete before dot */ 238759243Sobrien return(CC_REFRESH); 238859243Sobrien} 238959243Sobrien 239059243Sobrien/* DCS <dcs@neutron.chem.yale.edu>, 9 Oct 93 239159243Sobrien * 239259243Sobrien * Changed the names of some of the ^D family of editor functions to 239359243Sobrien * correspond to what they actually do and created new e_delnext_list 239459243Sobrien * for completeness. 239559243Sobrien * 239659243Sobrien * Old names: New names: 239759243Sobrien * 239859243Sobrien * delete-char delete-char-or-eof 239959243Sobrien * F_DELNEXT F_DELNEXT_EOF 240059243Sobrien * e_delnext e_delnext_eof 240159243Sobrien * edelnxt edelnxteof 240259243Sobrien * delete-char-or-eof delete-char 240359243Sobrien * F_DELNEXT_EOF F_DELNEXT 240459243Sobrien * e_delnext_eof e_delnext 240559243Sobrien * edelnxteof edelnxt 240659243Sobrien * delete-char-or-list delete-char-or-list-or-eof 240759243Sobrien * F_LIST_DELNEXT F_DELNEXT_LIST_EOF 240859243Sobrien * e_list_delnext e_delnext_list_eof 240959243Sobrien * edellsteof 241059243Sobrien * (no old equivalent) delete-char-or-list 241159243Sobrien * F_DELNEXT_LIST 241259243Sobrien * e_delnext_list 241359243Sobrien * e_delnxtlst 241459243Sobrien */ 241559243Sobrien 241659243Sobrien/* added by mtk@ari.ncl.omron.co.jp (920818) */ 241759243Sobrien/* rename e_delnext() -> e_delnext_eof() */ 241859243Sobrien/*ARGSUSED*/ 241959243SobrienCCRETVAL 2420167465Smpe_delnext(Char c) 242159243Sobrien{ 242259243Sobrien USE(c); 242359243Sobrien if (Cursor == LastChar) {/* if I'm at the end */ 242459243Sobrien if (!VImode) { 242559243Sobrien return(CC_ERROR); 242659243Sobrien } 242759243Sobrien else { 242859243Sobrien if (Cursor != InputBuf) 242959243Sobrien Cursor--; 243059243Sobrien else 243159243Sobrien return(CC_ERROR); 243259243Sobrien } 243359243Sobrien } 243459243Sobrien c_delafter(Argument); /* delete after dot */ 243559243Sobrien if (Cursor > LastChar) 243659243Sobrien Cursor = LastChar; /* bounds check */ 243759243Sobrien return(CC_REFRESH); 243859243Sobrien} 243959243Sobrien 244059243Sobrien 244159243Sobrien/*ARGSUSED*/ 244259243SobrienCCRETVAL 2443167465Smpe_delnext_eof(Char c) 244459243Sobrien{ 244559243Sobrien USE(c); 244659243Sobrien if (Cursor == LastChar) {/* if I'm at the end */ 244759243Sobrien if (!VImode) { 244859243Sobrien if (Cursor == InputBuf) { 244959243Sobrien /* if I'm also at the beginning */ 245059243Sobrien so_write(STReof, 4);/* then do a EOF */ 245159243Sobrien flush(); 245259243Sobrien return(CC_EOF); 245359243Sobrien } 245459243Sobrien else 245559243Sobrien return(CC_ERROR); 245659243Sobrien } 245759243Sobrien else { 245859243Sobrien if (Cursor != InputBuf) 245959243Sobrien Cursor--; 246059243Sobrien else 246159243Sobrien return(CC_ERROR); 246259243Sobrien } 246359243Sobrien } 246459243Sobrien c_delafter(Argument); /* delete after dot */ 246559243Sobrien if (Cursor > LastChar) 246659243Sobrien Cursor = LastChar; /* bounds check */ 246759243Sobrien return(CC_REFRESH); 246859243Sobrien} 246959243Sobrien 247059243Sobrien/*ARGSUSED*/ 247159243SobrienCCRETVAL 2472167465Smpe_delnext_list(Char c) 247359243Sobrien{ 247459243Sobrien USE(c); 247559243Sobrien if (Cursor == LastChar) { /* if I'm at the end */ 247659243Sobrien PastBottom(); 247759243Sobrien *LastChar = '\0'; /* just in case */ 247859243Sobrien return(CC_LIST_CHOICES); 247959243Sobrien } 248059243Sobrien else { 248159243Sobrien c_delafter(Argument); /* delete after dot */ 248259243Sobrien if (Cursor > LastChar) 248359243Sobrien Cursor = LastChar; /* bounds check */ 248459243Sobrien return(CC_REFRESH); 248559243Sobrien } 248659243Sobrien} 248759243Sobrien 248859243Sobrien/*ARGSUSED*/ 248959243SobrienCCRETVAL 2490167465Smpe_delnext_list_eof(Char c) 249159243Sobrien{ 249259243Sobrien USE(c); 249359243Sobrien if (Cursor == LastChar) { /* if I'm at the end */ 249459243Sobrien if (Cursor == InputBuf) { /* if I'm also at the beginning */ 249559243Sobrien so_write(STReof, 4);/* then do a EOF */ 249659243Sobrien flush(); 249759243Sobrien return(CC_EOF); 249859243Sobrien } 249959243Sobrien else { 250059243Sobrien PastBottom(); 250159243Sobrien *LastChar = '\0'; /* just in case */ 250259243Sobrien return(CC_LIST_CHOICES); 250359243Sobrien } 250459243Sobrien } 250559243Sobrien else { 250659243Sobrien c_delafter(Argument); /* delete after dot */ 250759243Sobrien if (Cursor > LastChar) 250859243Sobrien Cursor = LastChar; /* bounds check */ 250959243Sobrien return(CC_REFRESH); 251059243Sobrien } 251159243Sobrien} 251259243Sobrien 251359243Sobrien/*ARGSUSED*/ 251459243SobrienCCRETVAL 2515167465Smpe_list_eof(Char c) 251659243Sobrien{ 251759243Sobrien CCRETVAL rv; 251859243Sobrien 251959243Sobrien USE(c); 252059243Sobrien if (Cursor == LastChar && Cursor == InputBuf) { 252159243Sobrien so_write(STReof, 4); /* then do a EOF */ 252259243Sobrien flush(); 252359243Sobrien rv = CC_EOF; 252459243Sobrien } 252559243Sobrien else { 252659243Sobrien PastBottom(); 252759243Sobrien *LastChar = '\0'; /* just in case */ 252859243Sobrien rv = CC_LIST_CHOICES; 252959243Sobrien } 253059243Sobrien return rv; 253159243Sobrien} 253259243Sobrien 253359243Sobrien/*ARGSUSED*/ 253459243SobrienCCRETVAL 2535167465Smpe_delwordnext(Char c) 253659243Sobrien{ 253783098Smp Char *cp; 253859243Sobrien 253959243Sobrien USE(c); 254059243Sobrien if (Cursor == LastChar) 254159243Sobrien return(CC_ERROR); 254259243Sobrien /* else */ 254359243Sobrien 254459243Sobrien cp = c_next_word(Cursor, LastChar, Argument); 254559243Sobrien 254683098Smp c_push_kill(Cursor, cp); /* save the text */ 254759243Sobrien 254859243Sobrien c_delafter((int)(cp - Cursor)); /* delete after dot */ 254959243Sobrien if (Cursor > LastChar) 255059243Sobrien Cursor = LastChar; /* bounds check */ 255159243Sobrien return(CC_REFRESH); 255259243Sobrien} 255359243Sobrien 255459243Sobrien/*ARGSUSED*/ 255559243SobrienCCRETVAL 2556167465Smpe_toend(Char c) 255759243Sobrien{ 255859243Sobrien USE(c); 255959243Sobrien Cursor = LastChar; 256059243Sobrien if (VImode) 256159243Sobrien if (ActionFlag & TCSHOP_DELETE) { 256259243Sobrien c_delfini(); 256359243Sobrien return(CC_REFRESH); 256459243Sobrien } 256559243Sobrien RefCursor(); /* move the cursor */ 256659243Sobrien return(CC_NORM); 256759243Sobrien} 256859243Sobrien 256959243Sobrien/*ARGSUSED*/ 257059243SobrienCCRETVAL 2571167465Smpe_tobeg(Char c) 257259243Sobrien{ 257359243Sobrien USE(c); 257459243Sobrien Cursor = InputBuf; 257559243Sobrien 257659243Sobrien if (VImode) { 257759243Sobrien while (Isspace(*Cursor)) /* We want FIRST non space character */ 257859243Sobrien Cursor++; 257959243Sobrien if (ActionFlag & TCSHOP_DELETE) { 258059243Sobrien c_delfini(); 258159243Sobrien return(CC_REFRESH); 258259243Sobrien } 258359243Sobrien } 258459243Sobrien 258559243Sobrien RefCursor(); /* move the cursor */ 258659243Sobrien return(CC_NORM); 258759243Sobrien} 258859243Sobrien 258959243Sobrien/*ARGSUSED*/ 259059243SobrienCCRETVAL 2591167465Smpe_killend(Char c) 259259243Sobrien{ 259359243Sobrien USE(c); 259483098Smp c_push_kill(Cursor, LastChar); /* copy it */ 2595167465Smp LastChar = Cursor; /* zap! -- delete to end */ 2596167465Smp if (Mark > Cursor) 2597167465Smp Mark = Cursor; 2598167465Smp MarkIsSet = 0; 259959243Sobrien return(CC_REFRESH); 260059243Sobrien} 260159243Sobrien 260259243Sobrien 260359243Sobrien/*ARGSUSED*/ 260459243SobrienCCRETVAL 2605167465Smpe_killbeg(Char c) 260659243Sobrien{ 260759243Sobrien USE(c); 260883098Smp c_push_kill(InputBuf, Cursor); /* copy it */ 260959243Sobrien c_delbefore((int)(Cursor - InputBuf)); 2610145479Smp if (Mark && Mark > Cursor) 2611145479Smp Mark -= Cursor-InputBuf; 261259243Sobrien return(CC_REFRESH); 261359243Sobrien} 261459243Sobrien 261559243Sobrien/*ARGSUSED*/ 261659243SobrienCCRETVAL 2617167465Smpe_killall(Char c) 261859243Sobrien{ 261959243Sobrien USE(c); 262083098Smp c_push_kill(InputBuf, LastChar); /* copy it */ 2621145479Smp Cursor = Mark = LastChar = InputBuf; /* zap! -- delete all of it */ 2622167465Smp MarkIsSet = 0; 262359243Sobrien return(CC_REFRESH); 262459243Sobrien} 262559243Sobrien 262659243Sobrien/*ARGSUSED*/ 262759243SobrienCCRETVAL 2628167465Smpe_killregion(Char c) 262959243Sobrien{ 263059243Sobrien USE(c); 263159243Sobrien if (!Mark) 263259243Sobrien return(CC_ERROR); 263359243Sobrien 263459243Sobrien if (Mark > Cursor) { 263583098Smp c_push_kill(Cursor, Mark); /* copy it */ 263683098Smp c_delafter((int)(Mark - Cursor)); /* delete it - UNUSED BY VI mode */ 263783098Smp Mark = Cursor; 263859243Sobrien } 263959243Sobrien else { /* mark is before cursor */ 264083098Smp c_push_kill(Mark, Cursor); /* copy it */ 264183098Smp c_delbefore((int)(Cursor - Mark)); 264259243Sobrien } 2643167465Smp if (adrof(STRhighlight) && MarkIsSet) { 2644167465Smp ClearLines(); 2645167465Smp ClearDisp(); 2646167465Smp } 2647167465Smp MarkIsSet = 0; 264859243Sobrien return(CC_REFRESH); 264959243Sobrien} 265059243Sobrien 265159243Sobrien/*ARGSUSED*/ 265259243SobrienCCRETVAL 2653167465Smpe_copyregion(Char c) 265459243Sobrien{ 265559243Sobrien USE(c); 265659243Sobrien if (!Mark) 265759243Sobrien return(CC_ERROR); 265859243Sobrien 265959243Sobrien if (Mark > Cursor) { 266083098Smp c_push_kill(Cursor, Mark); /* copy it */ 266159243Sobrien } 266259243Sobrien else { /* mark is before cursor */ 266383098Smp c_push_kill(Mark, Cursor); /* copy it */ 266459243Sobrien } 266559243Sobrien return(CC_NORM); /* don't even need to Refresh() */ 266659243Sobrien} 266759243Sobrien 266859243Sobrien/*ARGSUSED*/ 266959243SobrienCCRETVAL 2670167465Smpe_charswitch(Char cc) 267159243Sobrien{ 267283098Smp Char c; 267359243Sobrien 267459243Sobrien USE(cc); 267559243Sobrien 267659243Sobrien /* do nothing if we are at beginning of line or have only one char */ 267759243Sobrien if (Cursor == &InputBuf[0] || LastChar == &InputBuf[1]) { 267859243Sobrien return(CC_ERROR); 267959243Sobrien } 268059243Sobrien 268159243Sobrien if (Cursor < LastChar) { 268259243Sobrien Cursor++; 268359243Sobrien } 268459243Sobrien c = Cursor[-2]; 268559243Sobrien Cursor[-2] = Cursor[-1]; 268659243Sobrien Cursor[-1] = c; 268759243Sobrien return(CC_REFRESH); 268859243Sobrien} 268959243Sobrien 269059243Sobrien/*ARGSUSED*/ 269159243SobrienCCRETVAL 2692167465Smpe_gcharswitch(Char cc) 269359243Sobrien{ /* gosmacs style ^T */ 269483098Smp Char c; 269559243Sobrien 269659243Sobrien USE(cc); 269759243Sobrien if (Cursor > &InputBuf[1]) {/* must have at least two chars entered */ 269859243Sobrien c = Cursor[-2]; 269959243Sobrien Cursor[-2] = Cursor[-1]; 270059243Sobrien Cursor[-1] = c; 270159243Sobrien return(CC_REFRESH); 270259243Sobrien } 270359243Sobrien else { 270459243Sobrien return(CC_ERROR); 270559243Sobrien } 270659243Sobrien} 270759243Sobrien 270859243Sobrien/*ARGSUSED*/ 270959243SobrienCCRETVAL 2710167465Smpe_charback(Char c) 271159243Sobrien{ 271259243Sobrien USE(c); 271359243Sobrien if (Cursor > InputBuf) { 2714167465Smp if (Argument > Cursor - InputBuf) 271559243Sobrien Cursor = InputBuf; 271659243Sobrien else 2717167465Smp Cursor -= Argument; 271859243Sobrien 271959243Sobrien if (VImode) 272059243Sobrien if (ActionFlag & TCSHOP_DELETE) { 272159243Sobrien c_delfini(); 272259243Sobrien return(CC_REFRESH); 272359243Sobrien } 272459243Sobrien 272559243Sobrien RefCursor(); 272659243Sobrien return(CC_NORM); 272759243Sobrien } 272859243Sobrien else { 272959243Sobrien return(CC_ERROR); 273059243Sobrien } 273159243Sobrien} 273259243Sobrien 273359243Sobrien/*ARGSUSED*/ 273459243SobrienCCRETVAL 2735167465Smpv_wordback(Char c) 273659243Sobrien{ 273759243Sobrien USE(c); 273859243Sobrien if (Cursor == InputBuf) 273959243Sobrien return(CC_ERROR); 274059243Sobrien /* else */ 274159243Sobrien 274283098Smp Cursor = c_preword(Cursor, InputBuf, Argument, STRshwspace); /* bounds check */ 274359243Sobrien 274459243Sobrien if (ActionFlag & TCSHOP_DELETE) { 274559243Sobrien c_delfini(); 274659243Sobrien return(CC_REFRESH); 274759243Sobrien } 274859243Sobrien 274959243Sobrien RefCursor(); 275059243Sobrien return(CC_NORM); 275159243Sobrien} 275259243Sobrien 275359243Sobrien/*ARGSUSED*/ 275459243SobrienCCRETVAL 2755167465Smpe_wordback(Char c) 275659243Sobrien{ 275759243Sobrien USE(c); 275859243Sobrien if (Cursor == InputBuf) 275959243Sobrien return(CC_ERROR); 276059243Sobrien /* else */ 276159243Sobrien 276259243Sobrien Cursor = c_prev_word(Cursor, InputBuf, Argument); /* bounds check */ 276359243Sobrien 276459243Sobrien if (VImode) 276559243Sobrien if (ActionFlag & TCSHOP_DELETE) { 276659243Sobrien c_delfini(); 276759243Sobrien return(CC_REFRESH); 276859243Sobrien } 276959243Sobrien 277059243Sobrien RefCursor(); 277159243Sobrien return(CC_NORM); 277259243Sobrien} 277359243Sobrien 277459243Sobrien/*ARGSUSED*/ 277559243SobrienCCRETVAL 2776167465Smpe_charfwd(Char c) 277759243Sobrien{ 277859243Sobrien USE(c); 277959243Sobrien if (Cursor < LastChar) { 2780167465Smp Cursor += Argument; 278159243Sobrien if (Cursor > LastChar) 278259243Sobrien Cursor = LastChar; 278359243Sobrien 278459243Sobrien if (VImode) 278559243Sobrien if (ActionFlag & TCSHOP_DELETE) { 278659243Sobrien c_delfini(); 278759243Sobrien return(CC_REFRESH); 278859243Sobrien } 278959243Sobrien 279059243Sobrien RefCursor(); 279159243Sobrien return(CC_NORM); 279259243Sobrien } 279359243Sobrien else { 279459243Sobrien return(CC_ERROR); 279559243Sobrien } 279659243Sobrien} 279759243Sobrien 279859243Sobrien/*ARGSUSED*/ 279959243SobrienCCRETVAL 2800167465Smpe_wordfwd(Char c) 280159243Sobrien{ 280259243Sobrien USE(c); 280359243Sobrien if (Cursor == LastChar) 280459243Sobrien return(CC_ERROR); 280559243Sobrien /* else */ 280659243Sobrien 280759243Sobrien Cursor = c_next_word(Cursor, LastChar, Argument); 280859243Sobrien 280959243Sobrien if (VImode) 281059243Sobrien if (ActionFlag & TCSHOP_DELETE) { 281159243Sobrien c_delfini(); 281259243Sobrien return(CC_REFRESH); 281359243Sobrien } 281459243Sobrien 281559243Sobrien RefCursor(); 281659243Sobrien return(CC_NORM); 281759243Sobrien} 281859243Sobrien 281959243Sobrien/*ARGSUSED*/ 282059243SobrienCCRETVAL 2821167465Smpv_wordfwd(Char c) 282259243Sobrien{ 282359243Sobrien USE(c); 282459243Sobrien if (Cursor == LastChar) 282559243Sobrien return(CC_ERROR); 282659243Sobrien /* else */ 282759243Sobrien 282859243Sobrien Cursor = c_nexword(Cursor, LastChar, Argument); 282959243Sobrien 283059243Sobrien if (VImode) 283159243Sobrien if (ActionFlag & TCSHOP_DELETE) { 283259243Sobrien c_delfini(); 283359243Sobrien return(CC_REFRESH); 283459243Sobrien } 283559243Sobrien 283659243Sobrien RefCursor(); 283759243Sobrien return(CC_NORM); 283859243Sobrien} 283959243Sobrien 284059243Sobrien/*ARGSUSED*/ 284159243SobrienCCRETVAL 2842167465Smpv_wordbegnext(Char c) 284359243Sobrien{ 284459243Sobrien USE(c); 284559243Sobrien if (Cursor == LastChar) 284659243Sobrien return(CC_ERROR); 284759243Sobrien /* else */ 284859243Sobrien 284959243Sobrien Cursor = c_next_word(Cursor, LastChar, Argument); 285059243Sobrien if (Cursor < LastChar) 285159243Sobrien Cursor++; 285259243Sobrien 285359243Sobrien if (VImode) 285459243Sobrien if (ActionFlag & TCSHOP_DELETE) { 285559243Sobrien c_delfini(); 285659243Sobrien return(CC_REFRESH); 285759243Sobrien } 285859243Sobrien 285959243Sobrien RefCursor(); 286059243Sobrien return(CC_NORM); 286159243Sobrien} 286259243Sobrien 286359243Sobrien/*ARGSUSED*/ 286459243Sobrienstatic CCRETVAL 2865167465Smpv_repeat_srch(int c) 286659243Sobrien{ 286759243Sobrien CCRETVAL rv = CC_ERROR; 286859243Sobrien#ifdef SDEBUG 2869167465Smp xprintf("dir %d patlen %d patbuf %S\n", 2870167465Smp c, (int)patbuf.len, patbuf.s); 287159243Sobrien#endif 287259243Sobrien 287359243Sobrien LastCmd = (KEYCMD) c; /* Hack to stop c_hsetpat */ 287459243Sobrien LastChar = InputBuf; 287559243Sobrien switch (c) { 287659243Sobrien case F_DOWN_SEARCH_HIST: 287759243Sobrien rv = e_down_search_hist(0); 287859243Sobrien break; 287959243Sobrien case F_UP_SEARCH_HIST: 288059243Sobrien rv = e_up_search_hist(0); 288159243Sobrien break; 288259243Sobrien default: 288359243Sobrien break; 288459243Sobrien } 288559243Sobrien return rv; 288659243Sobrien} 288759243Sobrien 288859243Sobrienstatic CCRETVAL 2889167465Smpv_csearch_back(Char ch, int count, int tflag) 289059243Sobrien{ 289159243Sobrien Char *cp; 289259243Sobrien 289359243Sobrien cp = Cursor; 289459243Sobrien while (count--) { 289559243Sobrien if (*cp == ch) 289659243Sobrien cp--; 289759243Sobrien while (cp > InputBuf && *cp != ch) 289859243Sobrien cp--; 289959243Sobrien } 290059243Sobrien 290159243Sobrien if (cp < InputBuf || (cp == InputBuf && *cp != ch)) 290259243Sobrien return(CC_ERROR); 290359243Sobrien 290459243Sobrien if (*cp == ch && tflag) 290559243Sobrien cp++; 290659243Sobrien 290759243Sobrien Cursor = cp; 290859243Sobrien 290959243Sobrien if (ActionFlag & TCSHOP_DELETE) { 291059243Sobrien Cursor++; 291159243Sobrien c_delfini(); 291259243Sobrien return(CC_REFRESH); 291359243Sobrien } 291459243Sobrien 291559243Sobrien RefCursor(); 291659243Sobrien return(CC_NORM); 291759243Sobrien} 291859243Sobrien 291959243Sobrienstatic CCRETVAL 2920167465Smpv_csearch_fwd(Char ch, int count, int tflag) 292159243Sobrien{ 292259243Sobrien Char *cp; 292359243Sobrien 292459243Sobrien cp = Cursor; 292559243Sobrien while (count--) { 292659243Sobrien if(*cp == ch) 292759243Sobrien cp++; 292859243Sobrien while (cp < LastChar && *cp != ch) 292959243Sobrien cp++; 293059243Sobrien } 293159243Sobrien 293259243Sobrien if (cp >= LastChar) 293359243Sobrien return(CC_ERROR); 293459243Sobrien 293559243Sobrien if (*cp == ch && tflag) 293659243Sobrien cp--; 293759243Sobrien 293859243Sobrien Cursor = cp; 293959243Sobrien 294059243Sobrien if (ActionFlag & TCSHOP_DELETE) { 294159243Sobrien Cursor++; 294259243Sobrien c_delfini(); 294359243Sobrien return(CC_REFRESH); 294459243Sobrien } 294559243Sobrien RefCursor(); 294659243Sobrien return(CC_NORM); 294759243Sobrien} 294859243Sobrien 294959243Sobrien/*ARGSUSED*/ 295059243Sobrienstatic CCRETVAL 2951167465Smpv_action(int c) 295259243Sobrien{ 295383098Smp Char *cp, *kp; 295459243Sobrien 295559243Sobrien if (ActionFlag == TCSHOP_DELETE) { 295659243Sobrien ActionFlag = TCSHOP_NOP; 295759243Sobrien ActionPos = 0; 295859243Sobrien 295959243Sobrien UndoSize = 0; 296059243Sobrien kp = UndoBuf; 296159243Sobrien for (cp = InputBuf; cp < LastChar; cp++) { 296259243Sobrien *kp++ = *cp; 296359243Sobrien UndoSize++; 296459243Sobrien } 296559243Sobrien 296659243Sobrien UndoAction = TCSHOP_INSERT; 296759243Sobrien UndoPtr = InputBuf; 296859243Sobrien LastChar = InputBuf; 296959243Sobrien Cursor = InputBuf; 297059243Sobrien if (c & TCSHOP_INSERT) 297159243Sobrien c_alternativ_key_map(0); 297259243Sobrien 297359243Sobrien return(CC_REFRESH); 297459243Sobrien } 297559243Sobrien#ifdef notdef 297659243Sobrien else if (ActionFlag == TCSHOP_NOP) { 297759243Sobrien#endif 297859243Sobrien ActionPos = Cursor; 297959243Sobrien ActionFlag = c; 298059243Sobrien return(CC_ARGHACK); /* Do NOT clear out argument */ 298159243Sobrien#ifdef notdef 298259243Sobrien } 298359243Sobrien else { 298459243Sobrien ActionFlag = 0; 298559243Sobrien ActionPos = 0; 298659243Sobrien return(CC_ERROR); 298759243Sobrien } 298859243Sobrien#endif 298959243Sobrien} 299059243Sobrien 299159243Sobrien#ifdef COMMENT 299259243Sobrien/* by: Brian Allison <uiucdcs!convex!allison@RUTGERS.EDU> */ 299359243Sobrienstatic void 2994167465Smpc_get_word(Char **begin, Char **end) 299559243Sobrien{ 299659243Sobrien Char *cp; 299759243Sobrien 299859243Sobrien cp = &Cursor[0]; 299959243Sobrien while (Argument--) { 300059243Sobrien while ((cp <= LastChar) && (isword(*cp))) 300159243Sobrien cp++; 300259243Sobrien *end = --cp; 300359243Sobrien while ((cp >= InputBuf) && (isword(*cp))) 300459243Sobrien cp--; 300559243Sobrien *begin = ++cp; 300659243Sobrien } 300759243Sobrien} 300859243Sobrien#endif /* COMMENT */ 300959243Sobrien 301059243Sobrien/*ARGSUSED*/ 301159243SobrienCCRETVAL 3012167465Smpe_uppercase(Char c) 301359243Sobrien{ 301459243Sobrien Char *cp, *end; 301559243Sobrien 301659243Sobrien USE(c); 301759243Sobrien end = c_next_word(Cursor, LastChar, Argument); 301859243Sobrien 301959243Sobrien for (cp = Cursor; cp < end; cp++) /* PWP: was cp=begin */ 302059243Sobrien if (Islower(*cp)) 302159243Sobrien *cp = Toupper(*cp); 302259243Sobrien 302359243Sobrien Cursor = end; 302459243Sobrien if (Cursor > LastChar) 302559243Sobrien Cursor = LastChar; 302659243Sobrien return(CC_REFRESH); 302759243Sobrien} 302859243Sobrien 302959243Sobrien 303059243Sobrien/*ARGSUSED*/ 303159243SobrienCCRETVAL 3032316957Sdchagine_capitalcase(Char c) 303359243Sobrien{ 303459243Sobrien Char *cp, *end; 303559243Sobrien 303659243Sobrien USE(c); 303759243Sobrien end = c_next_word(Cursor, LastChar, Argument); 303859243Sobrien 303959243Sobrien cp = Cursor; 304059243Sobrien for (; cp < end; cp++) { 304159243Sobrien if (Isalpha(*cp)) { 304259243Sobrien if (Islower(*cp)) 304359243Sobrien *cp = Toupper(*cp); 304459243Sobrien cp++; 304559243Sobrien break; 304659243Sobrien } 304759243Sobrien } 304859243Sobrien for (; cp < end; cp++) 304959243Sobrien if (Isupper(*cp)) 305059243Sobrien *cp = Tolower(*cp); 305159243Sobrien 305259243Sobrien Cursor = end; 305359243Sobrien if (Cursor > LastChar) 305459243Sobrien Cursor = LastChar; 305559243Sobrien return(CC_REFRESH); 305659243Sobrien} 305759243Sobrien 305859243Sobrien/*ARGSUSED*/ 305959243SobrienCCRETVAL 3060167465Smpe_lowercase(Char c) 306159243Sobrien{ 306259243Sobrien Char *cp, *end; 306359243Sobrien 306459243Sobrien USE(c); 306559243Sobrien end = c_next_word(Cursor, LastChar, Argument); 306659243Sobrien 306759243Sobrien for (cp = Cursor; cp < end; cp++) 306859243Sobrien if (Isupper(*cp)) 306959243Sobrien *cp = Tolower(*cp); 307059243Sobrien 307159243Sobrien Cursor = end; 307259243Sobrien if (Cursor > LastChar) 307359243Sobrien Cursor = LastChar; 307459243Sobrien return(CC_REFRESH); 307559243Sobrien} 307659243Sobrien 307759243Sobrien 307859243Sobrien/*ARGSUSED*/ 307959243SobrienCCRETVAL 3080167465Smpe_set_mark(Char c) 308159243Sobrien{ 308259243Sobrien USE(c); 3083167465Smp if (adrof(STRhighlight) && MarkIsSet && Mark != Cursor) { 3084167465Smp ClearLines(); 3085167465Smp ClearDisp(); 3086167465Smp Refresh(); 3087167465Smp } 308859243Sobrien Mark = Cursor; 3089167465Smp MarkIsSet = 1; 309059243Sobrien return(CC_NORM); 309159243Sobrien} 309259243Sobrien 309359243Sobrien/*ARGSUSED*/ 309459243SobrienCCRETVAL 3095167465Smpe_exchange_mark(Char c) 309659243Sobrien{ 309783098Smp Char *cp; 309859243Sobrien 309959243Sobrien USE(c); 310059243Sobrien cp = Cursor; 310159243Sobrien Cursor = Mark; 310259243Sobrien Mark = cp; 310359243Sobrien RefCursor(); 310459243Sobrien return(CC_NORM); 310559243Sobrien} 310659243Sobrien 310759243Sobrien/*ARGSUSED*/ 310859243SobrienCCRETVAL 3109167465Smpe_argfour(Char c) 311059243Sobrien{ /* multiply current argument by 4 */ 311159243Sobrien USE(c); 311259243Sobrien if (Argument > 1000000) 311359243Sobrien return CC_ERROR; 311459243Sobrien DoingArg = 1; 311559243Sobrien Argument *= 4; 311659243Sobrien return(CC_ARGHACK); 311759243Sobrien} 311859243Sobrien 3119167465Smpstatic void 3120167465Smpquote_mode_cleanup(void *unused) 3121167465Smp{ 3122167465Smp USE(unused); 3123167465Smp QuoteModeOff(); 3124167465Smp} 3125167465Smp 312659243Sobrien/*ARGSUSED*/ 312759243SobrienCCRETVAL 3128167465Smpe_quote(Char c) 312959243Sobrien{ 313059243Sobrien Char ch; 313159243Sobrien int num; 313259243Sobrien 313359243Sobrien USE(c); 313459243Sobrien QuoteModeOn(); 3135167465Smp cleanup_push(&c, quote_mode_cleanup); /* Using &c just as a mark */ 313659243Sobrien num = GetNextChar(&ch); 3137167465Smp cleanup_until(&c); 313859243Sobrien if (num == 1) 313959243Sobrien return e_insert(ch); 314059243Sobrien else 314159243Sobrien return e_send_eof(0); 314259243Sobrien} 314359243Sobrien 314459243Sobrien/*ARGSUSED*/ 314559243SobrienCCRETVAL 3146167465Smpe_metanext(Char c) 314759243Sobrien{ 314859243Sobrien USE(c); 314959243Sobrien MetaNext = 1; 315059243Sobrien return(CC_ARGHACK); /* preserve argument */ 315159243Sobrien} 315259243Sobrien 315359243Sobrien#ifdef notdef 315459243Sobrien/*ARGSUSED*/ 315559243SobrienCCRETVAL 3156167465Smpe_extendnext(Char c) 315759243Sobrien{ 315859243Sobrien CurrentKeyMap = CcAltMap; 315959243Sobrien return(CC_ARGHACK); /* preserve argument */ 316059243Sobrien} 316159243Sobrien 316259243Sobrien#endif 316359243Sobrien 316459243Sobrien/*ARGSUSED*/ 316559243SobrienCCRETVAL 3166167465Smpv_insbeg(Char c) 316759243Sobrien{ /* move to beginning of line and start vi 316859243Sobrien * insert mode */ 316959243Sobrien USE(c); 317059243Sobrien Cursor = InputBuf; 317159243Sobrien InsertPos = Cursor; 317259243Sobrien 317359243Sobrien UndoPtr = Cursor; 317459243Sobrien UndoAction = TCSHOP_DELETE; 317559243Sobrien 317659243Sobrien RefCursor(); /* move the cursor */ 317759243Sobrien c_alternativ_key_map(0); 317859243Sobrien return(CC_NORM); 317959243Sobrien} 318059243Sobrien 318159243Sobrien/*ARGSUSED*/ 318259243SobrienCCRETVAL 3183167465Smpv_replone(Char c) 318459243Sobrien{ /* vi mode overwrite one character */ 318559243Sobrien USE(c); 318659243Sobrien c_alternativ_key_map(0); 318759243Sobrien inputmode = MODE_REPLACE_1; 318859243Sobrien UndoAction = TCSHOP_CHANGE; /* Set Up for VI undo command */ 318959243Sobrien UndoPtr = Cursor; 319059243Sobrien UndoSize = 0; 319159243Sobrien return(CC_NORM); 319259243Sobrien} 319359243Sobrien 319459243Sobrien/*ARGSUSED*/ 319559243SobrienCCRETVAL 3196167465Smpv_replmode(Char c) 319759243Sobrien{ /* vi mode start overwriting */ 319859243Sobrien USE(c); 319959243Sobrien c_alternativ_key_map(0); 320059243Sobrien inputmode = MODE_REPLACE; 320159243Sobrien UndoAction = TCSHOP_CHANGE; /* Set Up for VI undo command */ 320259243Sobrien UndoPtr = Cursor; 320359243Sobrien UndoSize = 0; 320459243Sobrien return(CC_NORM); 320559243Sobrien} 320659243Sobrien 320759243Sobrien/*ARGSUSED*/ 320859243SobrienCCRETVAL 3209167465Smpv_substchar(Char c) 321059243Sobrien{ /* vi mode substitute for one char */ 321159243Sobrien USE(c); 321259243Sobrien c_delafter(Argument); 321359243Sobrien c_alternativ_key_map(0); 321459243Sobrien return(CC_REFRESH); 321559243Sobrien} 321659243Sobrien 321759243Sobrien/*ARGSUSED*/ 321859243SobrienCCRETVAL 3219167465Smpv_substline(Char c) 322059243Sobrien{ /* vi mode replace whole line */ 322159243Sobrien USE(c); 322259243Sobrien (void) e_killall(0); 322359243Sobrien c_alternativ_key_map(0); 322459243Sobrien return(CC_REFRESH); 322559243Sobrien} 322659243Sobrien 322759243Sobrien/*ARGSUSED*/ 322859243SobrienCCRETVAL 3229167465Smpv_chgtoend(Char c) 323059243Sobrien{ /* vi mode change to end of line */ 323159243Sobrien USE(c); 323259243Sobrien (void) e_killend(0); 323359243Sobrien c_alternativ_key_map(0); 323459243Sobrien return(CC_REFRESH); 323559243Sobrien} 323659243Sobrien 323759243Sobrien/*ARGSUSED*/ 323859243SobrienCCRETVAL 3239167465Smpv_insert(Char c) 324059243Sobrien{ /* vi mode start inserting */ 324159243Sobrien USE(c); 324259243Sobrien c_alternativ_key_map(0); 324359243Sobrien 324459243Sobrien InsertPos = Cursor; 324559243Sobrien UndoPtr = Cursor; 324659243Sobrien UndoAction = TCSHOP_DELETE; 324759243Sobrien 324859243Sobrien return(CC_NORM); 324959243Sobrien} 325059243Sobrien 325159243Sobrien/*ARGSUSED*/ 325259243SobrienCCRETVAL 3253167465Smpv_add(Char c) 325459243Sobrien{ /* vi mode start adding */ 325559243Sobrien USE(c); 325659243Sobrien c_alternativ_key_map(0); 325759243Sobrien if (Cursor < LastChar) 325859243Sobrien { 325959243Sobrien Cursor++; 326059243Sobrien if (Cursor > LastChar) 326159243Sobrien Cursor = LastChar; 326259243Sobrien RefCursor(); 326359243Sobrien } 326459243Sobrien 326559243Sobrien InsertPos = Cursor; 326659243Sobrien UndoPtr = Cursor; 326759243Sobrien UndoAction = TCSHOP_DELETE; 326859243Sobrien 326959243Sobrien return(CC_NORM); 327059243Sobrien} 327159243Sobrien 327259243Sobrien/*ARGSUSED*/ 327359243SobrienCCRETVAL 3274167465Smpv_addend(Char c) 327559243Sobrien{ /* vi mode to add at end of line */ 327659243Sobrien USE(c); 327759243Sobrien c_alternativ_key_map(0); 327859243Sobrien Cursor = LastChar; 327959243Sobrien 328059243Sobrien InsertPos = LastChar; /* Mark where insertion begins */ 328159243Sobrien UndoPtr = LastChar; 328259243Sobrien UndoAction = TCSHOP_DELETE; 328359243Sobrien 328459243Sobrien RefCursor(); 328559243Sobrien return(CC_NORM); 328659243Sobrien} 328759243Sobrien 328859243Sobrien/*ARGSUSED*/ 328959243SobrienCCRETVAL 3290167465Smpv_change_case(Char cc) 329159243Sobrien{ 3292145479Smp Char c; 329359243Sobrien 329459243Sobrien USE(cc); 329559243Sobrien if (Cursor < LastChar) { 329669408Sache#ifndef WINNT_NATIVE 329759243Sobrien c = *Cursor; 329859243Sobrien#else 329959243Sobrien c = CHAR & *Cursor; 330069408Sache#endif /* WINNT_NATIVE */ 330159243Sobrien if (Isupper(c)) 330259243Sobrien *Cursor++ = Tolower(c); 330359243Sobrien else if (Islower(c)) 330459243Sobrien *Cursor++ = Toupper(c); 330559243Sobrien else 330659243Sobrien Cursor++; 3307145479Smp RefPlusOne(1); /* fast refresh for one char */ 330859243Sobrien return(CC_NORM); 330959243Sobrien } 331059243Sobrien return(CC_ERROR); 331159243Sobrien} 331259243Sobrien 331359243Sobrien/*ARGSUSED*/ 331459243SobrienCCRETVAL 3315167465Smpe_expand(Char c) 331659243Sobrien{ 331783098Smp Char *p; 331859243Sobrien 331959243Sobrien USE(c); 332059243Sobrien for (p = InputBuf; Isspace(*p); p++) 332159243Sobrien continue; 332259243Sobrien if (p == LastChar) 332359243Sobrien return(CC_ERROR); 332459243Sobrien 332559243Sobrien justpr++; 332659243Sobrien Expand++; 332759243Sobrien return(e_newline(0)); 332859243Sobrien} 332959243Sobrien 333059243Sobrien/*ARGSUSED*/ 333159243SobrienCCRETVAL 3332167465Smpe_startover(Char c) 333359243Sobrien{ /* erase all of current line, start again */ 333459243Sobrien USE(c); 333559243Sobrien ResetInLine(0); /* reset the input pointers */ 333659243Sobrien return(CC_REFRESH); 333759243Sobrien} 333859243Sobrien 333959243Sobrien/*ARGSUSED*/ 334059243SobrienCCRETVAL 3341167465Smpe_redisp(Char c) 334259243Sobrien{ 334359243Sobrien USE(c); 334459243Sobrien ClearLines(); 334559243Sobrien ClearDisp(); 334659243Sobrien return(CC_REFRESH); 334759243Sobrien} 334859243Sobrien 334959243Sobrien/*ARGSUSED*/ 335059243SobrienCCRETVAL 3351167465Smpe_cleardisp(Char c) 335259243Sobrien{ 335359243Sobrien USE(c); 335459243Sobrien ClearScreen(); /* clear the whole real screen */ 335559243Sobrien ClearDisp(); /* reset everything */ 335659243Sobrien return(CC_REFRESH); 335759243Sobrien} 335859243Sobrien 335959243Sobrien/*ARGSUSED*/ 336059243SobrienCCRETVAL 3361167465Smpe_tty_int(Char c) 336259243Sobrien{ 336359243Sobrien USE(c); 336469408Sache#if defined(_MINIX) || defined(WINNT_NATIVE) 336559243Sobrien /* SAK PATCH: erase all of current line, start again */ 336659243Sobrien ResetInLine(0); /* reset the input pointers */ 336759243Sobrien xputchar('\n'); 336859243Sobrien ClearDisp(); 336959243Sobrien return (CC_REFRESH); 337069408Sache#else /* !_MINIX && !WINNT_NATIVE */ 337159243Sobrien /* do no editing */ 337259243Sobrien return (CC_NORM); 337369408Sache#endif /* _MINIX || WINNT_NATIVE */ 337459243Sobrien} 337559243Sobrien 337659243Sobrien/* 337759243Sobrien * From: ghazi@cesl.rutgers.edu (Kaveh R. Ghazi) 337859243Sobrien * Function to send a character back to the input stream in cooked 337959243Sobrien * mode. Only works if we have TIOCSTI 338059243Sobrien */ 338159243Sobrien/*ARGSUSED*/ 338259243SobrienCCRETVAL 3383167465Smpe_stuff_char(Char c) 338459243Sobrien{ 338559243Sobrien#ifdef TIOCSTI 338659243Sobrien int was_raw = Tty_raw_mode; 3387145479Smp char buf[MB_LEN_MAX]; 3388145479Smp size_t i, len; 338959243Sobrien 339059243Sobrien if (was_raw) 339159243Sobrien (void) Cookedmode(); 339259243Sobrien 3393167465Smp (void) xwrite(SHIN, "\n", 1); 3394316957Sdchagin len = one_wctomb(buf, c); 3395145479Smp for (i = 0; i < len; i++) 3396145479Smp (void) ioctl(SHIN, TIOCSTI, (ioctl_t) &buf[i]); 339759243Sobrien 339859243Sobrien if (was_raw) 3399167465Smp (void) Rawmode(); 340059243Sobrien return(e_redisp(c)); 340159243Sobrien#else /* !TIOCSTI */ 340259243Sobrien return(CC_ERROR); 340359243Sobrien#endif /* !TIOCSTI */ 340459243Sobrien} 340559243Sobrien 340659243Sobrien/*ARGSUSED*/ 340759243SobrienCCRETVAL 3408167465Smpe_insovr(Char c) 340959243Sobrien{ 341059243Sobrien USE(c); 341159243Sobrien inputmode = (inputmode == MODE_INSERT ? MODE_REPLACE : MODE_INSERT); 341259243Sobrien return(CC_NORM); 341359243Sobrien} 341459243Sobrien 341559243Sobrien/*ARGSUSED*/ 341659243SobrienCCRETVAL 3417167465Smpe_tty_dsusp(Char c) 341859243Sobrien{ 341959243Sobrien USE(c); 342059243Sobrien /* do no editing */ 342159243Sobrien return(CC_NORM); 342259243Sobrien} 342359243Sobrien 342459243Sobrien/*ARGSUSED*/ 342559243SobrienCCRETVAL 3426167465Smpe_tty_flusho(Char c) 342759243Sobrien{ 342859243Sobrien USE(c); 342959243Sobrien /* do no editing */ 343059243Sobrien return(CC_NORM); 343159243Sobrien} 343259243Sobrien 343359243Sobrien/*ARGSUSED*/ 343459243SobrienCCRETVAL 3435167465Smpe_tty_quit(Char c) 343659243Sobrien{ 343759243Sobrien USE(c); 343859243Sobrien /* do no editing */ 343959243Sobrien return(CC_NORM); 344059243Sobrien} 344159243Sobrien 344259243Sobrien/*ARGSUSED*/ 344359243SobrienCCRETVAL 3444167465Smpe_tty_tsusp(Char c) 344559243Sobrien{ 344659243Sobrien USE(c); 344759243Sobrien /* do no editing */ 344859243Sobrien return(CC_NORM); 344959243Sobrien} 345059243Sobrien 345159243Sobrien/*ARGSUSED*/ 345259243SobrienCCRETVAL 3453167465Smpe_tty_stopo(Char c) 345459243Sobrien{ 345559243Sobrien USE(c); 345659243Sobrien /* do no editing */ 345759243Sobrien return(CC_NORM); 345859243Sobrien} 345959243Sobrien 3460195609Smp/* returns the number of (attempted) expansions */ 3461195609Smpint 3462195609SmpExpandHistory(void) 3463195609Smp{ 3464195609Smp *LastChar = '\0'; /* just in case */ 3465195609Smp return c_substitute(); 3466195609Smp} 3467195609Smp 346859243Sobrien/*ARGSUSED*/ 346959243SobrienCCRETVAL 3470167465Smpe_expand_history(Char c) 347159243Sobrien{ 347259243Sobrien USE(c); 3473195609Smp (void)ExpandHistory(); 347459243Sobrien return(CC_NORM); 347559243Sobrien} 347659243Sobrien 347759243Sobrien/*ARGSUSED*/ 347859243SobrienCCRETVAL 3479167465Smpe_magic_space(Char c) 348059243Sobrien{ 348159243Sobrien USE(c); 348259243Sobrien *LastChar = '\0'; /* just in case */ 3483195609Smp (void)c_substitute(); 348459243Sobrien return(e_insert(' ')); 348559243Sobrien} 348659243Sobrien 348759243Sobrien/*ARGSUSED*/ 348859243SobrienCCRETVAL 3489167465Smpe_inc_fwd(Char c) 349059243Sobrien{ 3491167465Smp CCRETVAL ret; 3492167465Smp 349359243Sobrien USE(c); 3494167465Smp patbuf.len = 0; 3495167465Smp MarkIsSet = 0; 3496167465Smp ret = e_inc_search(F_DOWN_SEARCH_HIST); 3497167465Smp if (adrof(STRhighlight) && IncMatchLen) { 3498167465Smp IncMatchLen = 0; 3499167465Smp ClearLines(); 3500167465Smp ClearDisp(); 3501167465Smp Refresh(); 3502167465Smp } 3503167465Smp IncMatchLen = 0; 3504167465Smp return ret; 350559243Sobrien} 350659243Sobrien 350759243Sobrien 350859243Sobrien/*ARGSUSED*/ 350959243SobrienCCRETVAL 3510167465Smpe_inc_back(Char c) 351159243Sobrien{ 3512167465Smp CCRETVAL ret; 3513167465Smp 351459243Sobrien USE(c); 3515167465Smp patbuf.len = 0; 3516167465Smp MarkIsSet = 0; 3517167465Smp ret = e_inc_search(F_UP_SEARCH_HIST); 3518167465Smp if (adrof(STRhighlight) && IncMatchLen) { 3519167465Smp IncMatchLen = 0; 3520167465Smp ClearLines(); 3521167465Smp ClearDisp(); 3522167465Smp Refresh(); 3523167465Smp } 3524167465Smp IncMatchLen = 0; 3525167465Smp return ret; 352659243Sobrien} 352759243Sobrien 352859243Sobrien/*ARGSUSED*/ 352959243SobrienCCRETVAL 3530167465Smpe_copyprev(Char c) 353159243Sobrien{ 353283098Smp Char *cp, *oldc, *dp; 353359243Sobrien 353459243Sobrien USE(c); 353559243Sobrien if (Cursor == InputBuf) 353659243Sobrien return(CC_ERROR); 353759243Sobrien /* else */ 353859243Sobrien 353959243Sobrien oldc = Cursor; 354059243Sobrien /* does a bounds check */ 354159243Sobrien cp = c_prev_word(Cursor, InputBuf, Argument); 354259243Sobrien 354359243Sobrien c_insert((int)(oldc - cp)); 354459243Sobrien for (dp = oldc; cp < oldc && dp < LastChar; cp++) 354559243Sobrien *dp++ = *cp; 354659243Sobrien 354759243Sobrien Cursor = dp; /* put cursor at end */ 354859243Sobrien 354959243Sobrien return(CC_REFRESH); 355059243Sobrien} 355159243Sobrien 355259243Sobrien/*ARGSUSED*/ 355359243SobrienCCRETVAL 3554167465Smpe_tty_starto(Char c) 355559243Sobrien{ 355659243Sobrien USE(c); 355759243Sobrien /* do no editing */ 355859243Sobrien return(CC_NORM); 355959243Sobrien} 356059243Sobrien 356159243Sobrien/*ARGSUSED*/ 356259243SobrienCCRETVAL 3563167465Smpe_load_average(Char c) 356459243Sobrien{ 356559243Sobrien USE(c); 356659243Sobrien PastBottom(); 356759243Sobrien#ifdef TIOCSTAT 356859243Sobrien /* 356959243Sobrien * Here we pass &c to the ioctl because some os's (NetBSD) expect it 357059243Sobrien * there even if they don't use it. (lukem@netbsd.org) 357159243Sobrien */ 357259243Sobrien if (ioctl(SHIN, TIOCSTAT, (ioctl_t) &c) < 0) 357359243Sobrien#endif 3574195609Smp xprintf("%s", CGETS(5, 1, "Load average unavailable\n")); 357559243Sobrien return(CC_REFRESH); 357659243Sobrien} 357759243Sobrien 357859243Sobrien/*ARGSUSED*/ 357959243SobrienCCRETVAL 3580167465Smpv_chgmeta(Char c) 358159243Sobrien{ 358259243Sobrien USE(c); 358359243Sobrien /* 358459243Sobrien * Delete with insert == change: first we delete and then we leave in 358559243Sobrien * insert mode. 358659243Sobrien */ 358759243Sobrien return(v_action(TCSHOP_DELETE|TCSHOP_INSERT)); 358859243Sobrien} 358959243Sobrien 359059243Sobrien/*ARGSUSED*/ 359159243SobrienCCRETVAL 3592167465Smpv_delmeta(Char c) 359359243Sobrien{ 359459243Sobrien USE(c); 359559243Sobrien return(v_action(TCSHOP_DELETE)); 359659243Sobrien} 359759243Sobrien 359859243Sobrien 359959243Sobrien/*ARGSUSED*/ 360059243SobrienCCRETVAL 3601167465Smpv_endword(Char c) 360259243Sobrien{ 360359243Sobrien USE(c); 360459243Sobrien if (Cursor == LastChar) 360559243Sobrien return(CC_ERROR); 360659243Sobrien /* else */ 360759243Sobrien 360883098Smp Cursor = c_endword(Cursor, LastChar, Argument, STRshwspace); 360959243Sobrien 361059243Sobrien if (ActionFlag & TCSHOP_DELETE) 361159243Sobrien { 361259243Sobrien Cursor++; 361359243Sobrien c_delfini(); 361459243Sobrien return(CC_REFRESH); 361559243Sobrien } 361659243Sobrien 361759243Sobrien RefCursor(); 361859243Sobrien return(CC_NORM); 361959243Sobrien} 362059243Sobrien 362159243Sobrien/*ARGSUSED*/ 362259243SobrienCCRETVAL 3623167465Smpv_eword(Char c) 362459243Sobrien{ 362559243Sobrien USE(c); 362659243Sobrien if (Cursor == LastChar) 362759243Sobrien return(CC_ERROR); 362859243Sobrien /* else */ 362959243Sobrien 363059243Sobrien Cursor = c_eword(Cursor, LastChar, Argument); 363159243Sobrien 363259243Sobrien if (ActionFlag & TCSHOP_DELETE) { 363359243Sobrien Cursor++; 363459243Sobrien c_delfini(); 363559243Sobrien return(CC_REFRESH); 363659243Sobrien } 363759243Sobrien 363859243Sobrien RefCursor(); 363959243Sobrien return(CC_NORM); 364059243Sobrien} 364159243Sobrien 364259243Sobrien/*ARGSUSED*/ 364359243SobrienCCRETVAL 3644167465Smpv_char_fwd(Char c) 364559243Sobrien{ 364659243Sobrien Char ch; 364759243Sobrien 364859243Sobrien USE(c); 364959243Sobrien if (GetNextChar(&ch) != 1) 365059243Sobrien return e_send_eof(0); 365159243Sobrien 365259243Sobrien srch_dir = CHAR_FWD; 365359243Sobrien srch_char = ch; 365459243Sobrien 365559243Sobrien return v_csearch_fwd(ch, Argument, 0); 365659243Sobrien 365759243Sobrien} 365859243Sobrien 365959243Sobrien/*ARGSUSED*/ 366059243SobrienCCRETVAL 3661167465Smpv_char_back(Char c) 366259243Sobrien{ 366359243Sobrien Char ch; 366459243Sobrien 366559243Sobrien USE(c); 366659243Sobrien if (GetNextChar(&ch) != 1) 366759243Sobrien return e_send_eof(0); 366859243Sobrien 366959243Sobrien srch_dir = CHAR_BACK; 367059243Sobrien srch_char = ch; 367159243Sobrien 367259243Sobrien return v_csearch_back(ch, Argument, 0); 367359243Sobrien} 367459243Sobrien 367559243Sobrien/*ARGSUSED*/ 367659243SobrienCCRETVAL 3677167465Smpv_charto_fwd(Char c) 367859243Sobrien{ 367959243Sobrien Char ch; 368059243Sobrien 368159243Sobrien USE(c); 368259243Sobrien if (GetNextChar(&ch) != 1) 368359243Sobrien return e_send_eof(0); 368459243Sobrien 368559243Sobrien return v_csearch_fwd(ch, Argument, 1); 368659243Sobrien 368759243Sobrien} 368859243Sobrien 368959243Sobrien/*ARGSUSED*/ 369059243SobrienCCRETVAL 3691167465Smpv_charto_back(Char c) 369259243Sobrien{ 369359243Sobrien Char ch; 369459243Sobrien 369559243Sobrien USE(c); 369659243Sobrien if (GetNextChar(&ch) != 1) 369759243Sobrien return e_send_eof(0); 369859243Sobrien 369959243Sobrien return v_csearch_back(ch, Argument, 1); 370059243Sobrien} 370159243Sobrien 370259243Sobrien/*ARGSUSED*/ 370359243SobrienCCRETVAL 3704167465Smpv_rchar_fwd(Char c) 370559243Sobrien{ 370659243Sobrien USE(c); 370759243Sobrien if (srch_char == 0) 370859243Sobrien return CC_ERROR; 370959243Sobrien 371059243Sobrien return srch_dir == CHAR_FWD ? v_csearch_fwd(srch_char, Argument, 0) : 371159243Sobrien v_csearch_back(srch_char, Argument, 0); 371259243Sobrien} 371359243Sobrien 371459243Sobrien/*ARGSUSED*/ 371559243SobrienCCRETVAL 3716167465Smpv_rchar_back(Char c) 371759243Sobrien{ 371859243Sobrien USE(c); 371959243Sobrien if (srch_char == 0) 372059243Sobrien return CC_ERROR; 372159243Sobrien 372259243Sobrien return srch_dir == CHAR_BACK ? v_csearch_fwd(srch_char, Argument, 0) : 372359243Sobrien v_csearch_back(srch_char, Argument, 0); 372459243Sobrien} 372559243Sobrien 372659243Sobrien/*ARGSUSED*/ 372759243SobrienCCRETVAL 3728167465Smpv_undo(Char c) 372959243Sobrien{ 373083098Smp int loop; 373183098Smp Char *kp, *cp; 373259243Sobrien Char temp; 373359243Sobrien int size; 373459243Sobrien 373559243Sobrien USE(c); 373659243Sobrien switch (UndoAction) { 373759243Sobrien case TCSHOP_DELETE|TCSHOP_INSERT: 373859243Sobrien case TCSHOP_DELETE: 373959243Sobrien if (UndoSize == 0) return(CC_NORM); 374059243Sobrien cp = UndoPtr; 374159243Sobrien kp = UndoBuf; 374259243Sobrien for (loop=0; loop < UndoSize; loop++) /* copy the chars */ 374359243Sobrien *kp++ = *cp++; /* into UndoBuf */ 374459243Sobrien 374559243Sobrien for (cp = UndoPtr; cp <= LastChar; cp++) 374659243Sobrien *cp = cp[UndoSize]; 374759243Sobrien 374859243Sobrien LastChar -= UndoSize; 374959243Sobrien Cursor = UndoPtr; 375059243Sobrien 375159243Sobrien UndoAction = TCSHOP_INSERT; 375259243Sobrien break; 375359243Sobrien 375459243Sobrien case TCSHOP_INSERT: 375559243Sobrien if (UndoSize == 0) return(CC_NORM); 375659243Sobrien cp = UndoPtr; 375759243Sobrien Cursor = UndoPtr; 375859243Sobrien kp = UndoBuf; 375959243Sobrien c_insert(UndoSize); /* open the space, */ 376059243Sobrien for (loop = 0; loop < UndoSize; loop++) /* copy the chars */ 376159243Sobrien *cp++ = *kp++; 376259243Sobrien 376359243Sobrien UndoAction = TCSHOP_DELETE; 376459243Sobrien break; 376559243Sobrien 376659243Sobrien case TCSHOP_CHANGE: 376759243Sobrien if (UndoSize == 0) return(CC_NORM); 376859243Sobrien cp = UndoPtr; 376959243Sobrien Cursor = UndoPtr; 377059243Sobrien kp = UndoBuf; 377159243Sobrien size = (int)(Cursor-LastChar); /* NOT NSL independant */ 377259243Sobrien if (size < UndoSize) 377359243Sobrien size = UndoSize; 377459243Sobrien for(loop = 0; loop < size; loop++) { 377559243Sobrien temp = *kp; 377659243Sobrien *kp++ = *cp; 377759243Sobrien *cp++ = temp; 377859243Sobrien } 377959243Sobrien break; 378059243Sobrien 378159243Sobrien default: 378259243Sobrien return(CC_ERROR); 378359243Sobrien } 378459243Sobrien 378559243Sobrien return(CC_REFRESH); 378659243Sobrien} 378759243Sobrien 378859243Sobrien/*ARGSUSED*/ 378959243SobrienCCRETVAL 3790167465Smpv_ush_meta(Char c) 379159243Sobrien{ 379259243Sobrien USE(c); 379359243Sobrien return v_search(F_UP_SEARCH_HIST); 379459243Sobrien} 379559243Sobrien 379659243Sobrien/*ARGSUSED*/ 379759243SobrienCCRETVAL 3798167465Smpv_dsh_meta(Char c) 379959243Sobrien{ 380059243Sobrien USE(c); 380159243Sobrien return v_search(F_DOWN_SEARCH_HIST); 380259243Sobrien} 380359243Sobrien 380459243Sobrien/*ARGSUSED*/ 380559243SobrienCCRETVAL 3806167465Smpv_rsrch_fwd(Char c) 380759243Sobrien{ 380859243Sobrien USE(c); 3809167465Smp if (patbuf.len == 0) return(CC_ERROR); 381059243Sobrien return(v_repeat_srch(searchdir)); 381159243Sobrien} 381259243Sobrien 381359243Sobrien/*ARGSUSED*/ 381459243SobrienCCRETVAL 3815167465Smpv_rsrch_back(Char c) 381659243Sobrien{ 381759243Sobrien USE(c); 3818167465Smp if (patbuf.len == 0) return(CC_ERROR); 381959243Sobrien return(v_repeat_srch(searchdir == F_UP_SEARCH_HIST ? 382059243Sobrien F_DOWN_SEARCH_HIST : F_UP_SEARCH_HIST)); 382159243Sobrien} 382259243Sobrien 382369408Sache#ifndef WINNT_NATIVE 382459243Sobrien/* Since ed.defns.h is generated from ed.defns.c, these empty 382559243Sobrien functions will keep the F_NUM_FNS consistent 382659243Sobrien */ 382759243SobrienCCRETVAL 3828167465Smpe_copy_to_clipboard(Char c) 382959243Sobrien{ 383059243Sobrien USE(c); 383159243Sobrien return CC_ERROR; 383259243Sobrien} 383359243Sobrien 383459243SobrienCCRETVAL 3835167465Smpe_paste_from_clipboard(Char c) 383659243Sobrien{ 383759243Sobrien USE(c); 383859243Sobrien return (CC_ERROR); 383959243Sobrien} 384059243Sobrien 384159243SobrienCCRETVAL 3842167465Smpe_dosify_next(Char c) 384359243Sobrien{ 384459243Sobrien USE(c); 384559243Sobrien return (CC_ERROR); 384659243Sobrien} 384759243SobrienCCRETVAL 3848167465Smpe_dosify_prev(Char c) 384959243Sobrien{ 385059243Sobrien USE(c); 385159243Sobrien return (CC_ERROR); 385259243Sobrien} 385359243SobrienCCRETVAL 3854167465Smpe_page_up(Char c) 385559243Sobrien{ 385659243Sobrien USE(c); 385769408Sache return (CC_ERROR); 385859243Sobrien} 385959243SobrienCCRETVAL 3860167465Smpe_page_down(Char c) 386159243Sobrien{ 386259243Sobrien USE(c); 386369408Sache return (CC_ERROR); 386459243Sobrien} 386569408Sache#endif /* !WINNT_NATIVE */ 386659243Sobrien 386759243Sobrien#ifdef notdef 386859243Sobrienvoid 3869167465SmpMoveCursor(int n) /* move cursor + right - left char */ 387059243Sobrien{ 387159243Sobrien Cursor = Cursor + n; 387259243Sobrien if (Cursor < InputBuf) 387359243Sobrien Cursor = InputBuf; 387459243Sobrien if (Cursor > LastChar) 387559243Sobrien Cursor = LastChar; 387659243Sobrien return; 387759243Sobrien} 387859243Sobrien 387959243SobrienChar * 3880167465SmpGetCursor(void) 388159243Sobrien{ 388259243Sobrien return(Cursor); 388359243Sobrien} 388459243Sobrien 388559243Sobrienint 3886167465SmpPutCursor(Char *p) 388759243Sobrien{ 388859243Sobrien if (p < InputBuf || p > LastChar) 388959243Sobrien return 1; /* Error */ 389059243Sobrien Cursor = p; 389159243Sobrien return 0; 389259243Sobrien} 389359243Sobrien#endif 3894