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