Imported from ../bash-2.0.tar.gz.
[platform/upstream/bash.git] / lib / readline / kill.c
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 1, 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    675 Mass Ave, Cambridge, MA 02139, 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 extern int _rl_last_command_was_kill;
50 extern int rl_editing_mode;
51 extern int rl_explicit_arg;
52 extern Function *rl_last_func;
53
54 extern void _rl_init_argument ();
55 extern int _rl_set_mark_at_pos ();
56 extern void _rl_abort_internal ();
57
58 extern char *xmalloc (), *xrealloc ();
59
60 /* **************************************************************** */
61 /*                                                                  */
62 /*                      Killing Mechanism                           */
63 /*                                                                  */
64 /* **************************************************************** */
65
66 /* What we assume for a max number of kills. */
67 #define DEFAULT_MAX_KILLS 10
68
69 /* The real variable to look at to find out when to flush kills. */
70 static int rl_max_kills =  DEFAULT_MAX_KILLS;
71
72 /* Where to store killed text. */
73 static char **rl_kill_ring = (char **)NULL;
74
75 /* Where we are in the kill ring. */
76 static int rl_kill_index;
77
78 /* How many slots we have in the kill ring. */
79 static int rl_kill_ring_length;
80
81 /* How to say that you only want to save a certain amount
82    of kill material. */
83 int
84 rl_set_retained_kills (num)
85      int num;
86 {
87   return 0;
88 }
89
90 /* Add TEXT to the kill ring, allocating a new kill ring slot as necessary.
91    This uses TEXT directly, so the caller must not free it.  If APPEND is
92    non-zero, and the last command was a kill, the text is appended to the
93    current kill ring slot, otherwise prepended. */
94 static int
95 _rl_copy_to_kill_ring (text, append)
96      char *text;
97      int append;
98 {
99   char *old, *new;
100   int slot;
101
102   /* First, find the slot to work with. */
103   if (_rl_last_command_was_kill == 0)
104     {
105       /* Get a new slot.  */
106       if (rl_kill_ring == 0)
107         {
108           /* If we don't have any defined, then make one. */
109           rl_kill_ring = (char **)
110             xmalloc (((rl_kill_ring_length = 1) + 1) * sizeof (char *));
111           rl_kill_ring[slot = 0] = (char *)NULL;
112         }
113       else
114         {
115           /* We have to add a new slot on the end, unless we have
116              exceeded the max limit for remembering kills. */
117           slot = rl_kill_ring_length;
118           if (slot == rl_max_kills)
119             {
120               register int i;
121               free (rl_kill_ring[0]);
122               for (i = 0; i < slot; i++)
123                 rl_kill_ring[i] = rl_kill_ring[i + 1];
124             }
125           else
126             {
127               slot = rl_kill_ring_length += 1;
128               rl_kill_ring = (char **)xrealloc (rl_kill_ring, slot * sizeof (char *));
129             }
130           rl_kill_ring[--slot] = (char *)NULL;
131         }
132     }
133   else
134     slot = rl_kill_ring_length - 1;
135
136   /* If the last command was a kill, prepend or append. */
137   if (_rl_last_command_was_kill && rl_editing_mode != vi_mode)
138     {
139       old = rl_kill_ring[slot];
140       new = xmalloc (1 + strlen (old) + strlen (text));
141
142       if (append)
143         {
144           strcpy (new, old);
145           strcat (new, text);
146         }
147       else
148         {
149           strcpy (new, text);
150           strcat (new, old);
151         }
152       free (old);
153       free (text);
154       rl_kill_ring[slot] = new;
155     }
156   else
157     rl_kill_ring[slot] = text;
158
159   rl_kill_index = slot;
160   return 0;
161 }
162
163 /* The way to kill something.  This appends or prepends to the last
164    kill, if the last command was a kill command.  if FROM is less
165    than TO, then the text is appended, otherwise prepended.  If the
166    last command was not a kill command, then a new slot is made for
167    this kill. */
168 int
169 rl_kill_text (from, to)
170      int from, to;
171 {
172   char *text;
173
174   /* Is there anything to kill? */
175   if (from == to)
176     {
177       _rl_last_command_was_kill++;
178       return 0;
179     }
180
181   text = rl_copy_text (from, to);
182
183   /* Delete the copied text from the line. */
184   rl_delete_text (from, to);
185
186   _rl_copy_to_kill_ring (text, from < to);
187
188   _rl_last_command_was_kill++;
189   return 0;
190 }
191
192 /* Now REMEMBER!  In order to do prepending or appending correctly, kill
193    commands always make rl_point's original position be the FROM argument,
194    and rl_point's extent be the TO argument. */
195
196 /* **************************************************************** */
197 /*                                                                  */
198 /*                      Killing Commands                            */
199 /*                                                                  */
200 /* **************************************************************** */
201
202 /* Delete the word at point, saving the text in the kill ring. */
203 int
204 rl_kill_word (count, key)
205      int count, key;
206 {
207   int orig_point = rl_point;
208
209   if (count < 0)
210     return (rl_backward_kill_word (-count, key));
211   else
212     {
213       rl_forward_word (count, key);
214
215       if (rl_point != orig_point)
216         rl_kill_text (orig_point, rl_point);
217
218       rl_point = orig_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 = rl_point;
229
230   if (count < 0)
231     return (rl_kill_word (-count, ignore));
232   else
233     {
234       rl_backward_word (count, ignore);
235
236       if (rl_point != orig_point)
237         rl_kill_text (orig_point, rl_point);
238     }
239   return 0;
240 }
241
242 /* Kill from here to the end of the line.  If DIRECTION is negative, kill
243    back to the line start instead. */
244 int
245 rl_kill_line (direction, ignore)
246      int direction, ignore;
247 {
248   int orig_point = rl_point;
249
250   if (direction < 0)
251     return (rl_backward_kill_line (1, ignore));
252   else
253     {
254       rl_end_of_line (1, ignore);
255       if (orig_point != rl_point)
256         rl_kill_text (orig_point, rl_point);
257       rl_point = orig_point;
258     }
259   return 0;
260 }
261
262 /* Kill backwards to the start of the line.  If DIRECTION is negative, kill
263    forwards to the line end instead. */
264 int
265 rl_backward_kill_line (direction, ignore)
266      int direction, ignore;
267 {
268   int orig_point = rl_point;
269
270   if (direction < 0)
271     return (rl_kill_line (1, ignore));
272   else
273     {
274       if (!rl_point)
275         ding ();
276       else
277         {
278           rl_beg_of_line (1, ignore);
279           rl_kill_text (orig_point, rl_point);
280         }
281     }
282   return 0;
283 }
284
285 /* Kill the whole line, no matter where point is. */
286 int
287 rl_kill_full_line (count, ignore)
288      int count, ignore;
289 {
290   rl_begin_undo_group ();
291   rl_point = 0;
292   rl_kill_text (rl_point, rl_end);
293   rl_end_undo_group ();
294   return 0;
295 }
296
297 /* The next two functions mimic unix line editing behaviour, except they
298    save the deleted text on the kill ring.  This is safer than not saving
299    it, and since we have a ring, nobody should get screwed. */
300
301 /* This does what C-w does in Unix.  We can't prevent people from
302    using behaviour that they expect. */
303 int
304 rl_unix_word_rubout (count, key)
305      int count, key;
306 {
307   int orig_point;
308
309   if (rl_point == 0)
310     ding ();
311   else
312     {
313       orig_point = rl_point;
314       if (count <= 0)
315         count = 1;
316
317       while (count--)
318         {
319           while (rl_point && whitespace (rl_line_buffer[rl_point - 1]))
320             rl_point--;
321
322           while (rl_point && (whitespace (rl_line_buffer[rl_point - 1]) == 0))
323             rl_point--;
324         }
325
326       rl_kill_text (orig_point, rl_point);
327     }
328   return 0;
329 }
330
331 /* Here is C-u doing what Unix does.  You don't *have* to use these
332    key-bindings.  We have a choice of killing the entire line, or
333    killing from where we are to the start of the line.  We choose the
334    latter, because if you are a Unix weenie, then you haven't backspaced
335    into the line at all, and if you aren't, then you know what you are
336    doing. */
337 int
338 rl_unix_line_discard (count, key)
339      int count, key;
340 {
341   if (rl_point == 0)
342     ding ();
343   else
344     {
345       rl_kill_text (rl_point, 0);
346       rl_point = 0;
347     }
348   return 0;
349 }
350
351 /* Copy the text in the `region' to the kill ring.  If DELETE is non-zero,
352    delete the text from the line as well. */
353 static int
354 region_kill_internal (delete)
355      int delete;
356 {
357   char *text;
358
359   if (rl_mark == rl_point)
360     {
361       _rl_last_command_was_kill++;
362       return 0;
363     }
364
365   text = rl_copy_text (rl_point, rl_mark);
366   if (delete)
367     rl_delete_text (rl_point, rl_mark);
368   _rl_copy_to_kill_ring (text, rl_point < rl_mark);
369
370   _rl_last_command_was_kill++;
371   return 0;
372 }
373
374 /* Copy the text in the region to the kill ring. */
375 int
376 rl_copy_region_to_kill (count, ignore)
377      int count, ignore;
378 {
379   return (region_kill_internal (0));
380 }
381
382 /* Kill the text between the point and mark. */
383 int
384 rl_kill_region (count, ignore)
385      int count, ignore;
386 {
387   return (region_kill_internal (1));
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 COUNTth argument from the previous history line. */
494 int
495 rl_yank_nth_arg (count, ignore)
496      int count, ignore;
497 {
498   register HIST_ENTRY *entry;
499   char *arg;
500
501   entry = previous_history ();
502   if (entry)
503     next_history ();
504   else
505     {
506       ding ();
507       return -1;
508     }
509
510   arg = history_arg_extract (count, count, entry->line);
511   if (!arg || !*arg)
512     {
513       ding ();
514       return -1;
515     }
516
517   rl_begin_undo_group ();
518
519 #if defined (VI_MODE)
520   /* Vi mode always inserts a space before yanking the argument, and it
521      inserts it right *after* rl_point. */
522   if (rl_editing_mode == vi_mode)
523     {
524       rl_vi_append_mode ();
525       rl_insert_text (" ");
526     }
527 #endif /* VI_MODE */
528
529   rl_insert_text (arg);
530   free (arg);
531
532   rl_end_undo_group ();
533   return 0;
534 }
535
536 /* Yank the last argument from the previous history line.  This `knows'
537    how rl_yank_nth_arg treats a count of `$'.  With an argument, this
538    behaves the same as rl_yank_nth_arg. */
539 int
540 rl_yank_last_arg (count, key)
541      int count, key;
542 {
543   if (rl_explicit_arg)
544     return (rl_yank_nth_arg (count, key));
545   else
546     return (rl_yank_nth_arg ('$', key));
547 }