00001 /* kill.c -- kill ring management. */ 00002 00003 /* Copyright (C) 1994 Free Software Foundation, Inc. 00004 00005 This file is part of the GNU Readline Library, a library for 00006 reading lines of text with interactive input and history editing. 00007 00008 The GNU Readline Library is free software; you can redistribute it 00009 and/or modify it under the terms of the GNU General Public License 00010 as published by the Free Software Foundation; either version 2, or 00011 (at your option) any later version. 00012 00013 The GNU Readline Library is distributed in the hope that it will be 00014 useful, but WITHOUT ANY WARRANTY; without even the implied warranty 00015 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details. 00017 00018 The GNU General Public License is often shipped with GNU software, and 00019 is generally kept in a file called COPYING or LICENSE. If you do not 00020 have a copy of the license, write to the Free Software Foundation, 00021 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ 00022 #define READLINE_LIBRARY 00023 00024 #include "config_readline.h" 00025 00026 #include <sys/types.h> 00027 00028 #if defined (HAVE_UNISTD_H) 00029 # include <unistd.h> /* for _POSIX_VERSION */ 00030 #endif /* HAVE_UNISTD_H */ 00031 00032 #if defined (HAVE_STDLIB_H) 00033 # include <stdlib.h> 00034 #else 00035 # include "ansi_stdlib.h" 00036 #endif /* HAVE_STDLIB_H */ 00037 00038 #include <stdio.h> 00039 00040 /* System-specific feature definitions and include files. */ 00041 #include "rldefs.h" 00042 00043 /* Some standard library routines. */ 00044 #include "readline.h" 00045 #include "history.h" 00046 00047 #include "rlprivate.h" 00048 #include "xmalloc.h" 00049 00050 /* **************************************************************** */ 00051 /* */ 00052 /* Killing Mechanism */ 00053 /* */ 00054 /* **************************************************************** */ 00055 00056 /* What we assume for a max number of kills. */ 00057 #define DEFAULT_MAX_KILLS 10 00058 00059 /* The real variable to look at to find out when to flush kills. */ 00060 static int rl_max_kills = DEFAULT_MAX_KILLS; 00061 00062 /* Where to store killed text. */ 00063 static char **rl_kill_ring = (char **)NULL; 00064 00065 /* Where we are in the kill ring. */ 00066 static int rl_kill_index; 00067 00068 /* How many slots we have in the kill ring. */ 00069 static int rl_kill_ring_length; 00070 00071 static int _rl_copy_to_kill_ring PARAMS((char *, int)); 00072 static int region_kill_internal PARAMS((int)); 00073 static int _rl_copy_word_as_kill PARAMS((int, int)); 00074 static int rl_yank_nth_arg_internal PARAMS((int, int, int)); 00075 00076 /* How to say that you only want to save a certain amount 00077 of kill material. */ 00078 int 00079 rl_set_retained_kills (num) 00080 int num; 00081 { 00082 return 0; 00083 } 00084 00085 /* Add TEXT to the kill ring, allocating a new kill ring slot as necessary. 00086 This uses TEXT directly, so the caller must not free it. If APPEND is 00087 non-zero, and the last command was a kill, the text is appended to the 00088 current kill ring slot, otherwise prepended. */ 00089 static int 00090 _rl_copy_to_kill_ring (text, append) 00091 char *text; 00092 int append; 00093 { 00094 char *old, *new; 00095 int slot; 00096 00097 /* First, find the slot to work with. */ 00098 if (_rl_last_command_was_kill == 0) 00099 { 00100 /* Get a new slot. */ 00101 if (rl_kill_ring == 0) 00102 { 00103 /* If we don't have any defined, then make one. */ 00104 rl_kill_ring = (char **) 00105 xmalloc (((rl_kill_ring_length = 1) + 1) * sizeof (char *)); 00106 rl_kill_ring[slot = 0] = (char *)NULL; 00107 } 00108 else 00109 { 00110 /* We have to add a new slot on the end, unless we have 00111 exceeded the max limit for remembering kills. */ 00112 slot = rl_kill_ring_length; 00113 if (slot == rl_max_kills) 00114 { 00115 register int i; 00116 free (rl_kill_ring[0]); 00117 for (i = 0; i < slot; i++) 00118 rl_kill_ring[i] = rl_kill_ring[i + 1]; 00119 } 00120 else 00121 { 00122 slot = rl_kill_ring_length += 1; 00123 rl_kill_ring = (char **)xrealloc (rl_kill_ring, slot * sizeof (char *)); 00124 } 00125 rl_kill_ring[--slot] = (char *)NULL; 00126 } 00127 } 00128 else 00129 slot = rl_kill_ring_length - 1; 00130 00131 /* If the last command was a kill, prepend or append. */ 00132 if (_rl_last_command_was_kill && rl_editing_mode != vi_mode) 00133 { 00134 old = rl_kill_ring[slot]; 00135 new = (char *)xmalloc (1 + strlen (old) + strlen (text)); 00136 00137 if (append) 00138 { 00139 strcpy (new, old); 00140 strcat (new, text); 00141 } 00142 else 00143 { 00144 strcpy (new, text); 00145 strcat (new, old); 00146 } 00147 free (old); 00148 free (text); 00149 rl_kill_ring[slot] = new; 00150 } 00151 else 00152 rl_kill_ring[slot] = text; 00153 00154 rl_kill_index = slot; 00155 return 0; 00156 } 00157 00158 /* The way to kill something. This appends or prepends to the last 00159 kill, if the last command was a kill command. if FROM is less 00160 than TO, then the text is appended, otherwise prepended. If the 00161 last command was not a kill command, then a new slot is made for 00162 this kill. */ 00163 int 00164 rl_kill_text (from, to) 00165 int from, to; 00166 { 00167 char *text; 00168 00169 /* Is there anything to kill? */ 00170 if (from == to) 00171 { 00172 _rl_last_command_was_kill++; 00173 return 0; 00174 } 00175 00176 text = rl_copy_text (from, to); 00177 00178 /* Delete the copied text from the line. */ 00179 rl_delete_text (from, to); 00180 00181 _rl_copy_to_kill_ring (text, from < to); 00182 00183 _rl_last_command_was_kill++; 00184 return 0; 00185 } 00186 00187 /* Now REMEMBER! In order to do prepending or appending correctly, kill 00188 commands always make rl_point's original position be the FROM argument, 00189 and rl_point's extent be the TO argument. */ 00190 00191 /* **************************************************************** */ 00192 /* */ 00193 /* Killing Commands */ 00194 /* */ 00195 /* **************************************************************** */ 00196 00197 /* Delete the word at point, saving the text in the kill ring. */ 00198 int 00199 rl_kill_word (count, key) 00200 int count, key; 00201 { 00202 int orig_point; 00203 00204 if (count < 0) 00205 return (rl_backward_kill_word (-count, key)); 00206 else 00207 { 00208 orig_point = rl_point; 00209 rl_forward_word (count, key); 00210 00211 if (rl_point != orig_point) 00212 rl_kill_text (orig_point, rl_point); 00213 00214 rl_point = orig_point; 00215 if (rl_editing_mode == emacs_mode) 00216 rl_mark = rl_point; 00217 } 00218 return 0; 00219 } 00220 00221 /* Rubout the word before point, placing it on the kill ring. */ 00222 int 00223 rl_backward_kill_word (count, ignore) 00224 int count, ignore; 00225 { 00226 int orig_point; 00227 00228 if (count < 0) 00229 return (rl_kill_word (-count, ignore)); 00230 else 00231 { 00232 orig_point = rl_point; 00233 rl_backward_word (count, ignore); 00234 00235 if (rl_point != orig_point) 00236 rl_kill_text (orig_point, rl_point); 00237 00238 if (rl_editing_mode == emacs_mode) 00239 rl_mark = rl_point; 00240 } 00241 return 0; 00242 } 00243 00244 /* Kill from here to the end of the line. If DIRECTION is negative, kill 00245 back to the line start instead. */ 00246 int 00247 rl_kill_line (direction, ignore) 00248 int direction, ignore; 00249 { 00250 int orig_point; 00251 00252 if (direction < 0) 00253 return (rl_backward_kill_line (1, ignore)); 00254 else 00255 { 00256 orig_point = rl_point; 00257 rl_end_of_line (1, ignore); 00258 if (orig_point != rl_point) 00259 rl_kill_text (orig_point, rl_point); 00260 rl_point = orig_point; 00261 if (rl_editing_mode == emacs_mode) 00262 rl_mark = rl_point; 00263 } 00264 return 0; 00265 } 00266 00267 /* Kill backwards to the start of the line. If DIRECTION is negative, kill 00268 forwards to the line end instead. */ 00269 int 00270 rl_backward_kill_line (direction, ignore) 00271 int direction, ignore; 00272 { 00273 int orig_point; 00274 00275 if (direction < 0) 00276 return (rl_kill_line (1, ignore)); 00277 else 00278 { 00279 if (!rl_point) 00280 rl_ding (); 00281 else 00282 { 00283 orig_point = rl_point; 00284 rl_beg_of_line (1, ignore); 00285 if (rl_point != orig_point) 00286 rl_kill_text (orig_point, rl_point); 00287 if (rl_editing_mode == emacs_mode) 00288 rl_mark = rl_point; 00289 } 00290 } 00291 return 0; 00292 } 00293 00294 /* Kill the whole line, no matter where point is. */ 00295 int 00296 rl_kill_full_line (count, ignore) 00297 int count, ignore; 00298 { 00299 rl_begin_undo_group (); 00300 rl_point = 0; 00301 rl_kill_text (rl_point, rl_end); 00302 rl_mark = 0; 00303 rl_end_undo_group (); 00304 return 0; 00305 } 00306 00307 /* The next two functions mimic unix line editing behaviour, except they 00308 save the deleted text on the kill ring. This is safer than not saving 00309 it, and since we have a ring, nobody should get screwed. */ 00310 00311 /* This does what C-w does in Unix. We can't prevent people from 00312 using behaviour that they expect. */ 00313 int 00314 rl_unix_word_rubout (count, key) 00315 int count, key; 00316 { 00317 int orig_point; 00318 00319 if (rl_point == 0) 00320 rl_ding (); 00321 else 00322 { 00323 orig_point = rl_point; 00324 if (count <= 0) 00325 count = 1; 00326 00327 while (count--) 00328 { 00329 while (rl_point && whitespace (rl_line_buffer[rl_point - 1])) 00330 rl_point--; 00331 00332 while (rl_point && (whitespace (rl_line_buffer[rl_point - 1]) == 0)) 00333 rl_point--; 00334 } 00335 00336 rl_kill_text (orig_point, rl_point); 00337 if (rl_editing_mode == emacs_mode) 00338 rl_mark = rl_point; 00339 } 00340 00341 return 0; 00342 } 00343 00344 /* This deletes one filename component in a Unix pathname. That is, it 00345 deletes backward to directory separator (`/') or whitespace. */ 00346 int 00347 rl_unix_filename_rubout (count, key) 00348 int count, key; 00349 { 00350 int orig_point, c; 00351 00352 if (rl_point == 0) 00353 rl_ding (); 00354 else 00355 { 00356 orig_point = rl_point; 00357 if (count <= 0) 00358 count = 1; 00359 00360 while (count--) 00361 { 00362 c = rl_line_buffer[rl_point - 1]; 00363 while (rl_point && (whitespace (c) || c == '/')) 00364 { 00365 rl_point--; 00366 c = rl_line_buffer[rl_point - 1]; 00367 } 00368 00369 while (rl_point && (whitespace (c) == 0) && c != '/') 00370 { 00371 rl_point--; 00372 c = rl_line_buffer[rl_point - 1]; 00373 } 00374 } 00375 00376 rl_kill_text (orig_point, rl_point); 00377 if (rl_editing_mode == emacs_mode) 00378 rl_mark = rl_point; 00379 } 00380 00381 return 0; 00382 } 00383 00384 /* Here is C-u doing what Unix does. You don't *have* to use these 00385 key-bindings. We have a choice of killing the entire line, or 00386 killing from where we are to the start of the line. We choose the 00387 latter, because if you are a Unix weenie, then you haven't backspaced 00388 into the line at all, and if you aren't, then you know what you are 00389 doing. */ 00390 int 00391 rl_unix_line_discard (count, key) 00392 int count, key; 00393 { 00394 if (rl_point == 0) 00395 rl_ding (); 00396 else 00397 { 00398 rl_kill_text (rl_point, 0); 00399 rl_point = 0; 00400 if (rl_editing_mode == emacs_mode) 00401 rl_mark = rl_point; 00402 } 00403 return 0; 00404 } 00405 00406 /* Copy the text in the `region' to the kill ring. If DELETE is non-zero, 00407 delete the text from the line as well. */ 00408 static int 00409 region_kill_internal (delete) 00410 int delete; 00411 { 00412 char *text; 00413 00414 if (rl_mark != rl_point) 00415 { 00416 text = rl_copy_text (rl_point, rl_mark); 00417 if (delete) 00418 rl_delete_text (rl_point, rl_mark); 00419 _rl_copy_to_kill_ring (text, rl_point < rl_mark); 00420 } 00421 00422 _rl_last_command_was_kill++; 00423 return 0; 00424 } 00425 00426 /* Copy the text in the region to the kill ring. */ 00427 int 00428 rl_copy_region_to_kill (count, ignore) 00429 int count, ignore; 00430 { 00431 return (region_kill_internal (0)); 00432 } 00433 00434 /* Kill the text between the point and mark. */ 00435 int 00436 rl_kill_region (count, ignore) 00437 int count, ignore; 00438 { 00439 int r, npoint; 00440 00441 npoint = (rl_point < rl_mark) ? rl_point : rl_mark; 00442 r = region_kill_internal (1); 00443 _rl_fix_point (1); 00444 rl_point = npoint; 00445 return r; 00446 } 00447 00448 /* Copy COUNT words to the kill ring. DIR says which direction we look 00449 to find the words. */ 00450 static int 00451 _rl_copy_word_as_kill (count, dir) 00452 int count, dir; 00453 { 00454 int om, op, r; 00455 00456 om = rl_mark; 00457 op = rl_point; 00458 00459 if (dir > 0) 00460 rl_forward_word (count, 0); 00461 else 00462 rl_backward_word (count, 0); 00463 00464 rl_mark = rl_point; 00465 00466 if (dir > 0) 00467 rl_backward_word (count, 0); 00468 else 00469 rl_forward_word (count, 0); 00470 00471 r = region_kill_internal (0); 00472 00473 rl_mark = om; 00474 rl_point = op; 00475 00476 return r; 00477 } 00478 00479 int 00480 rl_copy_forward_word (count, key) 00481 int count, key; 00482 { 00483 if (count < 0) 00484 return (rl_copy_backward_word (-count, key)); 00485 00486 return (_rl_copy_word_as_kill (count, 1)); 00487 } 00488 00489 int 00490 rl_copy_backward_word (count, key) 00491 int count, key; 00492 { 00493 if (count < 0) 00494 return (rl_copy_forward_word (-count, key)); 00495 00496 return (_rl_copy_word_as_kill (count, -1)); 00497 } 00498 00499 /* Yank back the last killed text. This ignores arguments. */ 00500 int 00501 rl_yank (count, ignore) 00502 int count, ignore; 00503 { 00504 if (rl_kill_ring == 0) 00505 { 00506 _rl_abort_internal (); 00507 return -1; 00508 } 00509 00510 _rl_set_mark_at_pos (rl_point); 00511 rl_insert_text (rl_kill_ring[rl_kill_index]); 00512 return 0; 00513 } 00514 00515 /* If the last command was yank, or yank_pop, and the text just 00516 before point is identical to the current kill item, then 00517 delete that text from the line, rotate the index down, and 00518 yank back some other text. */ 00519 int 00520 rl_yank_pop (count, key) 00521 int count, key; 00522 { 00523 int l, n; 00524 00525 if (((rl_last_func != rl_yank_pop) && (rl_last_func != rl_yank)) || 00526 !rl_kill_ring) 00527 { 00528 _rl_abort_internal (); 00529 return -1; 00530 } 00531 00532 l = strlen (rl_kill_ring[rl_kill_index]); 00533 n = rl_point - l; 00534 if (n >= 0 && STREQN (rl_line_buffer + n, rl_kill_ring[rl_kill_index], l)) 00535 { 00536 rl_delete_text (n, rl_point); 00537 rl_point = n; 00538 rl_kill_index--; 00539 if (rl_kill_index < 0) 00540 rl_kill_index = rl_kill_ring_length - 1; 00541 rl_yank (1, 0); 00542 return 0; 00543 } 00544 else 00545 { 00546 _rl_abort_internal (); 00547 return -1; 00548 } 00549 } 00550 00551 /* Yank the COUNTh argument from the previous history line, skipping 00552 HISTORY_SKIP lines before looking for the `previous line'. */ 00553 static int 00554 rl_yank_nth_arg_internal (count, ignore, history_skip) 00555 int count, ignore, history_skip; 00556 { 00557 register HIST_ENTRY *entry; 00558 char *arg; 00559 int i, pos; 00560 00561 pos = where_history (); 00562 00563 if (history_skip) 00564 { 00565 for (i = 0; i < history_skip; i++) 00566 entry = previous_history (); 00567 } 00568 00569 entry = previous_history (); 00570 00571 history_set_pos (pos); 00572 00573 if (entry == 0) 00574 { 00575 rl_ding (); 00576 return -1; 00577 } 00578 00579 arg = history_arg_extract (count, count, entry->line); 00580 if (!arg || !*arg) 00581 { 00582 rl_ding (); 00583 return -1; 00584 } 00585 00586 rl_begin_undo_group (); 00587 00588 _rl_set_mark_at_pos (rl_point); 00589 00590 #if defined (VI_MODE) 00591 /* Vi mode always inserts a space before yanking the argument, and it 00592 inserts it right *after* rl_point. */ 00593 if (rl_editing_mode == vi_mode) 00594 { 00595 rl_vi_append_mode (1, ignore); 00596 rl_insert_text (" "); 00597 } 00598 #endif /* VI_MODE */ 00599 00600 rl_insert_text (arg); 00601 free (arg); 00602 00603 rl_end_undo_group (); 00604 return 0; 00605 } 00606 00607 /* Yank the COUNTth argument from the previous history line. */ 00608 int 00609 rl_yank_nth_arg (count, ignore) 00610 int count, ignore; 00611 { 00612 return (rl_yank_nth_arg_internal (count, ignore, 0)); 00613 } 00614 00615 /* Yank the last argument from the previous history line. This `knows' 00616 how rl_yank_nth_arg treats a count of `$'. With an argument, this 00617 behaves the same as rl_yank_nth_arg. */ 00618 int 00619 rl_yank_last_arg (count, key) 00620 int count, key; 00621 { 00622 static int history_skip = 0; 00623 static int explicit_arg_p = 0; 00624 static int count_passed = 1; 00625 static int direction = 1; 00626 static int undo_needed = 0; 00627 int retval; 00628 00629 if (rl_last_func != rl_yank_last_arg) 00630 { 00631 history_skip = 0; 00632 explicit_arg_p = rl_explicit_arg; 00633 count_passed = count; 00634 direction = 1; 00635 } 00636 else 00637 { 00638 if (undo_needed) 00639 rl_do_undo (); 00640 if (count < 1) 00641 direction = -direction; 00642 history_skip += direction; 00643 if (history_skip < 0) 00644 history_skip = 0; 00645 } 00646 00647 if (explicit_arg_p) 00648 retval = rl_yank_nth_arg_internal (count_passed, key, history_skip); 00649 else 00650 retval = rl_yank_nth_arg_internal ('$', key, history_skip); 00651 00652 undo_needed = retval == 0; 00653 return retval; 00654 } 00655 00656 /* A special paste command for users of Cygnus's cygwin32. */ 00657 #if defined (__CYGWIN__) 00658 #include <windows.h> 00659 00660 int 00661 rl_paste_from_clipboard (count, key) 00662 int count, key; 00663 { 00664 char *data, *ptr; 00665 int len; 00666 00667 if (OpenClipboard (NULL) == 0) 00668 return (0); 00669 00670 data = (char *)GetClipboardData (CF_TEXT); 00671 if (data) 00672 { 00673 ptr = strchr (data, '\r'); 00674 if (ptr) 00675 { 00676 len = ptr - data; 00677 ptr = (char *)xmalloc (len + 1); 00678 ptr[len] = '\0'; 00679 strncpy (ptr, data, len); 00680 } 00681 else 00682 ptr = data; 00683 _rl_set_mark_at_pos (rl_point); 00684 rl_insert_text (ptr); 00685 if (ptr != data) 00686 free (ptr); 00687 CloseClipboard (); 00688 } 00689 return (0); 00690 } 00691 #endif /* __CYGWIN__ */
1.4.7

