kill.c
Upload User: tsgydb
Upload Date: 2007-04-14
Package Size: 10674k
Code Size: 14k
Category:

MySQL

Development Platform:

Visual C++

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