File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / readline / kill.c
Revision 1.1: download - view: text, annotated - select for diffs - revision graph
Wed Jul 30 08:16:45 2014 UTC (9 years, 10 months ago) by misho
CVS tags: MAIN, HEAD
Initial revision

    1: /* kill.c -- kill ring management. */
    2: 
    3: /* Copyright (C) 1994 Free Software Foundation, Inc.
    4: 
    5:    This file is part of the GNU Readline Library (Readline), a library
    6:    for reading lines of text with interactive input and history editing.      
    7: 
    8:    Readline is free software: you can redistribute it and/or modify
    9:    it under the terms of the GNU General Public License as published by
   10:    the Free Software Foundation, either version 3 of the License, or
   11:    (at your option) any later version.
   12: 
   13:    Readline is distributed in the hope that it will be useful,
   14:    but WITHOUT ANY WARRANTY; without even the implied warranty of
   15:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   16:    GNU General Public License for more details.
   17: 
   18:    You should have received a copy of the GNU General Public License
   19:    along with Readline.  If not, see <http://www.gnu.org/licenses/>.
   20: */
   21: 
   22: #define READLINE_LIBRARY
   23: 
   24: #if defined (HAVE_CONFIG_H)
   25: #  include <config.h>
   26: #endif
   27: 
   28: #include <sys/types.h>
   29: 
   30: #if defined (HAVE_UNISTD_H)
   31: #  include <unistd.h>           /* for _POSIX_VERSION */
   32: #endif /* HAVE_UNISTD_H */
   33: 
   34: #if defined (HAVE_STDLIB_H)
   35: #  include <stdlib.h>
   36: #else
   37: #  include "ansi_stdlib.h"
   38: #endif /* HAVE_STDLIB_H */
   39: 
   40: #include <stdio.h>
   41: 
   42: /* System-specific feature definitions and include files. */
   43: #include "rldefs.h"
   44: 
   45: /* Some standard library routines. */
   46: #include "readline.h"
   47: #include "history.h"
   48: 
   49: #include "rlprivate.h"
   50: #include "xmalloc.h"
   51: 
   52: /* **************************************************************** */
   53: /*								    */
   54: /*			Killing Mechanism			    */
   55: /*								    */
   56: /* **************************************************************** */
   57: 
   58: /* What we assume for a max number of kills. */
   59: #define DEFAULT_MAX_KILLS 10
   60: 
   61: /* The real variable to look at to find out when to flush kills. */
   62: static int rl_max_kills =  DEFAULT_MAX_KILLS;
   63: 
   64: /* Where to store killed text. */
   65: static char **rl_kill_ring = (char **)NULL;
   66: 
   67: /* Where we are in the kill ring. */
   68: static int rl_kill_index;
   69: 
   70: /* How many slots we have in the kill ring. */
   71: static int rl_kill_ring_length;
   72: 
   73: static int _rl_copy_to_kill_ring PARAMS((char *, int));
   74: static int region_kill_internal PARAMS((int));
   75: static int _rl_copy_word_as_kill PARAMS((int, int));
   76: static int rl_yank_nth_arg_internal PARAMS((int, int, int));
   77: 
   78: /* How to say that you only want to save a certain amount
   79:    of kill material. */
   80: int
   81: rl_set_retained_kills (num)
   82:      int num;
   83: {
   84:   return 0;
   85: }
   86: 
   87: /* Add TEXT to the kill ring, allocating a new kill ring slot as necessary.
   88:    This uses TEXT directly, so the caller must not free it.  If APPEND is
   89:    non-zero, and the last command was a kill, the text is appended to the
   90:    current kill ring slot, otherwise prepended. */
   91: static int
   92: _rl_copy_to_kill_ring (text, append)
   93:      char *text;
   94:      int append;
   95: {
   96:   char *old, *new;
   97:   int slot;
   98: 
   99:   /* First, find the slot to work with. */
  100:   if (_rl_last_command_was_kill == 0)
  101:     {
  102:       /* Get a new slot.  */
  103:       if (rl_kill_ring == 0)
  104: 	{
  105: 	  /* If we don't have any defined, then make one. */
  106: 	  rl_kill_ring = (char **)
  107: 	    xmalloc (((rl_kill_ring_length = 1) + 1) * sizeof (char *));
  108: 	  rl_kill_ring[slot = 0] = (char *)NULL;
  109: 	}
  110:       else
  111: 	{
  112: 	  /* We have to add a new slot on the end, unless we have
  113: 	     exceeded the max limit for remembering kills. */
  114: 	  slot = rl_kill_ring_length;
  115: 	  if (slot == rl_max_kills)
  116: 	    {
  117: 	      register int i;
  118: 	      xfree (rl_kill_ring[0]);
  119: 	      for (i = 0; i < slot; i++)
  120: 		rl_kill_ring[i] = rl_kill_ring[i + 1];
  121: 	    }
  122: 	  else
  123: 	    {
  124: 	      slot = rl_kill_ring_length += 1;
  125: 	      rl_kill_ring = (char **)xrealloc (rl_kill_ring, slot * sizeof (char *));
  126: 	    }
  127: 	  rl_kill_ring[--slot] = (char *)NULL;
  128: 	}
  129:     }
  130:   else
  131:     slot = rl_kill_ring_length - 1;
  132: 
  133:   /* If the last command was a kill, prepend or append. */
  134:   if (_rl_last_command_was_kill && rl_editing_mode != vi_mode)
  135:     {
  136:       old = rl_kill_ring[slot];
  137:       new = (char *)xmalloc (1 + strlen (old) + strlen (text));
  138: 
  139:       if (append)
  140: 	{
  141: 	  strcpy (new, old);
  142: 	  strcat (new, text);
  143: 	}
  144:       else
  145: 	{
  146: 	  strcpy (new, text);
  147: 	  strcat (new, old);
  148: 	}
  149:       xfree (old);
  150:       xfree (text);
  151:       rl_kill_ring[slot] = new;
  152:     }
  153:   else
  154:     rl_kill_ring[slot] = text;
  155: 
  156:   rl_kill_index = slot;
  157:   return 0;
  158: }
  159: 
  160: /* The way to kill something.  This appends or prepends to the last
  161:    kill, if the last command was a kill command.  if FROM is less
  162:    than TO, then the text is appended, otherwise prepended.  If the
  163:    last command was not a kill command, then a new slot is made for
  164:    this kill. */
  165: int
  166: rl_kill_text (from, to)
  167:      int from, to;
  168: {
  169:   char *text;
  170: 
  171:   /* Is there anything to kill? */
  172:   if (from == to)
  173:     {
  174:       _rl_last_command_was_kill++;
  175:       return 0;
  176:     }
  177: 
  178:   text = rl_copy_text (from, to);
  179: 
  180:   /* Delete the copied text from the line. */
  181:   rl_delete_text (from, to);
  182: 
  183:   _rl_copy_to_kill_ring (text, from < to);
  184: 
  185:   _rl_last_command_was_kill++;
  186:   return 0;
  187: }
  188: 
  189: /* Now REMEMBER!  In order to do prepending or appending correctly, kill
  190:    commands always make rl_point's original position be the FROM argument,
  191:    and rl_point's extent be the TO argument. */
  192: 
  193: /* **************************************************************** */
  194: /*								    */
  195: /*			Killing Commands			    */
  196: /*								    */
  197: /* **************************************************************** */
  198: 
  199: /* Delete the word at point, saving the text in the kill ring. */
  200: int
  201: rl_kill_word (count, key)
  202:      int count, key;
  203: {
  204:   int orig_point;
  205: 
  206:   if (count < 0)
  207:     return (rl_backward_kill_word (-count, key));
  208:   else
  209:     {
  210:       orig_point = rl_point;
  211:       rl_forward_word (count, key);
  212: 
  213:       if (rl_point != orig_point)
  214: 	rl_kill_text (orig_point, rl_point);
  215: 
  216:       rl_point = orig_point;
  217:       if (rl_editing_mode == emacs_mode)
  218: 	rl_mark = rl_point;
  219:     }
  220:   return 0;
  221: }
  222: 
  223: /* Rubout the word before point, placing it on the kill ring. */
  224: int
  225: rl_backward_kill_word (count, ignore)
  226:      int count, ignore;
  227: {
  228:   int orig_point;
  229: 
  230:   if (count < 0)
  231:     return (rl_kill_word (-count, ignore));
  232:   else
  233:     {
  234:       orig_point = rl_point;
  235:       rl_backward_word (count, ignore);
  236: 
  237:       if (rl_point != orig_point)
  238: 	rl_kill_text (orig_point, rl_point);
  239: 
  240:       if (rl_editing_mode == emacs_mode)
  241: 	rl_mark = rl_point;
  242:     }
  243:   return 0;
  244: }
  245: 
  246: /* Kill from here to the end of the line.  If DIRECTION is negative, kill
  247:    back to the line start instead. */
  248: int
  249: rl_kill_line (direction, ignore)
  250:      int direction, ignore;
  251: {
  252:   int orig_point;
  253: 
  254:   if (direction < 0)
  255:     return (rl_backward_kill_line (1, ignore));
  256:   else
  257:     {
  258:       orig_point = rl_point;
  259:       rl_end_of_line (1, ignore);
  260:       if (orig_point != rl_point)
  261: 	rl_kill_text (orig_point, rl_point);
  262:       rl_point = orig_point;
  263:       if (rl_editing_mode == emacs_mode)
  264: 	rl_mark = rl_point;
  265:     }
  266:   return 0;
  267: }
  268: 
  269: /* Kill backwards to the start of the line.  If DIRECTION is negative, kill
  270:    forwards to the line end instead. */
  271: int
  272: rl_backward_kill_line (direction, ignore)
  273:      int direction, ignore;
  274: {
  275:   int orig_point;
  276: 
  277:   if (direction < 0)
  278:     return (rl_kill_line (1, ignore));
  279:   else
  280:     {
  281:       if (!rl_point)
  282: 	rl_ding ();
  283:       else
  284: 	{
  285: 	  orig_point = rl_point;
  286: 	  rl_beg_of_line (1, ignore);
  287: 	  if (rl_point != orig_point)
  288: 	    rl_kill_text (orig_point, rl_point);
  289: 	  if (rl_editing_mode == emacs_mode)
  290: 	    rl_mark = rl_point;
  291: 	}
  292:     }
  293:   return 0;
  294: }
  295: 
  296: /* Kill the whole line, no matter where point is. */
  297: int
  298: rl_kill_full_line (count, ignore)
  299:      int count, ignore;
  300: {
  301:   rl_begin_undo_group ();
  302:   rl_point = 0;
  303:   rl_kill_text (rl_point, rl_end);
  304:   rl_mark = 0;
  305:   rl_end_undo_group ();
  306:   return 0;
  307: }
  308: 
  309: /* The next two functions mimic unix line editing behaviour, except they
  310:    save the deleted text on the kill ring.  This is safer than not saving
  311:    it, and since we have a ring, nobody should get screwed. */
  312: 
  313: /* This does what C-w does in Unix.  We can't prevent people from
  314:    using behaviour that they expect. */
  315: int
  316: rl_unix_word_rubout (count, key)
  317:      int count, key;
  318: {
  319:   int orig_point;
  320: 
  321:   if (rl_point == 0)
  322:     rl_ding ();
  323:   else
  324:     {
  325:       orig_point = rl_point;
  326:       if (count <= 0)
  327: 	count = 1;
  328: 
  329:       while (count--)
  330: 	{
  331: 	  while (rl_point && whitespace (rl_line_buffer[rl_point - 1]))
  332: 	    rl_point--;
  333: 
  334: 	  while (rl_point && (whitespace (rl_line_buffer[rl_point - 1]) == 0))
  335: 	    rl_point--;
  336: 	}
  337: 
  338:       rl_kill_text (orig_point, rl_point);
  339:       if (rl_editing_mode == emacs_mode)
  340: 	rl_mark = rl_point;
  341:     }
  342: 
  343:   return 0;
  344: }
  345: 
  346: /* This deletes one filename component in a Unix pathname.  That is, it
  347:    deletes backward to directory separator (`/') or whitespace.  */
  348: int
  349: rl_unix_filename_rubout (count, key)
  350:      int count, key;
  351: {
  352:   int orig_point, c;
  353: 
  354:   if (rl_point == 0)
  355:     rl_ding ();
  356:   else
  357:     {
  358:       orig_point = rl_point;
  359:       if (count <= 0)
  360: 	count = 1;
  361: 
  362:       while (count--)
  363: 	{
  364: 	  c = rl_line_buffer[rl_point - 1];
  365: 	  while (rl_point && (whitespace (c) || c == '/'))
  366: 	    {
  367: 	      rl_point--;
  368: 	      c = rl_line_buffer[rl_point - 1];
  369: 	    }
  370: 
  371: 	  while (rl_point && (whitespace (c) == 0) && c != '/')
  372: 	    {
  373: 	      rl_point--;
  374: 	      c = rl_line_buffer[rl_point - 1];
  375: 	    }
  376: 	}
  377: 
  378:       rl_kill_text (orig_point, rl_point);
  379:       if (rl_editing_mode == emacs_mode)
  380: 	rl_mark = rl_point;
  381:     }
  382: 
  383:   return 0;
  384: }
  385: 
  386: /* Here is C-u doing what Unix does.  You don't *have* to use these
  387:    key-bindings.  We have a choice of killing the entire line, or
  388:    killing from where we are to the start of the line.  We choose the
  389:    latter, because if you are a Unix weenie, then you haven't backspaced
  390:    into the line at all, and if you aren't, then you know what you are
  391:    doing. */
  392: int
  393: rl_unix_line_discard (count, key)
  394:      int count, key;
  395: {
  396:   if (rl_point == 0)
  397:     rl_ding ();
  398:   else
  399:     {
  400:       rl_kill_text (rl_point, 0);
  401:       rl_point = 0;
  402:       if (rl_editing_mode == emacs_mode)
  403: 	rl_mark = rl_point;
  404:     }
  405:   return 0;
  406: }
  407: 
  408: /* Copy the text in the `region' to the kill ring.  If DELETE is non-zero,
  409:    delete the text from the line as well. */
  410: static int
  411: region_kill_internal (delete)
  412:      int delete;
  413: {
  414:   char *text;
  415: 
  416:   if (rl_mark != rl_point)
  417:     {
  418:       text = rl_copy_text (rl_point, rl_mark);
  419:       if (delete)
  420: 	rl_delete_text (rl_point, rl_mark);
  421:       _rl_copy_to_kill_ring (text, rl_point < rl_mark);
  422:     }
  423: 
  424:   _rl_last_command_was_kill++;
  425:   return 0;
  426: }
  427: 
  428: /* Copy the text in the region to the kill ring. */
  429: int
  430: rl_copy_region_to_kill (count, ignore)
  431:      int count, ignore;
  432: {
  433:   return (region_kill_internal (0));
  434: }
  435: 
  436: /* Kill the text between the point and mark. */
  437: int
  438: rl_kill_region (count, ignore)
  439:      int count, ignore;
  440: {
  441:   int r, npoint;
  442: 
  443:   npoint = (rl_point < rl_mark) ? rl_point : rl_mark;
  444:   r = region_kill_internal (1);
  445:   _rl_fix_point (1);
  446:   rl_point = npoint;
  447:   return r;
  448: }
  449: 
  450: /* Copy COUNT words to the kill ring.  DIR says which direction we look
  451:    to find the words. */
  452: static int
  453: _rl_copy_word_as_kill (count, dir)
  454:      int count, dir;
  455: {
  456:   int om, op, r;
  457: 
  458:   om = rl_mark;
  459:   op = rl_point;
  460: 
  461:   if (dir > 0)
  462:     rl_forward_word (count, 0);
  463:   else
  464:     rl_backward_word (count, 0);
  465: 
  466:   rl_mark = rl_point;
  467: 
  468:   if (dir > 0)
  469:     rl_backward_word (count, 0);
  470:   else
  471:     rl_forward_word (count, 0);
  472: 
  473:   r = region_kill_internal (0);
  474: 
  475:   rl_mark = om;
  476:   rl_point = op;
  477: 
  478:   return r;
  479: }
  480: 
  481: int
  482: rl_copy_forward_word (count, key)
  483:      int count, key;
  484: {
  485:   if (count < 0)
  486:     return (rl_copy_backward_word (-count, key));
  487: 
  488:   return (_rl_copy_word_as_kill (count, 1));
  489: }
  490: 
  491: int
  492: rl_copy_backward_word (count, key)
  493:      int count, key;
  494: {
  495:   if (count < 0)
  496:     return (rl_copy_forward_word (-count, key));
  497: 
  498:   return (_rl_copy_word_as_kill (count, -1));
  499: }
  500:   
  501: /* Yank back the last killed text.  This ignores arguments. */
  502: int
  503: rl_yank (count, ignore)
  504:      int count, ignore;
  505: {
  506:   if (rl_kill_ring == 0)
  507:     {
  508:       _rl_abort_internal ();
  509:       return -1;
  510:     }
  511: 
  512:   _rl_set_mark_at_pos (rl_point);
  513:   rl_insert_text (rl_kill_ring[rl_kill_index]);
  514:   return 0;
  515: }
  516: 
  517: /* If the last command was yank, or yank_pop, and the text just
  518:    before point is identical to the current kill item, then
  519:    delete that text from the line, rotate the index down, and
  520:    yank back some other text. */
  521: int
  522: rl_yank_pop (count, key)
  523:      int count, key;
  524: {
  525:   int l, n;
  526: 
  527:   if (((rl_last_func != rl_yank_pop) && (rl_last_func != rl_yank)) ||
  528:       !rl_kill_ring)
  529:     {
  530:       _rl_abort_internal ();
  531:       return -1;
  532:     }
  533: 
  534:   l = strlen (rl_kill_ring[rl_kill_index]);
  535:   n = rl_point - l;
  536:   if (n >= 0 && STREQN (rl_line_buffer + n, rl_kill_ring[rl_kill_index], l))
  537:     {
  538:       rl_delete_text (n, rl_point);
  539:       rl_point = n;
  540:       rl_kill_index--;
  541:       if (rl_kill_index < 0)
  542: 	rl_kill_index = rl_kill_ring_length - 1;
  543:       rl_yank (1, 0);
  544:       return 0;
  545:     }
  546:   else
  547:     {
  548:       _rl_abort_internal ();
  549:       return -1;
  550:     }
  551: }
  552: 
  553: /* Yank the COUNTh argument from the previous history line, skipping
  554:    HISTORY_SKIP lines before looking for the `previous line'. */
  555: static int
  556: rl_yank_nth_arg_internal (count, ignore, history_skip)
  557:      int count, ignore, history_skip;
  558: {
  559:   register HIST_ENTRY *entry;
  560:   char *arg;
  561:   int i, pos;
  562: 
  563:   pos = where_history ();
  564: 
  565:   if (history_skip)
  566:     {
  567:       for (i = 0; i < history_skip; i++)
  568: 	entry = previous_history ();
  569:     }
  570: 
  571:   entry = previous_history ();
  572: 
  573:   history_set_pos (pos);
  574: 
  575:   if (entry == 0)
  576:     {
  577:       rl_ding ();
  578:       return -1;
  579:     }
  580: 
  581:   arg = history_arg_extract (count, count, entry->line);
  582:   if (!arg || !*arg)
  583:     {
  584:       rl_ding ();
  585:       FREE (arg);
  586:       return -1;
  587:     }
  588: 
  589:   rl_begin_undo_group ();
  590: 
  591:   _rl_set_mark_at_pos (rl_point);
  592: 
  593: #if defined (VI_MODE)
  594:   /* Vi mode always inserts a space before yanking the argument, and it
  595:      inserts it right *after* rl_point. */
  596:   if (rl_editing_mode == vi_mode)
  597:     {
  598:       rl_vi_append_mode (1, ignore);
  599:       rl_insert_text (" ");
  600:     }
  601: #endif /* VI_MODE */
  602: 
  603:   rl_insert_text (arg);
  604:   xfree (arg);
  605: 
  606:   rl_end_undo_group ();
  607:   return 0;
  608: }
  609: 
  610: /* Yank the COUNTth argument from the previous history line. */
  611: int
  612: rl_yank_nth_arg (count, ignore)
  613:      int count, ignore;
  614: {
  615:   return (rl_yank_nth_arg_internal (count, ignore, 0));
  616: }
  617: 
  618: /* Yank the last argument from the previous history line.  This `knows'
  619:    how rl_yank_nth_arg treats a count of `$'.  With an argument, this
  620:    behaves the same as rl_yank_nth_arg. */
  621: int
  622: rl_yank_last_arg (count, key)
  623:      int count, key;
  624: {
  625:   static int history_skip = 0;
  626:   static int explicit_arg_p = 0;
  627:   static int count_passed = 1;
  628:   static int direction = 1;
  629:   static int undo_needed = 0;
  630:   int retval;
  631: 
  632:   if (rl_last_func != rl_yank_last_arg)
  633:     {
  634:       history_skip = 0;
  635:       explicit_arg_p = rl_explicit_arg;
  636:       count_passed = count;
  637:       direction = 1;
  638:     }
  639:   else
  640:     {
  641:       if (undo_needed)
  642: 	rl_do_undo ();
  643:       if (count < 0)		/* XXX - was < 1 */
  644:         direction = -direction;
  645:       history_skip += direction;
  646:       if (history_skip < 0)
  647: 	history_skip = 0;
  648:     }
  649:  
  650:   if (explicit_arg_p)
  651:     retval = rl_yank_nth_arg_internal (count_passed, key, history_skip);
  652:   else
  653:     retval = rl_yank_nth_arg_internal ('$', key, history_skip);
  654: 
  655:   undo_needed = retval == 0;
  656:   return retval;
  657: }
  658: 
  659: /* A special paste command for users of Cygnus's cygwin32. */
  660: #if defined (__CYGWIN__)
  661: #include <windows.h>
  662: 
  663: int
  664: rl_paste_from_clipboard (count, key)
  665:      int count, key;
  666: {
  667:   char *data, *ptr;
  668:   int len;
  669: 
  670:   if (OpenClipboard (NULL) == 0)
  671:     return (0);
  672: 
  673:   data = (char *)GetClipboardData (CF_TEXT);
  674:   if (data)
  675:     {
  676:       ptr = strchr (data, '\r');
  677:       if (ptr)
  678: 	{
  679: 	  len = ptr - data;
  680: 	  ptr = (char *)xmalloc (len + 1);
  681: 	  ptr[len] = '\0';
  682: 	  strncpy (ptr, data, len);
  683: 	}
  684:       else
  685:         ptr = data;
  686:       _rl_set_mark_at_pos (rl_point);
  687:       rl_insert_text (ptr);
  688:       if (ptr != data)
  689: 	xfree (ptr);
  690:       CloseClipboard ();
  691:     }
  692:   return (0);
  693: }
  694: #endif /* __CYGWIN__ */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>