123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488 |
- /* $NetBSD: emacs.c,v 1.10 2002/03/18 16:00:52 christos Exp $ */
- /*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Christos Zoulas of Cornell University.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
- #include "config.h"
- #if !defined(lint) && !defined(SCCSID)
- #if 0
- static char sccsid[] = "@(#)emacs.c 8.1 (Berkeley) 6/4/93";
- #else
- __RCSID("$NetBSD: emacs.c,v 1.10 2002/03/18 16:00:52 christos Exp $");
- #endif
- #endif /* not lint && not SCCSID */
- /*
- * emacs.c: Emacs functions
- */
- #include "el.h"
- /* em_delete_or_list():
- * Delete character under cursor or list completions if at end of line
- * [^D]
- */
- protected el_action_t
- /*ARGSUSED*/
- em_delete_or_list(EditLine *el, int c)
- {
- if (el->el_line.cursor == el->el_line.lastchar) {
- /* if I'm at the end */
- if (el->el_line.cursor == el->el_line.buffer) {
- /* and the beginning */
- term_overwrite(el, STReof, 4); /* then do a EOF */
- term__flush();
- return (CC_EOF);
- } else {
- /*
- * Here we could list completions, but it is an
- * error right now
- */
- term_beep(el);
- return (CC_ERROR);
- }
- } else {
- c_delafter(el, el->el_state.argument); /* delete after dot */
- if (el->el_line.cursor > el->el_line.lastchar)
- el->el_line.cursor = el->el_line.lastchar;
- /* bounds check */
- return (CC_REFRESH);
- }
- }
- /* em_delete_next_word():
- * Cut from cursor to end of current word
- * [M-d]
- */
- protected el_action_t
- /*ARGSUSED*/
- em_delete_next_word(EditLine *el, int c)
- {
- char *cp, *p, *kp;
- if (el->el_line.cursor == el->el_line.lastchar)
- return (CC_ERROR);
- cp = c__next_word(el->el_line.cursor, el->el_line.lastchar,
- el->el_state.argument, ce__isword);
- for (p = el->el_line.cursor, kp = el->el_chared.c_kill.buf; p < cp; p++)
- /* save the text */
- *kp++ = *p;
- el->el_chared.c_kill.last = kp;
- c_delafter(el, cp - el->el_line.cursor); /* delete after dot */
- if (el->el_line.cursor > el->el_line.lastchar)
- el->el_line.cursor = el->el_line.lastchar;
- /* bounds check */
- return (CC_REFRESH);
- }
- /* em_yank():
- * Paste cut buffer at cursor position
- * [^Y]
- */
- protected el_action_t
- /*ARGSUSED*/
- em_yank(EditLine *el, int c)
- {
- char *kp, *cp;
- if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf) {
- if (!ch_enlargebufs(el, 1))
- return (CC_ERROR);
- }
- if (el->el_line.lastchar +
- (el->el_chared.c_kill.last - el->el_chared.c_kill.buf) >=
- el->el_line.limit)
- return (CC_ERROR);
- el->el_chared.c_kill.mark = el->el_line.cursor;
- cp = el->el_line.cursor;
- /* open the space, */
- c_insert(el, el->el_chared.c_kill.last - el->el_chared.c_kill.buf);
- /* copy the chars */
- for (kp = el->el_chared.c_kill.buf; kp < el->el_chared.c_kill.last; kp++)
- *cp++ = *kp;
- /* if an arg, cursor at beginning else cursor at end */
- if (el->el_state.argument == 1)
- el->el_line.cursor = cp;
- return (CC_REFRESH);
- }
- /* em_kill_line():
- * Cut the entire line and save in cut buffer
- * [^U]
- */
- protected el_action_t
- /*ARGSUSED*/
- em_kill_line(EditLine *el, int c)
- {
- char *kp, *cp;
- cp = el->el_line.buffer;
- kp = el->el_chared.c_kill.buf;
- while (cp < el->el_line.lastchar)
- *kp++ = *cp++; /* copy it */
- el->el_chared.c_kill.last = kp;
- /* zap! -- delete all of it */
- el->el_line.lastchar = el->el_line.buffer;
- el->el_line.cursor = el->el_line.buffer;
- return (CC_REFRESH);
- }
- /* em_kill_region():
- * Cut area between mark and cursor and save in cut buffer
- * [^W]
- */
- protected el_action_t
- /*ARGSUSED*/
- em_kill_region(EditLine *el, int c)
- {
- char *kp, *cp;
- if (!el->el_chared.c_kill.mark)
- return (CC_ERROR);
- if (el->el_chared.c_kill.mark > el->el_line.cursor) {
- cp = el->el_line.cursor;
- kp = el->el_chared.c_kill.buf;
- while (cp < el->el_chared.c_kill.mark)
- *kp++ = *cp++; /* copy it */
- el->el_chared.c_kill.last = kp;
- c_delafter(el, cp - el->el_line.cursor);
- } else { /* mark is before cursor */
- cp = el->el_chared.c_kill.mark;
- kp = el->el_chared.c_kill.buf;
- while (cp < el->el_line.cursor)
- *kp++ = *cp++; /* copy it */
- el->el_chared.c_kill.last = kp;
- c_delbefore(el, cp - el->el_chared.c_kill.mark);
- el->el_line.cursor = el->el_chared.c_kill.mark;
- }
- return (CC_REFRESH);
- }
- /* em_copy_region():
- * Copy area between mark and cursor to cut buffer
- * [M-W]
- */
- protected el_action_t
- /*ARGSUSED*/
- em_copy_region(EditLine *el, int c)
- {
- char *kp, *cp;
- if (el->el_chared.c_kill.mark)
- return (CC_ERROR);
- if (el->el_chared.c_kill.mark > el->el_line.cursor) {
- cp = el->el_line.cursor;
- kp = el->el_chared.c_kill.buf;
- while (cp < el->el_chared.c_kill.mark)
- *kp++ = *cp++; /* copy it */
- el->el_chared.c_kill.last = kp;
- } else {
- cp = el->el_chared.c_kill.mark;
- kp = el->el_chared.c_kill.buf;
- while (cp < el->el_line.cursor)
- *kp++ = *cp++; /* copy it */
- el->el_chared.c_kill.last = kp;
- }
- return (CC_NORM);
- }
- /* em_gosmacs_traspose():
- * Exchange the two characters before the cursor
- * Gosling emacs transpose chars [^T]
- */
- protected el_action_t
- em_gosmacs_traspose(EditLine *el, int c)
- {
- if (el->el_line.cursor > &el->el_line.buffer[1]) {
- /* must have at least two chars entered */
- c = el->el_line.cursor[-2];
- el->el_line.cursor[-2] = el->el_line.cursor[-1];
- el->el_line.cursor[-1] = c;
- return (CC_REFRESH);
- } else
- return (CC_ERROR);
- }
- /* em_next_word():
- * Move next to end of current word
- * [M-f]
- */
- protected el_action_t
- /*ARGSUSED*/
- em_next_word(EditLine *el, int c)
- {
- if (el->el_line.cursor == el->el_line.lastchar)
- return (CC_ERROR);
- el->el_line.cursor = c__next_word(el->el_line.cursor,
- el->el_line.lastchar,
- el->el_state.argument,
- ce__isword);
- if (el->el_map.type == MAP_VI)
- if (el->el_chared.c_vcmd.action & DELETE) {
- cv_delfini(el);
- return (CC_REFRESH);
- }
- return (CC_CURSOR);
- }
- /* em_upper_case():
- * Uppercase the characters from cursor to end of current word
- * [M-u]
- */
- protected el_action_t
- /*ARGSUSED*/
- em_upper_case(EditLine *el, int c)
- {
- char *cp, *ep;
- ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
- el->el_state.argument, ce__isword);
- for (cp = el->el_line.cursor; cp < ep; cp++)
- if (islower((unsigned char) *cp))
- *cp = toupper(*cp);
- el->el_line.cursor = ep;
- if (el->el_line.cursor > el->el_line.lastchar)
- el->el_line.cursor = el->el_line.lastchar;
- return (CC_REFRESH);
- }
- /* em_capitol_case():
- * Capitalize the characters from cursor to end of current word
- * [M-c]
- */
- protected el_action_t
- /*ARGSUSED*/
- em_capitol_case(EditLine *el, int c)
- {
- char *cp, *ep;
- ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
- el->el_state.argument, ce__isword);
- for (cp = el->el_line.cursor; cp < ep; cp++) {
- if (isalpha((unsigned char) *cp)) {
- if (islower((unsigned char) *cp))
- *cp = toupper(*cp);
- cp++;
- break;
- }
- }
- for (; cp < ep; cp++)
- if (isupper((unsigned char) *cp))
- *cp = tolower(*cp);
- el->el_line.cursor = ep;
- if (el->el_line.cursor > el->el_line.lastchar)
- el->el_line.cursor = el->el_line.lastchar;
- return (CC_REFRESH);
- }
- /* em_lower_case():
- * Lowercase the characters from cursor to end of current word
- * [M-l]
- */
- protected el_action_t
- /*ARGSUSED*/
- em_lower_case(EditLine *el, int c)
- {
- char *cp, *ep;
- ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
- el->el_state.argument, ce__isword);
- for (cp = el->el_line.cursor; cp < ep; cp++)
- if (isupper((unsigned char) *cp))
- *cp = tolower(*cp);
- el->el_line.cursor = ep;
- if (el->el_line.cursor > el->el_line.lastchar)
- el->el_line.cursor = el->el_line.lastchar;
- return (CC_REFRESH);
- }
- /* em_set_mark():
- * Set the mark at cursor
- * [^@]
- */
- protected el_action_t
- /*ARGSUSED*/
- em_set_mark(EditLine *el, int c)
- {
- el->el_chared.c_kill.mark = el->el_line.cursor;
- return (CC_NORM);
- }
- /* em_exchange_mark():
- * Exchange the cursor and mark
- * [^X^X]
- */
- protected el_action_t
- /*ARGSUSED*/
- em_exchange_mark(EditLine *el, int c)
- {
- char *cp;
- cp = el->el_line.cursor;
- el->el_line.cursor = el->el_chared.c_kill.mark;
- el->el_chared.c_kill.mark = cp;
- return (CC_CURSOR);
- }
- /* em_universal_argument():
- * Universal argument (argument times 4)
- * [^U]
- */
- protected el_action_t
- /*ARGSUSED*/
- em_universal_argument(EditLine *el, int c)
- { /* multiply current argument by 4 */
- if (el->el_state.argument > 1000000)
- return (CC_ERROR);
- el->el_state.doingarg = 1;
- el->el_state.argument *= 4;
- return (CC_ARGHACK);
- }
- /* em_meta_next():
- * Add 8th bit to next character typed
- * [<ESC>]
- */
- protected el_action_t
- /*ARGSUSED*/
- em_meta_next(EditLine *el, int c)
- {
- el->el_state.metanext = 1;
- return (CC_ARGHACK);
- }
- /* em_toggle_overwrite():
- * Switch from insert to overwrite mode or vice versa
- */
- protected el_action_t
- /*ARGSUSED*/
- em_toggle_overwrite(EditLine *el, int c)
- {
- el->el_state.inputmode = (el->el_state.inputmode == MODE_INSERT) ?
- MODE_REPLACE : MODE_INSERT;
- return (CC_NORM);
- }
- /* em_copy_prev_word():
- * Copy current word to cursor
- */
- protected el_action_t
- /*ARGSUSED*/
- em_copy_prev_word(EditLine *el, int c)
- {
- char *cp, *oldc, *dp;
- if (el->el_line.cursor == el->el_line.buffer)
- return (CC_ERROR);
- oldc = el->el_line.cursor;
- /* does a bounds check */
- cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
- el->el_state.argument, ce__isword);
- c_insert(el, oldc - cp);
- for (dp = oldc; cp < oldc && dp < el->el_line.lastchar; cp++)
- *dp++ = *cp;
- el->el_line.cursor = dp;/* put cursor at end */
- return (CC_REFRESH);
- }
- /* em_inc_search_next():
- * Emacs incremental next search
- */
- protected el_action_t
- /*ARGSUSED*/
- em_inc_search_next(EditLine *el, int c)
- {
- el->el_search.patlen = 0;
- return (ce_inc_search(el, ED_SEARCH_NEXT_HISTORY));
- }
- /* em_inc_search_prev():
- * Emacs incremental reverse search
- */
- protected el_action_t
- /*ARGSUSED*/
- em_inc_search_prev(EditLine *el, int c)
- {
- el->el_search.patlen = 0;
- return (ce_inc_search(el, ED_SEARCH_PREV_HISTORY));
- }
|