121308Sache/* readline.c -- a general facility for reading lines of input 221308Sache with emacs style editing and completion. */ 321308Sache 4165670Sache/* Copyright (C) 1987, 1989, 1992, 2006 Free Software Foundation, Inc. 521308Sache 621308Sache This file is part of the GNU Readline Library, a library for 721308Sache reading lines of text with interactive input and history editing. 821308Sache 921308Sache The GNU Readline Library is free software; you can redistribute it 1021308Sache and/or modify it under the terms of the GNU General Public License 1158310Sache as published by the Free Software Foundation; either version 2, or 1221308Sache (at your option) any later version. 1321308Sache 1421308Sache The GNU Readline Library is distributed in the hope that it will be 1521308Sache useful, but WITHOUT ANY WARRANTY; without even the implied warranty 1621308Sache of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1721308Sache GNU General Public License for more details. 1821308Sache 1921308Sache The GNU General Public License is often shipped with GNU software, and 2021308Sache is generally kept in a file called COPYING or LICENSE. If you do not 2121308Sache have a copy of the license, write to the Free Software Foundation, 2258310Sache 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ 2321308Sache#define READLINE_LIBRARY 2421308Sache 2521308Sache#if defined (HAVE_CONFIG_H) 2621308Sache# include <config.h> 2721308Sache#endif 2821308Sache 2921308Sache#include <sys/types.h> 3021308Sache 3121308Sache#if defined (HAVE_UNISTD_H) 3221308Sache# include <unistd.h> /* for _POSIX_VERSION */ 3321308Sache#endif /* HAVE_UNISTD_H */ 3421308Sache 3521308Sache#if defined (HAVE_STDLIB_H) 3621308Sache# include <stdlib.h> 3721308Sache#else 3821308Sache# include "ansi_stdlib.h" 3921308Sache#endif /* HAVE_STDLIB_H */ 4021308Sache 4121308Sache#include <stdio.h> 4221308Sache 4321308Sache/* System-specific feature definitions and include files. */ 4421308Sache#include "rldefs.h" 4521308Sache 4621308Sache/* Some standard library routines. */ 4721308Sache#include "readline.h" 4821308Sache#include "history.h" 4921308Sache 5058310Sache#include "rlprivate.h" 51119610Sache#include "xmalloc.h" 5258310Sache 53165670Sacheextern void replace_history_data PARAMS((int, histdata_t *, histdata_t *)); 54165670Sache 5521308Sache/* Non-zero tells rl_delete_text and rl_insert_text to not add to 5621308Sache the undo list. */ 5721308Sacheint _rl_doing_an_undo = 0; 5821308Sache 5921308Sache/* How many unclosed undo groups we currently have. */ 6021308Sacheint _rl_undo_group_level = 0; 6121308Sache 6221308Sache/* The current undo list for THE_LINE. */ 6321308SacheUNDO_LIST *rl_undo_list = (UNDO_LIST *)NULL; 6421308Sache 6521308Sache/* **************************************************************** */ 6621308Sache/* */ 6721308Sache/* Undo, and Undoing */ 6821308Sache/* */ 6921308Sache/* **************************************************************** */ 7021308Sache 71165670Sachestatic UNDO_LIST * 72165670Sachealloc_undo_entry (what, start, end, text) 73165670Sache enum undo_code what; 74165670Sache int start, end; 75165670Sache char *text; 76165670Sache{ 77165670Sache UNDO_LIST *temp; 78165670Sache 79165670Sache temp = (UNDO_LIST *)xmalloc (sizeof (UNDO_LIST)); 80165670Sache temp->what = what; 81165670Sache temp->start = start; 82165670Sache temp->end = end; 83165670Sache temp->text = text; 84165670Sache 85165670Sache temp->next = (UNDO_LIST *)NULL; 86165670Sache return temp; 87165670Sache} 88165670Sache 8921308Sache/* Remember how to undo something. Concatenate some undos if that 9021308Sache seems right. */ 9121308Sachevoid 9221308Sacherl_add_undo (what, start, end, text) 9321308Sache enum undo_code what; 9421308Sache int start, end; 9521308Sache char *text; 9621308Sache{ 97165670Sache UNDO_LIST *temp; 98165670Sache 99165670Sache temp = alloc_undo_entry (what, start, end, text); 10021308Sache temp->next = rl_undo_list; 10121308Sache rl_undo_list = temp; 10221308Sache} 10321308Sache 10421308Sache/* Free the existing undo list. */ 10521308Sachevoid 10675406Sacherl_free_undo_list () 10721308Sache{ 108165670Sache UNDO_LIST *release, *orig_list; 109165670Sache 110165670Sache orig_list = rl_undo_list; 11121308Sache while (rl_undo_list) 11221308Sache { 113165670Sache release = rl_undo_list; 11421308Sache rl_undo_list = rl_undo_list->next; 11521308Sache 11621308Sache if (release->what == UNDO_DELETE) 11721308Sache free (release->text); 11821308Sache 11921308Sache free (release); 12021308Sache } 12121308Sache rl_undo_list = (UNDO_LIST *)NULL; 122165670Sache replace_history_data (-1, (histdata_t *)orig_list, (histdata_t *)NULL); 12321308Sache} 12421308Sache 125165670SacheUNDO_LIST * 126165670Sache_rl_copy_undo_entry (entry) 127165670Sache UNDO_LIST *entry; 128165670Sache{ 129165670Sache UNDO_LIST *new; 130165670Sache 131165670Sache new = alloc_undo_entry (entry->what, entry->start, entry->end, (char *)NULL); 132165670Sache new->text = entry->text ? savestring (entry->text) : 0; 133165670Sache return new; 134165670Sache} 135165670Sache 136165670SacheUNDO_LIST * 137165670Sache_rl_copy_undo_list (head) 138165670Sache UNDO_LIST *head; 139165670Sache{ 140165670Sache UNDO_LIST *list, *new, *roving, *c; 141165670Sache 142165670Sache list = head; 143165670Sache new = 0; 144165670Sache while (list) 145165670Sache { 146165670Sache c = _rl_copy_undo_entry (list); 147165670Sache if (new == 0) 148165670Sache roving = new = c; 149165670Sache else 150165670Sache { 151165670Sache roving->next = c; 152165670Sache roving = roving->next; 153165670Sache } 154165670Sache list = list->next; 155165670Sache } 156165670Sache 157165670Sache roving->next = 0; 158165670Sache return new; 159165670Sache} 160165670Sache 16121308Sache/* Undo the next thing in the list. Return 0 if there 16221308Sache is nothing to undo, or non-zero if there was. */ 16321308Sacheint 16421308Sacherl_do_undo () 16521308Sache{ 16621308Sache UNDO_LIST *release; 16775406Sache int waiting_for_begin, start, end; 16821308Sache 16921308Sache#define TRANS(i) ((i) == -1 ? rl_point : ((i) == -2 ? rl_end : (i))) 17021308Sache 17175406Sache start = end = waiting_for_begin = 0; 17221308Sache do 17321308Sache { 17421308Sache if (!rl_undo_list) 17521308Sache return (0); 17621308Sache 17721308Sache _rl_doing_an_undo = 1; 17875406Sache RL_SETSTATE(RL_STATE_UNDOING); 17921308Sache 18021308Sache /* To better support vi-mode, a start or end value of -1 means 18121308Sache rl_point, and a value of -2 means rl_end. */ 18221308Sache if (rl_undo_list->what == UNDO_DELETE || rl_undo_list->what == UNDO_INSERT) 18321308Sache { 18421308Sache start = TRANS (rl_undo_list->start); 18521308Sache end = TRANS (rl_undo_list->end); 18621308Sache } 18721308Sache 18821308Sache switch (rl_undo_list->what) 18921308Sache { 19021308Sache /* Undoing deletes means inserting some text. */ 19121308Sache case UNDO_DELETE: 19221308Sache rl_point = start; 19321308Sache rl_insert_text (rl_undo_list->text); 19421308Sache free (rl_undo_list->text); 19521308Sache break; 19621308Sache 19721308Sache /* Undoing inserts means deleting some text. */ 19821308Sache case UNDO_INSERT: 19921308Sache rl_delete_text (start, end); 20021308Sache rl_point = start; 20121308Sache break; 20221308Sache 20321308Sache /* Undoing an END means undoing everything 'til we get to a BEGIN. */ 20421308Sache case UNDO_END: 20521308Sache waiting_for_begin++; 20621308Sache break; 20721308Sache 20821308Sache /* Undoing a BEGIN means that we are done with this group. */ 20921308Sache case UNDO_BEGIN: 21021308Sache if (waiting_for_begin) 21121308Sache waiting_for_begin--; 21221308Sache else 21375406Sache rl_ding (); 21421308Sache break; 21521308Sache } 21621308Sache 21721308Sache _rl_doing_an_undo = 0; 21875406Sache RL_UNSETSTATE(RL_STATE_UNDOING); 21921308Sache 22021308Sache release = rl_undo_list; 22121308Sache rl_undo_list = rl_undo_list->next; 222165670Sache replace_history_data (-1, (histdata_t *)release, (histdata_t *)rl_undo_list); 223165670Sache 22421308Sache free (release); 22521308Sache } 22621308Sache while (waiting_for_begin); 22721308Sache 22821308Sache return (1); 22921308Sache} 23021308Sache#undef TRANS 23121308Sache 23221308Sacheint 23321308Sache_rl_fix_last_undo_of_type (type, start, end) 23421308Sache int type, start, end; 23521308Sache{ 23621308Sache UNDO_LIST *rl; 23721308Sache 23821308Sache for (rl = rl_undo_list; rl; rl = rl->next) 23921308Sache { 24021308Sache if (rl->what == type) 24121308Sache { 24221308Sache rl->start = start; 24321308Sache rl->end = end; 24421308Sache return 0; 24521308Sache } 24621308Sache } 24721308Sache return 1; 24821308Sache} 24921308Sache 25021308Sache/* Begin a group. Subsequent undos are undone as an atomic operation. */ 25121308Sacheint 25221308Sacherl_begin_undo_group () 25321308Sache{ 25421308Sache rl_add_undo (UNDO_BEGIN, 0, 0, 0); 25521308Sache _rl_undo_group_level++; 25621308Sache return 0; 25721308Sache} 25821308Sache 25921308Sache/* End an undo group started with rl_begin_undo_group (). */ 26021308Sacheint 26121308Sacherl_end_undo_group () 26221308Sache{ 26321308Sache rl_add_undo (UNDO_END, 0, 0, 0); 26421308Sache _rl_undo_group_level--; 26521308Sache return 0; 26621308Sache} 26721308Sache 26821308Sache/* Save an undo entry for the text from START to END. */ 26921308Sacheint 27021308Sacherl_modifying (start, end) 27121308Sache int start, end; 27221308Sache{ 27321308Sache if (start > end) 27421308Sache { 27521308Sache SWAP (start, end); 27621308Sache } 27721308Sache 27821308Sache if (start != end) 27921308Sache { 28021308Sache char *temp = rl_copy_text (start, end); 28121308Sache rl_begin_undo_group (); 28221308Sache rl_add_undo (UNDO_DELETE, start, end, temp); 28321308Sache rl_add_undo (UNDO_INSERT, start, end, (char *)NULL); 28421308Sache rl_end_undo_group (); 28521308Sache } 28621308Sache return 0; 28721308Sache} 28821308Sache 28921308Sache/* Revert the current line to its previous state. */ 29021308Sacheint 29121308Sacherl_revert_line (count, key) 29221308Sache int count, key; 29321308Sache{ 29421308Sache if (!rl_undo_list) 29575406Sache rl_ding (); 29621308Sache else 29721308Sache { 29821308Sache while (rl_undo_list) 29921308Sache rl_do_undo (); 300157184Sache#if defined (VI_MODE) 301157184Sache if (rl_editing_mode == vi_mode) 302157184Sache rl_point = rl_mark = 0; /* rl_end should be set correctly */ 303157184Sache#endif 30421308Sache } 305157184Sache 30621308Sache return 0; 30721308Sache} 30821308Sache 30921308Sache/* Do some undoing of things that were done. */ 31021308Sacheint 31121308Sacherl_undo_command (count, key) 31221308Sache int count, key; 31321308Sache{ 31421308Sache if (count < 0) 31521308Sache return 0; /* Nothing to do. */ 31621308Sache 31721308Sache while (count) 31821308Sache { 31921308Sache if (rl_do_undo ()) 32021308Sache count--; 32121308Sache else 32221308Sache { 32375406Sache rl_ding (); 32421308Sache break; 32521308Sache } 32621308Sache } 32721308Sache return 0; 32821308Sache} 329