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 | 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 | free (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 | free (old);
|
---|
150 | free (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 | return -1;
|
---|
586 | }
|
---|
587 |
|
---|
588 | rl_begin_undo_group ();
|
---|
589 |
|
---|
590 | _rl_set_mark_at_pos (rl_point);
|
---|
591 |
|
---|
592 | #if defined (VI_MODE)
|
---|
593 | /* Vi mode always inserts a space before yanking the argument, and it
|
---|
594 | inserts it right *after* rl_point. */
|
---|
595 | if (rl_editing_mode == vi_mode)
|
---|
596 | {
|
---|
597 | rl_vi_append_mode (1, ignore);
|
---|
598 | rl_insert_text (" ");
|
---|
599 | }
|
---|
600 | #endif /* VI_MODE */
|
---|
601 |
|
---|
602 | rl_insert_text (arg);
|
---|
603 | free (arg);
|
---|
604 |
|
---|
605 | rl_end_undo_group ();
|
---|
606 | return 0;
|
---|
607 | }
|
---|
608 |
|
---|
609 | /* Yank the COUNTth argument from the previous history line. */
|
---|
610 | int
|
---|
611 | rl_yank_nth_arg (count, ignore)
|
---|
612 | int count, ignore;
|
---|
613 | {
|
---|
614 | return (rl_yank_nth_arg_internal (count, ignore, 0));
|
---|
615 | }
|
---|
616 |
|
---|
617 | /* Yank the last argument from the previous history line. This `knows'
|
---|
618 | how rl_yank_nth_arg treats a count of `$'. With an argument, this
|
---|
619 | behaves the same as rl_yank_nth_arg. */
|
---|
620 | int
|
---|
621 | rl_yank_last_arg (count, key)
|
---|
622 | int count, key;
|
---|
623 | {
|
---|
624 | static int history_skip = 0;
|
---|
625 | static int explicit_arg_p = 0;
|
---|
626 | static int count_passed = 1;
|
---|
627 | static int direction = 1;
|
---|
628 | static int undo_needed = 0;
|
---|
629 | int retval;
|
---|
630 |
|
---|
631 | if (rl_last_func != rl_yank_last_arg)
|
---|
632 | {
|
---|
633 | history_skip = 0;
|
---|
634 | explicit_arg_p = rl_explicit_arg;
|
---|
635 | count_passed = count;
|
---|
636 | direction = 1;
|
---|
637 | }
|
---|
638 | else
|
---|
639 | {
|
---|
640 | if (undo_needed)
|
---|
641 | rl_do_undo ();
|
---|
642 | if (count < 1)
|
---|
643 | direction = -direction;
|
---|
644 | history_skip += direction;
|
---|
645 | if (history_skip < 0)
|
---|
646 | history_skip = 0;
|
---|
647 | }
|
---|
648 |
|
---|
649 | if (explicit_arg_p)
|
---|
650 | retval = rl_yank_nth_arg_internal (count_passed, key, history_skip);
|
---|
651 | else
|
---|
652 | retval = rl_yank_nth_arg_internal ('$', key, history_skip);
|
---|
653 |
|
---|
654 | undo_needed = retval == 0;
|
---|
655 | return retval;
|
---|
656 | }
|
---|
657 |
|
---|
658 | /* A special paste command for users of Cygnus's cygwin32. */
|
---|
659 | #if defined (__CYGWIN__)
|
---|
660 | #include <windows.h>
|
---|
661 |
|
---|
662 | int
|
---|
663 | rl_paste_from_clipboard (count, key)
|
---|
664 | int count, key;
|
---|
665 | {
|
---|
666 | char *data, *ptr;
|
---|
667 | int len;
|
---|
668 |
|
---|
669 | if (OpenClipboard (NULL) == 0)
|
---|
670 | return (0);
|
---|
671 |
|
---|
672 | data = (char *)GetClipboardData (CF_TEXT);
|
---|
673 | if (data)
|
---|
674 | {
|
---|
675 | ptr = strchr (data, '\r');
|
---|
676 | if (ptr)
|
---|
677 | {
|
---|
678 | len = ptr - data;
|
---|
679 | ptr = (char *)xmalloc (len + 1);
|
---|
680 | ptr[len] = '\0';
|
---|
681 | strncpy (ptr, data, len);
|
---|
682 | }
|
---|
683 | else
|
---|
684 | ptr = data;
|
---|
685 | _rl_set_mark_at_pos (rl_point);
|
---|
686 | rl_insert_text (ptr);
|
---|
687 | if (ptr != data)
|
---|
688 | free (ptr);
|
---|
689 | CloseClipboard ();
|
---|
690 | }
|
---|
691 | return (0);
|
---|
692 | }
|
---|
693 | #endif /* __CYGWIN__ */
|
---|