kill.c revision 58310
121308Sache/* kill.c -- kill ring management. */ 221308Sache 321308Sache/* Copyright (C) 1994 Free Software Foundation, Inc. 421308Sache 521308Sache This file is part of the GNU Readline Library, a library for 621308Sache reading lines of text with interactive input and history editing. 721308Sache 821308Sache The GNU Readline Library is free software; you can redistribute it 921308Sache and/or modify it under the terms of the GNU General Public License 1058310Sache as published by the Free Software Foundation; either version 2, or 1121308Sache (at your option) any later version. 1221308Sache 1321308Sache The GNU Readline Library is distributed in the hope that it will be 1421308Sache useful, but WITHOUT ANY WARRANTY; without even the implied warranty 1521308Sache of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1621308Sache GNU General Public License for more details. 1721308Sache 1821308Sache The GNU General Public License is often shipped with GNU software, and 1921308Sache is generally kept in a file called COPYING or LICENSE. If you do not 2021308Sache have a copy of the license, write to the Free Software Foundation, 2158310Sache 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ 2221308Sache#define READLINE_LIBRARY 2321308Sache 2421308Sache#if defined (HAVE_CONFIG_H) 2521308Sache# include <config.h> 2621308Sache#endif 2721308Sache 2821308Sache#include <sys/types.h> 2921308Sache 3021308Sache#if defined (HAVE_UNISTD_H) 3121308Sache# include <unistd.h> /* for _POSIX_VERSION */ 3221308Sache#endif /* HAVE_UNISTD_H */ 3321308Sache 3421308Sache#if defined (HAVE_STDLIB_H) 3521308Sache# include <stdlib.h> 3621308Sache#else 3721308Sache# include "ansi_stdlib.h" 3821308Sache#endif /* HAVE_STDLIB_H */ 3921308Sache 4021308Sache#include <stdio.h> 4121308Sache 4221308Sache/* System-specific feature definitions and include files. */ 4321308Sache#include "rldefs.h" 4421308Sache 4521308Sache/* Some standard library routines. */ 4621308Sache#include "readline.h" 4721308Sache#include "history.h" 4821308Sache 4958310Sache#include "rlprivate.h" 5058310Sache#include "xmalloc.h" 5121308Sache 5221308Sache/* **************************************************************** */ 5321308Sache/* */ 5421308Sache/* Killing Mechanism */ 5521308Sache/* */ 5621308Sache/* **************************************************************** */ 5721308Sache 5821308Sache/* What we assume for a max number of kills. */ 5921308Sache#define DEFAULT_MAX_KILLS 10 6021308Sache 6121308Sache/* The real variable to look at to find out when to flush kills. */ 6221308Sachestatic int rl_max_kills = DEFAULT_MAX_KILLS; 6321308Sache 6421308Sache/* Where to store killed text. */ 6521308Sachestatic char **rl_kill_ring = (char **)NULL; 6621308Sache 6721308Sache/* Where we are in the kill ring. */ 6821308Sachestatic int rl_kill_index; 6921308Sache 7021308Sache/* How many slots we have in the kill ring. */ 7121308Sachestatic int rl_kill_ring_length; 7221308Sache 7321308Sache/* How to say that you only want to save a certain amount 7421308Sache of kill material. */ 7521308Sacheint 7621308Sacherl_set_retained_kills (num) 7721308Sache int num; 7821308Sache{ 7921308Sache return 0; 8021308Sache} 8121308Sache 8221308Sache/* Add TEXT to the kill ring, allocating a new kill ring slot as necessary. 8321308Sache This uses TEXT directly, so the caller must not free it. If APPEND is 8421308Sache non-zero, and the last command was a kill, the text is appended to the 8521308Sache current kill ring slot, otherwise prepended. */ 8621308Sachestatic int 8721308Sache_rl_copy_to_kill_ring (text, append) 8821308Sache char *text; 8921308Sache int append; 9021308Sache{ 9121308Sache char *old, *new; 9221308Sache int slot; 9321308Sache 9421308Sache /* First, find the slot to work with. */ 9521308Sache if (_rl_last_command_was_kill == 0) 9621308Sache { 9721308Sache /* Get a new slot. */ 9821308Sache if (rl_kill_ring == 0) 9921308Sache { 10021308Sache /* If we don't have any defined, then make one. */ 10121308Sache rl_kill_ring = (char **) 10221308Sache xmalloc (((rl_kill_ring_length = 1) + 1) * sizeof (char *)); 10321308Sache rl_kill_ring[slot = 0] = (char *)NULL; 10421308Sache } 10521308Sache else 10621308Sache { 10721308Sache /* We have to add a new slot on the end, unless we have 10821308Sache exceeded the max limit for remembering kills. */ 10921308Sache slot = rl_kill_ring_length; 11021308Sache if (slot == rl_max_kills) 11121308Sache { 11221308Sache register int i; 11321308Sache free (rl_kill_ring[0]); 11421308Sache for (i = 0; i < slot; i++) 11521308Sache rl_kill_ring[i] = rl_kill_ring[i + 1]; 11621308Sache } 11721308Sache else 11821308Sache { 11921308Sache slot = rl_kill_ring_length += 1; 12021308Sache rl_kill_ring = (char **)xrealloc (rl_kill_ring, slot * sizeof (char *)); 12121308Sache } 12221308Sache rl_kill_ring[--slot] = (char *)NULL; 12321308Sache } 12421308Sache } 12521308Sache else 12621308Sache slot = rl_kill_ring_length - 1; 12721308Sache 12821308Sache /* If the last command was a kill, prepend or append. */ 12921308Sache if (_rl_last_command_was_kill && rl_editing_mode != vi_mode) 13021308Sache { 13121308Sache old = rl_kill_ring[slot]; 13221308Sache new = xmalloc (1 + strlen (old) + strlen (text)); 13321308Sache 13421308Sache if (append) 13521308Sache { 13621308Sache strcpy (new, old); 13721308Sache strcat (new, text); 13821308Sache } 13921308Sache else 14021308Sache { 14121308Sache strcpy (new, text); 14221308Sache strcat (new, old); 14321308Sache } 14421308Sache free (old); 14521308Sache free (text); 14621308Sache rl_kill_ring[slot] = new; 14721308Sache } 14821308Sache else 14921308Sache rl_kill_ring[slot] = text; 15021308Sache 15121308Sache rl_kill_index = slot; 15221308Sache return 0; 15321308Sache} 15421308Sache 15521308Sache/* The way to kill something. This appends or prepends to the last 15621308Sache kill, if the last command was a kill command. if FROM is less 15721308Sache than TO, then the text is appended, otherwise prepended. If the 15821308Sache last command was not a kill command, then a new slot is made for 15921308Sache this kill. */ 16021308Sacheint 16121308Sacherl_kill_text (from, to) 16221308Sache int from, to; 16321308Sache{ 16421308Sache char *text; 16521308Sache 16621308Sache /* Is there anything to kill? */ 16721308Sache if (from == to) 16821308Sache { 16921308Sache _rl_last_command_was_kill++; 17021308Sache return 0; 17121308Sache } 17221308Sache 17321308Sache text = rl_copy_text (from, to); 17421308Sache 17521308Sache /* Delete the copied text from the line. */ 17621308Sache rl_delete_text (from, to); 17721308Sache 17821308Sache _rl_copy_to_kill_ring (text, from < to); 17921308Sache 18021308Sache _rl_last_command_was_kill++; 18121308Sache return 0; 18221308Sache} 18321308Sache 18421308Sache/* Now REMEMBER! In order to do prepending or appending correctly, kill 18521308Sache commands always make rl_point's original position be the FROM argument, 18621308Sache and rl_point's extent be the TO argument. */ 18721308Sache 18821308Sache/* **************************************************************** */ 18921308Sache/* */ 19021308Sache/* Killing Commands */ 19121308Sache/* */ 19221308Sache/* **************************************************************** */ 19321308Sache 19421308Sache/* Delete the word at point, saving the text in the kill ring. */ 19521308Sacheint 19621308Sacherl_kill_word (count, key) 19721308Sache int count, key; 19821308Sache{ 19921308Sache int orig_point = rl_point; 20021308Sache 20121308Sache if (count < 0) 20221308Sache return (rl_backward_kill_word (-count, key)); 20321308Sache else 20421308Sache { 20521308Sache rl_forward_word (count, key); 20621308Sache 20721308Sache if (rl_point != orig_point) 20821308Sache rl_kill_text (orig_point, rl_point); 20921308Sache 21021308Sache rl_point = orig_point; 21121308Sache } 21221308Sache return 0; 21321308Sache} 21421308Sache 21521308Sache/* Rubout the word before point, placing it on the kill ring. */ 21621308Sacheint 21721308Sacherl_backward_kill_word (count, ignore) 21821308Sache int count, ignore; 21921308Sache{ 22021308Sache int orig_point = rl_point; 22121308Sache 22221308Sache if (count < 0) 22321308Sache return (rl_kill_word (-count, ignore)); 22421308Sache else 22521308Sache { 22621308Sache rl_backward_word (count, ignore); 22721308Sache 22821308Sache if (rl_point != orig_point) 22921308Sache rl_kill_text (orig_point, rl_point); 23021308Sache } 23121308Sache return 0; 23221308Sache} 23321308Sache 23421308Sache/* Kill from here to the end of the line. If DIRECTION is negative, kill 23521308Sache back to the line start instead. */ 23621308Sacheint 23721308Sacherl_kill_line (direction, ignore) 23821308Sache int direction, ignore; 23921308Sache{ 24021308Sache int orig_point = rl_point; 24121308Sache 24221308Sache if (direction < 0) 24321308Sache return (rl_backward_kill_line (1, ignore)); 24421308Sache else 24521308Sache { 24621308Sache rl_end_of_line (1, ignore); 24721308Sache if (orig_point != rl_point) 24821308Sache rl_kill_text (orig_point, rl_point); 24921308Sache rl_point = orig_point; 25021308Sache } 25121308Sache return 0; 25221308Sache} 25321308Sache 25421308Sache/* Kill backwards to the start of the line. If DIRECTION is negative, kill 25521308Sache forwards to the line end instead. */ 25621308Sacheint 25721308Sacherl_backward_kill_line (direction, ignore) 25821308Sache int direction, ignore; 25921308Sache{ 26021308Sache int orig_point = rl_point; 26121308Sache 26221308Sache if (direction < 0) 26321308Sache return (rl_kill_line (1, ignore)); 26421308Sache else 26521308Sache { 26621308Sache if (!rl_point) 26721308Sache ding (); 26821308Sache else 26921308Sache { 27021308Sache rl_beg_of_line (1, ignore); 27121308Sache rl_kill_text (orig_point, rl_point); 27221308Sache } 27321308Sache } 27421308Sache return 0; 27521308Sache} 27621308Sache 27721308Sache/* Kill the whole line, no matter where point is. */ 27821308Sacheint 27921308Sacherl_kill_full_line (count, ignore) 28021308Sache int count, ignore; 28121308Sache{ 28221308Sache rl_begin_undo_group (); 28321308Sache rl_point = 0; 28421308Sache rl_kill_text (rl_point, rl_end); 28521308Sache rl_end_undo_group (); 28621308Sache return 0; 28721308Sache} 28821308Sache 28921308Sache/* The next two functions mimic unix line editing behaviour, except they 29021308Sache save the deleted text on the kill ring. This is safer than not saving 29121308Sache it, and since we have a ring, nobody should get screwed. */ 29221308Sache 29321308Sache/* This does what C-w does in Unix. We can't prevent people from 29421308Sache using behaviour that they expect. */ 29521308Sacheint 29621308Sacherl_unix_word_rubout (count, key) 29721308Sache int count, key; 29821308Sache{ 29921308Sache int orig_point; 30021308Sache 30121308Sache if (rl_point == 0) 30221308Sache ding (); 30321308Sache else 30421308Sache { 30521308Sache orig_point = rl_point; 30621308Sache if (count <= 0) 30721308Sache count = 1; 30821308Sache 30921308Sache while (count--) 31021308Sache { 31121308Sache while (rl_point && whitespace (rl_line_buffer[rl_point - 1])) 31221308Sache rl_point--; 31321308Sache 31421308Sache while (rl_point && (whitespace (rl_line_buffer[rl_point - 1]) == 0)) 31521308Sache rl_point--; 31621308Sache } 31721308Sache 31821308Sache rl_kill_text (orig_point, rl_point); 31921308Sache } 32021308Sache return 0; 32121308Sache} 32221308Sache 32321308Sache/* Here is C-u doing what Unix does. You don't *have* to use these 32421308Sache key-bindings. We have a choice of killing the entire line, or 32521308Sache killing from where we are to the start of the line. We choose the 32621308Sache latter, because if you are a Unix weenie, then you haven't backspaced 32721308Sache into the line at all, and if you aren't, then you know what you are 32821308Sache doing. */ 32921308Sacheint 33021308Sacherl_unix_line_discard (count, key) 33121308Sache int count, key; 33221308Sache{ 33321308Sache if (rl_point == 0) 33421308Sache ding (); 33521308Sache else 33621308Sache { 33721308Sache rl_kill_text (rl_point, 0); 33821308Sache rl_point = 0; 33921308Sache } 34021308Sache return 0; 34121308Sache} 34221308Sache 34321308Sache/* Copy the text in the `region' to the kill ring. If DELETE is non-zero, 34421308Sache delete the text from the line as well. */ 34521308Sachestatic int 34621308Sacheregion_kill_internal (delete) 34721308Sache int delete; 34821308Sache{ 34921308Sache char *text; 35021308Sache 35121308Sache if (rl_mark == rl_point) 35221308Sache { 35321308Sache _rl_last_command_was_kill++; 35421308Sache return 0; 35521308Sache } 35621308Sache 35721308Sache text = rl_copy_text (rl_point, rl_mark); 35821308Sache if (delete) 35921308Sache rl_delete_text (rl_point, rl_mark); 36021308Sache _rl_copy_to_kill_ring (text, rl_point < rl_mark); 36121308Sache 36221308Sache _rl_last_command_was_kill++; 36321308Sache return 0; 36421308Sache} 36521308Sache 36621308Sache/* Copy the text in the region to the kill ring. */ 36721308Sacheint 36821308Sacherl_copy_region_to_kill (count, ignore) 36921308Sache int count, ignore; 37021308Sache{ 37121308Sache return (region_kill_internal (0)); 37221308Sache} 37321308Sache 37421308Sache/* Kill the text between the point and mark. */ 37521308Sacheint 37621308Sacherl_kill_region (count, ignore) 37721308Sache int count, ignore; 37821308Sache{ 37958310Sache int r, npoint; 38026497Sache 38158310Sache npoint = (rl_point < rl_mark) ? rl_point : rl_mark; 38226497Sache r = region_kill_internal (1); 38326497Sache _rl_fix_point (1); 38458310Sache rl_point = npoint; 38526497Sache return r; 38621308Sache} 38721308Sache 38821308Sache/* Copy COUNT words to the kill ring. DIR says which direction we look 38921308Sache to find the words. */ 39021308Sachestatic int 39121308Sache_rl_copy_word_as_kill (count, dir) 39221308Sache int count, dir; 39321308Sache{ 39421308Sache int om, op, r; 39521308Sache 39621308Sache om = rl_mark; 39721308Sache op = rl_point; 39821308Sache 39921308Sache if (dir > 0) 40021308Sache rl_forward_word (count, 0); 40121308Sache else 40221308Sache rl_backward_word (count, 0); 40321308Sache 40421308Sache rl_mark = rl_point; 40521308Sache 40621308Sache if (dir > 0) 40721308Sache rl_backward_word (count, 0); 40821308Sache else 40921308Sache rl_forward_word (count, 0); 41021308Sache 41121308Sache r = region_kill_internal (0); 41221308Sache 41321308Sache rl_mark = om; 41421308Sache rl_point = op; 41521308Sache 41621308Sache return r; 41721308Sache} 41821308Sache 41921308Sacheint 42021308Sacherl_copy_forward_word (count, key) 42121308Sache int count, key; 42221308Sache{ 42321308Sache if (count < 0) 42421308Sache return (rl_copy_backward_word (-count, key)); 42521308Sache 42621308Sache return (_rl_copy_word_as_kill (count, 1)); 42721308Sache} 42821308Sache 42921308Sacheint 43021308Sacherl_copy_backward_word (count, key) 43121308Sache int count, key; 43221308Sache{ 43321308Sache if (count < 0) 43421308Sache return (rl_copy_forward_word (-count, key)); 43521308Sache 43621308Sache return (_rl_copy_word_as_kill (count, -1)); 43721308Sache} 43821308Sache 43921308Sache/* Yank back the last killed text. This ignores arguments. */ 44021308Sacheint 44121308Sacherl_yank (count, ignore) 44221308Sache int count, ignore; 44321308Sache{ 44421308Sache if (rl_kill_ring == 0) 44521308Sache { 44621308Sache _rl_abort_internal (); 44721308Sache return -1; 44821308Sache } 44921308Sache 45021308Sache _rl_set_mark_at_pos (rl_point); 45121308Sache rl_insert_text (rl_kill_ring[rl_kill_index]); 45221308Sache return 0; 45321308Sache} 45421308Sache 45521308Sache/* If the last command was yank, or yank_pop, and the text just 45621308Sache before point is identical to the current kill item, then 45721308Sache delete that text from the line, rotate the index down, and 45821308Sache yank back some other text. */ 45921308Sacheint 46021308Sacherl_yank_pop (count, key) 46121308Sache int count, key; 46221308Sache{ 46321308Sache int l, n; 46421308Sache 46521308Sache if (((rl_last_func != rl_yank_pop) && (rl_last_func != rl_yank)) || 46621308Sache !rl_kill_ring) 46721308Sache { 46821308Sache _rl_abort_internal (); 46921308Sache return -1; 47021308Sache } 47121308Sache 47221308Sache l = strlen (rl_kill_ring[rl_kill_index]); 47321308Sache n = rl_point - l; 47421308Sache if (n >= 0 && STREQN (rl_line_buffer + n, rl_kill_ring[rl_kill_index], l)) 47521308Sache { 47621308Sache rl_delete_text (n, rl_point); 47721308Sache rl_point = n; 47821308Sache rl_kill_index--; 47921308Sache if (rl_kill_index < 0) 48021308Sache rl_kill_index = rl_kill_ring_length - 1; 48121308Sache rl_yank (1, 0); 48221308Sache return 0; 48321308Sache } 48421308Sache else 48521308Sache { 48621308Sache _rl_abort_internal (); 48721308Sache return -1; 48821308Sache } 48921308Sache} 49021308Sache 49135486Sache/* Yank the COUNTh argument from the previous history line, skipping 49235486Sache HISTORY_SKIP lines before looking for the `previous line'. */ 49335486Sachestatic int 49435486Sacherl_yank_nth_arg_internal (count, ignore, history_skip) 49535486Sache int count, ignore, history_skip; 49621308Sache{ 49721308Sache register HIST_ENTRY *entry; 49821308Sache char *arg; 49958310Sache int i, pos; 50021308Sache 50158310Sache pos = where_history (); 50258310Sache 50335486Sache if (history_skip) 50435486Sache { 50535486Sache for (i = 0; i < history_skip; i++) 50635486Sache entry = previous_history (); 50735486Sache } 50835486Sache 50921308Sache entry = previous_history (); 51058310Sache 51158310Sache history_set_pos (pos); 51258310Sache 51358310Sache if (entry == 0) 51435486Sache { 51521308Sache ding (); 51621308Sache return -1; 51721308Sache } 51821308Sache 51921308Sache arg = history_arg_extract (count, count, entry->line); 52021308Sache if (!arg || !*arg) 52121308Sache { 52221308Sache ding (); 52321308Sache return -1; 52421308Sache } 52521308Sache 52621308Sache rl_begin_undo_group (); 52721308Sache 52821308Sache#if defined (VI_MODE) 52921308Sache /* Vi mode always inserts a space before yanking the argument, and it 53021308Sache inserts it right *after* rl_point. */ 53121308Sache if (rl_editing_mode == vi_mode) 53221308Sache { 53326497Sache rl_vi_append_mode (1, ignore); 53421308Sache rl_insert_text (" "); 53521308Sache } 53621308Sache#endif /* VI_MODE */ 53721308Sache 53821308Sache rl_insert_text (arg); 53921308Sache free (arg); 54021308Sache 54121308Sache rl_end_undo_group (); 54221308Sache return 0; 54321308Sache} 54421308Sache 54535486Sache/* Yank the COUNTth argument from the previous history line. */ 54635486Sacheint 54735486Sacherl_yank_nth_arg (count, ignore) 54835486Sache int count, ignore; 54935486Sache{ 55035486Sache return (rl_yank_nth_arg_internal (count, ignore, 0)); 55135486Sache} 55235486Sache 55321308Sache/* Yank the last argument from the previous history line. This `knows' 55421308Sache how rl_yank_nth_arg treats a count of `$'. With an argument, this 55521308Sache behaves the same as rl_yank_nth_arg. */ 55621308Sacheint 55721308Sacherl_yank_last_arg (count, key) 55821308Sache int count, key; 55921308Sache{ 56035486Sache static int history_skip = 0; 56135486Sache static int explicit_arg_p = 0; 56235486Sache static int count_passed = 1; 56335486Sache static int direction = 1; 56447558Sache static int undo_needed = 0; 56547558Sache int retval; 56635486Sache 56735486Sache if (rl_last_func != rl_yank_last_arg) 56835486Sache { 56935486Sache history_skip = 0; 57035486Sache explicit_arg_p = rl_explicit_arg; 57135486Sache count_passed = count; 57235486Sache direction = 1; 57335486Sache } 57421308Sache else 57535486Sache { 57647558Sache if (undo_needed) 57747558Sache rl_do_undo (); 57835486Sache if (count < 1) 57935486Sache direction = -direction; 58035486Sache history_skip += direction; 58135486Sache if (history_skip < 0) 58235486Sache history_skip = 0; 58335486Sache } 58435486Sache 58535486Sache if (explicit_arg_p) 58647558Sache retval = rl_yank_nth_arg_internal (count_passed, key, history_skip); 58735486Sache else 58847558Sache retval = rl_yank_nth_arg_internal ('$', key, history_skip); 58947558Sache 59047558Sache undo_needed = retval == 0; 59147558Sache return retval; 59221308Sache} 59335486Sache 59435486Sache/* A special paste command for users of Cygnus's cygwin32. */ 59535486Sache#if defined (__CYGWIN32__) 59635486Sache#include <windows.h> 59735486Sache 59835486Sacheint 59935486Sacherl_paste_from_clipboard (count, key) 60035486Sache int count, key; 60135486Sache{ 60235486Sache char *data, *ptr; 60335486Sache int len; 60435486Sache 60535486Sache if (OpenClipboard (NULL) == 0) 60635486Sache return (0); 60735486Sache 60835486Sache data = (char *)GetClipboardData (CF_TEXT); 60935486Sache if (data) 61035486Sache { 61135486Sache ptr = strchr (data, '\r'); 61235486Sache if (ptr) 61335486Sache { 61435486Sache len = ptr - data; 61535486Sache ptr = xmalloc (len + 1); 61635486Sache ptr[len] = '\0'; 61735486Sache strncpy (ptr, data, len); 61835486Sache } 61935486Sache else 62035486Sache ptr = data; 62135486Sache rl_insert_text (ptr); 62235486Sache if (ptr != data) 62335486Sache free (ptr); 62435486Sache CloseClipboard (); 62535486Sache } 62635486Sache return (0); 62735486Sache} 62835486Sache#endif /* __CYGWIN32__ */ 629