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