1*54216Sbostic /*- 2*54216Sbostic * Copyright (c) 1992 The Regents of the University of California. 3*54216Sbostic * All rights reserved. 4*54216Sbostic * 5*54216Sbostic * This code is derived from software contributed to Berkeley by 6*54216Sbostic * Christos Zoulas of Cornell University. 7*54216Sbostic * 8*54216Sbostic * %sccs.include.redist.c% 9*54216Sbostic */ 10*54216Sbostic 11*54216Sbostic #ifndef lint 12*54216Sbostic static char sccsid[] = "@(#)emacs.c 5.1 (Berkeley) 06/22/92"; 13*54216Sbostic #endif /* not lint */ 14*54216Sbostic 15*54216Sbostic /* 16*54216Sbostic * el.emacs.c: Emacs functions 17*54216Sbostic */ 18*54216Sbostic #include "sys.h" 19*54216Sbostic #include "el.h" 20*54216Sbostic 21*54216Sbostic /* em_delete_or_list(): 22*54216Sbostic * Delete character under cursor or list completions if at end of line 23*54216Sbostic * [^D] 24*54216Sbostic */ 25*54216Sbostic protected el_action_t 26*54216Sbostic /*ARGSUSED*/ 27*54216Sbostic em_delete_or_list(el, c) 28*54216Sbostic EditLine *el; 29*54216Sbostic int c; 30*54216Sbostic { 31*54216Sbostic if (el->el_line.cursor == el->el_line.lastchar) { /* if I'm at the end */ 32*54216Sbostic #ifdef notyet 33*54216Sbostic if (el->el_line.cursor == el->el_line.buffer) { /* and the beginning */ 34*54216Sbostic #endif 35*54216Sbostic term_overwrite(el, STReof, 4);/* then do a EOF */ 36*54216Sbostic term__flush(); 37*54216Sbostic return CC_EOF; 38*54216Sbostic #ifdef notyet 39*54216Sbostic } 40*54216Sbostic else { 41*54216Sbostic re_goto_bottom(el); 42*54216Sbostic *el->el_line.lastchar = '\0'; /* just in case */ 43*54216Sbostic return CC_LIST_CHOICES; 44*54216Sbostic } 45*54216Sbostic #endif 46*54216Sbostic } 47*54216Sbostic else { 48*54216Sbostic c_delafter(el, el->el_state.argument); /* delete after dot */ 49*54216Sbostic if (el->el_line.cursor > el->el_line.lastchar) 50*54216Sbostic el->el_line.cursor = el->el_line.lastchar; /* bounds check */ 51*54216Sbostic return CC_REFRESH; 52*54216Sbostic } 53*54216Sbostic } 54*54216Sbostic 55*54216Sbostic 56*54216Sbostic /* em_delete_next_word(): 57*54216Sbostic * Cut from cursor to end of current word 58*54216Sbostic * [M-d] 59*54216Sbostic */ 60*54216Sbostic protected el_action_t 61*54216Sbostic /*ARGSUSED*/ 62*54216Sbostic em_delete_next_word(el, c) 63*54216Sbostic EditLine *el; 64*54216Sbostic int c; 65*54216Sbostic { 66*54216Sbostic char *cp, *p, *kp; 67*54216Sbostic 68*54216Sbostic if (el->el_line.cursor == el->el_line.lastchar) 69*54216Sbostic return CC_ERROR; 70*54216Sbostic 71*54216Sbostic cp = c__next_word(el->el_line.cursor, el->el_line.lastchar, 72*54216Sbostic el->el_state.argument, ce__isword); 73*54216Sbostic 74*54216Sbostic for (p = el->el_line.cursor, kp = el->el_chared.c_kill.buf; p < cp; p++) 75*54216Sbostic /* save the text */ 76*54216Sbostic *kp++ = *p; 77*54216Sbostic el->el_chared.c_kill.last = kp; 78*54216Sbostic 79*54216Sbostic c_delafter(el, cp - el->el_line.cursor); /* delete after dot */ 80*54216Sbostic if (el->el_line.cursor > el->el_line.lastchar) 81*54216Sbostic el->el_line.cursor = el->el_line.lastchar; /* bounds check */ 82*54216Sbostic return CC_REFRESH; 83*54216Sbostic } 84*54216Sbostic 85*54216Sbostic 86*54216Sbostic /* em_yank(): 87*54216Sbostic * Paste cut buffer at cursor position 88*54216Sbostic * [^Y] 89*54216Sbostic */ 90*54216Sbostic protected el_action_t 91*54216Sbostic /*ARGSUSED*/ 92*54216Sbostic em_yank(el, c) 93*54216Sbostic EditLine *el; 94*54216Sbostic int c; 95*54216Sbostic { 96*54216Sbostic char *kp, *cp; 97*54216Sbostic 98*54216Sbostic if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf) 99*54216Sbostic return CC_ERROR; 100*54216Sbostic 101*54216Sbostic if (el->el_line.lastchar + 102*54216Sbostic (el->el_chared.c_kill.last - el->el_chared.c_kill.buf) >= 103*54216Sbostic el->el_line.limit) 104*54216Sbostic return CC_ERROR; 105*54216Sbostic 106*54216Sbostic el->el_chared.c_kill.mark = el->el_line.cursor; 107*54216Sbostic cp = el->el_line.cursor; 108*54216Sbostic 109*54216Sbostic /* open the space, */ 110*54216Sbostic c_insert(el, el->el_chared.c_kill.last - el->el_chared.c_kill.buf); 111*54216Sbostic /* copy the chars */ 112*54216Sbostic for (kp = el->el_chared.c_kill.buf; kp < el->el_chared.c_kill.last; kp++) 113*54216Sbostic *cp++ = *kp; 114*54216Sbostic 115*54216Sbostic /* if an arg, cursor at beginning else cursor at end */ 116*54216Sbostic if (el->el_state.argument == 1) 117*54216Sbostic el->el_line.cursor = cp; 118*54216Sbostic 119*54216Sbostic return CC_REFRESH; 120*54216Sbostic } 121*54216Sbostic 122*54216Sbostic 123*54216Sbostic /* em_kill_line(): 124*54216Sbostic * Cut the entire line and save in cut buffer 125*54216Sbostic * [^U] 126*54216Sbostic */ 127*54216Sbostic protected el_action_t 128*54216Sbostic /*ARGSUSED*/ 129*54216Sbostic em_kill_line(el, c) 130*54216Sbostic EditLine *el; 131*54216Sbostic int c; 132*54216Sbostic { 133*54216Sbostic char *kp, *cp; 134*54216Sbostic 135*54216Sbostic cp = el->el_line.buffer; 136*54216Sbostic kp = el->el_chared.c_kill.buf; 137*54216Sbostic while (cp < el->el_line.lastchar) 138*54216Sbostic *kp++ = *cp++; /* copy it */ 139*54216Sbostic el->el_chared.c_kill.last = kp; 140*54216Sbostic el->el_line.lastchar = el->el_line.buffer; /* zap! -- delete all of it */ 141*54216Sbostic el->el_line.cursor = el->el_line.buffer; 142*54216Sbostic return CC_REFRESH; 143*54216Sbostic } 144*54216Sbostic 145*54216Sbostic 146*54216Sbostic /* em_kill_region(): 147*54216Sbostic * Cut area between mark and cursor and save in cut buffer 148*54216Sbostic * [^W] 149*54216Sbostic */ 150*54216Sbostic protected el_action_t 151*54216Sbostic /*ARGSUSED*/ 152*54216Sbostic em_kill_region(el, c) 153*54216Sbostic EditLine *el; 154*54216Sbostic int c; 155*54216Sbostic { 156*54216Sbostic char *kp, *cp; 157*54216Sbostic 158*54216Sbostic if (!el->el_chared.c_kill.mark) 159*54216Sbostic return CC_ERROR; 160*54216Sbostic 161*54216Sbostic if (el->el_chared.c_kill.mark > el->el_line.cursor) { 162*54216Sbostic cp = el->el_line.cursor; 163*54216Sbostic kp = el->el_chared.c_kill.buf; 164*54216Sbostic while (cp < el->el_chared.c_kill.mark) 165*54216Sbostic *kp++ = *cp++; /* copy it */ 166*54216Sbostic el->el_chared.c_kill.last = kp; 167*54216Sbostic c_delafter(el, cp - el->el_line.cursor); 168*54216Sbostic } 169*54216Sbostic else { /* mark is before cursor */ 170*54216Sbostic cp = el->el_chared.c_kill.mark; 171*54216Sbostic kp = el->el_chared.c_kill.buf; 172*54216Sbostic while (cp < el->el_line.cursor) 173*54216Sbostic *kp++ = *cp++; /* copy it */ 174*54216Sbostic el->el_chared.c_kill.last = kp; 175*54216Sbostic c_delbefore(el, cp - el->el_chared.c_kill.mark); 176*54216Sbostic el->el_line.cursor = el->el_chared.c_kill.mark; 177*54216Sbostic } 178*54216Sbostic return CC_REFRESH; 179*54216Sbostic } 180*54216Sbostic 181*54216Sbostic 182*54216Sbostic /* em_copy_region(): 183*54216Sbostic * Copy area between mark and cursor to cut buffer 184*54216Sbostic * [M-W] 185*54216Sbostic */ 186*54216Sbostic protected el_action_t 187*54216Sbostic /*ARGSUSED*/ 188*54216Sbostic em_copy_region(el, c) 189*54216Sbostic EditLine *el; 190*54216Sbostic int c; 191*54216Sbostic { 192*54216Sbostic char *kp, *cp; 193*54216Sbostic 194*54216Sbostic if (el->el_chared.c_kill.mark) 195*54216Sbostic return CC_ERROR; 196*54216Sbostic 197*54216Sbostic if (el->el_chared.c_kill.mark > el->el_line.cursor) { 198*54216Sbostic cp = el->el_line.cursor; 199*54216Sbostic kp = el->el_chared.c_kill.buf; 200*54216Sbostic while (cp < el->el_chared.c_kill.mark) 201*54216Sbostic *kp++ = *cp++; /* copy it */ 202*54216Sbostic el->el_chared.c_kill.last = kp; 203*54216Sbostic } 204*54216Sbostic else { 205*54216Sbostic cp = el->el_chared.c_kill.mark; 206*54216Sbostic kp = el->el_chared.c_kill.buf; 207*54216Sbostic while (cp < el->el_line.cursor) 208*54216Sbostic *kp++ = *cp++; /* copy it */ 209*54216Sbostic el->el_chared.c_kill.last = kp; 210*54216Sbostic } 211*54216Sbostic return CC_NORM; 212*54216Sbostic } 213*54216Sbostic 214*54216Sbostic 215*54216Sbostic /* em_gosmacs_traspose(): 216*54216Sbostic * Exchange the two characters before the cursor 217*54216Sbostic * Gosling emacs transpose chars [^T] 218*54216Sbostic */ 219*54216Sbostic protected el_action_t 220*54216Sbostic em_gosmacs_traspose(el, c) 221*54216Sbostic EditLine *el; 222*54216Sbostic int c; 223*54216Sbostic { 224*54216Sbostic 225*54216Sbostic if (el->el_line.cursor > &el->el_line.buffer[1]) { 226*54216Sbostic /* must have at least two chars entered */ 227*54216Sbostic c = el->el_line.cursor[-2]; 228*54216Sbostic el->el_line.cursor[-2] = el->el_line.cursor[-1]; 229*54216Sbostic el->el_line.cursor[-1] = c; 230*54216Sbostic return CC_REFRESH; 231*54216Sbostic } 232*54216Sbostic else 233*54216Sbostic return CC_ERROR; 234*54216Sbostic } 235*54216Sbostic 236*54216Sbostic 237*54216Sbostic /* em_next_word(): 238*54216Sbostic * Move next to end of current word 239*54216Sbostic * [M-f] 240*54216Sbostic */ 241*54216Sbostic protected el_action_t 242*54216Sbostic /*ARGSUSED*/ 243*54216Sbostic em_next_word(el, c) 244*54216Sbostic EditLine *el; 245*54216Sbostic int c; 246*54216Sbostic { 247*54216Sbostic if (el->el_line.cursor == el->el_line.lastchar) 248*54216Sbostic return CC_ERROR; 249*54216Sbostic 250*54216Sbostic el->el_line.cursor = c__next_word(el->el_line.cursor, el->el_line.lastchar, 251*54216Sbostic el->el_state.argument, 252*54216Sbostic ce__isword); 253*54216Sbostic 254*54216Sbostic if (el->el_map.type == MAP_VI) 255*54216Sbostic if (el->el_chared.c_vcmd.action & DELETE) { 256*54216Sbostic cv_delfini(el); 257*54216Sbostic return CC_REFRESH; 258*54216Sbostic } 259*54216Sbostic 260*54216Sbostic return CC_CURSOR; 261*54216Sbostic } 262*54216Sbostic 263*54216Sbostic /* em_upper_case(): 264*54216Sbostic * Uppercase the characters from cursor to end of current word 265*54216Sbostic * [M-u] 266*54216Sbostic */ 267*54216Sbostic protected el_action_t 268*54216Sbostic /*ARGSUSED*/ 269*54216Sbostic em_upper_case(el, c) 270*54216Sbostic EditLine *el; 271*54216Sbostic int c; 272*54216Sbostic { 273*54216Sbostic char *cp, *ep; 274*54216Sbostic 275*54216Sbostic ep = c__next_word(el->el_line.cursor, el->el_line.lastchar, 276*54216Sbostic el->el_state.argument, ce__isword); 277*54216Sbostic 278*54216Sbostic for (cp = el->el_line.cursor; cp < ep; cp++) 279*54216Sbostic if (islower(*cp)) 280*54216Sbostic *cp = toupper(*cp); 281*54216Sbostic 282*54216Sbostic el->el_line.cursor = ep; 283*54216Sbostic if (el->el_line.cursor > el->el_line.lastchar) 284*54216Sbostic el->el_line.cursor = el->el_line.lastchar; 285*54216Sbostic return CC_REFRESH; 286*54216Sbostic } 287*54216Sbostic 288*54216Sbostic 289*54216Sbostic /* em_capitol_case(): 290*54216Sbostic * Capitalize the characters from cursor to end of current word 291*54216Sbostic * [M-c] 292*54216Sbostic */ 293*54216Sbostic protected el_action_t 294*54216Sbostic /*ARGSUSED*/ 295*54216Sbostic em_capitol_case(el, c) 296*54216Sbostic EditLine *el; 297*54216Sbostic int c; 298*54216Sbostic { 299*54216Sbostic char *cp, *ep; 300*54216Sbostic 301*54216Sbostic ep = c__next_word(el->el_line.cursor, el->el_line.lastchar, 302*54216Sbostic el->el_state.argument, ce__isword); 303*54216Sbostic 304*54216Sbostic for (cp = el->el_line.cursor; cp < ep; cp++) { 305*54216Sbostic if (isalpha(*cp)) { 306*54216Sbostic if (islower(*cp)) 307*54216Sbostic *cp = toupper(*cp); 308*54216Sbostic cp++; 309*54216Sbostic break; 310*54216Sbostic } 311*54216Sbostic } 312*54216Sbostic for (; cp < ep; cp++) 313*54216Sbostic if (isupper(*cp)) 314*54216Sbostic *cp = tolower(*cp); 315*54216Sbostic 316*54216Sbostic el->el_line.cursor = ep; 317*54216Sbostic if (el->el_line.cursor > el->el_line.lastchar) 318*54216Sbostic el->el_line.cursor = el->el_line.lastchar; 319*54216Sbostic return CC_REFRESH; 320*54216Sbostic } 321*54216Sbostic 322*54216Sbostic /* em_lower_case(): 323*54216Sbostic * Lowercase the characters from cursor to end of current word 324*54216Sbostic * [M-l] 325*54216Sbostic */ 326*54216Sbostic protected el_action_t 327*54216Sbostic /*ARGSUSED*/ 328*54216Sbostic em_lower_case(el, c) 329*54216Sbostic EditLine *el; 330*54216Sbostic int c; 331*54216Sbostic { 332*54216Sbostic char *cp, *ep; 333*54216Sbostic 334*54216Sbostic ep = c__next_word(el->el_line.cursor, el->el_line.lastchar, 335*54216Sbostic el->el_state.argument, ce__isword); 336*54216Sbostic 337*54216Sbostic for (cp = el->el_line.cursor; cp < ep; cp++) 338*54216Sbostic if (isupper(*cp)) 339*54216Sbostic *cp = tolower(*cp); 340*54216Sbostic 341*54216Sbostic el->el_line.cursor = ep; 342*54216Sbostic if (el->el_line.cursor > el->el_line.lastchar) 343*54216Sbostic el->el_line.cursor = el->el_line.lastchar; 344*54216Sbostic return CC_REFRESH; 345*54216Sbostic } 346*54216Sbostic 347*54216Sbostic 348*54216Sbostic /* em_set_mark(): 349*54216Sbostic * Set the mark at cursor 350*54216Sbostic * [^@] 351*54216Sbostic */ 352*54216Sbostic protected el_action_t 353*54216Sbostic /*ARGSUSED*/ 354*54216Sbostic em_set_mark(el, c) 355*54216Sbostic EditLine *el; 356*54216Sbostic int c; 357*54216Sbostic { 358*54216Sbostic el->el_chared.c_kill.mark = el->el_line.cursor; 359*54216Sbostic return CC_NORM; 360*54216Sbostic } 361*54216Sbostic 362*54216Sbostic 363*54216Sbostic /* em_exchange_mark(): 364*54216Sbostic * Exchange the cursor and mark 365*54216Sbostic * [^X^X] 366*54216Sbostic */ 367*54216Sbostic protected el_action_t 368*54216Sbostic /*ARGSUSED*/ 369*54216Sbostic em_exchange_mark(el, c) 370*54216Sbostic EditLine *el; 371*54216Sbostic int c; 372*54216Sbostic { 373*54216Sbostic register char *cp; 374*54216Sbostic 375*54216Sbostic cp = el->el_line.cursor; 376*54216Sbostic el->el_line.cursor = el->el_chared.c_kill.mark; 377*54216Sbostic el->el_chared.c_kill.mark = cp; 378*54216Sbostic return CC_CURSOR; 379*54216Sbostic } 380*54216Sbostic 381*54216Sbostic /* em_universal_argument(): 382*54216Sbostic * Universal argument (argument times 4) 383*54216Sbostic * [^U] 384*54216Sbostic */ 385*54216Sbostic protected el_action_t 386*54216Sbostic /*ARGSUSED*/ 387*54216Sbostic em_universal_argument(el, c) 388*54216Sbostic EditLine *el; 389*54216Sbostic int c; 390*54216Sbostic { /* multiply current argument by 4 */ 391*54216Sbostic if (el->el_state.argument > 1000000) 392*54216Sbostic return CC_ERROR; 393*54216Sbostic el->el_state.doingarg = 1; 394*54216Sbostic el->el_state.argument *= 4; 395*54216Sbostic return CC_ARGHACK; 396*54216Sbostic } 397*54216Sbostic 398*54216Sbostic /* em_meta_next(): 399*54216Sbostic * Add 8th bit to next character typed 400*54216Sbostic * [<ESC>] 401*54216Sbostic */ 402*54216Sbostic protected el_action_t 403*54216Sbostic /*ARGSUSED*/ 404*54216Sbostic em_meta_next(el, c) 405*54216Sbostic EditLine *el; 406*54216Sbostic int c; 407*54216Sbostic { 408*54216Sbostic el->el_state.metanext = 1; 409*54216Sbostic return CC_ARGHACK; 410*54216Sbostic } 411*54216Sbostic 412*54216Sbostic 413*54216Sbostic /* em_toggle_overwrite(): 414*54216Sbostic * Switch from insert to overwrite mode or vice versa 415*54216Sbostic */ 416*54216Sbostic protected el_action_t 417*54216Sbostic /*ARGSUSED*/ 418*54216Sbostic em_toggle_overwrite(el, c) 419*54216Sbostic EditLine *el; 420*54216Sbostic int c; 421*54216Sbostic { 422*54216Sbostic el->el_state.inputmode = 423*54216Sbostic (el->el_state.inputmode == MODE_INSERT) ? MODE_REPLACE : MODE_INSERT; 424*54216Sbostic return CC_NORM; 425*54216Sbostic } 426*54216Sbostic 427*54216Sbostic 428*54216Sbostic /* em_copy_prev_word(): 429*54216Sbostic * Copy current word to cursor 430*54216Sbostic */ 431*54216Sbostic protected el_action_t 432*54216Sbostic /*ARGSUSED*/ 433*54216Sbostic em_copy_prev_word(el, c) 434*54216Sbostic EditLine *el; 435*54216Sbostic int c; 436*54216Sbostic { 437*54216Sbostic char *cp, *oldc, *dp; 438*54216Sbostic 439*54216Sbostic if (el->el_line.cursor == el->el_line.buffer) 440*54216Sbostic return CC_ERROR; 441*54216Sbostic 442*54216Sbostic oldc = el->el_line.cursor; 443*54216Sbostic /* does a bounds check */ 444*54216Sbostic cp = c__prev_word(el->el_line.cursor, el->el_line.buffer, 445*54216Sbostic el->el_state.argument, ce__isword); 446*54216Sbostic 447*54216Sbostic c_insert(el, oldc - cp); 448*54216Sbostic for (dp = oldc; cp < oldc && dp < el->el_line.lastchar; cp++) 449*54216Sbostic *dp++ = *cp; 450*54216Sbostic 451*54216Sbostic el->el_line.cursor = dp; /* put cursor at end */ 452*54216Sbostic 453*54216Sbostic return CC_REFRESH; 454*54216Sbostic } 455*54216Sbostic 456*54216Sbostic 457*54216Sbostic /* em_inc_search_next(): 458*54216Sbostic * Emacs incremental next search 459*54216Sbostic */ 460*54216Sbostic protected el_action_t 461*54216Sbostic /*ARGSUSED*/ 462*54216Sbostic em_inc_search_next(el, c) 463*54216Sbostic EditLine *el; 464*54216Sbostic int c; 465*54216Sbostic { 466*54216Sbostic el->el_search.patlen = 0; 467*54216Sbostic return ce_inc_search(el, ED_SEARCH_NEXT_HISTORY); 468*54216Sbostic } 469*54216Sbostic 470*54216Sbostic 471*54216Sbostic /* em_inc_search_prev(): 472*54216Sbostic * Emacs incremental reverse search 473*54216Sbostic */ 474*54216Sbostic protected el_action_t 475*54216Sbostic /*ARGSUSED*/ 476*54216Sbostic em_inc_search_prev(el, c) 477*54216Sbostic EditLine *el; 478*54216Sbostic int c; 479*54216Sbostic { 480*54216Sbostic el->el_search.patlen = 0; 481*54216Sbostic return ce_inc_search(el, ED_SEARCH_PREV_HISTORY); 482*54216Sbostic } 483