Commit | Line | Data |
---|---|---|
d60d9f65 SS |
1 | /* kill.c -- kill ring management. */ |
2 | ||
cb41b9e7 | 3 | /* Copyright (C) 1994-2017 Free Software Foundation, Inc. |
d60d9f65 | 4 | |
cc88a640 JK |
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. | |
d60d9f65 | 7 | |
cc88a640 JK |
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 | |
d60d9f65 SS |
11 | (at your option) any later version. |
12 | ||
cc88a640 JK |
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 | |
d60d9f65 SS |
16 | GNU General Public License for more details. |
17 | ||
cc88a640 JK |
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 | ||
d60d9f65 SS |
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 | ||
1b17e766 EZ |
49 | #include "rlprivate.h" |
50 | #include "xmalloc.h" | |
d60d9f65 SS |
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 | ||
9255ee31 EZ |
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 | ||
d60d9f65 SS |
78 | /* How to say that you only want to save a certain amount |
79 | of kill material. */ | |
80 | int | |
cb41b9e7 | 81 | rl_set_retained_kills (int num) |
d60d9f65 SS |
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 | |
cb41b9e7 | 91 | _rl_copy_to_kill_ring (char *text, int append) |
d60d9f65 SS |
92 | { |
93 | char *old, *new; | |
94 | int slot; | |
95 | ||
96 | /* First, find the slot to work with. */ | |
775e241e | 97 | if (_rl_last_command_was_kill == 0 || rl_kill_ring == 0) |
d60d9f65 SS |
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; | |
cc88a640 | 115 | xfree (rl_kill_ring[0]); |
d60d9f65 SS |
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; | |
cb41b9e7 | 122 | rl_kill_ring = (char **)xrealloc (rl_kill_ring, (slot + 1) * sizeof (char *)); |
d60d9f65 SS |
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. */ | |
cb41b9e7 | 131 | if (_rl_last_command_was_kill && rl_kill_ring[slot] && rl_editing_mode != vi_mode) |
d60d9f65 SS |
132 | { |
133 | old = rl_kill_ring[slot]; | |
9255ee31 | 134 | new = (char *)xmalloc (1 + strlen (old) + strlen (text)); |
d60d9f65 SS |
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 | } | |
cc88a640 JK |
146 | xfree (old); |
147 | xfree (text); | |
d60d9f65 SS |
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 | |
cb41b9e7 | 163 | rl_kill_text (int from, int to) |
d60d9f65 SS |
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 | |
cb41b9e7 | 197 | rl_kill_word (int count, int key) |
d60d9f65 | 198 | { |
9255ee31 | 199 | int orig_point; |
d60d9f65 SS |
200 | |
201 | if (count < 0) | |
202 | return (rl_backward_kill_word (-count, key)); | |
203 | else | |
204 | { | |
9255ee31 | 205 | orig_point = rl_point; |
d60d9f65 SS |
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; | |
9255ee31 EZ |
212 | if (rl_editing_mode == emacs_mode) |
213 | rl_mark = rl_point; | |
d60d9f65 SS |
214 | } |
215 | return 0; | |
216 | } | |
217 | ||
218 | /* Rubout the word before point, placing it on the kill ring. */ | |
219 | int | |
cb41b9e7 | 220 | rl_backward_kill_word (int count, int key) |
d60d9f65 | 221 | { |
9255ee31 | 222 | int orig_point; |
d60d9f65 SS |
223 | |
224 | if (count < 0) | |
cb41b9e7 | 225 | return (rl_kill_word (-count, key)); |
d60d9f65 SS |
226 | else |
227 | { | |
9255ee31 | 228 | orig_point = rl_point; |
cb41b9e7 | 229 | rl_backward_word (count, key); |
d60d9f65 SS |
230 | |
231 | if (rl_point != orig_point) | |
232 | rl_kill_text (orig_point, rl_point); | |
9255ee31 EZ |
233 | |
234 | if (rl_editing_mode == emacs_mode) | |
235 | rl_mark = rl_point; | |
d60d9f65 SS |
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 | |
cb41b9e7 | 243 | rl_kill_line (int direction, int key) |
d60d9f65 | 244 | { |
9255ee31 | 245 | int orig_point; |
d60d9f65 SS |
246 | |
247 | if (direction < 0) | |
cb41b9e7 | 248 | return (rl_backward_kill_line (1, key)); |
d60d9f65 SS |
249 | else |
250 | { | |
9255ee31 | 251 | orig_point = rl_point; |
cb41b9e7 | 252 | rl_end_of_line (1, key); |
d60d9f65 SS |
253 | if (orig_point != rl_point) |
254 | rl_kill_text (orig_point, rl_point); | |
255 | rl_point = orig_point; | |
9255ee31 EZ |
256 | if (rl_editing_mode == emacs_mode) |
257 | rl_mark = rl_point; | |
d60d9f65 SS |
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 | |
cb41b9e7 | 265 | rl_backward_kill_line (int direction, int key) |
d60d9f65 | 266 | { |
9255ee31 | 267 | int orig_point; |
d60d9f65 SS |
268 | |
269 | if (direction < 0) | |
cb41b9e7 | 270 | return (rl_kill_line (1, key)); |
d60d9f65 SS |
271 | else |
272 | { | |
775e241e | 273 | if (rl_point == 0) |
9255ee31 | 274 | rl_ding (); |
d60d9f65 SS |
275 | else |
276 | { | |
9255ee31 | 277 | orig_point = rl_point; |
cb41b9e7 | 278 | rl_beg_of_line (1, key); |
9255ee31 EZ |
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; | |
d60d9f65 SS |
283 | } |
284 | } | |
285 | return 0; | |
286 | } | |
287 | ||
288 | /* Kill the whole line, no matter where point is. */ | |
289 | int | |
cb41b9e7 | 290 | rl_kill_full_line (int count, int key) |
d60d9f65 SS |
291 | { |
292 | rl_begin_undo_group (); | |
293 | rl_point = 0; | |
294 | rl_kill_text (rl_point, rl_end); | |
9255ee31 | 295 | rl_mark = 0; |
d60d9f65 SS |
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 | |
cb41b9e7 | 307 | rl_unix_word_rubout (int count, int key) |
d60d9f65 SS |
308 | { |
309 | int orig_point; | |
310 | ||
311 | if (rl_point == 0) | |
9255ee31 | 312 | rl_ding (); |
d60d9f65 SS |
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)) | |
cb41b9e7 | 325 | rl_point--; /* XXX - multibyte? */ |
d60d9f65 SS |
326 | } |
327 | ||
328 | rl_kill_text (orig_point, rl_point); | |
9255ee31 EZ |
329 | if (rl_editing_mode == emacs_mode) |
330 | rl_mark = rl_point; | |
d60d9f65 | 331 | } |
5bdf8622 DJ |
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 | |
cb41b9e7 | 339 | rl_unix_filename_rubout (int count, int key) |
5bdf8622 DJ |
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 | { | |
cb41b9e7 | 362 | rl_point--; /* XXX - multibyte? */ |
5bdf8622 DJ |
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 | ||
d60d9f65 SS |
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 | |
cb41b9e7 | 382 | rl_unix_line_discard (int count, int key) |
d60d9f65 SS |
383 | { |
384 | if (rl_point == 0) | |
9255ee31 | 385 | rl_ding (); |
d60d9f65 SS |
386 | else |
387 | { | |
388 | rl_kill_text (rl_point, 0); | |
389 | rl_point = 0; | |
9255ee31 EZ |
390 | if (rl_editing_mode == emacs_mode) |
391 | rl_mark = rl_point; | |
d60d9f65 SS |
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 | |
cb41b9e7 | 399 | region_kill_internal (int delete) |
d60d9f65 SS |
400 | { |
401 | char *text; | |
402 | ||
9255ee31 | 403 | if (rl_mark != rl_point) |
d60d9f65 | 404 | { |
9255ee31 EZ |
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); | |
d60d9f65 SS |
409 | } |
410 | ||
d60d9f65 SS |
411 | _rl_last_command_was_kill++; |
412 | return 0; | |
413 | } | |
414 | ||
415 | /* Copy the text in the region to the kill ring. */ | |
416 | int | |
cb41b9e7 | 417 | rl_copy_region_to_kill (int count, int key) |
d60d9f65 SS |
418 | { |
419 | return (region_kill_internal (0)); | |
420 | } | |
421 | ||
422 | /* Kill the text between the point and mark. */ | |
423 | int | |
cb41b9e7 | 424 | rl_kill_region (int count, int key) |
d60d9f65 | 425 | { |
1b17e766 | 426 | int r, npoint; |
d60d9f65 | 427 | |
1b17e766 | 428 | npoint = (rl_point < rl_mark) ? rl_point : rl_mark; |
d60d9f65 SS |
429 | r = region_kill_internal (1); |
430 | _rl_fix_point (1); | |
1b17e766 | 431 | rl_point = npoint; |
d60d9f65 SS |
432 | return r; |
433 | } | |
434 | ||
435 | /* Copy COUNT words to the kill ring. DIR says which direction we look | |
436 | to find the words. */ | |
437 | static int | |
cb41b9e7 | 438 | _rl_copy_word_as_kill (int count, int dir) |
d60d9f65 SS |
439 | { |
440 | int om, op, r; | |
441 | ||
442 | om = rl_mark; | |
443 | op = rl_point; | |
444 | ||
445 | if (dir > 0) | |
446 | rl_forward_word (count, 0); | |
447 | else | |
448 | rl_backward_word (count, 0); | |
449 | ||
450 | rl_mark = rl_point; | |
451 | ||
452 | if (dir > 0) | |
453 | rl_backward_word (count, 0); | |
454 | else | |
455 | rl_forward_word (count, 0); | |
456 | ||
457 | r = region_kill_internal (0); | |
458 | ||
459 | rl_mark = om; | |
460 | rl_point = op; | |
461 | ||
462 | return r; | |
463 | } | |
464 | ||
465 | int | |
cb41b9e7 | 466 | rl_copy_forward_word (int count, int key) |
d60d9f65 SS |
467 | { |
468 | if (count < 0) | |
469 | return (rl_copy_backward_word (-count, key)); | |
470 | ||
471 | return (_rl_copy_word_as_kill (count, 1)); | |
472 | } | |
473 | ||
474 | int | |
cb41b9e7 | 475 | rl_copy_backward_word (int count, int key) |
d60d9f65 SS |
476 | { |
477 | if (count < 0) | |
478 | return (rl_copy_forward_word (-count, key)); | |
479 | ||
480 | return (_rl_copy_word_as_kill (count, -1)); | |
481 | } | |
482 | ||
483 | /* Yank back the last killed text. This ignores arguments. */ | |
484 | int | |
cb41b9e7 | 485 | rl_yank (int count, int key) |
d60d9f65 SS |
486 | { |
487 | if (rl_kill_ring == 0) | |
488 | { | |
489 | _rl_abort_internal (); | |
775e241e | 490 | return 1; |
d60d9f65 SS |
491 | } |
492 | ||
493 | _rl_set_mark_at_pos (rl_point); | |
494 | rl_insert_text (rl_kill_ring[rl_kill_index]); | |
495 | return 0; | |
496 | } | |
497 | ||
498 | /* If the last command was yank, or yank_pop, and the text just | |
499 | before point is identical to the current kill item, then | |
500 | delete that text from the line, rotate the index down, and | |
501 | yank back some other text. */ | |
502 | int | |
cb41b9e7 | 503 | rl_yank_pop (int count, int key) |
d60d9f65 SS |
504 | { |
505 | int l, n; | |
506 | ||
507 | if (((rl_last_func != rl_yank_pop) && (rl_last_func != rl_yank)) || | |
508 | !rl_kill_ring) | |
509 | { | |
510 | _rl_abort_internal (); | |
775e241e | 511 | return 1; |
d60d9f65 SS |
512 | } |
513 | ||
514 | l = strlen (rl_kill_ring[rl_kill_index]); | |
515 | n = rl_point - l; | |
516 | if (n >= 0 && STREQN (rl_line_buffer + n, rl_kill_ring[rl_kill_index], l)) | |
517 | { | |
518 | rl_delete_text (n, rl_point); | |
519 | rl_point = n; | |
520 | rl_kill_index--; | |
521 | if (rl_kill_index < 0) | |
522 | rl_kill_index = rl_kill_ring_length - 1; | |
523 | rl_yank (1, 0); | |
524 | return 0; | |
525 | } | |
526 | else | |
527 | { | |
528 | _rl_abort_internal (); | |
775e241e | 529 | return 1; |
d60d9f65 SS |
530 | } |
531 | } | |
532 | ||
775e241e TT |
533 | #if defined (VI_MODE) |
534 | int | |
cb41b9e7 | 535 | rl_vi_yank_pop (int count, int key) |
775e241e TT |
536 | { |
537 | int l, n; | |
538 | ||
539 | if (((rl_last_func != rl_vi_yank_pop) && (rl_last_func != rl_vi_put)) || | |
540 | !rl_kill_ring) | |
541 | { | |
542 | _rl_abort_internal (); | |
543 | return 1; | |
544 | } | |
545 | ||
546 | l = strlen (rl_kill_ring[rl_kill_index]); | |
547 | n = rl_point - l; | |
548 | if (n >= 0 && STREQN (rl_line_buffer + n, rl_kill_ring[rl_kill_index], l)) | |
549 | { | |
550 | rl_delete_text (n, rl_point); | |
551 | rl_point = n; | |
552 | rl_kill_index--; | |
553 | if (rl_kill_index < 0) | |
554 | rl_kill_index = rl_kill_ring_length - 1; | |
555 | rl_vi_put (1, 'p'); | |
556 | return 0; | |
557 | } | |
558 | else | |
559 | { | |
560 | _rl_abort_internal (); | |
561 | return 1; | |
562 | } | |
563 | } | |
564 | #endif /* VI_MODE */ | |
565 | ||
d60d9f65 SS |
566 | /* Yank the COUNTh argument from the previous history line, skipping |
567 | HISTORY_SKIP lines before looking for the `previous line'. */ | |
568 | static int | |
cb41b9e7 | 569 | rl_yank_nth_arg_internal (int count, int key, int history_skip) |
d60d9f65 SS |
570 | { |
571 | register HIST_ENTRY *entry; | |
572 | char *arg; | |
1b17e766 EZ |
573 | int i, pos; |
574 | ||
575 | pos = where_history (); | |
d60d9f65 SS |
576 | |
577 | if (history_skip) | |
578 | { | |
579 | for (i = 0; i < history_skip; i++) | |
580 | entry = previous_history (); | |
581 | } | |
582 | ||
583 | entry = previous_history (); | |
1b17e766 EZ |
584 | |
585 | history_set_pos (pos); | |
586 | ||
587 | if (entry == 0) | |
d60d9f65 | 588 | { |
9255ee31 | 589 | rl_ding (); |
775e241e | 590 | return 1; |
d60d9f65 SS |
591 | } |
592 | ||
593 | arg = history_arg_extract (count, count, entry->line); | |
594 | if (!arg || !*arg) | |
595 | { | |
9255ee31 | 596 | rl_ding (); |
cc88a640 | 597 | FREE (arg); |
775e241e | 598 | return 1; |
d60d9f65 SS |
599 | } |
600 | ||
601 | rl_begin_undo_group (); | |
602 | ||
9255ee31 EZ |
603 | _rl_set_mark_at_pos (rl_point); |
604 | ||
d60d9f65 SS |
605 | #if defined (VI_MODE) |
606 | /* Vi mode always inserts a space before yanking the argument, and it | |
607 | inserts it right *after* rl_point. */ | |
608 | if (rl_editing_mode == vi_mode) | |
609 | { | |
cb41b9e7 | 610 | rl_vi_append_mode (1, key); |
d60d9f65 SS |
611 | rl_insert_text (" "); |
612 | } | |
613 | #endif /* VI_MODE */ | |
614 | ||
615 | rl_insert_text (arg); | |
cc88a640 | 616 | xfree (arg); |
d60d9f65 SS |
617 | |
618 | rl_end_undo_group (); | |
619 | return 0; | |
620 | } | |
621 | ||
622 | /* Yank the COUNTth argument from the previous history line. */ | |
623 | int | |
cb41b9e7 | 624 | rl_yank_nth_arg (int count, int key) |
d60d9f65 | 625 | { |
cb41b9e7 | 626 | return (rl_yank_nth_arg_internal (count, key, 0)); |
d60d9f65 SS |
627 | } |
628 | ||
629 | /* Yank the last argument from the previous history line. This `knows' | |
630 | how rl_yank_nth_arg treats a count of `$'. With an argument, this | |
631 | behaves the same as rl_yank_nth_arg. */ | |
632 | int | |
cb41b9e7 | 633 | rl_yank_last_arg (int count, int key) |
d60d9f65 SS |
634 | { |
635 | static int history_skip = 0; | |
636 | static int explicit_arg_p = 0; | |
637 | static int count_passed = 1; | |
638 | static int direction = 1; | |
c862e87b JM |
639 | static int undo_needed = 0; |
640 | int retval; | |
d60d9f65 SS |
641 | |
642 | if (rl_last_func != rl_yank_last_arg) | |
643 | { | |
644 | history_skip = 0; | |
645 | explicit_arg_p = rl_explicit_arg; | |
646 | count_passed = count; | |
647 | direction = 1; | |
648 | } | |
649 | else | |
650 | { | |
c862e87b JM |
651 | if (undo_needed) |
652 | rl_do_undo (); | |
cc88a640 | 653 | if (count < 0) /* XXX - was < 1 */ |
d60d9f65 SS |
654 | direction = -direction; |
655 | history_skip += direction; | |
656 | if (history_skip < 0) | |
657 | history_skip = 0; | |
d60d9f65 SS |
658 | } |
659 | ||
660 | if (explicit_arg_p) | |
c862e87b | 661 | retval = rl_yank_nth_arg_internal (count_passed, key, history_skip); |
d60d9f65 | 662 | else |
c862e87b JM |
663 | retval = rl_yank_nth_arg_internal ('$', key, history_skip); |
664 | ||
665 | undo_needed = retval == 0; | |
666 | return retval; | |
d60d9f65 SS |
667 | } |
668 | ||
775e241e TT |
669 | /* Having read the special escape sequence denoting the beginning of a |
670 | `bracketed paste' sequence, read the rest of the pasted input until the | |
671 | closing sequence and insert the pasted text as a single unit without | |
672 | interpretation. */ | |
cb41b9e7 TT |
673 | char * |
674 | _rl_bracketed_text (size_t *lenp) | |
775e241e | 675 | { |
cb41b9e7 | 676 | int c; |
775e241e TT |
677 | size_t len, cap; |
678 | char *buf; | |
679 | ||
775e241e TT |
680 | len = 0; |
681 | buf = xmalloc (cap = 64); | |
cb41b9e7 | 682 | buf[0] = '\0'; |
775e241e TT |
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'; | |
775e241e TT |
711 | } |
712 | ||
cb41b9e7 TT |
713 | if (lenp) |
714 | *lenp = len; | |
715 | return (buf); | |
716 | } | |
717 | ||
718 | int | |
719 | rl_bracketed_paste_begin (int count, int key) | |
720 | { | |
721 | int retval, c; | |
722 | size_t len, cap; | |
723 | char *buf; | |
724 | ||
725 | buf = _rl_bracketed_text (&len); | |
726 | retval = rl_insert_text (buf) == len ? 0 : 1; | |
727 | ||
775e241e TT |
728 | xfree (buf); |
729 | return (retval); | |
730 | } | |
731 | ||
cb41b9e7 | 732 | /* A special paste command for Windows users. */ |
7f3c5ec8 | 733 | #if defined (_WIN32) |
d60d9f65 SS |
734 | #include <windows.h> |
735 | ||
736 | int | |
cb41b9e7 | 737 | rl_paste_from_clipboard (int count, int key) |
d60d9f65 SS |
738 | { |
739 | char *data, *ptr; | |
740 | int len; | |
741 | ||
742 | if (OpenClipboard (NULL) == 0) | |
743 | return (0); | |
744 | ||
745 | data = (char *)GetClipboardData (CF_TEXT); | |
746 | if (data) | |
747 | { | |
748 | ptr = strchr (data, '\r'); | |
749 | if (ptr) | |
750 | { | |
751 | len = ptr - data; | |
9255ee31 | 752 | ptr = (char *)xmalloc (len + 1); |
d60d9f65 SS |
753 | ptr[len] = '\0'; |
754 | strncpy (ptr, data, len); | |
755 | } | |
756 | else | |
757 | ptr = data; | |
9255ee31 | 758 | _rl_set_mark_at_pos (rl_point); |
d60d9f65 SS |
759 | rl_insert_text (ptr); |
760 | if (ptr != data) | |
cc88a640 | 761 | xfree (ptr); |
d60d9f65 SS |
762 | CloseClipboard (); |
763 | } | |
764 | return (0); | |
765 | } | |
775e241e | 766 | #endif /* _WIN32 */ |