154216Sbostic /*- 254216Sbostic * Copyright (c) 1992 The Regents of the University of California. 354216Sbostic * All rights reserved. 454216Sbostic * 554216Sbostic * This code is derived from software contributed to Berkeley by 654216Sbostic * Christos Zoulas of Cornell University. 754216Sbostic * 854216Sbostic * %sccs.include.redist.c% 954216Sbostic */ 1054216Sbostic 11*54624Schristos #if !defined(lint) && !defined(SCCSID) 12*54624Schristos static char sccsid[] = "@(#)emacs.c 5.2 (Berkeley) 07/03/92"; 13*54624Schristos #endif /* not lint && not SCCSID */ 1454216Sbostic 1554216Sbostic /* 16*54624Schristos * emacs.c: Emacs functions 1754216Sbostic */ 1854216Sbostic #include "sys.h" 1954216Sbostic #include "el.h" 2054216Sbostic 2154216Sbostic /* em_delete_or_list(): 2254216Sbostic * Delete character under cursor or list completions if at end of line 2354216Sbostic * [^D] 2454216Sbostic */ 2554216Sbostic protected el_action_t 2654216Sbostic /*ARGSUSED*/ 2754216Sbostic em_delete_or_list(el, c) 2854216Sbostic EditLine *el; 2954216Sbostic int c; 3054216Sbostic { 3154216Sbostic if (el->el_line.cursor == el->el_line.lastchar) { /* if I'm at the end */ 3254216Sbostic #ifdef notyet 3354216Sbostic if (el->el_line.cursor == el->el_line.buffer) { /* and the beginning */ 3454216Sbostic #endif 3554216Sbostic term_overwrite(el, STReof, 4);/* then do a EOF */ 3654216Sbostic term__flush(); 3754216Sbostic return CC_EOF; 3854216Sbostic #ifdef notyet 3954216Sbostic } 4054216Sbostic else { 4154216Sbostic re_goto_bottom(el); 4254216Sbostic *el->el_line.lastchar = '\0'; /* just in case */ 4354216Sbostic return CC_LIST_CHOICES; 4454216Sbostic } 4554216Sbostic #endif 4654216Sbostic } 4754216Sbostic else { 4854216Sbostic c_delafter(el, el->el_state.argument); /* delete after dot */ 4954216Sbostic if (el->el_line.cursor > el->el_line.lastchar) 5054216Sbostic el->el_line.cursor = el->el_line.lastchar; /* bounds check */ 5154216Sbostic return CC_REFRESH; 5254216Sbostic } 5354216Sbostic } 5454216Sbostic 5554216Sbostic 5654216Sbostic /* em_delete_next_word(): 5754216Sbostic * Cut from cursor to end of current word 5854216Sbostic * [M-d] 5954216Sbostic */ 6054216Sbostic protected el_action_t 6154216Sbostic /*ARGSUSED*/ 6254216Sbostic em_delete_next_word(el, c) 6354216Sbostic EditLine *el; 6454216Sbostic int c; 6554216Sbostic { 6654216Sbostic char *cp, *p, *kp; 6754216Sbostic 6854216Sbostic if (el->el_line.cursor == el->el_line.lastchar) 6954216Sbostic return CC_ERROR; 7054216Sbostic 7154216Sbostic cp = c__next_word(el->el_line.cursor, el->el_line.lastchar, 7254216Sbostic el->el_state.argument, ce__isword); 7354216Sbostic 7454216Sbostic for (p = el->el_line.cursor, kp = el->el_chared.c_kill.buf; p < cp; p++) 7554216Sbostic /* save the text */ 7654216Sbostic *kp++ = *p; 7754216Sbostic el->el_chared.c_kill.last = kp; 7854216Sbostic 7954216Sbostic c_delafter(el, cp - el->el_line.cursor); /* delete after dot */ 8054216Sbostic if (el->el_line.cursor > el->el_line.lastchar) 8154216Sbostic el->el_line.cursor = el->el_line.lastchar; /* bounds check */ 8254216Sbostic return CC_REFRESH; 8354216Sbostic } 8454216Sbostic 8554216Sbostic 8654216Sbostic /* em_yank(): 8754216Sbostic * Paste cut buffer at cursor position 8854216Sbostic * [^Y] 8954216Sbostic */ 9054216Sbostic protected el_action_t 9154216Sbostic /*ARGSUSED*/ 9254216Sbostic em_yank(el, c) 9354216Sbostic EditLine *el; 9454216Sbostic int c; 9554216Sbostic { 9654216Sbostic char *kp, *cp; 9754216Sbostic 9854216Sbostic if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf) 9954216Sbostic return CC_ERROR; 10054216Sbostic 10154216Sbostic if (el->el_line.lastchar + 10254216Sbostic (el->el_chared.c_kill.last - el->el_chared.c_kill.buf) >= 10354216Sbostic el->el_line.limit) 10454216Sbostic return CC_ERROR; 10554216Sbostic 10654216Sbostic el->el_chared.c_kill.mark = el->el_line.cursor; 10754216Sbostic cp = el->el_line.cursor; 10854216Sbostic 10954216Sbostic /* open the space, */ 11054216Sbostic c_insert(el, el->el_chared.c_kill.last - el->el_chared.c_kill.buf); 11154216Sbostic /* copy the chars */ 11254216Sbostic for (kp = el->el_chared.c_kill.buf; kp < el->el_chared.c_kill.last; kp++) 11354216Sbostic *cp++ = *kp; 11454216Sbostic 11554216Sbostic /* if an arg, cursor at beginning else cursor at end */ 11654216Sbostic if (el->el_state.argument == 1) 11754216Sbostic el->el_line.cursor = cp; 11854216Sbostic 11954216Sbostic return CC_REFRESH; 12054216Sbostic } 12154216Sbostic 12254216Sbostic 12354216Sbostic /* em_kill_line(): 12454216Sbostic * Cut the entire line and save in cut buffer 12554216Sbostic * [^U] 12654216Sbostic */ 12754216Sbostic protected el_action_t 12854216Sbostic /*ARGSUSED*/ 12954216Sbostic em_kill_line(el, c) 13054216Sbostic EditLine *el; 13154216Sbostic int c; 13254216Sbostic { 13354216Sbostic char *kp, *cp; 13454216Sbostic 13554216Sbostic cp = el->el_line.buffer; 13654216Sbostic kp = el->el_chared.c_kill.buf; 13754216Sbostic while (cp < el->el_line.lastchar) 13854216Sbostic *kp++ = *cp++; /* copy it */ 13954216Sbostic el->el_chared.c_kill.last = kp; 14054216Sbostic el->el_line.lastchar = el->el_line.buffer; /* zap! -- delete all of it */ 14154216Sbostic el->el_line.cursor = el->el_line.buffer; 14254216Sbostic return CC_REFRESH; 14354216Sbostic } 14454216Sbostic 14554216Sbostic 14654216Sbostic /* em_kill_region(): 14754216Sbostic * Cut area between mark and cursor and save in cut buffer 14854216Sbostic * [^W] 14954216Sbostic */ 15054216Sbostic protected el_action_t 15154216Sbostic /*ARGSUSED*/ 15254216Sbostic em_kill_region(el, c) 15354216Sbostic EditLine *el; 15454216Sbostic int c; 15554216Sbostic { 15654216Sbostic char *kp, *cp; 15754216Sbostic 15854216Sbostic if (!el->el_chared.c_kill.mark) 15954216Sbostic return CC_ERROR; 16054216Sbostic 16154216Sbostic if (el->el_chared.c_kill.mark > el->el_line.cursor) { 16254216Sbostic cp = el->el_line.cursor; 16354216Sbostic kp = el->el_chared.c_kill.buf; 16454216Sbostic while (cp < el->el_chared.c_kill.mark) 16554216Sbostic *kp++ = *cp++; /* copy it */ 16654216Sbostic el->el_chared.c_kill.last = kp; 16754216Sbostic c_delafter(el, cp - el->el_line.cursor); 16854216Sbostic } 16954216Sbostic else { /* mark is before cursor */ 17054216Sbostic cp = el->el_chared.c_kill.mark; 17154216Sbostic kp = el->el_chared.c_kill.buf; 17254216Sbostic while (cp < el->el_line.cursor) 17354216Sbostic *kp++ = *cp++; /* copy it */ 17454216Sbostic el->el_chared.c_kill.last = kp; 17554216Sbostic c_delbefore(el, cp - el->el_chared.c_kill.mark); 17654216Sbostic el->el_line.cursor = el->el_chared.c_kill.mark; 17754216Sbostic } 17854216Sbostic return CC_REFRESH; 17954216Sbostic } 18054216Sbostic 18154216Sbostic 18254216Sbostic /* em_copy_region(): 18354216Sbostic * Copy area between mark and cursor to cut buffer 18454216Sbostic * [M-W] 18554216Sbostic */ 18654216Sbostic protected el_action_t 18754216Sbostic /*ARGSUSED*/ 18854216Sbostic em_copy_region(el, c) 18954216Sbostic EditLine *el; 19054216Sbostic int c; 19154216Sbostic { 19254216Sbostic char *kp, *cp; 19354216Sbostic 19454216Sbostic if (el->el_chared.c_kill.mark) 19554216Sbostic return CC_ERROR; 19654216Sbostic 19754216Sbostic if (el->el_chared.c_kill.mark > el->el_line.cursor) { 19854216Sbostic cp = el->el_line.cursor; 19954216Sbostic kp = el->el_chared.c_kill.buf; 20054216Sbostic while (cp < el->el_chared.c_kill.mark) 20154216Sbostic *kp++ = *cp++; /* copy it */ 20254216Sbostic el->el_chared.c_kill.last = kp; 20354216Sbostic } 20454216Sbostic else { 20554216Sbostic cp = el->el_chared.c_kill.mark; 20654216Sbostic kp = el->el_chared.c_kill.buf; 20754216Sbostic while (cp < el->el_line.cursor) 20854216Sbostic *kp++ = *cp++; /* copy it */ 20954216Sbostic el->el_chared.c_kill.last = kp; 21054216Sbostic } 21154216Sbostic return CC_NORM; 21254216Sbostic } 21354216Sbostic 21454216Sbostic 21554216Sbostic /* em_gosmacs_traspose(): 21654216Sbostic * Exchange the two characters before the cursor 21754216Sbostic * Gosling emacs transpose chars [^T] 21854216Sbostic */ 21954216Sbostic protected el_action_t 22054216Sbostic em_gosmacs_traspose(el, c) 22154216Sbostic EditLine *el; 22254216Sbostic int c; 22354216Sbostic { 22454216Sbostic 22554216Sbostic if (el->el_line.cursor > &el->el_line.buffer[1]) { 22654216Sbostic /* must have at least two chars entered */ 22754216Sbostic c = el->el_line.cursor[-2]; 22854216Sbostic el->el_line.cursor[-2] = el->el_line.cursor[-1]; 22954216Sbostic el->el_line.cursor[-1] = c; 23054216Sbostic return CC_REFRESH; 23154216Sbostic } 23254216Sbostic else 23354216Sbostic return CC_ERROR; 23454216Sbostic } 23554216Sbostic 23654216Sbostic 23754216Sbostic /* em_next_word(): 23854216Sbostic * Move next to end of current word 23954216Sbostic * [M-f] 24054216Sbostic */ 24154216Sbostic protected el_action_t 24254216Sbostic /*ARGSUSED*/ 24354216Sbostic em_next_word(el, c) 24454216Sbostic EditLine *el; 24554216Sbostic int c; 24654216Sbostic { 24754216Sbostic if (el->el_line.cursor == el->el_line.lastchar) 24854216Sbostic return CC_ERROR; 24954216Sbostic 25054216Sbostic el->el_line.cursor = c__next_word(el->el_line.cursor, el->el_line.lastchar, 25154216Sbostic el->el_state.argument, 25254216Sbostic ce__isword); 25354216Sbostic 25454216Sbostic if (el->el_map.type == MAP_VI) 25554216Sbostic if (el->el_chared.c_vcmd.action & DELETE) { 25654216Sbostic cv_delfini(el); 25754216Sbostic return CC_REFRESH; 25854216Sbostic } 25954216Sbostic 26054216Sbostic return CC_CURSOR; 26154216Sbostic } 26254216Sbostic 26354216Sbostic /* em_upper_case(): 26454216Sbostic * Uppercase the characters from cursor to end of current word 26554216Sbostic * [M-u] 26654216Sbostic */ 26754216Sbostic protected el_action_t 26854216Sbostic /*ARGSUSED*/ 26954216Sbostic em_upper_case(el, c) 27054216Sbostic EditLine *el; 27154216Sbostic int c; 27254216Sbostic { 27354216Sbostic char *cp, *ep; 27454216Sbostic 27554216Sbostic ep = c__next_word(el->el_line.cursor, el->el_line.lastchar, 27654216Sbostic el->el_state.argument, ce__isword); 27754216Sbostic 27854216Sbostic for (cp = el->el_line.cursor; cp < ep; cp++) 27954216Sbostic if (islower(*cp)) 28054216Sbostic *cp = toupper(*cp); 28154216Sbostic 28254216Sbostic el->el_line.cursor = ep; 28354216Sbostic if (el->el_line.cursor > el->el_line.lastchar) 28454216Sbostic el->el_line.cursor = el->el_line.lastchar; 28554216Sbostic return CC_REFRESH; 28654216Sbostic } 28754216Sbostic 28854216Sbostic 28954216Sbostic /* em_capitol_case(): 29054216Sbostic * Capitalize the characters from cursor to end of current word 29154216Sbostic * [M-c] 29254216Sbostic */ 29354216Sbostic protected el_action_t 29454216Sbostic /*ARGSUSED*/ 29554216Sbostic em_capitol_case(el, c) 29654216Sbostic EditLine *el; 29754216Sbostic int c; 29854216Sbostic { 29954216Sbostic char *cp, *ep; 30054216Sbostic 30154216Sbostic ep = c__next_word(el->el_line.cursor, el->el_line.lastchar, 30254216Sbostic el->el_state.argument, ce__isword); 30354216Sbostic 30454216Sbostic for (cp = el->el_line.cursor; cp < ep; cp++) { 30554216Sbostic if (isalpha(*cp)) { 30654216Sbostic if (islower(*cp)) 30754216Sbostic *cp = toupper(*cp); 30854216Sbostic cp++; 30954216Sbostic break; 31054216Sbostic } 31154216Sbostic } 31254216Sbostic for (; cp < ep; cp++) 31354216Sbostic if (isupper(*cp)) 31454216Sbostic *cp = tolower(*cp); 31554216Sbostic 31654216Sbostic el->el_line.cursor = ep; 31754216Sbostic if (el->el_line.cursor > el->el_line.lastchar) 31854216Sbostic el->el_line.cursor = el->el_line.lastchar; 31954216Sbostic return CC_REFRESH; 32054216Sbostic } 32154216Sbostic 32254216Sbostic /* em_lower_case(): 32354216Sbostic * Lowercase the characters from cursor to end of current word 32454216Sbostic * [M-l] 32554216Sbostic */ 32654216Sbostic protected el_action_t 32754216Sbostic /*ARGSUSED*/ 32854216Sbostic em_lower_case(el, c) 32954216Sbostic EditLine *el; 33054216Sbostic int c; 33154216Sbostic { 33254216Sbostic char *cp, *ep; 33354216Sbostic 33454216Sbostic ep = c__next_word(el->el_line.cursor, el->el_line.lastchar, 33554216Sbostic el->el_state.argument, ce__isword); 33654216Sbostic 33754216Sbostic for (cp = el->el_line.cursor; cp < ep; cp++) 33854216Sbostic if (isupper(*cp)) 33954216Sbostic *cp = tolower(*cp); 34054216Sbostic 34154216Sbostic el->el_line.cursor = ep; 34254216Sbostic if (el->el_line.cursor > el->el_line.lastchar) 34354216Sbostic el->el_line.cursor = el->el_line.lastchar; 34454216Sbostic return CC_REFRESH; 34554216Sbostic } 34654216Sbostic 34754216Sbostic 34854216Sbostic /* em_set_mark(): 34954216Sbostic * Set the mark at cursor 35054216Sbostic * [^@] 35154216Sbostic */ 35254216Sbostic protected el_action_t 35354216Sbostic /*ARGSUSED*/ 35454216Sbostic em_set_mark(el, c) 35554216Sbostic EditLine *el; 35654216Sbostic int c; 35754216Sbostic { 35854216Sbostic el->el_chared.c_kill.mark = el->el_line.cursor; 35954216Sbostic return CC_NORM; 36054216Sbostic } 36154216Sbostic 36254216Sbostic 36354216Sbostic /* em_exchange_mark(): 36454216Sbostic * Exchange the cursor and mark 36554216Sbostic * [^X^X] 36654216Sbostic */ 36754216Sbostic protected el_action_t 36854216Sbostic /*ARGSUSED*/ 36954216Sbostic em_exchange_mark(el, c) 37054216Sbostic EditLine *el; 37154216Sbostic int c; 37254216Sbostic { 37354216Sbostic register char *cp; 37454216Sbostic 37554216Sbostic cp = el->el_line.cursor; 37654216Sbostic el->el_line.cursor = el->el_chared.c_kill.mark; 37754216Sbostic el->el_chared.c_kill.mark = cp; 37854216Sbostic return CC_CURSOR; 37954216Sbostic } 38054216Sbostic 38154216Sbostic /* em_universal_argument(): 38254216Sbostic * Universal argument (argument times 4) 38354216Sbostic * [^U] 38454216Sbostic */ 38554216Sbostic protected el_action_t 38654216Sbostic /*ARGSUSED*/ 38754216Sbostic em_universal_argument(el, c) 38854216Sbostic EditLine *el; 38954216Sbostic int c; 39054216Sbostic { /* multiply current argument by 4 */ 39154216Sbostic if (el->el_state.argument > 1000000) 39254216Sbostic return CC_ERROR; 39354216Sbostic el->el_state.doingarg = 1; 39454216Sbostic el->el_state.argument *= 4; 39554216Sbostic return CC_ARGHACK; 39654216Sbostic } 39754216Sbostic 39854216Sbostic /* em_meta_next(): 39954216Sbostic * Add 8th bit to next character typed 40054216Sbostic * [<ESC>] 40154216Sbostic */ 40254216Sbostic protected el_action_t 40354216Sbostic /*ARGSUSED*/ 40454216Sbostic em_meta_next(el, c) 40554216Sbostic EditLine *el; 40654216Sbostic int c; 40754216Sbostic { 40854216Sbostic el->el_state.metanext = 1; 40954216Sbostic return CC_ARGHACK; 41054216Sbostic } 41154216Sbostic 41254216Sbostic 41354216Sbostic /* em_toggle_overwrite(): 41454216Sbostic * Switch from insert to overwrite mode or vice versa 41554216Sbostic */ 41654216Sbostic protected el_action_t 41754216Sbostic /*ARGSUSED*/ 41854216Sbostic em_toggle_overwrite(el, c) 41954216Sbostic EditLine *el; 42054216Sbostic int c; 42154216Sbostic { 42254216Sbostic el->el_state.inputmode = 42354216Sbostic (el->el_state.inputmode == MODE_INSERT) ? MODE_REPLACE : MODE_INSERT; 42454216Sbostic return CC_NORM; 42554216Sbostic } 42654216Sbostic 42754216Sbostic 42854216Sbostic /* em_copy_prev_word(): 42954216Sbostic * Copy current word to cursor 43054216Sbostic */ 43154216Sbostic protected el_action_t 43254216Sbostic /*ARGSUSED*/ 43354216Sbostic em_copy_prev_word(el, c) 43454216Sbostic EditLine *el; 43554216Sbostic int c; 43654216Sbostic { 43754216Sbostic char *cp, *oldc, *dp; 43854216Sbostic 43954216Sbostic if (el->el_line.cursor == el->el_line.buffer) 44054216Sbostic return CC_ERROR; 44154216Sbostic 44254216Sbostic oldc = el->el_line.cursor; 44354216Sbostic /* does a bounds check */ 44454216Sbostic cp = c__prev_word(el->el_line.cursor, el->el_line.buffer, 44554216Sbostic el->el_state.argument, ce__isword); 44654216Sbostic 44754216Sbostic c_insert(el, oldc - cp); 44854216Sbostic for (dp = oldc; cp < oldc && dp < el->el_line.lastchar; cp++) 44954216Sbostic *dp++ = *cp; 45054216Sbostic 45154216Sbostic el->el_line.cursor = dp; /* put cursor at end */ 45254216Sbostic 45354216Sbostic return CC_REFRESH; 45454216Sbostic } 45554216Sbostic 45654216Sbostic 45754216Sbostic /* em_inc_search_next(): 45854216Sbostic * Emacs incremental next search 45954216Sbostic */ 46054216Sbostic protected el_action_t 46154216Sbostic /*ARGSUSED*/ 46254216Sbostic em_inc_search_next(el, c) 46354216Sbostic EditLine *el; 46454216Sbostic int c; 46554216Sbostic { 46654216Sbostic el->el_search.patlen = 0; 46754216Sbostic return ce_inc_search(el, ED_SEARCH_NEXT_HISTORY); 46854216Sbostic } 46954216Sbostic 47054216Sbostic 47154216Sbostic /* em_inc_search_prev(): 47254216Sbostic * Emacs incremental reverse search 47354216Sbostic */ 47454216Sbostic protected el_action_t 47554216Sbostic /*ARGSUSED*/ 47654216Sbostic em_inc_search_prev(el, c) 47754216Sbostic EditLine *el; 47854216Sbostic int c; 47954216Sbostic { 48054216Sbostic el->el_search.patlen = 0; 48154216Sbostic return ce_inc_search(el, ED_SEARCH_PREV_HISTORY); 48254216Sbostic } 483