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