emacs.c

Go to the documentation of this file.
00001 /* $NetBSD: emacs.c,v 1.10 2002/03/18 16:00:52 christos Exp $  */
00002 
00003 /*-
00004  * Copyright (c) 1992, 1993
00005  * The Regents of the University of California.  All rights reserved.
00006  *
00007  * This code is derived from software contributed to Berkeley by
00008  * Christos Zoulas of Cornell University.
00009  *
00010  * Redistribution and use in source and binary forms, with or without
00011  * modification, are permitted provided that the following conditions
00012  * are met:
00013  * 1. Redistributions of source code must retain the above copyright
00014  *    notice, this list of conditions and the following disclaimer.
00015  * 2. Redistributions in binary form must reproduce the above copyright
00016  *    notice, this list of conditions and the following disclaimer in the
00017  *    documentation and/or other materials provided with the distribution.
00018  * 3. All advertising materials mentioning features or use of this software
00019  *    must display the following acknowledgement:
00020  * This product includes software developed by the University of
00021  * California, Berkeley and its contributors.
00022  * 4. Neither the name of the University nor the names of its contributors
00023  *    may be used to endorse or promote products derived from this software
00024  *    without specific prior written permission.
00025  *
00026  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00027  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00029  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00030  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00031  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00032  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00033  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00034  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00035  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00036  * SUCH DAMAGE.
00037  */
00038 
00039 #include "config.h"
00040 #if !defined(lint) && !defined(SCCSID)
00041 #if 0
00042 static char sccsid[] = "@(#)emacs.c 8.1 (Berkeley) 6/4/93";
00043 #else
00044 __RCSID("$NetBSD: emacs.c,v 1.10 2002/03/18 16:00:52 christos Exp $");
00045 #endif
00046 #endif /* not lint && not SCCSID */
00047 
00048 /*
00049  * emacs.c: Emacs functions
00050  */
00051 #include "el.h"
00052 
00053 /* em_delete_or_list():
00054  * Delete character under cursor or list completions if at end of line
00055  * [^D]
00056  */
00057 protected el_action_t
00058 /*ARGSUSED*/
00059 em_delete_or_list(EditLine *el, int c)
00060 {
00061 
00062    if (el->el_line.cursor == el->el_line.lastchar) {
00063                /* if I'm at the end */
00064       if (el->el_line.cursor == el->el_line.buffer) {
00065                /* and the beginning */
00066          term_overwrite(el, STReof, 4);   /* then do a EOF */
00067          term__flush();
00068          return (CC_EOF);
00069       } else {
00070          /*
00071           * Here we could list completions, but it is an
00072           * error right now
00073           */
00074          term_beep(el);
00075          return (CC_ERROR);
00076       }
00077    } else {
00078       c_delafter(el, el->el_state.argument); /* delete after dot */
00079       if (el->el_line.cursor > el->el_line.lastchar)
00080          el->el_line.cursor = el->el_line.lastchar;
00081             /* bounds check */
00082       return (CC_REFRESH);
00083    }
00084 }
00085 
00086 
00087 /* em_delete_next_word():
00088  * Cut from cursor to end of current word
00089  * [M-d]
00090  */
00091 protected el_action_t
00092 /*ARGSUSED*/
00093 em_delete_next_word(EditLine *el, int c)
00094 {
00095    char *cp, *p, *kp;
00096 
00097    if (el->el_line.cursor == el->el_line.lastchar)
00098       return (CC_ERROR);
00099 
00100    cp = c__next_word(el->el_line.cursor, el->el_line.lastchar,
00101        el->el_state.argument, ce__isword);
00102 
00103    for (p = el->el_line.cursor, kp = el->el_chared.c_kill.buf; p < cp; p++)
00104             /* save the text */
00105       *kp++ = *p;
00106    el->el_chared.c_kill.last = kp;
00107 
00108    c_delafter(el, cp - el->el_line.cursor);  /* delete after dot */
00109    if (el->el_line.cursor > el->el_line.lastchar)
00110       el->el_line.cursor = el->el_line.lastchar;
00111             /* bounds check */
00112    return (CC_REFRESH);
00113 }
00114 
00115 
00116 /* em_yank():
00117  * Paste cut buffer at cursor position
00118  * [^Y]
00119  */
00120 protected el_action_t
00121 /*ARGSUSED*/
00122 em_yank(EditLine *el, int c)
00123 {
00124    char *kp, *cp;
00125 
00126    if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf) {
00127       if (!ch_enlargebufs(el, 1))
00128          return (CC_ERROR);
00129    }
00130 
00131    if (el->el_line.lastchar +
00132        (el->el_chared.c_kill.last - el->el_chared.c_kill.buf) >=
00133        el->el_line.limit)
00134       return (CC_ERROR);
00135 
00136    el->el_chared.c_kill.mark = el->el_line.cursor;
00137    cp = el->el_line.cursor;
00138 
00139    /* open the space, */
00140    c_insert(el, el->el_chared.c_kill.last - el->el_chared.c_kill.buf);
00141    /* copy the chars */
00142    for (kp = el->el_chared.c_kill.buf; kp < el->el_chared.c_kill.last; kp++)
00143       *cp++ = *kp;
00144 
00145    /* if an arg, cursor at beginning else cursor at end */
00146    if (el->el_state.argument == 1)
00147       el->el_line.cursor = cp;
00148 
00149    return (CC_REFRESH);
00150 }
00151 
00152 
00153 /* em_kill_line():
00154  * Cut the entire line and save in cut buffer
00155  * [^U]
00156  */
00157 protected el_action_t
00158 /*ARGSUSED*/
00159 em_kill_line(EditLine *el, int c)
00160 {
00161    char *kp, *cp;
00162 
00163    cp = el->el_line.buffer;
00164    kp = el->el_chared.c_kill.buf;
00165    while (cp < el->el_line.lastchar)
00166       *kp++ = *cp++; /* copy it */
00167    el->el_chared.c_kill.last = kp;
00168             /* zap! -- delete all of it */
00169    el->el_line.lastchar = el->el_line.buffer;
00170    el->el_line.cursor = el->el_line.buffer;
00171    return (CC_REFRESH);
00172 }
00173 
00174 
00175 /* em_kill_region():
00176  * Cut area between mark and cursor and save in cut buffer
00177  * [^W]
00178  */
00179 protected el_action_t
00180 /*ARGSUSED*/
00181 em_kill_region(EditLine *el, int c)
00182 {
00183    char *kp, *cp;
00184 
00185    if (!el->el_chared.c_kill.mark)
00186       return (CC_ERROR);
00187 
00188    if (el->el_chared.c_kill.mark > el->el_line.cursor) {
00189       cp = el->el_line.cursor;
00190       kp = el->el_chared.c_kill.buf;
00191       while (cp < el->el_chared.c_kill.mark)
00192          *kp++ = *cp++; /* copy it */
00193       el->el_chared.c_kill.last = kp;
00194       c_delafter(el, cp - el->el_line.cursor);
00195    } else {    /* mark is before cursor */
00196       cp = el->el_chared.c_kill.mark;
00197       kp = el->el_chared.c_kill.buf;
00198       while (cp < el->el_line.cursor)
00199          *kp++ = *cp++; /* copy it */
00200       el->el_chared.c_kill.last = kp;
00201       c_delbefore(el, cp - el->el_chared.c_kill.mark);
00202       el->el_line.cursor = el->el_chared.c_kill.mark;
00203    }
00204    return (CC_REFRESH);
00205 }
00206 
00207 
00208 /* em_copy_region():
00209  * Copy area between mark and cursor to cut buffer
00210  * [M-W]
00211  */
00212 protected el_action_t
00213 /*ARGSUSED*/
00214 em_copy_region(EditLine *el, int c)
00215 {
00216    char *kp, *cp;
00217 
00218    if (el->el_chared.c_kill.mark)
00219       return (CC_ERROR);
00220 
00221    if (el->el_chared.c_kill.mark > el->el_line.cursor) {
00222       cp = el->el_line.cursor;
00223       kp = el->el_chared.c_kill.buf;
00224       while (cp < el->el_chared.c_kill.mark)
00225          *kp++ = *cp++; /* copy it */
00226       el->el_chared.c_kill.last = kp;
00227    } else {
00228       cp = el->el_chared.c_kill.mark;
00229       kp = el->el_chared.c_kill.buf;
00230       while (cp < el->el_line.cursor)
00231          *kp++ = *cp++; /* copy it */
00232       el->el_chared.c_kill.last = kp;
00233    }
00234    return (CC_NORM);
00235 }
00236 
00237 
00238 /* em_gosmacs_traspose():
00239  * Exchange the two characters before the cursor
00240  * Gosling emacs transpose chars [^T]
00241  */
00242 protected el_action_t
00243 em_gosmacs_traspose(EditLine *el, int c)
00244 {
00245 
00246    if (el->el_line.cursor > &el->el_line.buffer[1]) {
00247       /* must have at least two chars entered */
00248       c = el->el_line.cursor[-2];
00249       el->el_line.cursor[-2] = el->el_line.cursor[-1];
00250       el->el_line.cursor[-1] = c;
00251       return (CC_REFRESH);
00252    } else
00253       return (CC_ERROR);
00254 }
00255 
00256 
00257 /* em_next_word():
00258  * Move next to end of current word
00259  * [M-f]
00260  */
00261 protected el_action_t
00262 /*ARGSUSED*/
00263 em_next_word(EditLine *el, int c)
00264 {
00265    if (el->el_line.cursor == el->el_line.lastchar)
00266       return (CC_ERROR);
00267 
00268    el->el_line.cursor = c__next_word(el->el_line.cursor,
00269        el->el_line.lastchar,
00270        el->el_state.argument,
00271        ce__isword);
00272 
00273    if (el->el_map.type == MAP_VI)
00274       if (el->el_chared.c_vcmd.action & DELETE) {
00275          cv_delfini(el);
00276          return (CC_REFRESH);
00277       }
00278    return (CC_CURSOR);
00279 }
00280 
00281 
00282 /* em_upper_case():
00283  * Uppercase the characters from cursor to end of current word
00284  * [M-u]
00285  */
00286 protected el_action_t
00287 /*ARGSUSED*/
00288 em_upper_case(EditLine *el, int c)
00289 {
00290    char *cp, *ep;
00291 
00292    ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
00293        el->el_state.argument, ce__isword);
00294 
00295    for (cp = el->el_line.cursor; cp < ep; cp++)
00296       if (islower((unsigned char) *cp))
00297          *cp = toupper(*cp);
00298 
00299    el->el_line.cursor = ep;
00300    if (el->el_line.cursor > el->el_line.lastchar)
00301       el->el_line.cursor = el->el_line.lastchar;
00302    return (CC_REFRESH);
00303 }
00304 
00305 
00306 /* em_capitol_case():
00307  * Capitalize the characters from cursor to end of current word
00308  * [M-c]
00309  */
00310 protected el_action_t
00311 /*ARGSUSED*/
00312 em_capitol_case(EditLine *el, int c)
00313 {
00314    char *cp, *ep;
00315 
00316    ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
00317        el->el_state.argument, ce__isword);
00318 
00319    for (cp = el->el_line.cursor; cp < ep; cp++) {
00320       if (isalpha((unsigned char) *cp)) {
00321          if (islower((unsigned char) *cp))
00322             *cp = toupper(*cp);
00323          cp++;
00324          break;
00325       }
00326    }
00327    for (; cp < ep; cp++)
00328       if (isupper((unsigned char) *cp))
00329          *cp = tolower(*cp);
00330 
00331    el->el_line.cursor = ep;
00332    if (el->el_line.cursor > el->el_line.lastchar)
00333       el->el_line.cursor = el->el_line.lastchar;
00334    return (CC_REFRESH);
00335 }
00336 
00337 
00338 /* em_lower_case():
00339  * Lowercase the characters from cursor to end of current word
00340  * [M-l]
00341  */
00342 protected el_action_t
00343 /*ARGSUSED*/
00344 em_lower_case(EditLine *el, int c)
00345 {
00346    char *cp, *ep;
00347 
00348    ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
00349        el->el_state.argument, ce__isword);
00350 
00351    for (cp = el->el_line.cursor; cp < ep; cp++)
00352       if (isupper((unsigned char) *cp))
00353          *cp = tolower(*cp);
00354 
00355    el->el_line.cursor = ep;
00356    if (el->el_line.cursor > el->el_line.lastchar)
00357       el->el_line.cursor = el->el_line.lastchar;
00358    return (CC_REFRESH);
00359 }
00360 
00361 
00362 /* em_set_mark():
00363  * Set the mark at cursor
00364  * [^@]
00365  */
00366 protected el_action_t
00367 /*ARGSUSED*/
00368 em_set_mark(EditLine *el, int c)
00369 {
00370 
00371    el->el_chared.c_kill.mark = el->el_line.cursor;
00372    return (CC_NORM);
00373 }
00374 
00375 
00376 /* em_exchange_mark():
00377  * Exchange the cursor and mark
00378  * [^X^X]
00379  */
00380 protected el_action_t
00381 /*ARGSUSED*/
00382 em_exchange_mark(EditLine *el, int c)
00383 {
00384    char *cp;
00385 
00386    cp = el->el_line.cursor;
00387    el->el_line.cursor = el->el_chared.c_kill.mark;
00388    el->el_chared.c_kill.mark = cp;
00389    return (CC_CURSOR);
00390 }
00391 
00392 
00393 /* em_universal_argument():
00394  * Universal argument (argument times 4)
00395  * [^U]
00396  */
00397 protected el_action_t
00398 /*ARGSUSED*/
00399 em_universal_argument(EditLine *el, int c)
00400 {           /* multiply current argument by 4 */
00401 
00402    if (el->el_state.argument > 1000000)
00403       return (CC_ERROR);
00404    el->el_state.doingarg = 1;
00405    el->el_state.argument *= 4;
00406    return (CC_ARGHACK);
00407 }
00408 
00409 
00410 /* em_meta_next():
00411  * Add 8th bit to next character typed
00412  * [<ESC>]
00413  */
00414 protected el_action_t
00415 /*ARGSUSED*/
00416 em_meta_next(EditLine *el, int c)
00417 {
00418 
00419    el->el_state.metanext = 1;
00420    return (CC_ARGHACK);
00421 }
00422 
00423 
00424 /* em_toggle_overwrite():
00425  * Switch from insert to overwrite mode or vice versa
00426  */
00427 protected el_action_t
00428 /*ARGSUSED*/
00429 em_toggle_overwrite(EditLine *el, int c)
00430 {
00431 
00432    el->el_state.inputmode = (el->el_state.inputmode == MODE_INSERT) ?
00433        MODE_REPLACE : MODE_INSERT;
00434    return (CC_NORM);
00435 }
00436 
00437 
00438 /* em_copy_prev_word():
00439  * Copy current word to cursor
00440  */
00441 protected el_action_t
00442 /*ARGSUSED*/
00443 em_copy_prev_word(EditLine *el, int c)
00444 {
00445    char *cp, *oldc, *dp;
00446 
00447    if (el->el_line.cursor == el->el_line.buffer)
00448       return (CC_ERROR);
00449 
00450    oldc = el->el_line.cursor;
00451    /* does a bounds check */
00452    cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
00453        el->el_state.argument, ce__isword);
00454 
00455    c_insert(el, oldc - cp);
00456    for (dp = oldc; cp < oldc && dp < el->el_line.lastchar; cp++)
00457       *dp++ = *cp;
00458 
00459    el->el_line.cursor = dp;/* put cursor at end */
00460 
00461    return (CC_REFRESH);
00462 }
00463 
00464 
00465 /* em_inc_search_next():
00466  * Emacs incremental next search
00467  */
00468 protected el_action_t
00469 /*ARGSUSED*/
00470 em_inc_search_next(EditLine *el, int c)
00471 {
00472 
00473    el->el_search.patlen = 0;
00474    return (ce_inc_search(el, ED_SEARCH_NEXT_HISTORY));
00475 }
00476 
00477 
00478 /* em_inc_search_prev():
00479  * Emacs incremental reverse search
00480  */
00481 protected el_action_t
00482 /*ARGSUSED*/
00483 em_inc_search_prev(EditLine *el, int c)
00484 {
00485 
00486    el->el_search.patlen = 0;
00487    return (ce_inc_search(el, ED_SEARCH_PREV_HISTORY));
00488 }

Generated on Thu Apr 16 06:27:33 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6