]>
Commit | Line | Data |
---|---|---|
ccc6cda3 JA |
1 | /* kill.c -- kill ring management. */ |
2 | ||
8868edaf | 3 | /* Copyright (C) 1994-2020 Free Software Foundation, Inc. |
ccc6cda3 | 4 | |
3185942a JA |
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. | |
ccc6cda3 | 7 | |
3185942a JA |
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 | |
ccc6cda3 JA |
11 | (at your option) any later version. |
12 | ||
3185942a JA |
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 | |
ccc6cda3 JA |
16 | GNU General Public License for more details. |
17 | ||
3185942a JA |
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 | ||
ccc6cda3 JA |
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 | ||
bb70624e JA |
49 | #include "rlprivate.h" |
50 | #include "xmalloc.h" | |
ccc6cda3 JA |
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 | ||
f73dda09 JA |
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 | ||
ccc6cda3 JA |
78 | /* How to say that you only want to save a certain amount |
79 | of kill material. */ | |
80 | int | |
d233b485 | 81 | rl_set_retained_kills (int num) |
ccc6cda3 JA |
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 | |
d233b485 | 91 | _rl_copy_to_kill_ring (char *text, int append) |
ccc6cda3 JA |
92 | { |
93 | char *old, *new; | |
94 | int slot; | |
95 | ||
96 | /* First, find the slot to work with. */ | |
a0c0a00f | 97 | if (_rl_last_command_was_kill == 0 || rl_kill_ring == 0) |
ccc6cda3 JA |
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; | |
3185942a | 115 | xfree (rl_kill_ring[0]); |
ccc6cda3 JA |
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; | |
d233b485 | 122 | rl_kill_ring = (char **)xrealloc (rl_kill_ring, (slot + 1) * sizeof (char *)); |
ccc6cda3 JA |
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. */ | |
d233b485 | 131 | if (_rl_last_command_was_kill && rl_kill_ring[slot] && rl_editing_mode != vi_mode) |
ccc6cda3 JA |
132 | { |
133 | old = rl_kill_ring[slot]; | |
f73dda09 | 134 | new = (char *)xmalloc (1 + strlen (old) + strlen (text)); |
ccc6cda3 JA |
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 | } | |
3185942a | 146 | xfree (old); |
495aee44 | 147 | xfree (text); |
ccc6cda3 JA |
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 | |
d233b485 | 163 | rl_kill_text (int from, int to) |
ccc6cda3 JA |
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 | |
d233b485 | 197 | rl_kill_word (int count, int key) |
ccc6cda3 | 198 | { |
7117c2d2 | 199 | int orig_point; |
ccc6cda3 JA |
200 | |
201 | if (count < 0) | |
202 | return (rl_backward_kill_word (-count, key)); | |
203 | else | |
204 | { | |
7117c2d2 | 205 | orig_point = rl_point; |
ccc6cda3 JA |
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; | |
7117c2d2 JA |
212 | if (rl_editing_mode == emacs_mode) |
213 | rl_mark = rl_point; | |
ccc6cda3 JA |
214 | } |
215 | return 0; | |
216 | } | |
217 | ||
218 | /* Rubout the word before point, placing it on the kill ring. */ | |
219 | int | |
d233b485 | 220 | rl_backward_kill_word (int count, int key) |
ccc6cda3 | 221 | { |
7117c2d2 | 222 | int orig_point; |
ccc6cda3 JA |
223 | |
224 | if (count < 0) | |
d233b485 | 225 | return (rl_kill_word (-count, key)); |
ccc6cda3 JA |
226 | else |
227 | { | |
7117c2d2 | 228 | orig_point = rl_point; |
d233b485 | 229 | rl_backward_word (count, key); |
ccc6cda3 JA |
230 | |
231 | if (rl_point != orig_point) | |
232 | rl_kill_text (orig_point, rl_point); | |
7117c2d2 JA |
233 | |
234 | if (rl_editing_mode == emacs_mode) | |
235 | rl_mark = rl_point; | |
ccc6cda3 JA |
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 | |
d233b485 | 243 | rl_kill_line (int direction, int key) |
ccc6cda3 | 244 | { |
7117c2d2 | 245 | int orig_point; |
ccc6cda3 JA |
246 | |
247 | if (direction < 0) | |
d233b485 | 248 | return (rl_backward_kill_line (1, key)); |
ccc6cda3 JA |
249 | else |
250 | { | |
7117c2d2 | 251 | orig_point = rl_point; |
d233b485 | 252 | rl_end_of_line (1, key); |
ccc6cda3 JA |
253 | if (orig_point != rl_point) |
254 | rl_kill_text (orig_point, rl_point); | |
255 | rl_point = orig_point; | |
7117c2d2 JA |
256 | if (rl_editing_mode == emacs_mode) |
257 | rl_mark = rl_point; | |
ccc6cda3 JA |
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 | |
d233b485 | 265 | rl_backward_kill_line (int direction, int key) |
ccc6cda3 | 266 | { |
7117c2d2 | 267 | int orig_point; |
ccc6cda3 JA |
268 | |
269 | if (direction < 0) | |
d233b485 | 270 | return (rl_kill_line (1, key)); |
ccc6cda3 JA |
271 | else |
272 | { | |
a0c0a00f | 273 | if (rl_point == 0) |
28ef6c31 | 274 | rl_ding (); |
ccc6cda3 JA |
275 | else |
276 | { | |
7117c2d2 | 277 | orig_point = rl_point; |
d233b485 | 278 | rl_beg_of_line (1, key); |
7117c2d2 JA |
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; | |
ccc6cda3 JA |
283 | } |
284 | } | |
285 | return 0; | |
286 | } | |
287 | ||
288 | /* Kill the whole line, no matter where point is. */ | |
289 | int | |
d233b485 | 290 | rl_kill_full_line (int count, int key) |
ccc6cda3 JA |
291 | { |
292 | rl_begin_undo_group (); | |
293 | rl_point = 0; | |
294 | rl_kill_text (rl_point, rl_end); | |
7117c2d2 | 295 | rl_mark = 0; |
ccc6cda3 JA |
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 | |
d233b485 | 307 | rl_unix_word_rubout (int count, int key) |
ccc6cda3 JA |
308 | { |
309 | int orig_point; | |
310 | ||
311 | if (rl_point == 0) | |
28ef6c31 | 312 | rl_ding (); |
ccc6cda3 JA |
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)) | |
d233b485 | 325 | rl_point--; /* XXX - multibyte? */ |
ccc6cda3 JA |
326 | } |
327 | ||
328 | rl_kill_text (orig_point, rl_point); | |
7117c2d2 JA |
329 | if (rl_editing_mode == emacs_mode) |
330 | rl_mark = rl_point; | |
ccc6cda3 | 331 | } |
b80f6443 JA |
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 | |
d233b485 | 339 | rl_unix_filename_rubout (int count, int key) |
b80f6443 JA |
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 | { | |
d233b485 | 362 | rl_point--; /* XXX - multibyte? */ |
b80f6443 JA |
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 | ||
ccc6cda3 JA |
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 | |
d233b485 | 382 | rl_unix_line_discard (int count, int key) |
ccc6cda3 JA |
383 | { |
384 | if (rl_point == 0) | |
28ef6c31 | 385 | rl_ding (); |
ccc6cda3 JA |
386 | else |
387 | { | |
388 | rl_kill_text (rl_point, 0); | |
389 | rl_point = 0; | |
7117c2d2 JA |
390 | if (rl_editing_mode == emacs_mode) |
391 | rl_mark = rl_point; | |
ccc6cda3 JA |
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 | |
d233b485 | 399 | region_kill_internal (int delete) |
ccc6cda3 JA |
400 | { |
401 | char *text; | |
402 | ||
7117c2d2 | 403 | if (rl_mark != rl_point) |
ccc6cda3 | 404 | { |
7117c2d2 JA |
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); | |
ccc6cda3 JA |
409 | } |
410 | ||
8868edaf | 411 | _rl_fix_point (1); |
ccc6cda3 JA |
412 | _rl_last_command_was_kill++; |
413 | return 0; | |
414 | } | |
415 | ||
416 | /* Copy the text in the region to the kill ring. */ | |
417 | int | |
d233b485 | 418 | rl_copy_region_to_kill (int count, int key) |
ccc6cda3 JA |
419 | { |
420 | return (region_kill_internal (0)); | |
421 | } | |
422 | ||
423 | /* Kill the text between the point and mark. */ | |
424 | int | |
d233b485 | 425 | rl_kill_region (int count, int key) |
ccc6cda3 | 426 | { |
bb70624e | 427 | int r, npoint; |
d166f048 | 428 | |
bb70624e | 429 | npoint = (rl_point < rl_mark) ? rl_point : rl_mark; |
d166f048 | 430 | r = region_kill_internal (1); |
bb70624e | 431 | rl_point = npoint; |
8868edaf | 432 | _rl_fix_point (1); |
d166f048 | 433 | return r; |
ccc6cda3 JA |
434 | } |
435 | ||
436 | /* Copy COUNT words to the kill ring. DIR says which direction we look | |
437 | to find the words. */ | |
438 | static int | |
d233b485 | 439 | _rl_copy_word_as_kill (int count, int dir) |
ccc6cda3 JA |
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 | |
d233b485 | 467 | rl_copy_forward_word (int count, int key) |
ccc6cda3 JA |
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 | |
d233b485 | 476 | rl_copy_backward_word (int count, int key) |
ccc6cda3 JA |
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 | |
d233b485 | 486 | rl_yank (int count, int key) |
ccc6cda3 JA |
487 | { |
488 | if (rl_kill_ring == 0) | |
489 | { | |
490 | _rl_abort_internal (); | |
a0c0a00f | 491 | return 1; |
ccc6cda3 JA |
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 | |
d233b485 | 504 | rl_yank_pop (int count, int key) |
ccc6cda3 JA |
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 (); | |
a0c0a00f | 512 | return 1; |
ccc6cda3 JA |
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 (); | |
a0c0a00f | 530 | return 1; |
ccc6cda3 JA |
531 | } |
532 | } | |
533 | ||
a0c0a00f CR |
534 | #if defined (VI_MODE) |
535 | int | |
d233b485 | 536 | rl_vi_yank_pop (int count, int key) |
a0c0a00f CR |
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 | ||
cce855bc JA |
567 | /* Yank the COUNTh argument from the previous history line, skipping |
568 | HISTORY_SKIP lines before looking for the `previous line'. */ | |
569 | static int | |
d233b485 | 570 | rl_yank_nth_arg_internal (int count, int key, int history_skip) |
ccc6cda3 JA |
571 | { |
572 | register HIST_ENTRY *entry; | |
573 | char *arg; | |
bb70624e JA |
574 | int i, pos; |
575 | ||
576 | pos = where_history (); | |
cce855bc JA |
577 | |
578 | if (history_skip) | |
579 | { | |
580 | for (i = 0; i < history_skip; i++) | |
581 | entry = previous_history (); | |
582 | } | |
ccc6cda3 JA |
583 | |
584 | entry = previous_history (); | |
bb70624e JA |
585 | |
586 | history_set_pos (pos); | |
587 | ||
588 | if (entry == 0) | |
ccc6cda3 | 589 | { |
28ef6c31 | 590 | rl_ding (); |
a0c0a00f | 591 | return 1; |
ccc6cda3 JA |
592 | } |
593 | ||
594 | arg = history_arg_extract (count, count, entry->line); | |
595 | if (!arg || !*arg) | |
596 | { | |
28ef6c31 | 597 | rl_ding (); |
0628567a | 598 | FREE (arg); |
a0c0a00f | 599 | return 1; |
ccc6cda3 JA |
600 | } |
601 | ||
602 | rl_begin_undo_group (); | |
603 | ||
7117c2d2 JA |
604 | _rl_set_mark_at_pos (rl_point); |
605 | ||
ccc6cda3 JA |
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. */ | |
8868edaf | 609 | if (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap) |
ccc6cda3 | 610 | { |
d233b485 | 611 | rl_vi_append_mode (1, key); |
ccc6cda3 JA |
612 | rl_insert_text (" "); |
613 | } | |
614 | #endif /* VI_MODE */ | |
615 | ||
616 | rl_insert_text (arg); | |
495aee44 | 617 | xfree (arg); |
ccc6cda3 JA |
618 | |
619 | rl_end_undo_group (); | |
620 | return 0; | |
621 | } | |
622 | ||
cce855bc JA |
623 | /* Yank the COUNTth argument from the previous history line. */ |
624 | int | |
d233b485 | 625 | rl_yank_nth_arg (int count, int key) |
cce855bc | 626 | { |
d233b485 | 627 | return (rl_yank_nth_arg_internal (count, key, 0)); |
cce855bc JA |
628 | } |
629 | ||
ccc6cda3 JA |
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 | |
d233b485 | 634 | rl_yank_last_arg (int count, int key) |
ccc6cda3 | 635 | { |
cce855bc JA |
636 | static int history_skip = 0; |
637 | static int explicit_arg_p = 0; | |
638 | static int count_passed = 1; | |
639 | static int direction = 1; | |
b72432fd JA |
640 | static int undo_needed = 0; |
641 | int retval; | |
cce855bc JA |
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 | { | |
b72432fd JA |
652 | if (undo_needed) |
653 | rl_do_undo (); | |
495aee44 | 654 | if (count < 0) /* XXX - was < 1 */ |
cce855bc JA |
655 | direction = -direction; |
656 | history_skip += direction; | |
657 | if (history_skip < 0) | |
658 | history_skip = 0; | |
cce855bc JA |
659 | } |
660 | ||
661 | if (explicit_arg_p) | |
b72432fd | 662 | retval = rl_yank_nth_arg_internal (count_passed, key, history_skip); |
ccc6cda3 | 663 | else |
b72432fd JA |
664 | retval = rl_yank_nth_arg_internal ('$', key, history_skip); |
665 | ||
666 | undo_needed = retval == 0; | |
667 | return retval; | |
cce855bc JA |
668 | } |
669 | ||
a0c0a00f CR |
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 | |
8868edaf | 672 | closing sequence and return the pasted text. */ |
d233b485 CR |
673 | char * |
674 | _rl_bracketed_text (size_t *lenp) | |
a0c0a00f | 675 | { |
d233b485 | 676 | int c; |
a0c0a00f CR |
677 | size_t len, cap; |
678 | char *buf; | |
679 | ||
a0c0a00f CR |
680 | len = 0; |
681 | buf = xmalloc (cap = 64); | |
d233b485 | 682 | buf[0] = '\0'; |
a0c0a00f CR |
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'; | |
a0c0a00f CR |
711 | } |
712 | ||
d233b485 CR |
713 | if (lenp) |
714 | *lenp = len; | |
715 | return (buf); | |
716 | } | |
717 | ||
8868edaf CR |
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. */ | |
d233b485 CR |
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); | |
8868edaf | 730 | rl_mark = rl_point; |
d233b485 | 731 | retval = rl_insert_text (buf) == len ? 0 : 1; |
8868edaf CR |
732 | if (_rl_enable_active_region) |
733 | rl_activate_mark (); | |
d233b485 | 734 | |
a0c0a00f CR |
735 | xfree (buf); |
736 | return (retval); | |
737 | } | |
738 | ||
8868edaf CR |
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 | ||
d233b485 | 832 | /* A special paste command for Windows users. */ |
a0c0a00f | 833 | #if defined (_WIN32) |
cce855bc JA |
834 | #include <windows.h> |
835 | ||
836 | int | |
d233b485 | 837 | rl_paste_from_clipboard (int count, int key) |
cce855bc JA |
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; | |
f73dda09 | 852 | ptr = (char *)xmalloc (len + 1); |
cce855bc JA |
853 | ptr[len] = '\0'; |
854 | strncpy (ptr, data, len); | |
855 | } | |
856 | else | |
857 | ptr = data; | |
7117c2d2 | 858 | _rl_set_mark_at_pos (rl_point); |
cce855bc JA |
859 | rl_insert_text (ptr); |
860 | if (ptr != data) | |
3185942a | 861 | xfree (ptr); |
cce855bc JA |
862 | CloseClipboard (); |
863 | } | |
864 | return (0); | |
ccc6cda3 | 865 | } |
a0c0a00f | 866 | #endif /* _WIN32 */ |