"Fossies" - the Fresh Open Source Software Archive

Member "tnftp-20200705/libedit/emacs.c" (4 Jul 2020, 12650 Bytes) of package /linux/privat/tnftp-20200705.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "emacs.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 20151004_vs_20200705.

    1 /*  $NetBSD: emacs.c,v 1.8 2020/07/04 13:43:21 lukem Exp $  */
    2 /*  from    NetBSD: emacs.c,v 1.36 2016/05/09 21:46:56 christos Exp */
    3 
    4 /*-
    5  * Copyright (c) 1992, 1993
    6  *  The Regents of the University of California.  All rights reserved.
    7  *
    8  * This code is derived from software contributed to Berkeley by
    9  * Christos Zoulas of Cornell University.
   10  *
   11  * Redistribution and use in source and binary forms, with or without
   12  * modification, are permitted provided that the following conditions
   13  * are met:
   14  * 1. Redistributions of source code must retain the above copyright
   15  *    notice, this list of conditions and the following disclaimer.
   16  * 2. Redistributions in binary form must reproduce the above copyright
   17  *    notice, this list of conditions and the following disclaimer in the
   18  *    documentation and/or other materials provided with the distribution.
   19  * 3. Neither the name of the University nor the names of its contributors
   20  *    may be used to endorse or promote products derived from this software
   21  *    without specific prior written permission.
   22  *
   23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   33  * SUCH DAMAGE.
   34  */
   35 
   36 #include "config.h"
   37 
   38 #if 0 /* tnftp */
   39 #if !defined(lint) && !defined(SCCSID)
   40 #if 0
   41 static char sccsid[] = "@(#)emacs.c 8.1 (Berkeley) 6/4/93";
   42 #else
   43 __RCSID(" NetBSD: emacs.c,v 1.36 2016/05/09 21:46:56 christos Exp  ");
   44 #endif
   45 #endif /* not lint && not SCCSID */
   46 #endif /* tnftp */
   47 
   48 /*
   49  * emacs.c: Emacs functions
   50  */
   51 #include <ctype.h>
   52 
   53 #include "el.h"
   54 #include "emacs.h"
   55 #include "fcns.h"
   56 
   57 /* em_delete_or_list():
   58  *  Delete character under cursor or list completions if at end of line
   59  *  [^D]
   60  */
   61 libedit_private el_action_t
   62 /*ARGSUSED*/
   63 em_delete_or_list(EditLine *el, wint_t c)
   64 {
   65 
   66     if (el->el_line.cursor == el->el_line.lastchar) {
   67                     /* if I'm at the end */
   68         if (el->el_line.cursor == el->el_line.buffer) {
   69                     /* and the beginning */
   70             terminal_writec(el, c); /* then do an EOF */
   71             return CC_EOF;
   72         } else {
   73             /*
   74              * Here we could list completions, but it is an
   75              * error right now
   76              */
   77             terminal_beep(el);
   78             return CC_ERROR;
   79         }
   80     } else {
   81         if (el->el_state.doingarg)
   82             c_delafter(el, el->el_state.argument);
   83         else
   84             c_delafter1(el);
   85         if (el->el_line.cursor > el->el_line.lastchar)
   86             el->el_line.cursor = el->el_line.lastchar;
   87                 /* bounds check */
   88         return CC_REFRESH;
   89     }
   90 }
   91 
   92 
   93 /* em_delete_next_word():
   94  *  Cut from cursor to end of current word
   95  *  [M-d]
   96  */
   97 libedit_private el_action_t
   98 /*ARGSUSED*/
   99 em_delete_next_word(EditLine *el, wint_t c __attribute__((__unused__)))
  100 {
  101     wchar_t *cp, *p, *kp;
  102 
  103     if (el->el_line.cursor == el->el_line.lastchar)
  104         return CC_ERROR;
  105 
  106     cp = c__next_word(el->el_line.cursor, el->el_line.lastchar,
  107         el->el_state.argument, ce__isword);
  108 
  109     for (p = el->el_line.cursor, kp = el->el_chared.c_kill.buf; p < cp; p++)
  110                 /* save the text */
  111         *kp++ = *p;
  112     el->el_chared.c_kill.last = kp;
  113 
  114     c_delafter(el, (int)(cp - el->el_line.cursor)); /* delete after dot */
  115     if (el->el_line.cursor > el->el_line.lastchar)
  116         el->el_line.cursor = el->el_line.lastchar;
  117                 /* bounds check */
  118     return CC_REFRESH;
  119 }
  120 
  121 
  122 /* em_yank():
  123  *  Paste cut buffer at cursor position
  124  *  [^Y]
  125  */
  126 libedit_private el_action_t
  127 /*ARGSUSED*/
  128 em_yank(EditLine *el, wint_t c __attribute__((__unused__)))
  129 {
  130     wchar_t *kp, *cp;
  131 
  132     if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf)
  133         return CC_NORM;
  134 
  135     if (el->el_line.lastchar +
  136         (el->el_chared.c_kill.last - el->el_chared.c_kill.buf) >=
  137         el->el_line.limit)
  138         return CC_ERROR;
  139 
  140     el->el_chared.c_kill.mark = el->el_line.cursor;
  141     cp = el->el_line.cursor;
  142 
  143     /* open the space, */
  144     c_insert(el,
  145         (int)(el->el_chared.c_kill.last - el->el_chared.c_kill.buf));
  146     /* copy the chars */
  147     for (kp = el->el_chared.c_kill.buf; kp < el->el_chared.c_kill.last; kp++)
  148         *cp++ = *kp;
  149 
  150     /* if an arg, cursor at beginning else cursor at end */
  151     if (el->el_state.argument == 1)
  152         el->el_line.cursor = cp;
  153 
  154     return CC_REFRESH;
  155 }
  156 
  157 
  158 /* em_kill_line():
  159  *  Cut the entire line and save in cut buffer
  160  *  [^U]
  161  */
  162 libedit_private el_action_t
  163 /*ARGSUSED*/
  164 em_kill_line(EditLine *el, wint_t c __attribute__((__unused__)))
  165 {
  166     wchar_t *kp, *cp;
  167 
  168     cp = el->el_line.buffer;
  169     kp = el->el_chared.c_kill.buf;
  170     while (cp < el->el_line.lastchar)
  171         *kp++ = *cp++;  /* copy it */
  172     el->el_chared.c_kill.last = kp;
  173                 /* zap! -- delete all of it */
  174     el->el_line.lastchar = el->el_line.buffer;
  175     el->el_line.cursor = el->el_line.buffer;
  176     return CC_REFRESH;
  177 }
  178 
  179 
  180 /* em_kill_region():
  181  *  Cut area between mark and cursor and save in cut buffer
  182  *  [^W]
  183  */
  184 libedit_private el_action_t
  185 /*ARGSUSED*/
  186 em_kill_region(EditLine *el, wint_t c __attribute__((__unused__)))
  187 {
  188     wchar_t *kp, *cp;
  189 
  190     if (!el->el_chared.c_kill.mark)
  191         return CC_ERROR;
  192 
  193     if (el->el_chared.c_kill.mark > el->el_line.cursor) {
  194         cp = el->el_line.cursor;
  195         kp = el->el_chared.c_kill.buf;
  196         while (cp < el->el_chared.c_kill.mark)
  197             *kp++ = *cp++;  /* copy it */
  198         el->el_chared.c_kill.last = kp;
  199         c_delafter(el, (int)(cp - el->el_line.cursor));
  200     } else {        /* mark is before cursor */
  201         cp = el->el_chared.c_kill.mark;
  202         kp = el->el_chared.c_kill.buf;
  203         while (cp < el->el_line.cursor)
  204             *kp++ = *cp++;  /* copy it */
  205         el->el_chared.c_kill.last = kp;
  206         c_delbefore(el, (int)(cp - el->el_chared.c_kill.mark));
  207         el->el_line.cursor = el->el_chared.c_kill.mark;
  208     }
  209     return CC_REFRESH;
  210 }
  211 
  212 
  213 /* em_copy_region():
  214  *  Copy area between mark and cursor to cut buffer
  215  *  [M-W]
  216  */
  217 libedit_private el_action_t
  218 /*ARGSUSED*/
  219 em_copy_region(EditLine *el, wint_t c __attribute__((__unused__)))
  220 {
  221     wchar_t *kp, *cp;
  222 
  223     if (!el->el_chared.c_kill.mark)
  224         return CC_ERROR;
  225 
  226     if (el->el_chared.c_kill.mark > el->el_line.cursor) {
  227         cp = el->el_line.cursor;
  228         kp = el->el_chared.c_kill.buf;
  229         while (cp < el->el_chared.c_kill.mark)
  230             *kp++ = *cp++;  /* copy it */
  231         el->el_chared.c_kill.last = kp;
  232     } else {
  233         cp = el->el_chared.c_kill.mark;
  234         kp = el->el_chared.c_kill.buf;
  235         while (cp < el->el_line.cursor)
  236             *kp++ = *cp++;  /* copy it */
  237         el->el_chared.c_kill.last = kp;
  238     }
  239     return CC_NORM;
  240 }
  241 
  242 
  243 /* em_gosmacs_transpose():
  244  *  Exchange the two characters before the cursor
  245  *  Gosling emacs transpose chars [^T]
  246  */
  247 libedit_private el_action_t
  248 em_gosmacs_transpose(EditLine *el, wint_t c)
  249 {
  250 
  251     if (el->el_line.cursor > &el->el_line.buffer[1]) {
  252         /* must have at least two chars entered */
  253         c = el->el_line.cursor[-2];
  254         el->el_line.cursor[-2] = el->el_line.cursor[-1];
  255         el->el_line.cursor[-1] = c;
  256         return CC_REFRESH;
  257     } else
  258         return CC_ERROR;
  259 }
  260 
  261 
  262 /* em_next_word():
  263  *  Move next to end of current word
  264  *  [M-f]
  265  */
  266 libedit_private el_action_t
  267 /*ARGSUSED*/
  268 em_next_word(EditLine *el, wint_t c __attribute__((__unused__)))
  269 {
  270     if (el->el_line.cursor == el->el_line.lastchar)
  271         return CC_ERROR;
  272 
  273     el->el_line.cursor = c__next_word(el->el_line.cursor,
  274         el->el_line.lastchar,
  275         el->el_state.argument,
  276         ce__isword);
  277 
  278     if (el->el_map.type == MAP_VI)
  279         if (el->el_chared.c_vcmd.action != NOP) {
  280             cv_delfini(el);
  281             return CC_REFRESH;
  282         }
  283     return CC_CURSOR;
  284 }
  285 
  286 
  287 /* em_upper_case():
  288  *  Uppercase the characters from cursor to end of current word
  289  *  [M-u]
  290  */
  291 libedit_private el_action_t
  292 /*ARGSUSED*/
  293 em_upper_case(EditLine *el, wint_t c __attribute__((__unused__)))
  294 {
  295     wchar_t *cp, *ep;
  296 
  297     ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
  298         el->el_state.argument, ce__isword);
  299 
  300     for (cp = el->el_line.cursor; cp < ep; cp++)
  301         if (iswlower(*cp))
  302             *cp = towupper(*cp);
  303 
  304     el->el_line.cursor = ep;
  305     if (el->el_line.cursor > el->el_line.lastchar)
  306         el->el_line.cursor = el->el_line.lastchar;
  307     return CC_REFRESH;
  308 }
  309 
  310 
  311 /* em_capitol_case():
  312  *  Capitalize the characters from cursor to end of current word
  313  *  [M-c]
  314  */
  315 libedit_private el_action_t
  316 /*ARGSUSED*/
  317 em_capitol_case(EditLine *el, wint_t c __attribute__((__unused__)))
  318 {
  319     wchar_t *cp, *ep;
  320 
  321     ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
  322         el->el_state.argument, ce__isword);
  323 
  324     for (cp = el->el_line.cursor; cp < ep; cp++) {
  325         if (iswalpha(*cp)) {
  326             if (iswlower(*cp))
  327                 *cp = towupper(*cp);
  328             cp++;
  329             break;
  330         }
  331     }
  332     for (; cp < ep; cp++)
  333         if (iswupper(*cp))
  334             *cp = towlower(*cp);
  335 
  336     el->el_line.cursor = ep;
  337     if (el->el_line.cursor > el->el_line.lastchar)
  338         el->el_line.cursor = el->el_line.lastchar;
  339     return CC_REFRESH;
  340 }
  341 
  342 
  343 /* em_lower_case():
  344  *  Lowercase the characters from cursor to end of current word
  345  *  [M-l]
  346  */
  347 libedit_private el_action_t
  348 /*ARGSUSED*/
  349 em_lower_case(EditLine *el, wint_t c __attribute__((__unused__)))
  350 {
  351     wchar_t *cp, *ep;
  352 
  353     ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
  354         el->el_state.argument, ce__isword);
  355 
  356     for (cp = el->el_line.cursor; cp < ep; cp++)
  357         if (iswupper(*cp))
  358             *cp = towlower(*cp);
  359 
  360     el->el_line.cursor = ep;
  361     if (el->el_line.cursor > el->el_line.lastchar)
  362         el->el_line.cursor = el->el_line.lastchar;
  363     return CC_REFRESH;
  364 }
  365 
  366 
  367 /* em_set_mark():
  368  *  Set the mark at cursor
  369  *  [^@]
  370  */
  371 libedit_private el_action_t
  372 /*ARGSUSED*/
  373 em_set_mark(EditLine *el, wint_t c __attribute__((__unused__)))
  374 {
  375 
  376     el->el_chared.c_kill.mark = el->el_line.cursor;
  377     return CC_NORM;
  378 }
  379 
  380 
  381 /* em_exchange_mark():
  382  *  Exchange the cursor and mark
  383  *  [^X^X]
  384  */
  385 libedit_private el_action_t
  386 /*ARGSUSED*/
  387 em_exchange_mark(EditLine *el, wint_t c __attribute__((__unused__)))
  388 {
  389     wchar_t *cp;
  390 
  391     cp = el->el_line.cursor;
  392     el->el_line.cursor = el->el_chared.c_kill.mark;
  393     el->el_chared.c_kill.mark = cp;
  394     return CC_CURSOR;
  395 }
  396 
  397 
  398 /* em_universal_argument():
  399  *  Universal argument (argument times 4)
  400  *  [^U]
  401  */
  402 libedit_private el_action_t
  403 /*ARGSUSED*/
  404 em_universal_argument(EditLine *el, wint_t c __attribute__((__unused__)))
  405 {               /* multiply current argument by 4 */
  406 
  407     if (el->el_state.argument > 1000000)
  408         return CC_ERROR;
  409     el->el_state.doingarg = 1;
  410     el->el_state.argument *= 4;
  411     return CC_ARGHACK;
  412 }
  413 
  414 
  415 /* em_meta_next():
  416  *  Add 8th bit to next character typed
  417  *  [<ESC>]
  418  */
  419 libedit_private el_action_t
  420 /*ARGSUSED*/
  421 em_meta_next(EditLine *el, wint_t c __attribute__((__unused__)))
  422 {
  423 
  424     el->el_state.metanext = 1;
  425     return CC_ARGHACK;
  426 }
  427 
  428 
  429 /* em_toggle_overwrite():
  430  *  Switch from insert to overwrite mode or vice versa
  431  */
  432 libedit_private el_action_t
  433 /*ARGSUSED*/
  434 em_toggle_overwrite(EditLine *el, wint_t c __attribute__((__unused__)))
  435 {
  436 
  437     el->el_state.inputmode = (el->el_state.inputmode == MODE_INSERT) ?
  438         MODE_REPLACE : MODE_INSERT;
  439     return CC_NORM;
  440 }
  441 
  442 
  443 /* em_copy_prev_word():
  444  *  Copy current word to cursor
  445  */
  446 libedit_private el_action_t
  447 /*ARGSUSED*/
  448 em_copy_prev_word(EditLine *el, wint_t c __attribute__((__unused__)))
  449 {
  450     wchar_t *cp, *oldc, *dp;
  451 
  452     if (el->el_line.cursor == el->el_line.buffer)
  453         return CC_ERROR;
  454 
  455     oldc = el->el_line.cursor;
  456     /* does a bounds check */
  457     cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
  458         el->el_state.argument, ce__isword);
  459 
  460     c_insert(el, (int)(oldc - cp));
  461     for (dp = oldc; cp < oldc && dp < el->el_line.lastchar; cp++)
  462         *dp++ = *cp;
  463 
  464     el->el_line.cursor = dp;/* put cursor at end */
  465 
  466     return CC_REFRESH;
  467 }
  468 
  469 
  470 /* em_inc_search_next():
  471  *  Emacs incremental next search
  472  */
  473 libedit_private el_action_t
  474 /*ARGSUSED*/
  475 em_inc_search_next(EditLine *el, wint_t c __attribute__((__unused__)))
  476 {
  477 
  478     el->el_search.patlen = 0;
  479     return ce_inc_search(el, ED_SEARCH_NEXT_HISTORY);
  480 }
  481 
  482 
  483 /* em_inc_search_prev():
  484  *  Emacs incremental reverse search
  485  */
  486 libedit_private el_action_t
  487 /*ARGSUSED*/
  488 em_inc_search_prev(EditLine *el, wint_t c __attribute__((__unused__)))
  489 {
  490 
  491     el->el_search.patlen = 0;
  492     return ce_inc_search(el, ED_SEARCH_PREV_HISTORY);
  493 }
  494 
  495 
  496 /* em_delete_prev_char():
  497  *  Delete the character to the left of the cursor
  498  *  [^?]
  499  */
  500 libedit_private el_action_t
  501 /*ARGSUSED*/
  502 em_delete_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
  503 {
  504 
  505     if (el->el_line.cursor <= el->el_line.buffer)
  506         return CC_ERROR;
  507 
  508     if (el->el_state.doingarg)
  509         c_delbefore(el, el->el_state.argument);
  510     else
  511         c_delbefore1(el);
  512     el->el_line.cursor -= el->el_state.argument;
  513     if (el->el_line.cursor < el->el_line.buffer)
  514         el->el_line.cursor = el->el_line.buffer;
  515     return CC_REFRESH;
  516 }