kill.c revision 58310
121308Sache/* kill.c -- kill ring management. */
221308Sache
321308Sache/* Copyright (C) 1994 Free Software Foundation, Inc.
421308Sache
521308Sache   This file is part of the GNU Readline Library, a library for
621308Sache   reading lines of text with interactive input and history editing.
721308Sache
821308Sache   The GNU Readline Library is free software; you can redistribute it
921308Sache   and/or modify it under the terms of the GNU General Public License
1058310Sache   as published by the Free Software Foundation; either version 2, or
1121308Sache   (at your option) any later version.
1221308Sache
1321308Sache   The GNU Readline Library is distributed in the hope that it will be
1421308Sache   useful, but WITHOUT ANY WARRANTY; without even the implied warranty
1521308Sache   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1621308Sache   GNU General Public License for more details.
1721308Sache
1821308Sache   The GNU General Public License is often shipped with GNU software, and
1921308Sache   is generally kept in a file called COPYING or LICENSE.  If you do not
2021308Sache   have a copy of the license, write to the Free Software Foundation,
2158310Sache   59 Temple Place, Suite 330, Boston, MA 02111 USA. */
2221308Sache#define READLINE_LIBRARY
2321308Sache
2421308Sache#if defined (HAVE_CONFIG_H)
2521308Sache#  include <config.h>
2621308Sache#endif
2721308Sache
2821308Sache#include <sys/types.h>
2921308Sache
3021308Sache#if defined (HAVE_UNISTD_H)
3121308Sache#  include <unistd.h>           /* for _POSIX_VERSION */
3221308Sache#endif /* HAVE_UNISTD_H */
3321308Sache
3421308Sache#if defined (HAVE_STDLIB_H)
3521308Sache#  include <stdlib.h>
3621308Sache#else
3721308Sache#  include "ansi_stdlib.h"
3821308Sache#endif /* HAVE_STDLIB_H */
3921308Sache
4021308Sache#include <stdio.h>
4121308Sache
4221308Sache/* System-specific feature definitions and include files. */
4321308Sache#include "rldefs.h"
4421308Sache
4521308Sache/* Some standard library routines. */
4621308Sache#include "readline.h"
4721308Sache#include "history.h"
4821308Sache
4958310Sache#include "rlprivate.h"
5058310Sache#include "xmalloc.h"
5121308Sache
5221308Sache/* **************************************************************** */
5321308Sache/*								    */
5421308Sache/*			Killing Mechanism			    */
5521308Sache/*								    */
5621308Sache/* **************************************************************** */
5721308Sache
5821308Sache/* What we assume for a max number of kills. */
5921308Sache#define DEFAULT_MAX_KILLS 10
6021308Sache
6121308Sache/* The real variable to look at to find out when to flush kills. */
6221308Sachestatic int rl_max_kills =  DEFAULT_MAX_KILLS;
6321308Sache
6421308Sache/* Where to store killed text. */
6521308Sachestatic char **rl_kill_ring = (char **)NULL;
6621308Sache
6721308Sache/* Where we are in the kill ring. */
6821308Sachestatic int rl_kill_index;
6921308Sache
7021308Sache/* How many slots we have in the kill ring. */
7121308Sachestatic int rl_kill_ring_length;
7221308Sache
7321308Sache/* How to say that you only want to save a certain amount
7421308Sache   of kill material. */
7521308Sacheint
7621308Sacherl_set_retained_kills (num)
7721308Sache     int num;
7821308Sache{
7921308Sache  return 0;
8021308Sache}
8121308Sache
8221308Sache/* Add TEXT to the kill ring, allocating a new kill ring slot as necessary.
8321308Sache   This uses TEXT directly, so the caller must not free it.  If APPEND is
8421308Sache   non-zero, and the last command was a kill, the text is appended to the
8521308Sache   current kill ring slot, otherwise prepended. */
8621308Sachestatic int
8721308Sache_rl_copy_to_kill_ring (text, append)
8821308Sache     char *text;
8921308Sache     int append;
9021308Sache{
9121308Sache  char *old, *new;
9221308Sache  int slot;
9321308Sache
9421308Sache  /* First, find the slot to work with. */
9521308Sache  if (_rl_last_command_was_kill == 0)
9621308Sache    {
9721308Sache      /* Get a new slot.  */
9821308Sache      if (rl_kill_ring == 0)
9921308Sache	{
10021308Sache	  /* If we don't have any defined, then make one. */
10121308Sache	  rl_kill_ring = (char **)
10221308Sache	    xmalloc (((rl_kill_ring_length = 1) + 1) * sizeof (char *));
10321308Sache	  rl_kill_ring[slot = 0] = (char *)NULL;
10421308Sache	}
10521308Sache      else
10621308Sache	{
10721308Sache	  /* We have to add a new slot on the end, unless we have
10821308Sache	     exceeded the max limit for remembering kills. */
10921308Sache	  slot = rl_kill_ring_length;
11021308Sache	  if (slot == rl_max_kills)
11121308Sache	    {
11221308Sache	      register int i;
11321308Sache	      free (rl_kill_ring[0]);
11421308Sache	      for (i = 0; i < slot; i++)
11521308Sache		rl_kill_ring[i] = rl_kill_ring[i + 1];
11621308Sache	    }
11721308Sache	  else
11821308Sache	    {
11921308Sache	      slot = rl_kill_ring_length += 1;
12021308Sache	      rl_kill_ring = (char **)xrealloc (rl_kill_ring, slot * sizeof (char *));
12121308Sache	    }
12221308Sache	  rl_kill_ring[--slot] = (char *)NULL;
12321308Sache	}
12421308Sache    }
12521308Sache  else
12621308Sache    slot = rl_kill_ring_length - 1;
12721308Sache
12821308Sache  /* If the last command was a kill, prepend or append. */
12921308Sache  if (_rl_last_command_was_kill && rl_editing_mode != vi_mode)
13021308Sache    {
13121308Sache      old = rl_kill_ring[slot];
13221308Sache      new = xmalloc (1 + strlen (old) + strlen (text));
13321308Sache
13421308Sache      if (append)
13521308Sache	{
13621308Sache	  strcpy (new, old);
13721308Sache	  strcat (new, text);
13821308Sache	}
13921308Sache      else
14021308Sache	{
14121308Sache	  strcpy (new, text);
14221308Sache	  strcat (new, old);
14321308Sache	}
14421308Sache      free (old);
14521308Sache      free (text);
14621308Sache      rl_kill_ring[slot] = new;
14721308Sache    }
14821308Sache  else
14921308Sache    rl_kill_ring[slot] = text;
15021308Sache
15121308Sache  rl_kill_index = slot;
15221308Sache  return 0;
15321308Sache}
15421308Sache
15521308Sache/* The way to kill something.  This appends or prepends to the last
15621308Sache   kill, if the last command was a kill command.  if FROM is less
15721308Sache   than TO, then the text is appended, otherwise prepended.  If the
15821308Sache   last command was not a kill command, then a new slot is made for
15921308Sache   this kill. */
16021308Sacheint
16121308Sacherl_kill_text (from, to)
16221308Sache     int from, to;
16321308Sache{
16421308Sache  char *text;
16521308Sache
16621308Sache  /* Is there anything to kill? */
16721308Sache  if (from == to)
16821308Sache    {
16921308Sache      _rl_last_command_was_kill++;
17021308Sache      return 0;
17121308Sache    }
17221308Sache
17321308Sache  text = rl_copy_text (from, to);
17421308Sache
17521308Sache  /* Delete the copied text from the line. */
17621308Sache  rl_delete_text (from, to);
17721308Sache
17821308Sache  _rl_copy_to_kill_ring (text, from < to);
17921308Sache
18021308Sache  _rl_last_command_was_kill++;
18121308Sache  return 0;
18221308Sache}
18321308Sache
18421308Sache/* Now REMEMBER!  In order to do prepending or appending correctly, kill
18521308Sache   commands always make rl_point's original position be the FROM argument,
18621308Sache   and rl_point's extent be the TO argument. */
18721308Sache
18821308Sache/* **************************************************************** */
18921308Sache/*								    */
19021308Sache/*			Killing Commands			    */
19121308Sache/*								    */
19221308Sache/* **************************************************************** */
19321308Sache
19421308Sache/* Delete the word at point, saving the text in the kill ring. */
19521308Sacheint
19621308Sacherl_kill_word (count, key)
19721308Sache     int count, key;
19821308Sache{
19921308Sache  int orig_point = rl_point;
20021308Sache
20121308Sache  if (count < 0)
20221308Sache    return (rl_backward_kill_word (-count, key));
20321308Sache  else
20421308Sache    {
20521308Sache      rl_forward_word (count, key);
20621308Sache
20721308Sache      if (rl_point != orig_point)
20821308Sache	rl_kill_text (orig_point, rl_point);
20921308Sache
21021308Sache      rl_point = orig_point;
21121308Sache    }
21221308Sache  return 0;
21321308Sache}
21421308Sache
21521308Sache/* Rubout the word before point, placing it on the kill ring. */
21621308Sacheint
21721308Sacherl_backward_kill_word (count, ignore)
21821308Sache     int count, ignore;
21921308Sache{
22021308Sache  int orig_point = rl_point;
22121308Sache
22221308Sache  if (count < 0)
22321308Sache    return (rl_kill_word (-count, ignore));
22421308Sache  else
22521308Sache    {
22621308Sache      rl_backward_word (count, ignore);
22721308Sache
22821308Sache      if (rl_point != orig_point)
22921308Sache	rl_kill_text (orig_point, rl_point);
23021308Sache    }
23121308Sache  return 0;
23221308Sache}
23321308Sache
23421308Sache/* Kill from here to the end of the line.  If DIRECTION is negative, kill
23521308Sache   back to the line start instead. */
23621308Sacheint
23721308Sacherl_kill_line (direction, ignore)
23821308Sache     int direction, ignore;
23921308Sache{
24021308Sache  int orig_point = rl_point;
24121308Sache
24221308Sache  if (direction < 0)
24321308Sache    return (rl_backward_kill_line (1, ignore));
24421308Sache  else
24521308Sache    {
24621308Sache      rl_end_of_line (1, ignore);
24721308Sache      if (orig_point != rl_point)
24821308Sache	rl_kill_text (orig_point, rl_point);
24921308Sache      rl_point = orig_point;
25021308Sache    }
25121308Sache  return 0;
25221308Sache}
25321308Sache
25421308Sache/* Kill backwards to the start of the line.  If DIRECTION is negative, kill
25521308Sache   forwards to the line end instead. */
25621308Sacheint
25721308Sacherl_backward_kill_line (direction, ignore)
25821308Sache     int direction, ignore;
25921308Sache{
26021308Sache  int orig_point = rl_point;
26121308Sache
26221308Sache  if (direction < 0)
26321308Sache    return (rl_kill_line (1, ignore));
26421308Sache  else
26521308Sache    {
26621308Sache      if (!rl_point)
26721308Sache	ding ();
26821308Sache      else
26921308Sache	{
27021308Sache	  rl_beg_of_line (1, ignore);
27121308Sache	  rl_kill_text (orig_point, rl_point);
27221308Sache	}
27321308Sache    }
27421308Sache  return 0;
27521308Sache}
27621308Sache
27721308Sache/* Kill the whole line, no matter where point is. */
27821308Sacheint
27921308Sacherl_kill_full_line (count, ignore)
28021308Sache     int count, ignore;
28121308Sache{
28221308Sache  rl_begin_undo_group ();
28321308Sache  rl_point = 0;
28421308Sache  rl_kill_text (rl_point, rl_end);
28521308Sache  rl_end_undo_group ();
28621308Sache  return 0;
28721308Sache}
28821308Sache
28921308Sache/* The next two functions mimic unix line editing behaviour, except they
29021308Sache   save the deleted text on the kill ring.  This is safer than not saving
29121308Sache   it, and since we have a ring, nobody should get screwed. */
29221308Sache
29321308Sache/* This does what C-w does in Unix.  We can't prevent people from
29421308Sache   using behaviour that they expect. */
29521308Sacheint
29621308Sacherl_unix_word_rubout (count, key)
29721308Sache     int count, key;
29821308Sache{
29921308Sache  int orig_point;
30021308Sache
30121308Sache  if (rl_point == 0)
30221308Sache    ding ();
30321308Sache  else
30421308Sache    {
30521308Sache      orig_point = rl_point;
30621308Sache      if (count <= 0)
30721308Sache	count = 1;
30821308Sache
30921308Sache      while (count--)
31021308Sache	{
31121308Sache	  while (rl_point && whitespace (rl_line_buffer[rl_point - 1]))
31221308Sache	    rl_point--;
31321308Sache
31421308Sache	  while (rl_point && (whitespace (rl_line_buffer[rl_point - 1]) == 0))
31521308Sache	    rl_point--;
31621308Sache	}
31721308Sache
31821308Sache      rl_kill_text (orig_point, rl_point);
31921308Sache    }
32021308Sache  return 0;
32121308Sache}
32221308Sache
32321308Sache/* Here is C-u doing what Unix does.  You don't *have* to use these
32421308Sache   key-bindings.  We have a choice of killing the entire line, or
32521308Sache   killing from where we are to the start of the line.  We choose the
32621308Sache   latter, because if you are a Unix weenie, then you haven't backspaced
32721308Sache   into the line at all, and if you aren't, then you know what you are
32821308Sache   doing. */
32921308Sacheint
33021308Sacherl_unix_line_discard (count, key)
33121308Sache     int count, key;
33221308Sache{
33321308Sache  if (rl_point == 0)
33421308Sache    ding ();
33521308Sache  else
33621308Sache    {
33721308Sache      rl_kill_text (rl_point, 0);
33821308Sache      rl_point = 0;
33921308Sache    }
34021308Sache  return 0;
34121308Sache}
34221308Sache
34321308Sache/* Copy the text in the `region' to the kill ring.  If DELETE is non-zero,
34421308Sache   delete the text from the line as well. */
34521308Sachestatic int
34621308Sacheregion_kill_internal (delete)
34721308Sache     int delete;
34821308Sache{
34921308Sache  char *text;
35021308Sache
35121308Sache  if (rl_mark == rl_point)
35221308Sache    {
35321308Sache      _rl_last_command_was_kill++;
35421308Sache      return 0;
35521308Sache    }
35621308Sache
35721308Sache  text = rl_copy_text (rl_point, rl_mark);
35821308Sache  if (delete)
35921308Sache    rl_delete_text (rl_point, rl_mark);
36021308Sache  _rl_copy_to_kill_ring (text, rl_point < rl_mark);
36121308Sache
36221308Sache  _rl_last_command_was_kill++;
36321308Sache  return 0;
36421308Sache}
36521308Sache
36621308Sache/* Copy the text in the region to the kill ring. */
36721308Sacheint
36821308Sacherl_copy_region_to_kill (count, ignore)
36921308Sache     int count, ignore;
37021308Sache{
37121308Sache  return (region_kill_internal (0));
37221308Sache}
37321308Sache
37421308Sache/* Kill the text between the point and mark. */
37521308Sacheint
37621308Sacherl_kill_region (count, ignore)
37721308Sache     int count, ignore;
37821308Sache{
37958310Sache  int r, npoint;
38026497Sache
38158310Sache  npoint = (rl_point < rl_mark) ? rl_point : rl_mark;
38226497Sache  r = region_kill_internal (1);
38326497Sache  _rl_fix_point (1);
38458310Sache  rl_point = npoint;
38526497Sache  return r;
38621308Sache}
38721308Sache
38821308Sache/* Copy COUNT words to the kill ring.  DIR says which direction we look
38921308Sache   to find the words. */
39021308Sachestatic int
39121308Sache_rl_copy_word_as_kill (count, dir)
39221308Sache     int count, dir;
39321308Sache{
39421308Sache  int om, op, r;
39521308Sache
39621308Sache  om = rl_mark;
39721308Sache  op = rl_point;
39821308Sache
39921308Sache  if (dir > 0)
40021308Sache    rl_forward_word (count, 0);
40121308Sache  else
40221308Sache    rl_backward_word (count, 0);
40321308Sache
40421308Sache  rl_mark = rl_point;
40521308Sache
40621308Sache  if (dir > 0)
40721308Sache    rl_backward_word (count, 0);
40821308Sache  else
40921308Sache    rl_forward_word (count, 0);
41021308Sache
41121308Sache  r = region_kill_internal (0);
41221308Sache
41321308Sache  rl_mark = om;
41421308Sache  rl_point = op;
41521308Sache
41621308Sache  return r;
41721308Sache}
41821308Sache
41921308Sacheint
42021308Sacherl_copy_forward_word (count, key)
42121308Sache     int count, key;
42221308Sache{
42321308Sache  if (count < 0)
42421308Sache    return (rl_copy_backward_word (-count, key));
42521308Sache
42621308Sache  return (_rl_copy_word_as_kill (count, 1));
42721308Sache}
42821308Sache
42921308Sacheint
43021308Sacherl_copy_backward_word (count, key)
43121308Sache     int count, key;
43221308Sache{
43321308Sache  if (count < 0)
43421308Sache    return (rl_copy_forward_word (-count, key));
43521308Sache
43621308Sache  return (_rl_copy_word_as_kill (count, -1));
43721308Sache}
43821308Sache
43921308Sache/* Yank back the last killed text.  This ignores arguments. */
44021308Sacheint
44121308Sacherl_yank (count, ignore)
44221308Sache     int count, ignore;
44321308Sache{
44421308Sache  if (rl_kill_ring == 0)
44521308Sache    {
44621308Sache      _rl_abort_internal ();
44721308Sache      return -1;
44821308Sache    }
44921308Sache
45021308Sache  _rl_set_mark_at_pos (rl_point);
45121308Sache  rl_insert_text (rl_kill_ring[rl_kill_index]);
45221308Sache  return 0;
45321308Sache}
45421308Sache
45521308Sache/* If the last command was yank, or yank_pop, and the text just
45621308Sache   before point is identical to the current kill item, then
45721308Sache   delete that text from the line, rotate the index down, and
45821308Sache   yank back some other text. */
45921308Sacheint
46021308Sacherl_yank_pop (count, key)
46121308Sache     int count, key;
46221308Sache{
46321308Sache  int l, n;
46421308Sache
46521308Sache  if (((rl_last_func != rl_yank_pop) && (rl_last_func != rl_yank)) ||
46621308Sache      !rl_kill_ring)
46721308Sache    {
46821308Sache      _rl_abort_internal ();
46921308Sache      return -1;
47021308Sache    }
47121308Sache
47221308Sache  l = strlen (rl_kill_ring[rl_kill_index]);
47321308Sache  n = rl_point - l;
47421308Sache  if (n >= 0 && STREQN (rl_line_buffer + n, rl_kill_ring[rl_kill_index], l))
47521308Sache    {
47621308Sache      rl_delete_text (n, rl_point);
47721308Sache      rl_point = n;
47821308Sache      rl_kill_index--;
47921308Sache      if (rl_kill_index < 0)
48021308Sache	rl_kill_index = rl_kill_ring_length - 1;
48121308Sache      rl_yank (1, 0);
48221308Sache      return 0;
48321308Sache    }
48421308Sache  else
48521308Sache    {
48621308Sache      _rl_abort_internal ();
48721308Sache      return -1;
48821308Sache    }
48921308Sache}
49021308Sache
49135486Sache/* Yank the COUNTh argument from the previous history line, skipping
49235486Sache   HISTORY_SKIP lines before looking for the `previous line'. */
49335486Sachestatic int
49435486Sacherl_yank_nth_arg_internal (count, ignore, history_skip)
49535486Sache     int count, ignore, history_skip;
49621308Sache{
49721308Sache  register HIST_ENTRY *entry;
49821308Sache  char *arg;
49958310Sache  int i, pos;
50021308Sache
50158310Sache  pos = where_history ();
50258310Sache
50335486Sache  if (history_skip)
50435486Sache    {
50535486Sache      for (i = 0; i < history_skip; i++)
50635486Sache	entry = previous_history ();
50735486Sache    }
50835486Sache
50921308Sache  entry = previous_history ();
51058310Sache
51158310Sache  history_set_pos (pos);
51258310Sache
51358310Sache  if (entry == 0)
51435486Sache    {
51521308Sache      ding ();
51621308Sache      return -1;
51721308Sache    }
51821308Sache
51921308Sache  arg = history_arg_extract (count, count, entry->line);
52021308Sache  if (!arg || !*arg)
52121308Sache    {
52221308Sache      ding ();
52321308Sache      return -1;
52421308Sache    }
52521308Sache
52621308Sache  rl_begin_undo_group ();
52721308Sache
52821308Sache#if defined (VI_MODE)
52921308Sache  /* Vi mode always inserts a space before yanking the argument, and it
53021308Sache     inserts it right *after* rl_point. */
53121308Sache  if (rl_editing_mode == vi_mode)
53221308Sache    {
53326497Sache      rl_vi_append_mode (1, ignore);
53421308Sache      rl_insert_text (" ");
53521308Sache    }
53621308Sache#endif /* VI_MODE */
53721308Sache
53821308Sache  rl_insert_text (arg);
53921308Sache  free (arg);
54021308Sache
54121308Sache  rl_end_undo_group ();
54221308Sache  return 0;
54321308Sache}
54421308Sache
54535486Sache/* Yank the COUNTth argument from the previous history line. */
54635486Sacheint
54735486Sacherl_yank_nth_arg (count, ignore)
54835486Sache     int count, ignore;
54935486Sache{
55035486Sache  return (rl_yank_nth_arg_internal (count, ignore, 0));
55135486Sache}
55235486Sache
55321308Sache/* Yank the last argument from the previous history line.  This `knows'
55421308Sache   how rl_yank_nth_arg treats a count of `$'.  With an argument, this
55521308Sache   behaves the same as rl_yank_nth_arg. */
55621308Sacheint
55721308Sacherl_yank_last_arg (count, key)
55821308Sache     int count, key;
55921308Sache{
56035486Sache  static int history_skip = 0;
56135486Sache  static int explicit_arg_p = 0;
56235486Sache  static int count_passed = 1;
56335486Sache  static int direction = 1;
56447558Sache  static int undo_needed = 0;
56547558Sache  int retval;
56635486Sache
56735486Sache  if (rl_last_func != rl_yank_last_arg)
56835486Sache    {
56935486Sache      history_skip = 0;
57035486Sache      explicit_arg_p = rl_explicit_arg;
57135486Sache      count_passed = count;
57235486Sache      direction = 1;
57335486Sache    }
57421308Sache  else
57535486Sache    {
57647558Sache      if (undo_needed)
57747558Sache	rl_do_undo ();
57835486Sache      if (count < 1)
57935486Sache        direction = -direction;
58035486Sache      history_skip += direction;
58135486Sache      if (history_skip < 0)
58235486Sache	history_skip = 0;
58335486Sache    }
58435486Sache
58535486Sache  if (explicit_arg_p)
58647558Sache    retval = rl_yank_nth_arg_internal (count_passed, key, history_skip);
58735486Sache  else
58847558Sache    retval = rl_yank_nth_arg_internal ('$', key, history_skip);
58947558Sache
59047558Sache  undo_needed = retval == 0;
59147558Sache  return retval;
59221308Sache}
59335486Sache
59435486Sache/* A special paste command for users of Cygnus's cygwin32. */
59535486Sache#if defined (__CYGWIN32__)
59635486Sache#include <windows.h>
59735486Sache
59835486Sacheint
59935486Sacherl_paste_from_clipboard (count, key)
60035486Sache     int count, key;
60135486Sache{
60235486Sache  char *data, *ptr;
60335486Sache  int len;
60435486Sache
60535486Sache  if (OpenClipboard (NULL) == 0)
60635486Sache    return (0);
60735486Sache
60835486Sache  data = (char *)GetClipboardData (CF_TEXT);
60935486Sache  if (data)
61035486Sache    {
61135486Sache      ptr = strchr (data, '\r');
61235486Sache      if (ptr)
61335486Sache	{
61435486Sache	  len = ptr - data;
61535486Sache	  ptr = xmalloc (len + 1);
61635486Sache	  ptr[len] = '\0';
61735486Sache	  strncpy (ptr, data, len);
61835486Sache	}
61935486Sache      else
62035486Sache        ptr = data;
62135486Sache      rl_insert_text (ptr);
62235486Sache      if (ptr != data)
62335486Sache	free (ptr);
62435486Sache      CloseClipboard ();
62535486Sache    }
62635486Sache  return (0);
62735486Sache}
62835486Sache#endif /* __CYGWIN32__ */
629