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