1*54210Sbostic /*- 2*54210Sbostic * Copyright (c) 1992 The Regents of the University of California. 3*54210Sbostic * All rights reserved. 4*54210Sbostic * 5*54210Sbostic * This code is derived from software contributed to Berkeley by 6*54210Sbostic * Christos Zoulas of Cornell University. 7*54210Sbostic * 8*54210Sbostic * %sccs.include.redist.c% 9*54210Sbostic */ 10*54210Sbostic 11*54210Sbostic #ifndef lint 12*54210Sbostic static char sccsid[] = "@(#)chared.c 5.1 (Berkeley) 06/22/92"; 13*54210Sbostic #endif /* not lint */ 14*54210Sbostic 15*54210Sbostic /* 16*54210Sbostic * el.chared.c: Character editor utilities 17*54210Sbostic */ 18*54210Sbostic #include "sys.h" 19*54210Sbostic 20*54210Sbostic #include <stdlib.h> 21*54210Sbostic #include "el.h" 22*54210Sbostic 23*54210Sbostic /* cv_undo(): 24*54210Sbostic * Handle state for the vi undo command 25*54210Sbostic */ 26*54210Sbostic protected void 27*54210Sbostic cv_undo(el, action, size, ptr) 28*54210Sbostic EditLine *el; 29*54210Sbostic int action, size; 30*54210Sbostic char *ptr; 31*54210Sbostic { 32*54210Sbostic c_undo_t *vu = &el->el_chared.c_undo; 33*54210Sbostic vu->action = action; 34*54210Sbostic vu->ptr = ptr; 35*54210Sbostic vu->isize = size; 36*54210Sbostic (void) memcpy(vu->buf, vu->ptr, size); 37*54210Sbostic #ifdef DEBUG_UNDO 38*54210Sbostic (void) fprintf(el->el_errfile, "Undo buffer \"%s\" size = +%d -%d\n", 39*54210Sbostic vu->ptr, vu->isize, vu->dsize); 40*54210Sbostic #endif 41*54210Sbostic } 42*54210Sbostic 43*54210Sbostic 44*54210Sbostic /* c_insert(): 45*54210Sbostic * Insert num characters 46*54210Sbostic */ 47*54210Sbostic protected void 48*54210Sbostic c_insert(el, num) 49*54210Sbostic EditLine *el; 50*54210Sbostic int num; 51*54210Sbostic { 52*54210Sbostic char *cp; 53*54210Sbostic 54*54210Sbostic if (el->el_line.lastchar + num >= el->el_line.limit) 55*54210Sbostic return; /* can't go past end of buffer */ 56*54210Sbostic 57*54210Sbostic if (el->el_line.cursor < el->el_line.lastchar) { 58*54210Sbostic /* if I must move chars */ 59*54210Sbostic for (cp = el->el_line.lastchar; cp >= el->el_line.cursor; cp--) 60*54210Sbostic cp[num] = *cp; 61*54210Sbostic } 62*54210Sbostic el->el_line.lastchar += num; 63*54210Sbostic } /* end c_insert */ 64*54210Sbostic 65*54210Sbostic 66*54210Sbostic /* c_delafter(): 67*54210Sbostic * Delete num characters after the cursor 68*54210Sbostic */ 69*54210Sbostic protected void 70*54210Sbostic c_delafter(el, num) 71*54210Sbostic EditLine *el; 72*54210Sbostic int num; 73*54210Sbostic { 74*54210Sbostic 75*54210Sbostic if (el->el_line.cursor + num > el->el_line.lastchar) 76*54210Sbostic num = el->el_line.lastchar - el->el_line.cursor; 77*54210Sbostic 78*54210Sbostic if (num > 0) { 79*54210Sbostic char *cp; 80*54210Sbostic 81*54210Sbostic if (el->el_map.current != el->el_map.emacs) 82*54210Sbostic cv_undo(el, INSERT, num, el->el_line.cursor); 83*54210Sbostic 84*54210Sbostic for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++) 85*54210Sbostic *cp = cp[num]; 86*54210Sbostic 87*54210Sbostic el->el_line.lastchar -= num; 88*54210Sbostic } 89*54210Sbostic } 90*54210Sbostic 91*54210Sbostic 92*54210Sbostic /* c_delbefore(): 93*54210Sbostic * Delete num characters before the cursor 94*54210Sbostic */ 95*54210Sbostic protected void 96*54210Sbostic c_delbefore(el, num) 97*54210Sbostic EditLine *el; 98*54210Sbostic int num; 99*54210Sbostic { 100*54210Sbostic 101*54210Sbostic if (el->el_line.cursor - num < el->el_line.buffer) 102*54210Sbostic num = el->el_line.cursor - el->el_line.buffer; 103*54210Sbostic 104*54210Sbostic if (num > 0) { 105*54210Sbostic char *cp; 106*54210Sbostic 107*54210Sbostic if (el->el_map.current != el->el_map.emacs) 108*54210Sbostic cv_undo(el, INSERT, num, el->el_line.cursor - num); 109*54210Sbostic 110*54210Sbostic for (cp = el->el_line.cursor - num; cp <= el->el_line.lastchar; cp++) 111*54210Sbostic *cp = cp[num]; 112*54210Sbostic 113*54210Sbostic el->el_line.lastchar -= num; 114*54210Sbostic } 115*54210Sbostic } 116*54210Sbostic 117*54210Sbostic 118*54210Sbostic /* ce__isword(): 119*54210Sbostic * Return if p is part of a word according to emacs 120*54210Sbostic */ 121*54210Sbostic protected int 122*54210Sbostic ce__isword(p) 123*54210Sbostic int p; 124*54210Sbostic { 125*54210Sbostic return isalpha(p) || isdigit(p) || strchr("*?_-.[]~=", p) != NULL; 126*54210Sbostic } 127*54210Sbostic 128*54210Sbostic 129*54210Sbostic /* cv__isword(): 130*54210Sbostic * Return if p is part of a word according to vi 131*54210Sbostic */ 132*54210Sbostic protected int 133*54210Sbostic cv__isword(p) 134*54210Sbostic int p; 135*54210Sbostic { 136*54210Sbostic return !isspace(p); 137*54210Sbostic } 138*54210Sbostic 139*54210Sbostic 140*54210Sbostic /* c__prev_word(): 141*54210Sbostic * Find the previous word 142*54210Sbostic */ 143*54210Sbostic protected char * 144*54210Sbostic c__prev_word(p, low, n, wtest) 145*54210Sbostic register char *p, *low; 146*54210Sbostic register int n; 147*54210Sbostic int (*wtest) __P((int)); 148*54210Sbostic { 149*54210Sbostic p--; 150*54210Sbostic 151*54210Sbostic while (n--) { 152*54210Sbostic while ((p >= low) && !(*wtest)((unsigned char) *p)) 153*54210Sbostic p--; 154*54210Sbostic while ((p >= low) && (*wtest)((unsigned char) *p)) 155*54210Sbostic p--; 156*54210Sbostic } 157*54210Sbostic 158*54210Sbostic /* cp now points to one character before the word */ 159*54210Sbostic p++; 160*54210Sbostic if (p < low) 161*54210Sbostic p = low; 162*54210Sbostic /* cp now points where we want it */ 163*54210Sbostic return p; 164*54210Sbostic } 165*54210Sbostic 166*54210Sbostic 167*54210Sbostic /* c__next_word(): 168*54210Sbostic * Find the next word 169*54210Sbostic */ 170*54210Sbostic protected char * 171*54210Sbostic c__next_word(p, high, n, wtest) 172*54210Sbostic register char *p, *high; 173*54210Sbostic register int n; 174*54210Sbostic int (*wtest) __P((int)); 175*54210Sbostic { 176*54210Sbostic while (n--) { 177*54210Sbostic while ((p < high) && !(*wtest)((unsigned char) *p)) 178*54210Sbostic p++; 179*54210Sbostic while ((p < high) && (*wtest)((unsigned char) *p)) 180*54210Sbostic p++; 181*54210Sbostic } 182*54210Sbostic if (p > high) 183*54210Sbostic p = high; 184*54210Sbostic /* p now points where we want it */ 185*54210Sbostic return p; 186*54210Sbostic } 187*54210Sbostic 188*54210Sbostic /* cv_next_word(): 189*54210Sbostic * Find the next word vi style 190*54210Sbostic */ 191*54210Sbostic protected char * 192*54210Sbostic cv_next_word(el, p, high, n, wtest) 193*54210Sbostic EditLine *el; 194*54210Sbostic register char *p, *high; 195*54210Sbostic register int n; 196*54210Sbostic int (*wtest) __P((int)); 197*54210Sbostic { 198*54210Sbostic int test; 199*54210Sbostic 200*54210Sbostic while (n--) { 201*54210Sbostic test = (*wtest)((unsigned char) *p); 202*54210Sbostic while ((p < high) && (*wtest)((unsigned char) *p) == test) 203*54210Sbostic p++; 204*54210Sbostic /* 205*54210Sbostic * vi historically deletes with cw only the word preserving the 206*54210Sbostic * trailing whitespace! This is not what 'w' does.. 207*54210Sbostic */ 208*54210Sbostic if (el->el_chared.c_vcmd.action != (DELETE|INSERT)) 209*54210Sbostic while ((p < high) && isspace((unsigned char) *p)) 210*54210Sbostic p++; 211*54210Sbostic } 212*54210Sbostic 213*54210Sbostic /* p now points where we want it */ 214*54210Sbostic if (p > high) 215*54210Sbostic return high; 216*54210Sbostic else 217*54210Sbostic return p; 218*54210Sbostic } 219*54210Sbostic 220*54210Sbostic 221*54210Sbostic /* cv_prev_word(): 222*54210Sbostic * Find the previous word vi style 223*54210Sbostic */ 224*54210Sbostic protected char * 225*54210Sbostic cv_prev_word(el, p, low, n, wtest) 226*54210Sbostic EditLine *el; 227*54210Sbostic register char *p, *low; 228*54210Sbostic register int n; 229*54210Sbostic int (*wtest) __P((int)); 230*54210Sbostic { 231*54210Sbostic int test; 232*54210Sbostic 233*54210Sbostic while (n--) { 234*54210Sbostic p--; 235*54210Sbostic /* 236*54210Sbostic * vi historically deletes with cb only the word preserving the 237*54210Sbostic * leading whitespace! This is not what 'b' does.. 238*54210Sbostic */ 239*54210Sbostic if (el->el_chared.c_vcmd.action != (DELETE|INSERT)) 240*54210Sbostic while ((p > low) && isspace((unsigned char) *p)) 241*54210Sbostic p--; 242*54210Sbostic test = (*wtest)((unsigned char) *p); 243*54210Sbostic while ((p >= low) && (*wtest)((unsigned char) *p) == test) 244*54210Sbostic p--; 245*54210Sbostic p++; 246*54210Sbostic while (isspace((unsigned char) *p)) 247*54210Sbostic p++; 248*54210Sbostic } 249*54210Sbostic 250*54210Sbostic /* p now points where we want it */ 251*54210Sbostic if (p < low) 252*54210Sbostic return low; 253*54210Sbostic else 254*54210Sbostic return p; 255*54210Sbostic } 256*54210Sbostic 257*54210Sbostic 258*54210Sbostic #ifdef notdef 259*54210Sbostic /* c__number(): 260*54210Sbostic * Ignore character p points to, return number appearing after that. 261*54210Sbostic * A '$' by itself means a big number; "$-" is for negative; '^' means 1. 262*54210Sbostic * Return p pointing to last char used. 263*54210Sbostic */ 264*54210Sbostic protected char * 265*54210Sbostic c__number(p, num, dval) 266*54210Sbostic char *p; /* character position */ 267*54210Sbostic int *num; /* Return value */ 268*54210Sbostic int dval; /* dval is the number to subtract from like $-3 */ 269*54210Sbostic { 270*54210Sbostic register int i; 271*54210Sbostic register int sign = 1; 272*54210Sbostic 273*54210Sbostic if (*++p == '^') { 274*54210Sbostic *num = 1; 275*54210Sbostic return p; 276*54210Sbostic } 277*54210Sbostic if (*p == '$') { 278*54210Sbostic if (*++p != '-') { 279*54210Sbostic *num = 0x7fffffff; /* Handle $ */ 280*54210Sbostic return --p; 281*54210Sbostic } 282*54210Sbostic sign = -1; /* Handle $- */ 283*54210Sbostic ++p; 284*54210Sbostic } 285*54210Sbostic for (i = 0; isdigit((unsigned char) *p); i = 10 * i + *p++ - '0') 286*54210Sbostic continue; 287*54210Sbostic *num = (sign < 0 ? dval - i : i); 288*54210Sbostic return --p; 289*54210Sbostic } 290*54210Sbostic #endif 291*54210Sbostic 292*54210Sbostic /* cv_delfini(): 293*54210Sbostic * Finish vi delete action 294*54210Sbostic */ 295*54210Sbostic protected void 296*54210Sbostic cv_delfini(el) 297*54210Sbostic EditLine *el; 298*54210Sbostic { 299*54210Sbostic register int size; 300*54210Sbostic int oaction; 301*54210Sbostic 302*54210Sbostic if (el->el_chared.c_vcmd.action & INSERT) 303*54210Sbostic el->el_map.current = el->el_map.key; 304*54210Sbostic 305*54210Sbostic oaction = el->el_chared.c_vcmd.action; 306*54210Sbostic el->el_chared.c_vcmd.action = NOP; 307*54210Sbostic 308*54210Sbostic if (el->el_chared.c_vcmd.pos == 0) 309*54210Sbostic return; 310*54210Sbostic 311*54210Sbostic 312*54210Sbostic if (el->el_line.cursor > el->el_chared.c_vcmd.pos) { 313*54210Sbostic size = (int) (el->el_line.cursor - el->el_chared.c_vcmd.pos); 314*54210Sbostic c_delbefore(el, size); 315*54210Sbostic el->el_line.cursor = el->el_chared.c_vcmd.pos; 316*54210Sbostic re_refresh_cursor(el); 317*54210Sbostic } 318*54210Sbostic else if (el->el_line.cursor < el->el_chared.c_vcmd.pos) { 319*54210Sbostic size = (int)(el->el_chared.c_vcmd.pos - el->el_line.cursor); 320*54210Sbostic c_delafter(el, size); 321*54210Sbostic } 322*54210Sbostic else { 323*54210Sbostic size = 1; 324*54210Sbostic c_delafter(el, size); 325*54210Sbostic } 326*54210Sbostic switch (oaction) { 327*54210Sbostic case DELETE|INSERT: 328*54210Sbostic el->el_chared.c_undo.action = DELETE|INSERT; 329*54210Sbostic break; 330*54210Sbostic case DELETE: 331*54210Sbostic el->el_chared.c_undo.action = INSERT; 332*54210Sbostic break; 333*54210Sbostic case NOP: 334*54210Sbostic case INSERT: 335*54210Sbostic default: 336*54210Sbostic abort(); 337*54210Sbostic break; 338*54210Sbostic } 339*54210Sbostic 340*54210Sbostic 341*54210Sbostic el->el_chared.c_undo.ptr = el->el_line.cursor; 342*54210Sbostic el->el_chared.c_undo.dsize = size; 343*54210Sbostic } 344*54210Sbostic 345*54210Sbostic 346*54210Sbostic #ifdef notdef 347*54210Sbostic /* ce__endword(): 348*54210Sbostic * Go to the end of this word according to emacs 349*54210Sbostic */ 350*54210Sbostic protected char * 351*54210Sbostic ce__endword(p, high, n) 352*54210Sbostic char *p, *high; 353*54210Sbostic int n; 354*54210Sbostic { 355*54210Sbostic p++; 356*54210Sbostic 357*54210Sbostic while (n--) { 358*54210Sbostic while ((p < high) && isspace((unsigned char) *p)) 359*54210Sbostic p++; 360*54210Sbostic while ((p < high) && !isspace((unsigned char) *p)) 361*54210Sbostic p++; 362*54210Sbostic } 363*54210Sbostic 364*54210Sbostic p--; 365*54210Sbostic return p; 366*54210Sbostic } 367*54210Sbostic #endif 368*54210Sbostic 369*54210Sbostic 370*54210Sbostic /* cv__endword(): 371*54210Sbostic * Go to the end of this word according to vi 372*54210Sbostic */ 373*54210Sbostic protected char * 374*54210Sbostic cv__endword(p, high, n) 375*54210Sbostic char *p, *high; 376*54210Sbostic int n; 377*54210Sbostic { 378*54210Sbostic p++; 379*54210Sbostic 380*54210Sbostic while (n--) { 381*54210Sbostic while ((p < high) && isspace((unsigned char) *p)) 382*54210Sbostic p++; 383*54210Sbostic 384*54210Sbostic if (isalnum((unsigned char) *p)) 385*54210Sbostic while ((p < high) && isalnum((unsigned char) *p)) 386*54210Sbostic p++; 387*54210Sbostic else 388*54210Sbostic while ((p < high) && !(isspace((unsigned char) *p) || 389*54210Sbostic isalnum((unsigned char) *p))) 390*54210Sbostic p++; 391*54210Sbostic } 392*54210Sbostic p--; 393*54210Sbostic return p; 394*54210Sbostic } 395*54210Sbostic 396*54210Sbostic /* ch_init(): 397*54210Sbostic * Initialize the character editor 398*54210Sbostic */ 399*54210Sbostic protected int 400*54210Sbostic ch_init(el) 401*54210Sbostic EditLine *el; 402*54210Sbostic { 403*54210Sbostic el->el_line.buffer = (char *) el_malloc(EL_BUFSIZ); 404*54210Sbostic (void) memset(el->el_line.buffer, 0, EL_BUFSIZ); 405*54210Sbostic el->el_line.cursor = el->el_line.buffer; 406*54210Sbostic el->el_line.lastchar = el->el_line.buffer; 407*54210Sbostic el->el_line.limit = &el->el_line.buffer[EL_BUFSIZ - 2]; 408*54210Sbostic 409*54210Sbostic el->el_chared.c_undo.buf = (char *) el_malloc(EL_BUFSIZ); 410*54210Sbostic (void) memset(el->el_chared.c_undo.buf, 0, EL_BUFSIZ); 411*54210Sbostic el->el_chared.c_undo.action = NOP; 412*54210Sbostic el->el_chared.c_undo.isize = 0; 413*54210Sbostic el->el_chared.c_undo.dsize = 0; 414*54210Sbostic el->el_chared.c_undo.ptr = el->el_line.buffer; 415*54210Sbostic 416*54210Sbostic el->el_chared.c_vcmd.action = NOP; 417*54210Sbostic el->el_chared.c_vcmd.pos = el->el_line.buffer; 418*54210Sbostic el->el_chared.c_vcmd.ins = el->el_line.buffer; 419*54210Sbostic 420*54210Sbostic el->el_chared.c_kill.buf = (char *) el_malloc(EL_BUFSIZ); 421*54210Sbostic (void) memset(el->el_chared.c_kill.buf, 0, EL_BUFSIZ); 422*54210Sbostic el->el_chared.c_kill.mark = el->el_line.buffer; 423*54210Sbostic el->el_chared.c_kill.last = el->el_chared.c_kill.buf; 424*54210Sbostic 425*54210Sbostic el->el_map.current = el->el_map.key; 426*54210Sbostic 427*54210Sbostic el->el_state.inputmode = MODE_INSERT; /* XXX: save a default */ 428*54210Sbostic el->el_state.doingarg = 0; 429*54210Sbostic el->el_state.metanext = 0; 430*54210Sbostic el->el_state.argument = 1; 431*54210Sbostic el->el_state.lastcmd = ED_UNASSIGNED; 432*54210Sbostic 433*54210Sbostic el->el_chared.c_macro.level = -1; 434*54210Sbostic el->el_chared.c_macro.macro = (char **) el_malloc(EL_MAXMACRO * 435*54210Sbostic sizeof(char *)); 436*54210Sbostic return 0; 437*54210Sbostic } 438*54210Sbostic 439*54210Sbostic /* ch_reset(): 440*54210Sbostic * Reset the character editor 441*54210Sbostic */ 442*54210Sbostic protected void 443*54210Sbostic ch_reset(el) 444*54210Sbostic EditLine *el; 445*54210Sbostic { 446*54210Sbostic el->el_line.cursor = el->el_line.buffer; 447*54210Sbostic el->el_line.lastchar = el->el_line.buffer; 448*54210Sbostic 449*54210Sbostic el->el_chared.c_undo.action = NOP; 450*54210Sbostic el->el_chared.c_undo.isize = 0; 451*54210Sbostic el->el_chared.c_undo.dsize = 0; 452*54210Sbostic el->el_chared.c_undo.ptr = el->el_line.buffer; 453*54210Sbostic 454*54210Sbostic el->el_chared.c_vcmd.action = NOP; 455*54210Sbostic el->el_chared.c_vcmd.pos = el->el_line.buffer; 456*54210Sbostic el->el_chared.c_vcmd.ins = el->el_line.buffer; 457*54210Sbostic 458*54210Sbostic el->el_chared.c_kill.mark = el->el_line.buffer; 459*54210Sbostic 460*54210Sbostic el->el_map.current = el->el_map.key; 461*54210Sbostic 462*54210Sbostic el->el_state.inputmode = MODE_INSERT; /* XXX: save a default */ 463*54210Sbostic el->el_state.doingarg = 0; 464*54210Sbostic el->el_state.metanext = 0; 465*54210Sbostic el->el_state.argument = 1; 466*54210Sbostic el->el_state.lastcmd = ED_UNASSIGNED; 467*54210Sbostic 468*54210Sbostic el->el_chared.c_macro.level = -1; 469*54210Sbostic 470*54210Sbostic el->el_history.eventno = 0; 471*54210Sbostic } 472*54210Sbostic 473*54210Sbostic 474*54210Sbostic /* ch_end(): 475*54210Sbostic * Free the data structures used by the editor 476*54210Sbostic */ 477*54210Sbostic protected void 478*54210Sbostic ch_end(el) 479*54210Sbostic EditLine *el; 480*54210Sbostic { 481*54210Sbostic el_free((ptr_t) el->el_line.buffer); 482*54210Sbostic el->el_line.buffer = NULL; 483*54210Sbostic el->el_line.limit = NULL; 484*54210Sbostic el_free((ptr_t) el->el_chared.c_undo.buf); 485*54210Sbostic el->el_chared.c_undo.buf = NULL; 486*54210Sbostic el_free((ptr_t) el->el_chared.c_kill.buf); 487*54210Sbostic el->el_chared.c_kill.buf = NULL; 488*54210Sbostic el_free((ptr_t) el->el_chared.c_macro.macro); 489*54210Sbostic el->el_chared.c_macro.macro = NULL; 490*54210Sbostic ch_reset(el); 491*54210Sbostic } 492*54210Sbostic 493*54210Sbostic 494*54210Sbostic /* el_insertstr(): 495*54210Sbostic * Insert string at cursorI 496*54210Sbostic */ 497*54210Sbostic public int 498*54210Sbostic el_insertstr(el, s) 499*54210Sbostic EditLine *el; 500*54210Sbostic char *s; 501*54210Sbostic { 502*54210Sbostic int len; 503*54210Sbostic 504*54210Sbostic if ((len = strlen(s)) == 0) 505*54210Sbostic return -1; 506*54210Sbostic if (el->el_line.lastchar + len >= el->el_line.limit) 507*54210Sbostic return -1; 508*54210Sbostic 509*54210Sbostic c_insert(el, len); 510*54210Sbostic while (*s) 511*54210Sbostic *el->el_line.cursor++ = *s++; 512*54210Sbostic return 0; 513*54210Sbostic } 514*54210Sbostic 515*54210Sbostic 516*54210Sbostic /* el_deletestr(): 517*54210Sbostic * Delete num characters before the cursor 518*54210Sbostic */ 519*54210Sbostic public void 520*54210Sbostic el_deletestr(el, n) 521*54210Sbostic EditLine *el; 522*54210Sbostic int n; 523*54210Sbostic { 524*54210Sbostic if (n <= 0) 525*54210Sbostic return; 526*54210Sbostic 527*54210Sbostic if (el->el_line.cursor < &el->el_line.buffer[n]) 528*54210Sbostic return; 529*54210Sbostic 530*54210Sbostic c_delbefore(el, n); /* delete before dot */ 531*54210Sbostic el->el_line.cursor -= n; 532*54210Sbostic if (el->el_line.cursor < el->el_line.buffer) 533*54210Sbostic el->el_line.cursor = el->el_line.buffer; 534*54210Sbostic } 535*54210Sbostic 536*54210Sbostic /* c_gets(): 537*54210Sbostic * Get a string 538*54210Sbostic */ 539*54210Sbostic protected int 540*54210Sbostic c_gets(el, buf) 541*54210Sbostic EditLine *el; 542*54210Sbostic char *buf; 543*54210Sbostic { 544*54210Sbostic char ch; 545*54210Sbostic int len = 0; 546*54210Sbostic 547*54210Sbostic for (ch = 0; ch == 0;) { 548*54210Sbostic if (el_getc(el, &ch) != 1) 549*54210Sbostic return ed_end_of_file(el, 0); 550*54210Sbostic switch (ch) { 551*54210Sbostic case 0010: /* Delete and backspace */ 552*54210Sbostic case 0177: 553*54210Sbostic if (len > 1) { 554*54210Sbostic *el->el_line.cursor-- = '\0'; 555*54210Sbostic el->el_line.lastchar = el->el_line.cursor; 556*54210Sbostic buf[len--] = '\0'; 557*54210Sbostic } 558*54210Sbostic else { 559*54210Sbostic el->el_line.buffer[0] = '\0'; 560*54210Sbostic el->el_line.lastchar = el->el_line.buffer; 561*54210Sbostic el->el_line.cursor = el->el_line.buffer; 562*54210Sbostic return CC_REFRESH; 563*54210Sbostic } 564*54210Sbostic re_refresh(el); 565*54210Sbostic ch = 0; 566*54210Sbostic break; 567*54210Sbostic 568*54210Sbostic case 0033: /* ESC */ 569*54210Sbostic case '\r': /* Newline */ 570*54210Sbostic case '\n': 571*54210Sbostic break; 572*54210Sbostic 573*54210Sbostic default: 574*54210Sbostic if (len >= EL_BUFSIZ) 575*54210Sbostic term_beep(el); 576*54210Sbostic else { 577*54210Sbostic buf[len++] = ch; 578*54210Sbostic *el->el_line.cursor++ = ch; 579*54210Sbostic el->el_line.lastchar = el->el_line.cursor; 580*54210Sbostic } 581*54210Sbostic re_refresh(el); 582*54210Sbostic ch = 0; 583*54210Sbostic break; 584*54210Sbostic } 585*54210Sbostic } 586*54210Sbostic buf[len] = ch; 587*54210Sbostic return len; 588*54210Sbostic } 589*54210Sbostic 590*54210Sbostic 591*54210Sbostic /* c_hpos(): 592*54210Sbostic * Return the current horizontal position of the cursor 593*54210Sbostic */ 594*54210Sbostic protected int 595*54210Sbostic c_hpos(el) 596*54210Sbostic EditLine *el; 597*54210Sbostic { 598*54210Sbostic char *ptr; 599*54210Sbostic 600*54210Sbostic /* 601*54210Sbostic * Find how many characters till the beginning of this line. 602*54210Sbostic */ 603*54210Sbostic if (el->el_line.cursor == el->el_line.buffer) 604*54210Sbostic return 0; 605*54210Sbostic else { 606*54210Sbostic for (ptr = el->el_line.cursor - 1; 607*54210Sbostic ptr >= el->el_line.buffer && *ptr != '\n'; 608*54210Sbostic ptr--) 609*54210Sbostic continue; 610*54210Sbostic return el->el_line.cursor - ptr - 1; 611*54210Sbostic } 612*54210Sbostic } 613