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
73119610Sachestatic int _rl_copy_to_kill_ring PARAMS((char *, int));
74119610Sachestatic int region_kill_internal PARAMS((int));
75119610Sachestatic int _rl_copy_word_as_kill PARAMS((int, int));
76119610Sachestatic int rl_yank_nth_arg_internal PARAMS((int, int, int));
77119610Sache
7821308Sache/* How to say that you only want to save a certain amount
7921308Sache   of kill material. */
8021308Sacheint
8121308Sacherl_set_retained_kills (num)
8221308Sache     int num;
8321308Sache{
8421308Sache  return 0;
8521308Sache}
8621308Sache
8721308Sache/* Add TEXT to the kill ring, allocating a new kill ring slot as necessary.
8821308Sache   This uses TEXT directly, so the caller must not free it.  If APPEND is
8921308Sache   non-zero, and the last command was a kill, the text is appended to the
9021308Sache   current kill ring slot, otherwise prepended. */
9121308Sachestatic int
9221308Sache_rl_copy_to_kill_ring (text, append)
9321308Sache     char *text;
9421308Sache     int append;
9521308Sache{
9621308Sache  char *old, *new;
9721308Sache  int slot;
9821308Sache
9921308Sache  /* First, find the slot to work with. */
10021308Sache  if (_rl_last_command_was_kill == 0)
10121308Sache    {
10221308Sache      /* Get a new slot.  */
10321308Sache      if (rl_kill_ring == 0)
10421308Sache	{
10521308Sache	  /* If we don't have any defined, then make one. */
10621308Sache	  rl_kill_ring = (char **)
10721308Sache	    xmalloc (((rl_kill_ring_length = 1) + 1) * sizeof (char *));
10821308Sache	  rl_kill_ring[slot = 0] = (char *)NULL;
10921308Sache	}
11021308Sache      else
11121308Sache	{
11221308Sache	  /* We have to add a new slot on the end, unless we have
11321308Sache	     exceeded the max limit for remembering kills. */
11421308Sache	  slot = rl_kill_ring_length;
11521308Sache	  if (slot == rl_max_kills)
11621308Sache	    {
11721308Sache	      register int i;
11821308Sache	      free (rl_kill_ring[0]);
11921308Sache	      for (i = 0; i < slot; i++)
12021308Sache		rl_kill_ring[i] = rl_kill_ring[i + 1];
12121308Sache	    }
12221308Sache	  else
12321308Sache	    {
12421308Sache	      slot = rl_kill_ring_length += 1;
12521308Sache	      rl_kill_ring = (char **)xrealloc (rl_kill_ring, slot * sizeof (char *));
12621308Sache	    }
12721308Sache	  rl_kill_ring[--slot] = (char *)NULL;
12821308Sache	}
12921308Sache    }
13021308Sache  else
13121308Sache    slot = rl_kill_ring_length - 1;
13221308Sache
13321308Sache  /* If the last command was a kill, prepend or append. */
13421308Sache  if (_rl_last_command_was_kill && rl_editing_mode != vi_mode)
13521308Sache    {
13621308Sache      old = rl_kill_ring[slot];
137119610Sache      new = (char *)xmalloc (1 + strlen (old) + strlen (text));
13821308Sache
13921308Sache      if (append)
14021308Sache	{
14121308Sache	  strcpy (new, old);
14221308Sache	  strcat (new, text);
14321308Sache	}
14421308Sache      else
14521308Sache	{
14621308Sache	  strcpy (new, text);
14721308Sache	  strcat (new, old);
14821308Sache	}
14921308Sache      free (old);
15021308Sache      free (text);
15121308Sache      rl_kill_ring[slot] = new;
15221308Sache    }
15321308Sache  else
15421308Sache    rl_kill_ring[slot] = text;
15521308Sache
15621308Sache  rl_kill_index = slot;
15721308Sache  return 0;
15821308Sache}
15921308Sache
16021308Sache/* The way to kill something.  This appends or prepends to the last
16121308Sache   kill, if the last command was a kill command.  if FROM is less
16221308Sache   than TO, then the text is appended, otherwise prepended.  If the
16321308Sache   last command was not a kill command, then a new slot is made for
16421308Sache   this kill. */
16521308Sacheint
16621308Sacherl_kill_text (from, to)
16721308Sache     int from, to;
16821308Sache{
16921308Sache  char *text;
17021308Sache
17121308Sache  /* Is there anything to kill? */
17221308Sache  if (from == to)
17321308Sache    {
17421308Sache      _rl_last_command_was_kill++;
17521308Sache      return 0;
17621308Sache    }
17721308Sache
17821308Sache  text = rl_copy_text (from, to);
17921308Sache
18021308Sache  /* Delete the copied text from the line. */
18121308Sache  rl_delete_text (from, to);
18221308Sache
18321308Sache  _rl_copy_to_kill_ring (text, from < to);
18421308Sache
18521308Sache  _rl_last_command_was_kill++;
18621308Sache  return 0;
18721308Sache}
18821308Sache
18921308Sache/* Now REMEMBER!  In order to do prepending or appending correctly, kill
19021308Sache   commands always make rl_point's original position be the FROM argument,
19121308Sache   and rl_point's extent be the TO argument. */
19221308Sache
19321308Sache/* **************************************************************** */
19421308Sache/*								    */
19521308Sache/*			Killing Commands			    */
19621308Sache/*								    */
19721308Sache/* **************************************************************** */
19821308Sache
19921308Sache/* Delete the word at point, saving the text in the kill ring. */
20021308Sacheint
20121308Sacherl_kill_word (count, key)
20221308Sache     int count, key;
20321308Sache{
204119610Sache  int orig_point;
20521308Sache
20621308Sache  if (count < 0)
20721308Sache    return (rl_backward_kill_word (-count, key));
20821308Sache  else
20921308Sache    {
210119610Sache      orig_point = rl_point;
21121308Sache      rl_forward_word (count, key);
21221308Sache
21321308Sache      if (rl_point != orig_point)
21421308Sache	rl_kill_text (orig_point, rl_point);
21521308Sache
21621308Sache      rl_point = orig_point;
217119610Sache      if (rl_editing_mode == emacs_mode)
218119610Sache	rl_mark = rl_point;
21921308Sache    }
22021308Sache  return 0;
22121308Sache}
22221308Sache
22321308Sache/* Rubout the word before point, placing it on the kill ring. */
22421308Sacheint
22521308Sacherl_backward_kill_word (count, ignore)
22621308Sache     int count, ignore;
22721308Sache{
228119610Sache  int orig_point;
22921308Sache
23021308Sache  if (count < 0)
23121308Sache    return (rl_kill_word (-count, ignore));
23221308Sache  else
23321308Sache    {
234119610Sache      orig_point = rl_point;
23521308Sache      rl_backward_word (count, ignore);
23621308Sache
23721308Sache      if (rl_point != orig_point)
23821308Sache	rl_kill_text (orig_point, rl_point);
239119610Sache
240119610Sache      if (rl_editing_mode == emacs_mode)
241119610Sache	rl_mark = rl_point;
24221308Sache    }
24321308Sache  return 0;
24421308Sache}
24521308Sache
24621308Sache/* Kill from here to the end of the line.  If DIRECTION is negative, kill
24721308Sache   back to the line start instead. */
24821308Sacheint
24921308Sacherl_kill_line (direction, ignore)
25021308Sache     int direction, ignore;
25121308Sache{
252119610Sache  int orig_point;
25321308Sache
25421308Sache  if (direction < 0)
25521308Sache    return (rl_backward_kill_line (1, ignore));
25621308Sache  else
25721308Sache    {
258119610Sache      orig_point = rl_point;
25921308Sache      rl_end_of_line (1, ignore);
26021308Sache      if (orig_point != rl_point)
26121308Sache	rl_kill_text (orig_point, rl_point);
26221308Sache      rl_point = orig_point;
263119610Sache      if (rl_editing_mode == emacs_mode)
264119610Sache	rl_mark = rl_point;
26521308Sache    }
26621308Sache  return 0;
26721308Sache}
26821308Sache
26921308Sache/* Kill backwards to the start of the line.  If DIRECTION is negative, kill
27021308Sache   forwards to the line end instead. */
27121308Sacheint
27221308Sacherl_backward_kill_line (direction, ignore)
27321308Sache     int direction, ignore;
27421308Sache{
275119610Sache  int orig_point;
27621308Sache
27721308Sache  if (direction < 0)
27821308Sache    return (rl_kill_line (1, ignore));
27921308Sache  else
28021308Sache    {
28121308Sache      if (!rl_point)
28275406Sache	rl_ding ();
28321308Sache      else
28421308Sache	{
285119610Sache	  orig_point = rl_point;
28621308Sache	  rl_beg_of_line (1, ignore);
287119610Sache	  if (rl_point != orig_point)
288119610Sache	    rl_kill_text (orig_point, rl_point);
289119610Sache	  if (rl_editing_mode == emacs_mode)
290119610Sache	    rl_mark = rl_point;
29121308Sache	}
29221308Sache    }
29321308Sache  return 0;
29421308Sache}
29521308Sache
29621308Sache/* Kill the whole line, no matter where point is. */
29721308Sacheint
29821308Sacherl_kill_full_line (count, ignore)
29921308Sache     int count, ignore;
30021308Sache{
30121308Sache  rl_begin_undo_group ();
30221308Sache  rl_point = 0;
30321308Sache  rl_kill_text (rl_point, rl_end);
304119610Sache  rl_mark = 0;
30521308Sache  rl_end_undo_group ();
30621308Sache  return 0;
30721308Sache}
30821308Sache
30921308Sache/* The next two functions mimic unix line editing behaviour, except they
31021308Sache   save the deleted text on the kill ring.  This is safer than not saving
31121308Sache   it, and since we have a ring, nobody should get screwed. */
31221308Sache
31321308Sache/* This does what C-w does in Unix.  We can't prevent people from
31421308Sache   using behaviour that they expect. */
31521308Sacheint
31621308Sacherl_unix_word_rubout (count, key)
31721308Sache     int count, key;
31821308Sache{
31921308Sache  int orig_point;
32021308Sache
32121308Sache  if (rl_point == 0)
32275406Sache    rl_ding ();
32321308Sache  else
32421308Sache    {
32521308Sache      orig_point = rl_point;
32621308Sache      if (count <= 0)
32721308Sache	count = 1;
32821308Sache
32921308Sache      while (count--)
33021308Sache	{
33121308Sache	  while (rl_point && whitespace (rl_line_buffer[rl_point - 1]))
33221308Sache	    rl_point--;
33321308Sache
33421308Sache	  while (rl_point && (whitespace (rl_line_buffer[rl_point - 1]) == 0))
33521308Sache	    rl_point--;
33621308Sache	}
33721308Sache
33821308Sache      rl_kill_text (orig_point, rl_point);
339119610Sache      if (rl_editing_mode == emacs_mode)
340119610Sache	rl_mark = rl_point;
34121308Sache    }
342136644Sache
34321308Sache  return 0;
34421308Sache}
34521308Sache
346136644Sache/* This deletes one filename component in a Unix pathname.  That is, it
347136644Sache   deletes backward to directory separator (`/') or whitespace.  */
348136644Sacheint
349136644Sacherl_unix_filename_rubout (count, key)
350136644Sache     int count, key;
351136644Sache{
352136644Sache  int orig_point, c;
353136644Sache
354136644Sache  if (rl_point == 0)
355136644Sache    rl_ding ();
356136644Sache  else
357136644Sache    {
358136644Sache      orig_point = rl_point;
359136644Sache      if (count <= 0)
360136644Sache	count = 1;
361136644Sache
362136644Sache      while (count--)
363136644Sache	{
364136644Sache	  c = rl_line_buffer[rl_point - 1];
365136644Sache	  while (rl_point && (whitespace (c) || c == '/'))
366136644Sache	    {
367136644Sache	      rl_point--;
368136644Sache	      c = rl_line_buffer[rl_point - 1];
369136644Sache	    }
370136644Sache
371136644Sache	  while (rl_point && (whitespace (c) == 0) && c != '/')
372136644Sache	    {
373136644Sache	      rl_point--;
374136644Sache	      c = rl_line_buffer[rl_point - 1];
375136644Sache	    }
376136644Sache	}
377136644Sache
378136644Sache      rl_kill_text (orig_point, rl_point);
379136644Sache      if (rl_editing_mode == emacs_mode)
380136644Sache	rl_mark = rl_point;
381136644Sache    }
382136644Sache
383136644Sache  return 0;
384136644Sache}
385136644Sache
38621308Sache/* Here is C-u doing what Unix does.  You don't *have* to use these
38721308Sache   key-bindings.  We have a choice of killing the entire line, or
38821308Sache   killing from where we are to the start of the line.  We choose the
38921308Sache   latter, because if you are a Unix weenie, then you haven't backspaced
39021308Sache   into the line at all, and if you aren't, then you know what you are
39121308Sache   doing. */
39221308Sacheint
39321308Sacherl_unix_line_discard (count, key)
39421308Sache     int count, key;
39521308Sache{
39621308Sache  if (rl_point == 0)
39775406Sache    rl_ding ();
39821308Sache  else
39921308Sache    {
40021308Sache      rl_kill_text (rl_point, 0);
40121308Sache      rl_point = 0;
402119610Sache      if (rl_editing_mode == emacs_mode)
403119610Sache	rl_mark = rl_point;
40421308Sache    }
40521308Sache  return 0;
40621308Sache}
40721308Sache
40821308Sache/* Copy the text in the `region' to the kill ring.  If DELETE is non-zero,
40921308Sache   delete the text from the line as well. */
41021308Sachestatic int
41121308Sacheregion_kill_internal (delete)
41221308Sache     int delete;
41321308Sache{
41421308Sache  char *text;
41521308Sache
416119610Sache  if (rl_mark != rl_point)
41721308Sache    {
418119610Sache      text = rl_copy_text (rl_point, rl_mark);
419119610Sache      if (delete)
420119610Sache	rl_delete_text (rl_point, rl_mark);
421119610Sache      _rl_copy_to_kill_ring (text, rl_point < rl_mark);
42221308Sache    }
42321308Sache
42421308Sache  _rl_last_command_was_kill++;
42521308Sache  return 0;
42621308Sache}
42721308Sache
42821308Sache/* Copy the text in the region to the kill ring. */
42921308Sacheint
43021308Sacherl_copy_region_to_kill (count, ignore)
43121308Sache     int count, ignore;
43221308Sache{
43321308Sache  return (region_kill_internal (0));
43421308Sache}
43521308Sache
43621308Sache/* Kill the text between the point and mark. */
43721308Sacheint
43821308Sacherl_kill_region (count, ignore)
43921308Sache     int count, ignore;
44021308Sache{
44158310Sache  int r, npoint;
44226497Sache
44358310Sache  npoint = (rl_point < rl_mark) ? rl_point : rl_mark;
44426497Sache  r = region_kill_internal (1);
44526497Sache  _rl_fix_point (1);
44658310Sache  rl_point = npoint;
44726497Sache  return r;
44821308Sache}
44921308Sache
45021308Sache/* Copy COUNT words to the kill ring.  DIR says which direction we look
45121308Sache   to find the words. */
45221308Sachestatic int
45321308Sache_rl_copy_word_as_kill (count, dir)
45421308Sache     int count, dir;
45521308Sache{
45621308Sache  int om, op, r;
45721308Sache
45821308Sache  om = rl_mark;
45921308Sache  op = rl_point;
46021308Sache
46121308Sache  if (dir > 0)
46221308Sache    rl_forward_word (count, 0);
46321308Sache  else
46421308Sache    rl_backward_word (count, 0);
46521308Sache
46621308Sache  rl_mark = rl_point;
46721308Sache
46821308Sache  if (dir > 0)
46921308Sache    rl_backward_word (count, 0);
47021308Sache  else
47121308Sache    rl_forward_word (count, 0);
47221308Sache
47321308Sache  r = region_kill_internal (0);
47421308Sache
47521308Sache  rl_mark = om;
47621308Sache  rl_point = op;
47721308Sache
47821308Sache  return r;
47921308Sache}
48021308Sache
48121308Sacheint
48221308Sacherl_copy_forward_word (count, key)
48321308Sache     int count, key;
48421308Sache{
48521308Sache  if (count < 0)
48621308Sache    return (rl_copy_backward_word (-count, key));
48721308Sache
48821308Sache  return (_rl_copy_word_as_kill (count, 1));
48921308Sache}
49021308Sache
49121308Sacheint
49221308Sacherl_copy_backward_word (count, key)
49321308Sache     int count, key;
49421308Sache{
49521308Sache  if (count < 0)
49621308Sache    return (rl_copy_forward_word (-count, key));
49721308Sache
49821308Sache  return (_rl_copy_word_as_kill (count, -1));
49921308Sache}
50021308Sache
50121308Sache/* Yank back the last killed text.  This ignores arguments. */
50221308Sacheint
50321308Sacherl_yank (count, ignore)
50421308Sache     int count, ignore;
50521308Sache{
50621308Sache  if (rl_kill_ring == 0)
50721308Sache    {
50821308Sache      _rl_abort_internal ();
50921308Sache      return -1;
51021308Sache    }
51121308Sache
51221308Sache  _rl_set_mark_at_pos (rl_point);
51321308Sache  rl_insert_text (rl_kill_ring[rl_kill_index]);
51421308Sache  return 0;
51521308Sache}
51621308Sache
51721308Sache/* If the last command was yank, or yank_pop, and the text just
51821308Sache   before point is identical to the current kill item, then
51921308Sache   delete that text from the line, rotate the index down, and
52021308Sache   yank back some other text. */
52121308Sacheint
52221308Sacherl_yank_pop (count, key)
52321308Sache     int count, key;
52421308Sache{
52521308Sache  int l, n;
52621308Sache
52721308Sache  if (((rl_last_func != rl_yank_pop) && (rl_last_func != rl_yank)) ||
52821308Sache      !rl_kill_ring)
52921308Sache    {
53021308Sache      _rl_abort_internal ();
53121308Sache      return -1;
53221308Sache    }
53321308Sache
53421308Sache  l = strlen (rl_kill_ring[rl_kill_index]);
53521308Sache  n = rl_point - l;
53621308Sache  if (n >= 0 && STREQN (rl_line_buffer + n, rl_kill_ring[rl_kill_index], l))
53721308Sache    {
53821308Sache      rl_delete_text (n, rl_point);
53921308Sache      rl_point = n;
54021308Sache      rl_kill_index--;
54121308Sache      if (rl_kill_index < 0)
54221308Sache	rl_kill_index = rl_kill_ring_length - 1;
54321308Sache      rl_yank (1, 0);
54421308Sache      return 0;
54521308Sache    }
54621308Sache  else
54721308Sache    {
54821308Sache      _rl_abort_internal ();
54921308Sache      return -1;
55021308Sache    }
55121308Sache}
55221308Sache
55335486Sache/* Yank the COUNTh argument from the previous history line, skipping
55435486Sache   HISTORY_SKIP lines before looking for the `previous line'. */
55535486Sachestatic int
55635486Sacherl_yank_nth_arg_internal (count, ignore, history_skip)
55735486Sache     int count, ignore, history_skip;
55821308Sache{
55921308Sache  register HIST_ENTRY *entry;
56021308Sache  char *arg;
56158310Sache  int i, pos;
56221308Sache
56358310Sache  pos = where_history ();
56458310Sache
56535486Sache  if (history_skip)
56635486Sache    {
56735486Sache      for (i = 0; i < history_skip; i++)
56835486Sache	entry = previous_history ();
56935486Sache    }
57035486Sache
57121308Sache  entry = previous_history ();
57258310Sache
57358310Sache  history_set_pos (pos);
57458310Sache
57558310Sache  if (entry == 0)
57635486Sache    {
57775406Sache      rl_ding ();
57821308Sache      return -1;
57921308Sache    }
58021308Sache
58121308Sache  arg = history_arg_extract (count, count, entry->line);
58221308Sache  if (!arg || !*arg)
58321308Sache    {
58475406Sache      rl_ding ();
585165670Sache      FREE (arg);
58621308Sache      return -1;
58721308Sache    }
58821308Sache
58921308Sache  rl_begin_undo_group ();
59021308Sache
591119610Sache  _rl_set_mark_at_pos (rl_point);
592119610Sache
59321308Sache#if defined (VI_MODE)
59421308Sache  /* Vi mode always inserts a space before yanking the argument, and it
59521308Sache     inserts it right *after* rl_point. */
59621308Sache  if (rl_editing_mode == vi_mode)
59721308Sache    {
59826497Sache      rl_vi_append_mode (1, ignore);
59921308Sache      rl_insert_text (" ");
60021308Sache    }
60121308Sache#endif /* VI_MODE */
60221308Sache
60321308Sache  rl_insert_text (arg);
60421308Sache  free (arg);
60521308Sache
60621308Sache  rl_end_undo_group ();
60721308Sache  return 0;
60821308Sache}
60921308Sache
61035486Sache/* Yank the COUNTth argument from the previous history line. */
61135486Sacheint
61235486Sacherl_yank_nth_arg (count, ignore)
61335486Sache     int count, ignore;
61435486Sache{
61535486Sache  return (rl_yank_nth_arg_internal (count, ignore, 0));
61635486Sache}
61735486Sache
61821308Sache/* Yank the last argument from the previous history line.  This `knows'
61921308Sache   how rl_yank_nth_arg treats a count of `$'.  With an argument, this
62021308Sache   behaves the same as rl_yank_nth_arg. */
62121308Sacheint
62221308Sacherl_yank_last_arg (count, key)
62321308Sache     int count, key;
62421308Sache{
62535486Sache  static int history_skip = 0;
62635486Sache  static int explicit_arg_p = 0;
62735486Sache  static int count_passed = 1;
62835486Sache  static int direction = 1;
62947558Sache  static int undo_needed = 0;
63047558Sache  int retval;
63135486Sache
63235486Sache  if (rl_last_func != rl_yank_last_arg)
63335486Sache    {
63435486Sache      history_skip = 0;
63535486Sache      explicit_arg_p = rl_explicit_arg;
63635486Sache      count_passed = count;
63735486Sache      direction = 1;
63835486Sache    }
63921308Sache  else
64035486Sache    {
64147558Sache      if (undo_needed)
64247558Sache	rl_do_undo ();
64335486Sache      if (count < 1)
64435486Sache        direction = -direction;
64535486Sache      history_skip += direction;
64635486Sache      if (history_skip < 0)
64735486Sache	history_skip = 0;
64835486Sache    }
64935486Sache
65035486Sache  if (explicit_arg_p)
65147558Sache    retval = rl_yank_nth_arg_internal (count_passed, key, history_skip);
65235486Sache  else
65347558Sache    retval = rl_yank_nth_arg_internal ('$', key, history_skip);
65447558Sache
65547558Sache  undo_needed = retval == 0;
65647558Sache  return retval;
65721308Sache}
65835486Sache
65935486Sache/* A special paste command for users of Cygnus's cygwin32. */
66075406Sache#if defined (__CYGWIN__)
66135486Sache#include <windows.h>
66235486Sache
66335486Sacheint
66435486Sacherl_paste_from_clipboard (count, key)
66535486Sache     int count, key;
66635486Sache{
66735486Sache  char *data, *ptr;
66835486Sache  int len;
66935486Sache
67035486Sache  if (OpenClipboard (NULL) == 0)
67135486Sache    return (0);
67235486Sache
67335486Sache  data = (char *)GetClipboardData (CF_TEXT);
67435486Sache  if (data)
67535486Sache    {
67635486Sache      ptr = strchr (data, '\r');
67735486Sache      if (ptr)
67835486Sache	{
67935486Sache	  len = ptr - data;
680119610Sache	  ptr = (char *)xmalloc (len + 1);
68135486Sache	  ptr[len] = '\0';
68235486Sache	  strncpy (ptr, data, len);
68335486Sache	}
68435486Sache      else
68535486Sache        ptr = data;
686119610Sache      _rl_set_mark_at_pos (rl_point);
68735486Sache      rl_insert_text (ptr);
68835486Sache      if (ptr != data)
68935486Sache	free (ptr);
69035486Sache      CloseClipboard ();
69135486Sache    }
69235486Sache  return (0);
69335486Sache}
69475406Sache#endif /* __CYGWIN__ */
695