1: /* kill.c -- kill ring management. */
2:
3: /* Copyright (C) 1994-2020 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 (int num)
82: {
83: return 0;
84: }
85:
86: /* Add TEXT to the kill ring, allocating a new kill ring slot as necessary.
87: This uses TEXT directly, so the caller must not free it. If APPEND is
88: non-zero, and the last command was a kill, the text is appended to the
89: current kill ring slot, otherwise prepended. */
90: static int
91: _rl_copy_to_kill_ring (char *text, int append)
92: {
93: char *old, *new;
94: int slot;
95:
96: /* First, find the slot to work with. */
97: if (_rl_last_command_was_kill == 0 || rl_kill_ring == 0)
98: {
99: /* Get a new slot. */
100: if (rl_kill_ring == 0)
101: {
102: /* If we don't have any defined, then make one. */
103: rl_kill_ring = (char **)
104: xmalloc (((rl_kill_ring_length = 1) + 1) * sizeof (char *));
105: rl_kill_ring[slot = 0] = (char *)NULL;
106: }
107: else
108: {
109: /* We have to add a new slot on the end, unless we have
110: exceeded the max limit for remembering kills. */
111: slot = rl_kill_ring_length;
112: if (slot == rl_max_kills)
113: {
114: register int i;
115: xfree (rl_kill_ring[0]);
116: for (i = 0; i < slot; i++)
117: rl_kill_ring[i] = rl_kill_ring[i + 1];
118: }
119: else
120: {
121: slot = rl_kill_ring_length += 1;
122: rl_kill_ring = (char **)xrealloc (rl_kill_ring, (slot + 1) * sizeof (char *));
123: }
124: rl_kill_ring[--slot] = (char *)NULL;
125: }
126: }
127: else
128: slot = rl_kill_ring_length - 1;
129:
130: /* If the last command was a kill, prepend or append. */
131: if (_rl_last_command_was_kill && rl_kill_ring[slot] && rl_editing_mode != vi_mode)
132: {
133: old = rl_kill_ring[slot];
134: new = (char *)xmalloc (1 + strlen (old) + strlen (text));
135:
136: if (append)
137: {
138: strcpy (new, old);
139: strcat (new, text);
140: }
141: else
142: {
143: strcpy (new, text);
144: strcat (new, old);
145: }
146: xfree (old);
147: xfree (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 (int from, int to)
164: {
165: char *text;
166:
167: /* Is there anything to kill? */
168: if (from == to)
169: {
170: _rl_last_command_was_kill++;
171: return 0;
172: }
173:
174: text = rl_copy_text (from, to);
175:
176: /* Delete the copied text from the line. */
177: rl_delete_text (from, to);
178:
179: _rl_copy_to_kill_ring (text, from < to);
180:
181: _rl_last_command_was_kill++;
182: return 0;
183: }
184:
185: /* Now REMEMBER! In order to do prepending or appending correctly, kill
186: commands always make rl_point's original position be the FROM argument,
187: and rl_point's extent be the TO argument. */
188:
189: /* **************************************************************** */
190: /* */
191: /* Killing Commands */
192: /* */
193: /* **************************************************************** */
194:
195: /* Delete the word at point, saving the text in the kill ring. */
196: int
197: rl_kill_word (int count, int key)
198: {
199: int orig_point;
200:
201: if (count < 0)
202: return (rl_backward_kill_word (-count, key));
203: else
204: {
205: orig_point = rl_point;
206: rl_forward_word (count, key);
207:
208: if (rl_point != orig_point)
209: rl_kill_text (orig_point, rl_point);
210:
211: rl_point = orig_point;
212: if (rl_editing_mode == emacs_mode)
213: rl_mark = rl_point;
214: }
215: return 0;
216: }
217:
218: /* Rubout the word before point, placing it on the kill ring. */
219: int
220: rl_backward_kill_word (int count, int key)
221: {
222: int orig_point;
223:
224: if (count < 0)
225: return (rl_kill_word (-count, key));
226: else
227: {
228: orig_point = rl_point;
229: rl_backward_word (count, key);
230:
231: if (rl_point != orig_point)
232: rl_kill_text (orig_point, rl_point);
233:
234: if (rl_editing_mode == emacs_mode)
235: rl_mark = rl_point;
236: }
237: return 0;
238: }
239:
240: /* Kill from here to the end of the line. If DIRECTION is negative, kill
241: back to the line start instead. */
242: int
243: rl_kill_line (int direction, int key)
244: {
245: int orig_point;
246:
247: if (direction < 0)
248: return (rl_backward_kill_line (1, key));
249: else
250: {
251: orig_point = rl_point;
252: rl_end_of_line (1, key);
253: if (orig_point != rl_point)
254: rl_kill_text (orig_point, rl_point);
255: rl_point = orig_point;
256: if (rl_editing_mode == emacs_mode)
257: rl_mark = rl_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 (int direction, int key)
266: {
267: int orig_point;
268:
269: if (direction < 0)
270: return (rl_kill_line (1, key));
271: else
272: {
273: if (rl_point == 0)
274: rl_ding ();
275: else
276: {
277: orig_point = rl_point;
278: rl_beg_of_line (1, key);
279: if (rl_point != orig_point)
280: rl_kill_text (orig_point, rl_point);
281: if (rl_editing_mode == emacs_mode)
282: rl_mark = rl_point;
283: }
284: }
285: return 0;
286: }
287:
288: /* Kill the whole line, no matter where point is. */
289: int
290: rl_kill_full_line (int count, int key)
291: {
292: rl_begin_undo_group ();
293: rl_point = 0;
294: rl_kill_text (rl_point, rl_end);
295: rl_mark = 0;
296: rl_end_undo_group ();
297: return 0;
298: }
299:
300: /* The next two functions mimic unix line editing behaviour, except they
301: save the deleted text on the kill ring. This is safer than not saving
302: it, and since we have a ring, nobody should get screwed. */
303:
304: /* This does what C-w does in Unix. We can't prevent people from
305: using behaviour that they expect. */
306: int
307: rl_unix_word_rubout (int count, int key)
308: {
309: int orig_point;
310:
311: if (rl_point == 0)
312: rl_ding ();
313: else
314: {
315: orig_point = rl_point;
316: if (count <= 0)
317: count = 1;
318:
319: while (count--)
320: {
321: while (rl_point && whitespace (rl_line_buffer[rl_point - 1]))
322: rl_point--;
323:
324: while (rl_point && (whitespace (rl_line_buffer[rl_point - 1]) == 0))
325: rl_point--; /* XXX - multibyte? */
326: }
327:
328: rl_kill_text (orig_point, rl_point);
329: if (rl_editing_mode == emacs_mode)
330: rl_mark = rl_point;
331: }
332:
333: return 0;
334: }
335:
336: /* This deletes one filename component in a Unix pathname. That is, it
337: deletes backward to directory separator (`/') or whitespace. */
338: int
339: rl_unix_filename_rubout (int count, int key)
340: {
341: int orig_point, c;
342:
343: if (rl_point == 0)
344: rl_ding ();
345: else
346: {
347: orig_point = rl_point;
348: if (count <= 0)
349: count = 1;
350:
351: while (count--)
352: {
353: c = rl_line_buffer[rl_point - 1];
354: while (rl_point && (whitespace (c) || c == '/'))
355: {
356: rl_point--;
357: c = rl_line_buffer[rl_point - 1];
358: }
359:
360: while (rl_point && (whitespace (c) == 0) && c != '/')
361: {
362: rl_point--; /* XXX - multibyte? */
363: c = rl_line_buffer[rl_point - 1];
364: }
365: }
366:
367: rl_kill_text (orig_point, rl_point);
368: if (rl_editing_mode == emacs_mode)
369: rl_mark = rl_point;
370: }
371:
372: return 0;
373: }
374:
375: /* Here is C-u doing what Unix does. You don't *have* to use these
376: key-bindings. We have a choice of killing the entire line, or
377: killing from where we are to the start of the line. We choose the
378: latter, because if you are a Unix weenie, then you haven't backspaced
379: into the line at all, and if you aren't, then you know what you are
380: doing. */
381: int
382: rl_unix_line_discard (int count, int key)
383: {
384: if (rl_point == 0)
385: rl_ding ();
386: else
387: {
388: rl_kill_text (rl_point, 0);
389: rl_point = 0;
390: if (rl_editing_mode == emacs_mode)
391: rl_mark = rl_point;
392: }
393: return 0;
394: }
395:
396: /* Copy the text in the `region' to the kill ring. If DELETE is non-zero,
397: delete the text from the line as well. */
398: static int
399: region_kill_internal (int delete)
400: {
401: char *text;
402:
403: if (rl_mark != rl_point)
404: {
405: text = rl_copy_text (rl_point, rl_mark);
406: if (delete)
407: rl_delete_text (rl_point, rl_mark);
408: _rl_copy_to_kill_ring (text, rl_point < rl_mark);
409: }
410:
411: _rl_fix_point (1);
412: _rl_last_command_was_kill++;
413: return 0;
414: }
415:
416: /* Copy the text in the region to the kill ring. */
417: int
418: rl_copy_region_to_kill (int count, int key)
419: {
420: return (region_kill_internal (0));
421: }
422:
423: /* Kill the text between the point and mark. */
424: int
425: rl_kill_region (int count, int key)
426: {
427: int r, npoint;
428:
429: npoint = (rl_point < rl_mark) ? rl_point : rl_mark;
430: r = region_kill_internal (1);
431: rl_point = npoint;
432: _rl_fix_point (1);
433: return r;
434: }
435:
436: /* Copy COUNT words to the kill ring. DIR says which direction we look
437: to find the words. */
438: static int
439: _rl_copy_word_as_kill (int count, int dir)
440: {
441: int om, op, r;
442:
443: om = rl_mark;
444: op = rl_point;
445:
446: if (dir > 0)
447: rl_forward_word (count, 0);
448: else
449: rl_backward_word (count, 0);
450:
451: rl_mark = rl_point;
452:
453: if (dir > 0)
454: rl_backward_word (count, 0);
455: else
456: rl_forward_word (count, 0);
457:
458: r = region_kill_internal (0);
459:
460: rl_mark = om;
461: rl_point = op;
462:
463: return r;
464: }
465:
466: int
467: rl_copy_forward_word (int count, int key)
468: {
469: if (count < 0)
470: return (rl_copy_backward_word (-count, key));
471:
472: return (_rl_copy_word_as_kill (count, 1));
473: }
474:
475: int
476: rl_copy_backward_word (int count, int key)
477: {
478: if (count < 0)
479: return (rl_copy_forward_word (-count, key));
480:
481: return (_rl_copy_word_as_kill (count, -1));
482: }
483:
484: /* Yank back the last killed text. This ignores arguments. */
485: int
486: rl_yank (int count, int key)
487: {
488: if (rl_kill_ring == 0)
489: {
490: _rl_abort_internal ();
491: return 1;
492: }
493:
494: _rl_set_mark_at_pos (rl_point);
495: rl_insert_text (rl_kill_ring[rl_kill_index]);
496: return 0;
497: }
498:
499: /* If the last command was yank, or yank_pop, and the text just
500: before point is identical to the current kill item, then
501: delete that text from the line, rotate the index down, and
502: yank back some other text. */
503: int
504: rl_yank_pop (int count, int key)
505: {
506: int l, n;
507:
508: if (((rl_last_func != rl_yank_pop) && (rl_last_func != rl_yank)) ||
509: !rl_kill_ring)
510: {
511: _rl_abort_internal ();
512: return 1;
513: }
514:
515: l = strlen (rl_kill_ring[rl_kill_index]);
516: n = rl_point - l;
517: if (n >= 0 && STREQN (rl_line_buffer + n, rl_kill_ring[rl_kill_index], l))
518: {
519: rl_delete_text (n, rl_point);
520: rl_point = n;
521: rl_kill_index--;
522: if (rl_kill_index < 0)
523: rl_kill_index = rl_kill_ring_length - 1;
524: rl_yank (1, 0);
525: return 0;
526: }
527: else
528: {
529: _rl_abort_internal ();
530: return 1;
531: }
532: }
533:
534: #if defined (VI_MODE)
535: int
536: rl_vi_yank_pop (int count, int key)
537: {
538: int l, n;
539:
540: if (((rl_last_func != rl_vi_yank_pop) && (rl_last_func != rl_vi_put)) ||
541: !rl_kill_ring)
542: {
543: _rl_abort_internal ();
544: return 1;
545: }
546:
547: l = strlen (rl_kill_ring[rl_kill_index]);
548: n = rl_point - l;
549: if (n >= 0 && STREQN (rl_line_buffer + n, rl_kill_ring[rl_kill_index], l))
550: {
551: rl_delete_text (n, rl_point);
552: rl_point = n;
553: rl_kill_index--;
554: if (rl_kill_index < 0)
555: rl_kill_index = rl_kill_ring_length - 1;
556: rl_vi_put (1, 'p');
557: return 0;
558: }
559: else
560: {
561: _rl_abort_internal ();
562: return 1;
563: }
564: }
565: #endif /* VI_MODE */
566:
567: /* Yank the COUNTh argument from the previous history line, skipping
568: HISTORY_SKIP lines before looking for the `previous line'. */
569: static int
570: rl_yank_nth_arg_internal (int count, int key, int history_skip)
571: {
572: register HIST_ENTRY *entry;
573: char *arg;
574: int i, pos;
575:
576: pos = where_history ();
577:
578: if (history_skip)
579: {
580: for (i = 0; i < history_skip; i++)
581: entry = previous_history ();
582: }
583:
584: entry = previous_history ();
585:
586: history_set_pos (pos);
587:
588: if (entry == 0)
589: {
590: rl_ding ();
591: return 1;
592: }
593:
594: arg = history_arg_extract (count, count, entry->line);
595: if (!arg || !*arg)
596: {
597: rl_ding ();
598: FREE (arg);
599: return 1;
600: }
601:
602: rl_begin_undo_group ();
603:
604: _rl_set_mark_at_pos (rl_point);
605:
606: #if defined (VI_MODE)
607: /* Vi mode always inserts a space before yanking the argument, and it
608: inserts it right *after* rl_point. */
609: if (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap)
610: {
611: rl_vi_append_mode (1, key);
612: rl_insert_text (" ");
613: }
614: #endif /* VI_MODE */
615:
616: rl_insert_text (arg);
617: xfree (arg);
618:
619: rl_end_undo_group ();
620: return 0;
621: }
622:
623: /* Yank the COUNTth argument from the previous history line. */
624: int
625: rl_yank_nth_arg (int count, int key)
626: {
627: return (rl_yank_nth_arg_internal (count, key, 0));
628: }
629:
630: /* Yank the last argument from the previous history line. This `knows'
631: how rl_yank_nth_arg treats a count of `$'. With an argument, this
632: behaves the same as rl_yank_nth_arg. */
633: int
634: rl_yank_last_arg (int count, int key)
635: {
636: static int history_skip = 0;
637: static int explicit_arg_p = 0;
638: static int count_passed = 1;
639: static int direction = 1;
640: static int undo_needed = 0;
641: int retval;
642:
643: if (rl_last_func != rl_yank_last_arg)
644: {
645: history_skip = 0;
646: explicit_arg_p = rl_explicit_arg;
647: count_passed = count;
648: direction = 1;
649: }
650: else
651: {
652: if (undo_needed)
653: rl_do_undo ();
654: if (count < 0) /* XXX - was < 1 */
655: direction = -direction;
656: history_skip += direction;
657: if (history_skip < 0)
658: history_skip = 0;
659: }
660:
661: if (explicit_arg_p)
662: retval = rl_yank_nth_arg_internal (count_passed, key, history_skip);
663: else
664: retval = rl_yank_nth_arg_internal ('$', key, history_skip);
665:
666: undo_needed = retval == 0;
667: return retval;
668: }
669:
670: /* Having read the special escape sequence denoting the beginning of a
671: `bracketed paste' sequence, read the rest of the pasted input until the
672: closing sequence and return the pasted text. */
673: char *
674: _rl_bracketed_text (size_t *lenp)
675: {
676: int c;
677: size_t len, cap;
678: char *buf;
679:
680: len = 0;
681: buf = xmalloc (cap = 64);
682: buf[0] = '\0';
683:
684: RL_SETSTATE (RL_STATE_MOREINPUT);
685: while ((c = rl_read_key ()) >= 0)
686: {
687: if (RL_ISSTATE (RL_STATE_MACRODEF))
688: _rl_add_macro_char (c);
689:
690: if (c == '\r') /* XXX */
691: c = '\n';
692:
693: if (len == cap)
694: buf = xrealloc (buf, cap *= 2);
695:
696: buf[len++] = c;
697: if (len >= BRACK_PASTE_SLEN && c == BRACK_PASTE_LAST &&
698: STREQN (buf + len - BRACK_PASTE_SLEN, BRACK_PASTE_SUFF, BRACK_PASTE_SLEN))
699: {
700: len -= BRACK_PASTE_SLEN;
701: break;
702: }
703: }
704: RL_UNSETSTATE (RL_STATE_MOREINPUT);
705:
706: if (c >= 0)
707: {
708: if (len == cap)
709: buf = xrealloc (buf, cap + 1);
710: buf[len] = '\0';
711: }
712:
713: if (lenp)
714: *lenp = len;
715: return (buf);
716: }
717:
718: /* Having read the special escape sequence denoting the beginning of a
719: `bracketed paste' sequence, read the rest of the pasted input until the
720: closing sequence and insert the pasted text as a single unit without
721: interpretation. Temporarily highlight the inserted text. */
722: int
723: rl_bracketed_paste_begin (int count, int key)
724: {
725: int retval, c;
726: size_t len, cap;
727: char *buf;
728:
729: buf = _rl_bracketed_text (&len);
730: rl_mark = rl_point;
731: retval = rl_insert_text (buf) == len ? 0 : 1;
732: if (_rl_enable_active_region)
733: rl_activate_mark ();
734:
735: xfree (buf);
736: return (retval);
737: }
738:
739: int
740: _rl_read_bracketed_paste_prefix (int c)
741: {
742: char pbuf[BRACK_PASTE_SLEN+1], *pbpref;
743: int key, ind, j;
744:
745: pbpref = BRACK_PASTE_PREF; /* XXX - debugging */
746: if (c != pbpref[0])
747: return (0);
748: pbuf[ind = 0] = c;
749: while (ind < BRACK_PASTE_SLEN-1 &&
750: (RL_ISSTATE (RL_STATE_INPUTPENDING|RL_STATE_MACROINPUT) == 0) &&
751: _rl_pushed_input_available () == 0 &&
752: _rl_input_queued (0))
753: {
754: key = rl_read_key (); /* XXX - for now */
755: if (key < 0)
756: break;
757: pbuf[++ind] = key;
758: if (pbuf[ind] != pbpref[ind])
759: break;
760: }
761:
762: if (ind < BRACK_PASTE_SLEN-1) /* read incomplete sequence */
763: {
764: while (ind >= 0)
765: _rl_unget_char (pbuf[ind--]);
766: return (key < 0 ? key : 0);
767: }
768: return (key < 0 ? key : 1);
769: }
770:
771: /* Get a character from wherever we read input, handling input in bracketed
772: paste mode. If we don't have or use bracketed paste mode, this can be
773: used in place of rl_read_key(). */
774: int
775: _rl_bracketed_read_key ()
776: {
777: int c, r;
778: char *pbuf;
779: size_t pblen;
780:
781: RL_SETSTATE(RL_STATE_MOREINPUT);
782: c = rl_read_key ();
783: RL_UNSETSTATE(RL_STATE_MOREINPUT);
784:
785: if (c < 0)
786: return -1;
787:
788: /* read pasted data with bracketed-paste mode enabled. */
789: if (_rl_enable_bracketed_paste && c == ESC && (r = _rl_read_bracketed_paste_prefix (c)) == 1)
790: {
791: pbuf = _rl_bracketed_text (&pblen);
792: if (pblen == 0)
793: {
794: xfree (pbuf);
795: return 0; /* XXX */
796: }
797: c = (unsigned char)pbuf[0];
798: if (pblen > 1)
799: {
800: while (--pblen > 0)
801: _rl_unget_char ((unsigned char)pbuf[pblen]);
802: }
803: xfree (pbuf);
804: }
805:
806: return c;
807: }
808:
809: /* Get a character from wherever we read input, handling input in bracketed
810: paste mode. If we don't have or use bracketed paste mode, this can be
811: used in place of rl_read_key(). */
812: int
813: _rl_bracketed_read_mbstring (char *mb, int mlen)
814: {
815: int c, r;
816:
817: c = _rl_bracketed_read_key ();
818: if (c < 0)
819: return -1;
820:
821: #if defined (HANDLE_MULTIBYTE)
822: if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
823: c = _rl_read_mbstring (c, mb, mlen);
824: else
825: #endif
826: mb[0] = c;
827: mb[mlen] = '\0'; /* just in case */
828:
829: return c;
830: }
831:
832: /* A special paste command for Windows users. */
833: #if defined (_WIN32)
834: #include <windows.h>
835:
836: int
837: rl_paste_from_clipboard (int count, int key)
838: {
839: char *data, *ptr;
840: int len;
841:
842: if (OpenClipboard (NULL) == 0)
843: return (0);
844:
845: data = (char *)GetClipboardData (CF_TEXT);
846: if (data)
847: {
848: ptr = strchr (data, '\r');
849: if (ptr)
850: {
851: len = ptr - data;
852: ptr = (char *)xmalloc (len + 1);
853: ptr[len] = '\0';
854: strncpy (ptr, data, len);
855: }
856: else
857: ptr = data;
858: _rl_set_mark_at_pos (rl_point);
859: rl_insert_text (ptr);
860: if (ptr != data)
861: xfree (ptr);
862: CloseClipboard ();
863: }
864: return (0);
865: }
866: #endif /* _WIN32 */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>